bugfix [#23406] DPX Images load darker then saved, UI broken.
authorCampbell Barton <ideasman42@gmail.com>
Wed, 1 Dec 2010 02:54:10 +0000 (02:54 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 1 Dec 2010 02:54:10 +0000 (02:54 +0000)
- a linear float buffer was being created and saved into a non-linear DPX/Cineon file.
- removed the UI since the settings are not used at the moment.

added a utility function IMB_float_profile_ensure(), which returns a float buffer in the requested profile, using the existing if needed or returning an allocated buffer if the profile is different to that of the ImBuf. - Useful this case where the save function has its own linear setting.

release/scripts/ui/properties_render.py
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/cineon/cineon_dpx.c
source/blender/imbuf/intern/divers.c

index c6b1e8816e09de2a47e5db9ad7fa033ef32a296a..00efb79a79898b35082ecfdbbf72fdbbfbb46f8a 100644 (file)
@@ -336,7 +336,10 @@ class RENDER_PT_output(RenderButtonsPanel, bpy.types.Panel):
             col.prop(rd, "jpeg2k_ycc")
 
         elif file_format in ('CINEON', 'DPX'):
+            
             split = layout.split()
+            split.label("FIXME: hard coded Non-Linear, Gamma:1.0")
+            '''
             col = split.column()
             col.prop(rd, "use_cineon_log", text="Convert to Log")
 
@@ -345,6 +348,7 @@ class RENDER_PT_output(RenderButtonsPanel, bpy.types.Panel):
             col.prop(rd, "cineon_black", text="Black")
             col.prop(rd, "cineon_white", text="White")
             col.prop(rd, "cineon_gamma", text="Gamma")
+            '''
 
         elif file_format == 'TIFF':
             split = layout.split()
index eff42e48dad65434ce0a543a910f3c098f715ae2..a22168e06a30474d3a5550651d477d195b00a75e 100644 (file)
@@ -321,6 +321,7 @@ void IMB_float_from_rect(struct ImBuf *ibuf);
 void IMB_float_from_rect_simple(struct ImBuf *ibuf); /* no profile conversion */
 /* note, check that the conversion exists, only some are supported */
 void IMB_convert_profile(struct ImBuf *ibuf, int profile);
+float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc);
 
 /**
  * Change the ordering of the color bytes pointed to by rect from
index 816d2d27b78868526fdddaf1da59fc44d0a8eccd..1395b04711301a17ff8d67e549acba782d6a1ff8 100644 (file)
@@ -44,6 +44,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#if 0
 static void cineon_conversion_parameters(LogImageByteConversionParameters *params)
 {
 //     params->blackPoint = scene?scene->r.cineonblack:95;
@@ -55,8 +56,8 @@ static void cineon_conversion_parameters(LogImageByteConversionParameters *param
        params->whitePoint = 685;
        params->gamma = 1.0f;
        params->doLogarithm = 0;
-       
 }
+#endif
 
 static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags)
 {
@@ -116,34 +117,33 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int
        return ibuf;
 }
 
-static int imb_save_dpx_cineon(ImBuf *buf, const char *filename, int use_cineon, int flags)
+static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon, int flags)
 {
        LogImageByteConversionParameters conversion;
-       int width, height, depth;
+       const int width= ibuf->x;
+       const int height= ibuf->y;
+       const int depth= 3;
        LogImageFile* logImage;
        unsigned short* line, *pixel;
        int i, j;
        int index;
        float *fline;
+       float *fbuf;
+       int is_alloc= 0;
        
        (void)flags; /* unused */
 
-       cineon_conversion_parameters(&conversion);
+       // cineon_conversion_parameters(&conversion);
+       logImageGetByteConversionDefaults(&conversion);
 
        /*
         * Get the drawable for the current image...
         */
 
-       width = buf->x;
-       height = buf->y;
-       depth = 3;
-       
-       
-       if (!buf->rect_float) {
-               IMB_float_from_rect(buf);
-               if (!buf->rect_float) { /* in the unlikely event that converting to a float buffer fails */
-                       return 0;
-               }
+       fbuf= IMB_float_profile_ensure(ibuf, conversion.doLogarithm ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE, &is_alloc);
+
+       if (fbuf == NULL) { /* in the unlikely event that converting to a float buffer fails */
+               return 0;
        }
        
        logImageSetVerbose((G.f & G_DEBUG) ? 1:0);
@@ -151,14 +151,16 @@ static int imb_save_dpx_cineon(ImBuf *buf, const char *filename, int use_cineon,
 
        if (!logImage) return 0;
        
-       logImageSetByteConversion(logImage, &conversion);
+       if(logImageSetByteConversion(logImage, &conversion)==0) {
+               printf("error setting args\n");
+       }
 
        index = 0;
        line = MEM_mallocN(sizeof(unsigned short)*depth*width, "line");
        
        /*note that image is flipped when sent to logImageSetRowBytes (see last passed parameter).*/
        for (j = 0; j < height; ++j) {
-               fline = &buf->rect_float[width*j*4];
+               fline = &fbuf[width*j*4];
                for (i=0; i<width; i++) {
                        float *fpix, fpix2[3];
                        /*we have to convert to cinepaint's 16-bit-per-channel here*/
@@ -179,6 +181,11 @@ static int imb_save_dpx_cineon(ImBuf *buf, const char *filename, int use_cineon,
        logImageClose(logImage);
 
        MEM_freeN(line);
+       
+       if(is_alloc) {
+               MEM_freeN(fbuf);
+       }
+       
        return 1;
 }
 
index 245dcfb7fae7a6e930bb90a24cded321adf858ad..f2803737377218930208950a5c67f221b796dde0 100644 (file)
@@ -40,6 +40,8 @@
 #include "BKE_utildefines.h"
 #include "BKE_colortools.h"
 
+#include "MEM_guardedalloc.h"
+
 void IMB_de_interlace(struct ImBuf *ibuf)
 {
        struct ImBuf * tbuf1, * tbuf2;
@@ -187,13 +189,47 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
        }
 }
 
+static void imb_float_from_rect_nonlinear(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] = ((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;
+       }
+}
+
+
+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;
+       }
+}
+
 void IMB_float_from_rect(struct ImBuf *ibuf)
 {
        /* quick method to convert byte to floatbuf */
        float *tof = ibuf->rect_float;
-       int i;
+
        unsigned char *to = (unsigned char *) ibuf->rect;
-       
        if(to==NULL) return;
        if(tof==NULL) {
                if (imb_addrectfloatImBuf(ibuf) == 0) return;
@@ -205,41 +241,16 @@ void IMB_float_from_rect(struct ImBuf *ibuf)
        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 */
-               
-               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;
-               }
+               imb_float_from_rect_linear(ibuf, ibuf->rect_float);
        } else {
-               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;
-               }
+               imb_float_from_rect_nonlinear(ibuf, ibuf->rect_float);
        }
 }
 
 /* no profile conversion */
 void IMB_float_from_rect_simple(struct ImBuf *ibuf)
 {
-       int profile = IB_PROFILE_NONE;
-
-       /* no color management:
-        * don't disturb the existing profiles */
-       SWAP(int, ibuf->profile, profile);
-
-       IMB_float_from_rect(ibuf);
-
-       SWAP(int, ibuf->profile, profile);
+       imb_float_from_rect_nonlinear(ibuf, ibuf->rect_float);
 }
 
 void IMB_convert_profile(struct ImBuf *ibuf, int profile)
@@ -299,3 +310,48 @@ void IMB_convert_profile(struct ImBuf *ibuf, int profile)
 
        ibuf->profile= profile;
 }
+
+/* use when you need to get a buffer with a certain 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);
+
+       
+       if(is_lin_from == is_lin_to) {
+               *alloc= 0;
+
+               /* simple case, just allocate the buffer and return */
+               if(ibuf->rect_float == NULL) {
+                       IMB_float_from_rect(ibuf);
+               }
+
+               return ibuf->rect_float;
+       }
+       else {
+               /* conversion is needed, first check */
+               float *fbuf= MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "IMB_float_profile_ensure");
+               *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);
+                       }
+               }
+               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);
+                       }
+               }
+
+               return fbuf;
+       }
+}