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>2019-02-05 18:23:53 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2019-02-05 18:26:16 +0300
commitcfc0790a459a710fcb4328b399d9d1f2dd3aab0d (patch)
tree2d98589a599249591565cf9bc5e8c458a87879ee /source
parent7a2a08e0cd967554c7ec6fee36805921e2e28228 (diff)
Movieclip: Improve support of multilayer EXR files
Use first combined pass if possible. Is not ideal but better than showing completely empty image. Also, covers quite a lot of usecases when movie clip editor is used to review animation render of single-layer renders but with multiple passes.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/movieclip.c79
1 files changed, 77 insertions, 2 deletions
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index fa3f3759e50..5d2616b7720 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -197,6 +197,82 @@ static void get_proxy_fname(const MovieClip *clip,
strcat(name, ".jpg");
}
+typedef struct MultilayerConvertContext {
+ float *combined_pass;
+ int num_combined_channels;
+} MultilayerConvertContext;
+
+static void *movieclip_convert_multilayer_add_view(
+ void *UNUSED(ctx_v),
+ const char *UNUSED(view_name))
+{
+ return NULL;
+}
+
+static void *movieclip_convert_multilayer_add_layer(
+ void *ctx_v,
+ const char *UNUSED(layer_name))
+{
+ /* Return dummy non-NULL value, we don't use layer handle but need to return
+ * something, so render API invokes the add_pass() callbacks. */
+ return ctx_v;
+}
+
+static void movieclip_convert_multilayer_add_pass(
+ void *UNUSED(layer),
+ void *ctx_v,
+ const char *pass_name,
+ float *rect,
+ int num_channels,
+ const char *chan_id,
+ const char *UNUSED(view_name))
+{
+ /* NOTE: This function must free pass pixels data if it is not used, this
+ * is how IMB_exr_multilayer_convert() is working. */
+ MultilayerConvertContext *ctx = ctx_v;
+ /* If we've found a first combined pass, skip all the rest ones. */
+ if (ctx->combined_pass != NULL) {
+ MEM_freeN(rect);
+ return;
+ }
+ if (STREQ(pass_name, RE_PASSNAME_COMBINED) ||
+ STREQ(chan_id, "RGBA") ||
+ STREQ(chan_id, "RGB"))
+ {
+ ctx->combined_pass = rect;
+ ctx->num_combined_channels = num_channels;
+ }
+ else {
+ MEM_freeN(rect);
+ }
+}
+
+/* Will try to make image buffer usable when originating from the multi-layer
+ * source.
+ * Internally finds a first combined pass and uses that as a buffer. Not ideal,
+ * but is better than a complete empty buffer. */
+static void movieclip_convert_multilayer(ImBuf *ibuf)
+{
+ MultilayerConvertContext ctx;
+ ctx.combined_pass = NULL;
+ ctx.num_combined_channels = 0;
+ IMB_exr_multilayer_convert(
+ ibuf->userdata,
+ &ctx,
+ movieclip_convert_multilayer_add_view,
+ movieclip_convert_multilayer_add_layer,
+ movieclip_convert_multilayer_add_pass);
+ if (ctx.combined_pass != NULL) {
+ BLI_assert(ibuf->rect_float == NULL);
+ ibuf->rect_float = ctx.combined_pass;
+ ibuf->channels = ctx.num_combined_channels;
+ ibuf->flags |= IB_rectfloat;
+ ibuf->mall |= IB_rectfloat;
+ }
+ IMB_exr_close(ibuf->userdata);
+ ibuf->userdata = NULL;
+}
+
static ImBuf *movieclip_load_sequence_file(MovieClip *clip,
const MovieClipUser *user,
int framenr,
@@ -238,8 +314,7 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip,
#ifdef WITH_OPENEXR
if (ibuf) {
if (ibuf->ftype == IMB_FTYPE_OPENEXR && ibuf->userdata) {
- IMB_exr_close(ibuf->userdata);
- ibuf->userdata = NULL;
+ movieclip_convert_multilayer(ibuf);
}
}
#endif