svn merge ^/trunk/blender -r42927:42931
authorCampbell Barton <ideasman42@gmail.com>
Wed, 28 Dec 2011 14:05:02 +0000 (14:05 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 28 Dec 2011 14:05:02 +0000 (14:05 +0000)
17 files changed:
source/blender/blenkernel/BKE_colortools.h
source/blender/blenkernel/intern/colortools.c
source/blender/blenlib/BLI_math_color.h
source/blender/blenlib/intern/math_color.c
source/blender/blenlib/intern/math_color_inline.c [new file with mode: 0644]
source/blender/blenloader/intern/writefile.c
source/blender/editors/render/render_internal.c
source/blender/editors/render/render_opengl.c
source/blender/editors/screen/glutil.c
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/divers.c
source/blender/makesdna/DNA_mesh_types.h
source/blender/nodes/composite/node_composite_util.c
source/blender/nodes/composite/nodes/node_composite_image.c
source/blender/python/intern/bpy_app_ffmpeg.c
source/blender/render/intern/source/pipeline.c
source/blender/windowmanager/intern/wm_operators.c

index fd3a3fea2bb54316938026bb2d8b56911913882a..b358209a0f4eb3758d9e3c46a6b43bd50a05b0bc 100644 (file)
@@ -45,9 +45,6 @@ struct rctf;
 #   define DO_INLINE static inline
 #endif
 
-void                           floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w);
-void                           floatbuf_to_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w);
-
 struct CurveMapping    *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy);
 void                           curvemapping_free(struct CurveMapping *cumap);
 struct CurveMapping    *curvemapping_copy(struct CurveMapping *cumap);
index 2f568aa01ebfd4ca9ca012eb3a60ff1bc9e3812d..67bd6a223487f405cbb28ca48341cde4be6c3420 100644 (file)
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
 
-
-void floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int UNUSED(w))
-{
-       int x, y;
-       float *rf= rectf;
-       float srgb[3];
-       unsigned char *rc= rectc;
-       
-       for(y=y1; y<y2; y++) {
-               for(x=x1; x<x2; x++, rf+=4, rc+=4) {
-                       srgb[0]= linearrgb_to_srgb(rf[0]);
-                       srgb[1]= linearrgb_to_srgb(rf[1]);
-                       srgb[2]= linearrgb_to_srgb(rf[2]);
-
-                       rc[0]= FTOCHAR(srgb[0]);
-                       rc[1]= FTOCHAR(srgb[1]);
-                       rc[2]= FTOCHAR(srgb[2]);
-                       rc[3]= FTOCHAR(rf[3]);
-               }
-       }
-}
-
-void floatbuf_to_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int UNUSED(w))
-{
-       int x, y;
-       float *rf= rectf;
-       unsigned char *rc= rectc;
-       
-       for(y=y1; y<y2; y++) {
-               for(x=x1; x<x2; x++, rf+=4, rc+=4) {
-                       rc[0]= FTOCHAR(rf[0]);
-                       rc[1]= FTOCHAR(rf[1]);
-                       rc[2]= FTOCHAR(rf[2]);
-                       rc[3]= FTOCHAR(rf[3]);
-               }
-       }
-}
-
-
 /* ********************************* color curve ********************* */
 
 /* ***************** operations on full struct ************* */
index 0e33ee2be3fc8966f5406c07e65e165c5fc482cd..7fbb4680b6db6d2d5bfb0d71e08ca6d4cf04ff31 100644 (file)
@@ -34,6 +34,8 @@
 extern "C" {
 #endif
 
+#include "BLI_math_inline.h"
+
 /* primaries */
 #define BLI_XYZ_SMPTE  0
 #define BLI_XYZ_REC709_SRGB    1
@@ -48,7 +50,7 @@ extern "C" {
 #define BLI_YCC_ITU_BT601      0
 #define BLI_YCC_ITU_BT709      1
 #define BLI_YCC_JFIF_0_255     2
-       
+
 /******************* Conversion to RGB ********************/
 
 void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b);
@@ -70,22 +72,23 @@ unsigned int hsv_to_cpack(float h, float s, float v);
 float rgb_to_grayscale(float rgb[3]);
 unsigned char rgb_to_grayscale_byte(unsigned char rgb[3]);
 
-/***************** Profile Transformations ********************/
+/**************** Profile Transformations *****************/
 
 void gamma_correct(float *c, float gamma);
 float rec709_to_linearrgb(float c);
 float linearrgb_to_rec709(float c);
 float srgb_to_linearrgb(float c);
 float linearrgb_to_srgb(float c);
-void srgb_to_linearrgb_v3_v3(float *col_to, float *col_from);
-void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from);
-
-/* rgba buffer convenience functions */
-void srgb_to_linearrgb_rgba_buf(float *col, int tot);
-void linearrgb_to_srgb_rgba_buf(float *col, int tot);
-void srgb_to_linearrgb_rgba_rgba_buf(float *col_to, float *col_from, int tot);
-void linearrgb_to_srgb_rgba_rgba_buf(float *col_to, float *col_from, int tot);
-       
+
+MINLINE void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3]);
+MINLINE void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3]);
+
+MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4]);
+MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4]);
+
+MINLINE void srgb_to_linearrgb_predivide_v4(float linear[4], const float srgb[4]);
+MINLINE void linearrgb_to_srgb_predivide_v4(float srgb[4], const float linear[4]);
+
 /************************** Other *************************/
 
 int constrain_rgb(float *r, float *g, float *b);
@@ -101,6 +104,10 @@ void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *o
 void rgb_byte_to_float(const unsigned char *in, float *out);
 void rgb_float_to_byte(const float *in, unsigned char *out);
 
+#ifdef BLI_MATH_INLINE_H
+#include "intern/math_color_inline.c"
+#endif
+
 #ifdef __cplusplus
 }
 #endif
index 2ef29c1ce94cbff92292cc39ca8c8a9bbe78e798..8f5366b6317124ef90b89d2f1ef72c25dab9c5a3 100644 (file)
@@ -393,57 +393,6 @@ float linearrgb_to_srgb(float c)
                return  1.055f * powf(c, 1.0f/2.4f) - 0.055f;
 }
 
-void srgb_to_linearrgb_v3_v3(float *col_to, float *col_from)
-{
-       col_to[0] = srgb_to_linearrgb(col_from[0]);
-       col_to[1] = srgb_to_linearrgb(col_from[1]);
-       col_to[2] = srgb_to_linearrgb(col_from[2]);
-}
-
-void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from)
-{
-       col_to[0] = linearrgb_to_srgb(col_from[0]);
-       col_to[1] = linearrgb_to_srgb(col_from[1]);
-       col_to[2] = linearrgb_to_srgb(col_from[2]);
-}
-
-/* todo, should these be moved elsewhere?, they dont belong in imbuf */
-void srgb_to_linearrgb_rgba_buf(float *col, int tot)
-{
-       while(tot--) {
-               srgb_to_linearrgb_v3_v3(col, col);
-               col += 4;
-       }
-}
-
-void linearrgb_to_srgb_rgba_buf(float *col, int tot)
-{
-       while(tot--) {
-               linearrgb_to_srgb_v3_v3(col, col);
-               col += 4;
-       }
-}
-
-void srgb_to_linearrgb_rgba_rgba_buf(float *col_to, float *col_from, int tot)
-{
-       while(tot--) {
-               srgb_to_linearrgb_v3_v3(col_to, col_from);
-               col_to[3]= col_from[3];
-               col_to += 4;
-               col_from += 4;
-       }
-}
-
-void linearrgb_to_srgb_rgba_rgba_buf(float *col_to, float *col_from, int tot)
-{
-       while(tot--) {
-               linearrgb_to_srgb_v3_v3(col_to, col_from);
-               col_to[3]= col_from[3];
-               col_to += 4;
-               col_from += 4;
-       }
-}
-
 void minmax_rgb(short c[])
 {
        if(c[0]>255) c[0]=255;
diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c
new file mode 100644 (file)
index 0000000..aaaa065
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: some of this file.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * */
+
+/** \file blender/blenlib/intern/math_color_inline.c
+ *  \ingroup bli
+ */
+
+
+#include "BLI_math_color.h"
+#include "BLI_utildefines.h"
+
+#ifndef BLI_MATH_COLOR_INLINE_H
+#define BLI_MATH_COLOR_INLINE_H
+
+/******************************** Color Space ********************************/
+
+MINLINE void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
+{
+       linear[0] = srgb_to_linearrgb(srgb[0]);
+       linear[1] = srgb_to_linearrgb(srgb[1]);
+       linear[2] = srgb_to_linearrgb(srgb[2]);
+}
+
+MINLINE void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
+{
+       srgb[0] = linearrgb_to_srgb(linear[0]);
+       srgb[1] = linearrgb_to_srgb(linear[1]);
+       srgb[2] = linearrgb_to_srgb(linear[2]);
+}
+
+MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4])
+{
+       srgb_to_linearrgb_v3_v3(linear, srgb);
+       linear[3] = srgb[3];
+}
+
+MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4])
+{
+       linearrgb_to_srgb_v3_v3(srgb, linear);
+       srgb[3] = linear[3];
+}
+
+/* predivide versions to work on associated/premultipled alpha. if this should
+   be done or not depends on the background the image will be composited over,
+   ideally you would never do color space conversion on an image with alpha
+   because it is ill defined */
+
+MINLINE void srgb_to_linearrgb_predivide_v4(float linear[4], const float srgb[4])
+{
+       float alpha, inv_alpha;
+
+       if(srgb[3] == 1.0f || srgb[3] == 0.0f) {
+               alpha = 1.0f;
+               inv_alpha = 1.0f;
+       }
+       else {
+               alpha = srgb[3];
+               inv_alpha = 1.0f/alpha;
+       }
+
+       linear[0] = srgb_to_linearrgb(srgb[0] * inv_alpha) * alpha;
+       linear[1] = srgb_to_linearrgb(srgb[1] * inv_alpha) * alpha;
+       linear[2] = srgb_to_linearrgb(srgb[2] * inv_alpha) * alpha;
+       linear[3] = srgb[3];
+}
+
+MINLINE void linearrgb_to_srgb_predivide_v4(float srgb[4], const float linear[4])
+{
+       float alpha, inv_alpha;
+
+       if(linear[3] == 1.0f || linear[3] == 0.0f) {
+               alpha = 1.0f;
+               inv_alpha = 1.0f;
+       }
+       else {
+               alpha = linear[3];
+               inv_alpha = 1.0f/alpha;
+       }
+
+       srgb[0] = linearrgb_to_srgb(linear[0] * inv_alpha) * alpha;
+       srgb[1] = linearrgb_to_srgb(linear[1] * inv_alpha) * alpha;
+       srgb[2] = linearrgb_to_srgb(linear[2] * inv_alpha) * alpha;
+       srgb[3] = linear[3];
+}
+
+#endif /* BLI_MATH_COLOR_INLINE_H */
+
index 6f84d89c00a409a292791ffb738c89218a046bec..c1759aa80fdf3851202143d7d23d277c3602a381 100644 (file)
@@ -176,7 +176,7 @@ typedef struct {
        
        int tot, count, error, memsize;
 
-#ifdef USE_MESH_FORWARDS_COMAT
+#ifdef USE_BMESH_SAVE_AS_COMPAT
        char use_mesh_compat; /* option to save with older mesh format */
 #endif
 } WriteData;
@@ -2717,7 +2717,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
 
        wd= bgnwrite(handle, compare, current);
 
-#ifdef USE_MESH_FORWARDS_COMAT
+#ifdef USE_BMESH_SAVE_AS_COMPAT
        wd->use_mesh_compat = (write_flags & G_FILE_MESH_COMPAT) != 0;
 #endif
 
index 8a580627da375cc7440efdbaf1ba403b87fd0f1a..bff93fea0677c64b44174dd19fcb4234c8f88b44 100644 (file)
 /* called inside thread! */
 void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volatile rcti *renrect)
 {
-       float x1, y1, *rectf= NULL;
+       float *rectf= NULL;
        int ymin, ymax, xmin, xmax;
-       int rymin, rxmin, do_color_management;
-       char *rectc;
+       int rymin, rxmin, predivide, profile_from;
+       unsigned char *rectc;
 
        /* if renrect argument, we only refresh scanlines */
        if(renrect) {
@@ -136,50 +136,17 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat
                imb_addrectImBuf(ibuf);
        
        rectf+= 4*(rr->rectx*ymin + xmin);
-       rectc= (char *)(ibuf->rect + ibuf->x*rymin + rxmin);
+       rectc= (unsigned char*)(ibuf->rect + ibuf->x*rymin + rxmin);
 
-       do_color_management = (scene && (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT));
-       
-       /* XXX make nice consistent functions for this */
-       for(y1= 0; y1<ymax; y1++) {
-               float *rf= rectf;
-               float srgb[3];
-               char *rc= rectc;
-               const float dither = ibuf->dither / 255.0f;
-
-               /* XXX temp. because crop offset */
-               if(rectc >= (char *)(ibuf->rect)) {
-                       for(x1= 0; x1<xmax; x1++, rf += 4, rc+=4) {
-                               /* color management */
-                               if(do_color_management) {
-                                       srgb[0]= linearrgb_to_srgb(rf[0]);
-                                       srgb[1]= linearrgb_to_srgb(rf[1]);
-                                       srgb[2]= linearrgb_to_srgb(rf[2]);
-                               }
-                               else {
-                                       copy_v3_v3(srgb, rf);
-                               }
-
-                               /* dither */
-                               if(dither != 0.0f) {
-                                       const float d = (BLI_frand()-0.5f)*dither;
-
-                                       srgb[0] += d;
-                                       srgb[1] += d;
-                                       srgb[2] += d;
-                               }
-
-                               /* write */
-                               rc[0]= FTOCHAR(srgb[0]);
-                               rc[1]= FTOCHAR(srgb[1]);
-                               rc[2]= FTOCHAR(srgb[2]);
-                               rc[3]= FTOCHAR(rf[3]);
-                       }
-               }
+       if(scene && (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT))
+               profile_from= IB_PROFILE_LINEAR_RGB;
+       else
+               profile_from= IB_PROFILE_SRGB;
+       predivide= 0;
 
-               rectf += 4*rr->rectx;
-               rectc += 4*ibuf->x;
-       }
+       IMB_buffer_byte_from_float(rectc, rectf,
+               4, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide,
+               xmax, ymax, ibuf->x, rr->rectx);
 }
 
 /* ****************************** render invoking ***************** */
index 35b21c626ed3914d703a662817a8a7346957b636..be4d54ae2e889e6d8d82af4197f9b70ff983efd5 100644 (file)
@@ -206,14 +206,11 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
         * float buffer. */
 
        if(oglrender->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
-               float *rctf = rr->rectf;
-               int i;
+               int predivide= 0; /* no alpha */
 
-               for (i = oglrender->sizex * oglrender->sizey; i > 0; i--, rctf+=4) {
-                       rctf[0]= srgb_to_linearrgb(rctf[0]);
-                       rctf[1]= srgb_to_linearrgb(rctf[1]);
-                       rctf[2]= srgb_to_linearrgb(rctf[2]);
-               }
+               IMB_buffer_float_from_float(rr->rectf, rr->rectf,
+                       4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, predivide,
+                       oglrender->sizex, oglrender->sizey, oglrender->sizex, oglrender->sizex);
        }
 
        RE_ReleaseResult(oglrender->re);
index 0bba9838005729c21271ed0a8ed1619b4d67c807..8f04940efd6541af0c7172a8d6df983bb276b587 100644 (file)
@@ -45,6 +45,9 @@
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
 
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
 #ifndef GL_CLAMP_TO_EDGE
 #define GL_CLAMP_TO_EDGE                        0x812F
 #endif
@@ -563,17 +566,17 @@ void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void *
 void glaDrawPixelsSafe_to32(float fx, float fy, int img_w, int img_h, int UNUSED(row_w), float *rectf, int do_gamma_correct)
 {
        unsigned char *rect32;
+       int profile_from= (do_gamma_correct)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
+       int predivide= 0;
        
        /* copy imgw-imgh to a temporal 32 bits rect */
        if(img_w<1 || img_h<1) return;
        
        rect32= MEM_mallocN(img_w*img_h*sizeof(int), "temp 32 bits");
        
-       if (do_gamma_correct) {
-               floatbuf_to_srgb_byte(rectf, rect32, 0, img_w, 0, img_h, img_w);
-       } else {
-               floatbuf_to_byte(rectf, rect32, 0, img_w, 0, img_h, img_w);
-        }
+       IMB_buffer_byte_from_float(rect32, rectf,
+               4, 0, IB_PROFILE_SRGB, profile_from, predivide, 
+               img_w, img_h, img_w, img_w);
        
        glaDrawPixelsSafe(fx, fy, img_w, img_h, img_w, GL_RGBA, GL_UNSIGNED_BYTE, rect32);
 
index 39282335f46bb501bf0276a088af57a356a928ed..7f99fc3ffc7c35fe655425369c7b3ffc63874ab1 100644 (file)
@@ -378,6 +378,20 @@ void IMB_convert_profile(struct ImBuf *ibuf, int profile);
 float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc);
 void IMB_color_to_bw(struct ImBuf *ibuf);
 
+/* converting pixel buffers */
+void IMB_buffer_byte_from_float(unsigned char *rect_to, const float *rect_from,
+       int channels_from, int dither, int profile_to, int profile_from, int predivide,
+       int width, int height, int stride_to, int stride_from);
+void IMB_buffer_float_from_byte(float *rect_to, const unsigned char *rect_from,
+       int profile_to, int profile_from, int predivide,
+       int width, int height, int stride_to, int stride_from);
+void IMB_buffer_float_from_float(float *rect_to, const float *rect_from,
+       int channels_from, int profile_to, int profile_from, int predivide,
+       int width, int height, int stride_to, int stride_from);
+void IMB_buffer_byte_from_byte(unsigned char *rect_to, const unsigned char *rect_from,
+       int profile_to, int profile_from, int predivide,
+       int width, int height, int stride_to, int stride_from);
+
 /**
  * Change the ordering of the color bytes pointed to by rect from
  * rgba to abgr. size * 4 color bytes are reordered.
index 8c5f2dcafd6f4a67e09d6f4ffa36353284acab2d..8a3f6358c5b3f68f6b1158b9131d3d7ca8602219 100644 (file)
 #include "IMB_imbuf.h"
 #include "IMB_allocimbuf.h"
 
-#include "BKE_colortools.h"
-
 #include "MEM_guardedalloc.h"
 
+/**************************** Interlace/Deinterlace **************************/
+
 void IMB_de_interlace(struct ImBuf *ibuf)
 {
        struct ImBuf * tbuf1, * tbuf2;
@@ -100,347 +100,498 @@ void IMB_interlace(struct ImBuf *ibuf)
        }
 }
 
+/************************* Generic Buffer Conversion *************************/
 
-/* assume converting from linear float to sRGB byte */
-void IMB_rect_from_float(struct ImBuf *ibuf)
+MINLINE void byte_to_float_v4(float f[4], const uchar b[4])
 {
-       /* quick method to convert floatbuf to byte */
-       float *tof = (float *)ibuf->rect_float;
-//     int do_dither = ibuf->dither != 0.f;
-       float dither= ibuf->dither / 255.0f;
-       float srgb[4];
-       int i, channels= ibuf->channels;
-       short profile= ibuf->profile;
-       unsigned char *to = (unsigned char *) ibuf->rect;
-       
-       if(tof==NULL) return;
-       if(to==NULL) {
-               imb_addrectImBuf(ibuf);
-               to = (unsigned char *) ibuf->rect;
-       }
-       
-       if(channels==1) {
-               for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof++)
-                       to[1]= to[2]= to[3]= to[0] = FTOCHAR(tof[0]);
+       f[0] = b[0] * (1.0f/255.0f);
+       f[1] = b[1] * (1.0f/255.0f);
+       f[2] = b[2] * (1.0f/255.0f);
+       f[3] = b[3] * (1.0f/255.0f);
+}
+
+MINLINE void float_to_byte_v4(uchar b[4], const float f[4])
+{
+       F4TOCHAR4(f, b);
+}
+
+MINLINE void float_to_byte_dither_v4(uchar b[4], const float f[4], float dither)
+{
+       float tmp[4] = {f[0]+dither, f[1]+dither, f[2]+dither, f[3]+dither};
+       float_to_byte_v4(b, tmp);
+}
+
+/* float to byte pixels, output 4-channel RGBA */
+void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
+       int channels_from, int dither, int profile_to, int profile_from, int predivide,
+       int width, int height, int stride_to, int stride_from)
+{
+       float tmp[4];
+       float dither_fac = dither/255.0f;
+       int x, y;
+
+       /* we need valid profiles */
+       BLI_assert(profile_to != IB_PROFILE_NONE);
+       BLI_assert(profile_from != IB_PROFILE_NONE);
+
+       if(channels_from==1) {
+               /* single channel input */
+               for(y = 0; y < height; y++) {
+                       const float *from = rect_from + stride_from*y;
+                       uchar *to = rect_to + stride_to*y*4;
+
+                       for(x = 0; x < width; x++, from++, to+=4)
+                               to[0] = to[1] = to[2] = to[3] = FTOCHAR(from[0]);
+               }
        }
-       else if (profile == IB_PROFILE_LINEAR_RGB) {
-               if(channels == 3) {
-                       for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) {
-                               srgb[0]= linearrgb_to_srgb(tof[0]);
-                               srgb[1]= linearrgb_to_srgb(tof[1]);
-                               srgb[2]= linearrgb_to_srgb(tof[2]);
-
-                               to[0] = FTOCHAR(srgb[0]);
-                               to[1] = FTOCHAR(srgb[1]);
-                               to[2] = FTOCHAR(srgb[2]);
-                               to[3] = 255;
+       else if(channels_from == 3) {
+               /* RGB input */
+               for(y = 0; y < height; y++) {
+                       const float *from = rect_from + stride_from*y*3;
+                       uchar *to = rect_to + stride_to*y*4;
+
+                       if(profile_to == profile_from) {
+                               /* no color space conversion */
+                               for(x = 0; x < width; x++, from+=3, to+=4) {
+                                       F3TOCHAR3(from, to);
+                                       to[3] = 255;
+                               }
+                       }
+                       else if(profile_to == IB_PROFILE_SRGB) {
+                               /* convert from linear to sRGB */
+                               for(x = 0; x < width; x++, from+=3, to+=4) {
+                                       linearrgb_to_srgb_v3_v3(tmp, from);
+                                       F3TOCHAR3(tmp, to);
+                                       to[3] = 255;
+                               }
+                       }
+                       else if(profile_to == IB_PROFILE_LINEAR_RGB) {
+                               /* convert from sRGB to linear */
+                               for(x = 0; x < width; x++, from+=3, to+=4) {
+                                       srgb_to_linearrgb_v3_v3(tmp, from);
+                                       F3TOCHAR3(tmp, to);
+                                       to[3] = 255;
+                               }
                        }
                }
-               else if (channels == 4) {
-                       if (dither != 0.f) {
-                               for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) {
-                                       const float d = (BLI_frand()-0.5f)*dither;
-                                       
-                                       srgb[0]= d + linearrgb_to_srgb(tof[0]);
-                                       srgb[1]= d + linearrgb_to_srgb(tof[1]);
-                                       srgb[2]= d + linearrgb_to_srgb(tof[2]);
-                                       srgb[3]= d + tof[3]; 
-                                       
-                                       to[0] = FTOCHAR(srgb[0]);
-                                       to[1] = FTOCHAR(srgb[1]);
-                                       to[2] = FTOCHAR(srgb[2]);
-                                       to[3] = FTOCHAR(srgb[3]);
+       }
+       else if(channels_from == 4) {
+               /* RGBA input */
+               for(y = 0; y < height; y++) {
+                       const float *from = rect_from + stride_from*y*4;
+                       uchar *to = rect_to + stride_to*y*4;
+
+                       if(profile_to == profile_from) {
+                               /* no color space conversion */
+                               if(dither) {
+                                       for(x = 0; x < width; x++, from+=4, to+=4)
+                                               float_to_byte_dither_v4(to, from, (BLI_frand()-0.5f)*dither_fac);
+                               }
+                               else {
+                                       for(x = 0; x < width; x++, from+=4, to+=4)
+                                               float_to_byte_v4(to, from);
+                               }
+                       }
+                       else if(profile_to == IB_PROFILE_SRGB) {
+                               /* convert from linear to sRGB */
+                               if(dither && predivide) {
+                                       for(x = 0; x < width; x++, from+=4, to+=4) {
+                                               linearrgb_to_srgb_predivide_v4(tmp, from);
+                                               float_to_byte_dither_v4(to, tmp, (BLI_frand()-0.5f)*dither_fac);
+                                       }
+                               }
+                               else if(dither) {
+                                       for(x = 0; x < width; x++, from+=4, to+=4) {
+                                               linearrgb_to_srgb_v4(tmp, from);
+                                               float_to_byte_dither_v4(to, tmp, (BLI_frand()-0.5f)*dither_fac);
+                                       }
+                               }
+                               else if(predivide) {
+                                       for(x = 0; x < width; x++, from+=4, to+=4) {
+                                               linearrgb_to_srgb_predivide_v4(tmp, from);
+                                               float_to_byte_v4(to, tmp);
+                                       }
+                               }
+                               else {
+                                       for(x = 0; x < width; x++, from+=4, to+=4) {
+                                               linearrgb_to_srgb_v4(tmp, from);
+                                               float_to_byte_v4(to, tmp);
+                                       }
+                               }
+                       }
+                       else if(profile_to == IB_PROFILE_LINEAR_RGB) {
+                               /* convert from sRGB to linear */
+                               if(dither && predivide) {
+                                       for(x = 0; x < width; x++, from+=4, to+=4) {
+                                               srgb_to_linearrgb_predivide_v4(tmp, from);
+                                               float_to_byte_dither_v4(to, tmp, (BLI_frand()-0.5f)*dither_fac);
+                                       }
+                               }
+                               else if(dither) {
+                                       for(x = 0; x < width; x++, from+=4, to+=4) {
+                                               srgb_to_linearrgb_v4(tmp, from);
+                                               float_to_byte_dither_v4(to, tmp, (BLI_frand()-0.5f)*dither_fac);
+                                       }
+                               }
+                               else if(predivide) {
+                                       for(x = 0; x < width; x++, from+=4, to+=4) {
+                                               srgb_to_linearrgb_predivide_v4(tmp, from);
+                                               float_to_byte_v4(to, tmp);
+                                       }
+                               }
+                               else {
+                                       for(x = 0; x < width; x++, from+=4, to+=4) {
+                                               srgb_to_linearrgb_v4(tmp, from);
+                                               float_to_byte_v4(to, tmp);
+                                       }
                                }
-                       } else {
-                               floatbuf_to_srgb_byte(tof, to, 0, ibuf->x, 0, ibuf->y, ibuf->x);
                        }
                }
        }
-       else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) {
-               if(channels==3) {
-                       for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) {
-                               to[0] = FTOCHAR(tof[0]);
-                               to[1] = FTOCHAR(tof[1]);
-                               to[2] = FTOCHAR(tof[2]);
-                               to[3] = 255;
+}
+
+/* byte to float pixels, input and output 4-channel RGBA  */
+void IMB_buffer_float_from_byte(float *rect_to, const uchar *rect_from,
+       int profile_to, int profile_from, int predivide,
+       int width, int height, int stride_to, int stride_from)
+{
+       float tmp[4];
+       int x, y;
+
+       /* we need valid profiles */
+       BLI_assert(profile_to != IB_PROFILE_NONE);
+       BLI_assert(profile_from != IB_PROFILE_NONE);
+
+       /* RGBA input */
+       for(y = 0; y < height; y++) {
+               const uchar *from = rect_from + stride_from*y*4;
+               float *to = rect_to + stride_to*y*4;
+
+               if(profile_to == profile_from) {
+                       /* no color space conversion */
+                       for(x = 0; x < width; x++, from+=4, to+=4)
+                               byte_to_float_v4(to, from);
+               }
+               else if(profile_to == IB_PROFILE_LINEAR_RGB) {
+                       /* convert sRGB to linear */
+                       if(predivide) {
+                               for(x = 0; x < width; x++, from+=4, to+=4) {
+                                       byte_to_float_v4(tmp, from);
+                                       srgb_to_linearrgb_predivide_v4(to, tmp);
+                               }
+                       }
+                       else {
+                               for(x = 0; x < width; x++, from+=4, to+=4) {
+                                       byte_to_float_v4(tmp, from);
+                                       srgb_to_linearrgb_v4(to, tmp);
+                               }
                        }
                }
-               else {
-                       if (dither != 0.f) {
-                               for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) {
-                                       const float d = (BLI_frand()-0.5f)*dither;
-                                       float col[4];
-
-                                       col[0]= d + tof[0];
-                                       col[1]= d + tof[1];
-                                       col[2]= d + tof[2];
-                                       col[3]= d + tof[3];
-
-                                       to[0] = FTOCHAR(col[0]);
-                                       to[1] = FTOCHAR(col[1]);
-                                       to[2] = FTOCHAR(col[2]);
-                                       to[3] = FTOCHAR(col[3]);
+               else if(profile_to == IB_PROFILE_SRGB) {
+                       /* convert linear to sRGB */
+                       if(predivide) {
+                               for(x = 0; x < width; x++, from+=4, to+=4) {
+                                       byte_to_float_v4(tmp, from);
+                                       linearrgb_to_srgb_predivide_v4(to, tmp);
                                }
-                       } else {
-                               for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) {
-                                       to[0] = FTOCHAR(tof[0]);
-                                       to[1] = FTOCHAR(tof[1]);
-                                       to[2] = FTOCHAR(tof[2]);
-                                       to[3] = FTOCHAR(tof[3]);
+                       }
+                       else {
+                               for(x = 0; x < width; x++, from+=4, to+=4) {
+                                       byte_to_float_v4(tmp, from);
+                                       linearrgb_to_srgb_v4(to, tmp);
                                }
                        }
                }
        }
-       /* ensure user flag is reset */
-       ibuf->userflags &= ~IB_RECT_INVALID;
 }
 
-
-/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */
-void IMB_partial_rect_from_float(struct ImBuf *ibuf,float *buffer, int x, int y, int w, int h)
+/* float to float pixels, output 4-channel RGBA */
+void IMB_buffer_float_from_float(float *rect_to, const float *rect_from,
+       int channels_from, int profile_to, int profile_from, int predivide,
+       int width, int height, int stride_to, int stride_from)
 {
-       /* indices to source and destination image pixels */
-       float *srcFloatPxl;
-       unsigned char *dstBytePxl;
-       /* buffer index will fill buffer */
-       float *bufferIndex;
-
-       /* convenience pointers to start of image buffers */
-       float *init_srcFloatPxl = (float *)ibuf->rect_float;
-       unsigned char *init_dstBytePxl = (unsigned char *) ibuf->rect;
-
-       /* Dithering factor */
-       float dither= ibuf->dither / 255.0f;
-       /* respective attributes of image */
-       short profile= ibuf->profile;
-       int channels= ibuf->channels;
-       
-       int i, j;
-       
-       /*
-               if called -only- from GPU_paint_update_image this test will never fail
-               but leaving it here for better or worse
-       */
-       if(init_srcFloatPxl==NULL || (buffer == NULL)){
-               return;
-       }
-       if(init_dstBytePxl==NULL) {
-               imb_addrectImBuf(ibuf);
-               init_dstBytePxl = (unsigned char *) ibuf->rect;
+       int x, y;
+
+       /* we need valid profiles */
+       BLI_assert(profile_to != IB_PROFILE_NONE);
+       BLI_assert(profile_from != IB_PROFILE_NONE);
+
+       if(channels_from==1) {
+               /* single channel input */
+               for(y = 0; y < height; y++) {
+                       const float *from = rect_from + stride_from*y;
+                       float *to = rect_to + stride_to*y*4;
+
+                       for(x = 0; x < width; x++, from++, to+=4)
+                               to[0] = to[1] = to[2] = to[3] = from[0];
+               }
        }
-       if(channels==1) {
-                       for (j = 0; j < h; j++){
-                               bufferIndex = buffer + w*j*4;
-                               dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
-                               srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x);
-                               for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl++, bufferIndex+=4) {
-                                       dstBytePxl[1]= dstBytePxl[2]= dstBytePxl[3]= dstBytePxl[0] = FTOCHAR(srcFloatPxl[0]);
-                                       bufferIndex[0] = bufferIndex[1] = bufferIndex[2] = bufferIndex[3] = srcFloatPxl[0];
+       else if(channels_from == 3) {
+               /* RGB input */
+               for(y = 0; y < height; y++) {
+                       const float *from = rect_from + stride_from*y*3;
+                       float *to = rect_to + stride_to*y*4;
+
+                       if(profile_to == profile_from) {
+                               /* no color space conversion */
+                               for(x = 0; x < width; x++, from+=3, to+=4) {
+                                       copy_v3_v3(to, from);
+                                       to[3] = 1.0f;
                                }
                        }
-       }
-       else if (profile == IB_PROFILE_LINEAR_RGB) {
-               if(channels == 3) {
-                       for (j = 0; j < h; j++){
-                               bufferIndex = buffer + w*j*4;
-                               dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
-                               srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3;
-                               for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex += 4) {
-                                       linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
-                                       F3TOCHAR4(bufferIndex, dstBytePxl);
-                                       bufferIndex[3]= 1.0;
+                       else if(profile_to == IB_PROFILE_LINEAR_RGB) {
+                               /* convert from sRGB to linear */
+                               for(x = 0; x < width; x++, from+=3, to+=4) {
+                                       srgb_to_linearrgb_v3_v3(to, from);
+                                       to[3] = 1.0f;
+                               }
+                       }
+                       else if(profile_to == IB_PROFILE_SRGB) {
+                               /* convert from linear to sRGB */
+                               for(x = 0; x < width; x++, from+=3, to+=4) {
+                                       linearrgb_to_srgb_v3_v3(to, from);
+                                       to[3] = 1.0f;
                                }
                        }
                }
-               else if (channels == 4) {
-                       if (dither != 0.f) {
-                               for (j = 0; j < h; j++){
-                                       bufferIndex = buffer + w*j*4;
-                                       dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
-                                       srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
-                                       for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
-                                               const float d = (BLI_frand()-0.5f)*dither;
-                                               linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
-                                               bufferIndex[3] = srcFloatPxl[3];
-                                               add_v4_fl(bufferIndex, d);
-                                               F4TOCHAR4(bufferIndex, dstBytePxl);
-                                       }
+       }
+       else if(channels_from == 4) {
+               /* RGBA input */
+               for(y = 0; y < height; y++) {
+                       const float *from = rect_from + stride_from*y*4;
+                       float *to = rect_to + stride_to*y*4;
+
+                       if(profile_to == profile_from) {
+                               /* same profile, copy */
+                               memcpy(to, from, sizeof(float)*4*width);
+                       }
+                       else if(profile_to == IB_PROFILE_LINEAR_RGB) {
+                               /* convert to sRGB to linear */
+                               if(predivide) {
+                                       for(x = 0; x < width; x++, from+=4, to+=4)
+                                               srgb_to_linearrgb_predivide_v4(to, from);
                                }
-                       } else {
-                               for (j = 0; j < h; j++){
-                                       bufferIndex = buffer + w*j*4;
-                                       dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
-                                       srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
-                                       for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
-                                               linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
-                                               bufferIndex[3]= srcFloatPxl[3];
-                                               F4TOCHAR4(bufferIndex, dstBytePxl);
-                                       }
+                               else {
+                                       for(x = 0; x < width; x++, from+=4, to+=4)
+                                               srgb_to_linearrgb_v4(to, from);
+                               }
+                       }
+                       else if(profile_to == IB_PROFILE_SRGB) {
+                               /* convert from linear to sRGB */
+                               if(predivide) {
+                                       for(x = 0; x < width; x++, from+=4, to+=4)
+                                               linearrgb_to_srgb_predivide_v4(to, from);
+                               }
+                               else {
+                                       for(x = 0; x < width; x++, from+=4, to+=4)
+                                               linearrgb_to_srgb_v4(to, from);
                                }
                        }
                }
        }
-       else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) {
-               if(channels==3) {
-                       for (j = 0; j < h; j++){
-                               bufferIndex = buffer + w*j*4;
-                               dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
-                               srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3;
-                               for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex+=4) {
-                                       copy_v3_v3(bufferIndex, srcFloatPxl);
-                                       F3TOCHAR4(bufferIndex, dstBytePxl);
-                                       bufferIndex[3] = 1.0;
+}
+
+/* byte to byte pixels, input and output 4-channel RGBA */
+void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from,
+       int profile_to, int profile_from, int predivide,
+       int width, int height, int stride_to, int stride_from)
+{
+       float tmp[4];
+       int x, y;
+
+       /* we need valid profiles */
+       BLI_assert(profile_to != IB_PROFILE_NONE);
+       BLI_assert(profile_from != IB_PROFILE_NONE);
+
+       /* always RGBA input */
+       for(y = 0; y < height; y++) {
+               const uchar *from = rect_from + stride_from*y*4;
+               uchar *to = rect_to + stride_to*y*4;
+
+               if(profile_to == profile_from) {
+                       /* same profile, copy */
+                       memcpy(to, from, sizeof(uchar)*4*width);
+               }
+               else if(profile_to == IB_PROFILE_LINEAR_RGB) {
+                       /* convert to sRGB to linear */
+                       if(predivide) {
+                               for(x = 0; x < width; x++, from+=4, to+=4) {
+                                       byte_to_float_v4(tmp, from);
+                                       srgb_to_linearrgb_predivide_v4(tmp, tmp);
+                                       float_to_byte_v4(to, tmp);
+                               }
+                       }
+                       else {
+                               for(x = 0; x < width; x++, from+=4, to+=4) {
+                                       byte_to_float_v4(tmp, from);
+                                       srgb_to_linearrgb_v4(tmp, tmp);
+                                       float_to_byte_v4(to, tmp);
                                }
                        }
                }
-               else {
-                       if (dither != 0.f) {
-                               for (j = 0; j < h; j++){
-                                       bufferIndex = buffer + w*j*4;
-                                       dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
-                                       srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
-                                       for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
-                                               const float d = (BLI_frand()-0.5f)*dither;
-                                               copy_v4_v4(bufferIndex, srcFloatPxl);
-                                               add_v4_fl(bufferIndex,d);
-                                               F4TOCHAR4(bufferIndex, dstBytePxl);
-                                       }
+               else if(profile_to == IB_PROFILE_SRGB) {
+                       /* convert from linear to sRGB */
+                       if(predivide) {
+                               for(x = 0; x < width; x++, from+=4, to+=4) {
+                                       byte_to_float_v4(tmp, from);
+                                       linearrgb_to_srgb_predivide_v4(tmp, tmp);
+                                       float_to_byte_v4(to, tmp);
                                }
-                       } else {
-                               for (j = 0; j < h; j++){
-                                       bufferIndex = buffer + w*j*4;
-                                       dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
-                                       srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
-                                       for(i = 0;  i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
-                                               copy_v4_v4(bufferIndex, srcFloatPxl);
-                                               F4TOCHAR4(bufferIndex, dstBytePxl);
-                                       }
+                       }
+                       else {
+                               for(x = 0; x < width; x++, from+=4, to+=4) {
+                                       byte_to_float_v4(tmp, from);
+                                       linearrgb_to_srgb_v4(tmp, tmp);
+                                       float_to_byte_v4(to, tmp);
                                }
                        }
                }
        }
+}
+
+/****************************** ImBuf Conversion *****************************/
+
+void IMB_rect_from_float(struct ImBuf *ibuf)
+{
+       int predivide= 0, profile_from;
+
+       /* verify we have a float buffer */
+       if(ibuf->rect_float==NULL)
+               return;
+
+       /* create byte rect if it didn't exist yet */
+       if(ibuf->rect==NULL)
+               imb_addrectImBuf(ibuf);
+
+       /* determine profiles */
+       if(ibuf->profile == IB_PROFILE_LINEAR_RGB)
+               profile_from = IB_PROFILE_LINEAR_RGB;
+       else if(ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE))
+               profile_from = IB_PROFILE_SRGB;
+       else
+               BLI_assert(0);
+
+       /* do conversion */
+       IMB_buffer_byte_from_float((uchar*)ibuf->rect, ibuf->rect_float,
+               ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide,
+               ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+
        /* ensure user flag is reset */
        ibuf->userflags &= ~IB_RECT_INVALID;
 }
 
-static void imb_float_from_rect_nonlinear(struct ImBuf *ibuf, float *fbuf)
+/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */
+void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h)
 {
-       float *tof = fbuf;
-       int i;
-       unsigned char *to = (unsigned char *) ibuf->rect;
-
-       for (i = ibuf->x * ibuf->y; i > 0; i--) 
-       {
-               tof[0] = ((float)to[0])*(1.0f/255.0f);
-               tof[1] = ((float)to[1])*(1.0f/255.0f);
-               tof[2] = ((float)to[2])*(1.0f/255.0f);
-               tof[3] = ((float)to[3])*(1.0f/255.0f);
-               to += 4; 
-               tof += 4;
-       }
-}
+       float *rect_float;
+       uchar *rect_byte;
+       int predivide= 0, profile_from;
+
+       /* verify we have a float buffer */
+       if(ibuf->rect_float==NULL || buffer==NULL)
+               return;
 
+       /* create byte rect if it didn't exist yet */
+       if(ibuf->rect==NULL)
+               imb_addrectImBuf(ibuf);
 
-static void imb_float_from_rect_linear(struct ImBuf *ibuf, float *fbuf)
-{
-       float *tof = fbuf;
-       int i;
-       unsigned char *to = (unsigned char *) ibuf->rect;
-
-       for (i = ibuf->x * ibuf->y; i > 0; i--) 
-       {
-               tof[0] = srgb_to_linearrgb(((float)to[0])*(1.0f/255.0f));
-               tof[1] = srgb_to_linearrgb(((float)to[1])*(1.0f/255.0f));
-               tof[2] = srgb_to_linearrgb(((float)to[2])*(1.0f/255.0f));
-               tof[3] = ((float)to[3])*(1.0f/255.0f);
-               to += 4; 
-               tof += 4;
-       }
+       /* determine profiles */
+       if(ibuf->profile == IB_PROFILE_LINEAR_RGB)
+               profile_from = IB_PROFILE_LINEAR_RGB;
+       else if(ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE))
+               profile_from = IB_PROFILE_SRGB;
+       else
+               BLI_assert(0);
+
+       /* do conversion */
+       rect_float= ibuf->rect_float + (x + y*ibuf->x)*ibuf->channels;
+       rect_byte= (uchar*)ibuf->rect + (x + y*ibuf->x)*4;
+
+       IMB_buffer_float_from_float(buffer, rect_float,
+               ibuf->channels, IB_PROFILE_SRGB, profile_from, predivide,
+               w, h, w, ibuf->x);
+
+       IMB_buffer_byte_from_float(rect_byte, buffer,
+               4, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, 0,
+               w, h, ibuf->x, w);
+
+       /* ensure user flag is reset */
+       ibuf->userflags &= ~IB_RECT_INVALID;
 }
 
 void IMB_float_from_rect(struct ImBuf *ibuf)
 {
-       /* quick method to convert byte to floatbuf */
-       if(ibuf->rect==NULL) return;
-       if(ibuf->rect_float==NULL) {
-               if (imb_addrectfloatImBuf(ibuf) == 0) return;
-       }
+       int predivide= 0, profile_from;
+
+       /* verify if we byte and float buffers */
+       if(ibuf->rect==NULL)
+               return;
+
+       if(ibuf->rect_float==NULL)
+               if(imb_addrectfloatImBuf(ibuf) == 0)
+                       return;
        
-       /* Float bufs should be stored linear */
-
-       if (ibuf->profile != IB_PROFILE_NONE) {
-               /* if the image has been given a profile then we're working 
-                * with color management in mind, so convert it to linear space */
-               imb_float_from_rect_linear(ibuf, ibuf->rect_float);
-       } else {
-               imb_float_from_rect_nonlinear(ibuf, ibuf->rect_float);
-       }
+       /* determine profiles */
+       if(ibuf->profile == IB_PROFILE_NONE)
+               profile_from = IB_PROFILE_LINEAR_RGB;
+       else
+               profile_from = IB_PROFILE_SRGB;
+       
+       /* do conversion */
+       IMB_buffer_float_from_byte(ibuf->rect_float, (uchar*)ibuf->rect,
+               IB_PROFILE_LINEAR_RGB, profile_from, predivide,
+               ibuf->x, ibuf->y, ibuf->x, ibuf->x);
 }
 
 /* no profile conversion */
 void IMB_float_from_rect_simple(struct ImBuf *ibuf)
 {
+       int predivide= 0;
+
        if(ibuf->rect_float==NULL)
                imb_addrectfloatImBuf(ibuf);
-       imb_float_from_rect_nonlinear(ibuf, ibuf->rect_float);
+
+       IMB_buffer_float_from_byte(ibuf->rect_float, (uchar*)ibuf->rect,
+               IB_PROFILE_SRGB, IB_PROFILE_SRGB, predivide,
+               ibuf->x, ibuf->y, ibuf->x, ibuf->x);
 }
 
 void IMB_convert_profile(struct ImBuf *ibuf, int profile)
 {
-       int ok= FALSE;
-       int i;
-
-       unsigned char *rct= (unsigned char *)ibuf->rect;
-       float *rctf= ibuf->rect_float;
+       int predivide= 0, profile_from, profile_to;
 
        if(ibuf->profile == profile)
                return;
 
-       if(ELEM(ibuf->profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) { /* from */
-               if(profile == IB_PROFILE_LINEAR_RGB) { /* to */
-                       if(ibuf->rect_float) {
-                               for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
-                                       rctf[0]= srgb_to_linearrgb(rctf[0]);
-                                       rctf[1]= srgb_to_linearrgb(rctf[1]);
-                                       rctf[2]= srgb_to_linearrgb(rctf[2]);
-                               }
-                       }
-                       if(ibuf->rect) {
-                               for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
-                                       rct[0]= (unsigned char)((srgb_to_linearrgb((float)rct[0]/255.0f) * 255.0f) + 0.5f);
-                                       rct[1]= (unsigned char)((srgb_to_linearrgb((float)rct[1]/255.0f) * 255.0f) + 0.5f);
-                                       rct[2]= (unsigned char)((srgb_to_linearrgb((float)rct[2]/255.0f) * 255.0f) + 0.5f);
-                               }
-                       }
-                       ok= TRUE;
-               }
-       }
-       else if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { /* from */
-               if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) { /* to */
-                       if(ibuf->rect_float) {
-                               for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
-                                       rctf[0]= linearrgb_to_srgb(rctf[0]);
-                                       rctf[1]= linearrgb_to_srgb(rctf[1]);
-                                       rctf[2]= linearrgb_to_srgb(rctf[2]);
-                               }
-                       }
-                       if(ibuf->rect) {
-                               for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
-                                       rct[0]= (unsigned char)((linearrgb_to_srgb((float)rct[0]/255.0f) * 255.0f) + 0.5f);
-                                       rct[1]= (unsigned char)((linearrgb_to_srgb((float)rct[1]/255.0f) * 255.0f) + 0.5f);
-                                       rct[2]= (unsigned char)((linearrgb_to_srgb((float)rct[2]/255.0f) * 255.0f) + 0.5f);
-                               }
-                       }
-                       ok= TRUE;
-               }
+       /* determine profiles */
+       if(ibuf->profile == IB_PROFILE_LINEAR_RGB)
+               profile_from = IB_PROFILE_LINEAR_RGB;
+       else if(ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE))
+               profile_from = IB_PROFILE_SRGB;
+       else
+               BLI_assert(0);
+
+       if(profile == IB_PROFILE_LINEAR_RGB)
+               profile_to = IB_PROFILE_LINEAR_RGB;
+       else if(ELEM(profile, IB_PROFILE_SRGB, IB_PROFILE_NONE))
+               profile_to = IB_PROFILE_SRGB;
+       else
+               BLI_assert(0);
+       
+       /* do conversion */
+       if(ibuf->rect_float) {
+               IMB_buffer_float_from_float(ibuf->rect_float, ibuf->rect_float,
+                       4, profile_to, profile_from, predivide,
+                       ibuf->x, ibuf->y, ibuf->x, ibuf->x);
        }
 
-       if(ok==FALSE){
-               printf("IMB_convert_profile: failed profile conversion %d -> %d\n", ibuf->profile, profile);
-               return;
+       if(ibuf->rect) {
+               IMB_buffer_byte_from_byte((uchar*)ibuf->rect, (uchar*)ibuf->rect,
+                       profile_to, profile_from, predivide,
+                       ibuf->x, ibuf->y, ibuf->x, ibuf->x);
        }
 
+       /* set new profile */
        ibuf->profile= profile;
 }
 
@@ -448,18 +599,25 @@ void IMB_convert_profile(struct ImBuf *ibuf, int profile)
  * if the return  */
 float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc)
 {
-       /* stupid but it works like this everywhere now */
-       const short is_lin_from= (ibuf->profile != IB_PROFILE_NONE);
-       const short is_lin_to= (profile != IB_PROFILE_NONE);
-
+       int predivide= 0, profile_from, profile_to;
+
+       /* determine profiles */
+       if(ibuf->profile == IB_PROFILE_NONE)
+               profile_from = IB_PROFILE_LINEAR_RGB;
+       else
+               profile_from = IB_PROFILE_SRGB;
+
+       if(profile == IB_PROFILE_NONE)
+               profile_to = IB_PROFILE_LINEAR_RGB;
+       else
+               profile_to = IB_PROFILE_SRGB;
        
-       if(is_lin_from == is_lin_to) {
+       if(profile_from == profile_to) {
+               /* simple case, just allocate the buffer and return */
                *alloc= 0;
 
-               /* simple case, just allocate the buffer and return */
-               if(ibuf->rect_float == NULL) {
+               if(ibuf->rect_float == NULL)
                        IMB_float_from_rect(ibuf);
-               }
 
                return ibuf->rect_float;
        }
@@ -469,42 +627,36 @@ float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc)
                *alloc= 1;
 
                if(ibuf->rect_float == NULL) {
-                       if(is_lin_to) {
-                               imb_float_from_rect_linear(ibuf, fbuf);
-                       }
-                       else {
-                               imb_float_from_rect_nonlinear(ibuf, fbuf);
-                       }
+                       IMB_buffer_float_from_byte(fbuf, (uchar*)ibuf->rect,
+                               profile_to, profile_from, predivide,
+                               ibuf->x, ibuf->y, ibuf->x, ibuf->x);
                }
                else {
-                       if(is_lin_to) { /* lin -> nonlin */
-                               linearrgb_to_srgb_rgba_rgba_buf(fbuf, ibuf->rect_float, ibuf->x * ibuf->y);
-                       }
-                       else { /* nonlin -> lin */
-                               srgb_to_linearrgb_rgba_rgba_buf(fbuf, ibuf->rect_float, ibuf->x * ibuf->y);
-                       }
+                       IMB_buffer_float_from_float(fbuf, ibuf->rect_float,
+                               4, profile_to, profile_from, predivide,
+                               ibuf->x, ibuf->y, ibuf->x, ibuf->x);
                }
 
                return fbuf;
        }
 }
 
+/**************************** Color to Grayscale *****************************/
 
 /* no profile conversion */
 void IMB_color_to_bw(struct ImBuf *ibuf)
 {
        float *rctf= ibuf->rect_float;
-       unsigned char *rct= (unsigned char *)ibuf->rect;
+       uchar *rct= (uchar*)ibuf->rect;
        int i;
+
        if(rctf) {
-               for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
+               for(i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4)
                        rctf[0]= rctf[1]= rctf[2]= rgb_to_grayscale(rctf);
-               }
        }
 
        if(rct) {
-               for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
+               for(i = ibuf->x * ibuf->y; i > 0; i--, rct+=4)
                        rct[0]= rct[1]= rct[2]= rgb_to_grayscale_byte(rct);
-               }
        }
 }
index bedb3e7429bbb6ea502c88876e1ce78f0b6e0d93..26a67c0504c441109befed38536a93dfdfcadfad 100644 (file)
@@ -214,7 +214,7 @@ typedef struct TFace {
 /* this is so we can save bmesh files that load in trunk, ignoring NGons
  * will eventually be removed */
 
-#define USE_MESH_FORWARDS_COMAT
+#define USE_BMESH_SAVE_AS_COMPAT
 
 
 #endif
index 99a36691b1001f3d488dd85ce932b64f197be918..8aaf1771b68eaa1da3dfbb3e895d55ca265606cf 100644 (file)
@@ -606,7 +606,9 @@ void generate_preview(void *data, bNode *node, CompBuf *stackbuf)
        RenderData *rd= data;
        bNodePreview *preview= node->preview;
        int xsize, ysize;
-       int color_manage= rd->color_mgt_flag & R_COLOR_MANAGEMENT;
+       int profile_from= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
+       int predivide= 0;
+       int dither= 0;
        unsigned char *rect;
        
        if(preview && stackbuf) {
@@ -633,10 +635,9 @@ void generate_preview(void *data, bNode *node, CompBuf *stackbuf)
                /* convert to byte for preview */
                rect= MEM_callocN(sizeof(unsigned char)*4*xsize*ysize, "bNodePreview.rect");
 
-               if(color_manage)
-                       floatbuf_to_srgb_byte(cbuf->rect, rect, 0, xsize, 0, ysize, xsize);
-               else
-                       floatbuf_to_byte(cbuf->rect, rect, 0, xsize, 0, ysize, xsize);
+               IMB_buffer_byte_from_float(rect, cbuf->rect,
+                       4, dither, IB_PROFILE_SRGB, profile_from, predivide, 
+                       xsize, ysize, xsize, xsize);
                
                free_compbuf(cbuf);
                if(stackbuf_use!=stackbuf)
index 9920cdab0398d6aafb9e362958c1fa75b764509f..fd7c87adea20bbf3d129436961dbd2a6fda4d1b5 100644 (file)
@@ -62,6 +62,7 @@ static bNodeSocketTemplate cmp_node_rlayers_out[]= {
 float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc)
 {
        float *rect;
+       int predivide= 0;
 
        *alloc= FALSE;
 
@@ -71,7 +72,11 @@ float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc)
                }
                else {
                        rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image");
-                       srgb_to_linearrgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y);
+
+                       IMB_buffer_float_from_float(rect, ibuf->rect_float,
+                               4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, predivide,
+                               ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+
                        *alloc= TRUE;
                }
        }
@@ -81,7 +86,11 @@ float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc)
                }
                else {
                        rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image");
-                       linearrgb_to_srgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y);
+
+                       IMB_buffer_float_from_float(rect, ibuf->rect_float,
+                               4, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, predivide,
+                               ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+
                        *alloc= TRUE;
                }
        }
index 9c4428919ec7d3583c31ae73c213bf6573864ac0..778334c960080a2f43a3a77941dc7c31c9105d45 100644 (file)
@@ -69,7 +69,11 @@ static PyStructSequence_Desc app_ffmpeg_info_desc = {
 static PyObject *make_ffmpeg_info(void)
 {
        PyObject *ffmpeg_info;
-       int pos = 0, curversion;
+       int pos = 0;
+
+#ifdef WITH_FFMPEG
+       int curversion;
+#endif
 
        ffmpeg_info = PyStructSequence_New(&BlenderAppFFmpegType);
        if (ffmpeg_info == NULL) {
index d82cff164969fd8837598eb5225b60e18f18b165..0a481629ee8ce8f3c8b43366912bbf80a0a3387f 100644 (file)
@@ -1149,32 +1149,17 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
        
        RE_AcquireResultImage(re, &rres);
 
-       if(rres.rect32) 
+       if(rres.rect32) {
                memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty);
+       }
        else if(rres.rectf) {
-               float *fp= rres.rectf;
-               int tot= rres.rectx*rres.recty;
-               char *cp= (char *)rect;
-               
-               if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
-                       /* Finally convert back to sRGB rendered image */ 
-                       for(;tot>0; tot--, cp+=4, fp+=4) {
-                               cp[0] = FTOCHAR(linearrgb_to_srgb(fp[0]));
-                               cp[1] = FTOCHAR(linearrgb_to_srgb(fp[1]));
-                               cp[2] = FTOCHAR(linearrgb_to_srgb(fp[2]));
-                               cp[3] = FTOCHAR(fp[3]);
-                       }
-               }
-               else {
-                       /* Color management is off : no conversion necessary */
-                       for(;tot>0; tot--, cp+=4, fp+=4) {
-                               cp[0] = FTOCHAR(fp[0]);
-                               cp[1] = FTOCHAR(fp[1]);
-                               cp[2] = FTOCHAR(fp[2]);
-                               cp[3] = FTOCHAR(fp[3]);
-                       }
-               }
+               int profile_from= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
+               int predivide= 0;
+               int dither= 0;
 
+               IMB_buffer_byte_from_float((unsigned char*)rect, rres.rectf,
+                       4, dither, IB_PROFILE_SRGB, profile_from, predivide,
+                       rres.rectx, rres.recty, rres.rectx, rres.rectx);
        }
        else
                /* else fill with black */
@@ -2567,24 +2552,18 @@ static void do_render_seq(Render * re)
 
        if(ibuf) {
                if(ibuf->rect_float) {
+                       /* color management: when off ensure rectf is non-lin, since thats what the internal
+                        * render engine delivers */
+                       int profile_to= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
+                       int profile_from= (ibuf->profile == IB_PROFILE_LINEAR_RGB)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
+                       int predivide= 0;
+
                        if (!rr->rectf)
                                rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");
                        
-                       /* color management: when off ensure rectf is non-lin, since thats what the internal
-                        * render engine delivers */
-                       if(re->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
-                               if(ibuf->profile == IB_PROFILE_LINEAR_RGB)
-                                       memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty);
-                               else
-                                       srgb_to_linearrgb_rgba_rgba_buf(rr->rectf, ibuf->rect_float, rr->rectx*rr->recty);
-                                       
-                       }
-                       else {
-                               if(ibuf->profile != IB_PROFILE_LINEAR_RGB)
-                                       memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty);
-                               else
-                                       linearrgb_to_srgb_rgba_rgba_buf(rr->rectf, ibuf->rect_float, rr->rectx*rr->recty);
-                       }
+                       IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float,
+                               4, profile_to, profile_from, predivide,
+                               rr->rectx, rr->recty, rr->rectx, rr->rectx);
                        
                        /* TSK! Since sequence render doesn't free the *rr render result, the old rect32
                           can hang around when sequence render has rendered a 32 bits one before */
index 22b1bf1b5080dc909709de5c763f9c350c8ff805..e528bb52bc980e0283092fe58233dbd722a77883 100644 (file)
@@ -46,7 +46,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_userdef_types.h"
 #include "DNA_windowmanager_types.h"
-#include "DNA_mesh_types.h" /* only for USE_MESH_FORWARDS_COMAT */
+#include "DNA_mesh_types.h" /* only for USE_BMESH_SAVE_AS_COMPAT */
 
 #include "BLF_translation.h"
 
@@ -2016,7 +2016,7 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot)
        RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file");
        RNA_def_boolean(ot->srna, "relative_remap", 1, "Remap Relative", "Remap relative paths when saving in a different directory");
        RNA_def_boolean(ot->srna, "copy", 0, "Save Copy", "Save a copy of the actual working state but does not make saved file active");
-#ifdef USE_MESH_FORWARDS_COMAT
+#ifdef USE_BMESH_SAVE_AS_COMPAT
        RNA_def_boolean(ot->srna, "use_mesh_compat", 0, "Legacy Mesh Format", "Save using legacy mesh format (no ngons)");
 #endif
 }