diff options
Diffstat (limited to 'source/blender/imbuf/intern/divers.c')
-rw-r--r-- | source/blender/imbuf/intern/divers.c | 137 |
1 files changed, 42 insertions, 95 deletions
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index 8acceb77b36..9ce5d0e30da 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -40,6 +40,9 @@ #include "IMB_imbuf.h" #include "IMB_allocimbuf.h" +#include "IMB_colormanagement.h" +#include "IMB_colormanagement_intern.h" + #include "MEM_guardedalloc.h" /**************************** Interlace/Deinterlace **************************/ @@ -522,32 +525,34 @@ void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from, void IMB_rect_from_float(ImBuf *ibuf) { int predivide = (ibuf->flags & IB_cm_predivide); - int profile_from; + float *buffer; + const char *from_colorspace; /* 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 { - profile_from = IB_PROFILE_SRGB; /* should never happen */ - BLI_assert(0); + if (ibuf->rect == NULL) { + if (imb_addrectImBuf(ibuf) == 0) + return; } - /* 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); + if (ibuf->float_colorspace == NULL) + from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); + else + from_colorspace = ibuf->float_colorspace->name; + + buffer = MEM_dupallocN(ibuf->rect_float); + + /* first make float buffer in byte space */ + IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, ibuf->rect_colorspace->name, predivide); + + /* convert float to byte */ + IMB_buffer_byte_from_float((unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, + FALSE, ibuf->x, ibuf->y, ibuf->x, ibuf->x); + + MEM_freeN(buffer); /* ensure user flag is reset */ ibuf->userflags &= ~IB_RECT_INVALID; @@ -559,7 +564,7 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w float *rect_float; uchar *rect_byte; int predivide = (ibuf->flags & IB_cm_predivide); - int profile_from; + int profile_from = IB_PROFILE_LINEAR_RGB; /* verify we have a float buffer */ if (ibuf->rect_float == NULL || buffer == NULL) @@ -569,18 +574,6 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w 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 { - profile_from = IB_PROFILE_SRGB; /* should never happen */ - 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; @@ -589,6 +582,7 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w ibuf->channels, IB_PROFILE_SRGB, profile_from, predivide, w, h, w, ibuf->x); + /* XXX: need to convert to image buffer's rect space */ IMB_buffer_byte_from_float(rect_byte, buffer, 4, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, 0, w, h, ibuf->x, w); @@ -600,26 +594,23 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w void IMB_float_from_rect(ImBuf *ibuf) { int predivide = (ibuf->flags & IB_cm_predivide); - int profile_from; /* verify if we byte and float buffers */ if (ibuf->rect == NULL) return; - if (ibuf->rect_float == NULL) + if (ibuf->rect_float == NULL) { if (imb_addrectfloatImBuf(ibuf) == 0) return; - - /* 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); + } + + /* first, create float buffer in non-linear space */ + IMB_buffer_float_from_byte(ibuf->rect_float, (unsigned char *) ibuf->rect, IB_PROFILE_SRGB, IB_PROFILE_SRGB, + FALSE, ibuf->x, ibuf->y, ibuf->x, ibuf->x); + + /* then make float be in linear space */ + IMB_colormanagement_colorspace_to_scene_linear(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, + ibuf->rect_colorspace, predivide); } /* no profile conversion */ @@ -635,63 +626,19 @@ void IMB_float_from_rect_simple(ImBuf *ibuf) ibuf->x, ibuf->y, ibuf->x, ibuf->x); } -void IMB_convert_profile(ImBuf *ibuf, int profile) -{ - int predivide = (ibuf->flags & IB_cm_predivide); - int profile_from, profile_to; - - if (ibuf->profile == profile) - return; - - /* 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); - profile_from = IB_PROFILE_SRGB; /* dummy, should never happen */ - } - - 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); - profile_to = IB_PROFILE_SRGB; /* dummy, should never happen */ - } - - /* 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 (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; -} - /* use when you need to get a buffer with a certain profile * if the return */ + +/* OCIO_TODO: used only by Cineon/DPX exporter which is still broken, so can not guarantee + * this function is working properly + */ float *IMB_float_profile_ensure(ImBuf *ibuf, int profile, int *alloc) { int predivide = (ibuf->flags & IB_cm_predivide); - int profile_from, profile_to; - - /* determine profiles */ - if (ibuf->profile == IB_PROFILE_NONE) - profile_from = IB_PROFILE_LINEAR_RGB; - else - profile_from = IB_PROFILE_SRGB; + int profile_from = IB_PROFILE_LINEAR_RGB; + int profile_to; + /* determine profile */ if (profile == IB_PROFILE_NONE) profile_to = IB_PROFILE_LINEAR_RGB; else |