Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/imbuf/intern/colormanagement.c')
-rw-r--r--source/blender/imbuf/intern/colormanagement.c211
1 files changed, 155 insertions, 56 deletions
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 6db45f0308a..11dce3087c6 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -68,7 +68,8 @@
/*********************** Global declarations *************************/
-#define MAX_COLORSPACE_NAME 64
+#define MAX_COLORSPACE_NAME 64
+#define DISPLAY_BUFFER_CHANNELS 4
/* ** list of all supported color spaces, displays and views */
static char global_role_scene_linear[MAX_COLORSPACE_NAME];
@@ -329,8 +330,7 @@ static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheV
ColormnaageCacheData *cache_data;
BLI_assert(cache_ibuf->x == ibuf->x &&
- cache_ibuf->y == ibuf->y &&
- cache_ibuf->channels == ibuf->channels);
+ cache_ibuf->y == ibuf->y);
/* only buffers with different color space conversions are being stored
* in cache separately. buffer which were used only different exposure/gamma
@@ -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,27 +438,28 @@ 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);
for (index = 0 ; index < tot_colorspace; index++) {
ConstColorSpaceRcPtr *ocio_colorspace;
const char *description;
- int is_invertible;
+ int is_invertible, is_data;
name = OCIO_configGetColorSpaceNameByIndex(config, index);
ocio_colorspace = OCIO_configGetColorSpace(config, name);
description = OCIO_colorSpaceGetDescription(ocio_colorspace);
is_invertible = OCIO_colorSpaceIsInvertible(ocio_colorspace);
+ is_data = OCIO_colorSpaceIsData(ocio_colorspace);
- colormanage_colorspace_add(name, description, is_invertible);
+ colormanage_colorspace_add(name, description, is_invertible, is_data);
OCIO_colorSpaceRelease(ocio_colorspace);
}
@@ -565,6 +569,10 @@ void IMB_colormanagement_init(void)
}
}
+ if (config == NULL) {
+ config = OCIO_getDefaultConfig();
+ }
+
if (config) {
OCIO_setCurrentConfig(config);
@@ -789,10 +797,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));
@@ -837,6 +847,13 @@ void colormanage_imbuf_set_default_spaces(ImBuf *ibuf)
void colormanage_imbuf_make_linear(ImBuf *ibuf, const char *from_colorspace)
{
+ ColorSpace *colorspace = colormanage_colorspace_get_named(from_colorspace);
+
+ if (colorspace->is_data) {
+ ibuf->colormanage_flag |= IMB_COLORMANAGE_IS_DATA;
+ return;
+ }
+
if (ibuf->rect_float) {
const char *to_colorspace = global_role_scene_linear;
int predivide = ibuf->flags & IB_cm_predivide;
@@ -874,11 +891,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));
@@ -888,7 +907,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",
@@ -970,11 +991,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;
@@ -983,7 +1006,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));
}
@@ -1016,6 +1039,19 @@ const char *IMB_colormanagement_role_colorspace_name_get(int role)
return NULL;
}
+void IMB_colormanagement_assign_rect_colorspace(ImBuf *ibuf, const char *name)
+{
+ ColorSpace *colorspace = colormanage_colorspace_get_named(name);
+ if (colorspace) {
+ ibuf->rect_colorspace = colorspace;
+
+ if (colorspace->is_data)
+ ibuf->colormanage_flag |= IMB_COLORMANAGE_IS_DATA;
+ else
+ ibuf->colormanage_flag &= ~IMB_COLORMANAGE_IS_DATA;
+ }
+}
+
/*********************** Threaded display buffer transform routines *************************/
typedef struct DisplayBufferThread {
@@ -1034,6 +1070,7 @@ typedef struct DisplayBufferThread {
int channels;
float dither;
int predivide;
+ int is_data;
const char *byte_colorspace;
const char *float_colorspace;
@@ -1063,8 +1100,10 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l
int predivide = ibuf->flags & IB_cm_predivide;
int channels = ibuf->channels;
float dither = ibuf->dither;
+ int is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
int offset = channels * start_line * ibuf->x;
+ int display_buffer_byte_offset = DISPLAY_BUFFER_CHANNELS * start_line * ibuf->x;
memset(handle, 0, sizeof(DisplayBufferThread));
@@ -1080,7 +1119,7 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l
handle->display_buffer = init_data->display_buffer + offset;
if (init_data->display_buffer_byte)
- handle->display_buffer_byte = init_data->display_buffer_byte + offset;
+ handle->display_buffer_byte = init_data->display_buffer_byte + display_buffer_byte_offset;
handle->width = ibuf->x;
@@ -1090,6 +1129,7 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l
handle->channels = channels;
handle->dither = dither;
handle->predivide = predivide;
+ handle->is_data = is_data;
handle->byte_colorspace = init_data->byte_colorspace;
handle->float_colorspace = init_data->float_colorspace;
@@ -1106,6 +1146,7 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle)
int buffer_size = channels * width * height;
int predivide = handle->predivide;
+ int is_data = handle->is_data;
linear_buffer = MEM_callocN(buffer_size * sizeof(float), "color conversion linear buffer");
@@ -1127,9 +1168,11 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle)
*fp = (float)(*cp) / 255.0f;
}
- /* convert float buffer to scene linear space */
- IMB_colormanagement_transform(linear_buffer, width, height, channels,
- from_colorspace, to_colorspace, predivide);
+ if (!is_data) {
+ /* convert float buffer to scene linear space */
+ IMB_colormanagement_transform(linear_buffer, width, height, channels,
+ from_colorspace, to_colorspace, predivide);
+ }
}
else if (handle->float_colorspace) {
/* currently float is non-linear only in sequencer, which is working
@@ -1166,7 +1209,6 @@ static void *do_display_buffer_apply_thread(void *handle_v)
{
DisplayBufferThread *handle = (DisplayBufferThread *) handle_v;
ColormanageProcessor *cm_processor = handle->cm_processor;
- float *buffer = handle->buffer;
float *display_buffer = handle->display_buffer;
unsigned char *display_buffer_byte = handle->display_buffer_byte;
int channels = handle->channels;
@@ -1174,25 +1216,45 @@ static void *do_display_buffer_apply_thread(void *handle_v)
int height = handle->tot_line;
float dither = handle->dither;
int predivide = handle->predivide;
+ int is_data = handle->is_data;
- float *linear_buffer = display_buffer_apply_get_linear_buffer(handle);
-
- /* apply processor */
- IMB_colormanagement_processor_apply(cm_processor, linear_buffer, width, height, channels, predivide);
+ if (cm_processor == NULL) {
+ if (display_buffer_byte) {
+ IMB_buffer_byte_from_byte(display_buffer_byte, handle->byte_buffer, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
+ FALSE, width, height, width, width);
+ }
- /* copy result to output buffers */
- if (display_buffer_byte) {
- /* do conversion */
- IMB_buffer_byte_from_float(display_buffer_byte, linear_buffer,
- channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- predivide, width, height, width, width);
+ if (display_buffer) {
+ IMB_buffer_float_from_byte(display_buffer, handle->byte_buffer, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
+ FALSE, width, height, width, width);
+ }
}
+ else {
+ float *linear_buffer = display_buffer_apply_get_linear_buffer(handle);
+
+ if (is_data) {
+ /* special case for data buffers - no color space conversions,
+ * only generate byte buffers
+ */
+ }
+ else {
+ /* apply processor */
+ IMB_colormanagement_processor_apply(cm_processor, linear_buffer, width, height, channels, predivide);
+ }
- if (display_buffer)
- memcpy(display_buffer, linear_buffer, width * height * channels * sizeof(float));
+ /* copy result to output buffers */
+ if (display_buffer_byte) {
+ /* do conversion */
+ IMB_buffer_byte_from_float(display_buffer_byte, linear_buffer,
+ channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
+ predivide, width, height, width, width);
+ }
+
+ if (display_buffer)
+ memcpy(display_buffer, linear_buffer, width * height * channels * sizeof(float));
- if (linear_buffer != buffer)
MEM_freeN(linear_buffer);
+ }
return NULL;
}
@@ -1235,14 +1297,43 @@ static void colormanage_display_buffer_process_ex(ImBuf *ibuf, float *display_bu
const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings)
{
- ColormanageProcessor *cm_processor;
+ ColormanageProcessor *cm_processor = NULL;
+ int skip_transform = FALSE;
- cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+ /* if we're going to transform byte buffer, check whether transformation would
+ * happen to the same color space as byte buffer itself is
+ * this would save byte -> float -> byte conversions making display buffer
+ * computation noticeable faster
+ */
+ if (ibuf->rect_float == NULL && ibuf->rect_colorspace) {
+ if ((view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) == 0 &&
+ view_settings->exposure == 0.0f &&
+ view_settings->gamma == 1.0f)
+ {
+ ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+
+ if (config) {
+ const char *display = display_settings->display_device;
+ const char *view = view_settings->view_transform;
+ const char *from_colorspace = ibuf->rect_colorspace->name;
+ const char *to_colorspace = OCIO_configGetDisplayColorSpaceName(config, display, view);
+
+ if (!strcmp(from_colorspace, to_colorspace))
+ skip_transform = TRUE;
+
+ OCIO_configRelease(config);
+ }
+ }
+ }
+
+ if (skip_transform == FALSE)
+ cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
display_buffer_apply_threaded(ibuf, ibuf->rect_float, (unsigned char *) ibuf->rect,
display_buffer, display_buffer_byte, cm_processor);
- IMB_colormanagement_processor_free(cm_processor);
+ if (cm_processor)
+ IMB_colormanagement_processor_free(cm_processor);
}
static void colormanage_display_buffer_process(ImBuf *ibuf, unsigned char *display_buffer,
@@ -1622,7 +1713,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet
return display_buffer;
}
- buffer_size = ibuf->channels * ibuf->x * ibuf->y * sizeof(float);
+ buffer_size = DISPLAY_BUFFER_CHANNELS * ibuf->x * ibuf->y * sizeof(float);
display_buffer = MEM_callocN(buffer_size, "imbuf display buffer");
colormanage_display_buffer_process(ibuf, display_buffer, applied_view_settings, display_settings);
@@ -1667,7 +1758,7 @@ void IMB_display_buffer_transform_apply(unsigned char *display_buffer, float *li
const ColorManagedDisplaySettings *display_settings, int predivide)
{
if (global_tot_display == 0 || global_tot_view == 0) {
- IMB_buffer_byte_from_float(display_buffer, linear_buffer, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, FALSE,
+ IMB_buffer_byte_from_float(display_buffer, linear_buffer, channels, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, FALSE,
width, height, width, width);
}
else {
@@ -1890,11 +1981,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;
}
@@ -1921,7 +2014,7 @@ static void colormanage_description_strip(char *description)
}
}
-ColorSpace *colormanage_colorspace_add(const char *name, const char *description, int is_invertible)
+ColorSpace *colormanage_colorspace_add(const char *name, const char *description, int is_invertible, int is_data)
{
ColorSpace *colorspace, *prev_space;
int counter = 1;
@@ -1937,6 +2030,7 @@ ColorSpace *colormanage_colorspace_add(const char *name, const char *description
}
colorspace->is_invertible = is_invertible;
+ colorspace->is_data = is_data;
for (prev_space = global_colorspaces.first; prev_space; prev_space = prev_space->next) {
if (BLI_strcasecmp(prev_space->name, colorspace->name) > 0)
@@ -2124,6 +2218,7 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
float *display_buffer_float = NULL;
int width = xmax - xmin;
int height = ymax - ymin;
+ int is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
if (dither != 0.0f) {
display_buffer_float = MEM_callocN(channels * width * height * sizeof(float), "display buffer for dither");
@@ -2144,10 +2239,12 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace);
}
- if (predivide)
- IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
- else
- IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
+ if (!is_data) {
+ if (predivide)
+ IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
+ else
+ IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
+ }
if (display_buffer_float) {
int index = ((y - ymin) * width + (x - xmin)) * channels;
@@ -2283,7 +2380,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])
@@ -2291,7 +2389,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,
@@ -2310,7 +2409,7 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo
}
}
- {
+ if (cm_processor->processor && channels >= 3) {
PackedImageDesc *img;
/* apply OCIO processor */
@@ -2330,8 +2429,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);
}