diff --git a/source/blender/blenkernel/BKE_image_format.hh b/source/blender/blenkernel/BKE_image_format.hh index a9c7df7798d..1e63d95806c 100644 --- a/source/blender/blenkernel/BKE_image_format.hh +++ b/source/blender/blenkernel/BKE_image_format.hh @@ -32,6 +32,8 @@ void BKE_image_format_update_color_space_for_type(ImageFormatData *format); void BKE_image_format_blend_read_data(BlendDataReader *reader, ImageFormatData *imf); void BKE_image_format_blend_write(BlendWriter *writer, ImageFormatData *imf); +void BKE_image_format_set(ImageFormatData *imf, ID *owner_id, const char imtype); + /* File Paths */ void BKE_image_path_from_imformat(char *filepath, @@ -88,6 +90,7 @@ bool BKE_imtype_requires_linear_float(char imtype); char BKE_imtype_valid_channels(char imtype, bool write_file); char BKE_imtype_valid_depths(char imtype); char BKE_imtype_valid_depths_with_video(char imtype, const ID *owner_id); +char BKE_imtype_first_valid_depth(const char valid_depths); /** * String is from command line `--render-format` argument, diff --git a/source/blender/blenkernel/intern/image_format.cc b/source/blender/blenkernel/intern/image_format.cc index ec99f921702..82745eff2ce 100644 --- a/source/blender/blenkernel/intern/image_format.cc +++ b/source/blender/blenkernel/intern/image_format.cc @@ -87,6 +87,40 @@ void BKE_image_format_blend_write(BlendWriter *writer, ImageFormatData *imf) BKE_color_managed_view_settings_blend_write(writer, &imf->view_settings); } +void BKE_image_format_set(ImageFormatData *imf, ID *owner_id, const char imtype) +{ + imf->imtype = imtype; + + const bool is_render = (owner_id && GS(owner_id->name) == ID_SCE); + /* see note below on why this is */ + const char chan_flag = BKE_imtype_valid_channels(imf->imtype, true) | + (is_render ? IMA_CHAN_FLAG_BW : 0); + + /* ensure depth and color settings match */ + if ((imf->planes == R_IMF_PLANES_BW) && !(chan_flag & IMA_CHAN_FLAG_BW)) { + imf->planes = R_IMF_PLANES_RGBA; + } + if ((imf->planes == R_IMF_PLANES_RGBA) && !(chan_flag & IMA_CHAN_FLAG_RGBA)) { + imf->planes = R_IMF_PLANES_RGB; + } + + /* ensure usable depth */ + { + const int depth_ok = BKE_imtype_valid_depths(imf->imtype); + if ((imf->depth & depth_ok) == 0) { + imf->depth = BKE_imtype_first_valid_depth(depth_ok); + } + } + + if (owner_id && GS(owner_id->name) == ID_SCE) { + Scene *scene = reinterpret_cast(owner_id); + RenderData *rd = &scene->r; + MOV_validate_output_settings(rd, imf); + } + + BKE_image_format_update_color_space_for_type(imf); +} + /* File Types */ int BKE_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options) @@ -338,6 +372,27 @@ char BKE_imtype_valid_depths_with_video(char imtype, const ID *owner_id) return depths; } +char BKE_imtype_first_valid_depth(const char valid_depths) +{ + /* set first available depth */ + const char depth_ls[] = { + R_IMF_CHAN_DEPTH_32, + R_IMF_CHAN_DEPTH_24, + R_IMF_CHAN_DEPTH_16, + R_IMF_CHAN_DEPTH_12, + R_IMF_CHAN_DEPTH_10, + R_IMF_CHAN_DEPTH_8, + R_IMF_CHAN_DEPTH_1, + 0, + }; + for (int i = 0; depth_ls[i]; i++) { + if (valid_depths & depth_ls[i]) { + return depth_ls[i]; + } + } + return R_IMF_CHAN_DEPTH_8; +} + char BKE_imtype_from_arg(const char *imtype_arg) { if (STREQ(imtype_arg, "TGA")) { diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc index 0cbfece36ef..0fcfb833ffc 100644 --- a/source/blender/blenkernel/intern/image_save.cc +++ b/source/blender/blenkernel/intern/image_save.cc @@ -579,9 +579,11 @@ static bool image_save_single(ReportList *reports, ibuf = IMB_stereo3d_ImBuf(imf, ibuf_stereo[0], ibuf_stereo[1]); /* save via traditional path */ - ok = BKE_imbuf_write_as(ibuf, opts->filepath, imf, save_copy); + if (ibuf) { + ok = BKE_imbuf_write_as(ibuf, opts->filepath, imf, save_copy); - IMB_freeImBuf(ibuf); + IMB_freeImBuf(ibuf); + } } for (int i = 0; i < 2; i++) { @@ -1169,28 +1171,36 @@ bool BKE_image_render_write(ReportList *reports, ibuf_arr[2] = IMB_stereo3d_ImBuf(&image_format, ibuf_arr[0], ibuf_arr[1]); - ok = image_render_write_stamp_test( - reports, scene, rr, ibuf_arr[2], filepath, &image_format, stamp); - - /* optional preview images for exr */ - if (ok && is_exr_rr && (image_format.flag & R_IMF_FLAG_PREVIEW_JPG)) { - image_format.imtype = R_IMF_IMTYPE_JPEG90; - image_format.depth = R_IMF_CHAN_DEPTH_8; - - if (BLI_path_extension_check(filepath, ".exr")) { - filepath[strlen(filepath) - 4] = 0; - } - - BKE_image_path_ext_from_imformat_ensure(filepath, sizeof(filepath), &image_format); - ibuf_arr[2]->planes = 24; - + if (ibuf_arr[2]) { ok = image_render_write_stamp_test( reports, scene, rr, ibuf_arr[2], filepath, &image_format, stamp); + + /* optional preview images for exr */ + if (ok && is_exr_rr && (image_format.flag & R_IMF_FLAG_PREVIEW_JPG)) { + image_format.imtype = R_IMF_IMTYPE_JPEG90; + image_format.depth = R_IMF_CHAN_DEPTH_8; + + if (BLI_path_extension_check(filepath, ".exr")) { + filepath[strlen(filepath) - 4] = 0; + } + + BKE_image_path_ext_from_imformat_ensure(filepath, sizeof(filepath), &image_format); + ibuf_arr[2]->planes = 24; + + ok = image_render_write_stamp_test( + reports, scene, rr, ibuf_arr[2], filepath, &image_format, stamp); + } + } + else { + BKE_reportf(reports, RPT_ERROR, "Failed to create stereo image buffer"); + ok = false; } /* imbuf knows which rects are not part of ibuf */ for (i = 0; i < 3; i++) { - IMB_freeImBuf(ibuf_arr[i]); + if (ibuf_arr[i]) { + IMB_freeImBuf(ibuf_arr[i]); + } } } } diff --git a/source/blender/imbuf/IMB_imbuf.hh b/source/blender/imbuf/IMB_imbuf.hh index 76c90e02056..78a30c5ca4c 100644 --- a/source/blender/imbuf/IMB_imbuf.hh +++ b/source/blender/imbuf/IMB_imbuf.hh @@ -676,18 +676,6 @@ void IMB_stereo3d_write_dimensions( char mode, bool is_squeezed, size_t width, size_t height, size_t *r_width, size_t *r_height); void IMB_stereo3d_read_dimensions( char mode, bool is_squeezed, size_t width, size_t height, size_t *r_width, size_t *r_height); -int *IMB_stereo3d_from_rect(const ImageFormatData *im_format, - size_t x, - size_t y, - size_t channels, - int *rect_left, - int *rect_right); -float *IMB_stereo3d_from_rectf(const ImageFormatData *im_format, - size_t x, - size_t y, - size_t channels, - float *rectf_left, - float *rectf_right); /** * Left/right are always float. */ diff --git a/source/blender/imbuf/intern/stereoimbuf.cc b/source/blender/imbuf/intern/stereoimbuf.cc index b7cfd8ab4cf..51b87788f17 100644 --- a/source/blender/imbuf/intern/stereoimbuf.cc +++ b/source/blender/imbuf/intern/stereoimbuf.cc @@ -592,73 +592,6 @@ static void imb_stereo3d_unsqueeze_ImBuf(ImBuf *ibuf, IMB_scale(ibuf, x, y, IMBScaleFilter::Bilinear); } -static void imb_stereo3d_squeeze_rectf( - float *rectf, const Stereo3dFormat *s3d, const size_t x, const size_t y, const size_t channels) -{ - ImBuf *ibuf; - size_t width, height; - - if (ELEM(s3d->display_mode, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM) == false) { - return; - } - - if ((s3d->flag & S3D_SQUEEZED_FRAME) == 0) { - return; - } - - /* creates temporary imbuf to store the rectf */ - IMB_stereo3d_write_dimensions(s3d->display_mode, false, x, y, &width, &height); - ibuf = IMB_allocImBuf(width, height, channels, IB_rectfloat); - - IMB_buffer_float_from_float(ibuf->float_buffer.data, - rectf, - channels, - IB_PROFILE_LINEAR_RGB, - IB_PROFILE_LINEAR_RGB, - false, - width, - height, - width, - width); - - IMB_scale(ibuf, x, y, IMBScaleFilter::Bilinear); - memcpy(rectf, ibuf->float_buffer.data, x * y * sizeof(float[4])); - IMB_freeImBuf(ibuf); -} - -static void imb_stereo3d_squeeze_rect( - int *rect, const Stereo3dFormat *s3d, const size_t x, const size_t y, const size_t channels) -{ - ImBuf *ibuf; - size_t width, height; - - if (ELEM(s3d->display_mode, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM) == false) { - return; - } - - if ((s3d->flag & S3D_SQUEEZED_FRAME) == 0) { - return; - } - - /* creates temporary imbuf to store the rectf */ - IMB_stereo3d_write_dimensions(s3d->display_mode, false, x, y, &width, &height); - ibuf = IMB_allocImBuf(width, height, channels, IB_rect); - - IMB_buffer_byte_from_byte(ibuf->byte_buffer.data, - (uchar *)rect, - IB_PROFILE_SRGB, - IB_PROFILE_SRGB, - false, - width, - height, - width, - width); - - IMB_scale(ibuf, x, y, IMBScaleFilter::Bilinear); - memcpy(rect, ibuf->byte_buffer.data, x * y * sizeof(uint)); - IMB_freeImBuf(ibuf); -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -689,79 +622,17 @@ static void imb_stereo3d_data_init(Stereo3DData *s3d_data, s3d_data->rectf.stereo = rectf_stereo; } -int *IMB_stereo3d_from_rect(const ImageFormatData *im_format, - const size_t x, - const size_t y, - const size_t channels, - int *rect_left, - int *rect_right) -{ - int *rect_result; - Stereo3DData s3d_data = {{nullptr}}; - size_t width, height; - const bool is_float = im_format->depth > 8; - - IMB_stereo3d_write_dimensions( - im_format->stereo3d_format.display_mode, false, x, y, &width, &height); - rect_result = static_cast(MEM_mallocN(channels * sizeof(int) * width * height, __func__)); - - imb_stereo3d_data_init(&s3d_data, - is_float, - x, - y, - channels, - rect_left, - rect_right, - rect_result, - nullptr, - nullptr, - nullptr); - imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format); - imb_stereo3d_squeeze_rect(rect_result, &im_format->stereo3d_format, x, y, channels); - - return rect_result; -} - -float *IMB_stereo3d_from_rectf(const ImageFormatData *im_format, - const size_t x, - const size_t y, - const size_t channels, - float *rectf_left, - float *rectf_right) -{ - float *rectf_result; - Stereo3DData s3d_data = {{nullptr}}; - size_t width, height; - const bool is_float = im_format->depth > 8; - - IMB_stereo3d_write_dimensions( - im_format->stereo3d_format.display_mode, false, x, y, &width, &height); - rectf_result = static_cast( - MEM_mallocN(channels * sizeof(float) * width * height, __func__)); - - imb_stereo3d_data_init(&s3d_data, - is_float, - x, - y, - channels, - nullptr, - nullptr, - nullptr, - rectf_left, - rectf_right, - rectf_result); - imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format); - imb_stereo3d_squeeze_rectf(rectf_result, &im_format->stereo3d_format, x, y, channels); - - return rectf_result; -} - ImBuf *IMB_stereo3d_ImBuf(const ImageFormatData *im_format, ImBuf *ibuf_left, ImBuf *ibuf_right) { ImBuf *ibuf_stereo = nullptr; Stereo3DData s3d_data = {{nullptr}}; size_t width, height; - const bool is_float = im_format->depth > 8; + const bool is_float = ibuf_left->float_buffer.data && ibuf_right->float_buffer.data; + const bool is_byte = ibuf_left->byte_buffer.data && ibuf_right->byte_buffer.data; + + if (!(is_float || is_byte)) { + return nullptr; + } IMB_stereo3d_write_dimensions( im_format->stereo3d_format.display_mode, false, ibuf_left->x, ibuf_left->y, &width, &height); diff --git a/source/blender/makesrna/intern/rna_scene.cc b/source/blender/makesrna/intern/rna_scene.cc index 250fb94cccf..7f3bfbcf1c2 100644 --- a/source/blender/makesrna/intern/rna_scene.cc +++ b/source/blender/makesrna/intern/rna_scene.cc @@ -1327,61 +1327,9 @@ static bool rna_RenderSettings_is_movie_format_get(PointerRNA *ptr) return BKE_imtype_is_movie(rd->im_format.imtype); } -static int get_first_valid_depth(const int valid_depths) -{ - /* set first available depth */ - const char depth_ls[] = { - R_IMF_CHAN_DEPTH_32, - R_IMF_CHAN_DEPTH_24, - R_IMF_CHAN_DEPTH_16, - R_IMF_CHAN_DEPTH_12, - R_IMF_CHAN_DEPTH_10, - R_IMF_CHAN_DEPTH_8, - R_IMF_CHAN_DEPTH_1, - 0, - }; - for (int i = 0; depth_ls[i]; i++) { - if (valid_depths & depth_ls[i]) { - return depth_ls[i]; - } - } - return R_IMF_CHAN_DEPTH_8; -} - static void rna_ImageFormatSettings_file_format_set(PointerRNA *ptr, int value) { - ImageFormatData *imf = (ImageFormatData *)ptr->data; - ID *id = ptr->owner_id; - imf->imtype = value; - - const bool is_render = (id && GS(id->name) == ID_SCE); - /* see note below on why this is */ - const char chan_flag = BKE_imtype_valid_channels(imf->imtype, true) | - (is_render ? IMA_CHAN_FLAG_BW : 0); - - /* ensure depth and color settings match */ - if ((imf->planes == R_IMF_PLANES_BW) && !(chan_flag & IMA_CHAN_FLAG_BW)) { - imf->planes = R_IMF_PLANES_RGBA; - } - if ((imf->planes == R_IMF_PLANES_RGBA) && !(chan_flag & IMA_CHAN_FLAG_RGBA)) { - imf->planes = R_IMF_PLANES_RGB; - } - - /* ensure usable depth */ - { - const int depth_ok = BKE_imtype_valid_depths(imf->imtype); - if ((imf->depth & depth_ok) == 0) { - imf->depth = get_first_valid_depth(depth_ok); - } - } - - if (id && GS(id->name) == ID_SCE) { - Scene *scene = (Scene *)ptr->owner_id; - RenderData *rd = &scene->r; - MOV_validate_output_settings(rd, imf); - } - - BKE_image_format_update_color_space_for_type(imf); + BKE_image_format_set((ImageFormatData *)ptr->data, ptr->owner_id, value); } static const EnumPropertyItem *rna_ImageFormatSettings_file_format_itemf(bContext * /*C*/, @@ -2984,7 +2932,7 @@ static void rna_FFmpegSettings_codec_update(Main * /*bmain*/, Scene * /*scene*/, Scene *scene = (Scene *)ptr->owner_id; const int valid_depths = BKE_imtype_valid_depths_with_video(scene->r.im_format.imtype, id); if ((scene->r.im_format.depth & valid_depths) == 0) { - scene->r.im_format.depth = get_first_valid_depth(valid_depths); + scene->r.im_format.depth = BKE_imtype_first_valid_depth(valid_depths); } } } diff --git a/source/blender/render/intern/pipeline.cc b/source/blender/render/intern/pipeline.cc index 890e650e842..3251dccb172 100644 --- a/source/blender/render/intern/pipeline.cc +++ b/source/blender/render/intern/pipeline.cc @@ -2208,21 +2208,29 @@ bool RE_WriteRenderViewsMovie(ReportList *reports, ibuf_arr[2] = IMB_stereo3d_ImBuf(&image_format, ibuf_arr[0], ibuf_arr[1]); - BLI_assert(movie_writers[0] != nullptr); - if (!MOV_write_append(movie_writers[0], - rd, - preview ? scene->r.psfra : scene->r.sfra, - scene->r.cfra, - ibuf_arr[2], - "", - reports)) - { + if (ibuf_arr[2]) { + BLI_assert(movie_writers[0] != nullptr); + if (!MOV_write_append(movie_writers[0], + rd, + preview ? scene->r.psfra : scene->r.sfra, + scene->r.cfra, + ibuf_arr[2], + "", + reports)) + { + ok = false; + } + } + else { + BKE_report(reports, RPT_ERROR, "Failed to create stereo image buffer"); ok = false; } for (i = 0; i < 3; i++) { /* imbuf knows which rects are not part of ibuf */ - IMB_freeImBuf(ibuf_arr[i]); + if (ibuf_arr[i]) { + IMB_freeImBuf(ibuf_arr[i]); + } } } diff --git a/source/creator/creator_args.cc b/source/creator/creator_args.cc index e10188967b1..7bf81d97056 100644 --- a/source/creator/creator_args.cc +++ b/source/creator/creator_args.cc @@ -2007,7 +2007,7 @@ static int arg_handle_image_type_set(int argc, const char **argv, void *data) "release.\n"); } else { - scene->r.im_format.imtype = imtype_new; + BKE_image_format_set(&scene->r.im_format, &scene->id, imtype_new); DEG_id_tag_update(&scene->id, ID_RECALC_SYNC_TO_EVAL); } }