Color Management: don't apply display transform on Non-Color images
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 19 Sep 2012 15:01:36 +0000 (15:01 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 19 Sep 2012 15:01:36 +0000 (15:01 +0000)
Also don't color manage data buffers in texture painting.

Makes it possible to view heights and normal maps in proper space
and also paint on them without applying extra transformation.

intern/opencolorio/ocio_capi.cpp
intern/opencolorio/ocio_capi.h
intern/opencolorio/ocio_capi_stub.cpp
source/blender/editors/sculpt_paint/paint_image.c
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/intern/IMB_colormanagement_intern.h
source/blender/imbuf/intern/colormanagement.c

index 2fa66e5d2f5de06e23983654a3cc9a8b7c7bb5e4..cc45eb9b2ddcda86ce7a59634850669805bbca49 100644 (file)
@@ -302,6 +302,11 @@ int OCIO_colorSpaceIsInvertible(ConstColorSpaceRcPtr *cs)
        return true;
 }
 
+int OCIO_colorSpaceIsData(ConstColorSpaceRcPtr *cs)
+{
+       return ((*cs)->isData());
+}
+
 void OCIO_colorSpaceRelease(ConstColorSpaceRcPtr *cs)
 {
        MEM_DELETE(cs, ConstColorSpaceRcPtr);
index e774e3e8548d4a654b80d283baa99a3d4718f2f6..0218ccfafcde7255f3f008330ff38c14ff54820a 100644 (file)
@@ -73,6 +73,7 @@ ConstColorSpaceRcPtr *OCIO_configGetColorSpace(ConstConfigRcPtr *config, const c
 int OCIO_configGetIndexForColorSpace(ConstConfigRcPtr *config, const char *name);
 
 int OCIO_colorSpaceIsInvertible(ConstColorSpaceRcPtr *cs);
+int OCIO_colorSpaceIsData(ConstColorSpaceRcPtr *cs);
 
 void OCIO_colorSpaceRelease(ConstColorSpaceRcPtr *cs);
 
index f910d1a34cf7727894506b529b710b82ebe7d259..2112b88ad728b7ad8a3b877af593031665865bdd 100644 (file)
@@ -174,6 +174,11 @@ int OCIO_colorSpaceIsInvertible(ConstColorSpaceRcPtr *cs)
        return 1;
 }
 
+int OCIO_colorSpaceIsData(ConstColorSpaceRcPtr *cs)
+{
+       return 0;
+}
+
 void OCIO_colorSpaceRelease(ConstColorSpaceRcPtr *cs)
 {
 }
index 15593b57aac7b9b2e072b834247e9b9f288ea969..a0e3cb1d20f5a75ab6e4aa44c682edd154d3c5dc 100644 (file)
@@ -4596,10 +4596,13 @@ static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter,
 {
        ImBuf *ibuf = BKE_image_get_ibuf(image, s->sima ? &s->sima->iuser : NULL);
        float pos[2];
+       int is_data;
 
        if (!ibuf)
                return 0;
 
+       is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
+
        pos[0] = uv[0] * ibuf->x;
        pos[1] = uv[1] * ibuf->y;
 
@@ -4608,7 +4611,7 @@ static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter,
        /* OCIO_TODO: float buffers are now always linear, so always use color correction
         *            this should probably be changed when texture painting color space is supported
         */
-       if (BKE_brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, TRUE)) {
+       if (BKE_brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, is_data == FALSE)) {
                if (update)
                        imapaint_image_update(s->scene, s->sima, image, ibuf, texpaint);
                return 1;
index 93e213dc48665366f3b2015cce22b778ff83e6bf..f03f709f13fc15be794c78d042c88f9961dcc6e9 100644 (file)
@@ -131,6 +131,7 @@ typedef struct ImBuf {
        struct ColorSpace *float_colorspace;         /* color space of float buffer, used by sequencer only */
        unsigned int *display_buffer_flags;          /* array of per-display display buffers dirty flags */
        struct ColormanageCache *colormanage_cache;  /* cache used by color management */
+       int colormanage_flag;
 
        /* information for compressed textures */
        struct DDSData dds_data;
@@ -260,4 +261,8 @@ extern const char *imb_ext_image_qt[];
 extern const char *imb_ext_movie[];
 extern const char *imb_ext_audio[];
 
+enum {
+       IMB_COLORMANAGE_IS_DATA = (1 << 0)
+};
+
 #endif
index 0c002b788485c1a8f854a561b33cdaefabbe2942..059bdee00eb20212b1c91e613654e6a2ff4e0d8d 100644 (file)
@@ -48,6 +48,7 @@ typedef struct ColorSpace {
        struct ConstProcessorRcPtr *from_scene_linear;
 
        int is_invertible;
+       int is_data;
 } ColorSpace;
 
 typedef struct ColorManagedDisplay {
@@ -79,7 +80,7 @@ struct ColorManagedView *colormanage_view_add(const char *name);
 struct ColorManagedView *colormanage_view_get_indexed(int index);
 struct ColorManagedView *colormanage_view_get_named(const char *name);
 
-struct ColorSpace *colormanage_colorspace_add(const char *name, const char *description, int is_invertible);
+struct ColorSpace *colormanage_colorspace_add(const char *name, const char *description, int is_invertible, int is_data);
 struct ColorSpace *colormanage_colorspace_get_named(const char *name);
 struct ColorSpace *colormanage_colorspace_get_roled(int role);
 struct ColorSpace *colormanage_colorspace_get_indexed(int index);
index 0e0937576eb46fb20cef5d80a5fa200ed0c06148..310448074fb86e1ef4856b3c6d23314c6bf98e0a 100644 (file)
@@ -450,15 +450,16 @@ static void colormanage_load_config(ConstConfigRcPtr *config)
        for (index = 0 ; index < tot_colorspace; index++) {
                ConstColorSpaceRcPtr *ocio_colorspace;
                const char *description;
-               int is_invertible;
+               int is_invertible, is_data;
 
                name = OCIO_configGetColorSpaceNameByIndex(config, index);
 
                ocio_colorspace = OCIO_configGetColorSpace(config, name);
                description = OCIO_colorSpaceGetDescription(ocio_colorspace);
                is_invertible = OCIO_colorSpaceIsInvertible(ocio_colorspace);
+               is_data = OCIO_colorSpaceIsData(ocio_colorspace);
 
-               colormanage_colorspace_add(name, description, is_invertible);
+               colormanage_colorspace_add(name, description, is_invertible, is_data);
 
                OCIO_colorSpaceRelease(ocio_colorspace);
        }
@@ -847,9 +848,15 @@ void colormanage_imbuf_set_default_spaces(ImBuf *ibuf)
 void colormanage_imbuf_make_linear(ImBuf *ibuf, const char *from_colorspace)
 {
        if (ibuf->rect_float) {
+               ColorSpace *colorspace = colormanage_colorspace_get_named(from_colorspace);
                const char *to_colorspace = global_role_scene_linear;
                int predivide = ibuf->flags & IB_cm_predivide;
 
+               if (colorspace->is_data) {
+                       ibuf->colormanage_flag |= IMB_COLORMANAGE_IS_DATA;
+                       return;
+               }
+
                if (ibuf->rect)
                        imb_freerectImBuf(ibuf);
 
@@ -1049,6 +1056,7 @@ typedef struct DisplayBufferThread {
        int channels;
        float dither;
        int predivide;
+       int is_data;
 
        const char *byte_colorspace;
        const char *float_colorspace;
@@ -1078,6 +1086,7 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l
        int predivide = ibuf->flags & IB_cm_predivide;
        int channels = ibuf->channels;
        float dither = ibuf->dither;
+       int is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
 
        int offset = channels * start_line * ibuf->x;
 
@@ -1105,6 +1114,7 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l
        handle->channels = channels;
        handle->dither = dither;
        handle->predivide = predivide;
+       handle->is_data = is_data;
 
        handle->byte_colorspace = init_data->byte_colorspace;
        handle->float_colorspace = init_data->float_colorspace;
@@ -1189,11 +1199,19 @@ static void *do_display_buffer_apply_thread(void *handle_v)
        int height = handle->tot_line;
        float dither = handle->dither;
        int predivide = handle->predivide;
+       int is_data = handle->is_data;
 
        float *linear_buffer = display_buffer_apply_get_linear_buffer(handle);
 
-       /* apply processor */
-       IMB_colormanagement_processor_apply(cm_processor, linear_buffer, width, height, channels, predivide);
+       if (is_data) {
+               /* special case for data buffers - no color space conversions,
+                * only generate byte buffers
+                */
+       }
+       else {
+               /* apply processor */
+               IMB_colormanagement_processor_apply(cm_processor, linear_buffer, width, height, channels, predivide);
+       }
 
        /* copy result to output buffers */
        if (display_buffer_byte) {
@@ -1938,7 +1956,7 @@ static void colormanage_description_strip(char *description)
        }
 }
 
-ColorSpace *colormanage_colorspace_add(const char *name, const char *description, int is_invertible)
+ColorSpace *colormanage_colorspace_add(const char *name, const char *description, int is_invertible, int is_data)
 {
        ColorSpace *colorspace, *prev_space;
        int counter = 1;
@@ -1954,6 +1972,7 @@ ColorSpace *colormanage_colorspace_add(const char *name, const char *description
        }
 
        colorspace->is_invertible = is_invertible;
+       colorspace->is_data = is_data;
 
        for (prev_space = global_colorspaces.first; prev_space; prev_space = prev_space->next) {
                if (BLI_strcasecmp(prev_space->name, colorspace->name) > 0)
@@ -2141,6 +2160,7 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
        float *display_buffer_float = NULL;
        int width = xmax - xmin;
        int height = ymax - ymin;
+       int is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
 
        if (dither != 0.0f) {
                display_buffer_float = MEM_callocN(channels * width * height * sizeof(float), "display buffer for dither");
@@ -2161,10 +2181,12 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
                                IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace);
                        }
 
-                       if (predivide)
-                               IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
-                       else
-                               IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
+                       if (!is_data) {
+                               if (predivide)
+                                       IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
+                               else
+                                       IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
+                       }
 
                        if (display_buffer_float) {
                                int index = ((y - ymin) * width + (x - xmin)) * channels;