00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 00029 00030 #ifdef WIN32 00031 #include <windows.h> 00032 #endif 00033 00034 #include <stdlib.h> 00035 #include <string.h> 00036 00037 #include " SDL_rotozoom.h 00038 00039 00040 00044 typedef struct tColorRGBA { 00045 Uint8 r; 00046 Uint8 g; 00047 Uint8 b; 00048 Uint8 a; 00049 } tColorRGBA; 00050 00054 typedef struct tColorY { 00055 Uint8 y; 00056 } tColorY; 00057 00061 #define MAX(a,b) (((a) > (b)) ? (a) : (b)) 00062 00073 #define GUARD_ROWS (2) 00074 00078 #define VALUE_LIMIT 0.001 00079 00083 Uint32 _colorkey(SDL_Surface *src) 00084 { 00085 Uint32 key = 0; 00086 #if (SDL_MINOR_VERSION == 3) 00087 SDL_GetColorKey(src, &key); 00088 #else 00089 if (src) 00090 { 00091 key = src->format->colorkey; 00092 } 00093 #endif 00094 return key; 00095 } 00096 00097 00113 int _shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory) 00114 { 00115 int x, y, dx, dy, sgap, dgap, ra, ga, ba, aa; 00116 int n_average; 00117 tColorRGBA *sp, *osp, *oosp; 00118 tColorRGBA *dp; 00119 00120 00121 00122 00123 00124 00125 n_average = factorx*factory; 00126 00127 00128 00129 00130 sp = (tColorRGBA *) src->pixels; 00131 sgap = src->pitch - src->w * 4; 00132 00133 dp = (tColorRGBA *) dst->pixels; 00134 dgap = dst->pitch - dst->w * 4; 00135 00136 for (y = 0; y < dst->h; y++) { 00137 00138 osp=sp; 00139 for (x = 0; x < dst->w; x++) { 00140 00141 00142 oosp=sp; 00143 ra=ga=ba=aa=0; 00144 for (dy=0; dy < factory; dy++) { 00145 for (dx=0; dx < factorx; dx++) { 00146 ra += sp->r; 00147 ga += sp->g; 00148 ba += sp->b; 00149 aa += sp->a; 00150 00151 sp++; 00152 } 00153 00154 sp = (tColorRGBA *)((Uint8*)sp + (src->pitch - 4*factorx)); 00155 } 00156 00157 00158 00159 sp = (tColorRGBA *)((Uint8*)oosp + 4*factorx); 00160 00161 00162 dp->r = ra/n_average; 00163 dp->g = ga/n_average; 00164 dp->b = ba/n_average; 00165 dp->a = aa/n_average; 00166 00167 00168 00169 00170 dp++; 00171 } 00172 00173 00174 00175 sp = (tColorRGBA *)((Uint8*)osp + src->pitch*factory); 00176 00177 00178 00179 00180 dp = (tColorRGBA *) ((Uint8 *) dp + dgap); 00181 } 00182 00183 00184 return (0); 00185 } 00186 00202 int _shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory) 00203 { 00204 int x, y, dx, dy, sgap, dgap, a; 00205 int n_average; 00206 Uint8 *sp, *osp, *oosp; 00207 Uint8 *dp; 00208 00209 00210 00211 00212 00213 00214 n_average = factorx*factory; 00215 00216 00217 00218 00219 sp = (Uint8 *) src->pixels; 00220 sgap = src->pitch - src->w; 00221 00222 dp = (Uint8 *) dst->pixels; 00223 dgap = dst->pitch - dst->w; 00224 00225 for (y = 0; y < dst->h; y++) { 00226 00227 osp=sp; 00228 for (x = 0; x < dst->w; x++) { 00229 00230 00231 oosp=sp; 00232 a=0; 00233 for (dy=0; dy < factory; dy++) { 00234 for (dx=0; dx < factorx; dx++) { 00235 a += (*sp); 00236 00237 sp++; 00238 } 00239 00240 00241 sp = (Uint8 *)((Uint8*)sp + (src->pitch - factorx)); 00242 } 00243 00244 00245 00246 sp = (Uint8 *)((Uint8*)oosp + factorx); 00247 00248 00249 *dp = a/n_average; 00250 00251 00252 00253 00254 dp++; 00255 } 00256 00257 00258 00259 sp = (Uint8 *)((Uint8*)osp + src->pitch*factory); 00260 00261 00262 00263 00264 dp = (Uint8 *)((Uint8 *)dp + dgap); 00265 } 00266 00267 00268 return (0); 00269 } 00270 00286 int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth) 00287 { 00288 int x, y, sx, sy, ssx, ssy, *sax, *say, *csax, *csay, *salast, csx, csy, ex, ey, cx, cy, sstep, sstepx, sstepy; 00289 tColorRGBA *c00, *c01, *c10, *c11; 00290 tColorRGBA *sp, *csp, *dp; 00291 int spixelgap, spixelw, spixelh, dgap, t1, t2; 00292 00293 00294 00295 00296 if ((sax = ( int *) malloc((dst->w + 1) * sizeof (Uint32))) == NULL) { 00297 return (-1); 00298 } 00299 if ((say = ( int *) malloc((dst->h + 1) * sizeof (Uint32))) == NULL) { 00300 free(sax); 00301 return (-1); 00302 } 00303 00304 00305 00306 00307 spixelw = (src->w - 1); 00308 spixelh = (src->h - 1); 00309 if (smooth) { 00310 sx = (int) (65536.0 * ( float ) spixelw / (float) (dst->w - 1)); 00311 sy = (int) (65536.0 * ( float ) spixelh / (float) (dst->h - 1)); 00312 } else { 00313 sx = (int) (65536.0 * ( float ) (src->w) / ( float ) (dst->w)); 00314 sy = (int) (65536.0 * ( float ) (src->h) / ( float ) (dst->h)); 00315 } 00316 00317 00318 ssx = (src->w << 16) - 1; 00319 ssy = (src->h << 16) - 1; 00320 00321 00322 csx = 0; 00323 csax = sax; 00324 for (x = 0; x <= dst->w; x++) { 00325 *csax = csx; 00326 csax++; 00327 csx += sx; 00328 00329 00330 if (csx > ssx) { 00331 csx = ssx; 00332 } 00333 } 00334 00335 00336 csy = 0; 00337 csay = say; 00338 for (y = 0; y <= dst->h; y++) { 00339 *csay = csy; 00340 csay++; 00341 csy += sy; 00342 00343 00344 if (csy > ssy) { 00345 csy = ssy; 00346 } 00347 } 00348 00349 sp = (tColorRGBA *) src->pixels; 00350 dp = (tColorRGBA *) dst->pixels; 00351 dgap = dst->pitch - dst->w * 4; 00352 spixelgap = src->pitch/4; 00353 00354 if (flipx) sp += spixelw; 00355 if (flipy) sp += (spixelgap * spixelh); 00356 00357 00358 00359 00360 if (smooth) { 00361 00362 00363 00364 00365 csay = say; 00366 for (y = 0; y < dst->h; y++) { 00367 csp = sp; 00368 csax = sax; 00369 for (x = 0; x < dst->w; x++) { 00370 00371 00372 00373 ex = (*csax & 0xffff); 00374 ey = (*csay & 0xffff); 00375 cx = (*csax >> 16); 00376 cy = (*csay >> 16); 00377 sstepx = cx < spixelw; 00378 sstepy = cy < spixelh; 00379 c00 = sp; 00380 c01 = sp; 00381 c10 = sp; 00382 if (sstepy) { 00383 if (flipy) { 00384 c10 -= spixelgap; 00385 } else { 00386 c10 += spixelgap; 00387 } 00388 } 00389 c11 = c10; 00390 if (sstepx) { 00391 if (flipx) { 00392 c01--; 00393 c11--; 00394 } else { 00395 c01++; 00396 c11++; 00397 } 00398 } 00399 00400 00401 00402 00403 t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff; 00404 t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff; 00405 dp->r = (((t2 - t1) * ey) >> 16) + t1; 00406 t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff; 00407 t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff; 00408 dp->g = (((t2 - t1) * ey) >> 16) + t1; 00409 t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff; 00410 t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff; 00411 dp->b = (((t2 - t1) * ey) >> 16) + t1; 00412 t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff; 00413 t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff; 00414 dp->a = (((t2 - t1) * ey) >> 16) + t1; 00415 00416 00417 00418 salast = csax; 00419 csax++; 00420 sstep = (*csax >> 16) - (*salast >> 16); 00421 if (flipx) { 00422 sp -= sstep; 00423 } else { 00424 sp += sstep; 00425 } 00426 00427 00428 00429 00430 dp++; 00431 } 00432 00433 00434 00435 salast = csay; 00436 csay++; 00437 sstep = (*csay >> 16) - (*salast >> 16); 00438 sstep *= spixelgap; 00439 if (flipy) { 00440 sp = csp - sstep; 00441 } else { 00442 sp = csp + sstep; 00443 } 00444 00445 00446 00447 00448 dp = (tColorRGBA *) ((Uint8 *) dp + dgap); 00449 } 00450 } else { 00451 00452 00453 00454 csay = say; 00455 for (y = 0; y < dst->h; y++) { 00456 csp = sp; 00457 csax = sax; 00458 for (x = 0; x < dst->w; x++) { 00459 00460 00461 00462 *dp = *sp; 00463 00464 00465 00466 00467 salast = csax; 00468 csax++; 00469 sstep = (*csax >> 16) - (*salast >> 16); 00470 if (flipx) sstep = -sstep; 00471 sp += sstep; 00472 00473 00474 00475 00476 dp++; 00477 } 00478 00479 00480 00481 salast = csay; 00482 csay++; 00483 sstep = (*csay >> 16) - (*salast >> 16); 00484 sstep *= spixelgap; 00485 if (flipy) sstep = -sstep; 00486 sp = csp + sstep; 00487 00488 00489 00490 00491 dp = (tColorRGBA *) ((Uint8 *) dp + dgap); 00492 } 00493 } 00494 00495 00496 00497 00498 free(sax); 00499 free(say); 00500 00501 return (0); 00502 } 00503 00519 int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) 00520 { 00521 int x, y; 00522 Uint32 *sax, *say, *csax, *csay; 00523 int csx, csy; 00524 Uint8 *sp, *dp, *csp; 00525 int dgap; 00526 00527 00528 00529 00530 if ((sax = (Uint32 *) malloc((dst->w + 1) * sizeof (Uint32))) == NULL) { 00531 return (-1); 00532 } 00533 if ((say = (Uint32 *) malloc((dst->h + 1) * sizeof (Uint32))) == NULL) { 00534 free(sax); 00535 return (-1); 00536 } 00537 00538 00539 00540 00541 sp = csp = (Uint8 *) src->pixels; 00542 dp = (Uint8 *) dst->pixels; 00543 dgap = dst->pitch - dst->w; 00544 00545 if (flipx) csp += (src->w-1); 00546 if (flipy) csp = ( (Uint8*)csp + src->pitch*(src->h-1) ); 00547 00548 00549 00550 00551 csx = 0; 00552 csax = sax; 00553 for (x = 0; x < dst->w; x++) { 00554 csx += src->w; 00555 *csax = 0; 00556 while (csx >= dst->w) { 00557 csx -= dst->w; 00558 (*csax)++; 00559 } 00560 (*csax) = (*csax) * (flipx ? -1 : 1); 00561 csax++; 00562 } 00563 csy = 0; 00564 csay = say; 00565 for (y = 0; y < dst->h; y++) { 00566 csy += src->h; 00567 *csay = 0; 00568 while (csy >= dst->h) { 00569 csy -= dst->h; 00570 (*csay)++; 00571 } 00572 (*csay) = (*csay) * (flipy ? -1 : 1); 00573 csay++; 00574 } 00575 00576 00577 00578 00579 csay = say; 00580 for (y = 0; y < dst->h; y++) { 00581 csax = sax; 00582 sp = csp; 00583 for (x = 0; x < dst->w; x++) { 00584 00585 00586 00587 *dp = *sp; 00588 00589 00590 00591 sp += (*csax); 00592 csax++; 00593 00594 00595 00596 dp++; 00597 } 00598 00599 00600 00601 csp += ((*csay) * src->pitch); 00602 csay++; 00603 00604 00605 00606 00607 dp += dgap; 00608 } 00609 00610 00611 00612 00613 free(sax); 00614 free(say); 00615 00616 return (0); 00617 } 00618 00638 void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth) 00639 { 00640 int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; 00641 tColorRGBA c00, c01, c10, c11, cswap; 00642 tColorRGBA *pc, *sp; 00643 int gap; 00644 00645 00646 00647 00648 xd = ((src->w - dst->w) << 15); 00649 yd = ((src->h - dst->h) << 15); 00650 ax = (cx << 16) - (icos * cx); 00651 ay = (cy << 16) - (isin * cx); 00652 sw = src->w - 1; 00653 sh = src->h - 1; 00654 pc = (tColorRGBA*) dst->pixels; 00655 gap = dst->pitch - dst->w * 4; 00656 00657 00658 00659 00660 if (smooth) { 00661 for (y = 0; y < dst->h; y++) { 00662 dy = cy - y; 00663 sdx = (ax + (isin * dy)) + xd; 00664 sdy = (ay - (icos * dy)) + yd; 00665 for (x = 0; x < dst->w; x++) { 00666 dx = (sdx >> 16); 00667 dy = (sdy >> 16); 00668 if (flipx) dx = sw - dx; 00669 if (flipy) dy = sh - dy; 00670 if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) { 00671 sp = (tColorRGBA *)src->pixels;; 00672 sp += ((src->pitch/4) * dy); 00673 sp += dx; 00674 c00 = *sp; 00675 sp += 1; 00676 c01 = *sp; 00677 sp += (src->pitch/4); 00678 c11 = *sp; 00679 sp -= 1; 00680 c10 = *sp; 00681 if (flipx) { 00682 cswap = c00; c00=c01; c01=cswap; 00683 cswap = c10; c10=c11; c11=cswap; 00684 } 00685 if (flipy) { 00686 cswap = c00; c00=c10; c10=cswap; 00687 cswap = c01; c01=c11; c11=cswap; 00688 } 00689 00690 00691 00692 ex = (sdx & 0xffff); 00693 ey = (sdy & 0xffff); 00694 t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff; 00695 t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff; 00696 pc->r = (((t2 - t1) * ey) >> 16) + t1; 00697 t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff; 00698 t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff; 00699 pc->g = (((t2 - t1) * ey) >> 16) + t1; 00700 t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff; 00701 t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff; 00702 pc->b = (((t2 - t1) * ey) >> 16) + t1; 00703 t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff; 00704 t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff; 00705 pc->a = (((t2 - t1) * ey) >> 16) + t1; 00706 } 00707 sdx += icos; 00708 sdy += isin; 00709 pc++; 00710 } 00711 pc = (tColorRGBA *) ((Uint8 *) pc + gap); 00712 } 00713 } else { 00714 for (y = 0; y < dst->h; y++) { 00715 dy = cy - y; 00716 sdx = (ax + (isin * dy)) + xd; 00717 sdy = (ay - (icos * dy)) + yd; 00718 for (x = 0; x < dst->w; x++) { 00719 dx = (short) (sdx >> 16); 00720 dy = (short) (sdy >> 16); 00721 if (flipx) dx = (src->w-1)-dx; 00722 if (flipy) dy = (src->h-1)-dy; 00723 if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) { 00724 sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); 00725 sp += dx; 00726 *pc = *sp; 00727 } 00728 sdx += icos; 00729 sdy += isin; 00730 pc++; 00731 } 00732 pc = (tColorRGBA *) ((Uint8 *) pc + gap); 00733 } 00734 } 00735 } 00736 00755 void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy) 00756 { 00757 int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh; 00758 tColorY *pc, *sp; 00759 int gap; 00760 00761 00762 00763 00764 xd = ((src->w - dst->w) << 15); 00765 yd = ((src->h - dst->h) << 15); 00766 ax = (cx << 16) - (icos * cx); 00767 ay = (cy << 16) - (isin * cx); 00768 sw = src->w - 1; 00769 sh = src->h - 1; 00770 pc = (tColorY*) dst->pixels; 00771 gap = dst->pitch - dst->w; 00772 00773 00774 00775 memset(pc, ( int )(_colorkey(src) & 0xff), dst->pitch * dst->h); 00776 00777 00778 00779 for (y = 0; y < dst->h; y++) { 00780 dy = cy - y; 00781 sdx = (ax + (isin * dy)) + xd; 00782 sdy = (ay - (icos * dy)) + yd; 00783 for (x = 0; x < dst->w; x++) { 00784 dx = (short) (sdx >> 16); 00785 dy = (short) (sdy >> 16); 00786 if (flipx) dx = (src->w-1)-dx; 00787 if (flipy) dy = (src->h-1)-dy; 00788 if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) { 00789 sp = (tColorY *) (src->pixels); 00790 sp += (src->pitch * dy + dx); 00791 *pc = *sp; 00792 } 00793 sdx += icos; 00794 sdy += isin; 00795 pc++; 00796 } 00797 pc += gap; 00798 } 00799 } 00800 00814 SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns) 00815 { 00816 int row, col, newWidth, newHeight; 00817 int bpp, src_ipr, dst_ipr; 00818 SDL_Surface* dst; 00819 Uint32* srcBuf; 00820 Uint32* dstBuf; 00821 00822 00823 if (!src || src->format->BitsPerPixel != 32) { return NULL; } 00824 00825 00826 while (numClockwiseTurns < 0) { numClockwiseTurns += 4; } 00827 numClockwiseTurns = (numClockwiseTurns % 4); 00828 00829 00830 newWidth = (numClockwiseTurns % 2) ? (src->h) : (src->w); 00831 newHeight = (numClockwiseTurns % 2) ? (src->w) : (src->h); 00832 dst = SDL_CreateRGBSurface( src->flags, newWidth, newHeight, src->format->BitsPerPixel, 00833 src->format->Rmask, 00834 src->format->Gmask, 00835 src->format->Bmask, 00836 src->format->Amask); 00837 if (!dst) { 00838 return NULL; 00839 } 00840 00841 if (SDL_MUSTLOCK(dst)) { 00842 SDL_LockSurface(dst); 00843 } 00844 if (SDL_MUSTLOCK(dst)) { 00845 SDL_LockSurface(dst); 00846 } 00847 00848 00849 bpp = src->format->BitsPerPixel / 8; 00850 src_ipr = src->pitch / bpp; 00851 dst_ipr = dst->pitch / bpp; 00852 00853 switch (numClockwiseTurns) { 00854 case 0: 00855 { 00856 00857 00858 00859 if (src->pitch == dst->pitch) { 00860 00861 memcpy(dst->pixels, src->pixels, (src->h * src->pitch)); 00862 } 00863 else 00864 { 00865 00866 srcBuf = (Uint32*)(src->pixels); 00867 dstBuf = (Uint32*)(dst->pixels); 00868 for (row = 0; row < src->h; row++) { 00869 memcpy(dstBuf, srcBuf, dst->w * bpp); 00870 srcBuf += src_ipr; 00871 dstBuf += dst_ipr; 00872 } 00873 } 00874 } 00875 break ; 00876 00877 00878 case 1: 00879 { 00880 for (row = 0; row < src->h; ++row) { 00881 srcBuf = (Uint32*)(src->pixels) + (row * src_ipr); 00882 dstBuf = (Uint32*)(dst->pixels) + (dst->w - row - 1); 00883 for (col = 0; col < src->w; ++col) { 00884 *dstBuf = *srcBuf; 00885 ++srcBuf; 00886 dstBuf += dst_ipr; 00887 } 00888 00889 } 00890 00891 } 00892 break ; 00893 00894 case 2: 00895 { 00896 for (row = 0; row < src->h; ++row) { 00897 srcBuf = (Uint32*)(src->pixels) + (row * src_ipr); 00898 dstBuf = (Uint32*)(dst->pixels) + ((dst->h - row - 1) * dst_ipr) + (dst->w - 1); 00899 for (col = 0; col < src->w; ++col) { 00900 *dstBuf = *srcBuf; 00901 ++srcBuf; 00902 --dstBuf; 00903 } 00904 } 00905 } 00906 break ; 00907 00908 case 3: 00909 { 00910 for (row = 0; row < src->h; ++row) { 00911 srcBuf = (Uint32*)(src->pixels) + (row * src_ipr); 00912 dstBuf = (Uint32*)(dst->pixels) + row + ((dst->h - 1) * dst_ipr); 00913 for (col = 0; col < src->w; ++col) { 00914 *dstBuf = *srcBuf; 00915 ++srcBuf; 00916 dstBuf -= dst_ipr; 00917 } 00918 } 00919 } 00920 break ; 00921 } 00922 00923 00924 if (SDL_MUSTLOCK(src)) { 00925 SDL_UnlockSurface(src); 00926 } 00927 if (SDL_MUSTLOCK(dst)) { 00928 SDL_UnlockSurface(dst); 00929 } 00930 00931 return dst; 00932 } 00933 00934 00949 void _rotozoomSurfaceSizeTrig( int width, int height, double angle, double zoomx, double zoomy, 00950 int *dstwidth, int *dstheight, 00951 double *canglezoom, double *sanglezoom) 00952 { 00953 double x, y, cx, cy, sx, sy; 00954 double radangle; 00955 int dstwidthhalf, dstheighthalf; 00956 00957 00958 00959 00960 radangle = angle * (M_PI / 180.0); 00961 *sanglezoom = sin(radangle); 00962 *canglezoom = cos(radangle); 00963 *sanglezoom *= zoomx; 00964 *canglezoom *= zoomx; 00965 x = (double)(width / 2); 00966 y = (double)(height / 2); 00967 cx = *canglezoom * x; 00968 cy = *canglezoom * y; 00969 sx = *sanglezoom * x; 00970 sy = *sanglezoom * y; 00971 00972 dstwidthhalf = MAX(( int ) 00973 ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1); 00974 dstheighthalf = MAX(( int ) 00975 ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1); 00976 *dstwidth = 2 * dstwidthhalf; 00977 *dstheight = 2 * dstheighthalf; 00978 } 00979 00991 void rotozoomSurfaceSizeXY( int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight) 00992 { 00993 double dummy_sanglezoom, dummy_canglezoom; 00994 00995 _rotozoomSurfaceSizeTrig(width, height, angle, zoomx, zoomy, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom); 00996 } 00997 01008 void rotozoomSurfaceSize( int width, int height, double angle, double zoom, int *dstwidth, int *dstheight) 01009 { 01010 double dummy_sanglezoom, dummy_canglezoom; 01011 01012 _rotozoomSurfaceSizeTrig(width, height, angle, zoom, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom); 01013 } 01014 01030 SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth) 01031 { 01032 return rotozoomSurfaceXY(src, angle, zoom, zoom, smooth); 01033 } 01034 01051 SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth) 01052 { 01053 SDL_Surface *rz_src; 01054 SDL_Surface *rz_dst; 01055 double zoominv; 01056 double sanglezoom, canglezoom, sanglezoominv, canglezoominv; 01057 int dstwidthhalf, dstwidth, dstheighthalf, dstheight; 01058 int is32bit; 01059 int i, src_converted; 01060 int flipx,flipy; 01061 Uint8 r,g,b; 01062 Uint32 colorkey = 0; 01063 int colorKeyAvailable = 0; 01064 01065 01066 01067 01068 if (src == NULL) 01069 return (NULL); 01070 01071 if (src->flags & SDL_SRCCOLORKEY) 01072 { 01073 colorkey = _colorkey(src); 01074 SDL_GetRGB(colorkey, src->format, &r, &g, &b); 01075 colorKeyAvailable = 1; 01076 } 01077 01078 01079 01080 is32bit = (src->format->BitsPerPixel == 32); 01081 if ((is32bit) || (src->format->BitsPerPixel == 8)) { 01082 01083 01084 01085 rz_src = src; 01086 src_converted = 0; 01087 } else { 01088 01089 01090 01091 rz_src = 01092 SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 01093 # if SDL_BYTEORDER == SDL_LIL_ENDIAN 01094 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 01095 # else 01096 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff 01097 #endif 01098 ); 01099 if (colorKeyAvailable) 01100 SDL_SetColorKey(src, 0, 0); 01101 01102 SDL_BlitSurface(src, NULL, rz_src, NULL); 01103 01104 if (colorKeyAvailable) 01105 SDL_SetColorKey(src, SDL_SRCCOLORKEY, colorkey); 01106 src_converted = 1; 01107 is32bit = 1; 01108 } 01109 01110 01111 01112 01113 flipx = (zoomx<0.0); 01114 if (flipx) zoomx=-zoomx; 01115 flipy = (zoomy<0.0); 01116 if (flipy) zoomy=-zoomy; 01117 if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT; 01118 if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT; 01119 zoominv = 65536.0 / (zoomx * zoomx); 01120 01121 01122 01123 01124 if (fabs(angle) > VALUE_LIMIT) { 01125 01126 01127 01128 01129 01130 01131 01132 01133 01134 _rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom); 01135 01136 01137 01138 01139 sanglezoominv = sanglezoom; 01140 canglezoominv = canglezoom; 01141 sanglezoominv *= zoominv; 01142 canglezoominv *= zoominv; 01143 01144 01145 dstwidthhalf = dstwidth / 2; 01146 dstheighthalf = dstheight / 2; 01147 01148 01149 01150 01151 rz_dst = NULL; 01152 if (is32bit) { 01153 01154 01155 01156 rz_dst = 01157 SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32, 01158 rz_src->format->Rmask, rz_src->format->Gmask, 01159 rz_src->format->Bmask, rz_src->format->Amask); 01160 } else { 01161 01162 01163 01164 rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0); 01165 } 01166 01167 01168 if (rz_dst == NULL) 01169 return NULL; 01170 01171 01172 rz_dst->h = dstheight; 01173 01174 if (colorKeyAvailable == 1){ 01175 colorkey = SDL_MapRGB(rz_dst->format, r, g, b); 01176 01177 SDL_FillRect(rz_dst, NULL, colorkey ); 01178 } 01179 01180 01181 01182 01183 if (SDL_MUSTLOCK(rz_src)) { 01184 SDL_LockSurface(rz_src); 01185 } 01186 01187 01188 01189 01190 if (is32bit) { 01191 01192 01193 01194 _transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf, 01195 ( int ) (sanglezoominv), ( int ) (canglezoominv), 01196 flipx, flipy, 01197 smooth); 01198 01199 01200 01201 SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); 01202 SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); 01203 } else { 01204 01205 01206 01207 for (i = 0; i < rz_src->format->palette->ncolors; i++) { 01208 rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; 01209 } 01210 rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; 01211 01212 01213 01214 transformSurfaceY(rz_src, rz_dst, dstwidthhalf, dstheighthalf, 01215 ( int ) (sanglezoominv), ( int ) (canglezoominv), 01216 flipx, flipy); 01217 SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); 01218 } 01219 01220 01221 01222 if (SDL_MUSTLOCK(rz_src)) { 01223 SDL_UnlockSurface(rz_src); 01224 } 01225 01226 } else { 01227 01228 01229 01230 01231 01232 01233 01234 01235 01236 01237 01238 zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight); 01239 01240 01241 01242 01243 rz_dst = NULL; 01244 if (is32bit) { 01245 01246 01247 01248 rz_dst = 01249 SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32, 01250 rz_src->format->Rmask, rz_src->format->Gmask, 01251 rz_src->format->Bmask, rz_src->format->Amask); 01252 } else { 01253 01254 01255 01256 rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0); 01257 } 01258 01259 01260 if (rz_dst == NULL) 01261 return NULL; 01262 01263 01264 rz_dst->h = dstheight; 01265 01266 if (colorKeyAvailable == 1){ 01267 colorkey = SDL_MapRGB(rz_dst->format, r, g, b); 01268 01269 SDL_FillRect(rz_dst, NULL, colorkey ); 01270 } 01271 01272 01273 01274 01275 if (SDL_MUSTLOCK(rz_src)) { 01276 SDL_LockSurface(rz_src); 01277 } 01278 01279 01280 01281 01282 if (is32bit) { 01283 01284 01285 01286 _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth); 01287 01288 01289 01290 01291 SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); 01292 SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); 01293 } else { 01294 01295 01296 01297 for (i = 0; i < rz_src->format->palette->ncolors; i++) { 01298 rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; 01299 } 01300 rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; 01301 01302 01303 01304 01305 _zoomSurfaceY(rz_src, rz_dst, flipx, flipy); 01306 SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); 01307 } 01308 01309 01310 01311 01312 if (SDL_MUSTLOCK(rz_src)) { 01313 SDL_UnlockSurface(rz_src); 01314 } 01315 } 01316 01317 01318 01319 01320 if (src_converted) { 01321 SDL_FreeSurface(rz_src); 01322 } 01323 01324 01325 01326 01327 return (rz_dst); 01328 } 01329 01342 void zoomSurfaceSize( int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight) 01343 { 01344 01345 01346 01347 int flipx, flipy; 01348 flipx = (zoomx<0.0); 01349 if (flipx) zoomx = -zoomx; 01350 flipy = (zoomy<0.0); 01351 if (flipy) zoomy = -zoomy; 01352 01353 01354 01355 01356 if (zoomx < VALUE_LIMIT) { 01357 zoomx = VALUE_LIMIT; 01358 } 01359 if (zoomy < VALUE_LIMIT) { 01360 zoomy = VALUE_LIMIT; 01361 } 01362 01363 01364 01365 01366 *dstwidth = (int) floor((( double ) width * zoomx) + 0.5); 01367 *dstheight = (int) floor((( double ) height * zoomy) + 0.5); 01368 if (*dstwidth < 1) { 01369 *dstwidth = 1; 01370 } 01371 if (*dstheight < 1) { 01372 *dstheight = 1; 01373 } 01374 } 01375 01392 SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth) 01393 { 01394 SDL_Surface *rz_src; 01395 SDL_Surface *rz_dst; 01396 int dstwidth, dstheight; 01397 int is32bit; 01398 int i, src_converted; 01399 int flipx, flipy; 01400 01401 01402 01403 01404 if (src == NULL) 01405 return (NULL); 01406 01407 01408 01409 01410 is32bit = (src->format->BitsPerPixel == 32); 01411 if ((is32bit) || (src->format->BitsPerPixel == 8)) { 01412 01413 01414 01415 rz_src = src; 01416 src_converted = 0; 01417 } else { 01418 01419 01420 01421 rz_src = 01422 SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 01423 # if SDL_BYTEORDER == SDL_LIL_ENDIAN 01424 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 01425 # else 01426 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff 01427 #endif 01428 ); 01429 if (rz_src == NULL) { 01430 return NULL; 01431 } 01432 SDL_BlitSurface(src, NULL, rz_src, NULL); 01433 src_converted = 1; 01434 is32bit = 1; 01435 } 01436 01437 flipx = (zoomx<0.0); 01438 if (flipx) zoomx = -zoomx; 01439 flipy = (zoomy<0.0); 01440 if (flipy) zoomy = -zoomy; 01441 01442 01443 zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight); 01444 01445 01446 01447 01448 rz_dst = NULL; 01449 if (is32bit) { 01450 01451 01452 01453 rz_dst = 01454 SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32, 01455 rz_src->format->Rmask, rz_src->format->Gmask, 01456 rz_src->format->Bmask, rz_src->format->Amask); 01457 } else { 01458 01459 01460 01461 rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0); 01462 } 01463 01464 01465 if (rz_dst == NULL) { 01466 01467 01468 01469 if (src_converted) { 01470 SDL_FreeSurface(rz_src); 01471 } 01472 return NULL; 01473 } 01474 01475 01476 rz_dst->h = dstheight; 01477 01478 01479 01480 01481 if (SDL_MUSTLOCK(rz_src)) { 01482 SDL_LockSurface(rz_src); 01483 } 01484 01485 01486 01487 01488 if (is32bit) { 01489 01490 01491 01492 _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth); 01493 01494 01495 01496 SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); 01497 } else { 01498 01499 01500 01501 for (i = 0; i < rz_src->format->palette->ncolors; i++) { 01502 rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; 01503 } 01504 rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; 01505 01506 01507 01508 _zoomSurfaceY(rz_src, rz_dst, flipx, flipy); 01509 SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); 01510 } 01511 01512 01513 01514 if (SDL_MUSTLOCK(rz_src)) { 01515 SDL_UnlockSurface(rz_src); 01516 } 01517 01518 01519 01520 01521 if (src_converted) { 01522 SDL_FreeSurface(rz_src); 01523 } 01524 01525 01526 01527 01528 return (rz_dst); 01529 } 01530 01547 01548 SDL_Surface *shrinkSurface(SDL_Surface *src, int factorx, int factory) 01549 { 01550 int result; 01551 SDL_Surface *rz_src; 01552 SDL_Surface *rz_dst = NULL; 01553 int dstwidth, dstheight; 01554 int is32bit; 01555 int i, src_converted; 01556 int haveError = 0; 01557 01558 01559 01560 01561 if (src == NULL) { 01562 return (NULL); 01563 } 01564 01565 01566 01567 01568 is32bit = (src->format->BitsPerPixel == 32); 01569 if ((is32bit) || (src->format->BitsPerPixel == 8)) { 01570 01571 01572 01573 rz_src = src; 01574 src_converted = 0; 01575 } else { 01576 01577 01578 01579 rz_src = SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 01580 # if SDL_BYTEORDER == SDL_LIL_ENDIAN 01581 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 01582 # else 01583 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff 01584 #endif 01585 ); 01586 if (rz_src==NULL) { 01587 haveError = 1; 01588 goto exitShrinkSurface; 01589 } 01590 01591 SDL_BlitSurface(src, NULL, rz_src, NULL); 01592 src_converted = 1; 01593 is32bit = 1; 01594 } 01595 01596 01597 01598 01599 if (SDL_MUSTLOCK(rz_src)) { 01600 if (SDL_LockSurface(rz_src) < 0) { 01601 haveError = 1; 01602 goto exitShrinkSurface; 01603 } 01604 } 01605 01606 01607 dstwidth=rz_src->w/factorx; 01608 while (dstwidth*factorx>rz_src->w) { dstwidth--; } 01609 dstheight=rz_src->h/factory; 01610 while (dstheight*factory>rz_src->h) { dstheight--; } 01611 01612 01613 01614 01615 01616 if (is32bit==1) { 01617 01618 01619 01620 rz_dst = 01621 SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32, 01622 rz_src->format->Rmask, rz_src->format->Gmask, 01623 rz_src->format->Bmask, rz_src->format->Amask); 01624 } else { 01625 01626 01627 01628 rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0); 01629 } 01630 01631 01632 if (rz_dst == NULL) { 01633 haveError = 1; 01634 goto exitShrinkSurface; 01635 } 01636 01637 01638 rz_dst->h = dstheight; 01639 01640 01641 01642 01643 if (is32bit==1) { 01644 01645 01646 01647 result = _shrinkSurfaceRGBA(rz_src, rz_dst, factorx, factory); 01648 if ((result!=0) || (rz_dst==NULL)) { 01649 haveError = 1; 01650 goto exitShrinkSurface; 01651 } 01652 01653 01654 01655 01656 result = SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); 01657 if (result!=0) { 01658 haveError = 1; 01659 goto exitShrinkSurface; 01660 } 01661 } else { 01662 01663 01664 01665 for (i = 0; i < rz_src->format->palette->ncolors; i++) { 01666 rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; 01667 } 01668 rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; 01669 01670 01671 01672 result = _shrinkSurfaceY(rz_src, rz_dst, factorx, factory); 01673 if (result!=0) { 01674 haveError = 1; 01675 goto exitShrinkSurface; 01676 } 01677 01678 01679 01680 01681 result = SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src)); 01682 if (result!=0) { 01683 haveError = 1; 01684 goto exitShrinkSurface; 01685 } 01686 } 01687 01688 exitShrinkSurface: 01689 if (rz_src!=NULL) { 01690 01691 01692 01693 if (SDL_MUSTLOCK(rz_src)) { 01694 SDL_UnlockSurface(rz_src); 01695 } 01696 01697 01698 01699 01700 if (src_converted==1) { 01701 SDL_FreeSurface(rz_src); 01702 } 01703 } 01704 01705 01706 if (haveError==1) { 01707 if (rz_dst!=NULL) { 01708 SDL_FreeSurface(rz_dst); 01709 } 01710 rz_dst=NULL; 01711 } 01712 01713 01714 01715 01716 return (rz_dst); 01717 }