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_rand.h" 00037 #include "BLI_math.h" 00038 #include "BLI_utildefines.h" 00039 00040 #include "imbuf.h" 00041 #include "IMB_imbuf_types.h" 00042 #include "IMB_imbuf.h" 00043 #include "IMB_allocimbuf.h" 00044 00045 #include "MEM_guardedalloc.h" 00046 00047 /**************************** Interlace/Deinterlace **************************/ 00048 00049 void IMB_de_interlace(ImBuf *ibuf) 00050 { 00051 ImBuf * tbuf1, * tbuf2; 00052 00053 if (ibuf == NULL) return; 00054 if (ibuf->flags & IB_fields) return; 00055 ibuf->flags |= IB_fields; 00056 00057 if (ibuf->rect) { 00058 /* make copies */ 00059 tbuf1 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect); 00060 tbuf2 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect); 00061 00062 ibuf->x *= 2; 00063 IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); 00064 IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y); 00065 00066 ibuf->x /= 2; 00067 IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y); 00068 IMB_rectcpy(ibuf, tbuf2, 0, tbuf2->y, 0, 0, tbuf2->x, tbuf2->y); 00069 00070 IMB_freeImBuf(tbuf1); 00071 IMB_freeImBuf(tbuf2); 00072 } 00073 ibuf->y /= 2; 00074 } 00075 00076 void IMB_interlace(ImBuf *ibuf) 00077 { 00078 ImBuf * tbuf1, * tbuf2; 00079 00080 if (ibuf == NULL) return; 00081 ibuf->flags &= ~IB_fields; 00082 00083 ibuf->y *= 2; 00084 00085 if (ibuf->rect) { 00086 /* make copies */ 00087 tbuf1 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect); 00088 tbuf2 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect); 00089 00090 IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); 00091 IMB_rectcpy(tbuf2, ibuf, 0, 0, 0, tbuf2->y, ibuf->x, ibuf->y); 00092 00093 ibuf->x *= 2; 00094 IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y); 00095 IMB_rectcpy(ibuf, tbuf2, tbuf2->x, 0, 0, 0, tbuf2->x, tbuf2->y); 00096 ibuf->x /= 2; 00097 00098 IMB_freeImBuf(tbuf1); 00099 IMB_freeImBuf(tbuf2); 00100 } 00101 } 00102 00103 /************************* Floyd-Steinberg dithering *************************/ 00104 00105 typedef struct DitherContext { 00106 int *error_buf, *e; 00107 int v[4], v0[4], v1[4]; 00108 float f; 00109 } DitherContext; 00110 00111 DitherContext *create_dither_context(int w, float factor) 00112 { 00113 DitherContext *di; 00114 int i; 00115 00116 di= MEM_callocN(sizeof(DitherContext), "dithering context"); 00117 di->f= factor / 16.0f; 00118 di->error_buf= MEM_callocN(4*(w+1)*sizeof(int), "dithering error"); 00119 di->e= di->error_buf; 00120 00121 for(i=0; i<4; ++i) 00122 di->v[i]= di->v0[i]= di->v1[i]= 1024.0f*(BLI_frand()-0.5f); 00123 00124 return di; 00125 } 00126 00127 static void clear_dither_context(DitherContext *di) 00128 { 00129 MEM_freeN(di->error_buf); 00130 MEM_freeN(di); 00131 } 00132 00133 static void dither_finish_row(DitherContext *di) 00134 { 00135 int i; 00136 00137 for(i=0; i<4; i++) 00138 di->v[i]= di->v0[i]= di->v1[i] = 0; 00139 00140 di->e= di->error_buf; 00141 } 00142 00143 MINLINE unsigned char dither_value(unsigned short v_in, DitherContext *di, int i) 00144 { 00145 int dv, d2; 00146 unsigned char v_out; 00147 00148 di->v[i] = v_in + (2*di->v[i] + di->e[4]) * di->f; 00149 CLAMP(di->v[i], 0, 0xFF00); 00150 v_out = USHORTTOUCHAR(di->v[i]); 00151 di->v[i] -= v_out<<8; 00152 dv = di->v[i]; 00153 d2 = di->v[i]<<1; 00154 di->v[i] += d2; 00155 *(di->e++) = di->v[i] + di->v0[i]; 00156 di->v[i] += d2; 00157 00158 di->v0[i] = di->v[i] + di->v1[i]; 00159 di->v1[i] = dv; 00160 di->v[i] += d2; 00161 00162 return v_out; 00163 } 00164 00165 /************************* Generic Buffer Conversion *************************/ 00166 00167 MINLINE void byte_to_float_v4(float f[4], const uchar b[4]) 00168 { 00169 f[0]= b[0] * (1.0f/255.0f); 00170 f[1]= b[1] * (1.0f/255.0f); 00171 f[2]= b[2] * (1.0f/255.0f); 00172 f[3]= b[3] * (1.0f/255.0f); 00173 } 00174 00175 MINLINE void float_to_byte_v4(uchar b[4], const float f[4]) 00176 { 00177 F4TOCHAR4(f, b); 00178 } 00179 00180 MINLINE void ushort_to_byte_v4(uchar b[4], const unsigned short us[4]) 00181 { 00182 b[0]= USHORTTOUCHAR(us[0]); 00183 b[1]= USHORTTOUCHAR(us[1]); 00184 b[2]= USHORTTOUCHAR(us[2]); 00185 b[3]= USHORTTOUCHAR(us[3]); 00186 } 00187 00188 MINLINE void ushort_to_byte_dither_v4(uchar b[4], const unsigned short us[4], DitherContext *di) 00189 { 00190 b[0]= dither_value(us[0], di, 0); 00191 b[1]= dither_value(us[1], di, 1); 00192 b[2]= dither_value(us[2], di, 2); 00193 b[3]= dither_value(us[3], di, 3); 00194 } 00195 00196 MINLINE void float_to_byte_dither_v4(uchar b[4], const float f[4], DitherContext *di) 00197 { 00198 unsigned short us[4] = {FTOUSHORT(f[0]), FTOUSHORT(f[1]), FTOUSHORT(f[2]), FTOUSHORT(f[3])}; 00199 ushort_to_byte_dither_v4(b, us, di); 00200 } 00201 00202 /* float to byte pixels, output 4-channel RGBA */ 00203 void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from, 00204 int channels_from, float dither, int profile_to, int profile_from, int predivide, 00205 int width, int height, int stride_to, int stride_from) 00206 { 00207 float tmp[4]; 00208 int x, y; 00209 DitherContext *di; 00210 00211 /* we need valid profiles */ 00212 BLI_assert(profile_to != IB_PROFILE_NONE); 00213 BLI_assert(profile_from != IB_PROFILE_NONE); 00214 00215 BLI_init_srgb_conversion(); 00216 if(dither) 00217 di= create_dither_context(width, dither); 00218 00219 for(y = 0; y < height; y++) { 00220 if(channels_from == 1) { 00221 /* single channel input */ 00222 const float *from = rect_from + stride_from*y; 00223 uchar *to = rect_to + stride_to*y*4; 00224 00225 for(x = 0; x < width; x++, from++, to+=4) 00226 to[0] = to[1] = to[2] = to[3] = FTOCHAR(from[0]); 00227 } 00228 else if(channels_from == 3) { 00229 /* RGB input */ 00230 const float *from = rect_from + stride_from*y*3; 00231 uchar *to = rect_to + stride_to*y*4; 00232 00233 if(profile_to == profile_from) { 00234 /* no color space conversion */ 00235 for(x = 0; x < width; x++, from+=3, to+=4) { 00236 F3TOCHAR3(from, to); 00237 to[3] = 255; 00238 } 00239 } 00240 else if(profile_to == IB_PROFILE_SRGB) { 00241 /* convert from linear to sRGB */ 00242 for(x = 0; x < width; x++, from+=3, to+=4) { 00243 linearrgb_to_srgb_v3_v3(tmp, from); 00244 F3TOCHAR3(tmp, to); 00245 to[3] = 255; 00246 } 00247 } 00248 else if(profile_to == IB_PROFILE_LINEAR_RGB) { 00249 /* convert from sRGB to linear */ 00250 for(x = 0; x < width; x++, from+=3, to+=4) { 00251 srgb_to_linearrgb_v3_v3(tmp, from); 00252 F3TOCHAR3(tmp, to); 00253 to[3] = 255; 00254 } 00255 } 00256 } 00257 else if(channels_from == 4) { 00258 /* RGBA input */ 00259 const float *from = rect_from + stride_from*y*4; 00260 uchar *to = rect_to + stride_to*y*4; 00261 00262 if(profile_to == profile_from) { 00263 /* no color space conversion */ 00264 if(dither) { 00265 for(x = 0; x < width; x++, from+=4, to+=4) 00266 float_to_byte_dither_v4(to, from, di); 00267 } 00268 else { 00269 for(x = 0; x < width; x++, from+=4, to+=4) 00270 float_to_byte_v4(to, from); 00271 } 00272 } 00273 else if(profile_to == IB_PROFILE_SRGB) { 00274 /* convert from linear to sRGB */ 00275 unsigned short us[4]; 00276 00277 if(dither && predivide) { 00278 for(x = 0; x < width; x++, from+=4, to+=4) { 00279 linearrgb_to_srgb_ushort4_predivide(us, from); 00280 ushort_to_byte_dither_v4(to, us, di); 00281 } 00282 } 00283 else if(dither) { 00284 for(x = 0; x < width; x++, from+=4, to+=4) { 00285 linearrgb_to_srgb_ushort4(us, from); 00286 ushort_to_byte_dither_v4(to, us, di); 00287 } 00288 } 00289 else if(predivide) { 00290 for(x = 0; x < width; x++, from+=4, to+=4) { 00291 linearrgb_to_srgb_ushort4_predivide(us, from); 00292 ushort_to_byte_v4(to, us); 00293 } 00294 } 00295 else { 00296 for(x = 0; x < width; x++, from+=4, to+=4) { 00297 linearrgb_to_srgb_ushort4(us, from); 00298 ushort_to_byte_v4(to, us); 00299 } 00300 } 00301 } 00302 else if(profile_to == IB_PROFILE_LINEAR_RGB) { 00303 /* convert from sRGB to linear */ 00304 if(dither && predivide) { 00305 for(x = 0; x < width; x++, from+=4, to+=4) { 00306 srgb_to_linearrgb_predivide_v4(tmp, from); 00307 float_to_byte_dither_v4(to, tmp, di); 00308 } 00309 } 00310 else if(dither) { 00311 for(x = 0; x < width; x++, from+=4, to+=4) { 00312 srgb_to_linearrgb_v4(tmp, from); 00313 float_to_byte_dither_v4(to, tmp, di); 00314 } 00315 } 00316 else if(predivide) { 00317 for(x = 0; x < width; x++, from+=4, to+=4) { 00318 srgb_to_linearrgb_predivide_v4(tmp, from); 00319 float_to_byte_v4(to, tmp); 00320 } 00321 } 00322 else { 00323 for(x = 0; x < width; x++, from+=4, to+=4) { 00324 srgb_to_linearrgb_v4(tmp, from); 00325 float_to_byte_v4(to, tmp); 00326 } 00327 } 00328 } 00329 } 00330 00331 if(dither) 00332 dither_finish_row(di); 00333 } 00334 00335 if(dither) 00336 clear_dither_context(di); 00337 } 00338 00339 /* byte to float pixels, input and output 4-channel RGBA */ 00340 void IMB_buffer_float_from_byte(float *rect_to, const uchar *rect_from, 00341 int profile_to, int profile_from, int predivide, 00342 int width, int height, int stride_to, int stride_from) 00343 { 00344 float tmp[4]; 00345 int x, y; 00346 00347 /* we need valid profiles */ 00348 BLI_assert(profile_to != IB_PROFILE_NONE); 00349 BLI_assert(profile_from != IB_PROFILE_NONE); 00350 00351 BLI_init_srgb_conversion(); 00352 00353 /* RGBA input */ 00354 for(y = 0; y < height; y++) { 00355 const uchar *from = rect_from + stride_from*y*4; 00356 float *to = rect_to + stride_to*y*4; 00357 00358 if(profile_to == profile_from) { 00359 /* no color space conversion */ 00360 for(x = 0; x < width; x++, from+=4, to+=4) 00361 byte_to_float_v4(to, from); 00362 } 00363 else if(profile_to == IB_PROFILE_LINEAR_RGB) { 00364 /* convert sRGB to linear */ 00365 if(predivide) { 00366 for(x = 0; x < width; x++, from+=4, to+=4) { 00367 srgb_to_linearrgb_uchar4_predivide(to, from); 00368 } 00369 } 00370 else { 00371 for(x = 0; x < width; x++, from+=4, to+=4) { 00372 srgb_to_linearrgb_uchar4(to, from); 00373 } 00374 } 00375 } 00376 else if(profile_to == IB_PROFILE_SRGB) { 00377 /* convert linear to sRGB */ 00378 if(predivide) { 00379 for(x = 0; x < width; x++, from+=4, to+=4) { 00380 byte_to_float_v4(tmp, from); 00381 linearrgb_to_srgb_predivide_v4(to, tmp); 00382 } 00383 } 00384 else { 00385 for(x = 0; x < width; x++, from+=4, to+=4) { 00386 byte_to_float_v4(tmp, from); 00387 linearrgb_to_srgb_v4(to, tmp); 00388 } 00389 } 00390 } 00391 } 00392 } 00393 00394 /* float to float pixels, output 4-channel RGBA */ 00395 void IMB_buffer_float_from_float(float *rect_to, const float *rect_from, 00396 int channels_from, int profile_to, int profile_from, int predivide, 00397 int width, int height, int stride_to, int stride_from) 00398 { 00399 int x, y; 00400 00401 /* we need valid profiles */ 00402 BLI_assert(profile_to != IB_PROFILE_NONE); 00403 BLI_assert(profile_from != IB_PROFILE_NONE); 00404 00405 if(channels_from==1) { 00406 /* single channel input */ 00407 for(y = 0; y < height; y++) { 00408 const float *from = rect_from + stride_from*y; 00409 float *to = rect_to + stride_to*y*4; 00410 00411 for(x = 0; x < width; x++, from++, to+=4) 00412 to[0] = to[1] = to[2] = to[3] = from[0]; 00413 } 00414 } 00415 else if(channels_from == 3) { 00416 /* RGB input */ 00417 for(y = 0; y < height; y++) { 00418 const float *from = rect_from + stride_from*y*3; 00419 float *to = rect_to + stride_to*y*4; 00420 00421 if(profile_to == profile_from) { 00422 /* no color space conversion */ 00423 for(x = 0; x < width; x++, from+=3, to+=4) { 00424 copy_v3_v3(to, from); 00425 to[3] = 1.0f; 00426 } 00427 } 00428 else if(profile_to == IB_PROFILE_LINEAR_RGB) { 00429 /* convert from sRGB to linear */ 00430 for(x = 0; x < width; x++, from+=3, to+=4) { 00431 srgb_to_linearrgb_v3_v3(to, from); 00432 to[3] = 1.0f; 00433 } 00434 } 00435 else if(profile_to == IB_PROFILE_SRGB) { 00436 /* convert from linear to sRGB */ 00437 for(x = 0; x < width; x++, from+=3, to+=4) { 00438 linearrgb_to_srgb_v3_v3(to, from); 00439 to[3] = 1.0f; 00440 } 00441 } 00442 } 00443 } 00444 else if(channels_from == 4) { 00445 /* RGBA input */ 00446 for(y = 0; y < height; y++) { 00447 const float *from = rect_from + stride_from*y*4; 00448 float *to = rect_to + stride_to*y*4; 00449 00450 if(profile_to == profile_from) { 00451 /* same profile, copy */ 00452 memcpy(to, from, sizeof(float)*4*width); 00453 } 00454 else if(profile_to == IB_PROFILE_LINEAR_RGB) { 00455 /* convert to sRGB to linear */ 00456 if(predivide) { 00457 for(x = 0; x < width; x++, from+=4, to+=4) 00458 srgb_to_linearrgb_predivide_v4(to, from); 00459 } 00460 else { 00461 for(x = 0; x < width; x++, from+=4, to+=4) 00462 srgb_to_linearrgb_v4(to, from); 00463 } 00464 } 00465 else if(profile_to == IB_PROFILE_SRGB) { 00466 /* convert from linear to sRGB */ 00467 if(predivide) { 00468 for(x = 0; x < width; x++, from+=4, to+=4) 00469 linearrgb_to_srgb_predivide_v4(to, from); 00470 } 00471 else { 00472 for(x = 0; x < width; x++, from+=4, to+=4) 00473 linearrgb_to_srgb_v4(to, from); 00474 } 00475 } 00476 } 00477 } 00478 } 00479 00480 /* byte to byte pixels, input and output 4-channel RGBA */ 00481 void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from, 00482 int profile_to, int profile_from, int predivide, 00483 int width, int height, int stride_to, int stride_from) 00484 { 00485 float tmp[4]; 00486 int x, y; 00487 00488 /* we need valid profiles */ 00489 BLI_assert(profile_to != IB_PROFILE_NONE); 00490 BLI_assert(profile_from != IB_PROFILE_NONE); 00491 00492 /* always RGBA input */ 00493 for(y = 0; y < height; y++) { 00494 const uchar *from = rect_from + stride_from*y*4; 00495 uchar *to = rect_to + stride_to*y*4; 00496 00497 if(profile_to == profile_from) { 00498 /* same profile, copy */ 00499 memcpy(to, from, sizeof(uchar)*4*width); 00500 } 00501 else if(profile_to == IB_PROFILE_LINEAR_RGB) { 00502 /* convert to sRGB to linear */ 00503 if(predivide) { 00504 for(x = 0; x < width; x++, from+=4, to+=4) { 00505 byte_to_float_v4(tmp, from); 00506 srgb_to_linearrgb_predivide_v4(tmp, tmp); 00507 float_to_byte_v4(to, tmp); 00508 } 00509 } 00510 else { 00511 for(x = 0; x < width; x++, from+=4, to+=4) { 00512 byte_to_float_v4(tmp, from); 00513 srgb_to_linearrgb_v4(tmp, tmp); 00514 float_to_byte_v4(to, tmp); 00515 } 00516 } 00517 } 00518 else if(profile_to == IB_PROFILE_SRGB) { 00519 /* convert from linear to sRGB */ 00520 if(predivide) { 00521 for(x = 0; x < width; x++, from+=4, to+=4) { 00522 byte_to_float_v4(tmp, from); 00523 linearrgb_to_srgb_predivide_v4(tmp, tmp); 00524 float_to_byte_v4(to, tmp); 00525 } 00526 } 00527 else { 00528 for(x = 0; x < width; x++, from+=4, to+=4) { 00529 byte_to_float_v4(tmp, from); 00530 linearrgb_to_srgb_v4(tmp, tmp); 00531 float_to_byte_v4(to, tmp); 00532 } 00533 } 00534 } 00535 } 00536 } 00537 00538 /****************************** ImBuf Conversion *****************************/ 00539 00540 void IMB_rect_from_float(ImBuf *ibuf) 00541 { 00542 int predivide= (ibuf->flags & IB_cm_predivide); 00543 int profile_from; 00544 00545 /* verify we have a float buffer */ 00546 if(ibuf->rect_float==NULL) 00547 return; 00548 00549 /* create byte rect if it didn't exist yet */ 00550 if(ibuf->rect==NULL) 00551 imb_addrectImBuf(ibuf); 00552 00553 /* determine profiles */ 00554 if(ibuf->profile == IB_PROFILE_LINEAR_RGB) 00555 profile_from = IB_PROFILE_LINEAR_RGB; 00556 else if(ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) 00557 profile_from = IB_PROFILE_SRGB; 00558 else 00559 BLI_assert(0); 00560 00561 /* do conversion */ 00562 IMB_buffer_byte_from_float((uchar*)ibuf->rect, ibuf->rect_float, 00563 ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide, 00564 ibuf->x, ibuf->y, ibuf->x, ibuf->x); 00565 00566 /* ensure user flag is reset */ 00567 ibuf->userflags &= ~IB_RECT_INVALID; 00568 } 00569 00570 /* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */ 00571 void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w, int h) 00572 { 00573 float *rect_float; 00574 uchar *rect_byte; 00575 int predivide= (ibuf->flags & IB_cm_predivide); 00576 int profile_from; 00577 00578 /* verify we have a float buffer */ 00579 if(ibuf->rect_float==NULL || buffer==NULL) 00580 return; 00581 00582 /* create byte rect if it didn't exist yet */ 00583 if(ibuf->rect==NULL) 00584 imb_addrectImBuf(ibuf); 00585 00586 /* determine profiles */ 00587 if(ibuf->profile == IB_PROFILE_LINEAR_RGB) 00588 profile_from = IB_PROFILE_LINEAR_RGB; 00589 else if(ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) 00590 profile_from = IB_PROFILE_SRGB; 00591 else 00592 BLI_assert(0); 00593 00594 /* do conversion */ 00595 rect_float= ibuf->rect_float + (x + y*ibuf->x)*ibuf->channels; 00596 rect_byte= (uchar*)ibuf->rect + (x + y*ibuf->x)*4; 00597 00598 IMB_buffer_float_from_float(buffer, rect_float, 00599 ibuf->channels, IB_PROFILE_SRGB, profile_from, predivide, 00600 w, h, w, ibuf->x); 00601 00602 IMB_buffer_byte_from_float(rect_byte, buffer, 00603 4, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, 0, 00604 w, h, ibuf->x, w); 00605 00606 /* ensure user flag is reset */ 00607 ibuf->userflags &= ~IB_RECT_INVALID; 00608 } 00609 00610 void IMB_float_from_rect(ImBuf *ibuf) 00611 { 00612 int predivide= (ibuf->flags & IB_cm_predivide); 00613 int profile_from; 00614 00615 /* verify if we byte and float buffers */ 00616 if(ibuf->rect==NULL) 00617 return; 00618 00619 if(ibuf->rect_float==NULL) 00620 if(imb_addrectfloatImBuf(ibuf) == 0) 00621 return; 00622 00623 /* determine profiles */ 00624 if(ibuf->profile == IB_PROFILE_NONE) 00625 profile_from = IB_PROFILE_LINEAR_RGB; 00626 else 00627 profile_from = IB_PROFILE_SRGB; 00628 00629 /* do conversion */ 00630 IMB_buffer_float_from_byte(ibuf->rect_float, (uchar*)ibuf->rect, 00631 IB_PROFILE_LINEAR_RGB, profile_from, predivide, 00632 ibuf->x, ibuf->y, ibuf->x, ibuf->x); 00633 } 00634 00635 /* no profile conversion */ 00636 void IMB_float_from_rect_simple(ImBuf *ibuf) 00637 { 00638 int predivide= (ibuf->flags & IB_cm_predivide); 00639 00640 if(ibuf->rect_float==NULL) 00641 imb_addrectfloatImBuf(ibuf); 00642 00643 IMB_buffer_float_from_byte(ibuf->rect_float, (uchar*)ibuf->rect, 00644 IB_PROFILE_SRGB, IB_PROFILE_SRGB, predivide, 00645 ibuf->x, ibuf->y, ibuf->x, ibuf->x); 00646 } 00647 00648 void IMB_convert_profile(ImBuf *ibuf, int profile) 00649 { 00650 int predivide= (ibuf->flags & IB_cm_predivide); 00651 int profile_from, profile_to; 00652 00653 if(ibuf->profile == profile) 00654 return; 00655 00656 /* determine profiles */ 00657 if(ibuf->profile == IB_PROFILE_LINEAR_RGB) 00658 profile_from = IB_PROFILE_LINEAR_RGB; 00659 else if(ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) 00660 profile_from = IB_PROFILE_SRGB; 00661 else 00662 BLI_assert(0); 00663 00664 if(profile == IB_PROFILE_LINEAR_RGB) 00665 profile_to = IB_PROFILE_LINEAR_RGB; 00666 else if(ELEM(profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) 00667 profile_to = IB_PROFILE_SRGB; 00668 else 00669 BLI_assert(0); 00670 00671 /* do conversion */ 00672 if(ibuf->rect_float) { 00673 IMB_buffer_float_from_float(ibuf->rect_float, ibuf->rect_float, 00674 4, profile_to, profile_from, predivide, 00675 ibuf->x, ibuf->y, ibuf->x, ibuf->x); 00676 } 00677 00678 if(ibuf->rect) { 00679 IMB_buffer_byte_from_byte((uchar*)ibuf->rect, (uchar*)ibuf->rect, 00680 profile_to, profile_from, predivide, 00681 ibuf->x, ibuf->y, ibuf->x, ibuf->x); 00682 } 00683 00684 /* set new profile */ 00685 ibuf->profile= profile; 00686 } 00687 00688 /* use when you need to get a buffer with a certain profile 00689 * if the return */ 00690 float *IMB_float_profile_ensure(ImBuf *ibuf, int profile, int *alloc) 00691 { 00692 int predivide= (ibuf->flags & IB_cm_predivide); 00693 int profile_from, profile_to; 00694 00695 /* determine profiles */ 00696 if(ibuf->profile == IB_PROFILE_NONE) 00697 profile_from = IB_PROFILE_LINEAR_RGB; 00698 else 00699 profile_from = IB_PROFILE_SRGB; 00700 00701 if(profile == IB_PROFILE_NONE) 00702 profile_to = IB_PROFILE_LINEAR_RGB; 00703 else 00704 profile_to = IB_PROFILE_SRGB; 00705 00706 if(profile_from == profile_to) { 00707 /* simple case, just allocate the buffer and return */ 00708 *alloc= 0; 00709 00710 if(ibuf->rect_float == NULL) 00711 IMB_float_from_rect(ibuf); 00712 00713 return ibuf->rect_float; 00714 } 00715 else { 00716 /* conversion is needed, first check */ 00717 float *fbuf= MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "IMB_float_profile_ensure"); 00718 *alloc= 1; 00719 00720 if(ibuf->rect_float == NULL) { 00721 IMB_buffer_float_from_byte(fbuf, (uchar*)ibuf->rect, 00722 profile_to, profile_from, predivide, 00723 ibuf->x, ibuf->y, ibuf->x, ibuf->x); 00724 } 00725 else { 00726 IMB_buffer_float_from_float(fbuf, ibuf->rect_float, 00727 4, profile_to, profile_from, predivide, 00728 ibuf->x, ibuf->y, ibuf->x, ibuf->x); 00729 } 00730 00731 return fbuf; 00732 } 00733 } 00734 00735 /**************************** Color to Grayscale *****************************/ 00736 00737 /* no profile conversion */ 00738 void IMB_color_to_bw(ImBuf *ibuf) 00739 { 00740 float *rctf= ibuf->rect_float; 00741 uchar *rct= (uchar*)ibuf->rect; 00742 int i; 00743 00744 if(rctf) { 00745 for(i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) 00746 rctf[0]= rctf[1]= rctf[2]= rgb_to_grayscale(rctf); 00747 } 00748 00749 if(rct) { 00750 for(i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) 00751 rct[0]= rct[1]= rct[2]= rgb_to_grayscale_byte(rct); 00752 } 00753 }