00001 /*!@file AppPsycho/psycho-skin-indexing.C Psychophysics support for psycho-skin-indexing.C */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/psycho-skin-resize.C $ 00035 // $Id: psycho-skin-resize.C 10794 2009-02-08 06:21:09Z itti $ 00036 // 00037 00038 /* 00039 * Filtered filter_Image Rescaling 00040 * 00041 * by Dale Schumacher 00042 * 00043 */ 00044 00045 /* 00046 Additional changes by Ray Gardener, Daylon Graphics Ltd. 00047 December 4, 1999 00048 00049 Extreme modification to this to make it usable with SDL_Surfaces -Dave Olsen 1/2006 00050 and compatible with c++ compilers.... namely VC++2005 Express edition. 00051 It's a major hack-job. If anyone cleans this up, please let me know! 00052 I'm sure it can be made more efficient. (It's lots faster in release than in debug) 00053 00054 Summary: 00055 00056 - Horizontal filter contributions are calculated on the fly, 00057 as each column is mapped from src to dst image. This lets 00058 us omit having to allocate a temporary full horizontal stretch 00059 of the src image. 00060 00061 - If none of the src pixels within a sampling region differ, 00062 then the output pixel is forced to equal (any of) the source pixel. 00063 This ensures that filters do not corrupt areas of constant color. 00064 00065 - Filter weight contribution results, after summing, are 00066 rounded to the nearest pixel color value instead of 00067 being casted to Pixel (usually an int or char). Otherwise, 00068 artifacting occurs. 00069 00070 - All memory allocations checked for failure; zoom() returns 00071 error code. filter_new_image() returns NULL if unable to allocate 00072 pixel storage, even if filter_Image struct can be allocated. 00073 Some assertions added. 00074 */ 00075 00076 00077 // "Public Domain 1991 by Dale Schumacher. Mods by Ray Gardener"; 00078 // further mods by ME! (David Olsen) 00079 // and even more by Kevin Baragona, to make it valid C 00080 // and a few more to make it valid C89, and return NULL when needed (David Olsen) 00081 00082 00083 //It would be fantastic if someone would eventually modify these routines to make use 00084 //of native SDL image and pixel formats during the resize process... but, whatever. 00085 00086 //Modified by Nader Noori, nnoori@usc.edu . The modification is in a way that the source image will not be discarded 00087 00088 #include <stdlib.h> 00089 #include <math.h> 00090 #include <SDL/SDL.h> 00091 00092 /* clamp the input to the specified range */ 00093 #define CLAMP(v,l,h) ((v)<(l) ? (l) : (v) > (h) ? (h) : v) 00094 #ifndef M_PI 00095 #define M_PI 3.14159265359 00096 #endif 00097 00098 typedef Uint8 Pixel; 00099 typedef struct 00100 { 00101 int xsize; /* horizontal size of the image in Pixels */ 00102 int ysize; /* vertical size of the image in Pixels */ 00103 Pixel * data; /* pointer to first scanline of image */ 00104 int span; /* byte offset between two scanlines */ 00105 } filter_Image; 00106 typedef struct 00107 { 00108 int pixel; 00109 double weight; 00110 } CONTRIB; 00111 typedef struct 00112 { 00113 int n; /* number of contributors */ 00114 CONTRIB *p; /* pointer to list of contributions */ 00115 } CLIST; 00116 00117 SDL_Surface* SDL_ResizeFactor(SDL_Surface *image, float scalefactor, int filter); 00118 SDL_Surface* SDL_ResizeXY(SDL_Surface *image, int new_w, int new_h, int filter); 00119 00120 static SDL_Surface *filter_resizexy(SDL_Surface* source,int new_w, int new_h, int filter); 00121 00122 static Uint32 filter_GetPixel(SDL_Surface *surface, int x, int y) 00123 { 00124 int bpp = surface->format->BytesPerPixel; 00125 /* Here p is the address to the pixel we want to retrieve */ 00126 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; 00127 00128 switch(bpp) 00129 { 00130 case 1: return *p; 00131 case 2: return *(Uint16 *)p; 00132 case 3: if(SDL_BYTEORDER == SDL_BIG_ENDIAN) 00133 return p[0] << 16 | p[1] << 8 | p[2]; 00134 else 00135 return p[0] | p[1] << 8 | p[2] << 16; 00136 case 4: return *(Uint32 *)p; 00137 default: return 0; /* shouldn't happen, but avoids warnings */ 00138 } 00139 } 00140 00141 static void filter_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) 00142 { 00143 int bpp = surface->format->BytesPerPixel; 00144 /* Here p is the address to the pixel we want to set */ 00145 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; 00146 00147 switch(bpp) 00148 { 00149 case 1: *p = pixel; 00150 break; 00151 case 2: *(Uint16 *)p = pixel; 00152 break; 00153 case 3: if(SDL_BYTEORDER == SDL_BIG_ENDIAN) 00154 { 00155 p[0] = (pixel >> 16) & 0xff; 00156 p[1] = (pixel >> 8) & 0xff; 00157 p[2] = pixel & 0xff; 00158 } 00159 else 00160 { 00161 p[0] = pixel & 0xff; 00162 p[1] = (pixel >> 8) & 0xff; 00163 p[2] = (pixel >> 16) & 0xff; 00164 } 00165 break; 00166 case 4: *(Uint32 *)p = pixel; 00167 break; 00168 } 00169 } 00170 00171 #ifdef __cplusplus 00172 SDL_Surface* SDL_Resize(SDL_Surface *image, float scalefactor, int filter) 00173 { 00174 return SDL_ResizeFactor(image, scalefactor, filter); 00175 } 00176 #endif 00177 SDL_Surface* SDL_ResizeFactor(SDL_Surface *image, float scalefactor, int filter) 00178 { 00179 int neww, newh; 00180 SDL_Surface * r; 00181 if (!image) return NULL; //invalid image passed in. 00182 if (scalefactor > 100.0f) scalefactor = 100.0f; //let's be reasonable... 00183 neww = (int)((float)image->w*scalefactor); 00184 newh = (int)((float)image->h*scalefactor); 00185 if (neww<1) neww = 1; 00186 if (newh<1) newh = 1; 00187 r = SDL_ResizeXY(image, neww, newh, filter); 00188 return r; 00189 } 00190 00191 #ifdef __cplusplus 00192 SDL_Surface* SDL_Resize(SDL_Surface *image, int new_w, int new_h, int filter) 00193 { 00194 return SDL_ResizeXY(image, new_w, new_h, filter); 00195 } 00196 #endif 00197 SDL_Surface* SDL_ResizeXY(SDL_Surface *image, int new_w, int new_h, int filter) 00198 { 00199 SDL_Surface *dest = NULL; 00200 Uint8 alpha, r, g, b; 00201 char usealpha; 00202 int cx; 00203 if (!image) return NULL; //invalid image passed in 00204 00205 if ((new_w != image->w) || (new_h != image->h)) 00206 dest = filter_resizexy(image, new_w, new_h, filter); 00207 else 00208 { 00209 SDL_FreeSurface(dest); 00210 dest = image; 00211 } 00212 00213 //check for alpha content of the image... like for buttons... 00214 00215 if (SDL_MUSTLOCK(dest)) SDL_LockSurface(dest); 00216 alpha = 0; r = 0; g = 0; b = 0; 00217 usealpha = 0; 00218 cx = 0; 00219 for (; cx < dest->w; cx++) 00220 { //check the whole image for any occurance of alpha 00221 int cy = 0; 00222 for (; cy < dest->h; cy++) 00223 { 00224 SDL_GetRGBA(filter_GetPixel(dest, cx, cy), dest->format, &r, &g, &b, &alpha); 00225 if (alpha != SDL_ALPHA_OPAQUE) {usealpha = 1; cx=dest->w; break;} 00226 } 00227 } 00228 if (SDL_MUSTLOCK(dest)) SDL_UnlockSurface(dest); 00229 00230 if (!usealpha) // no alpha component 00231 { 00232 image = SDL_DisplayFormat(dest); 00233 SDL_SetAlpha(image, SDL_RLEACCEL, 0); 00234 } 00235 else // it does have alpha 00236 { 00237 image = SDL_DisplayFormatAlpha(dest); 00238 SDL_SetAlpha(image, SDL_RLEACCEL | SDL_SRCALPHA, 0); 00239 } 00240 SDL_FreeSurface(dest); 00241 return image; 00242 } 00243 00244 static Pixel filter_get_pixel2(SDL_Surface *image, int x, int y, int which) 00245 { 00246 static Uint8 r=0, g=0, b=0, a=0; 00247 static int xx=-1, yy=-1; 00248 Pixel p = 0; 00249 00250 if((x < 0) || (x >= image->w) || (y < 0) || (y >= image->h)) 00251 return(0); 00252 00253 if ((xx!=x) || (yy!=y)) 00254 { 00255 Uint32 fullpixel; 00256 xx = x; yy = y; //this way it only calls the Getpixel,RGBA once per pixel... 00257 fullpixel = filter_GetPixel(image,x,y); 00258 SDL_GetRGBA(fullpixel,image->format,&r,&g,&b,&a); 00259 } 00260 00261 switch (which) 00262 { 00263 case 0 : p = r; break; 00264 case 1 : p = g; break; 00265 case 2 : p = b; break; 00266 case 3 : p = a; break; 00267 default: p = r; break; //not really needed... 00268 } 00269 return(p); 00270 } 00271 00272 static char filter_put_pixel2(SDL_Surface *image, int x, int y, Uint8 c[4]) 00273 { 00274 if((x < 0) || (x >= image->w) || (y < 0) || (y >= image->h)) 00275 return 0; 00276 filter_PutPixel(image,x,y,SDL_MapRGBA(image->format,c[0],c[1],c[2],c[3])); 00277 return 1; 00278 } 00279 00280 static double filter_hermite_interp(double t) 00281 { 00282 /* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */ 00283 if(t < 0.0) t = -t; 00284 if(t < 1.0) return((2.0 * t - 3.0) * t * t + 1.0); 00285 return(0.0); 00286 } 00287 00288 static double filter_box_interp(double t) 00289 { 00290 if((t > -0.5) && (t <= 0.5)) return(1.0); 00291 return(0.0); 00292 } 00293 00294 static double filter_triangle_interp(double t) 00295 { 00296 if(t < 0.0) t = -t; 00297 if(t < 1.0) return(1.0 - t); 00298 return(0.0); 00299 } 00300 00301 static double filter_bell_interp(double t) /* box (*) box (*) box */ 00302 { 00303 if(t < 0) t = -t; 00304 if(t < .5) return(.75 - (t * t)); 00305 if(t < 1.5) { 00306 t = (t - 1.5); 00307 return(.5 * (t * t)); 00308 } 00309 return(0.0); 00310 } 00311 00312 static double filter_B_spline_interp(double t) /* box (*) box (*) box (*) box */ 00313 { 00314 double tt; 00315 00316 if(t < 0) t = -t; 00317 if(t < 1) { 00318 tt = t * t; 00319 return((.5 * tt * t) - tt + (2.0 / 3.0)); 00320 } else if(t < 2) { 00321 t = 2 - t; 00322 return((1.0 / 6.0) * (t * t * t)); 00323 } 00324 return(0.0); 00325 } 00326 00327 static double filter_sinc(double x) 00328 { 00329 x *= M_PI; 00330 if(x != 0) return(sin(x) / x); 00331 return(1.0); 00332 } 00333 00334 static double filter_Lanczos3_interp(double t) 00335 { 00336 if(t < 0) t = -t; 00337 if(t < 3.0) return(filter_sinc(t) * filter_sinc(t/3.0)); 00338 return(0.0); 00339 } 00340 00341 static double filter_Mitchell_interp(double t) 00342 { 00343 static double B = (1.0 / 3.0); 00344 static double C = (1.0 / 3.0); 00345 double tt; 00346 00347 tt = t * t; 00348 if(t < 0) t = -t; 00349 if(t < 1.0) { 00350 t = (((12.0 - 9.0 * B - 6.0 * C) * (t * tt)) 00351 + ((-18.0 + 12.0 * B + 6.0 * C) * tt) 00352 + (6.0 - 2 * B)); 00353 return(t / 6.0); 00354 } else if(t < 2.0) { 00355 t = (((-1.0 * B - 6.0 * C) * (t * tt)) 00356 + ((6.0 * B + 30.0 * C) * tt) 00357 + ((-12.0 * B - 48.0 * C) * t) 00358 + (8.0 * B + 24 * C)); 00359 return(t / 6.0); 00360 } 00361 return(0.0); 00362 } 00363 00364 static int filter_roundcloser(double d) 00365 { 00366 /* Untested potential one-liner, but smacks of call overhead */ 00367 /* return fabs(ceil(d)-d) <= 0.5 ? ceil(d) : floor(d); */ 00368 00369 /* Untested potential optimized ceil() usage */ 00370 /* double cd = ceil(d); 00371 int ncd = (int)cd; 00372 if(fabs(cd - d) > 0.5) 00373 ncd--; 00374 return ncd; 00375 */ 00376 00377 /* Version that uses no function calls at all. */ 00378 int n = (int) d; 00379 double diff = d - (double)n; 00380 if(diff < 0) 00381 diff = -diff; 00382 if(diff >= 0.5) 00383 { 00384 if(d < 0) 00385 n--; 00386 else 00387 n++; 00388 } 00389 return n; 00390 } /* filter_roundcloser */ 00391 00392 static int filter_calc_x_contrib(CLIST *contribX, double xscale, double fwidth, 00393 int dstwidth, int srcwidth, double (*filterf)(double), int i) 00394 { 00395 double width; 00396 double fscale; 00397 double center, left, right; 00398 double weight; 00399 int j, k, n; 00400 00401 if(xscale < 1.0) 00402 { 00403 /* Shrinking image */ 00404 width = fwidth / xscale; 00405 fscale = 1.0 / xscale; 00406 00407 contribX->n = 0; 00408 contribX->p = (CONTRIB *)calloc((int) (width * 2 + 1), 00409 sizeof(CONTRIB)); 00410 if(contribX->p == NULL) 00411 return -1; 00412 00413 center = (double) i / xscale; 00414 left = ceil(center - width); 00415 right = floor(center + width); 00416 for(j = (int)left; j <= right; ++j) 00417 { 00418 weight = center - (double) j; 00419 weight = ((*filterf)(weight / fscale)) / fscale; 00420 if(j < 0) 00421 n = -j; 00422 else if(j >= srcwidth) 00423 n = (srcwidth - j) + srcwidth - 1; 00424 else 00425 n = j; 00426 00427 k = contribX->n++; 00428 contribX->p[k].pixel = n; 00429 contribX->p[k].weight = weight; 00430 } 00431 00432 } 00433 else 00434 { 00435 /* Expanding image */ 00436 contribX->n = 0; 00437 contribX->p = (CONTRIB *)calloc((int) (fwidth * 2 + 1), 00438 sizeof(CONTRIB)); 00439 if(contribX->p == NULL) 00440 return -1; 00441 center = (double) i / xscale; 00442 left = ceil(center - fwidth); 00443 right = floor(center + fwidth); 00444 00445 for(j = (int)left; j <= right; ++j) 00446 { 00447 weight = center - (double) j; 00448 weight = (*filterf)(weight); 00449 if(j < 0) { 00450 n = -j; 00451 } else if(j >= srcwidth) { 00452 n = (srcwidth - j) + srcwidth - 1; 00453 } else { 00454 n = j; 00455 } 00456 k = contribX->n++; 00457 contribX->p[k].pixel = n; 00458 contribX->p[k].weight = weight; 00459 } 00460 } 00461 return 0; 00462 } /* filter_calc_x_contrib */ 00463 00464 static int filter_zoom2(SDL_Surface *dst, SDL_Surface *src, double (*filterf)(double), double fwidth) 00465 { 00466 Pixel* tmp; 00467 double xscale, yscale; /* zoom scale factors */ 00468 int xx; 00469 int i, j, k; /* loop variables */ 00470 int n; /* pixel number */ 00471 double center, left, right; /* filter calculation variables */ 00472 double width, fscale, weight; /* filter calculation variables */ 00473 Uint8 weightedcolor[4]; //reconstruct the pixel out of these! 00474 Pixel pel, pel2; 00475 int bPelDelta; 00476 CLIST *contribY; /* array of contribution lists */ 00477 CLIST contribX; 00478 int nRet = -1; 00479 00480 /* create intermediate column to hold horizontal dst column zoom */ 00481 tmp = (Pixel*)malloc(src->h * sizeof(Pixel) * 4); 00482 if(tmp == NULL) 00483 return 0; 00484 00485 xscale = (double) dst->w / (double) src->w; 00486 00487 /* Build y weights */ 00488 /* pre-calculate filter contributions for a column */ 00489 contribY = (CLIST *)calloc(dst->h, sizeof(CLIST)); 00490 if(contribY == NULL) 00491 { 00492 free(tmp); 00493 return -1; 00494 } 00495 00496 yscale = (double) dst->h / (double) src->h; 00497 00498 if(yscale < 1.0) 00499 { 00500 width = fwidth / yscale; 00501 fscale = 1.0 / yscale; 00502 for(i = 0; i < dst->h; ++i) 00503 { 00504 contribY[i].n = 0; 00505 contribY[i].p = (CONTRIB *)calloc((int) (width * 2 + 1), 00506 sizeof(CONTRIB)); 00507 if(contribY[i].p == NULL) 00508 { 00509 free(tmp); 00510 free(contribY); 00511 return -1; 00512 } 00513 center = (double) i / yscale; 00514 left = ceil(center - width); 00515 right = floor(center + width); 00516 for(j = (int)left; j <= right; ++j) { 00517 weight = center - (double) j; 00518 weight = (*filterf)(weight / fscale) / fscale; 00519 if(j < 0) { 00520 n = -j; 00521 } else if(j >= src->h) { 00522 n = (src->h - j) + src->h - 1; 00523 } else { 00524 n = j; 00525 } 00526 k = contribY[i].n++; 00527 contribY[i].p[k].pixel = n; 00528 contribY[i].p[k].weight = weight; 00529 } 00530 } 00531 } else { 00532 for(i = 0; i < dst->h; ++i) { 00533 contribY[i].n = 0; 00534 contribY[i].p = (CONTRIB *)calloc((int) (fwidth * 2 + 1), 00535 sizeof(CONTRIB)); 00536 if(contribY[i].p == NULL) 00537 { 00538 free(tmp); 00539 free(contribY); 00540 return -1; 00541 } 00542 center = (double) i / yscale; 00543 left = ceil(center - fwidth); 00544 right = floor(center + fwidth); 00545 for(j = (int)left; j <= right; ++j) { 00546 weight = center - (double) j; 00547 weight = (*filterf)(weight); 00548 if(j < 0) { 00549 n = -j; 00550 } else if(j >= src->h) { 00551 n = (src->h - j) + src->h - 1; 00552 } else { 00553 n = j; 00554 } 00555 k = contribY[i].n++; 00556 contribY[i].p[k].pixel = n; 00557 contribY[i].p[k].weight = weight; 00558 } 00559 } 00560 } 00561 00562 00563 00564 for(xx = 0; xx < dst->w; xx++) 00565 { 00566 if(0 != filter_calc_x_contrib(&contribX, xscale, fwidth, 00567 dst->w, src->w, filterf, xx)) 00568 { 00569 goto __zoom_cleanup; 00570 } 00571 /* Apply horz filter to make dst column in tmp. */ 00572 for(k = 0; k < src->h; ++k) 00573 { 00574 //mine!!!! 00575 int w=0; 00576 for (; w<4; w++) { 00577 weight = 0.0; 00578 bPelDelta = 0; 00579 pel = filter_get_pixel2(src, contribX.p[0].pixel, k, w); 00580 for(j = 0; j < contribX.n; ++j) 00581 { 00582 pel2 = filter_get_pixel2(src, contribX.p[j].pixel, k, w); 00583 if(pel2 != pel) 00584 bPelDelta = 1; 00585 weight += pel2 * contribX.p[j].weight; 00586 } 00587 weight = bPelDelta ? filter_roundcloser(weight) : pel; 00588 00589 tmp[k+w*src->h] = (Pixel)CLAMP(weight, 0, 255); // keep it Uint8 00590 } //cycle through each color... 00591 } /* next row in temp column */ 00592 00593 free(contribX.p); 00594 00595 00596 /* The temp column has been built. Now stretch it 00597 vertically into dst column. */ 00598 for(i = 0; i < dst->h; ++i) 00599 { 00600 int w=0; 00601 for (; w<4; w++) { 00602 weight = 0.0; 00603 bPelDelta = 0; 00604 pel = tmp[contribY[i].p[0].pixel+w*src->h]; 00605 00606 for(j = 0; j < contribY[i].n; ++j) 00607 { 00608 pel2 = tmp[contribY[i].p[j].pixel+w*src->h]; 00609 if(pel2 != pel) 00610 bPelDelta = 1; 00611 weight += pel2 * contribY[i].p[j].weight; 00612 } 00613 weight = bPelDelta ? filter_roundcloser(weight) : pel; 00614 weightedcolor[w] = (Uint8)CLAMP(weight, 0, 255); //get all 4 "colors" this way 00615 } 00616 filter_put_pixel2(dst, xx, i, weightedcolor ); //keep it Uint8 00617 } /* next dst row */ 00618 00619 } /* next dst column */ 00620 nRet = 0; /* success */ 00621 00622 __zoom_cleanup: 00623 free(tmp); 00624 00625 /* free the memory allocated for vertical filter weights */ 00626 for(i = 0; i < dst->h; ++i) 00627 free(contribY[i].p); 00628 free(contribY); 00629 00630 return nRet; 00631 } /* zoom */ 00632 00633 static SDL_Surface *filter_resizexy(SDL_Surface* source,int new_w, int new_h, int filter) 00634 { 00635 //f and s need to be complementary... one as filter, one as support. 00636 double (*f)(double) ; //function pointer 00637 double s; //support 00638 SDL_Surface *temp, *dest; 00639 00640 const double box_support = 0.5, 00641 triangle_support = 1.0, 00642 bell_support = 1.5, 00643 B_spline_support = 2.0, 00644 hermite_support = 1.0, 00645 Mitchell_support = 2.0, 00646 Lanczos3_support = 3.0; 00647 00648 switch (filter) 00649 { 00650 case 1 : f=filter_box_interp; s=box_support; break; 00651 case 2 : f=filter_triangle_interp; s=triangle_support; break; 00652 case 3 : f=filter_bell_interp; s=bell_support; break; 00653 case 4 : f=filter_hermite_interp; s=hermite_support; break; 00654 case 5 : f=filter_B_spline_interp; s=B_spline_support; break; 00655 case 6 : f=filter_Mitchell_interp; s=Mitchell_support; break; 00656 case 7 : f=filter_Lanczos3_interp; s=Lanczos3_support; break; 00657 default: f=filter_Lanczos3_interp; s=Lanczos3_support; break; 00658 } 00659 00660 //Make new surface and send it in to the real filter 00661 temp = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, 00662 new_w, new_h, 32,0,0,0,0) , 00663 dest = SDL_DisplayFormatAlpha(temp); 00664 00665 SDL_FreeSurface(temp); 00666 00667 if (SDL_MUSTLOCK(source)) SDL_LockSurface(source); 00668 if (SDL_MUSTLOCK(dest)) SDL_LockSurface(dest); 00669 00670 filter_zoom2(dest, source, f, s ); 00671 00672 if (SDL_MUSTLOCK(dest)) SDL_UnlockSurface(dest); 00673 if (SDL_MUSTLOCK(source)) SDL_UnlockSurface(source); 00674 00675 //SDL_FreeSurface(source); 00676 //should be all cleaned up! 00677 *source=*dest ; 00678 00679 dest = NULL; 00680 SDL_FreeSurface(dest); 00681 return source; 00682 } 00683