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
path: root/source
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2012-09-24 15:56:07 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2012-09-24 15:56:07 +0400
commit9e3e12fa4e2b9038314e3f2f690a908042b835fa (patch)
tree4f5178f7e7ff7b8ff6a6ebd74459621f146adaf2 /source
parent5a5b37a4fadee5ce2c44b097a50986e0b70ca898 (diff)
Proper fix for #32626: TIFF renders are limited to 8 bit even when we choose 16.
Color management would be applied on both of float and byte buffers on image save in cases if file format doesn't require linear float buffer and if image is saving as render result. This solves both initial report issue and TODO marked in previous fix. Also de-duplicated image buffer color managing code and gave some more meaningful names for few functions. Also wrote documentation around this function, so current assumptions about spaces should be clear enough. Made regression tests by saving EXR/PNG images to all supported format and rendering OpenGL/Normal animation, in all cases seems everything is fine, but more tests for sure would be welcome.
Diffstat (limited to 'source')
-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));