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/blenkernel/BKE_image.h2
-rw-r--r--source/blender/blenkernel/intern/image.c3
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.cpp5
-rw-r--r--source/blender/editors/render/render_opengl.c8
-rw-r--r--source/blender/editors/space_image/image_buttons.c2
-rw-r--r--source/blender/editors/space_image/image_ops.c43
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c10
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h9
-rw-r--r--source/blender/imbuf/intern/colormanagement.c144
-rw-r--r--source/blender/imbuf/intern/jp2.c51
-rw-r--r--source/blender/imbuf/intern/tiff.c10
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c9
-rw-r--r--source/blender/render/intern/source/pipeline.c24
13 files changed, 192 insertions, 128 deletions
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index ac324b2af00..5e5f58f73fe 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -66,7 +66,7 @@ int BKE_imtype_is_movie(const char imtype);
int BKE_imtype_supports_zbuf(const char imtype);
int BKE_imtype_supports_compress(const char imtype);
int BKE_imtype_supports_quality(const char imtype);
-int BKE_imtype_supports_float(const char imtype);
+int BKE_imtype_requires_linear_float(const char imtype);
char BKE_imtype_valid_channels(const char imtype);
char BKE_imtype_valid_depths(const char imtype);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 97278f14d83..e73f4fa79af 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -1031,13 +1031,12 @@ int BKE_imtype_supports_quality(const char imtype)
return 0;
}
-int BKE_imtype_supports_float(const char imtype)
+int BKE_imtype_requires_linear_float(const char imtype)
{
switch (imtype) {
case R_IMF_IMTYPE_CINEON:
case R_IMF_IMTYPE_DPX:
case R_IMF_IMTYPE_RADHDR:
- case R_IMF_IMTYPE_TIFF: /* uses the float buffer to write 16bits per channel */
case R_IMF_IMTYPE_OPENEXR:
case R_IMF_IMTYPE_MULTILAYER:
return TRUE;
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
index 21ecfdb5272..c8b6a4ee330 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
@@ -138,8 +138,9 @@ void OutputSingleLayerOperation::deinitExecution()
ibuf->mall |= IB_rectfloat;
ibuf->dither = this->m_rd->dither_intensity;
- IMB_display_buffer_to_imbuf_rect(ibuf, m_viewSettings, m_displaySettings);
-
+ IMB_colormanagement_imbuf_for_write(ibuf, TRUE, FALSE, m_viewSettings, m_displaySettings,
+ this->m_format);
+
BKE_makepicstring(filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format->imtype,
(this->m_rd->scemode & R_EXTENSION), true);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index d9618e89b68..85ae923f881 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -547,11 +547,11 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
if (ibuf) {
int needs_free = FALSE;
- if (is_movie || !BKE_imtype_supports_float(scene->r.im_format.imtype)) {
- ImBuf *colormanage_ibuf = IMB_dupImBuf(ibuf);
+ if (is_movie || !BKE_imtype_requires_linear_float(scene->r.im_format.imtype)) {
+ ImBuf *colormanage_ibuf;
- IMB_display_buffer_to_imbuf_rect(colormanage_ibuf, &scene->view_settings, &scene->display_settings);
- imb_freerectfloatImBuf(colormanage_ibuf);
+ colormanage_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, TRUE, TRUE, &scene->view_settings,
+ &scene->display_settings, &scene->r.im_format);
// IMB_freeImBuf(ibuf); /* owned by the image */
ibuf = colormanage_ibuf;
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 0b904f36a8c..59416dcf0c3 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -814,7 +814,7 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
/* color management */
if (color_management &&
- (!BKE_imtype_supports_float(imf->imtype) ||
+ (!BKE_imtype_requires_linear_float(imf->imtype) ||
(show_preview && imf->flag & R_IMF_FLAG_PREVIEW_JPG)))
{
prop = RNA_struct_find_property(imfptr, "display_settings");
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 16c9405e098..cfb265433a9 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1205,39 +1205,6 @@ static void save_image_options_to_op(SaveImageOptions *simopts, wmOperator *op)
RNA_string_set(op->ptr, "filepath", simopts->filepath);
}
-static ImBuf *save_image_colormanaged_imbuf_acquire(ImBuf *ibuf, SaveImageOptions *simopts, int save_as_render, void **cache_handle)
-{
- ImageFormatData *imf = &simopts->im_format;
- ImBuf *colormanaged_ibuf;
- int do_colormanagement;
-
- *cache_handle = NULL;
- do_colormanagement = save_as_render && !BKE_imtype_supports_float(imf->imtype);
-
- if (do_colormanagement) {
- unsigned char *display_buffer;
-
- display_buffer = IMB_display_buffer_acquire(ibuf, &imf->view_settings, &imf->display_settings, cache_handle);
-
- 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;
- }
-
- return colormanaged_ibuf;
-}
-
/* assumes name is FILE_MAX */
/* ima->name and ibuf->name should end up the same */
static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveImageOptions *simopts, int do_newpath)
@@ -1247,12 +1214,12 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock);
if (ibuf) {
- void *cache_handle;
ImBuf *colormanaged_ibuf;
const char *relbase = ID_BLEND_PATH(CTX_data_main(C), &ima->id);
const short relative = (RNA_struct_find_property(op->ptr, "relative_path") && RNA_boolean_get(op->ptr, "relative_path"));
const short save_copy = (RNA_struct_find_property(op->ptr, "copy") && RNA_boolean_get(op->ptr, "copy"));
const short save_as_render = (RNA_struct_find_property(op->ptr, "save_as_render") && RNA_boolean_get(op->ptr, "save_as_render"));
+ ImageFormatData *imf = &simopts->im_format;
short ok = FALSE;
/* old global to ensure a 2nd save goes to same dir */
@@ -1277,7 +1244,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
}
}
- colormanaged_ibuf = save_image_colormanaged_imbuf_acquire(ibuf, simopts, save_as_render, &cache_handle);
+ colormanaged_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, save_as_render, TRUE, &imf->view_settings, &imf->display_settings, imf);
if (simopts->im_format.imtype == R_IMF_IMTYPE_MULTILAYER) {
Scene *scene = CTX_data_scene(C);
@@ -1345,12 +1312,8 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
WM_cursor_wait(0);
- if (cache_handle) {
- colormanaged_ibuf->rect = NULL;
+ if (colormanaged_ibuf != ibuf)
IMB_freeImBuf(colormanaged_ibuf);
-
- IMB_display_buffer_release(cache_handle);
- }
}
ED_space_image_release_buffer(sima, lock);
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index f927e83cabe..c72bff12056 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -885,7 +885,10 @@ static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scop
ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
ImBuf *scope;
- IMB_colormanagement_imbuf_make_display_space(display_ibuf, &scene->view_settings, &scene->display_settings);
+ if (display_ibuf->rect_float) {
+ IMB_colormanagement_imbuf_make_display_space(display_ibuf, &scene->view_settings,
+ &scene->display_settings);
+ }
scope = make_scope_cb(display_ibuf);
@@ -967,7 +970,10 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
if (!scopes->zebra_ibuf) {
ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
- IMB_colormanagement_imbuf_make_display_space(display_ibuf, &scene->view_settings, &scene->display_settings);
+ if (display_ibuf->rect_float) {
+ IMB_colormanagement_imbuf_make_display_space(display_ibuf, &scene->view_settings,
+ &scene->display_settings);
+ }
scopes->zebra_ibuf = make_zebra_view_from_ibuf(display_ibuf, sseq->zebra);
IMB_freeImBuf(display_ibuf);
}
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 5d0ab5e57d4..7126d1bcc8b 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -45,6 +45,7 @@ struct rcti;
struct PartialBufferUpdateContext;
struct wmWindow;
struct Scene;
+struct ImageFormatData;
struct ColorSpace;
struct ColorManagedDisplay;
@@ -90,15 +91,17 @@ void IMB_colormanagement_imbuf_assign_float_space(struct ImBuf *ibuf, struct Col
void IMB_colormanagement_imbuf_make_display_space(struct ImBuf *ibuf, const struct ColorManagedViewSettings *view_settings,
const struct ColorManagedDisplaySettings *display_settings);
+struct ImBuf *IMB_colormanagement_imbuf_for_write(struct ImBuf *ibuf, int save_as_render, int allocate_result,
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings,
+ struct ImageFormatData *image_format_data);
+
/* ** Public display buffers interfaces ** */
unsigned char *IMB_display_buffer_acquire(struct ImBuf *ibuf, const struct ColorManagedViewSettings *view_settings,
const struct ColorManagedDisplaySettings *display_settings, void **cache_handle);
unsigned char *IMB_display_buffer_acquire_ctx(const struct bContext *C, struct ImBuf *ibuf, void **cache_handle);
-void IMB_display_buffer_to_imbuf_rect(struct ImBuf *ibuf, const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings);
-
void IMB_display_buffer_transform_apply(unsigned char *display_buffer, float *linear_buffer, int width, int height,
int channels, const struct ColorManagedViewSettings *view_settings,
const struct ColorManagedDisplaySettings *display_settings, int predivide);
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 11dce3087c6..18a03c859e9 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -59,6 +59,7 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
+#include "BKE_image.h"
#include "BKE_utildefines.h"
#include "BKE_main.h"
@@ -632,6 +633,37 @@ static void display_transform_get_from_ctx(const bContext *C, ColorManagedViewSe
}
}
+static const char *display_transform_get_colorspace_name(const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
+{
+ ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+
+ if (config) {
+ const char *display = display_settings->display_device;
+ const char *view = view_settings->view_transform;
+ const char *colorspace_name;
+
+ colorspace_name = OCIO_configGetDisplayColorSpaceName(config, display, view);
+
+ OCIO_configRelease(config);
+
+ return colorspace_name;
+ }
+
+ return NULL;
+}
+
+static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
+{
+ const char *colorspace_name = display_transform_get_colorspace_name(view_settings, display_settings);
+
+ if (colorspace_name)
+ return colormanage_colorspace_get_named(colorspace_name);
+
+ return NULL;
+}
+
static ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display,
float exposure, float gamma)
{
@@ -1310,19 +1342,11 @@ static void colormanage_display_buffer_process_ex(ImBuf *ibuf, float *display_bu
view_settings->exposure == 0.0f &&
view_settings->gamma == 1.0f)
{
- ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+ const char *from_colorspace = ibuf->rect_colorspace->name;
+ const char *to_colorspace = display_transform_get_colorspace_name(view_settings, display_settings);
- 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 (to_colorspace && !strcmp(from_colorspace, to_colorspace))
+ skip_transform = TRUE;
}
}
@@ -1612,22 +1636,90 @@ void IMB_colormanagement_imbuf_assign_float_space(ImBuf *ibuf, ColorManagedColor
ibuf->float_colorspace = colormanage_colorspace_get_named(colorspace_settings->name);
}
-void IMB_colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
+static void colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings, int make_byte)
{
- /* OCIO_TODO: byte buffer management is not supported here yet */
- if (!ibuf->rect_float)
- return;
+ if (!ibuf->rect && make_byte)
+ imb_addrectImBuf(ibuf);
if (global_tot_display == 0 || global_tot_view == 0) {
IMB_buffer_float_from_float(ibuf->rect_float, ibuf->rect_float, ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB,
ibuf->flags & IB_cm_predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
}
else {
- colormanage_display_buffer_process_ex(ibuf, ibuf->rect_float, NULL, view_settings, display_settings);
+ colormanage_display_buffer_process_ex(ibuf, ibuf->rect_float, (unsigned char *)ibuf->rect,
+ view_settings, display_settings);
}
}
+void IMB_colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
+{
+ colormanagement_imbuf_make_display_space(ibuf, view_settings, display_settings, FALSE);
+}
+
+/* prepare image buffer to be saved on disk, applying color management if needed
+ * color management would be applied if image is saving as render result and if
+ * file format is not expecting float buffer to be in linear space (currently
+ * JPEG2000 and TIFF are such formats -- they're storing image as float but
+ * file itself stores applied color space).
+ *
+ * Both byte and float buffers would contain applied color space, and result's
+ * float_colorspace would be set to display color space. This should be checked
+ * in image format write callback and if float_colorspace is not NULL, no color
+ * space transformation should be applied on this buffer.
+ */
+ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, int save_as_render, int allocate_result, const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings, ImageFormatData *image_format_data)
+{
+ ImBuf *colormanaged_ibuf = ibuf;
+ int do_colormanagement;
+ int is_movie = BKE_imtype_is_movie(image_format_data->imtype);
+ int requires_linear_float = BKE_imtype_requires_linear_float(image_format_data->imtype);
+
+ do_colormanagement = save_as_render && (is_movie || !requires_linear_float);
+
+ if (do_colormanagement) {
+ int make_byte = FALSE;
+ ImFileType *type;
+
+ if (allocate_result)
+ colormanaged_ibuf = IMB_dupImBuf(ibuf);
+
+ /* if file format isn't able to handle float buffer itself,
+ * we need to allocate byte buffer and store color managed
+ * image there
+ */
+ for (type = IMB_FILE_TYPES; type->is_a; type++) {
+ if (type->save && type->ftype(type, ibuf)) {
+ if ((type->flag & IM_FTYPE_FLOAT) == 0)
+ make_byte = TRUE;
+
+ break;
+ }
+ }
+
+ /* perform color space conversions */
+ colormanagement_imbuf_make_display_space(colormanaged_ibuf, view_settings, display_settings, make_byte);
+
+ if (colormanaged_ibuf->rect_float) {
+ if (make_byte && allocate_result) {
+ /* save a bit of memory */
+ imb_freerectfloatImBuf(colormanaged_ibuf);
+ }
+ else {
+ /* float buffer isn't linear anymore,
+ * image format write callback should check for this flag and assume
+ * no space conversion should happen if ibuf->float_colorspace != NULL
+ */
+ colormanaged_ibuf->float_colorspace = display_transform_get_colorspace(view_settings, display_settings);
+ }
+ }
+ }
+
+ return colormanaged_ibuf;
+}
+
static void imbuf_verify_float(ImBuf *ibuf)
{
/* multiple threads could request for display buffer at once and in case
@@ -1737,22 +1829,6 @@ unsigned char *IMB_display_buffer_acquire_ctx(const bContext *C, ImBuf *ibuf, vo
return IMB_display_buffer_acquire(ibuf, view_settings, display_settings, cache_handle);
}
-/* covert float buffer to display space and store it in image buffer's byte array */
-void IMB_display_buffer_to_imbuf_rect(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
-{
- if (global_tot_display == 0 || global_tot_view == 0) {
- imbuf_verify_float(ibuf);
- }
- else {
- if (!ibuf->rect) {
- imb_addrectImBuf(ibuf);
- }
-
- colormanage_display_buffer_process(ibuf, (unsigned char *) ibuf->rect, view_settings, display_settings);
- }
-}
-
void IMB_display_buffer_transform_apply(unsigned char *display_buffer, float *linear_buffer, int width, int height,
int channels, const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings, int predivide)
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index dd559c55402..01523463712 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -544,6 +544,10 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *ima
parameters->cp_disto_alloc = 1;
}
+static float channel_colormanage_noop(float value)
+{
+ return value;
+}
static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
{
@@ -560,9 +564,20 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */
opj_image_t *image = NULL;
+ float (*chanel_colormanage_cb)(float);
+
img_fol_t img_fol; /* only needed for cinema presets */
memset(&img_fol, 0, sizeof(img_fol_t));
+ if (ibuf->float_colorspace) {
+ /* float buffer was managed already, no need in color space conversion */
+ chanel_colormanage_cb = channel_colormanage_noop;
+ }
+ else {
+ /* standard linear-to-srgb conversion if float buffer wasn't managed */
+ chanel_colormanage_cb = linearrgb_to_srgb;
+ }
+
if (ibuf->ftype & JP2_CINE) {
if (ibuf->x == 4096 || ibuf->y == 2160)
@@ -649,9 +664,9 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
if (numcomps == 4) {
PIXEL_LOOPER_BEGIN(rect_float)
{
- r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[2]));
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]);
}
PIXEL_LOOPER_END;
@@ -659,9 +674,9 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
else {
PIXEL_LOOPER_BEGIN(rect_float)
{
- r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(linearrgb_to_srgb(rect_float[2]));
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
}
PIXEL_LOOPER_END;
}
@@ -671,9 +686,9 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
if (numcomps == 4) {
PIXEL_LOOPER_BEGIN(rect_float)
{
- r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[2]));
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]);
}
PIXEL_LOOPER_END;
@@ -681,9 +696,9 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
else {
PIXEL_LOOPER_BEGIN(rect_float)
{
- r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(linearrgb_to_srgb(rect_float[2]));
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
}
PIXEL_LOOPER_END;
}
@@ -693,9 +708,9 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
if (numcomps == 4) {
PIXEL_LOOPER_BEGIN(rect_float)
{
- r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[2]));
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]);
}
PIXEL_LOOPER_END;
@@ -703,9 +718,9 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
else {
PIXEL_LOOPER_BEGIN(rect_float)
{
- r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(linearrgb_to_srgb(rect_float[2]));
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
}
PIXEL_LOOPER_END;
}
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 2cb30b84a09..e09fdf259c6 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -790,8 +790,14 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
/* convert from float source */
float rgb[4];
- /* TODO - support color management */
- linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]);
+ if (ibuf->float_colorspace) {
+ /* float buffer was managed already, no need in color space conversion */
+ copy_v3_v3(rgb, &fromf[from_i]);
+ }
+ else {
+ /* standard linear-to-srgb conversion if float buffer wasn't managed */
+ linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]);
+ }
rgb[3] = fromf[from_i + 3];
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index c66c0085763..cb7844c50e3 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -81,9 +81,10 @@ static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports
BKE_reportf(reports, RPT_ERROR, "Couldn't acquire buffer from image");
}
else {
- ImBuf *write_ibuf = IMB_dupImBuf(ibuf);
+ ImBuf *write_ibuf;
- IMB_display_buffer_to_imbuf_rect(write_ibuf, &scene->view_settings, &scene->display_settings);
+ write_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, TRUE, TRUE, &scene->view_settings,
+ &scene->display_settings, &scene->r.im_format);
write_ibuf->planes = scene->r.im_format.planes;
write_ibuf->dither = scene->r.dither_intensity;
@@ -91,7 +92,9 @@ static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports
if (!BKE_imbuf_write(write_ibuf, path, &scene->r.im_format)) {
BKE_reportf(reports, RPT_ERROR, "Couldn't write image: %s", path);
}
- IMB_freeImBuf(write_ibuf);
+
+ if (write_ibuf != ibuf)
+ IMB_freeImBuf(write_ibuf);
}
BKE_image_release_ibuf(image, lock);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index d22e8f95e01..b1b88fc9fd5 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -2094,14 +2094,6 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
G.is_rendering = FALSE;
}
-static void colormanage_image_for_write(Scene *scene, ImBuf *ibuf)
-{
- IMB_display_buffer_to_imbuf_rect(ibuf, &scene->view_settings, &scene->display_settings);
-
- if (ibuf)
- imb_freerectfloatImBuf(ibuf);
-}
-
static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const char *name_override)
{
char name[FILE_MAX];
@@ -2123,7 +2115,9 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
do_free = TRUE;
}
- colormanage_image_for_write(scene, ibuf);
+
+ IMB_colormanagement_imbuf_for_write(ibuf, TRUE, FALSE, &scene->view_settings,
+ &scene->display_settings, &scene->r.im_format);
ok = mh->append_movie(&re->r, scene->r.sfra, scene->r.cfra, (int *) ibuf->rect,
ibuf->x, ibuf->y, re->reports);
@@ -2151,12 +2145,9 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
}
else {
ImBuf *ibuf = render_result_rect_to_ibuf(&rres, &scene->r);
- int do_colormanagement;
-
- do_colormanagement = !BKE_imtype_supports_float(scene->r.im_format.imtype);
- if (do_colormanagement)
- colormanage_image_for_write(scene, ibuf);
+ IMB_colormanagement_imbuf_for_write(ibuf, TRUE, FALSE, &scene->view_settings,
+ &scene->display_settings, &scene->r.im_format);
ok = BKE_imbuf_write_stamp(scene, camera, ibuf, name, &scene->r.im_format);
@@ -2175,7 +2166,8 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
BKE_add_image_extension(name, R_IMF_IMTYPE_JPEG90);
ibuf->planes = 24;
- colormanage_image_for_write(scene, ibuf);
+ IMB_colormanagement_imbuf_for_write(ibuf, TRUE, FALSE, &scene->view_settings,
+ &scene->display_settings, &imf);
BKE_imbuf_write_stamp(scene, camera, ibuf, name, &imf);
printf("\nSaved: %s", name);
@@ -2521,7 +2513,7 @@ int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env,
return 0;
}
- IMB_display_buffer_to_imbuf_rect(ibuf, &scene->view_settings, &scene->display_settings);
+ IMB_colormanagement_imbuf_for_write(ibuf, TRUE, FALSE, &scene->view_settings, &scene->display_settings, &imf);
/* to save, we first get absolute path */
BLI_strncpy(filepath, relpath, sizeof(filepath));