diff --git a/source/blender/blenkernel/intern/image_format.cc b/source/blender/blenkernel/intern/image_format.cc index 82745eff2ce..0a431edfa49 100644 --- a/source/blender/blenkernel/intern/image_format.cc +++ b/source/blender/blenkernel/intern/image_format.cc @@ -818,12 +818,51 @@ void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf) } } +static char imtype_best_depth(const ImBuf *ibuf, const char imtype) +{ + const char depth_ok = BKE_imtype_valid_depths(imtype); + + if (ibuf->float_buffer.data) { + if (depth_ok & R_IMF_CHAN_DEPTH_32) { + return R_IMF_CHAN_DEPTH_32; + } + if (depth_ok & R_IMF_CHAN_DEPTH_24) { + return R_IMF_CHAN_DEPTH_24; + } + if (depth_ok & R_IMF_CHAN_DEPTH_16) { + return R_IMF_CHAN_DEPTH_16; + } + if (depth_ok & R_IMF_CHAN_DEPTH_12) { + return R_IMF_CHAN_DEPTH_12; + } + return R_IMF_CHAN_DEPTH_8; + } + + if (depth_ok & R_IMF_CHAN_DEPTH_8) { + return R_IMF_CHAN_DEPTH_8; + } + if (depth_ok & R_IMF_CHAN_DEPTH_12) { + return R_IMF_CHAN_DEPTH_12; + } + if (depth_ok & R_IMF_CHAN_DEPTH_16) { + return R_IMF_CHAN_DEPTH_16; + } + if (depth_ok & R_IMF_CHAN_DEPTH_24) { + return R_IMF_CHAN_DEPTH_24; + } + if (depth_ok & R_IMF_CHAN_DEPTH_32) { + return R_IMF_CHAN_DEPTH_32; + } + return R_IMF_CHAN_DEPTH_8; /* fallback, should not get here */ +} + void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf) { /* Read from ImBuf after file read. */ int ftype = imbuf->ftype; int custom_flags = imbuf->foptions.flag; char quality = imbuf->foptions.quality; + bool is_depth_set = false; BKE_image_format_init(im_format, false); @@ -839,6 +878,7 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf) if (custom_flags & PNG_16BIT) { im_format->depth = R_IMF_CHAN_DEPTH_16; + is_depth_set = true; } im_format->compress = quality; @@ -853,6 +893,7 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf) im_format->imtype = R_IMF_IMTYPE_TIFF; if (custom_flags & TIF_16BIT) { im_format->depth = R_IMF_CHAN_DEPTH_16; + is_depth_set = true; } if (custom_flags & TIF_COMPRESS_NONE) { im_format->tiff_codec = R_IMF_TIFF_CODEC_NONE; @@ -871,11 +912,17 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf) #ifdef WITH_OPENEXR else if (ftype == IMB_FTYPE_OPENEXR) { im_format->imtype = R_IMF_IMTYPE_OPENEXR; + char exr_codec = custom_flags & OPENEXR_CODEC_MASK; if (custom_flags & OPENEXR_HALF) { im_format->depth = R_IMF_CHAN_DEPTH_16; + is_depth_set = true; } - if (custom_flags & OPENEXR_CODEC_MASK) { - im_format->exr_codec = R_IMF_EXR_CODEC_ZIP; /* Can't determine compression */ + else if (exr_codec == R_IMF_EXR_CODEC_B44 || exr_codec == R_IMF_EXR_CODEC_B44A) { + /* B44 and B44A are only selectable for half precision images, default to ZIP compression */ + exr_codec = R_IMF_EXR_CODEC_ZIP; + } + if (exr_codec < R_IMF_EXR_CODEC_MAX) { + im_format->exr_codec = exr_codec; } } #endif @@ -903,9 +950,11 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf) if (custom_flags & JP2_16BIT) { im_format->depth = R_IMF_CHAN_DEPTH_16; + is_depth_set = true; } else if (custom_flags & JP2_12BIT) { im_format->depth = R_IMF_CHAN_DEPTH_12; + is_depth_set = true; } if (custom_flags & JP2_YCC) { @@ -942,6 +991,11 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf) im_format->quality = quality; } + /* Default depth, accounting for float buffer and format support */ + if (!is_depth_set) { + im_format->depth = imtype_best_depth(imbuf, im_format->imtype); + } + /* planes */ im_format->planes = imbuf->planes; } diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc index a8b62792431..f3cf9ae9a5a 100644 --- a/source/blender/blenkernel/intern/image_save.cc +++ b/source/blender/blenkernel/intern/image_save.cc @@ -42,44 +42,6 @@ using blender::Vector; -static char imtype_best_depth(ImBuf *ibuf, const char imtype) -{ - const char depth_ok = BKE_imtype_valid_depths(imtype); - - if (ibuf->float_buffer.data) { - if (depth_ok & R_IMF_CHAN_DEPTH_32) { - return R_IMF_CHAN_DEPTH_32; - } - if (depth_ok & R_IMF_CHAN_DEPTH_24) { - return R_IMF_CHAN_DEPTH_24; - } - if (depth_ok & R_IMF_CHAN_DEPTH_16) { - return R_IMF_CHAN_DEPTH_16; - } - if (depth_ok & R_IMF_CHAN_DEPTH_12) { - return R_IMF_CHAN_DEPTH_12; - } - return R_IMF_CHAN_DEPTH_8; - } - - if (depth_ok & R_IMF_CHAN_DEPTH_8) { - return R_IMF_CHAN_DEPTH_8; - } - if (depth_ok & R_IMF_CHAN_DEPTH_12) { - return R_IMF_CHAN_DEPTH_12; - } - if (depth_ok & R_IMF_CHAN_DEPTH_16) { - return R_IMF_CHAN_DEPTH_16; - } - if (depth_ok & R_IMF_CHAN_DEPTH_24) { - return R_IMF_CHAN_DEPTH_24; - } - if (depth_ok & R_IMF_CHAN_DEPTH_32) { - return R_IMF_CHAN_DEPTH_32; - } - return R_IMF_CHAN_DEPTH_8; /* fallback, should not get here */ -} - bool BKE_image_save_options_init(ImageSaveOptions *opts, Main *bmain, Scene *scene, @@ -108,13 +70,11 @@ bool BKE_image_save_options_init(ImageSaveOptions *opts, ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); if (ibuf) { - bool is_depth_set = false; const char *ima_colorspace = ima->colorspace_settings.name; if (opts->save_as_render) { /* Render/compositor output or user chose to save with render settings. */ BKE_image_format_init_for_write(&opts->im_format, scene, nullptr); - is_depth_set = true; if (!BKE_image_is_multiview(ima)) { /* In case multiview is disabled, * render settings would be invalid for render result in this area. */ @@ -156,11 +116,6 @@ bool BKE_image_save_options_init(ImageSaveOptions *opts, opts->im_format.planes = R_IMF_PLANES_RGBA; } - /* depth, account for float buffer and format support */ - if (is_depth_set == false) { - opts->im_format.depth = imtype_best_depth(ibuf, opts->im_format.imtype); - } - /* some formats don't use quality so fallback to scenes quality */ if (opts->im_format.quality == 0) { opts->im_format.quality = scene->r.im_format.quality; diff --git a/source/blender/compositor/cached_resources/intern/cached_image.cc b/source/blender/compositor/cached_resources/intern/cached_image.cc index 6bfd8152956..bec29638cd7 100644 --- a/source/blender/compositor/cached_resources/intern/cached_image.cc +++ b/source/blender/compositor/cached_resources/intern/cached_image.cc @@ -283,7 +283,7 @@ CachedImage::CachedImage(Context &context, ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &image_user_for_pass, nullptr); ImBuf *linear_image_buffer = compute_linear_buffer(image_buffer); - const bool use_half_float = linear_image_buffer->flags & IB_halffloat; + const bool use_half_float = linear_image_buffer->foptions.flag & OPENEXR_HALF; this->result.set_precision(use_half_float ? ResultPrecision::Half : ResultPrecision::Full); this->result.set_type(get_result_type(render_result, image_user_for_pass, linear_image_buffer)); diff --git a/source/blender/editors/space_image/image_buttons.cc b/source/blender/editors/space_image/image_buttons.cc index da80e5609fe..4b0c8a7b7f0 100644 --- a/source/blender/editors/space_image/image_buttons.cc +++ b/source/blender/editors/space_image/image_buttons.cc @@ -943,7 +943,7 @@ void uiTemplateImage(uiLayout *layout, void *lock; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); - if (ibuf && ibuf->float_buffer.data && (ibuf->flags & IB_halffloat) == 0) { + if (ibuf && ibuf->float_buffer.data && (ibuf->foptions.flag & OPENEXR_HALF) == 0) { uiItemR(col, &imaptr, "use_half_precision", UI_ITEM_NONE, std::nullopt, ICON_NONE); } BKE_image_release_ibuf(ima, ibuf, lock); diff --git a/source/blender/imbuf/IMB_imbuf_types.hh b/source/blender/imbuf/IMB_imbuf_types.hh index 50a9508df48..194dc62df5a 100644 --- a/source/blender/imbuf/IMB_imbuf_types.hh +++ b/source/blender/imbuf/IMB_imbuf_types.hh @@ -102,7 +102,6 @@ enum eImBufFlags { /** ignore alpha on load and substitute it with 1.0f */ IB_alphamode_ignore = 1 << 15, IB_thumbnail = 1 << 16, - IB_halffloat = 1 << 18, }; /** \} */ diff --git a/source/blender/imbuf/intern/oiio/openimageio_support.cc b/source/blender/imbuf/intern/oiio/openimageio_support.cc index 0183a4dc0c5..e4970338f62 100644 --- a/source/blender/imbuf/intern/oiio/openimageio_support.cc +++ b/source/blender/imbuf/intern/oiio/openimageio_support.cc @@ -203,7 +203,7 @@ static ImBuf *get_oiio_ibuf(ImageInput *in, const ReadContext &ctx, char colorsp /* Fill in common ibuf properties. */ if (ibuf) { ibuf->ftype = ctx.file_type; - ibuf->flags |= (spec.format == TypeDesc::HALF) ? IB_halffloat : 0; + ibuf->foptions.flag |= (spec.format == TypeDesc::HALF) ? OPENEXR_HALF : 0; set_colorspace_name(colorspace, ctx, spec, is_float); diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 4b5def97379..4e451fe64f2 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -466,6 +466,35 @@ static void openexr_header_compression(Header *header, int compression, int qual } } +static int openexr_header_get_compression(const Header &header) +{ + switch (header.compression()) { + case NO_COMPRESSION: + return R_IMF_EXR_CODEC_NONE; + case RLE_COMPRESSION: + return R_IMF_EXR_CODEC_RLE; + case ZIPS_COMPRESSION: + return R_IMF_EXR_CODEC_ZIPS; + case ZIP_COMPRESSION: + return R_IMF_EXR_CODEC_ZIP; + case PIZ_COMPRESSION: + return R_IMF_EXR_CODEC_PIZ; + case PXR24_COMPRESSION: + return R_IMF_EXR_CODEC_PXR24; + case B44_COMPRESSION: + return R_IMF_EXR_CODEC_B44; + case B44A_COMPRESSION: + return R_IMF_EXR_CODEC_B44A; + case DWAA_COMPRESSION: + return R_IMF_EXR_CODEC_DWAA; + case DWAB_COMPRESSION: + return R_IMF_EXR_CODEC_DWAB; + case NUM_COMPRESSION_METHODS: + return R_IMF_EXR_CODEC_NONE; + } + return R_IMF_EXR_CODEC_NONE; +} + static void openexr_header_metadata(Header *header, ImBuf *ibuf) { if (ibuf->metadata) { @@ -2220,7 +2249,8 @@ ImBuf *imb_load_openexr(const uchar *mem, size_t size, int flags, char colorspac const bool is_alpha = exr_has_alpha(*file); ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, 0); - ibuf->flags |= exr_is_half_float(*file) ? IB_halffloat : 0; + ibuf->foptions.flag |= exr_is_half_float(*file) ? OPENEXR_HALF : 0; + ibuf->foptions.flag |= openexr_header_get_compression(file_header); if (hasXDensity(file_header)) { /* Convert inches to meters. */ diff --git a/source/blender/imbuf/intern/util_gpu.cc b/source/blender/imbuf/intern/util_gpu.cc index 808918ac6fa..e21310b61b2 100644 --- a/source/blender/imbuf/intern/util_gpu.cc +++ b/source/blender/imbuf/intern/util_gpu.cc @@ -59,7 +59,7 @@ static void imb_gpu_get_format(const ImBuf *ibuf, if (float_rect) { /* Float. */ - const bool use_high_bitdepth = (!(ibuf->flags & IB_halffloat) && high_bitdepth); + const bool use_high_bitdepth = (!(ibuf->foptions.flag & OPENEXR_HALF) && high_bitdepth); *r_texture_format = is_grayscale ? (use_high_bitdepth ? GPU_R32F : GPU_R16F) : (use_high_bitdepth ? GPU_RGBA32F : GPU_RGBA16F); }