Color Management: fix for color sample information line
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 4 Sep 2012 12:32:32 +0000 (12:32 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 4 Sep 2012 12:32:32 +0000 (12:32 +0000)
- Color managed RGB values wouldn't be displayed anymore for
  byte images (which are currently unsupported to be managed).

- Color rectangle would now be color managed

- Sequencer was passing non-linear float to information line,
  now it'll pass linear float.

source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_node/node_view.c
source/blender/editors/space_sequencer/sequencer_view.c
source/blender/imbuf/IMB_colormanagement.h
source/blender/imbuf/intern/colormanagement.c

index 1fd29c0..3078aba 100644 (file)
@@ -222,8 +222,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int channel
                        dx += BLF_width(blf_mono_font, str);
                }
 
-               /* OCIO_TODO: make it fit better to overall color interaction */
-               if (fp && channels == 4) {
+               if (color_manage && channels == 4) {
                        float pixel[4];
 
                        IMB_display_buffer_pixel(pixel, fp,  &scene->view_settings, &scene->display_settings);
@@ -276,11 +275,12 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int channel
        }
 
        if (color_manage) {
-               linearrgb_to_srgb_v4(finalcol, col);
+               IMB_display_buffer_pixel(finalcol, col,  &scene->view_settings, &scene->display_settings);
        }
        else {
                copy_v4_v4(finalcol, col);
        }
+
        glDisable(GL_BLEND);
        glColor3fv(finalcol);
        dx += 5;
index 43e4db1..bc51864 100644 (file)
@@ -1986,6 +1986,7 @@ typedef struct ImageSampleInfo {
        float *zfp;
 
        int draw;
+       int color_manage;
 } ImageSampleInfo;
 
 static void image_sample_draw(const bContext *C, ARegion *ar, void *arg_info)
@@ -1994,8 +1995,7 @@ static void image_sample_draw(const bContext *C, ARegion *ar, void *arg_info)
        if (info->draw) {
                Scene *scene = CTX_data_scene(C);
 
-               /* no color management needed for images (color_manage=0) */
-               ED_image_draw_info(scene, ar, 0, info->channels, info->x, info->y, info->colp, info->colfp, info->zp, info->zfp);
+               ED_image_draw_info(scene, ar, info->color_manage, info->channels, info->x, info->y, info->colp, info->colfp, info->zp, info->zfp);
        }
 }
 
@@ -2094,6 +2094,8 @@ static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event)
                        info->colf[2] = (float)cp[2] / 255.0f;
                        info->colf[3] = (float)cp[3] / 255.0f;
                        info->colfp = info->colf;
+
+                       info->color_manage = FALSE;
                }
                if (ibuf->rect_float) {
                        fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
@@ -2103,6 +2105,8 @@ static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event)
                        info->colf[2] = fp[2];
                        info->colf[3] = fp[3];
                        info->colfp = info->colf;
+
+                       info->color_manage = TRUE;
                }
 
                if (ibuf->zbuf) {
index dfceb83..e86d2b4 100644 (file)
@@ -327,12 +327,12 @@ typedef struct ImageSampleInfo {
        void *draw_handle;
        int x, y;
        int channels;
-       int color_manage;
 
        unsigned char col[4];
        float colf[4];
 
        int draw;
+       int color_manage;
 } ImageSampleInfo;
 
 static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
@@ -341,7 +341,7 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
        ImageSampleInfo *info = arg_info;
 
        if (info->draw) {
-               ED_image_draw_info(scene, ar, (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT), info->channels,
+               ED_image_draw_info(scene, ar, info->color_manage, info->channels,
                                   info->x, info->y, info->col, info->colf,
                                   NULL, NULL /* zbuf - unused for nodes */
                                   );
@@ -457,6 +457,8 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
                        info->colf[1] = (float)cp[1] / 255.0f;
                        info->colf[2] = (float)cp[2] / 255.0f;
                        info->colf[3] = (float)cp[3] / 255.0f;
+
+                       info->color_manage = FALSE;
                }
                if (ibuf->rect_float) {
                        fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
@@ -465,6 +467,8 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
                        info->colf[1] = fp[1];
                        info->colf[2] = fp[2];
                        info->colf[3] = fp[3];
+
+                       info->color_manage = TRUE;
                }
 
                ED_node_sample_set(info->colf);
index f83a903..7dc8259 100644 (file)
@@ -49,6 +49,7 @@
 
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
+#include "IMB_colormanagement.h"
 
 #include "UI_view2d.h"
 
@@ -70,6 +71,7 @@ typedef struct ImageSampleInfo {
        float *colfp;
 
        int draw;
+int color_manage;
 } ImageSampleInfo;
 
 static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
@@ -78,8 +80,8 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
        ImageSampleInfo *info = arg_info;
 
        if (info->draw) {
-               ED_image_draw_info(scene, ar, (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT), info->channels,
-                                  info->x, info->y, info->col, info->colf, NULL, NULL);
+               ED_image_draw_info(scene, ar, info->color_manage, info->channels,
+                                  info->x, info->y, info->colp, info->colfp, NULL, NULL);
        }
 }
 
@@ -131,6 +133,8 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
                        info->colf[2] = (float)cp[2] / 255.0f;
                        info->colf[3] = (float)cp[3] / 255.0f;
                        info->colfp = info->colf;
+
+                       info->color_manage = FALSE;
                }
                if (ibuf->rect_float) {
                        fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
@@ -140,6 +144,11 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
                        info->colf[2] = fp[2];
                        info->colf[3] = fp[3];
                        info->colfp = info->colf;
+
+                       /* sequencer's image buffers are in non-linear space, need to make them linear */
+                       IMB_colormanagement_pixel_from_sequencer_space(info->colf);
+
+                       info->color_manage = TRUE;
                }
        }
        else {
index 5512515..d6a9a1d 100644 (file)
@@ -54,15 +54,15 @@ void IMB_colormanagement_exit(void);
 void IMB_colormanagement_colorspace_transform(float *buffer, int width, int height, int channels,
                                               const char *from_colorspace, const char *to_colorspace);
 
+void IMB_colormanagement_pixel_to_role(float pixel[4], int role);
+void IMB_colormanagement_pixel_from_role(float pixel[4], int role);
+
 void IMB_colormanagement_imbuf_to_role(struct ImBuf *ibuf, int role);
 void IMB_colormanagement_imbuf_from_role(struct ImBuf *ibuf, int role);
 
 void IMB_colormanagement_imbuf_make_scene_linear(struct ImBuf *ibuf,
                struct ColorManagedColorspaceSettings *colorspace_settings);
 
-void IMB_colormanagement_imbuf_to_sequencer_space(struct ImBuf *ibuf, int make_float);
-void IMB_colormanagement_imbuf_from_sequencer_space(struct ImBuf *ibuf);
-
 /* ** Public display buffers interfaces ** */
 
 void IMB_colormanage_cache_free(struct ImBuf *ibuf);
@@ -109,6 +109,17 @@ void IMB_partial_display_buffer_update(struct ImBuf *ibuf, const float *linear_b
                                        int stride, int offset_x, int offset_y,
                                        int xmin, int ymin, int xmax, int ymax);
 
+/* ** Area-specific functions ** */
+
+/* Sequencer */
+
+void IMB_colormanagement_imbuf_to_sequencer_space(struct ImBuf *ibuf, int make_float);
+void IMB_colormanagement_imbuf_from_sequencer_space(struct ImBuf *ibuf);
+
+void IMB_colormanagement_pixel_from_sequencer_space(float pixel[4]);
+
+
+/* Roles */
 enum {
        COLOR_ROLE_SCENE_LINEAR = 0,
        COLOR_ROLE_COLOR_PICKING,
index 1bedfb5..2ba1bec 100644 (file)
@@ -1019,81 +1019,60 @@ void IMB_colormanagement_imbuf_from_role(ImBuf *ibuf, int role)
 #endif
 }
 
-void IMB_colormanagement_imbuf_make_scene_linear(ImBuf *ibuf, ColorManagedColorspaceSettings *colorspace_settings)
+void IMB_colormanagement_pixel_to_role(float pixel[4], int role)
 {
 #ifdef WITH_OCIO
-       if (ibuf->rect_float) {
-               const char *from_colorspace = colorspace_settings->name;
-               const char *to_colorspace = global_role_scene_linear;
+               ConstProcessorRcPtr *processor;
+               const char *from_colorspace = global_role_scene_linear;
+               const char *to_colorspace = role_colorspace_name_get(role);
 
-               IMB_colormanagement_colorspace_transform(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
-                                                        from_colorspace, to_colorspace);
-       }
+               processor = create_colorspace_transform_processor(from_colorspace, to_colorspace);
+
+               if (processor) {
+                       OCIO_processorApplyRGBA(processor, pixel);
+
+                       OCIO_processorRelease(processor);
+               }
 #else
-       (void) ibuf;
-       (void) colorspace_settings;
+       (void) pixel;
+       (void) role;
 #endif
 }
 
-void IMB_colormanagement_imbuf_to_sequencer_space(ImBuf *ibuf, int make_float)
+void IMB_colormanagement_pixel_from_role(float pixel[4], int role)
 {
-       (void) make_float;
+#ifdef WITH_OCIO
+               ConstProcessorRcPtr *processor;
+               const char *from_colorspace = role_colorspace_name_get(role);
+               const char *to_colorspace = global_role_scene_linear;
 
-       if (!ibuf->rect_float) {
-               if (make_float && ibuf->rect) {
-                       /* when converting byte buffer to float in sequencer we need to make float
-                        * buffer be in sequencer's working space, which is currently only doable
-                        * from linear space.
-                        *
-                        */
+               processor = create_colorspace_transform_processor(from_colorspace, to_colorspace);
 
-                       /*
-                        * OCIO_TODO: would be nice to support direct single transform from byte to sequencer's
-                        */
+               if (processor) {
+                       OCIO_processorApplyRGBA(processor, pixel);
 
-                       ibuf->profile = IB_PROFILE_SRGB;
-                       IMB_float_from_rect(ibuf);
+                       OCIO_processorRelease(processor);
                }
-               else {
-                       /* if there's only byte buffer in image it's already in compositor's working space,
-                        * nothing to do here
-                        */
-
-                       return;
-               }
-       }
-
-#ifdef WITH_OCIO
-       if (global_role_sequencer[0]) {
-               IMB_colormanagement_imbuf_to_role(ibuf, COLOR_ROLE_SEQUENCER);
-
-               ibuf->profile = IB_PROFILE_NONE;
-       }
-       else
+#else
+       (void) pixel;
+       (void) role;
 #endif
-       {
-               /* if no sequencer's working space defined fallback to legacy sRGB space */
-               IMB_convert_profile(ibuf, IB_PROFILE_NONE);
-       }
 }
 
-void IMB_colormanagement_imbuf_from_sequencer_space(ImBuf *ibuf)
+void IMB_colormanagement_imbuf_make_scene_linear(ImBuf *ibuf, ColorManagedColorspaceSettings *colorspace_settings)
 {
-       if (!ibuf->rect_float)
-               return;
-
 #ifdef WITH_OCIO
-       if (global_role_sequencer[0]) {
-               IMB_colormanagement_imbuf_from_role(ibuf, COLOR_ROLE_SEQUENCER);
-               ibuf->profile = IB_PROFILE_LINEAR_RGB;
-       }
-       else
-#endif
-       {
-               /* if no sequencer's working space defined fallback to legacy sRGB space */
+       if (ibuf->rect_float) {
+               const char *from_colorspace = colorspace_settings->name;
+               const char *to_colorspace = global_role_scene_linear;
 
-               IMB_convert_profile(ibuf, IB_PROFILE_LINEAR_RGB);
+               IMB_colormanagement_colorspace_transform(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
+                                                        from_colorspace, to_colorspace);
        }
+#else
+       (void) ibuf;
+       (void) colorspace_settings;
+#endif
 }
 
 #ifdef WITH_OCIO
@@ -1958,3 +1937,81 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
        (void) display_buffer_flags;
 #endif
 }
+
+/*********************** Area-specific functions *************************/
+
+/* ** Sequencer ** */
+
+void IMB_colormanagement_imbuf_to_sequencer_space(ImBuf *ibuf, int make_float)
+{
+       (void) make_float;
+
+       if (!ibuf->rect_float) {
+               if (make_float && ibuf->rect) {
+                       /* when converting byte buffer to float in sequencer we need to make float
+                        * buffer be in sequencer's working space, which is currently only doable
+                        * from linear space.
+                        *
+                        */
+
+                       /*
+                        * OCIO_TODO: would be nice to support direct single transform from byte to sequencer's
+                        */
+
+                       ibuf->profile = IB_PROFILE_SRGB;
+                       IMB_float_from_rect(ibuf);
+               }
+               else {
+                       /* if there's only byte buffer in image it's already in compositor's working space,
+                        * nothing to do here
+                        */
+
+                       return;
+               }
+       }
+
+#ifdef WITH_OCIO
+       if (global_role_sequencer[0]) {
+               IMB_colormanagement_imbuf_to_role(ibuf, COLOR_ROLE_SEQUENCER);
+
+               ibuf->profile = IB_PROFILE_NONE;
+       }
+       else
+#endif
+       {
+               /* if no sequencer's working space defined fallback to legacy sRGB space */
+               IMB_convert_profile(ibuf, IB_PROFILE_NONE);
+       }
+}
+
+void IMB_colormanagement_imbuf_from_sequencer_space(ImBuf *ibuf)
+{
+       if (!ibuf->rect_float)
+               return;
+
+#ifdef WITH_OCIO
+       if (global_role_sequencer[0]) {
+               IMB_colormanagement_imbuf_from_role(ibuf, COLOR_ROLE_SEQUENCER);
+               ibuf->profile = IB_PROFILE_LINEAR_RGB;
+       }
+       else
+#endif
+       {
+               /* if no sequencer's working space defined fallback to legacy sRGB space */
+
+               IMB_convert_profile(ibuf, IB_PROFILE_LINEAR_RGB);
+       }
+}
+
+void IMB_colormanagement_pixel_from_sequencer_space(float pixel[4])
+{
+#ifdef WITH_OCIO
+       if (global_role_sequencer[0]) {
+               IMB_colormanagement_pixel_from_role(pixel, COLOR_ROLE_SEQUENCER);
+       }
+       else
+#endif
+       {
+               srgb_to_linearrgb_v4(pixel, pixel);
+       }
+}