[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [50421] branches/soc-2011-tomato: Color Management: made OpenColorIO transformations aware of color unpremultiply

Sergey Sharybin sergey.vfx at gmail.com
Wed Sep 5 15:58:01 CEST 2012


Revision: 50421
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=50421
Author:   nazgul
Date:     2012-09-05 13:58:01 +0000 (Wed, 05 Sep 2012)
Log Message:
-----------
Color Management: made OpenColorIO transformations aware of color unpremultiply

Mainly behaves in the same way as legacy color transformation, but it'll
give different result on over and under exposured areas.

Not sure if it's indeed issue -- seems this behaves crappy in both of
current stable release and OCIO branch.

Modified Paths:
--------------
    branches/soc-2011-tomato/intern/opencolorio/ocio_capi.cpp
    branches/soc-2011-tomato/intern/opencolorio/ocio_capi.h
    branches/soc-2011-tomato/source/blender/editors/space_image/space_image.c
    branches/soc-2011-tomato/source/blender/imbuf/IMB_colormanagement.h
    branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c

Modified: branches/soc-2011-tomato/intern/opencolorio/ocio_capi.cpp
===================================================================
--- branches/soc-2011-tomato/intern/opencolorio/ocio_capi.cpp	2012-09-05 13:50:24 UTC (rev 50420)
+++ branches/soc-2011-tomato/intern/opencolorio/ocio_capi.cpp	2012-09-05 13:58:01 UTC (rev 50421)
@@ -304,6 +304,34 @@
 	}
 }
 
+void OCIO_processorApply_predivide(ConstProcessorRcPtr *processor, PackedImageDesc *img)
+{
+	try {
+		int channels = img->getNumChannels();
+
+		if (channels == 4) {
+			float *pixels = img->getData();
+
+			int width = img->getWidth();
+			int height = img->getHeight();
+
+			for (int y = 0; y < height; y++) {
+				for (int x = 0; x < width; x++) {
+					float *pixel = pixels + 4 * (y * width + x);
+
+					OCIO_processorApplyRGBA_predivide(processor, pixel);
+				}
+			}
+		}
+		else {
+			(*processor)->apply(*img);
+		}
+	}
+	catch (Exception &exception) {
+		OCIO_reportException(exception);
+	}
+}
+
 void OCIO_processorApplyRGB(ConstProcessorRcPtr *processor, float *pixel)
 {
 	(*processor)->applyRGB(pixel);
@@ -314,6 +342,29 @@
 	(*processor)->applyRGBA(pixel);
 }
 
+void OCIO_processorApplyRGBA_predivide(ConstProcessorRcPtr *processor, float *pixel)
+{
+	if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
+		(*processor)->applyRGBA(pixel);
+	}
+	else {
+		float alpha, inv_alpha;
+
+		alpha = pixel[3];
+		inv_alpha = 1.0f / alpha;
+
+		pixel[0] *= inv_alpha;
+		pixel[1] *= inv_alpha;
+		pixel[2] *= inv_alpha;
+
+		(*processor)->applyRGBA(pixel);
+
+		pixel[0] *= alpha;
+		pixel[1] *= alpha;
+		pixel[2] *= alpha;
+	}
+}
+
 void OCIO_processorRelease(ConstProcessorRcPtr *p)
 {
 	delete p;

Modified: branches/soc-2011-tomato/intern/opencolorio/ocio_capi.h
===================================================================
--- branches/soc-2011-tomato/intern/opencolorio/ocio_capi.h	2012-09-05 13:50:24 UTC (rev 50420)
+++ branches/soc-2011-tomato/intern/opencolorio/ocio_capi.h	2012-09-05 13:58:01 UTC (rev 50421)
@@ -83,8 +83,10 @@
 ConstProcessorRcPtr *OCIO_configGetProcessor(ConstConfigRcPtr *config, ConstTransformRcPtr *transform);
 
 void OCIO_processorApply(ConstProcessorRcPtr *processor, PackedImageDesc *img);
+void OCIO_processorApply_predivide(ConstProcessorRcPtr *processor, PackedImageDesc *img);
 void OCIO_processorApplyRGB(ConstProcessorRcPtr *processor, float *pixel);
 void OCIO_processorApplyRGBA(ConstProcessorRcPtr *processor, float *pixel);
+void OCIO_processorApplyRGBA_predivide(ConstProcessorRcPtr *processor, float *pixel);
 
 void OCIO_processorRelease(ConstProcessorRcPtr *p);
 

Modified: branches/soc-2011-tomato/source/blender/editors/space_image/space_image.c
===================================================================
--- branches/soc-2011-tomato/source/blender/editors/space_image/space_image.c	2012-09-05 13:50:24 UTC (rev 50420)
+++ branches/soc-2011-tomato/source/blender/editors/space_image/space_image.c	2012-09-05 13:58:01 UTC (rev 50421)
@@ -443,6 +443,7 @@
 					break;
 				case ND_MODE:
 				case ND_RENDER_RESULT:
+				case ND_RENDER_OPTIONS:
 				case ND_COMPO_RESULT:
 					if (ED_space_image_show_render(sima))
 						image_scopes_tag_refresh(sa);

Modified: branches/soc-2011-tomato/source/blender/imbuf/IMB_colormanagement.h
===================================================================
--- branches/soc-2011-tomato/source/blender/imbuf/IMB_colormanagement.h	2012-09-05 13:50:24 UTC (rev 50420)
+++ branches/soc-2011-tomato/source/blender/imbuf/IMB_colormanagement.h	2012-09-05 13:58:01 UTC (rev 50421)
@@ -59,7 +59,8 @@
 
 /* ** Color space transformation functions ** */
 void IMB_colormanagement_colorspace_transform(float *buffer, int width, int height, int channels,
-                                              const char *from_colorspace, const char *to_colorspace);
+                                              const char *from_colorspace, const char *to_colorspace,
+                                              int predivide);
 
 void IMB_colormanagement_pixel_to_role(float pixel[4], int role);
 void IMB_colormanagement_pixel_from_role(float pixel[4], int role);

Modified: branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c
===================================================================
--- branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c	2012-09-05 13:50:24 UTC (rev 50420)
+++ branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c	2012-09-05 13:58:01 UTC (rev 50421)
@@ -176,6 +176,7 @@
 typedef struct ColormnaageCacheData {
 	float exposure;  /* exposure value cached buffer is calculated with */
 	float gamma;     /* gamma value cached buffer is calculated with */
+	int predivide;   /* predivide flag of cached buffer */
 } ColormnaageCacheData;
 
 typedef struct ColormanageCache {
@@ -308,6 +309,7 @@
 	ColormanageCacheKey key;
 	ImBuf *cache_ibuf;
 	int view_flag = 1 << (view_settings->view - 1);
+	int predivide = ibuf->flags & IB_cm_predivide;
 
 	colormanage_settings_to_key(&key, view_settings, display_settings);
 
@@ -335,7 +337,8 @@
 		cache_data = colormanage_cachedata_get(cache_ibuf);
 
 		if (cache_data->exposure != view_settings->exposure ||
-		    cache_data->gamma != view_settings->gamma)
+		    cache_data->gamma != view_settings->gamma ||
+			cache_data->predivide != predivide)
 		{
 			*cache_handle = NULL;
 
@@ -358,6 +361,7 @@
 	ImBuf *cache_ibuf;
 	ColormnaageCacheData *cache_data;
 	int view_flag = 1 << (view_settings->view - 1);
+	int predivide = ibuf->flags & IB_cm_predivide;
 	struct MovieCache *moviecache = colormanage_moviecache_ensure(ibuf);
 
 	colormanage_settings_to_key(&key, view_settings, display_settings);
@@ -376,6 +380,7 @@
 	cache_data = MEM_callocN(sizeof(ColormnaageCacheData), "color manage cache imbuf data");
 	cache_data->exposure = view_settings->exposure;
 	cache_data->gamma = view_settings->gamma;
+	cache_data->predivide = predivide;
 
 	colormanage_cachedata_set(cache_ibuf, cache_data);
 
@@ -693,7 +698,6 @@
 
 	int buffer_size = channels * width * height;
 
-	/* TODO: do we actually need to handle alpha premultiply in some way here? */
 	int predivide = handle->predivide;
 
 	linear_buffer = MEM_callocN(buffer_size * sizeof(float), "color conversion linear buffer");
@@ -721,7 +725,7 @@
 		memcpy(linear_buffer, handle->buffer, buffer_size * sizeof(float));
 
 		IMB_colormanagement_colorspace_transform(linear_buffer, width, height, channels,
-		                                         from_colorspace, to_colorspace);
+		                                         from_colorspace, to_colorspace, predivide);
 	}
 	else {
 		/* some processors would want to modify float original buffer
@@ -758,7 +762,10 @@
 	img = OCIO_createPackedImageDesc(linear_buffer, width, height, channels, sizeof(float),
 	                                 channels * sizeof(float), channels * sizeof(float) * width);
 
-	OCIO_processorApply(processor, img);
+	if (predivide)
+		OCIO_processorApply_predivide(processor, img);
+	else
+		OCIO_processorApply(processor, img);
 
 	OCIO_packedImageDescRelease(img);
 
@@ -865,6 +872,7 @@
 	int start_line;
 	int tot_line;
 	int channels;
+	int predivide;
 } ColorspaceTransformThread;
 
 typedef struct ColorspaceTransformInit {
@@ -873,6 +881,7 @@
 	int width;
 	int height;
 	int channels;
+	int predivide;
 } ColorspaceTransformInitData;
 
 static void colorspace_transform_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
@@ -882,6 +891,7 @@
 
 	int channels = init_data->channels;
 	int width = init_data->width;
+	int predivide = init_data->predivide;
 
 	int offset = channels * start_line * width;
 
@@ -897,10 +907,11 @@
 	handle->tot_line = tot_line;
 
 	handle->channels = channels;
+	handle->predivide = predivide;
 }
 
 static void colorspace_transform_apply_threaded(float *buffer, int width, int height, int channels,
-                                                void *processor, void *(do_thread) (void *))
+                                                void *processor, int predivide, void *(do_thread) (void *))
 {
 	ColorspaceTransformInitData init_data;
 
@@ -909,6 +920,7 @@
 	init_data.width = width;
 	init_data.height = height;
 	init_data.channels = channels;
+	init_data.predivide = predivide;
 
 	IMB_processor_apply_threaded(height, sizeof(ColorspaceTransformThread), &init_data,
 	                             colorspace_transform_init_handle, do_thread);
@@ -923,11 +935,15 @@
 	int channels = handle->channels;
 	int width = handle->width;
 	int height = handle->tot_line;
+	int predivide = handle->predivide;
 
 	img = OCIO_createPackedImageDesc(buffer, width, height, channels, sizeof(float),
 	                                 channels * sizeof(float), channels * sizeof(float) * width);
 
-	OCIO_processorApply(processor, img);
+	if (predivide)
+		OCIO_processorApply_predivide(processor, img);
+	else
+		OCIO_processorApply(processor, img);
 
 	OCIO_packedImageDescRelease(img);
 
@@ -947,7 +963,8 @@
 #endif
 
 void IMB_colormanagement_colorspace_transform(float *buffer, int width, int height, int channels,
-                                              const char *from_colorspace, const char *to_colorspace)
+                                              const char *from_colorspace, const char *to_colorspace,
+                                              int predivide)
 {
 #ifdef WITH_OCIO
 	ConstProcessorRcPtr *processor;
@@ -966,8 +983,8 @@
 	processor = create_colorspace_transform_processor(from_colorspace, to_colorspace);
 
 	if (processor) {
-		colorspace_transform_apply_threaded(buffer, width, height, channels,
-		                                    processor, do_color_space_transform_thread);
+		colorspace_transform_apply_threaded(buffer, width, height, channels, processor, predivide,
+		                                    do_color_space_transform_thread);
 
 		OCIO_processorRelease(processor);
 	}
@@ -1012,12 +1029,13 @@
 	if (ibuf->rect_float) {
 		const char *from_colorspace = global_role_scene_linear;
 		const char *to_colorspace = role_colorspace_name_get(role);
+		int predivide = ibuf->flags & IB_cm_predivide;
 
 		if (ibuf->rect)
 			imb_freerectImBuf(ibuf);
 
 		IMB_colormanagement_colorspace_transform(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
-		                                         from_colorspace, to_colorspace);
+		                                         from_colorspace, to_colorspace, predivide);
 	}
 #else
 	(void) ibuf;
@@ -1031,12 +1049,13 @@

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list