Color management: fix crashes and memory leaks when using custom OCIO configuration
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 18 Sep 2012 19:20:26 +0000 (19:20 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 18 Sep 2012 19:20:26 +0000 (19:20 +0000)
Also fix some missing color spaces when loading some OCIO configurations, by falling
back to scene linear if role is not found. There can still be some errors in the
console, need to check this further.

http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management#OpenColorIO_Configuration

intern/opencolorio/ocio_capi.cpp
source/blender/imbuf/intern/colormanagement.c

index d67cea618368b2dee0582c0122c715cd5ed81d65..2fa66e5d2f5de06e23983654a3cc9a8b7c7bb5e4 100644 (file)
 #endif
 
 #define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type()
-#define MEM_DELETE(what, type) { what->~type(); MEM_freeN(what); } (void)0
+#define MEM_DELETE(what, type) if(what) { what->~type(); MEM_freeN(what); } (void)0
 
 static void OCIO_reportError(const char *err)
 {
        std::cerr << "OpenColorIO Error: " << err << std::endl;
 
-       OCIO_abort();
+       // OCIO_abort();
 }
 
 static void OCIO_reportException(Exception &exception)
@@ -75,6 +75,8 @@ ConstConfigRcPtr *OCIO_getCurrentConfig(void)
                OCIO_reportException(exception);
        }
 
+       MEM_DELETE(config, ConstConfigRcPtr);
+
        return NULL;
 }
 
@@ -107,6 +109,8 @@ ConstConfigRcPtr *OCIO_configCreateFromEnv(void)
                OCIO_reportException(exception);
        }
 
+       MEM_DELETE(config, ConstConfigRcPtr);
+
        return NULL;
 }
 
@@ -125,6 +129,8 @@ ConstConfigRcPtr *OCIO_configCreateFromFile(const char *filename)
                OCIO_reportException(exception);
        }
 
+       MEM_DELETE(config, ConstConfigRcPtr);
+
        return NULL;
 }
 
@@ -169,9 +175,10 @@ ConstColorSpaceRcPtr *OCIO_configGetColorSpace(ConstConfigRcPtr *config, const c
        }
        catch (Exception &exception) {
                OCIO_reportException(exception);
-               MEM_DELETE(cs, ConstColorSpaceRcPtr);
        }
 
+       MEM_DELETE(cs, ConstColorSpaceRcPtr);
+
        return NULL;
 }
 
@@ -314,6 +321,8 @@ ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(ConstConfigRcPtr *config,
                OCIO_reportException(exception);
        }
 
+       MEM_DELETE(p, ConstProcessorRcPtr);
+
        return 0;
 }
 
@@ -331,6 +340,8 @@ ConstProcessorRcPtr *OCIO_configGetProcessor(ConstConfigRcPtr *config, ConstTran
                OCIO_reportException(exception);
        }
 
+       MEM_DELETE(p, ConstProcessorRcPtr);
+
        return NULL;
 }
 
index d896395f6479551f1f690e3545f7b8ecc0380372..0e0937576eb46fb20cef5d80a5fa200ed0c06148 100644 (file)
@@ -411,12 +411,15 @@ static void colormanage_cache_handle_release(void *cache_handle)
 
 /*********************** Initialization / De-initialization *************************/
 
-static void colormanage_role_color_space_name_get(ConstConfigRcPtr *config, char *colorspace_name, const char *role)
+static void colormanage_role_color_space_name_get(ConstConfigRcPtr *config, char *colorspace_name, const char *role, const char *backup_role)
 {
        ConstColorSpaceRcPtr *ociocs;
 
        ociocs = OCIO_configGetColorSpace(config, role);
 
+       if (!ociocs && backup_role)
+               ociocs = OCIO_configGetColorSpace(config, backup_role);
+
        if (ociocs) {
                const char *name = OCIO_colorSpaceGetName(ociocs);
 
@@ -435,12 +438,12 @@ static void colormanage_load_config(ConstConfigRcPtr *config)
        const char *name;
 
        /* get roles */
-       colormanage_role_color_space_name_get(config, global_role_scene_linear, OCIO_ROLE_SCENE_LINEAR);
-       colormanage_role_color_space_name_get(config, global_role_color_picking, OCIO_ROLE_COLOR_PICKING);
-       colormanage_role_color_space_name_get(config, global_role_texture_painting, OCIO_ROLE_TEXTURE_PAINT);
-       colormanage_role_color_space_name_get(config, global_role_default_sequencer, OCIO_ROLE_DEFAULT_SEQUENCER);
-       colormanage_role_color_space_name_get(config, global_role_default_byte, OCIO_ROLE_DEFAULT_BYTE);
-       colormanage_role_color_space_name_get(config, global_role_default_float, OCIO_ROLE_DEFAULT_FLOAT);
+       colormanage_role_color_space_name_get(config, global_role_scene_linear, OCIO_ROLE_SCENE_LINEAR, NULL);
+       colormanage_role_color_space_name_get(config, global_role_color_picking, OCIO_ROLE_COLOR_PICKING, NULL);
+       colormanage_role_color_space_name_get(config, global_role_texture_painting, OCIO_ROLE_TEXTURE_PAINT, NULL);
+       colormanage_role_color_space_name_get(config, global_role_default_sequencer, OCIO_ROLE_DEFAULT_SEQUENCER, OCIO_ROLE_SCENE_LINEAR);
+       colormanage_role_color_space_name_get(config, global_role_default_byte, OCIO_ROLE_DEFAULT_BYTE, OCIO_ROLE_TEXTURE_PAINT);
+       colormanage_role_color_space_name_get(config, global_role_default_float, OCIO_ROLE_DEFAULT_FLOAT, OCIO_ROLE_SCENE_LINEAR);
 
        /* load colorspaces */
        tot_colorspace = OCIO_configGetNumColorSpaces(config);
@@ -793,10 +796,12 @@ static void init_default_view_settings(const ColorManagedDisplaySettings *displa
                                        ColorManagedViewSettings *view_settings)
 {
        ColorManagedDisplay *display;
-       ColorManagedView *default_view;
+       ColorManagedView *default_view = NULL;
 
        display = colormanage_display_get_named(display_settings->display_device);
-       default_view = colormanage_view_get_default(display);
+
+       if (display)
+               default_view = colormanage_view_get_default(display);
 
        if (default_view)
                BLI_strncpy(view_settings->view_transform, default_view->name, sizeof(view_settings->view_transform));
@@ -878,11 +883,13 @@ static void colormanage_check_view_settings(ColorManagedDisplaySettings *display
                                             ColorManagedViewSettings *view_settings, const char *what)
 {
        ColorManagedDisplay *display;
-       ColorManagedView *default_view;
+       ColorManagedView *default_view = NULL;
 
        if (view_settings->view_transform[0] == '\0') {
                display = colormanage_display_get_named(display_settings->display_device);
-               default_view = colormanage_view_get_default(display);
+
+               if (display)
+                       default_view = colormanage_view_get_default(display);
 
                if (default_view)
                        BLI_strncpy(view_settings->view_transform, default_view->name, sizeof(view_settings->view_transform));
@@ -892,7 +899,9 @@ static void colormanage_check_view_settings(ColorManagedDisplaySettings *display
 
                if (!view) {
                        display = colormanage_display_get_named(display_settings->display_device);
-                       default_view = colormanage_view_get_default(display);
+
+                       if (display)
+                               default_view = colormanage_view_get_default(display);
 
                        if (default_view) {
                                printf("Color management: %s view \"%s\" not found, setting default \"%s\".\n",
@@ -974,11 +983,13 @@ void IMB_colormanagement_validate_settings(ColorManagedDisplaySettings *display_
                                            ColorManagedViewSettings *view_settings)
 {
        ColorManagedDisplay *display;
-       ColorManagedView *default_view;
+       ColorManagedView *default_view = NULL;
        LinkData *view_link;
 
        display = colormanage_display_get_named(display_settings->display_device);
-       default_view = colormanage_view_get_default(display);
+
+       if (display)
+               default_view = colormanage_view_get_default(display);
 
        for (view_link = display->views.first; view_link; view_link = view_link->next) {
                ColorManagedView *view = view_link->data;
@@ -987,7 +998,7 @@ void IMB_colormanagement_validate_settings(ColorManagedDisplaySettings *display_
                        break;
        }
 
-       if (view_link == NULL)
+       if (view_link == NULL && default_view)
                BLI_strncpy(view_settings->view_transform, default_view->name, sizeof(view_settings->view_transform));
 }
 
@@ -1894,11 +1905,13 @@ const char *IMB_colormanagement_view_get_indexed_name(int index)
 const char *IMB_colormanagement_view_get_default_name(const char *display_name)
 {
        ColorManagedDisplay *display = colormanage_display_get_named(display_name);
-       ColorManagedView *view = colormanage_view_get_default(display);
+       ColorManagedView *view = NULL;
+       
+       if (display)
+               view = colormanage_view_get_default(display);
 
-       if (view) {
+       if (view)
                return view->name;
-       }
 
        return NULL;
 }
@@ -2287,7 +2300,8 @@ void IMB_colormanagement_processor_apply_v4(ColormanageProcessor *cm_processor,
        if (cm_processor->curve_mapping)
                curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel);
 
-       OCIO_processorApplyRGBA(cm_processor->processor, pixel);
+       if (cm_processor->processor)
+               OCIO_processorApplyRGBA(cm_processor->processor, pixel);
 }
 
 void IMB_colormanagement_processor_apply_v3(ColormanageProcessor *cm_processor, float pixel[3])
@@ -2295,7 +2309,8 @@ void IMB_colormanagement_processor_apply_v3(ColormanageProcessor *cm_processor,
        if (cm_processor->curve_mapping)
                curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel);
 
-       OCIO_processorApplyRGB(cm_processor->processor, pixel);
+       if (cm_processor->processor)
+               OCIO_processorApplyRGB(cm_processor->processor, pixel);
 }
 
 void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, float *buffer, int width, int height,
@@ -2314,7 +2329,7 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo
                }
        }
 
-       {
+       if (cm_processor->processor) {
                PackedImageDesc *img;
 
                /* apply OCIO processor */
@@ -2334,8 +2349,8 @@ void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor)
 {
        if (cm_processor->curve_mapping)
                curvemapping_free(cm_processor->curve_mapping);
-
-       OCIO_processorRelease(cm_processor->processor);
+       if (cm_processor->processor)
+               OCIO_processorRelease(cm_processor->processor);
 
        MEM_freeN(cm_processor);
 }