Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 * allocimbuf.c 00027 * 00028 */ 00029 00035 #include "BLI_blenlib.h" 00036 #include "BLI_utildefines.h" 00037 #include "MEM_guardedalloc.h" 00038 00039 #include "imbuf.h" 00040 #include "IMB_imbuf_types.h" 00041 #include "IMB_imbuf.h" 00042 00043 #include "IMB_allocimbuf.h" 00044 #include "IMB_filter.h" 00045 00046 #include "BLO_sys_types.h" // for intptr_t support 00047 00048 /************************************************************************/ 00049 /* SCALING */ 00050 /************************************************************************/ 00051 00052 00053 struct ImBuf *IMB_half_x(struct ImBuf *ibuf1) 00054 { 00055 struct ImBuf *ibuf2; 00056 uchar *p1,*_p1,*dest; 00057 short a,r,g,b; 00058 int x,y; 00059 float af,rf,gf,bf, *p1f, *_p1f, *destf; 00060 int do_rect, do_float; 00061 00062 if (ibuf1==NULL) return (NULL); 00063 if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (NULL); 00064 00065 do_rect= (ibuf1->rect != NULL); 00066 do_float= (ibuf1->rect_float != NULL); 00067 00068 if (ibuf1->x <= 1) return(IMB_dupImBuf(ibuf1)); 00069 00070 ibuf2 = IMB_allocImBuf((ibuf1->x)/2, ibuf1->y, ibuf1->planes, ibuf1->flags); 00071 if (ibuf2==NULL) return (NULL); 00072 00073 _p1 = (uchar *) ibuf1->rect; 00074 dest=(uchar *) ibuf2->rect; 00075 00076 _p1f = ibuf1->rect_float; 00077 destf= ibuf2->rect_float; 00078 00079 for(y=ibuf2->y;y>0;y--){ 00080 p1 = _p1; 00081 p1f = _p1f; 00082 for(x = ibuf2->x ; x>0 ; x--){ 00083 if (do_rect) { 00084 a = *(p1++) ; 00085 b = *(p1++) ; 00086 g = *(p1++) ; 00087 r = *(p1++); 00088 a += *(p1++) ; 00089 b += *(p1++) ; 00090 g += *(p1++) ; 00091 r += *(p1++); 00092 *(dest++) = a >> 1; 00093 *(dest++) = b >> 1; 00094 *(dest++) = g >> 1; 00095 *(dest++) = r >> 1; 00096 } 00097 if (do_float) { 00098 af = *(p1f++); 00099 bf = *(p1f++); 00100 gf = *(p1f++); 00101 rf = *(p1f++); 00102 af += *(p1f++); 00103 bf += *(p1f++); 00104 gf += *(p1f++); 00105 rf += *(p1f++); 00106 *(destf++) = 0.5f*af; 00107 *(destf++) = 0.5f*bf; 00108 *(destf++) = 0.5f*gf; 00109 *(destf++) = 0.5f*rf; 00110 } 00111 } 00112 if (do_rect) _p1 += (ibuf1->x << 2); 00113 if (do_float) _p1f += (ibuf1->x << 2); 00114 } 00115 return (ibuf2); 00116 } 00117 00118 00119 struct ImBuf *IMB_double_fast_x(struct ImBuf *ibuf1) 00120 { 00121 struct ImBuf *ibuf2; 00122 int *p1,*dest, i, col, do_rect, do_float; 00123 float *p1f, *destf; 00124 00125 if (ibuf1==NULL) return (NULL); 00126 if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (NULL); 00127 00128 do_rect= (ibuf1->rect != NULL); 00129 do_float= (ibuf1->rect_float != NULL); 00130 00131 ibuf2 = IMB_allocImBuf(2 * ibuf1->x , ibuf1->y , ibuf1->planes, ibuf1->flags); 00132 if (ibuf2==NULL) return (NULL); 00133 00134 p1 = (int *) ibuf1->rect; 00135 dest=(int *) ibuf2->rect; 00136 p1f = (float *)ibuf1->rect_float; 00137 destf = (float *)ibuf2->rect_float; 00138 00139 for(i = ibuf1->y * ibuf1->x ; i>0 ; i--) { 00140 if (do_rect) { 00141 col = *p1++; 00142 *dest++ = col; 00143 *dest++ = col; 00144 } 00145 if (do_float) { 00146 destf[0]= destf[4] =p1f[0]; 00147 destf[1]= destf[5] =p1f[1]; 00148 destf[2]= destf[6] =p1f[2]; 00149 destf[3]= destf[7] =p1f[3]; 00150 destf+= 8; 00151 p1f+= 4; 00152 } 00153 } 00154 00155 return (ibuf2); 00156 } 00157 00158 struct ImBuf *IMB_double_x(struct ImBuf *ibuf1) 00159 { 00160 struct ImBuf *ibuf2; 00161 00162 if (ibuf1==NULL) return (NULL); 00163 if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (NULL); 00164 00165 ibuf2 = IMB_double_fast_x(ibuf1); 00166 00167 imb_filterx(ibuf2); 00168 return (ibuf2); 00169 } 00170 00171 00172 struct ImBuf *IMB_half_y(struct ImBuf *ibuf1) 00173 { 00174 struct ImBuf *ibuf2; 00175 uchar *p1,*p2,*_p1,*dest; 00176 short a,r,g,b; 00177 int x,y; 00178 int do_rect, do_float; 00179 float af,rf,gf,bf,*p1f,*p2f,*_p1f,*destf; 00180 00181 p1= p2= NULL; 00182 p1f= p2f= NULL; 00183 if (ibuf1==NULL) return (NULL); 00184 if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (NULL); 00185 if (ibuf1->y <= 1) return(IMB_dupImBuf(ibuf1)); 00186 00187 do_rect= (ibuf1->rect != NULL); 00188 do_float= (ibuf1->rect_float != NULL); 00189 00190 ibuf2 = IMB_allocImBuf(ibuf1->x , (ibuf1->y) / 2 , ibuf1->planes, ibuf1->flags); 00191 if (ibuf2==NULL) return (NULL); 00192 00193 _p1 = (uchar *) ibuf1->rect; 00194 dest=(uchar *) ibuf2->rect; 00195 _p1f = (float *) ibuf1->rect_float; 00196 destf= (float *) ibuf2->rect_float; 00197 00198 for(y=ibuf2->y ; y>0 ; y--){ 00199 if (do_rect) { 00200 p1 = _p1; 00201 p2 = _p1 + (ibuf1->x << 2); 00202 } 00203 if (do_float) { 00204 p1f = _p1f; 00205 p2f = _p1f + (ibuf1->x << 2); 00206 } 00207 for(x = ibuf2->x ; x>0 ; x--){ 00208 if (do_rect) { 00209 a = *(p1++) ; 00210 b = *(p1++) ; 00211 g = *(p1++) ; 00212 r = *(p1++); 00213 a += *(p2++) ; 00214 b += *(p2++) ; 00215 g += *(p2++) ; 00216 r += *(p2++); 00217 *(dest++) = a >> 1; 00218 *(dest++) = b >> 1; 00219 *(dest++) = g >> 1; 00220 *(dest++) = r >> 1; 00221 } 00222 if (do_float) { 00223 af = *(p1f++) ; 00224 bf = *(p1f++) ; 00225 gf = *(p1f++) ; 00226 rf = *(p1f++); 00227 af += *(p2f++) ; 00228 bf += *(p2f++) ; 00229 gf += *(p2f++) ; 00230 rf += *(p2f++); 00231 *(destf++) = 0.5f*af; 00232 *(destf++) = 0.5f*bf; 00233 *(destf++) = 0.5f*gf; 00234 *(destf++) = 0.5f*rf; 00235 } 00236 } 00237 if (do_rect) _p1 += (ibuf1->x << 3); 00238 if (do_float) _p1f += (ibuf1->x << 3); 00239 } 00240 return (ibuf2); 00241 } 00242 00243 00244 struct ImBuf *IMB_double_fast_y(struct ImBuf *ibuf1) 00245 { 00246 struct ImBuf *ibuf2; 00247 int *p1, *dest1, *dest2; 00248 float *p1f, *dest1f, *dest2f; 00249 int x,y; 00250 int do_rect, do_float; 00251 00252 if (ibuf1==NULL) return (NULL); 00253 if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (NULL); 00254 00255 do_rect= (ibuf1->rect != NULL); 00256 do_float= (ibuf1->rect_float != NULL); 00257 00258 ibuf2 = IMB_allocImBuf(ibuf1->x , 2 * ibuf1->y , ibuf1->planes, ibuf1->flags); 00259 if (ibuf2==NULL) return (NULL); 00260 00261 p1 = (int *) ibuf1->rect; 00262 dest1= (int *) ibuf2->rect; 00263 p1f = (float *) ibuf1->rect_float; 00264 dest1f= (float *) ibuf2->rect_float; 00265 00266 for(y = ibuf1->y ; y>0 ; y--){ 00267 if (do_rect) { 00268 dest2 = dest1 + ibuf2->x; 00269 for(x = ibuf2->x ; x>0 ; x--) *dest1++ = *dest2++ = *p1++; 00270 dest1 = dest2; 00271 } 00272 if (do_float) { 00273 dest2f = dest1f + (4*ibuf2->x); 00274 for(x = ibuf2->x*4 ; x>0 ; x--) *dest1f++ = *dest2f++ = *p1f++; 00275 dest1f = dest2f; 00276 } 00277 } 00278 00279 return (ibuf2); 00280 } 00281 00282 struct ImBuf *IMB_double_y(struct ImBuf *ibuf1) 00283 { 00284 struct ImBuf *ibuf2; 00285 00286 if (ibuf1==NULL) return (NULL); 00287 if (ibuf1->rect==NULL) return (NULL); 00288 00289 ibuf2 = IMB_double_fast_y(ibuf1); 00290 00291 IMB_filtery(ibuf2); 00292 return (ibuf2); 00293 } 00294 00295 /* result in ibuf2, scaling should be done correctly */ 00296 void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1) 00297 { 00298 uchar *p1, *p2 = NULL, *dest; 00299 float *p1f, *destf, *p2f = NULL; 00300 int x,y; 00301 const short do_rect= (ibuf1->rect != NULL); 00302 const short do_float= (ibuf1->rect_float != NULL) && (ibuf2->rect_float != NULL); 00303 00304 if(do_rect && (ibuf2->rect == NULL)) { 00305 imb_addrectImBuf(ibuf2); 00306 } 00307 00308 p1f = ibuf1->rect_float; 00309 destf=ibuf2->rect_float; 00310 p1 = (uchar *) ibuf1->rect; 00311 dest=(uchar *) ibuf2->rect; 00312 00313 for(y=ibuf2->y;y>0;y--){ 00314 if (do_rect) p2 = p1 + (ibuf1->x << 2); 00315 if (do_float) p2f = p1f + (ibuf1->x << 2); 00316 for(x=ibuf2->x;x>0;x--){ 00317 if (do_rect) { 00318 dest[0] = (p1[0] + p2[0] + p1[4] + p2[4]) >> 2; 00319 dest[1] = (p1[1] + p2[1] + p1[5] + p2[5]) >> 2; 00320 dest[2] = (p1[2] + p2[2] + p1[6] + p2[6]) >> 2; 00321 dest[3] = (p1[3] + p2[3] + p1[7] + p2[7]) >> 2; 00322 p1 += 8; 00323 p2 += 8; 00324 dest += 4; 00325 } 00326 if (do_float){ 00327 destf[0] = 0.25f*(p1f[0] + p2f[0] + p1f[4] + p2f[4]); 00328 destf[1] = 0.25f*(p1f[1] + p2f[1] + p1f[5] + p2f[5]); 00329 destf[2] = 0.25f*(p1f[2] + p2f[2] + p1f[6] + p2f[6]); 00330 destf[3] = 0.25f*(p1f[3] + p2f[3] + p1f[7] + p2f[7]); 00331 p1f += 8; 00332 p2f += 8; 00333 destf += 4; 00334 } 00335 } 00336 if (do_rect) p1=p2; 00337 if (do_float) p1f=p2f; 00338 if(ibuf1->x & 1) { 00339 if (do_rect) p1+=4; 00340 if (do_float) p1f+=4; 00341 } 00342 } 00343 00344 } 00345 00346 struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1) 00347 { 00348 struct ImBuf *ibuf2; 00349 00350 if (ibuf1==NULL) return (NULL); 00351 if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (NULL); 00352 00353 if (ibuf1->x <= 1) return(IMB_half_y(ibuf1)); 00354 if (ibuf1->y <= 1) return(IMB_half_x(ibuf1)); 00355 00356 ibuf2=IMB_allocImBuf((ibuf1->x)/2, (ibuf1->y)/2, ibuf1->planes, ibuf1->flags); 00357 if (ibuf2==NULL) return (NULL); 00358 00359 imb_onehalf_no_alloc(ibuf2, ibuf1); 00360 00361 return (ibuf2); 00362 } 00363 00364 /* q_scale_linear_interpolation helper functions */ 00365 00366 static void enlarge_picture_byte( 00367 unsigned char* src, unsigned char* dst, int src_width, 00368 int src_height, int dst_width, int dst_height) 00369 { 00370 double ratiox = (double) (dst_width - 1.0) 00371 / (double) (src_width - 1.001); 00372 double ratioy = (double) (dst_height - 1.0) 00373 / (double) (src_height - 1.001); 00374 uintptr_t x_src, dx_src, x_dst; 00375 uintptr_t y_src, dy_src, y_dst; 00376 00377 dx_src = 65536.0 / ratiox; 00378 dy_src = 65536.0 / ratioy; 00379 00380 y_src = 0; 00381 for (y_dst = 0; y_dst < dst_height; y_dst++) { 00382 unsigned char* line1 = src + (y_src >> 16) * 4 * src_width; 00383 unsigned char* line2 = line1 + 4 * src_width; 00384 uintptr_t weight1y = 65536 - (y_src & 0xffff); 00385 uintptr_t weight2y = 65536 - weight1y; 00386 00387 if ((y_src >> 16) == src_height - 1) { 00388 line2 = line1; 00389 } 00390 00391 x_src = 0; 00392 for (x_dst = 0; x_dst < dst_width; x_dst++) { 00393 uintptr_t weight1x = 65536 - (x_src & 0xffff); 00394 uintptr_t weight2x = 65536 - weight1x; 00395 00396 unsigned long x = (x_src >> 16) * 4; 00397 00398 *dst++ = ((((line1[x] * weight1y) >> 16) 00399 * weight1x) >> 16) 00400 + ((((line2[x] * weight2y) >> 16) 00401 * weight1x) >> 16) 00402 + ((((line1[4 + x] * weight1y) >> 16) 00403 * weight2x) >> 16) 00404 + ((((line2[4 + x] * weight2y) >> 16) 00405 * weight2x) >> 16); 00406 00407 *dst++ = ((((line1[x + 1] * weight1y) >> 16) 00408 * weight1x) >> 16) 00409 + ((((line2[x + 1] * weight2y) >> 16) 00410 * weight1x) >> 16) 00411 + ((((line1[4 + x + 1] * weight1y) >> 16) 00412 * weight2x) >> 16) 00413 + ((((line2[4 + x + 1] * weight2y) >> 16) 00414 * weight2x) >> 16); 00415 00416 *dst++ = ((((line1[x + 2] * weight1y) >> 16) 00417 * weight1x) >> 16) 00418 + ((((line2[x + 2] * weight2y) >> 16) 00419 * weight1x) >> 16) 00420 + ((((line1[4 + x + 2] * weight1y) >> 16) 00421 * weight2x) >> 16) 00422 + ((((line2[4 + x + 2] * weight2y) >> 16) 00423 * weight2x) >> 16); 00424 00425 *dst++ = ((((line1[x + 3] * weight1y) >> 16) 00426 * weight1x) >> 16) 00427 + ((((line2[x + 3] * weight2y) >> 16) 00428 * weight1x) >> 16) 00429 + ((((line1[4 + x + 3] * weight1y) >> 16) 00430 * weight2x) >> 16) 00431 + ((((line2[4 + x + 3] * weight2y) >> 16) 00432 * weight2x) >> 16); 00433 00434 x_src += dx_src; 00435 } 00436 y_src += dy_src; 00437 } 00438 } 00439 00440 struct scale_outpix_byte { 00441 uintptr_t r; 00442 uintptr_t g; 00443 uintptr_t b; 00444 uintptr_t a; 00445 00446 uintptr_t weight; 00447 }; 00448 00449 static void shrink_picture_byte( 00450 unsigned char* src, unsigned char* dst, int src_width, 00451 int src_height, int dst_width, int dst_height) 00452 { 00453 double ratiox = (double) (dst_width) / (double) (src_width); 00454 double ratioy = (double) (dst_height) / (double) (src_height); 00455 uintptr_t x_src, dx_dst, x_dst; 00456 uintptr_t y_src, dy_dst, y_dst; 00457 intptr_t y_counter; 00458 unsigned char * dst_begin = dst; 00459 00460 struct scale_outpix_byte * dst_line1 = NULL; 00461 struct scale_outpix_byte * dst_line2 = NULL; 00462 00463 dst_line1 = (struct scale_outpix_byte*) MEM_callocN( 00464 (dst_width + 1) * sizeof(struct scale_outpix_byte), 00465 "shrink_picture_byte 1"); 00466 dst_line2 = (struct scale_outpix_byte*) MEM_callocN( 00467 (dst_width + 1) * sizeof(struct scale_outpix_byte), 00468 "shrink_picture_byte 2"); 00469 00470 dx_dst = 65536.0 * ratiox; 00471 dy_dst = 65536.0 * ratioy; 00472 00473 y_dst = 0; 00474 y_counter = 65536; 00475 for (y_src = 0; y_src < src_height; y_src++) { 00476 unsigned char* line = src + y_src * 4 * src_width; 00477 uintptr_t weight1y = 65535 - (y_dst & 0xffff); 00478 uintptr_t weight2y = 65535 - weight1y; 00479 x_dst = 0; 00480 for (x_src = 0; x_src < src_width; x_src++) { 00481 uintptr_t weight1x = 65535 - (x_dst & 0xffff); 00482 uintptr_t weight2x = 65535 - weight1x; 00483 00484 uintptr_t x = x_dst >> 16; 00485 00486 uintptr_t w; 00487 00488 w = (weight1y * weight1x) >> 16; 00489 00490 /* ensure correct rounding, without this you get ugly banding, or too low color values (ton) */ 00491 dst_line1[x].r += (line[0] * w + 32767) >> 16; 00492 dst_line1[x].g += (line[1] * w + 32767) >> 16; 00493 dst_line1[x].b += (line[2] * w + 32767) >> 16; 00494 dst_line1[x].a += (line[3] * w + 32767) >> 16; 00495 dst_line1[x].weight += w; 00496 00497 w = (weight2y * weight1x) >> 16; 00498 00499 dst_line2[x].r += (line[0] * w + 32767) >> 16; 00500 dst_line2[x].g += (line[1] * w + 32767) >> 16; 00501 dst_line2[x].b += (line[2] * w + 32767) >> 16; 00502 dst_line2[x].a += (line[3] * w + 32767) >> 16; 00503 dst_line2[x].weight += w; 00504 00505 w = (weight1y * weight2x) >> 16; 00506 00507 dst_line1[x+1].r += (line[0] * w + 32767) >> 16; 00508 dst_line1[x+1].g += (line[1] * w + 32767) >> 16; 00509 dst_line1[x+1].b += (line[2] * w + 32767) >> 16; 00510 dst_line1[x+1].a += (line[3] * w + 32767) >> 16; 00511 dst_line1[x+1].weight += w; 00512 00513 w = (weight2y * weight2x) >> 16; 00514 00515 dst_line2[x+1].r += (line[0] * w + 32767) >> 16; 00516 dst_line2[x+1].g += (line[1] * w + 32767) >> 16; 00517 dst_line2[x+1].b += (line[2] * w + 32767) >> 16; 00518 dst_line2[x+1].a += (line[3] * w + 32767) >> 16; 00519 dst_line2[x+1].weight += w; 00520 00521 x_dst += dx_dst; 00522 line += 4; 00523 } 00524 00525 y_dst += dy_dst; 00526 y_counter -= dy_dst; 00527 if (y_counter < 0) { 00528 int val; 00529 uintptr_t x; 00530 struct scale_outpix_byte * temp; 00531 00532 y_counter += 65536; 00533 00534 for (x=0; x < dst_width; x++) { 00535 uintptr_t f = 0x80000000UL / dst_line1[x].weight; 00536 *dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val; 00537 *dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val; 00538 *dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val; 00539 *dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val; 00540 } 00541 memset(dst_line1, 0, dst_width * 00542 sizeof(struct scale_outpix_byte)); 00543 temp = dst_line1; 00544 dst_line1 = dst_line2; 00545 dst_line2 = temp; 00546 } 00547 } 00548 if (dst - dst_begin < dst_width * dst_height * 4) { 00549 int val; 00550 uintptr_t x; 00551 for (x = 0; x < dst_width; x++) { 00552 uintptr_t f = 0x80000000UL / dst_line1[x].weight; 00553 *dst++ = (val= (dst_line1[x].r * f) >> 15) > 255 ? 255: val; 00554 *dst++ = (val= (dst_line1[x].g * f) >> 15) > 255 ? 255: val; 00555 *dst++ = (val= (dst_line1[x].b * f) >> 15) > 255 ? 255: val; 00556 *dst++ = (val= (dst_line1[x].a * f) >> 15) > 255 ? 255: val; 00557 } 00558 } 00559 MEM_freeN(dst_line1); 00560 MEM_freeN(dst_line2); 00561 } 00562 00563 00564 static void q_scale_byte(unsigned char* in, unsigned char* out, int in_width, 00565 int in_height, int dst_width, int dst_height) 00566 { 00567 if (dst_width > in_width && dst_height > in_height) { 00568 enlarge_picture_byte(in, out, in_width, in_height, 00569 dst_width, dst_height); 00570 } else if (dst_width < in_width && dst_height < in_height) { 00571 shrink_picture_byte(in, out, in_width, in_height, 00572 dst_width, dst_height); 00573 } 00574 } 00575 00576 static void enlarge_picture_float( 00577 float* src, float* dst, int src_width, 00578 int src_height, int dst_width, int dst_height) 00579 { 00580 double ratiox = (double) (dst_width - 1.0) 00581 / (double) (src_width - 1.001); 00582 double ratioy = (double) (dst_height - 1.0) 00583 / (double) (src_height - 1.001); 00584 uintptr_t x_dst; 00585 uintptr_t y_dst; 00586 double x_src, dx_src; 00587 double y_src, dy_src; 00588 00589 dx_src = 1.0 / ratiox; 00590 dy_src = 1.0 / ratioy; 00591 00592 y_src = 0; 00593 for (y_dst = 0; y_dst < dst_height; y_dst++) { 00594 float* line1 = src + ((int) y_src) * 4 * src_width; 00595 float* line2 = line1 + 4 * src_width; 00596 const float weight1y = (float)(1.0 - (y_src - (int) y_src)); 00597 const float weight2y = 1.0f - weight1y; 00598 00599 if ((int) y_src == src_height - 1) { 00600 line2 = line1; 00601 } 00602 00603 x_src = 0; 00604 for (x_dst = 0; x_dst < dst_width; x_dst++) { 00605 const float weight1x = (float)(1.0 - (x_src - (int) x_src)); 00606 const float weight2x = (float)(1.0f - weight1x); 00607 00608 const float w11 = weight1y * weight1x; 00609 const float w21 = weight2y * weight1x; 00610 const float w12 = weight1y * weight2x; 00611 const float w22 = weight2y * weight2x; 00612 00613 uintptr_t x = ((int) x_src) * 4; 00614 00615 *dst++ = line1[x] * w11 00616 + line2[x] * w21 00617 + line1[4 + x] * w12 00618 + line2[4 + x] * w22; 00619 00620 *dst++ = line1[x + 1] * w11 00621 + line2[x + 1] * w21 00622 + line1[4 + x + 1] * w12 00623 + line2[4 + x + 1] * w22; 00624 00625 *dst++ = line1[x + 2] * w11 00626 + line2[x + 2] * w21 00627 + line1[4 + x + 2] * w12 00628 + line2[4 + x + 2] * w22; 00629 00630 *dst++ = line1[x + 3] * w11 00631 + line2[x + 3] * w21 00632 + line1[4 + x + 3] * w12 00633 + line2[4 + x + 3] * w22; 00634 00635 x_src += dx_src; 00636 } 00637 y_src += dy_src; 00638 } 00639 } 00640 00641 struct scale_outpix_float { 00642 float r; 00643 float g; 00644 float b; 00645 float a; 00646 00647 float weight; 00648 }; 00649 00650 static void shrink_picture_float( 00651 float* src, float* dst, int src_width, 00652 int src_height, int dst_width, int dst_height) 00653 { 00654 double ratiox = (double) (dst_width) / (double) (src_width); 00655 double ratioy = (double) (dst_height) / (double) (src_height); 00656 uintptr_t x_src; 00657 uintptr_t y_src; 00658 float dx_dst, x_dst; 00659 float dy_dst, y_dst; 00660 float y_counter; 00661 float * dst_begin = dst; 00662 00663 struct scale_outpix_float * dst_line1; 00664 struct scale_outpix_float * dst_line2; 00665 00666 dst_line1 = (struct scale_outpix_float*) MEM_callocN( 00667 (dst_width + 1) * sizeof(struct scale_outpix_float), 00668 "shrink_picture_float 1"); 00669 dst_line2 = (struct scale_outpix_float*) MEM_callocN( 00670 (dst_width + 1) * sizeof(struct scale_outpix_float), 00671 "shrink_picture_float 2"); 00672 00673 dx_dst = ratiox; 00674 dy_dst = ratioy; 00675 00676 y_dst = 0; 00677 y_counter = 1.0; 00678 for (y_src = 0; y_src < src_height; y_src++) { 00679 float* line = src + y_src * 4 * src_width; 00680 uintptr_t weight1y = 1.0f - (y_dst - (int) y_dst); 00681 uintptr_t weight2y = 1.0f - weight1y; 00682 x_dst = 0; 00683 for (x_src = 0; x_src < src_width; x_src++) { 00684 uintptr_t weight1x = 1.0f - (x_dst - (int) x_dst); 00685 uintptr_t weight2x = 1.0f - weight1x; 00686 00687 uintptr_t x = (int) x_dst; 00688 00689 float w; 00690 00691 w = weight1y * weight1x; 00692 00693 dst_line1[x].r += line[0] * w; 00694 dst_line1[x].g += line[1] * w; 00695 dst_line1[x].b += line[2] * w; 00696 dst_line1[x].a += line[3] * w; 00697 dst_line1[x].weight += w; 00698 00699 w = weight2y * weight1x; 00700 00701 dst_line2[x].r += line[0] * w; 00702 dst_line2[x].g += line[1] * w; 00703 dst_line2[x].b += line[2] * w; 00704 dst_line2[x].a += line[3] * w; 00705 dst_line2[x].weight += w; 00706 00707 w = weight1y * weight2x; 00708 00709 dst_line1[x+1].r += line[0] * w; 00710 dst_line1[x+1].g += line[1] * w; 00711 dst_line1[x+1].b += line[2] * w; 00712 dst_line1[x+1].a += line[3] * w; 00713 dst_line1[x+1].weight += w; 00714 00715 w = weight2y * weight2x; 00716 00717 dst_line2[x+1].r += line[0] * w; 00718 dst_line2[x+1].g += line[1] * w; 00719 dst_line2[x+1].b += line[2] * w; 00720 dst_line2[x+1].a += line[3] * w; 00721 dst_line2[x+1].weight += w; 00722 00723 x_dst += dx_dst; 00724 line += 4; 00725 } 00726 00727 y_dst += dy_dst; 00728 y_counter -= dy_dst; 00729 if (y_counter < 0) { 00730 uintptr_t x; 00731 struct scale_outpix_float * temp; 00732 00733 y_counter += 1.0f; 00734 00735 for (x=0; x < dst_width; x++) { 00736 float f = 1.0f / dst_line1[x].weight; 00737 *dst++ = dst_line1[x].r * f; 00738 *dst++ = dst_line1[x].g * f; 00739 *dst++ = dst_line1[x].b * f; 00740 *dst++ = dst_line1[x].a * f; 00741 } 00742 memset(dst_line1, 0, dst_width * 00743 sizeof(struct scale_outpix_float)); 00744 temp = dst_line1; 00745 dst_line1 = dst_line2; 00746 dst_line2 = temp; 00747 } 00748 } 00749 if (dst - dst_begin < dst_width * dst_height * 4) { 00750 uintptr_t x; 00751 for (x = 0; x < dst_width; x++) { 00752 float f = 1.0f / dst_line1[x].weight; 00753 *dst++ = dst_line1[x].r * f; 00754 *dst++ = dst_line1[x].g * f; 00755 *dst++ = dst_line1[x].b * f; 00756 *dst++ = dst_line1[x].a * f; 00757 } 00758 } 00759 MEM_freeN(dst_line1); 00760 MEM_freeN(dst_line2); 00761 } 00762 00763 00764 static void q_scale_float(float* in, float* out, int in_width, 00765 int in_height, int dst_width, int dst_height) 00766 { 00767 if (dst_width > in_width && dst_height > in_height) { 00768 enlarge_picture_float(in, out, in_width, in_height, 00769 dst_width, dst_height); 00770 } else if (dst_width < in_width && dst_height < in_height) { 00771 shrink_picture_float(in, out, in_width, in_height, 00772 dst_width, dst_height); 00773 } 00774 } 00775 00776 /* q_scale_linear_interpolation (derived from ppmqscale, http://libdv.sf.net) 00777 00778 q stands for quick _and_ quality :) 00779 00780 only handles common cases when we either 00781 00782 scale both, x and y or 00783 shrink both, x and y 00784 00785 but that is pretty fast: 00786 * does only blit once instead of two passes like the old code 00787 (fewer cache misses) 00788 * uses fixed point integer arithmetic for byte buffers 00789 * doesn't branch in tight loops 00790 00791 Should be comparable in speed to the ImBuf ..._fast functions at least 00792 for byte-buffers. 00793 00794 NOTE: disabled, due to inacceptable inaccuracy and quality loss, see bug #18609 (ton) 00795 00796 */ 00797 static int q_scale_linear_interpolation( 00798 struct ImBuf *ibuf, int newx, int newy) 00799 { 00800 if ((newx >= ibuf->x && newy <= ibuf->y) || 00801 (newx <= ibuf->x && newy >= ibuf->y)) { 00802 return FALSE; 00803 } 00804 00805 if (ibuf->rect) { 00806 unsigned char * newrect = 00807 MEM_mallocN(newx * newy * sizeof(int), "q_scale rect"); 00808 q_scale_byte((unsigned char *)ibuf->rect, newrect, ibuf->x, ibuf->y, 00809 newx, newy); 00810 00811 imb_freerectImBuf(ibuf); 00812 ibuf->mall |= IB_rect; 00813 ibuf->rect = (unsigned int *) newrect; 00814 } 00815 if (ibuf->rect_float) { 00816 float * newrect = 00817 MEM_mallocN(newx * newy * 4 *sizeof(float), 00818 "q_scale rectfloat"); 00819 q_scale_float(ibuf->rect_float, newrect, ibuf->x, ibuf->y, 00820 newx, newy); 00821 imb_freerectfloatImBuf(ibuf); 00822 ibuf->mall |= IB_rectfloat; 00823 ibuf->rect_float = newrect; 00824 } 00825 ibuf->x = newx; 00826 ibuf->y = newy; 00827 00828 return TRUE; 00829 } 00830 00831 static struct ImBuf *scaledownx(struct ImBuf *ibuf, int newx) 00832 { 00833 const int do_rect= (ibuf->rect != NULL); 00834 const int do_float= (ibuf->rect_float != NULL); 00835 const size_t rect_size= ibuf->x * ibuf->y * 4; 00836 00837 uchar *rect, *_newrect, *newrect; 00838 float *rectf, *_newrectf, *newrectf; 00839 float sample, add, val[4], nval[4], valf[4], nvalf[4]; 00840 int x, y; 00841 00842 rectf= _newrectf= newrectf= NULL; 00843 rect=_newrect= newrect= NULL; 00844 nval[0]= nval[1]= nval[2]= nval[3]= 0.0f; 00845 nvalf[0]=nvalf[1]=nvalf[2]=nvalf[3]= 0.0f; 00846 00847 if (!do_rect && !do_float) return (ibuf); 00848 00849 if (do_rect) { 00850 _newrect = MEM_mallocN(newx * ibuf->y * sizeof(uchar) * 4, "scaledownx"); 00851 if (_newrect==NULL) return(ibuf); 00852 } 00853 if (do_float) { 00854 _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaledownxf"); 00855 if (_newrectf==NULL) { 00856 if (_newrect) MEM_freeN(_newrect); 00857 return(ibuf); 00858 } 00859 } 00860 00861 add = (ibuf->x - 0.01) / newx; 00862 00863 if (do_rect) { 00864 rect = (uchar *) ibuf->rect; 00865 newrect = _newrect; 00866 } 00867 if (do_float) { 00868 rectf = ibuf->rect_float; 00869 newrectf = _newrectf; 00870 } 00871 00872 for (y = ibuf->y; y>0 ; y--) { 00873 sample = 0.0f; 00874 val[0]= val[1]= val[2]= val[3]= 0.0f; 00875 valf[0]=valf[1]=valf[2]=valf[3]= 0.0f; 00876 00877 for (x = newx ; x>0 ; x--) { 00878 if (do_rect) { 00879 nval[0] = - val[0] * sample; 00880 nval[1] = - val[1] * sample; 00881 nval[2] = - val[2] * sample; 00882 nval[3] = - val[3] * sample; 00883 } 00884 if (do_float) { 00885 nvalf[0] = - valf[0] * sample; 00886 nvalf[1] = - valf[1] * sample; 00887 nvalf[2] = - valf[2] * sample; 00888 nvalf[3] = - valf[3] * sample; 00889 } 00890 00891 sample += add; 00892 00893 while (sample >= 1.0f){ 00894 sample -= 1.0f; 00895 00896 if (do_rect) { 00897 nval[0] += rect[0]; 00898 nval[1] += rect[1]; 00899 nval[2] += rect[2]; 00900 nval[3] += rect[3]; 00901 rect += 4; 00902 } 00903 if (do_float) { 00904 nvalf[0] += rectf[0]; 00905 nvalf[1] += rectf[1]; 00906 nvalf[2] += rectf[2]; 00907 nvalf[3] += rectf[3]; 00908 rectf += 4; 00909 } 00910 } 00911 00912 if (do_rect) { 00913 val[0]= rect[0];val[1]= rect[1];val[2]= rect[2];val[3]= rect[3]; 00914 rect += 4; 00915 00916 newrect[0] = ((nval[0] + sample * val[0])/add + 0.5f); 00917 newrect[1] = ((nval[1] + sample * val[1])/add + 0.5f); 00918 newrect[2] = ((nval[2] + sample * val[2])/add + 0.5f); 00919 newrect[3] = ((nval[3] + sample * val[3])/add + 0.5f); 00920 00921 newrect += 4; 00922 } 00923 if (do_float) { 00924 00925 valf[0]= rectf[0];valf[1]= rectf[1];valf[2]= rectf[2];valf[3]= rectf[3]; 00926 rectf += 4; 00927 00928 newrectf[0] = ((nvalf[0] + sample * valf[0])/add); 00929 newrectf[1] = ((nvalf[1] + sample * valf[1])/add); 00930 newrectf[2] = ((nvalf[2] + sample * valf[2])/add); 00931 newrectf[3] = ((nvalf[3] + sample * valf[3])/add); 00932 00933 newrectf += 4; 00934 } 00935 00936 sample -= 1.0f; 00937 } 00938 } 00939 00940 if (do_rect) { 00941 // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size); 00942 BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug [#26502] */ 00943 imb_freerectImBuf(ibuf); 00944 ibuf->mall |= IB_rect; 00945 ibuf->rect = (unsigned int *) _newrect; 00946 } 00947 if (do_float) { 00948 // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size); 00949 BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug [#26502] */ 00950 imb_freerectfloatImBuf(ibuf); 00951 ibuf->mall |= IB_rectfloat; 00952 ibuf->rect_float = _newrectf; 00953 } 00954 (void)rect_size; /* UNUSED in release builds */ 00955 00956 ibuf->x = newx; 00957 return(ibuf); 00958 } 00959 00960 00961 static struct ImBuf *scaledowny(struct ImBuf *ibuf, int newy) 00962 { 00963 const int do_rect= (ibuf->rect != NULL); 00964 const int do_float= (ibuf->rect_float != NULL); 00965 const size_t rect_size= ibuf->x * ibuf->y * 4; 00966 00967 uchar *rect, *_newrect, *newrect; 00968 float *rectf, *_newrectf, *newrectf; 00969 float sample, add, val[4], nval[4], valf[4], nvalf[4]; 00970 int x, y, skipx; 00971 00972 rectf= _newrectf= newrectf= NULL; 00973 rect= _newrect= newrect= NULL; 00974 nval[0]= nval[1]= nval[2]= nval[3]= 0.0f; 00975 nvalf[0]=nvalf[1]=nvalf[2]=nvalf[3]= 0.0f; 00976 00977 if (!do_rect && !do_float) return (ibuf); 00978 00979 if (do_rect) { 00980 _newrect = MEM_mallocN(newy * ibuf->x * sizeof(uchar) * 4, "scaledowny"); 00981 if (_newrect==NULL) return(ibuf); 00982 } 00983 if (do_float) { 00984 _newrectf = MEM_mallocN(newy * ibuf->x * sizeof(float) * 4, "scaledownyf"); 00985 if (_newrectf==NULL) { 00986 if (_newrect) MEM_freeN(_newrect); 00987 return(ibuf); 00988 } 00989 } 00990 00991 add = (ibuf->y - 0.01) / newy; 00992 skipx = 4 * ibuf->x; 00993 00994 for (x = skipx - 4; x>=0 ; x-= 4) { 00995 if (do_rect) { 00996 rect = ((uchar *) ibuf->rect) + x; 00997 newrect = _newrect + x; 00998 } 00999 if (do_float) { 01000 rectf = ibuf->rect_float + x; 01001 newrectf = _newrectf + x; 01002 } 01003 01004 sample = 0.0f; 01005 val[0]= val[1]= val[2]= val[3]= 0.0f; 01006 valf[0]=valf[1]=valf[2]=valf[3]= 0.0f; 01007 01008 for (y = newy ; y>0 ; y--) { 01009 if (do_rect) { 01010 nval[0] = - val[0] * sample; 01011 nval[1] = - val[1] * sample; 01012 nval[2] = - val[2] * sample; 01013 nval[3] = - val[3] * sample; 01014 } 01015 if (do_float) { 01016 nvalf[0] = - valf[0] * sample; 01017 nvalf[1] = - valf[1] * sample; 01018 nvalf[2] = - valf[2] * sample; 01019 nvalf[3] = - valf[3] * sample; 01020 } 01021 01022 sample += add; 01023 01024 while (sample >= 1.0f) { 01025 sample -= 1.0f; 01026 01027 if (do_rect) { 01028 nval[0] += rect[0]; 01029 nval[1] += rect[1]; 01030 nval[2] += rect[2]; 01031 nval[3] += rect[3]; 01032 rect += skipx; 01033 } 01034 if (do_float) { 01035 nvalf[0] += rectf[0]; 01036 nvalf[1] += rectf[1]; 01037 nvalf[2] += rectf[2]; 01038 nvalf[3] += rectf[3]; 01039 rectf += skipx; 01040 } 01041 } 01042 01043 if (do_rect) { 01044 val[0]= rect[0];val[1]= rect[1];val[2]= rect[2];val[3]= rect[3]; 01045 rect += skipx; 01046 01047 newrect[0] = ((nval[0] + sample * val[0])/add + 0.5f); 01048 newrect[1] = ((nval[1] + sample * val[1])/add + 0.5f); 01049 newrect[2] = ((nval[2] + sample * val[2])/add + 0.5f); 01050 newrect[3] = ((nval[3] + sample * val[3])/add + 0.5f); 01051 01052 newrect += skipx; 01053 } 01054 if (do_float) { 01055 01056 valf[0]= rectf[0];valf[1]= rectf[1];valf[2]= rectf[2];valf[3]= rectf[3]; 01057 rectf += skipx; 01058 01059 newrectf[0] = ((nvalf[0] + sample * valf[0])/add); 01060 newrectf[1] = ((nvalf[1] + sample * valf[1])/add); 01061 newrectf[2] = ((nvalf[2] + sample * valf[2])/add); 01062 newrectf[3] = ((nvalf[3] + sample * valf[3])/add); 01063 01064 newrectf += skipx; 01065 } 01066 01067 sample -= 1.0f; 01068 } 01069 } 01070 01071 if (do_rect) { 01072 // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size); 01073 BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug [#26502] */ 01074 imb_freerectImBuf(ibuf); 01075 ibuf->mall |= IB_rect; 01076 ibuf->rect = (unsigned int *) _newrect; 01077 } 01078 if (do_float) { 01079 // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size); 01080 BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug [#26502] */ 01081 imb_freerectfloatImBuf(ibuf); 01082 ibuf->mall |= IB_rectfloat; 01083 ibuf->rect_float = (float *) _newrectf; 01084 } 01085 (void)rect_size; /* UNUSED in release builds */ 01086 01087 ibuf->y = newy; 01088 return(ibuf); 01089 } 01090 01091 01092 static struct ImBuf *scaleupx(struct ImBuf *ibuf, int newx) 01093 { 01094 uchar *rect,*_newrect=NULL,*newrect; 01095 float *rectf,*_newrectf=NULL,*newrectf; 01096 float sample,add; 01097 float val_a,nval_a,diff_a; 01098 float val_b,nval_b,diff_b; 01099 float val_g,nval_g,diff_g; 01100 float val_r,nval_r,diff_r; 01101 float val_af,nval_af,diff_af; 01102 float val_bf,nval_bf,diff_bf; 01103 float val_gf,nval_gf,diff_gf; 01104 float val_rf,nval_rf,diff_rf; 01105 int x,y, do_rect = 0, do_float = 0; 01106 01107 val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0; 01108 val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0; 01109 val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0; 01110 val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0; 01111 if (ibuf==NULL) return(NULL); 01112 if (ibuf->rect==NULL && ibuf->rect_float==NULL) return (ibuf); 01113 01114 if (ibuf->rect) { 01115 do_rect = 1; 01116 _newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaleupx"); 01117 if (_newrect==NULL) return(ibuf); 01118 } 01119 if (ibuf->rect_float) { 01120 do_float = 1; 01121 _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaleupxf"); 01122 if (_newrectf==NULL) { 01123 if (_newrect) MEM_freeN(_newrect); 01124 return(ibuf); 01125 } 01126 } 01127 01128 add = (ibuf->x - 1.001) / (newx - 1.0); 01129 01130 rect = (uchar *) ibuf->rect; 01131 rectf = (float *) ibuf->rect_float; 01132 newrect = _newrect; 01133 newrectf = _newrectf; 01134 01135 for (y = ibuf->y; y>0 ; y--){ 01136 01137 sample = 0; 01138 01139 if (do_rect) { 01140 val_a = rect[0] ; 01141 nval_a = rect[4]; 01142 diff_a = nval_a - val_a ; 01143 val_a += 0.5f; 01144 01145 val_b = rect[1] ; 01146 nval_b = rect[5]; 01147 diff_b = nval_b - val_b ; 01148 val_b += 0.5f; 01149 01150 val_g = rect[2] ; 01151 nval_g = rect[6]; 01152 diff_g = nval_g - val_g ; 01153 val_g += 0.5f; 01154 01155 val_r = rect[3] ; 01156 nval_r = rect[7]; 01157 diff_r = nval_r - val_r ; 01158 val_r += 0.5f; 01159 01160 rect += 8; 01161 } 01162 if (do_float) { 01163 val_af = rectf[0] ; 01164 nval_af = rectf[4]; 01165 diff_af = nval_af - val_af; 01166 01167 val_bf = rectf[1] ; 01168 nval_bf = rectf[5]; 01169 diff_bf = nval_bf - val_bf; 01170 01171 val_gf = rectf[2] ; 01172 nval_gf = rectf[6]; 01173 diff_gf = nval_gf - val_gf; 01174 01175 val_rf = rectf[3] ; 01176 nval_rf = rectf[7]; 01177 diff_rf = nval_rf - val_rf; 01178 01179 rectf += 8; 01180 } 01181 for (x = newx ; x>0 ; x--){ 01182 if (sample >= 1.0f){ 01183 sample -= 1.0f; 01184 01185 if (do_rect) { 01186 val_a = nval_a ; 01187 nval_a = rect[0] ; 01188 diff_a = nval_a - val_a ; 01189 val_a += 0.5f; 01190 01191 val_b = nval_b ; 01192 nval_b = rect[1] ; 01193 diff_b = nval_b - val_b ; 01194 val_b += 0.5f; 01195 01196 val_g = nval_g ; 01197 nval_g = rect[2] ; 01198 diff_g = nval_g - val_g ; 01199 val_g += 0.5f; 01200 01201 val_r = nval_r ; 01202 nval_r = rect[3] ; 01203 diff_r = nval_r - val_r ; 01204 val_r += 0.5f; 01205 rect += 4; 01206 } 01207 if (do_float) { 01208 val_af = nval_af ; 01209 nval_af = rectf[0] ; 01210 diff_af = nval_af - val_af ; 01211 01212 val_bf = nval_bf ; 01213 nval_bf = rectf[1] ; 01214 diff_bf = nval_bf - val_bf ; 01215 01216 val_gf = nval_gf ; 01217 nval_gf = rectf[2] ; 01218 diff_gf = nval_gf - val_gf ; 01219 01220 val_rf = nval_rf ; 01221 nval_rf = rectf[3] ; 01222 diff_rf = nval_rf - val_rf; 01223 rectf += 4; 01224 } 01225 } 01226 if (do_rect) { 01227 newrect[0] = val_a + sample * diff_a; 01228 newrect[1] = val_b + sample * diff_b; 01229 newrect[2] = val_g + sample * diff_g; 01230 newrect[3] = val_r + sample * diff_r; 01231 newrect += 4; 01232 } 01233 if (do_float) { 01234 newrectf[0] = val_af + sample * diff_af; 01235 newrectf[1] = val_bf + sample * diff_bf; 01236 newrectf[2] = val_gf + sample * diff_gf; 01237 newrectf[3] = val_rf + sample * diff_rf; 01238 newrectf += 4; 01239 } 01240 sample += add; 01241 } 01242 } 01243 01244 if (do_rect) { 01245 imb_freerectImBuf(ibuf); 01246 ibuf->mall |= IB_rect; 01247 ibuf->rect = (unsigned int *) _newrect; 01248 } 01249 if (do_float) { 01250 imb_freerectfloatImBuf(ibuf); 01251 ibuf->mall |= IB_rectfloat; 01252 ibuf->rect_float = (float *) _newrectf; 01253 } 01254 01255 ibuf->x = newx; 01256 return(ibuf); 01257 } 01258 01259 static struct ImBuf *scaleupy(struct ImBuf *ibuf, int newy) 01260 { 01261 uchar *rect,*_newrect=NULL,*newrect; 01262 float *rectf,*_newrectf=NULL,*newrectf; 01263 float sample,add; 01264 float val_a,nval_a,diff_a; 01265 float val_b,nval_b,diff_b; 01266 float val_g,nval_g,diff_g; 01267 float val_r,nval_r,diff_r; 01268 float val_af,nval_af,diff_af; 01269 float val_bf,nval_bf,diff_bf; 01270 float val_gf,nval_gf,diff_gf; 01271 float val_rf,nval_rf,diff_rf; 01272 int x,y, do_rect = 0, do_float = 0, skipx; 01273 01274 val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0; 01275 val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0; 01276 val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0; 01277 val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0; 01278 if (ibuf==NULL) return(NULL); 01279 if (ibuf->rect==NULL && ibuf->rect_float==NULL) return (ibuf); 01280 01281 if (ibuf->rect) { 01282 do_rect = 1; 01283 _newrect = MEM_mallocN(ibuf->x * newy * sizeof(int), "scaleupy"); 01284 if (_newrect==NULL) return(ibuf); 01285 } 01286 if (ibuf->rect_float) { 01287 do_float = 1; 01288 _newrectf = MEM_mallocN(ibuf->x * newy * sizeof(float) * 4, "scaleupyf"); 01289 if (_newrectf==NULL) { 01290 if (_newrect) MEM_freeN(_newrect); 01291 return(ibuf); 01292 } 01293 } 01294 01295 add = (ibuf->y - 1.001) / (newy - 1.0); 01296 skipx = 4 * ibuf->x; 01297 01298 rect = (uchar *) ibuf->rect; 01299 rectf = (float *) ibuf->rect_float; 01300 newrect = _newrect; 01301 newrectf = _newrectf; 01302 01303 for (x = ibuf->x; x>0 ; x--){ 01304 01305 sample = 0; 01306 if (do_rect) { 01307 rect = ((uchar *)ibuf->rect) + 4*(x-1); 01308 newrect = _newrect + 4*(x-1); 01309 01310 val_a = rect[0] ; 01311 nval_a = rect[skipx]; 01312 diff_a = nval_a - val_a ; 01313 val_a += 0.5f; 01314 01315 val_b = rect[1] ; 01316 nval_b = rect[skipx+1]; 01317 diff_b = nval_b - val_b ; 01318 val_b += 0.5f; 01319 01320 val_g = rect[2] ; 01321 nval_g = rect[skipx+2]; 01322 diff_g = nval_g - val_g ; 01323 val_g += 0.5f; 01324 01325 val_r = rect[3] ; 01326 nval_r = rect[skipx+4]; 01327 diff_r = nval_r - val_r ; 01328 val_r += 0.5f; 01329 01330 rect += 2*skipx; 01331 } 01332 if (do_float) { 01333 rectf = ((float *)ibuf->rect_float) + 4*(x-1); 01334 newrectf = _newrectf + 4*(x-1); 01335 01336 val_af = rectf[0] ; 01337 nval_af = rectf[skipx]; 01338 diff_af = nval_af - val_af; 01339 01340 val_bf = rectf[1] ; 01341 nval_bf = rectf[skipx+1]; 01342 diff_bf = nval_bf - val_bf; 01343 01344 val_gf = rectf[2] ; 01345 nval_gf = rectf[skipx+2]; 01346 diff_gf = nval_gf - val_gf; 01347 01348 val_rf = rectf[3] ; 01349 nval_rf = rectf[skipx+3]; 01350 diff_rf = nval_rf - val_rf; 01351 01352 rectf += 2*skipx; 01353 } 01354 01355 for (y = newy ; y>0 ; y--){ 01356 if (sample >= 1.0f){ 01357 sample -= 1.0f; 01358 01359 if (do_rect) { 01360 val_a = nval_a ; 01361 nval_a = rect[0] ; 01362 diff_a = nval_a - val_a ; 01363 val_a += 0.5f; 01364 01365 val_b = nval_b ; 01366 nval_b = rect[1] ; 01367 diff_b = nval_b - val_b ; 01368 val_b += 0.5f; 01369 01370 val_g = nval_g ; 01371 nval_g = rect[2] ; 01372 diff_g = nval_g - val_g ; 01373 val_g += 0.5f; 01374 01375 val_r = nval_r ; 01376 nval_r = rect[3] ; 01377 diff_r = nval_r - val_r ; 01378 val_r += 0.5f; 01379 rect += skipx; 01380 } 01381 if (do_float) { 01382 val_af = nval_af ; 01383 nval_af = rectf[0] ; 01384 diff_af = nval_af - val_af ; 01385 01386 val_bf = nval_bf ; 01387 nval_bf = rectf[1] ; 01388 diff_bf = nval_bf - val_bf ; 01389 01390 val_gf = nval_gf ; 01391 nval_gf = rectf[2] ; 01392 diff_gf = nval_gf - val_gf ; 01393 01394 val_rf = nval_rf ; 01395 nval_rf = rectf[3] ; 01396 diff_rf = nval_rf - val_rf; 01397 rectf += skipx; 01398 } 01399 } 01400 if (do_rect) { 01401 newrect[0] = val_a + sample * diff_a; 01402 newrect[1] = val_b + sample * diff_b; 01403 newrect[2] = val_g + sample * diff_g; 01404 newrect[3] = val_r + sample * diff_r; 01405 newrect += skipx; 01406 } 01407 if (do_float) { 01408 newrectf[0] = val_af + sample * diff_af; 01409 newrectf[1] = val_bf + sample * diff_bf; 01410 newrectf[2] = val_gf + sample * diff_gf; 01411 newrectf[3] = val_rf + sample * diff_rf; 01412 newrectf += skipx; 01413 } 01414 sample += add; 01415 } 01416 } 01417 01418 if (do_rect) { 01419 imb_freerectImBuf(ibuf); 01420 ibuf->mall |= IB_rect; 01421 ibuf->rect = (unsigned int *) _newrect; 01422 } 01423 if (do_float) { 01424 imb_freerectfloatImBuf(ibuf); 01425 ibuf->mall |= IB_rectfloat; 01426 ibuf->rect_float = (float *) _newrectf; 01427 } 01428 01429 ibuf->y = newy; 01430 return(ibuf); 01431 } 01432 01433 01434 /* no float buf needed here! */ 01435 static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy) 01436 { 01437 unsigned int *rect, *_newrect, *newrect; 01438 int x, y; 01439 int ofsx, ofsy, stepx, stepy; 01440 01441 if (ibuf->zbuf) { 01442 _newrect = MEM_mallocN(newx * newy * sizeof(int), "z rect"); 01443 if (_newrect==NULL) return; 01444 01445 stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5; 01446 stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5; 01447 ofsy = 32768; 01448 01449 newrect = _newrect; 01450 01451 for (y = newy; y > 0 ; y--){ 01452 rect = (unsigned int*) ibuf->zbuf; 01453 rect += (ofsy >> 16) * ibuf->x; 01454 ofsy += stepy; 01455 ofsx = 32768; 01456 for (x = newx ; x > 0 ; x--){ 01457 *newrect++ = rect[ofsx >> 16]; 01458 ofsx += stepx; 01459 } 01460 } 01461 01462 IMB_freezbufImBuf(ibuf); 01463 ibuf->mall |= IB_zbuf; 01464 ibuf->zbuf = (int*) _newrect; 01465 } 01466 } 01467 01468 struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, unsigned int newx, unsigned int newy) 01469 { 01470 if (ibuf==NULL) return (NULL); 01471 if (ibuf->rect==NULL && ibuf->rect_float==NULL) return (ibuf); 01472 01473 if (newx == ibuf->x && newy == ibuf->y) { return ibuf; } 01474 01475 /* scaleup / scaledown functions below change ibuf->x and ibuf->y 01476 so we first scale the Z-buffer (if any) */ 01477 scalefast_Z_ImBuf(ibuf, newx, newy); 01478 01479 /* try to scale common cases in a fast way */ 01480 /* disabled, quality loss is inacceptable, see report #18609 (ton) */ 01481 if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) { 01482 return ibuf; 01483 } 01484 01485 if (newx < ibuf->x) if (newx) scaledownx(ibuf,newx); 01486 if (newy < ibuf->y) if (newy) scaledowny(ibuf,newy); 01487 if (newx > ibuf->x) if (newx) scaleupx(ibuf,newx); 01488 if (newy > ibuf->y) if (newy) scaleupy(ibuf,newy); 01489 01490 return(ibuf); 01491 } 01492 01493 struct imbufRGBA { 01494 float r, g, b, a; 01495 }; 01496 01497 struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy) 01498 { 01499 unsigned int *rect,*_newrect,*newrect; 01500 struct imbufRGBA *rectf, *_newrectf, *newrectf; 01501 int x,y, do_float=0, do_rect=0; 01502 int ofsx,ofsy,stepx,stepy; 01503 01504 rect = NULL; _newrect = NULL; newrect = NULL; 01505 rectf = NULL; _newrectf = NULL; newrectf = NULL; 01506 01507 if (ibuf==NULL) return(NULL); 01508 if (ibuf->rect) do_rect = 1; 01509 if (ibuf->rect_float) do_float = 1; 01510 if (do_rect==0 && do_float==0) return(ibuf); 01511 01512 if (newx == ibuf->x && newy == ibuf->y) return(ibuf); 01513 01514 if(do_rect) { 01515 _newrect = MEM_mallocN(newx * newy * sizeof(int), "scalefastimbuf"); 01516 if (_newrect==NULL) return(ibuf); 01517 newrect = _newrect; 01518 } 01519 01520 if (do_float) { 01521 _newrectf = MEM_mallocN(newx * newy * sizeof(float) * 4, "scalefastimbuf f"); 01522 if (_newrectf==NULL) { 01523 if (_newrect) MEM_freeN(_newrect); 01524 return(ibuf); 01525 } 01526 newrectf = _newrectf; 01527 } 01528 01529 stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5; 01530 stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5; 01531 ofsy = 32768; 01532 01533 for (y = newy; y > 0 ; y--){ 01534 if(do_rect) { 01535 rect = ibuf->rect; 01536 rect += (ofsy >> 16) * ibuf->x; 01537 } 01538 if (do_float) { 01539 rectf = (struct imbufRGBA *)ibuf->rect_float; 01540 rectf += (ofsy >> 16) * ibuf->x; 01541 } 01542 ofsy += stepy; 01543 ofsx = 32768; 01544 01545 if (do_rect) { 01546 for (x = newx ; x>0 ; x--){ 01547 *newrect++ = rect[ofsx >> 16]; 01548 ofsx += stepx; 01549 } 01550 } 01551 01552 if (do_float) { 01553 ofsx = 32768; 01554 for (x = newx ; x>0 ; x--){ 01555 *newrectf++ = rectf[ofsx >> 16]; 01556 ofsx += stepx; 01557 } 01558 } 01559 } 01560 01561 if (do_rect) { 01562 imb_freerectImBuf(ibuf); 01563 ibuf->mall |= IB_rect; 01564 ibuf->rect = _newrect; 01565 } 01566 01567 if (do_float) { 01568 imb_freerectfloatImBuf(ibuf); 01569 ibuf->mall |= IB_rectfloat; 01570 ibuf->rect_float = (float *)_newrectf; 01571 } 01572 01573 scalefast_Z_ImBuf(ibuf, newx, newy); 01574 01575 ibuf->x = newx; 01576 ibuf->y = newy; 01577 return(ibuf); 01578 } 01579