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:
-rw-r--r--source/blender/imbuf/intern/colormanagement.c126
1 files changed, 87 insertions, 39 deletions
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 00a4699676d..23804291a65 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -1353,6 +1353,23 @@ static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned c
display_buffer_init_handle, do_display_buffer_apply_thread);
}
+static int is_ibuf_rect_in_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
+{
+ if ((view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) == 0 &&
+ view_settings->exposure == 0.0f &&
+ view_settings->gamma == 1.0f)
+ {
+ const char *from_colorspace = ibuf->rect_colorspace->name;
+ const char *to_colorspace = display_transform_get_colorspace_name(view_settings, display_settings);
+
+ if (to_colorspace && !strcmp(from_colorspace, to_colorspace))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void colormanage_display_buffer_process_ex(ImBuf *ibuf, float *display_buffer, unsigned char *display_buffer_byte,
const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings)
@@ -1366,16 +1383,7 @@ static void colormanage_display_buffer_process_ex(ImBuf *ibuf, float *display_bu
* 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)
- {
- const char *from_colorspace = ibuf->rect_colorspace->name;
- const char *to_colorspace = display_transform_get_colorspace_name(view_settings, display_settings);
-
- if (to_colorspace && !strcmp(from_colorspace, to_colorspace))
- skip_transform = TRUE;
- }
+ skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings);
}
if (skip_transform == FALSE)
@@ -2332,37 +2340,67 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
int is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
if (dither != 0.0f) {
+ /* cm_processor is NULL in cases byte_buffer's space matches display
+ * buffer's space
+ * in this case we could skip extra transform and only apply dither
+ * use 4 channels for easier byte->float->byte conversion here so
+ * (this is only needed to apply dither, in other cases we'll convert
+ * byte buffer to display directly)
+ */
+ if (!cm_processor)
+ channels = 4;
+
display_buffer_float = MEM_callocN(channels * width * height * sizeof(float), "display buffer for dither");
}
- for (y = ymin; y < ymax; y++) {
- for (x = xmin; x < xmax; x++) {
- int display_index = (y * display_stride + x) * channels;
- int linear_index = ((y - linear_offset_y) * linear_stride + (x - linear_offset_x)) * channels;
- float pixel[4];
-
- if (linear_buffer) {
- copy_v4_v4(pixel, (float *) linear_buffer + linear_index);
- }
- else if (byte_buffer) {
- rgba_uchar_to_float(pixel, byte_buffer + linear_index);
- IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace);
- straight_to_premul_v4(pixel);
- }
-
- if (!is_data) {
- IMB_colormanagement_processor_apply_v4_predivide(cm_processor, pixel);
+ if (cm_processor) {
+ for (y = ymin; y < ymax; y++) {
+ for (x = xmin; x < xmax; x++) {
+ int display_index = (y * display_stride + x) * channels;
+ int linear_index = ((y - linear_offset_y) * linear_stride + (x - linear_offset_x)) * channels;
+ float pixel[4];
+
+ if (linear_buffer) {
+ copy_v4_v4(pixel, (float *) linear_buffer + linear_index);
+ }
+ else if (byte_buffer) {
+ rgba_uchar_to_float(pixel, byte_buffer + linear_index);
+ IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace);
+ straight_to_premul_v4(pixel);
+ }
+
+ if (!is_data) {
+ IMB_colormanagement_processor_apply_v4_predivide(cm_processor, pixel);
+ }
+
+ if (display_buffer_float) {
+ int index = ((y - ymin) * width + (x - xmin)) * channels;
+
+ copy_v4_v4(display_buffer_float + index, pixel);
+ }
+ else {
+ float pixel_straight[4];
+ premul_to_straight_v4_v4(pixel_straight, pixel);
+ rgba_float_to_uchar(display_buffer + display_index, pixel_straight);
+ }
}
+ }
+ }
+ else {
+ if (display_buffer_float) {
+ /* huh, for dither we need float buffer first, no cheaper way. currently */
+ IMB_buffer_float_from_byte(display_buffer_float, byte_buffer,
+ IB_PROFILE_SRGB, IB_PROFILE_SRGB, TRUE,
+ width, height, width, display_stride);
+ }
+ else {
+ int i, width = xmax - xmin;
- if (display_buffer_float) {
- int index = ((y - ymin) * width + (x - xmin)) * channels;
+ for (i = ymin; i < ymax; i++) {
+ int byte_offset = (linear_stride * i + xmin) * 4;
+ int display_offset = (display_stride * i + xmin) * 4;
- copy_v4_v4(display_buffer_float + index, pixel);
- }
- else {
- float pixel_straight[4];
- premul_to_straight_v4_v4(pixel_straight, pixel);
- rgba_float_to_uchar(display_buffer + display_index, pixel_straight);
+ memcpy(display_buffer + display_offset, byte_buffer + byte_offset, 4 * sizeof(char) * width);
}
}
}
@@ -2426,14 +2464,24 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
BLI_unlock_thread(LOCK_COLORMANAGE);
if (display_buffer) {
- ColormanageProcessor *cm_processor;
+ ColormanageProcessor *cm_processor = NULL;
+ int skip_transform = 0;
+
+ /* byte buffer is assumed to be in imbuf's rect space, so if byte buffer
+ * is known we could skip display->linear->display conversion in case
+ * display color space matches imbuf's rect space
+ */
+ if (byte_buffer != NULL)
+ skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings);
- cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+ if (!skip_transform)
+ cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
partial_buffer_update_rect(ibuf, display_buffer, linear_buffer, byte_buffer, buffer_width, stride,
- offset_x, offset_y, cm_processor, xmin, ymin, xmax, ymax);
+ offset_x, offset_y, cm_processor, xmin, ymin, xmax, ymax);
- IMB_colormanagement_processor_free(cm_processor);
+ if (cm_processor)
+ IMB_colormanagement_processor_free(cm_processor);
IMB_display_buffer_release(cache_handle);
}