diff options
-rw-r--r-- | source/blender/blenkernel/BKE_image.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 3 | ||||
-rw-r--r-- | source/blender/compositor/operations/COM_OutputFileOperation.cpp | 5 | ||||
-rw-r--r-- | source/blender/editors/render/render_opengl.c | 8 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_buttons.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_ops.c | 43 | ||||
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_draw.c | 10 | ||||
-rw-r--r-- | source/blender/imbuf/IMB_colormanagement.h | 9 | ||||
-rw-r--r-- | source/blender/imbuf/intern/colormanagement.c | 144 | ||||
-rw-r--r-- | source/blender/imbuf/intern/jp2.c | 51 | ||||
-rw-r--r-- | source/blender/imbuf/intern/tiff.c | 10 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_image_api.c | 9 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 24 |
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)); |