[Bf-blender-cvs] [8530e48f869] master: Cleanup: move render image and multilayer EXR write code to image_save.cc

Brecht Van Lommel noreply at git.blender.org
Mon Mar 21 16:43:40 CET 2022


Commit: 8530e48f8692f4b92c43489029f2d2ef67c7cb62
Author: Brecht Van Lommel
Date:   Fri Mar 18 21:28:04 2022 +0100
Branches: master
https://developer.blender.org/rB8530e48f8692f4b92c43489029f2d2ef67c7cb62

Cleanup: move render image and multilayer EXR write code to image_save.cc

These share a lot of logic with regular image saving and should be unified
more in the future.

===================================================================

M	source/blender/blenkernel/BKE_image.h
M	source/blender/blenkernel/BKE_image_save.h
M	source/blender/blenkernel/BKE_scene.h
M	source/blender/blenkernel/intern/image.cc
M	source/blender/blenkernel/intern/image_save.cc
M	source/blender/blenkernel/intern/scene.c
M	source/blender/editors/render/render_opengl.cc
M	source/blender/imbuf/IMB_colormanagement.h
M	source/blender/imbuf/IMB_imbuf.h
M	source/blender/imbuf/intern/colormanagement.c
M	source/blender/imbuf/intern/stereoimbuf.c
M	source/blender/render/RE_pipeline.h
M	source/blender/render/intern/pipeline.c
M	source/blender/render/intern/render_result.c
M	source/blender/render/intern/render_result.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 7b3124cca26..fba2512fa49 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -64,7 +64,7 @@ struct StampData *BKE_stamp_info_from_scene_static(const struct Scene *scene);
  * Check whether the given metadata field name translates to a known field of a stamp.
  */
 bool BKE_stamp_is_known_field(const char *field_name);
-void BKE_imbuf_stamp_info(struct RenderResult *rr, struct ImBuf *ibuf);
+void BKE_imbuf_stamp_info(const struct RenderResult *rr, struct ImBuf *ibuf);
 void BKE_stamp_info_from_imbuf(struct RenderResult *rr, struct ImBuf *ibuf);
 void BKE_stamp_info_callback(void *data,
                              struct StampData *stamp_data,
@@ -82,8 +82,8 @@ void BKE_image_stamp_buf(struct Scene *scene,
                          int height,
                          int channels);
 bool BKE_imbuf_alpha_test(struct ImBuf *ibuf);
-int BKE_imbuf_write_stamp(struct Scene *scene,
-                          struct RenderResult *rr,
+int BKE_imbuf_write_stamp(const struct Scene *scene,
+                          const struct RenderResult *rr,
                           struct ImBuf *ibuf,
                           const char *name,
                           const struct ImageFormatData *imf);
diff --git a/source/blender/blenkernel/BKE_image_save.h b/source/blender/blenkernel/BKE_image_save.h
index dea1c25cd5e..f9d07387463 100644
--- a/source/blender/blenkernel/BKE_image_save.h
+++ b/source/blender/blenkernel/BKE_image_save.h
@@ -16,6 +16,9 @@ struct Image;
 struct Main;
 struct ReportList;
 struct Scene;
+struct RenderResult;
+
+/* Image datablock saving. */
 
 typedef struct ImageSaveOptions {
   /* Context within which image is saved. */
@@ -44,6 +47,23 @@ bool BKE_image_save(struct ReportList *reports,
                     struct ImageUser *iuser,
                     struct ImageSaveOptions *opts);
 
+/* Lower level image writing. */
+
+/* Save single or multilayer OpenEXR files from the render result.
+ * Optionally saves only a specific view or layer. */
+bool BKE_image_render_write_exr(struct ReportList *reports,
+                                const struct RenderResult *rr,
+                                const char *filename,
+                                const struct ImageFormatData *imf,
+                                const char *view,
+                                int layer);
+
+bool BKE_image_render_write(struct ReportList *reports,
+                            struct RenderResult *rr,
+                            const struct Scene *scene,
+                            const bool stamp,
+                            const char *name);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index d06b1d43b96..8c50a89ec90 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -282,7 +282,7 @@ struct SceneRenderView *BKE_scene_multiview_render_view_findindex(const struct R
                                                                   int view_id);
 const char *BKE_scene_multiview_render_view_name_get(const struct RenderData *rd, int view_id);
 int BKE_scene_multiview_view_id_get(const struct RenderData *rd, const char *viewname);
-void BKE_scene_multiview_filepath_get(struct SceneRenderView *srv,
+void BKE_scene_multiview_filepath_get(const struct SceneRenderView *srv,
                                       const char *filepath,
                                       char *r_filepath);
 /**
diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc
index 51ffd3338c4..f8fb2ec7e45 100644
--- a/source/blender/blenkernel/intern/image.cc
+++ b/source/blender/blenkernel/intern/image.cc
@@ -2343,9 +2343,9 @@ static void metadata_get_field(void *data, const char *propname, char *propvalue
   IMB_metadata_get_field(imbuf->metadata, propname, propvalue, len);
 }
 
-void BKE_imbuf_stamp_info(RenderResult *rr, struct ImBuf *ibuf)
+void BKE_imbuf_stamp_info(const RenderResult *rr, ImBuf *ibuf)
 {
-  struct StampData *stamp_data = rr->stamp_data;
+  StampData *stamp_data = const_cast<StampData *>(rr->stamp_data);
   IMB_metadata_ensure(&ibuf->metadata);
   BKE_stamp_info_callback(ibuf, stamp_data, metadata_set_field, false);
 }
@@ -2359,12 +2359,12 @@ static void metadata_copy_custom_fields(const char *field, const char *value, vo
   BKE_render_result_stamp_data(rr, field, value);
 }
 
-void BKE_stamp_info_from_imbuf(RenderResult *rr, struct ImBuf *ibuf)
+void BKE_stamp_info_from_imbuf(RenderResult *rr, ImBuf *ibuf)
 {
   if (rr->stamp_data == nullptr) {
     rr->stamp_data = MEM_cnew<StampData>("RenderResult.stamp_data");
   }
-  struct StampData *stamp_data = rr->stamp_data;
+  StampData *stamp_data = rr->stamp_data;
   IMB_metadata_ensure(&ibuf->metadata);
   BKE_stamp_info_callback(ibuf, stamp_data, metadata_get_field, true);
   /* Copy render engine specific settings. */
@@ -2428,8 +2428,8 @@ int BKE_imbuf_write_as(ImBuf *ibuf, const char *name, ImageFormatData *imf, cons
   return ok;
 }
 
-int BKE_imbuf_write_stamp(Scene *scene,
-                          struct RenderResult *rr,
+int BKE_imbuf_write_stamp(const Scene *scene,
+                          const struct RenderResult *rr,
                           ImBuf *ibuf,
                           const char *name,
                           const struct ImageFormatData *imf)
diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc
index 180008e0f64..fdeb5eedcde 100644
--- a/source/blender/blenkernel/intern/image_save.cc
+++ b/source/blender/blenkernel/intern/image_save.cc
@@ -20,6 +20,8 @@
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
 
+#include "intern/openexr/openexr_multi.h"
+
 #include "BKE_colortools.h"
 #include "BKE_image.h"
 #include "BKE_image_format.h"
@@ -219,14 +221,14 @@ static bool image_save_single(ReportList *reports,
   /* fancy multiview OpenEXR */
   if (imf->views_format == R_IMF_VIEWS_MULTIVIEW && is_exr_rr) {
     /* save render result */
-    ok = RE_WriteRenderResult(reports, rr, opts->filepath, imf, nullptr, layer);
+    ok = BKE_image_render_write_exr(reports, rr, opts->filepath, imf, NULL, layer);
     image_save_post(reports, ima, ibuf, ok, opts, true, opts->filepath, r_colorspace_changed);
     BKE_image_release_ibuf(ima, ibuf, lock);
   }
   /* regular mono pipeline */
   else if (is_mono) {
     if (is_exr_rr) {
-      ok = RE_WriteRenderResult(reports, rr, opts->filepath, imf, nullptr, layer);
+      ok = BKE_image_render_write_exr(reports, rr, opts->filepath, imf, NULL, layer);
     }
     else {
       colormanaged_ibuf = IMB_colormanagement_imbuf_for_write(
@@ -261,7 +263,7 @@ static bool image_save_single(ReportList *reports,
 
       if (is_exr_rr) {
         BKE_scene_multiview_view_filepath_get(&opts->scene->r, opts->filepath, view, filepath);
-        ok_view = RE_WriteRenderResult(reports, rr, filepath, imf, view, layer);
+        ok_view = BKE_image_render_write_exr(reports, rr, filepath, imf, view, layer);
         image_save_post(reports, ima, ibuf, ok_view, opts, true, filepath, r_colorspace_changed);
       }
       else {
@@ -308,7 +310,7 @@ static bool image_save_single(ReportList *reports,
   /* stereo (multiview) images */
   else if (opts->im_format.views_format == R_IMF_VIEWS_STEREO_3D) {
     if (imf->imtype == R_IMF_IMTYPE_MULTILAYER) {
-      ok = RE_WriteRenderResult(reports, rr, opts->filepath, imf, nullptr, layer);
+      ok = BKE_image_render_write_exr(reports, rr, opts->filepath, imf, NULL, layer);
       image_save_post(reports, ima, ibuf, ok, opts, true, opts->filepath, r_colorspace_changed);
       BKE_image_release_ibuf(ima, ibuf, lock);
     }
@@ -449,3 +451,329 @@ bool BKE_image_save(
 
   return ok;
 }
+
+/* OpenEXR saving, single and multilayer. */
+
+bool BKE_image_render_write_exr(ReportList *reports,
+                                const RenderResult *rr,
+                                const char *filename,
+                                const ImageFormatData *imf,
+                                const char *view,
+                                int layer)
+{
+  void *exrhandle = IMB_exr_get_handle();
+  const bool half_float = (imf && imf->depth == R_IMF_CHAN_DEPTH_16);
+  const bool multi_layer = !(imf && imf->imtype == R_IMF_IMTYPE_OPENEXR);
+  const bool write_z = !multi_layer && (imf && (imf->flag & R_IMF_FLAG_ZBUF));
+
+  /* Write first layer if not multilayer and no layer was specified. */
+  if (!multi_layer && layer == -1) {
+    layer = 0;
+  }
+
+  /* First add views since IMB_exr_add_channel checks number of views. */
+  const RenderView *first_rview = (const RenderView *)rr->views.first;
+  if (first_rview && (first_rview->next || first_rview->name[0])) {
+    LISTBASE_FOREACH (RenderView *, rview, &rr->views) {
+      if (!view || STREQ(view, rview->name)) {
+        IMB_exr_add_view(exrhandle, rview->name);
+      }
+    }
+  }
+
+  /* Compositing result. */
+  if (rr->have_combined) {
+    LISTBASE_FOREACH (RenderView *, rview, &rr->views) {
+      if (!rview->rectf) {
+        continue;
+      }
+
+      const char *viewname = rview->name;
+      if (view) {
+        if (!STREQ(view, viewname)) {
+          continue;
+        }
+
+        viewname = "";
+      }
+
+      /* Skip compositing if only a single other layer is requested. */
+      if (!multi_layer && layer != 0) {
+        continue;
+      }
+
+      float *output_rect = rview->rectf;
+
+      for (int a = 0; a < 4; a++) {
+        char passname[EXR_PASS_MAXNAME];
+        char layname[EXR_PASS_MAXNAME];
+        const char *chan_id = "RGBA";
+
+        if (multi_layer) {
+          IMB_exr_channel_name(passname, NULL, "Combined", NULL, chan_id, a);
+          BLI_strncpy(layname, "Composite", sizeof(layname));
+        }
+        else {
+          passname[0] = chan_id[a];
+          passname[1] = '\0';
+          layname[0] = '\0';
+        }
+
+        IMB_exr_add_channel(
+            exrhandle, layname, passname, viewname, 4, 4 * rr->rectx, output_rect + a, half_float);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list