Blender  V3.3
COM_OutputFileMultiViewOperation.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2015 Blender Foundation. */
3 
5 
6 #include "BKE_image.h"
7 #include "BKE_image_format.h"
8 #include "BKE_main.h"
9 #include "BKE_scene.h"
10 
11 #include "IMB_colormanagement.h"
12 #include "IMB_imbuf.h"
13 #include "IMB_imbuf_types.h"
14 
15 namespace blender::compositor {
16 
17 /************************************ OpenEXR Singlelayer Multiview ******************************/
18 
20  const Scene *scene,
21  const RenderData *rd,
22  const bNodeTree *tree,
23  DataType datatype,
24  const ImageFormatData *format,
25  const char *path,
26  const char *view_name,
27  const bool save_as_render)
29  scene, rd, tree, datatype, format, path, view_name, save_as_render)
30 {
31 }
32 
34 {
35  size_t width = this->get_width();
36  size_t height = this->get_height();
37  SceneRenderView *srv;
38 
39  if (width != 0 && height != 0) {
40  void *exrhandle;
41 
42  exrhandle = IMB_exr_get_handle_name(filename);
43 
45  return exrhandle;
46  }
47 
48  IMB_exr_clear_channels(exrhandle);
49 
50  for (srv = (SceneRenderView *)rd_->views.first; srv; srv = srv->next) {
52  continue;
53  }
54 
55  IMB_exr_add_view(exrhandle, srv->name);
56  add_exr_channels(exrhandle, nullptr, datatype_, srv->name, width, false, nullptr);
57  }
58 
59  BLI_make_existing_file(filename);
60 
61  /* prepare the file with all the channels */
62 
63  if (!IMB_exr_begin_write(exrhandle, filename, width, height, format_.exr_codec, nullptr)) {
64  printf("Error Writing Singlelayer Multiview Openexr\n");
65  IMB_exr_close(exrhandle);
66  }
67  else {
68  IMB_exr_clear_channels(exrhandle);
69  return exrhandle;
70  }
71  }
72  return nullptr;
73 }
74 
76 {
77  unsigned int width = this->get_width();
78  unsigned int height = this->get_height();
79 
80  if (width != 0 && height != 0) {
81  void *exrhandle;
82  char filename[FILE_MAX];
83 
85  path_,
87  rd_->cfra,
89  (rd_->scemode & R_EXTENSION) != 0,
90  true,
91  nullptr);
92 
93  exrhandle = this->get_handle(filename);
94  add_exr_channels(exrhandle,
95  nullptr,
96  datatype_,
97  view_name_,
98  width,
101 
102  /* memory can only be freed after we write all views to the file */
103  output_buffer_ = nullptr;
104  image_input_ = nullptr;
105 
106  /* ready to close the file */
108  IMB_exr_write_channels(exrhandle);
109 
110  /* free buffer memory for all the views */
111  free_exr_channels(exrhandle, rd_, nullptr, datatype_);
112 
113  /* remove exr handle and data */
114  IMB_exr_close(exrhandle);
115  }
116  }
117 }
118 
119 /************************************ OpenEXR Multilayer Multiview *******************************/
120 
122  const Scene *scene,
123  const RenderData *rd,
124  const bNodeTree *tree,
125  const char *path,
126  char exr_codec,
127  bool exr_half_float,
128  const char *view_name)
129  : OutputOpenExrMultiLayerOperation(scene, rd, tree, path, exr_codec, exr_half_float, view_name)
130 {
131 }
132 
134 {
135  unsigned int width = this->get_width();
136  unsigned int height = this->get_height();
137 
138  if (width != 0 && height != 0) {
139 
140  void *exrhandle;
141  SceneRenderView *srv;
142 
143  /* get a new global handle */
144  exrhandle = IMB_exr_get_handle_name(filename);
145 
147  return exrhandle;
148  }
149 
150  IMB_exr_clear_channels(exrhandle);
151 
152  /* check renderdata for amount of views */
153  for (srv = (SceneRenderView *)rd_->views.first; srv; srv = srv->next) {
154 
155  if (BKE_scene_multiview_is_render_view_active(rd_, srv) == false) {
156  continue;
157  }
158 
159  IMB_exr_add_view(exrhandle, srv->name);
160 
161  for (unsigned int i = 0; i < layers_.size(); i++) {
162  add_exr_channels(exrhandle,
163  layers_[i].name,
164  layers_[i].datatype,
165  srv->name,
166  width,
168  nullptr);
169  }
170  }
171 
172  BLI_make_existing_file(filename);
173 
174  /* prepare the file with all the channels for the header */
175  StampData *stamp_data = create_stamp_data();
176  if (!IMB_exr_begin_write(exrhandle, filename, width, height, exr_codec_, stamp_data)) {
177  printf("Error Writing Multilayer Multiview Openexr\n");
178  IMB_exr_close(exrhandle);
179  BKE_stamp_data_free(stamp_data);
180  }
181  else {
182  IMB_exr_clear_channels(exrhandle);
183  BKE_stamp_data_free(stamp_data);
184  return exrhandle;
185  }
186  }
187  return nullptr;
188 }
189 
191 {
192  unsigned int width = this->get_width();
193  unsigned int height = this->get_height();
194 
195  if (width != 0 && height != 0) {
196  void *exrhandle;
197  char filename[FILE_MAX];
198 
200  path_,
202  rd_->cfra,
204  (rd_->scemode & R_EXTENSION) != 0,
205  true,
206  nullptr);
207 
208  exrhandle = this->get_handle(filename);
209 
210  for (unsigned int i = 0; i < layers_.size(); i++) {
211  add_exr_channels(exrhandle,
212  layers_[i].name,
213  layers_[i].datatype,
214  view_name_,
215  width,
217  layers_[i].output_buffer);
218  }
219 
220  for (unsigned int i = 0; i < layers_.size(); i++) {
221  /* memory can only be freed after we write all views to the file */
222  layers_[i].output_buffer = nullptr;
223  layers_[i].image_input = nullptr;
224  }
225 
226  /* ready to close the file */
228  IMB_exr_write_channels(exrhandle);
229 
230  /* free buffer memory for all the views */
231  for (unsigned int i = 0; i < layers_.size(); i++) {
232  free_exr_channels(exrhandle, rd_, layers_[i].name, layers_[i].datatype);
233  }
234 
235  IMB_exr_close(exrhandle);
236  }
237  }
238 }
239 
240 /******************************** Stereo3D ******************************/
241 
243  const RenderData *rd,
244  const bNodeTree *tree,
245  DataType datatype,
246  const ImageFormatData *format,
247  const char *path,
248  const char *name,
249  const char *view_name,
250  const bool save_as_render)
252  scene, rd, tree, datatype, format, path, view_name, save_as_render)
253 {
254  BLI_strncpy(name_, name, sizeof(name_));
255  channels_ = get_datatype_size(datatype);
256 }
257 
258 void *OutputStereoOperation::get_handle(const char *filename)
259 {
260  size_t width = this->get_width();
261  size_t height = this->get_height();
262  const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
263  size_t i;
264 
265  if (width != 0 && height != 0) {
266  void *exrhandle;
267 
268  exrhandle = IMB_exr_get_handle_name(filename);
269 
271  return exrhandle;
272  }
273 
274  IMB_exr_clear_channels(exrhandle);
275 
276  for (i = 0; i < 2; i++) {
277  IMB_exr_add_view(exrhandle, names[i]);
278  }
279 
280  return exrhandle;
281  }
282  return nullptr;
283 }
284 
286 {
287  unsigned int width = this->get_width();
288  unsigned int height = this->get_height();
289 
290  if (width != 0 && height != 0) {
291  void *exrhandle;
292 
293  exrhandle = this->get_handle(path_);
294  float *buf = output_buffer_;
295 
296  /* populate single EXR channel with view data */
297  IMB_exr_add_channel(exrhandle,
298  nullptr,
299  name_,
300  view_name_,
301  1,
302  channels_ * width * height,
303  buf,
305 
306  image_input_ = nullptr;
307  output_buffer_ = nullptr;
308 
309  /* create stereo ibuf */
311  ImBuf *ibuf[3] = {nullptr};
312  const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
313  char filename[FILE_MAX];
314  int i;
315 
316  /* get rectf from EXR */
317  for (i = 0; i < 2; i++) {
318  float *rectf = IMB_exr_channel_rect(exrhandle, nullptr, name_, names[i]);
319  ibuf[i] = IMB_allocImBuf(width, height, format_.planes, 0);
320 
321  ibuf[i]->channels = channels_;
322  ibuf[i]->rect_float = rectf;
323  ibuf[i]->mall |= IB_rectfloat;
324  ibuf[i]->dither = rd_->dither_intensity;
325 
326  /* do colormanagement in the individual views, so it doesn't need to do in the stereo */
327  IMB_colormanagement_imbuf_for_write(ibuf[i], true, false, &format_);
328  }
329 
330  /* create stereo buffer */
331  ibuf[2] = IMB_stereo3d_ImBuf(&format_, ibuf[0], ibuf[1]);
332 
334  path_,
336  rd_->cfra,
337  &format_,
338  (rd_->scemode & R_EXTENSION) != 0,
339  true,
340  nullptr);
341 
342  BKE_imbuf_write(ibuf[2], filename, &format_);
343 
344  /* imbuf knows which rects are not part of ibuf */
345  for (i = 0; i < 3; i++) {
346  IMB_freeImBuf(ibuf[i]);
347  }
348 
349  IMB_exr_close(exrhandle);
350  }
351  }
352 }
353 
354 } // namespace blender::compositor
void BKE_stamp_data_free(struct StampData *stamp_data)
int BKE_imbuf_write(struct ImBuf *ibuf, const char *name, const struct ImageFormatData *imf)
void BKE_image_path_from_imformat(char *string, const char *base, const char *relbase, int frame, const struct ImageFormatData *im_format, bool use_ext, bool use_frames, const char *suffix)
void BKE_image_path_from_imtype(char *string, const char *base, const char *relbase, int frame, char imtype, bool use_ext, bool use_frames, const char *suffix)
const char * BKE_main_blendfile_path_from_global(void)
Definition: main.c:562
bool BKE_scene_multiview_is_render_view_active(const struct RenderData *rd, const struct SceneRenderView *srv)
bool BKE_scene_multiview_is_render_view_last(const struct RenderData *rd, const char *viewname)
bool BKE_scene_multiview_is_render_view_first(const struct RenderData *rd, const char *viewname)
bool BLI_make_existing_file(const char *name)
Definition: path_util.c:1197
#define FILE_MAX
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
#define STEREO_LEFT_NAME
#define R_EXTENSION
#define R_IMF_IMTYPE_MULTILAYER
@ R_IMF_CHAN_DEPTH_16
#define STEREO_RIGHT_NAME
#define R_IMF_IMTYPE_OPENEXR
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
struct ImBuf * IMB_colormanagement_imbuf_for_write(struct ImBuf *ibuf, bool save_as_render, bool allocate_result, const struct ImageFormatData *image_format)
struct ImBuf * IMB_stereo3d_ImBuf(const struct ImageFormatData *im_format, struct ImBuf *ibuf_left, struct ImBuf *ibuf_right)
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:500
Contains defines and structs used throughout the imbuf module.
@ IB_rectfloat
bool IMB_exr_begin_write(void *handle, const char *filepath, int width, int height, int compress, const struct StampData *stamp)
void IMB_exr_add_channel(void *handle, const char *layname, const char *passname, const char *view, int xstride, int ystride, float *rect, bool use_half_float)
void IMB_exr_add_view(void *handle, const char *name)
void IMB_exr_close(void *handle)
void IMB_exr_clear_channels(void *handle)
void * IMB_exr_get_handle_name(const char *name)
void IMB_exr_write_channels(void *handle)
float * IMB_exr_channel_rect(void *handle, const char *layname, const char *passname, const char *view)
OutputOpenExrMultiLayerMultiViewOperation(const Scene *scene, const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec, bool exr_half_float, const char *view_name)
OutputOpenExrSingleLayerMultiViewOperation(const Scene *scene, const RenderData *rd, const bNodeTree *tree, DataType datatype, const ImageFormatData *format, const char *path, const char *view_name, bool save_as_render)
OutputStereoOperation(const Scene *scene, const RenderData *rd, const bNodeTree *tree, DataType datatype, const struct ImageFormatData *format, const char *path, const char *name, const char *view_name, bool save_as_render)
Scene scene
void * tree
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
DataType
possible data types for sockets
Definition: COM_defines.h:30
format
Definition: logImageCore.h:38
static char ** names
Definition: makesdna.c:65
void add_exr_channels(void *exrhandle, const char *layer_name, const DataType datatype, const char *view_name, const size_t width, bool use_half_float, float *buf)
int get_datatype_size(DataType datatype)
void free_exr_channels(void *exrhandle, const RenderData *rd, const char *layer_name, const DataType datatype)
int channels
float dither
float * rect_float
void * first
Definition: DNA_listBase.h:31
float dither_intensity
ListBase views
struct SceneRenderView * next