Blender V2.61 - r43446

divers.c

Go to the documentation of this file.
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 }