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')
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h13
-rw-r--r--source/blender/imbuf/intern/IMB_colormanagement_intern.h7
-rw-r--r--source/blender/imbuf/intern/colormanagement.c91
3 files changed, 111 insertions, 0 deletions
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 620f8984d9f..e683d38a0aa 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -58,6 +58,10 @@ void IMB_colormanagement_assign_rect_colorspace(struct ImBuf *ibuf, const char *
const char *IMB_colormanagement_get_float_colorspace(struct ImBuf *ibuf);
const char *IMB_colormanagement_get_rect_colorspace(struct ImBuf *ibuf);
+bool IMB_colormanagement_space_is_data(struct ColorSpace *colorspace);
+bool IMB_colormanagement_space_is_scene_linear(struct ColorSpace *colorspace);
+bool IMB_colormanagement_space_is_srgb(struct ColorSpace *colorspace);
+
BLI_INLINE float IMB_colormanagement_get_luminance(const float rgb[3]);
BLI_INLINE unsigned char IMB_colormanagement_get_luminance_byte(const unsigned char[3]);
BLI_INLINE void IMB_colormangement_xyz_to_rgb(float rgb[3], const float xyz[3]);
@@ -124,6 +128,14 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer,
struct ColorSpace *colorspace,
bool predivide);
+void IMB_colormanagement_imbuf_to_srgb_texture(unsigned char *rect,
+ const int x,
+ const int y,
+ const int width,
+ const int height,
+ const struct ImBuf *ibuf,
+ const bool compress_as_srgb);
+
void IMB_colormanagement_scene_linear_to_color_picking_v3(float pixel[3]);
void IMB_colormanagement_color_picking_to_scene_linear_v3(float pixel[3]);
@@ -340,6 +352,7 @@ enum {
COLOR_ROLE_DEFAULT_SEQUENCER,
COLOR_ROLE_DEFAULT_BYTE,
COLOR_ROLE_DEFAULT_FLOAT,
+ COLOR_ROLE_DATA,
};
#include "intern/colormanagement_inline.c"
diff --git a/source/blender/imbuf/intern/IMB_colormanagement_intern.h b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
index 2566016ffdd..a83f2d60b8c 100644
--- a/source/blender/imbuf/intern/IMB_colormanagement_intern.h
+++ b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
@@ -48,6 +48,13 @@ typedef struct ColorSpace {
bool is_invertible;
bool is_data;
+
+ /* Additional info computed only when needed since it's not cheap. */
+ struct {
+ bool cached;
+ bool is_srgb;
+ bool is_scene_linear;
+ } info;
} ColorSpace;
typedef struct ColorManagedDisplay {
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index f31d4ede693..b460d268d38 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -65,6 +65,7 @@
#define DISPLAY_BUFFER_CHANNELS 4
/* ** list of all supported color spaces, displays and views */
+static char global_role_data[MAX_COLORSPACE_NAME];
static char global_role_scene_linear[MAX_COLORSPACE_NAME];
static char global_role_color_picking[MAX_COLORSPACE_NAME];
static char global_role_texture_painting[MAX_COLORSPACE_NAME];
@@ -488,6 +489,7 @@ static void colormanage_load_config(OCIO_ConstConfigRcPtr *config)
const char *name;
/* get roles */
+ colormanage_role_color_space_name_get(config, global_role_data, OCIO_ROLE_DATA, NULL);
colormanage_role_color_space_name_get(
config, global_role_scene_linear, OCIO_ROLE_SCENE_LINEAR, NULL);
colormanage_role_color_space_name_get(
@@ -1260,6 +1262,8 @@ void IMB_colormanagement_validate_settings(const ColorManagedDisplaySettings *di
const char *IMB_colormanagement_role_colorspace_name_get(int role)
{
switch (role) {
+ case COLOR_ROLE_DATA:
+ return global_role_data;
case COLOR_ROLE_SCENE_LINEAR:
return global_role_scene_linear;
case COLOR_ROLE_COLOR_PICKING:
@@ -1341,6 +1345,42 @@ const char *IMB_colormanagement_get_rect_colorspace(ImBuf *ibuf)
}
}
+bool IMB_colormanagement_space_is_data(ColorSpace *colorspace)
+{
+ return (colorspace && colorspace->is_data);
+}
+
+static void colormanage_ensure_srgb_scene_linear_info(ColorSpace *colorspace)
+{
+ if (!colorspace->info.cached) {
+ OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+ OCIO_ConstColorSpaceRcPtr *ocio_colorspace = OCIO_configGetColorSpace(config,
+ colorspace->name);
+
+ bool is_scene_linear, is_srgb;
+ OCIO_colorSpaceIsBuiltin(config, ocio_colorspace, &is_scene_linear, &is_srgb);
+
+ OCIO_colorSpaceRelease(ocio_colorspace);
+ OCIO_configRelease(config);
+
+ colorspace->info.is_scene_linear = is_scene_linear;
+ colorspace->info.is_srgb = is_srgb;
+ colorspace->info.cached = true;
+ }
+}
+
+bool IMB_colormanagement_space_is_scene_linear(ColorSpace *colorspace)
+{
+ colormanage_ensure_srgb_scene_linear_info(colorspace);
+ return (colorspace && colorspace->info.is_scene_linear);
+}
+
+bool IMB_colormanagement_space_is_srgb(ColorSpace *colorspace)
+{
+ colormanage_ensure_srgb_scene_linear_info(colorspace);
+ return (colorspace && colorspace->info.is_srgb);
+}
+
/*********************** Threaded display buffer transform routines *************************/
typedef struct DisplayBufferThread {
@@ -2111,6 +2151,57 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer,
}
}
+void IMB_colormanagement_imbuf_to_srgb_texture(unsigned char *out_buffer,
+ const int offset_x,
+ const int offset_y,
+ const int width,
+ const int height,
+ const struct ImBuf *ibuf,
+ const bool compress_as_srgb)
+{
+ /* Convert byte buffer for texture storage on the GPU. These have builtin
+ * support for converting sRGB to linear, which allows us to store textures
+ * without precision or performance loss at minimal memory usage. */
+ BLI_assert(ibuf->rect && ibuf->rect_float == NULL);
+
+ OCIO_ConstProcessorRcPtr *processor = NULL;
+ if (compress_as_srgb && ibuf->rect_colorspace &&
+ !IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace)) {
+ processor = colorspace_to_scene_linear_processor(ibuf->rect_colorspace);
+ }
+
+ /* TODO(brecht): make this multithreaded, or at least process in batches. */
+ const unsigned char *in_buffer = (unsigned char *)ibuf->rect;
+
+ for (int y = 0; y < height; y++) {
+ const size_t in_offset = (offset_y + y) * ibuf->x + offset_x;
+ const size_t out_offset = y * width;
+ const unsigned char *in = in_buffer + in_offset * 4;
+ unsigned char *out = out_buffer + out_offset * 4;
+
+ if (processor) {
+ /* Convert to scene linear, to sRGB and premultiply. */
+ for (int x = 0; x < width; x++, in += 4, out += 4) {
+ float pixel[4];
+ rgba_uchar_to_float(pixel, in);
+ OCIO_processorApplyRGB(processor, pixel);
+ linearrgb_to_srgb_v3_v3(pixel, pixel);
+ mul_v3_fl(pixel, pixel[3]);
+ rgba_float_to_uchar(out, pixel);
+ }
+ }
+ else {
+ /* Premultiply only. */
+ for (int x = 0; x < width; x++, in += 4, out += 4) {
+ out[0] = (in[0] * in[3]) >> 8;
+ out[1] = (in[1] * in[3]) >> 8;
+ out[2] = (in[2] * in[3]) >> 8;
+ out[3] = in[3];
+ }
+ }
+ }
+}
+
/* Conversion between color picking role. Typically we would expect such a
* requirements:
* - It is approximately perceptually linear, so that the HSV numbers and