Color management refactoiring and some extra options
authorSergey Sharybin <sergey.vfx@gmail.com>
Sat, 30 Jun 2012 12:37:16 +0000 (12:37 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sat, 30 Jun 2012 12:37:16 +0000 (12:37 +0000)
- Move space-being settings (such as view transform) into own
  DNA and RNA structure to avoid code duplication in some areas
  and save some arguments on display buffer acquiring function.

  Also added some utility functions to BKE to manipulate this
  settings.

- Replace static sized color managed buffer flags array with
  dynamically sized array which matches actual number of displays.

  Probably this flags better be transfposed so it'll support
  any number of view transforms and 32 displays (currently it's
  other way around). it's runtime flags only, so would be simple
  to change any time.

- Added support of configurable exposure and gamma.

  Changing this settings wouldn't generate new item in cache,
  it'll affect on buffer with the same color spaces conversion.

  It'll also run full color transform from scratch on every run,
  this could be changes in a way that it'll re-use color managed
  buffer, but from quick glance it doesn't give really noticeable
  boost.

  Currently this settings are stored as pointer in ImBuf structure
  itself. Probably it make sense removing them from ImBuf and make
  moviecache be able to store some kind of tags associated with
  cached ImBuf.

18 files changed:
intern/opencolorio/ocio_capi.cpp
intern/opencolorio/ocio_capi.h
release/scripts/startup/bl_ui/space_image.py
release/scripts/startup/bl_ui/space_node.py
source/blender/blenkernel/BKE_colortools.h
source/blender/blenkernel/intern/colortools.c
source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/space_node.c
source/blender/imbuf/IMB_colormanagement.h
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/intern/allocimbuf.c
source/blender/imbuf/intern/colormanagement.c
source/blender/makesdna/DNA_color_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesrna/intern/rna_color.c
source/blender/makesrna/intern/rna_space.c

index 7181298583f92bb799496036a823d90073c16b92..5a1352a31fa8e7039a4f547ae4ee5f2346525db0 100644 (file)
@@ -361,6 +361,16 @@ extern void OCIO_displayTransformSetView(DisplayTransformRcPtr* dt, const char *
        (*dt)->setView(name);
 }
 
+extern void OCIO_displayTransformSetDisplayCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *t)
+{
+       (*dt)->setDisplayCC(*t);
+}
+
+extern void OCIO_displayTransformSetLinearCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *t)
+{
+       (*dt)->setLinearCC(*t);
+}
+
 extern void OCIO_displayTransformRelease(DisplayTransformRcPtr* dt)
 {
        if(dt){
@@ -392,3 +402,45 @@ void OCIO_packedImageDescRelease(PackedImageDesc* id)
        }
 }
 
+ExponentTransformRcPtr *OCIO_createExponentTransform(void)
+{
+       ExponentTransformRcPtr *et =  new ExponentTransformRcPtr();
+
+       *et = ExponentTransform::Create();
+
+       return et;
+}
+
+void OCIO_exponentTransformSetValue(ExponentTransformRcPtr *et, const float *exponent)
+{
+       (*et)->setValue(exponent);
+}
+
+void OCIO_exponentTransformRelease(ExponentTransformRcPtr *et)
+{
+       delete et;
+}
+
+MatrixTransformRcPtr *OCIO_createMatrixTransform(void)
+{
+       MatrixTransformRcPtr *mt =  new MatrixTransformRcPtr();
+
+       *mt = MatrixTransform::Create();
+
+       return mt;
+}
+
+void OCIO_matrixTransformSetValue(MatrixTransformRcPtr *mt, const float *m44, const float *offset4)
+{
+       (*mt)->setValue(m44, offset4);
+}
+
+void OCIO_matrixTransformRelease(MatrixTransformRcPtr *mt)
+{
+       delete mt;
+}
+
+void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4f)
+{
+       MatrixTransform::Scale(m44, offset4, scale4f);
+}
index c5b7acf6914ae6b89fb6ab34513769b8d2cf5568..fb51ac7e6b203a5cc65d69085d79541847ba6c17 100644 (file)
@@ -49,6 +49,8 @@ extern "C" {
        OCIO_DECLARE_HANDLE(PackedImageDesc);
        OCIO_DECLARE_HANDLE(DisplayTransformRcPtr);
        OCIO_DECLARE_HANDLE(ConstTransformRcPtr);
+       OCIO_DECLARE_HANDLE(ExponentTransformRcPtr);
+       OCIO_DECLARE_HANDLE(MatrixTransformRcPtr);
 #endif
 
 
@@ -92,6 +94,8 @@ extern DisplayTransformRcPtr* OCIO_createDisplayTransform(void);
 extern void OCIO_displayTransformSetInputColorSpaceName(DisplayTransformRcPtr* dt, const char * name);
 extern void OCIO_displayTransformSetDisplay(DisplayTransformRcPtr* dt, const char * name);
 extern void OCIO_displayTransformSetView(DisplayTransformRcPtr* dt, const char * name);
+extern void OCIO_displayTransformSetDisplayCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *et);
+extern void OCIO_displayTransformSetLinearCC(DisplayTransformRcPtr *dt, ConstTransformRcPtr *et);
 extern void OCIO_displayTransformRelease(DisplayTransformRcPtr* dt);
 
 PackedImageDesc* OCIO_createPackedImageDesc(float * data, long width, long height, long numChannels,
@@ -99,6 +103,16 @@ PackedImageDesc* OCIO_createPackedImageDesc(float * data, long width, long heigh
 
 extern void OCIO_packedImageDescRelease(PackedImageDesc* p);
 
+ExponentTransformRcPtr *OCIO_createExponentTransform(void);
+void OCIO_exponentTransformSetValue(ExponentTransformRcPtr *et, const float *exponent);
+void OCIO_exponentTransformRelease(ExponentTransformRcPtr *et);
+
+MatrixTransformRcPtr *OCIO_createMatrixTransform(void);
+void OCIO_matrixTransformSetValue(MatrixTransformRcPtr *et, const float *m44, const float *offset4);
+void OCIO_matrixTransformRelease(MatrixTransformRcPtr *mt);
+
+void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale4);
+
 #ifdef __cplusplus
 }
 #endif
index 9fb0d0b4afdf81e83323abdc04444ad18bb54336..0ecfccf68c9bb68b0b9adbb97604748014cb7bdd 100644 (file)
@@ -437,9 +437,17 @@ class IMAGE_PT_display_properties(Panel):
 
         sima = context.space_data
         window = context.window
+        view_settings = sima.view_settings
 
-        layout.prop(window, "display_device", text="Display")
-        layout.prop(sima, "view_transform", text="View")
+        # OCIO_TODO: de-duplicate this between different spaces
+        col = layout.column()
+        col.prop(window, "display_device", text="Display")
+        col.prop(view_settings, "view_transform", text="View")
+
+        col = layout.column()
+        col.active = view_settings.view_transform not in {'ACES ODT Tonecurve', 'NONE'}
+        col.prop(view_settings, "exposure")
+        col.prop(view_settings, "gamma")
 
 
 class IMAGE_PT_image_properties(Panel):
index dc54dc795f5465d27370afa374a8121367c4a5c5..110c467e141793cdc07601cdbf161cde545b9bc0 100644 (file)
@@ -194,9 +194,17 @@ class NODE_PT_display_properties(Panel):
 
         snode = context.space_data
         window = context.window
+        view_settings = snode.view_settings
 
-        layout.prop(window, "display_device", text="Display")
-        layout.prop(snode, "view_transform", text="View")
+        # OCIO_TODO: de-duplicate this between different spaces
+        col = layout.column()
+        col.prop(window, "display_device", text="Display")
+        col.prop(view_settings, "view_transform", text="View")
+
+        col = layout.column()
+        col.active = view_settings.view_transform not in {'ACES ODT Tonecurve', 'NONE'}
+        col.prop(view_settings, "exposure")
+        col.prop(view_settings, "gamma")
 
 
 # Node Backdrop options
index f58af8f39a0c221ea718c43632b9ee7116ce26eb..2e1cfb988962f78c2de80aa9a3ec3a2ea3fd1cb0 100644 (file)
@@ -31,6 +31,7 @@
  *  \ingroup bke
  */
 
+struct ColorManagedViewSettings;
 struct CurveMapping;
 struct CurveMap;
 struct CurveMapPoint;
@@ -80,5 +81,8 @@ void                scopes_update(struct Scopes *scopes, struct ImBuf *ibuf, int
 void                scopes_free(struct Scopes *scopes);
 void                scopes_new(struct Scopes *scopes);
 
-#endif
+void BKE_color_managed_view_settings_init(struct ColorManagedViewSettings *settings);
+void BKE_color_managed_view_settings_copy(struct ColorManagedViewSettings *new_settings,
+                                          const struct ColorManagedViewSettings *settings);
 
+#endif
index 6879ec506f050d2dbecd006e394378931a0fda34..8e0f27090a1dac4e7bfe329cabe640df34cb952b 100644 (file)
@@ -1207,3 +1207,21 @@ void scopes_new(Scopes *scopes)
        scopes->waveform_3 = NULL;
        scopes->vecscope = NULL;
 }
+
+void BKE_color_managed_view_settings_init(ColorManagedViewSettings *settings)
+{
+       /* OCIO_TODO: use default view transform here when OCIO is completely integrated
+       *             and proper versioning stuff is added.
+       *             for now use NONE to be compatible with all current files
+       */
+       BLI_strncpy(settings->view_transform, "NONE", sizeof(settings->view_transform));
+
+       settings->gamma = 1.0f;
+       settings->exposure = 0.5f;
+}
+
+void BKE_color_managed_view_settings_copy(ColorManagedViewSettings *new_settings,
+                                          const ColorManagedViewSettings *settings)
+{
+       *new_settings = *settings;
+}
index 552da1bb2f91de79a8b981c5df3fd21103cea5f6..b400cea041b3a461f0d8aa78e8efc7eee179144a 100644 (file)
@@ -461,7 +461,8 @@ static void draw_image_buffer(wmWindow *win, SpaceImage *sima, ARegion *ar, Scen
                 * convert them, and optionally apply curves */
                image_verify_buffer_float(ima, ibuf, color_manage);
 
-               display_buffer = IMB_display_buffer_acquire(ibuf, sima->view_transform, win->display_device, &cache_handle);
+               display_buffer = IMB_display_buffer_acquire(ibuf, &sima->view_settings,
+                                                           win->display_device, &cache_handle);
 
                if (display_buffer)
                        glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
index 97fee2238a02d0aa5c75502af26e37817b0926f6..894f207051fccf705f9a22420f11dffececbf017 100644 (file)
@@ -387,11 +387,7 @@ static SpaceLink *image_new(const bContext *UNUSED(C))
        simage->zoom = 1;
        simage->lock = 1;
 
-       /* OCIO_TODO: use default view transform here when OCIO is completely integrated
-       *             and proper versioning stuff is added.
-       *             for now use NONE to be compatible with all current files
-       */
-       BLI_strncpy(simage->view_transform, "NONE", sizeof(simage->view_transform));
+       BKE_color_managed_view_settings_init(&simage->view_settings);
 
        simage->iuser.ok = 1;
        simage->iuser.fie_ima = 2;
@@ -464,7 +460,7 @@ static SpaceLink *image_duplicate(SpaceLink *sl)
 
        scopes_new(&simagen->scopes);
 
-       BLI_strncpy(simagen->view_transform, simage->view_transform, sizeof(simage->view_transform));
+       BKE_color_managed_view_settings_copy(&simagen->view_settings, &simage->view_settings);
 
        return (SpaceLink *)simagen;
 }
index d9109a85a5ea4911b9c61ba94810b054b051a8e5..90f379e6f44803662fd25edc320407dd62a41ab9 100644 (file)
@@ -2984,7 +2984,8 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
                        y = (ar->winy - snode->zoom * ibuf->y) / 2 + snode->yof;
                        
 
-                       display_buffer = IMB_display_buffer_acquire(ibuf, snode->view_transform, win->display_device, &cache_handle);
+                       display_buffer = IMB_display_buffer_acquire(ibuf, &snode->view_settings,
+                                                                   win->display_device, &cache_handle);
 
                        if (display_buffer) {
                                if (snode->flag & SNODE_SHOW_ALPHA) {
index 7f7c074c823c7a5bbf3c3cfd711837b4b101ccb3..09f7ca95124e4ba0443469beef84c913ce2fa809 100644 (file)
@@ -46,6 +46,7 @@
 #include "BLI_rand.h"
 #include "BLI_utildefines.h"
 
+#include "BKE_colortools.h"
 #include "BKE_context.h"
 #include "BKE_screen.h"
 #include "BKE_node.h"
@@ -104,12 +105,7 @@ static SpaceLink *node_new(const bContext *UNUSED(C))
        /* backdrop */
        snode->zoom = 1.0f;
 
-
-       /* OCIO_TODO: use default view transform here when OCIO is completely integrated
-        *             and proper versioning stuff is added.
-        *             for now use NONE to be compatible with all current files
-        */
-       BLI_strncpy(snode->view_transform, "NONE", sizeof(snode->view_transform));
+       BKE_color_managed_view_settings_init(&snode->view_settings);
 
        /* header */
        ar= MEM_callocN(sizeof(ARegion), "header for node");
@@ -322,13 +318,14 @@ static void node_area_refresh(const struct bContext *C, struct ScrArea *sa)
 
 static SpaceLink *node_duplicate(SpaceLink *sl)
 {
+       SpaceImage *snode = (SpaceImage *) sl;
        SpaceNode *snoden= MEM_dupallocN(sl);
        
        /* clear or remove stuff from old */
        snoden->nodetree= NULL;
        snoden->linkdrag.first= snoden->linkdrag.last= NULL;
 
-       BLI_strncpy(snoden->view_transform, snoden->view_transform, sizeof(snoden->view_transform));
+       BKE_color_managed_view_settings_copy(&snoden->view_settings, &snode->view_settings);
 
        return (SpaceLink *)snoden;
 }
index 758a57ff3eb4579c8fb887356dd1a36fd9097a34..343cdef1ece35517b5bd48391527499a922bf0b9 100644 (file)
@@ -33,6 +33,7 @@
 
 #define BCM_CONFIG_FILE "config.ocio"
 
+struct ColorManagedViewSettings;
 struct EnumPropertyItem;
 struct ImBuf;
 struct Main;
@@ -46,8 +47,13 @@ void IMB_colormanagement_exit(void);
 
 /* ** Public display buffers interfaces ** */
 
-unsigned char *IMB_display_buffer_acquire(struct ImBuf *ibuf, const char *view_transform, const char *display,
-                                          void **cache_handle);
+void IMB_colormanage_flags_allocate(struct ImBuf *ibuf);
+void IMB_colormanage_flags_free(struct ImBuf *ibuf);
+
+void IMB_colormanage_cache_data_free(struct ImBuf *ibuf);
+
+unsigned char *IMB_display_buffer_acquire(struct ImBuf *ibuf, struct ColorManagedViewSettings *view_settings,
+                                          const char *display, void **cache_handle);
 void IMB_display_buffer_release(void *cache_handle);
 
 void IMB_display_buffer_invalidate(struct ImBuf *ibuf);
index aa95bf5f2ddfa715b6779082d5501a55742d5c92..166b7dd9024fa9e46140956774cc27b164bdbba9 100644 (file)
@@ -123,8 +123,9 @@ typedef struct ImBuf {
        /* color management */
        int colormanage_refcounter;
        unsigned int colormanage_flags;
-       unsigned int display_buffer_flags[16];  /* array of per-display display buffers dirty flags */
-                                               /* currently supports 16 display spaces and 32 view-transform */
+       unsigned int *display_buffer_flags;  /* array of per-display display buffers dirty flags */
+       void *colormanage_cache_data;        /* cache data which is being assigned when */
+                                            /* put ImBuf to colormanage cache */
 } ImBuf;
 
 /* Moved from BKE_bmfont_types.h because it is a userflag bit mask. */
index 93ee5a42fe5e86f0f7b49ab4c38c0ad9ada8d921..e355683b065550952a7747067570bc0e261f8192 100644 (file)
@@ -163,6 +163,8 @@ void IMB_freeImBuf(ImBuf *ibuf)
                        IMB_freezbuffloatImBuf(ibuf);
                        freeencodedbufferImBuf(ibuf);
                        IMB_metadata_free(ibuf);
+                       IMB_colormanage_flags_free(ibuf);
+                       IMB_colormanage_cache_data_free(ibuf);
                        MEM_freeN(ibuf);
                }
        }
@@ -443,6 +445,8 @@ ImBuf *IMB_dupImBuf(ImBuf *ibuf1)
        *ibuf2 = tbuf;
 
        IMB_display_buffer_invalidate(ibuf2);
+       IMB_colormanage_cache_data_free(ibuf2);
+
        ibuf2->colormanage_flags &= ~ IMB_COLORMANAGED;
 
        return(ibuf2);
index 331a7788b403b64ea6480471ba86e2f5acdef995..568cea9f493027172c730ea327262ef106f4373e 100644 (file)
 #include <string.h>
 #include <math.h>
 
-#include "DNA_windowmanager_types.h"
-#include "DNA_space_types.h"
+#include "DNA_color_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_windowmanager_types.h"
 
 #include "IMB_filter.h"
 #include "IMB_imbuf.h"
@@ -71,6 +72,8 @@ static ListBase global_colorspaces = {NULL};
 static ListBase global_displays = {NULL};
 static ListBase global_views = {NULL};
 
+static int global_tot_display = 0;
+
 /*********************** Color managed cache *************************/
 
 /* Currently it's original ImBuf pointer is used to distinguish which
@@ -121,6 +124,11 @@ typedef struct ColormanageCacheKey {
        int display;         /* display device name */
 } ColormanageCacheKey;
 
+typedef struct ColormnaageCacheImBufData {
+       float exposure;  /* exposure value cached buffer is calculated with */
+       float gamma;     /* gamma value cached buffer is calculated with */
+} ColormnaageCacheImBufData;
+
 static struct MovieCache *colormanage_cache = NULL;
 
 static unsigned int colormanage_hashhash(const void *key_v)
@@ -205,35 +213,62 @@ static ImBuf *colormanage_cache_get_ibuf(ImBuf *ibuf, int view_transform, int di
        return cache_ibuf;
 }
 
-static unsigned char *colormanage_cache_get(ImBuf *ibuf, int view_transform, int display, void **cache_handle)
+static unsigned char *colormanage_cache_get(ImBuf *ibuf, int view_transform, int display,
+                                            float exposure, float gamma, void **cache_handle)
 {
        ImBuf *cache_ibuf = colormanage_cache_get_ibuf(ibuf, view_transform, display, cache_handle);
 
        if (cache_ibuf) {
+               ColormnaageCacheImBufData *cache_data;
+
+               /* only buffers with different color space conversions are being stored
+                * in cache separately. buffer which were used only different exposure/gamma
+                * are re-suing the same cached buffer
+                *
+                * check here which exposure/gamma was used for cached buffer and if they're
+                * different from requested buffer should be re-generated
+                */
+               cache_data = (ColormnaageCacheImBufData *) cache_ibuf->colormanage_cache_data;
+               if (cache_data->exposure != exposure || cache_data->gamma != gamma) {
+                       IMB_freeImBuf(cache_ibuf);
+
+                       return NULL;
+               }
+
                return (unsigned char *) cache_ibuf->rect;
        }
 
        return NULL;
 }
 
-static void colormanage_cache_put(ImBuf *ibuf, int view_transform, int display,
+static void colormanage_cache_put(ImBuf *ibuf, int view_transform, int display, float exposure, float gamma,
                                   unsigned char *display_buffer, void **cache_handle)
 {
        ColormanageCacheKey key;
        ImBuf *cache_ibuf;
+       ColormnaageCacheImBufData *cache_data;
 
        key.ibuf = ibuf;
        key.view_transform = view_transform;
        key.display = display;
 
+       /* buffer itself */
        cache_ibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, 0);
        cache_ibuf->rect = (unsigned int *) display_buffer;
 
        cache_ibuf->mall |= IB_rect;
        cache_ibuf->flags |= IB_rect;
 
+       /* store data which is needed to check whether cached buffer could be used for color managed display settings */
+       cache_data = MEM_callocN(sizeof(ColormnaageCacheImBufData), "color manage cache imbuf data");
+       cache_data->exposure = exposure;
+       cache_data->gamma = gamma;
+
+       cache_ibuf->colormanage_cache_data = cache_data;
+
        *cache_handle = cache_ibuf;
 
+       /* mark source buffer as having color managed buffer and increment color managed buffers count for it */
        if ((ibuf->colormanage_flags & IMB_COLORMANAGED) == 0) {
                ibuf->colormanage_flags |= IMB_COLORMANAGED;
 
@@ -245,19 +280,33 @@ static void colormanage_cache_put(ImBuf *ibuf, int view_transform, int display,
        IMB_moviecache_put(colormanage_cache, &key, cache_ibuf);
 }
 
+/* validation function checks whether there's buffer with given display transform
+ * in the cache and if so, check whether it matches resolution of source buffer.
+ * if resolution is different new buffer would be put into the cache and it'll
+ * be returned as a result
+ *
+ * this function does not check exposure / gamma because currently it's only
+ * used by partial buffer update functions which uses the same exposure / gamma
+ * settings as cached buffer had
+ */
 static unsigned char *colormanage_cache_get_validated(ImBuf *ibuf, int view_transform, int display, void **cache_handle)
 {
        ImBuf *cache_ibuf = colormanage_cache_get_ibuf(ibuf, view_transform, display, cache_handle);
 
        if (cache_ibuf) {
                if (cache_ibuf->x != ibuf->x || cache_ibuf->y != ibuf->y) {
+                       ColormnaageCacheImBufData *cache_data;
                        unsigned char *display_buffer;
                        int buffer_size;
 
+                       /* use the same settings as original cached buffer  */
+                       cache_data = (ColormnaageCacheImBufData *) cache_ibuf->colormanage_cache_data;
+
                        buffer_size = ibuf->channels * ibuf->x * ibuf->y * sizeof(float);
                        display_buffer = MEM_callocN(buffer_size, "imbuf validated display buffer");
 
-                       colormanage_cache_put(ibuf, view_transform, display, display_buffer, cache_handle);
+                       colormanage_cache_put(ibuf, view_transform, display, cache_data->exposure, cache_data->gamma,
+                                             display_buffer, cache_handle);
 
                        IMB_freeImBuf(cache_ibuf);
 
@@ -269,6 +318,18 @@ static unsigned char *colormanage_cache_get_validated(ImBuf *ibuf, int view_tran
 
        return NULL;
 }
+
+/* return view settings which are stored in cached buffer, not in key itself */
+static void colormanage_cache_get_cache_data(void *cache_handle, float *exposure, float *gamma)
+{
+       ImBuf *cache_ibuf = (ImBuf *) cache_handle;
+       ColormnaageCacheImBufData *cache_data;
+
+       cache_data = (ColormnaageCacheImBufData *) cache_ibuf->colormanage_cache_data;
+
+       *exposure = cache_data->exposure;
+       *gamma = cache_data->gamma;
+}
 #endif
 
 static void colormanage_cache_handle_release(void *cache_handle)
@@ -338,6 +399,8 @@ static void colormanage_load_config(ConstConfigRcPtr* config)
                        BLI_addtail(&display->views, display_view);
                }
        }
+
+       global_tot_display = tot_display;
 }
 
 void colormanage_free_config(void)
@@ -551,16 +614,21 @@ static void *do_display_buffer_apply_ocio_thread(void *handle_v)
        return NULL;
 }
 
-static void display_buffer_apply_ocio(ImBuf *ibuf, unsigned char *display_buffer,
-                                      const char *view_transform, const char *display)
+static ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display,
+                                                            float exposure, float gamma)
 {
        ConstConfigRcPtr *config = OCIO_getCurrentConfig();
        DisplayTransformRcPtr *dt = OCIO_createDisplayTransform();
+       ExponentTransformRcPtr *et;
+       MatrixTransformRcPtr *mt;
        ConstProcessorRcPtr *processor;
 
-       float *rect_float;
+       float exponent = 1.0f / MAX2(FLT_EPSILON, gamma);
+       const float exponent4f[] = {exponent, exponent, exponent, exponent};
 
-       rect_float = MEM_dupallocN(ibuf->rect_float);
+       float gain = powf(2.0f, exposure);
+       const float scale4f[] = {gain, gain, gain, gain};
+       float m44[16], offset4[4];
 
        /* OCIO_TODO: get rid of hardcoded input and display spaces */
        OCIO_displayTransformSetInputColorSpaceName(dt, "aces");
@@ -568,26 +636,83 @@ static void display_buffer_apply_ocio(ImBuf *ibuf, unsigned char *display_buffer
        OCIO_displayTransformSetView(dt, view_transform);
        OCIO_displayTransformSetDisplay(dt, display);
 
+    /* fstop exposure control */
+       OCIO_matrixTransformScale(m44, offset4, scale4f);
+       mt = OCIO_createMatrixTransform();
+       OCIO_matrixTransformSetValue(mt, m44, offset4);
+       OCIO_displayTransformSetLinearCC(dt, (ConstTransformRcPtr *) mt);
+
+    /* post-display gamma transform */
+       et = OCIO_createExponentTransform();
+       OCIO_exponentTransformSetValue(et, exponent4f);
+       OCIO_displayTransformSetDisplayCC(dt, (ConstTransformRcPtr *) et);
+
        processor = OCIO_configGetProcessor(config, (ConstTransformRcPtr *) dt);
 
+       OCIO_exponentTransformRelease(et);
+       OCIO_displayTransformRelease(dt);
+       OCIO_configRelease(config);
+
+       return processor;
+}
+
+static void display_buffer_apply_ocio(ImBuf *ibuf, unsigned char *display_buffer,
+                                      const ColorManagedViewSettings *view_settings,
+                                      const char *display)
+{
+       ConstProcessorRcPtr *processor;
+       const float gamma = view_settings->gamma;
+       const float exposure = view_settings->exposure;
+       const char *view_transform = view_settings->view_transform;
+       float *rect_float;
+
+       rect_float = MEM_dupallocN(ibuf->rect_float);
+
+       processor = create_display_buffer_processor(view_transform, display, exposure, gamma);
+
        if (processor) {
                display_buffer_apply_threaded(ibuf, rect_float, display_buffer, processor,
                                              do_display_buffer_apply_ocio_thread);
        }
 
-       OCIO_displayTransformRelease(dt);
        OCIO_processorRelease(processor);
-       OCIO_configRelease(config);
 
        MEM_freeN(rect_float);
 }
 #endif
 
-unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const char *view_transform, const char *display, void **cache_handle)
+void IMB_colormanage_flags_allocate(ImBuf *ibuf)
+{
+       ibuf->display_buffer_flags = MEM_callocN(sizeof(unsigned int) * global_tot_display, "imbuf display_buffer_flags");
+}
+
+void IMB_colormanage_flags_free(ImBuf *ibuf)
+{
+       if (ibuf->display_buffer_flags) {
+               MEM_freeN(ibuf->display_buffer_flags);
+
+               ibuf->display_buffer_flags = NULL;
+       }
+}
+
+void IMB_colormanage_cache_data_free(ImBuf *ibuf)
+{
+       if (ibuf->colormanage_cache_data) {
+               MEM_freeN(ibuf->colormanage_cache_data);
+
+               ibuf->colormanage_cache_data = NULL;
+       }
+}
+
+unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, ColorManagedViewSettings *view_settings,
+                                          const char *display, void **cache_handle)
 {
+       const char *view_transform = view_settings->view_transform;
+
        *cache_handle = NULL;
 
 #ifdef WITH_OCIO
+
        if (!ibuf->x || !ibuf->y)
                return NULL;
 
@@ -610,9 +735,17 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const char *view_transfor
                int display_index = IMB_colormanagement_display_get_named_index(display);
                int view_transform_flag = 1 << (view_transform_index - 1);
 
+               float exposure = view_settings->exposure;
+               float gamma = view_settings->gamma;
+
+               /* ensure color management bit fields exists */
+               if (!ibuf->display_buffer_flags)
+                       IMB_colormanage_flags_allocate(ibuf);
+
                /* check whether display buffer isn't marked as dirty and if so try to get buffer from cache */
                if (ibuf->display_buffer_flags[display_index - 1] & view_transform_flag) {
-                       display_buffer = colormanage_cache_get(ibuf, view_transform_index, display_index, cache_handle);
+                       display_buffer = colormanage_cache_get(ibuf, view_transform_index, display_index,
+                                                              exposure, gamma, cache_handle);
 
                        if (display_buffer) {
                                return display_buffer;
@@ -621,6 +754,9 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const char *view_transfor
 
                /* OCIO_TODO: in case when image is being resized it is possible
                 *            to save buffer allocation here
+                *
+                *            actually not because there might be other users of
+                *            that buffer which better not to change
                 */
 
                buffer_size = ibuf->channels * ibuf->x * ibuf->y * sizeof(float);
@@ -634,10 +770,11 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const char *view_transfor
                        display_buffer_apply_tonemap(ibuf, display_buffer, IMB_ratio_preserving_odt_tonecurve);
                }
                else {
-                       display_buffer_apply_ocio(ibuf, display_buffer, view_transform, display);
+                       display_buffer_apply_ocio(ibuf, display_buffer, view_settings, display);
                }
 
-               colormanage_cache_put(ibuf, view_transform_index, display_index, display_buffer, cache_handle);
+               colormanage_cache_put(ibuf, view_transform_index, display_index, exposure, gamma,
+                                     display_buffer, cache_handle);
 
                ibuf->display_buffer_flags[display_index - 1] |= view_transform_flag;
 
@@ -648,6 +785,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const char *view_transfor
         * generated from float buffer (if any) using standard
         * profiles without applying any view / display transformation */
 
+       (void) view_settings;
        (void) view_transform;
        (void) display;
 
@@ -668,29 +806,40 @@ void IMB_display_buffer_release(void *cache_handle)
 
 void IMB_display_buffer_invalidate(ImBuf *ibuf)
 {
-       memset(ibuf->display_buffer_flags, 0, sizeof(ibuf->display_buffer_flags));
+       /* if there's no display_buffer_flags this means there's no color managed
+        * buffers created for this imbuf, no need to invalidate
+        */
+       if (ibuf->display_buffer_flags) {
+               memset(ibuf->display_buffer_flags, 0, global_tot_display * sizeof(unsigned int));
+       }
 }
 
 #ifdef WITH_OCIO
-static void colormanage_check_space_view_transform(char *view_transform, int max_view_transform, const char *editor,
-                                                   const ColorManagedView *default_view)
+static void colormanage_check_view_settings(ColorManagedViewSettings *view_settings, const char *editor,
+                                            const ColorManagedView *default_view)
 {
-       if (view_transform[0] == '\0') {
-               BLI_strncpy(view_transform, "NONE", max_view_transform);
+       if (view_settings->view_transform[0] == '\0') {
+               BLI_strncpy(view_settings->view_transform, "NONE", sizeof(view_settings->view_transform));
        }
-       else if (!strcmp(view_transform, "NONE")) {
+       else if (!strcmp(view_settings->view_transform, "NONE")) {
                /* pass */
        }
        else {
-               ColorManagedView *view = colormanage_view_get_named(view_transform);
+               ColorManagedView *view = colormanage_view_get_named(view_settings->view_transform);
 
                if (!view) {
                        printf("Blender color management: %s editor view \"%s\" not found, setting default \"%s\".\n",
-                              editor, view_transform, default_view->name);
+                              editor, view_settings->view_transform, default_view->name);
 
-                       BLI_strncpy(view_transform, default_view->name, max_view_transform);
+                       BLI_strncpy(view_settings->view_transform, default_view->name, sizeof(view_settings->view_transform));
                }
        }
+
+       /* OCIO_TODO: move to do_versions() */
+       if (view_settings->exposure == 0.0f && view_settings->gamma == 0.0f) {
+               view_settings->exposure = 0.5f;
+               view_settings->gamma = 1.0f;
+       }
 }
 #endif
 
@@ -732,14 +881,12 @@ void IMB_colormanagement_check_file_config(Main *bmain)
                                if (sl->spacetype == SPACE_IMAGE) {
                                        SpaceImage *sima = (SpaceImage *) sl;
 
-                                       colormanage_check_space_view_transform(sima->view_transform, sizeof(sima->view_transform),
-                                                                              "image", default_view);
+                                       colormanage_check_view_settings(&sima->view_settings, "image", default_view);
                                }
                                else if (sl->spacetype == SPACE_NODE) {
                                        SpaceNode *snode = (SpaceNode *) sl;
 
-                                       colormanage_check_space_view_transform(snode->view_transform, sizeof(snode->view_transform),
-                                                                              "node", default_view);
+                                       colormanage_check_view_settings(&snode->view_settings, "node", default_view);
                                }
                        }
                }
@@ -990,7 +1137,6 @@ typedef struct PartialBufferUpdateItem {
        int display, view;
 
 #ifdef WITH_OCIO
-       DisplayTransformRcPtr *dt;
        ConstProcessorRcPtr *processor;
 #endif
 
@@ -1009,10 +1155,7 @@ PartialBufferUpdateContext *IMB_partial_buffer_update_context_new(ImBuf *ibuf)
        PartialBufferUpdateContext *context = NULL;
 
 #ifdef WITH_OCIO
-       ConstConfigRcPtr *config = OCIO_getCurrentConfig();
-
        int display;
-       int tot_display = sizeof(ibuf->display_buffer_flags) / sizeof(ibuf->display_buffer_flags[0]);
 
        context = MEM_callocN(sizeof(PartialBufferUpdateContext), "partial buffer update context");
 
@@ -1021,7 +1164,12 @@ PartialBufferUpdateContext *IMB_partial_buffer_update_context_new(ImBuf *ibuf)
        context->predivide = ibuf->flags & IB_cm_predivide;
        context->dither = ibuf->dither;
 
-       for (display = 0; display < tot_display; display++) {
+       if (!ibuf->display_buffer_flags) {
+               /* there's no cached display buffers, so no need to iterate though bit fields */
+               return context;
+       }
+
+       for (display = 0; display < global_tot_display; display++) {
                int display_index = display + 1; /* displays in configuration are 1-based */
                const char *display_name = IMB_colormanagement_display_get_indexed_name(display_index);
                int view_flags = ibuf->display_buffer_flags[display];
@@ -1038,6 +1186,9 @@ PartialBufferUpdateContext *IMB_partial_buffer_update_context_new(ImBuf *ibuf)
                                if (display_buffer) {
                                        PartialBufferUpdateItem *item;
                                        const char *view_name = IMB_colormanagement_view_get_indexed_name(view_index);
+                                       float exposure, gamma;
+
+                                       colormanage_cache_get_cache_data(cache_handle, &exposure, &gamma);
 
                                        item = MEM_callocN(sizeof(PartialBufferUpdateItem), "partial buffer update item");
 
@@ -1050,18 +1201,10 @@ PartialBufferUpdateContext *IMB_partial_buffer_update_context_new(ImBuf *ibuf)
                                                item->tonecurve_func = IMB_ratio_preserving_odt_tonecurve;
                                        }
                                        else {
-                                               DisplayTransformRcPtr *dt = OCIO_createDisplayTransform();
                                                ConstProcessorRcPtr *processor;
 
-                                               /* OCIO_TODO: get rid of hardcoded input and display spaces */
-                                               OCIO_displayTransformSetInputColorSpaceName(dt, "aces");
-
-                                               OCIO_displayTransformSetView(dt, view_name);
-                                               OCIO_displayTransformSetDisplay(dt, display_name);
-
-                                               processor = OCIO_configGetProcessor(config, (ConstTransformRcPtr *) dt);
+                                               processor = create_display_buffer_processor(view_name, display_name, exposure, gamma);
 
-                                               item->dt = dt;
                                                item->processor = processor;
                                        }
 
@@ -1135,7 +1278,6 @@ void IMB_partial_buffer_update_free(PartialBufferUpdateContext *context, ImBuf *
                colormanage_cache_handle_release(item->cache_handle);
 
                OCIO_processorRelease(item->processor);
-               OCIO_displayTransformRelease(item->dt);
 
                MEM_freeN(item);
 
index 1f8fdd20ddaae5a29bdb26acfb2399ff351e67c4..cc9c6bd9aec0aabc62e232d0b73a286d9b14aeb8 100644 (file)
@@ -158,6 +158,16 @@ typedef struct Scopes {
 #define SCOPES_WAVEFRM_YCC_709 3
 #define SCOPES_WAVEFRM_YCC_JPEG        4
 
+typedef struct ColorManagedViewSettings {
+       int flag;                  /* assodted flags such as using global settings from window and so */
+       char view_transform[64];   /* view transform which is being applied when displaying buffer on the screen */
+       float exposure;            /* fstop exposure */
+       float gamma;               /* post-display gamma transform */
+} ColorManagedViewSettings;
+
+enum {
+       COLORMANAGE_VIEW_USE_GLOBAL = (1 << 0)    /* use global display settings instead of per-space setting */
+};
 
 #endif
 
index 0556bc0c03def5bb65be68ebf450ebafed2233fd..daf81a140c5f69c0ed1b416b31884038ad0b59a6 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "DNA_defs.h"
 #include "DNA_listBase.h"
-#include "DNA_color_types.h"        /* for Histogram */
+#include "DNA_color_types.h"        /* for Histogram and color management */
 #include "DNA_vec_types.h"
 #include "DNA_outliner_types.h"     /* for TreeStoreElem */
 #include "DNA_image_types.h"        /* ImageUser */
@@ -690,8 +690,8 @@ typedef struct SpaceImage {
        char dt_uvstretch;
        char around;
 
-       /* color transformation  */
-       char view_transform[64];
+       ColorManagedViewSettings view_settings;
+       int pad1;
 } SpaceImage;
 
 
@@ -875,8 +875,8 @@ typedef struct SpaceNode {
        
        struct bGPdata *gpd;        /* grease-pencil data */
 
-       /* color transformation  */
-       char view_transform[64];
+       ColorManagedViewSettings view_settings;
+       int pad2;
 } SpaceNode;
 
 /* snode->flag */
index 15fdce09d83dc41ee64f02176e3faf51f1eeef27..14272bc65919b9facec92837d2eabb952d925afe 100644 (file)
 #include "DNA_color_types.h"
 #include "DNA_texture_types.h"
 
+#include "WM_api.h"
+#include "WM_types.h"
+
+static EnumPropertyItem view_transform_items[] = {
+       {0, "NONE", 0, "None", ""},
+       {0, NULL, 0, NULL, NULL}
+};
+
 #ifdef RNA_RUNTIME
 
 #include "RNA_access.h"
 #include "BKE_node.h"
 #include "BKE_texture.h"
 
-#include "WM_api.h"
-#include "WM_types.h"
-
 #include "ED_node.h"
 
+#include "IMB_colormanagement.h"
+
 static int rna_CurveMapping_curves_length(PointerRNA *ptr)
 {
        CurveMapping *cumap = (CurveMapping *)ptr->data;
@@ -337,6 +344,38 @@ static void rna_Scopes_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointer
        s->ok = 0;
 }
 
+static int rna_ColorManagedViewSettings_view_transform_get(PointerRNA *ptr)
+{
+       ColorManagedViewSettings *view = (ColorManagedViewSettings *) ptr->data;
+
+       return IMB_colormanagement_view_get_named_index(view->view_transform);
+}
+
+static void rna_ColorManagedViewSettings_view_transform_set(PointerRNA *ptr, int value)
+{
+       ColorManagedViewSettings *view = (ColorManagedViewSettings *) ptr->data;
+
+       const char *name = IMB_colormanagement_view_get_indexed_name(value);
+
+       if (name) {
+               BLI_strncpy(view->view_transform, name, sizeof(view->view_transform));
+       }
+}
+
+static EnumPropertyItem* rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+{
+       wmWindow *win = CTX_wm_window(C);
+       EnumPropertyItem *items = NULL;
+       int totitem = 0;
+
+       RNA_enum_item_add(&items, &totitem, &view_transform_items[0]);
+       IMB_colormanagement_view_items_add(&items, &totitem, win->display_device);
+       RNA_enum_item_end(&items, &totitem);
+
+       *free = 1;
+       return items;
+}
+
 #else
 
 static void rna_def_curvemappoint(BlenderRNA *brna)
@@ -676,6 +715,39 @@ static void rna_def_scopes(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Vectorscope Opacity", "Opacity of the points");
 }
 
+static void rna_def_colormanage(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna = RNA_def_struct(brna, "ColorManagedViewSettings", NULL);
+       RNA_def_struct_ui_text(srna, "ColorManagedViewSettings", "Color management settings used for displaying images on the display");
+
+       prop = RNA_def_property(srna, "use_global_settings", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", COLORMANAGE_VIEW_USE_GLOBAL);
+       RNA_def_property_ui_text(prop, "Use Global Settings", "Use global display settings instead of per-space setting");
+       RNA_def_property_update(prop, NC_WINDOW, NULL);
+
+       prop= RNA_def_property(srna, "view_transform", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, view_transform_items);
+       RNA_def_property_enum_funcs(prop, "rna_ColorManagedViewSettings_view_transform_get",
+                                         "rna_ColorManagedViewSettings_view_transform_set",
+                                         "rna_ColorManagedViewSettings_view_transform_itemf");
+       RNA_def_property_ui_text(prop, "View Transform", "View transform used for this image editor");
+       RNA_def_property_update(prop, NC_WINDOW, NULL);
+
+       prop = RNA_def_property(srna, "exposure", PROP_FLOAT, PROP_FACTOR);
+       RNA_def_property_float_sdna(prop, NULL, "exposure");
+       RNA_def_property_range(prop, -10.0f, 10.0f);
+       RNA_def_property_ui_text(prop, "Exposure", "Exposure (stops) applied on displaying image buffers");
+       RNA_def_property_update(prop, NC_WINDOW, NULL);
+
+       prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_FACTOR);
+       RNA_def_property_float_sdna(prop, NULL, "gamma");
+       RNA_def_property_range(prop, 0.0f, 5.0f);
+       RNA_def_property_ui_text(prop, "Gamma", "Amount f gamma modification for displaying image buffers");
+       RNA_def_property_update(prop, NC_WINDOW, NULL);
+}
 
 void RNA_def_color(BlenderRNA *brna)
 {
@@ -686,6 +758,7 @@ void RNA_def_color(BlenderRNA *brna)
        rna_def_color_ramp(brna);
        rna_def_histogram(brna);
        rna_def_scopes(brna);
+       rna_def_colormanage(brna);
 }
 
 #endif
index 6a9651bf964d240eb471cd8c66aa6cfd5fa4e35a..c3a390efd32311d379dbcecfb1d3182dcb77ced5 100644 (file)
@@ -118,11 +118,6 @@ EnumPropertyItem viewport_shade_items[] = {
        {0, NULL, 0, NULL, NULL}
 };
 
-static EnumPropertyItem view_transform_items[] = {
-       {0, "NONE", 0, "None", ""},
-       {0, NULL, 0, NULL, NULL}
-};
-
 #ifdef RNA_RUNTIME
 
 #include "DNA_anim_types.h"
@@ -671,38 +666,6 @@ static void rna_SpaceImageEditor_scopes_update(Main *UNUSED(bmain), Scene *scene
        ED_space_image_release_buffer(sima, lock);
 }
 
-static int rna_SpaceImageEditor_view_transform_get(PointerRNA *ptr)
-{
-       SpaceImage *sima = (SpaceImage *) ptr->data;
-
-       return IMB_colormanagement_view_get_named_index(sima->view_transform);
-}
-
-static void rna_SpaceImageEditor_view_transform_set(PointerRNA *ptr, int value)
-{
-       SpaceImage *sima = (SpaceImage*) ptr->data;
-
-       const char *name = IMB_colormanagement_view_get_indexed_name(value);
-
-       if (name) {
-               BLI_strncpy(sima->view_transform, name, sizeof(sima->view_transform));
-       }
-}
-
-static EnumPropertyItem* rna_SpaceImageEditor_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
-{
-       wmWindow *win = CTX_wm_window(C);
-       EnumPropertyItem *items = NULL;
-       int totitem = 0;
-
-       RNA_enum_item_add(&items, &totitem, &view_transform_items[0]);
-       IMB_colormanagement_view_items_add(&items, &totitem, win->display_device);
-       RNA_enum_item_end(&items, &totitem);
-
-       *free = 1;
-       return items;
-}
-
 /* Space Text Editor */
 
 static void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, int value)
@@ -1015,38 +978,6 @@ static void rna_SpaceNodeEditor_node_tree_update(Main *UNUSED(bmain), Scene *sce
        ED_node_tree_update(snode, scene);
 }
 
-static int rna_SpaceNodeEditor_view_transform_get(PointerRNA *ptr)
-{
-       SpaceNode *snode = (SpaceNode *)ptr->data;
-
-       return IMB_colormanagement_view_get_named_index(snode->view_transform);
-}
-
-static void rna_SpaceNodeEditor_view_transform_set(PointerRNA *ptr, int value)
-{
-       SpaceNode *snode = (SpaceNode *)ptr->data;
-
-       const char *name = IMB_colormanagement_view_get_indexed_name(value);
-
-       if (name) {
-               BLI_strncpy(snode->view_transform, name, sizeof(snode->view_transform));
-       }
-}
-
-static EnumPropertyItem *rna_SpaceNodeEditor_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
-{
-       wmWindow *win = CTX_wm_window(C);
-       EnumPropertyItem *items = NULL;
-       int totitem = 0;
-
-       RNA_enum_item_add(&items, &totitem, &view_transform_items[0]);
-       IMB_colormanagement_view_items_add(&items, &totitem, win->display_device);
-       RNA_enum_item_end(&items, &totitem);
-
-       *free = 1;
-       return items;
-}
-
 static EnumPropertyItem *rna_SpaceProperties_texture_context_itemf(bContext *C, PointerRNA *UNUSED(ptr),
                                                                    PropertyRNA *UNUSED(prop), int *free)
 {
@@ -2096,12 +2027,10 @@ static void rna_def_space_image(BlenderRNA *brna)
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Show UV Editor", "Show UV editing related properties");
 
-       prop= RNA_def_property(srna, "view_transform", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_items(prop, view_transform_items);
-       RNA_def_property_enum_funcs(prop, "rna_SpaceImageEditor_view_transform_get", "rna_SpaceImageEditor_view_transform_set",
-                                   "rna_SpaceImageEditor_view_transform_itemf");
-       RNA_def_property_ui_text(prop, "View Transform", "View transform used for this image editor");
-       RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
+       prop = RNA_def_property(srna, "view_settings", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "view_settings");
+       RNA_def_property_struct_type(prop, "ColorManagedViewSettings");
+       RNA_def_property_ui_text(prop, "View Settings", "Sampled colors alongColor management settings used for displaying images on the display");
 
        rna_def_space_image_uv(brna);
 }
@@ -3004,12 +2933,10 @@ static void rna_def_space_node(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Draw Channels", "Channels of the image to draw");
        RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
 
-       prop= RNA_def_property(srna, "view_transform", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_items(prop, view_transform_items);
-       RNA_def_property_enum_funcs(prop, "rna_SpaceNodeEditor_view_transform_get", "rna_SpaceNodeEditor_view_transform_set",
-                                   "rna_SpaceNodeEditor_view_transform_itemf");
-       RNA_def_property_ui_text(prop, "View Transform", "View transform used for this node editor");
-       RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
+       prop = RNA_def_property(srna, "view_settings", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "view_settings");
+       RNA_def_property_struct_type(prop, "ColorManagedViewSettings");
+       RNA_def_property_ui_text(prop, "View Settings", "Sampled colors alongColor management settings used for displaying images on the display");
 }
 
 static void rna_def_space_logic(BlenderRNA *brna)