Revision: 48935
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48935
Author: nazgul
Date: 2012-07-15 10:43:45 +0000 (Sun, 15 Jul 2012)
Log Message:
-----------
Color management: implemented ability to color manage byte buffers
Color management of byte buffers is currently disabled, to enable
it COLORMANAGE_BYTE_BUFFER from colormanagement.c should be defined.
Currently color management supposes that byte buffer is originally
in sRGB space. Ideally it'll be using the same input color space
setting as float buffer which is still in a TODO list.
It could be nice artistic option to play with. Also in theory it's
possible that byte images would store data in non-sRGB space.
There's still kind of issue with byte buffers which results in
showing linear image when view transform is set to RAW. It'll be
resolved as soon as real input color space is added. Other view
transformations should work fine.
Modified Paths:
--------------
branches/soc-2011-tomato/source/blender/editors/space_image/image_ops.c
branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c
Modified:
branches/soc-2011-tomato/source/blender/editors/space_image/image_ops.c
===================================================================
--- branches/soc-2011-tomato/source/blender/editors/space_image/image_ops.c
2012-07-15 06:14:35 UTC (rev 48934)
+++ branches/soc-2011-tomato/source/blender/editors/space_image/image_ops.c
2012-07-15 10:43:45 UTC (rev 48935)
@@ -1186,8 +1186,17 @@
unsigned char *display_buffer =
IMB_display_buffer_acquire(ibuf, &imf->view_settings,
&imf->display_settings, cache_handle);
- colormanaged_ibuf = IMB_allocImBuf(ibuf->x, ibuf->y,
ibuf->planes, 0);
- colormanaged_ibuf->rect = (unsigned int *) display_buffer;
+ if (*cache_handle) {
+ colormanaged_ibuf = IMB_allocImBuf(ibuf->x, ibuf->y,
ibuf->planes, 0);
+ colormanaged_ibuf->rect = (unsigned int *)
display_buffer;
+ }
+ else {
+ /* no cache handle means color management didn't run
transformation
+ * or performed transformation to image's byte buffer
which doesn't
+ * require allocating new image buffer
+ */
+ colormanaged_ibuf = ibuf;
+ }
}
else {
colormanaged_ibuf = ibuf;
Modified: branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c
===================================================================
--- branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c
2012-07-15 06:14:35 UTC (rev 48934)
+++ branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c
2012-07-15 10:43:45 UTC (rev 48935)
@@ -65,11 +65,14 @@
/*********************** Global declarations *************************/
+/* define this to allow byte buffers be color managed */
+#undef COLORMANAGE_BYTE_BUFFER
+
/* ** list of all supported color spaces, displays and views */
#ifdef WITH_OCIO
static ListBase global_colorspaces = {NULL};
-static char global_role_linear[64];
+static char global_role_scene_linear[64];
static char global_role_color_picking[64];
static char global_role_texture_painting[64];
@@ -462,7 +465,7 @@
const char *name;
/* get roles */
- colormanage_role_color_space_name_get(config, global_role_linear,
sizeof(global_role_linear),
+ colormanage_role_color_space_name_get(config, global_role_scene_linear,
sizeof(global_role_scene_linear),
OCIO_ROLE_SCENE_LINEAR, "scene
linear");
colormanage_role_color_space_name_get(config,
global_role_color_picking, sizeof(global_role_color_picking),
@@ -616,6 +619,7 @@
void *processor;
float *buffer;
+ unsigned char *byte_buffer;
unsigned char *display_buffer;
int width;
@@ -629,7 +633,8 @@
int buffer_in_srgb;
} DisplayBufferThread;
-static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned
char *display_buffer,
+static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned
char *byte_buffer,
+ unsigned char *display_buffer,
void *processor, void *(do_thread)
(void *))
{
DisplayBufferThread handles[BLENDER_MAX_THREADS];
@@ -656,9 +661,16 @@
for (i = 0; i < tot_thread; i++) {
int offset = ibuf->channels * start_line * ibuf->x;
+ memset(&handles[i], 0, sizeof(handles[i]));
+
handles[i].processor = processor;
- handles[i].buffer = buffer + offset;
+ if (buffer)
+ handles[i].buffer = buffer + offset;
+
+ if (byte_buffer)
+ handles[i].byte_buffer = byte_buffer + offset;
+
handles[i].display_buffer = display_buffer + offset;
handles[i].width = ibuf->x;
@@ -690,25 +702,54 @@
static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread
*handle)
{
- float *linear_buffer = handle->buffer;
+ float *linear_buffer = NULL;
- if (handle->buffer_in_srgb) {
- float *buffer = handle->buffer;
+ int channels = handle->channels;
+ int width = handle->width;
+ int height = handle->tot_line;
- int channels = handle->channels;
- int width = handle->width;
- int height = handle->tot_line;
- int predivide = handle->predivide;
+ int buffer_size = channels * width * height;
- int buffer_size = 4 * 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");
+ linear_buffer = MEM_callocN(buffer_size * sizeof(float), "color
conversion linear buffer");
+ if (!handle->buffer) {
+ unsigned char *byte_buffer = handle->byte_buffer;
+
+ /* OCIO_TODO: for now assume byte buffers are in sRGB space,
+ * in the future it shall use color space specified
+ * by user
+ */
+ IMB_buffer_float_from_byte(linear_buffer, byte_buffer,
+ IB_PROFILE_LINEAR_RGB,
IB_PROFILE_SRGB,
+ predivide, width, height, width,
width);
+ }
+ else if (handle->buffer_in_srgb) {
+ /* sequencer is working with float buffers which are in sRGB
space,
+ * so we need to ensure float buffer is in linear space before
+ * applying all the view transformations
+ */
+ float *buffer = handle->buffer;
+
IMB_buffer_float_from_float(linear_buffer, buffer, channels,
IB_PROFILE_LINEAR_RGB,
IB_PROFILE_SRGB,
predivide, width, height, width,
width);
}
+ else {
+ /* some processors would want to modify float original buffer
+ * before converting it into display byte buffer, so we need to
+ * make sure original's ImBuf buffers wouldn't be modified by
+ * using duplicated buffer here
+ *
+ * NOTE: MEM_dupallocN can't be used because buffer could be
+ * specified as an offset inside allocated buffer
+ */
+ memcpy(linear_buffer, handle->buffer, buffer_size *
sizeof(float));
+ }
+
return linear_buffer;
}
@@ -742,7 +783,8 @@
static void display_buffer_apply_tonemap(ImBuf *ibuf, unsigned char
*display_buffer,
imb_tonecurveCb tonecurve_func)
{
- display_buffer_apply_threaded(ibuf, ibuf->rect_float, display_buffer,
tonecurve_func,
+ display_buffer_apply_threaded(ibuf, ibuf->rect_float, (unsigned char
*)ibuf->rect,
+ display_buffer, tonecurve_func,
do_display_buffer_apply_tonemap_thread);
}
@@ -804,7 +846,7 @@
dt = OCIO_createDisplayTransform();
/* OCIO_TODO: get rid of hardcoded input space */
- OCIO_displayTransformSetInputColorSpaceName(dt, global_role_linear);
+ OCIO_displayTransformSetInputColorSpaceName(dt,
global_role_scene_linear);
OCIO_displayTransformSetView(dt, view_transform);
OCIO_displayTransformSetDisplay(dt, display);
@@ -838,20 +880,15 @@
const float exposure = view_settings->exposure;
const char *view_transform = view_settings->view_transform;
const char *display = display_settings->display_device;
- 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);
+ display_buffer_apply_threaded(ibuf, ibuf->rect_float, (unsigned
char *) ibuf->rect,
+ display_buffer, processor,
do_display_buffer_apply_ocio_thread);
}
OCIO_processorRelease(processor);
-
- MEM_freeN(rect_float);
}
static void colormanage_display_buffer_process(ImBuf *ibuf, unsigned char
*display_buffer,
@@ -908,6 +945,12 @@
}
}
+static void imbuf_verify_float(ImBuf *ibuf)
+{
+ if (ibuf->rect_float && (ibuf->rect == NULL || (ibuf->userflags &
IB_RECT_INVALID)))
+ IMB_rect_from_float(ibuf);
+}
+
unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const
ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings
*display_settings, void **cache_handle)
{
@@ -920,9 +963,16 @@
if (!ibuf->x || !ibuf->y)
return NULL;
+#if !defined(COLORMANAGE_BYTE_BUFFER)
+ if (!ibuf->rect_float) {
+ imbuf_verify_float(ibuf);
+
+ return (unsigned char *) ibuf->rect;
+ }
+#endif
+
/* OCIO_TODO: support colormanaged byte buffers */
if (!strcmp(view_transform, "NONE") ||
- !ibuf->rect_float ||
global_tot_display == 0 ||
global_tot_view == 0)
{
@@ -931,8 +981,7 @@
* it's safe to suppose standard byte buffer is used for display
*/
- if (ibuf->rect_float && (ibuf->rect == NULL || (ibuf->userflags
& IB_RECT_INVALID)))
- IMB_rect_from_float(ibuf);
+ imbuf_verify_float(ibuf);
return (unsigned char *) ibuf->rect;
}
@@ -980,8 +1029,7 @@
(void) view_transform;
(void) display_settings;
- if (ibuf->rect_float && (ibuf->rect == NULL || (ibuf->userflags &
IB_RECT_INVALID)))
- IMB_rect_from_float(ibuf);
+ imbuf_verify_float(ibuf);
return (unsigned char*) ibuf->rect;
#endif
@@ -993,16 +1041,16 @@
#ifdef WITH_OCIO
const char *view_transform = view_settings->view_transform;
+#if !defined(COLORMANAGE_BYTE_BUFFER)
if (!ibuf->rect_float)
return;
+#endif
if (!strcmp(view_transform, "NONE") ||
- !ibuf->rect_float ||
global_tot_display == 0 ||
global_tot_view == 0)
{
- if (!ibuf->rect)
- IMB_rect_from_float(ibuf);
+ imbuf_verify_float(ibuf);
}
else {
if (!ibuf->rect) {
@@ -1015,8 +1063,7 @@
(void) view_settings;
(void) display_settings;
- if (!ibuf->rect)
- IMB_rect_from_float(ibuf);
+ imbuf_verify_float(ibuf);
#endif
}
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs