diff --git a/release/scripts/ui/properties_render.py b/release/scripts/ui/properties_render.py index c6b1e8816e0..00efb79a798 100644 --- a/release/scripts/ui/properties_render.py +++ b/release/scripts/ui/properties_render.py @@ -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() diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index eff42e48dad..a22168e06a3 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -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 diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c index 816d2d27b78..1395b047113 100644 --- a/source/blender/imbuf/intern/cineon/cineon_dpx.c +++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c @@ -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; irect; + + 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; + } +}