diff options
Diffstat (limited to 'source/blender/imbuf/intern/openexr/openexr_api.cpp')
-rw-r--r-- | source/blender/imbuf/intern/openexr/openexr_api.cpp | 93 |
1 files changed, 66 insertions, 27 deletions
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index fd505115994..a0969979817 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -46,6 +46,7 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void) #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" +#include "BLI_math_color.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -228,35 +229,65 @@ static int imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags) sizeof(float), sizeof(float) * -width)); if(ibuf->rect_float) { float *from; - - for (int i = ibuf->y-1; i >= 0; i--) - { - from= ibuf->rect_float + channels*i*width; - - for (int j = ibuf->x; j > 0; j--) + + if(ibuf->profile == IB_PROFILE_LINEAR_RGB) { + for (int i = ibuf->y-1; i >= 0; i--) + { + from= ibuf->rect_float + channels*i*width; + + for (int j = ibuf->x; j > 0; j--) + { + to->r = from[0]; + to->g = from[1]; + to->b = from[2]; + to->a = (channels >= 4)? from[3]: 1.0f; + to++; from += 4; + } + } + } + else { + for (int i = ibuf->y-1; i >= 0; i--) { - to->r = from[0]; - to->g = (channels >= 2)? from[1]: from[0]; - to->b = (channels >= 3)? from[2]: from[0]; - to->a = (channels >= 4)? from[3]: from[0]; - to++; from += 4; + from= ibuf->rect_float + channels*i*width; + + for (int j = ibuf->x; j > 0; j--) + { + to->r = srgb_to_linearrgb(from[0]); + to->g = srgb_to_linearrgb(from[1]); + to->b = srgb_to_linearrgb(from[2]); + to->a = (channels >= 4)? from[3]: 1.0f; + to++; from += 4; + } } } } else { unsigned char *from; - - for (int i = ibuf->y-1; i >= 0; i--) - { - from= (unsigned char *)ibuf->rect + channels*i*width; - - for (int j = ibuf->x; j > 0; j--) + + if(ibuf->profile == IB_PROFILE_LINEAR_RGB) { + for (int i = ibuf->y-1; i >= 0; i--) + { + for (int j = ibuf->x; j > 0; j--) + { + to->r = (float)(from[0])/255.0; + to->g = (float)(from[1])/255.0; + to->b = (float)(from[2])/255.0; + to->a = (float)(channels >= 4) ? from[3]/255.0 : 1.0f; + to++; from += 4; + } + } + } + else { + for (int i = ibuf->y-1; i >= 0; i--) { - to->r = (float)(from[0])/255.0; - to->g = (float)((channels >= 2)? from[1]: from[0])/255.0; - to->b = (float)((channels >= 3)? from[2]: from[0])/255.0; - to->a = (float)((channels >= 4)? from[3]: from[0])/255.0; - to++; from += 4; + for (int j = ibuf->x; j > 0; j--) + { + to->r = srgb_to_linearrgb((float)from[0] / 255.0); + to->g = srgb_to_linearrgb((float)from[1] / 255.0); + to->b = srgb_to_linearrgb((float)from[2] / 255.0); + to->a = channels >= 4 ? (float)from[3]/255.0 : 1.0f; + to++; from += 4; + } } } } @@ -308,9 +339,9 @@ static int imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags) float *rect[4] = {NULL, NULL, NULL, NULL}; rect[0]= ibuf->rect_float + channels*(height-1)*width; - rect[1]= (channels >= 2)? rect[0]+1: rect[0]; - rect[2]= (channels >= 3)? rect[0]+2: rect[0]; - rect[3]= (channels >= 4)? rect[0]+3: rect[0]; + rect[1]= rect[0]+1; + rect[2]= rect[0]+2; + rect[3]= (channels >= 4)? rect[0]+3:rect[0]; /* red as alpha, is this needed since alpha isnt written? */ frameBuffer.insert ("R", Slice (FLOAT, (char *)rect[0], xstride, ystride)); frameBuffer.insert ("G", Slice (FLOAT, (char *)rect[1], xstride, ystride)); @@ -993,8 +1024,16 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags) file->setFrameBuffer (frameBuffer); file->readPixels (dw.min.y, dw.max.y); - - IMB_rect_from_float(ibuf); + + // XXX, ImBuf has no nice way to deal with this. + // ideally IM_rect would be used when the caller wants a rect BUT + // at the moment all functions use IM_rect. + // Disabling this is ok because all functions should check if a rect exists and create one on demand. + // + // Disabling this because the sequencer frees immediate. + // + // if(flag & IM_rect) + // IMB_rect_from_float(ibuf); } } |