diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-09-20 14:07:49 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-09-20 14:07:49 +0400 |
commit | ddcc3f612a33de6cc1ed7ecb2b2fd66290952a31 (patch) | |
tree | c6fef0892fa237abc08627dec80995fa23878e28 /source | |
parent | be2454dc551779aaa7bf5fd39f27b65a9201bcc6 (diff) |
Fix #32603: Multi-Layer EXR files can't be color managed
Issue was caused by completely different way how multi-layer EXRs are loading,
they're bypassing general image buffer loading functions.
Solved by running color space transformation on render result construction
from multi-layer EXR image.
Also fixed issue with wrong display buffer computing for buffers with less
than 4 channels. Issues were:
- Display buffer is always expected to be RGBA
- OpenColorIO can not apply color space transformations on non-{RGB, RGBA}
pixels.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 4 | ||||
-rw-r--r-- | source/blender/imbuf/intern/colormanagement.c | 15 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_pipeline.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_result.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_result.c | 10 |
6 files changed, 23 insertions, 14 deletions
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 7146c48cd2f..b0fdbba2aa9 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2213,8 +2213,10 @@ void BKE_image_backup_render(Scene *scene, Image *ima) /* in that case we have to build a render-result */ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr) { + const char *colorspace = ima->colorspace_settings.name; + int predivide = ima->flag & IMA_CM_PREDIVIDE; - ima->rr = RE_MultilayerConvert(ibuf->userdata, ibuf->x, ibuf->y); + ima->rr = RE_MultilayerConvert(ibuf->userdata, colorspace, predivide, ibuf->x, ibuf->y); #ifdef WITH_OPENEXR IMB_exr_close(ibuf->userdata); diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 310448074fb..4843c9b2b6c 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -68,7 +68,8 @@ /*********************** Global declarations *************************/ -#define MAX_COLORSPACE_NAME 64 +#define MAX_COLORSPACE_NAME 64 +#define DISPLAY_BUFFER_CHANNELS 4 /* ** list of all supported color spaces, displays and views */ static char global_role_scene_linear[MAX_COLORSPACE_NAME]; @@ -329,8 +330,7 @@ static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheV ColormnaageCacheData *cache_data; BLI_assert(cache_ibuf->x == ibuf->x && - cache_ibuf->y == ibuf->y && - cache_ibuf->channels == ibuf->channels); + cache_ibuf->y == ibuf->y); /* only buffers with different color space conversions are being stored * in cache separately. buffer which were used only different exposure/gamma @@ -1089,6 +1089,7 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l int is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA; int offset = channels * start_line * ibuf->x; + int display_buffer_byte_offset = DISPLAY_BUFFER_CHANNELS * start_line * ibuf->x; memset(handle, 0, sizeof(DisplayBufferThread)); @@ -1104,7 +1105,7 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l handle->display_buffer = init_data->display_buffer + offset; if (init_data->display_buffer_byte) - handle->display_buffer_byte = init_data->display_buffer_byte + offset; + handle->display_buffer_byte = init_data->display_buffer_byte + display_buffer_byte_offset; handle->width = ibuf->x; @@ -1655,7 +1656,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet return display_buffer; } - buffer_size = ibuf->channels * ibuf->x * ibuf->y * sizeof(float); + buffer_size = DISPLAY_BUFFER_CHANNELS * ibuf->x * ibuf->y * sizeof(float); display_buffer = MEM_callocN(buffer_size, "imbuf display buffer"); colormanage_display_buffer_process(ibuf, display_buffer, applied_view_settings, display_settings); @@ -1700,7 +1701,7 @@ void IMB_display_buffer_transform_apply(unsigned char *display_buffer, float *li const ColorManagedDisplaySettings *display_settings, int predivide) { if (global_tot_display == 0 || global_tot_view == 0) { - IMB_buffer_byte_from_float(display_buffer, linear_buffer, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, FALSE, + IMB_buffer_byte_from_float(display_buffer, linear_buffer, channels, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, FALSE, width, height, width, width); } else { @@ -2351,7 +2352,7 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo } } - if (cm_processor->processor) { + if (cm_processor->processor && channels >= 3) { PackedImageDesc *img; /* apply OCIO processor */ diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index b43824d6d5e..c7a8bfeec1d 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -225,7 +225,7 @@ void RE_PreviewRender(struct Render *re, struct Main *bmain, struct Scene *scene int RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode); int RE_WriteRenderResult(struct ReportList *reports, RenderResult *rr, const char *filename, int compress); -struct RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty); +struct RenderResult *RE_MultilayerConvert(void *exrhandle, const char *colorspace, int predivide, int rectx, int recty); extern const float default_envmap_layout[]; int RE_WriteEnvmapResult(struct ReportList *reports, struct Scene *scene, struct EnvMap *env, const char *relpath, const char imtype, float layout[12]); diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h index 999fb24ba32..5d61417cbaf 100644 --- a/source/blender/render/intern/include/render_result.h +++ b/source/blender/render/intern/include/render_result.h @@ -57,7 +57,7 @@ struct RenderResult *render_result_new(struct Render *re, struct RenderResult *render_result_new_full_sample(struct Render *re, struct ListBase *lb, struct rcti *partrct, int crop, int savebuffers); -struct RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty); +struct RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace, int predivide, int rectx, int recty); /* Merge */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 4a1674b8bca..d22e8f95e01 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -203,9 +203,9 @@ RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name) } } -RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty) +RenderResult *RE_MultilayerConvert(void *exrhandle, const char *colorspace, int predivide, int rectx, int recty) { - return render_result_new_from_exr(exrhandle, rectx, recty); + return render_result_new_from_exr(exrhandle, colorspace, predivide, rectx, recty); } RenderLayer *render_get_active_layer(Render *re, RenderResult *rr) diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 2d680bf2e81..0bac26e7e3c 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -627,12 +627,13 @@ static void ml_addpass_cb(void *UNUSED(base), void *lay, const char *str, float } /* from imbuf, if a handle was returned we convert this to render result */ -RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty) +RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace, int predivide, int rectx, int recty) { RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__); RenderLayer *rl; RenderPass *rpass; - + const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); + rr->rectx = rectx; rr->recty = recty; @@ -645,6 +646,11 @@ RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty) for (rpass = rl->passes.first; rpass; rpass = rpass->next) { rpass->rectx = rectx; rpass->recty = recty; + + if (rpass->channels >= 3) { + IMB_colormanagement_transform(rpass->rect, rpass->rectx, rpass->recty, rpass->channels, + colorspace, to_colorspace, predivide); + } } } |