916 lines
26 KiB
C++
916 lines
26 KiB
C++
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup bke
|
|
*/
|
|
|
|
#include <cstring>
|
|
|
|
#include "DNA_defaults.h"
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "BLI_path_util.h"
|
|
#include "BLI_string.h"
|
|
#include "BLI_utildefines.h"
|
|
|
|
#include "IMB_colormanagement.h"
|
|
#include "IMB_imbuf.h"
|
|
#include "IMB_imbuf_types.h"
|
|
|
|
#include "BKE_colortools.h"
|
|
#include "BKE_image_format.h"
|
|
|
|
/* Init/Copy/Free */
|
|
|
|
void BKE_image_format_init(ImageFormatData *imf, const bool render)
|
|
{
|
|
*imf = *DNA_struct_default_get(ImageFormatData);
|
|
|
|
BKE_color_managed_display_settings_init(&imf->display_settings);
|
|
|
|
if (render) {
|
|
BKE_color_managed_view_settings_init_render(
|
|
&imf->view_settings, &imf->display_settings, "Filmic");
|
|
}
|
|
else {
|
|
BKE_color_managed_view_settings_init_default(&imf->view_settings, &imf->display_settings);
|
|
}
|
|
|
|
BKE_color_managed_colorspace_settings_init(&imf->linear_colorspace_settings);
|
|
}
|
|
|
|
void BKE_image_format_copy(ImageFormatData *imf_dst, const ImageFormatData *imf_src)
|
|
{
|
|
memcpy(imf_dst, imf_src, sizeof(*imf_dst));
|
|
BKE_color_managed_display_settings_copy(&imf_dst->display_settings, &imf_src->display_settings);
|
|
BKE_color_managed_view_settings_copy(&imf_dst->view_settings, &imf_src->view_settings);
|
|
BKE_color_managed_colorspace_settings_copy(&imf_dst->linear_colorspace_settings,
|
|
&imf_src->linear_colorspace_settings);
|
|
}
|
|
|
|
void BKE_image_format_free(ImageFormatData *imf)
|
|
{
|
|
BKE_color_managed_view_settings_free(&imf->view_settings);
|
|
}
|
|
|
|
void BKE_image_format_blend_read_data(BlendDataReader *reader, ImageFormatData *imf)
|
|
{
|
|
BKE_color_managed_view_settings_blend_read_data(reader, &imf->view_settings);
|
|
}
|
|
|
|
void BKE_image_format_blend_write(BlendWriter *writer, ImageFormatData *imf)
|
|
{
|
|
BKE_color_managed_view_settings_blend_write(writer, &imf->view_settings);
|
|
}
|
|
|
|
/* File Types */
|
|
|
|
int BKE_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options)
|
|
{
|
|
memset(r_options, 0, sizeof(*r_options));
|
|
|
|
if (imtype == R_IMF_IMTYPE_TARGA) {
|
|
return IMB_FTYPE_TGA;
|
|
}
|
|
if (imtype == R_IMF_IMTYPE_RAWTGA) {
|
|
r_options->flag = RAWTGA;
|
|
return IMB_FTYPE_TGA;
|
|
}
|
|
if (imtype == R_IMF_IMTYPE_IRIS) {
|
|
return IMB_FTYPE_IMAGIC;
|
|
}
|
|
if (imtype == R_IMF_IMTYPE_RADHDR) {
|
|
return IMB_FTYPE_RADHDR;
|
|
}
|
|
if (imtype == R_IMF_IMTYPE_PNG) {
|
|
r_options->quality = 15;
|
|
return IMB_FTYPE_PNG;
|
|
}
|
|
if (imtype == R_IMF_IMTYPE_DDS) {
|
|
return IMB_FTYPE_DDS;
|
|
}
|
|
if (imtype == R_IMF_IMTYPE_BMP) {
|
|
return IMB_FTYPE_BMP;
|
|
}
|
|
if (imtype == R_IMF_IMTYPE_TIFF) {
|
|
return IMB_FTYPE_TIF;
|
|
}
|
|
if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
|
|
return IMB_FTYPE_OPENEXR;
|
|
}
|
|
#ifdef WITH_CINEON
|
|
if (imtype == R_IMF_IMTYPE_CINEON) {
|
|
return IMB_FTYPE_CINEON;
|
|
}
|
|
if (imtype == R_IMF_IMTYPE_DPX) {
|
|
return IMB_FTYPE_DPX;
|
|
}
|
|
#endif
|
|
#ifdef WITH_OPENJPEG
|
|
if (imtype == R_IMF_IMTYPE_JP2) {
|
|
r_options->flag |= JP2_JP2;
|
|
r_options->quality = 90;
|
|
return IMB_FTYPE_JP2;
|
|
}
|
|
#endif
|
|
#ifdef WITH_WEBP
|
|
if (imtype == R_IMF_IMTYPE_WEBP) {
|
|
r_options->quality = 90;
|
|
return IMB_FTYPE_WEBP;
|
|
}
|
|
#endif
|
|
|
|
r_options->quality = 90;
|
|
return IMB_FTYPE_JPG;
|
|
}
|
|
|
|
char BKE_ftype_to_imtype(const int ftype, const ImbFormatOptions *options)
|
|
{
|
|
if (ftype == IMB_FTYPE_NONE) {
|
|
return R_IMF_IMTYPE_TARGA;
|
|
}
|
|
if (ftype == IMB_FTYPE_IMAGIC) {
|
|
return R_IMF_IMTYPE_IRIS;
|
|
}
|
|
if (ftype == IMB_FTYPE_RADHDR) {
|
|
return R_IMF_IMTYPE_RADHDR;
|
|
}
|
|
if (ftype == IMB_FTYPE_PNG) {
|
|
return R_IMF_IMTYPE_PNG;
|
|
}
|
|
if (ftype == IMB_FTYPE_DDS) {
|
|
return R_IMF_IMTYPE_DDS;
|
|
}
|
|
if (ftype == IMB_FTYPE_BMP) {
|
|
return R_IMF_IMTYPE_BMP;
|
|
}
|
|
if (ftype == IMB_FTYPE_TIF) {
|
|
return R_IMF_IMTYPE_TIFF;
|
|
}
|
|
if (ftype == IMB_FTYPE_OPENEXR) {
|
|
return R_IMF_IMTYPE_OPENEXR;
|
|
}
|
|
#ifdef WITH_CINEON
|
|
if (ftype == IMB_FTYPE_CINEON) {
|
|
return R_IMF_IMTYPE_CINEON;
|
|
}
|
|
if (ftype == IMB_FTYPE_DPX) {
|
|
return R_IMF_IMTYPE_DPX;
|
|
}
|
|
#endif
|
|
if (ftype == IMB_FTYPE_TGA) {
|
|
if (options && (options->flag & RAWTGA)) {
|
|
return R_IMF_IMTYPE_RAWTGA;
|
|
}
|
|
|
|
return R_IMF_IMTYPE_TARGA;
|
|
}
|
|
#ifdef WITH_OPENJPEG
|
|
if (ftype == IMB_FTYPE_JP2) {
|
|
return R_IMF_IMTYPE_JP2;
|
|
}
|
|
#endif
|
|
#ifdef WITH_WEBP
|
|
if (ftype == IMB_FTYPE_WEBP) {
|
|
return R_IMF_IMTYPE_WEBP;
|
|
}
|
|
#endif
|
|
|
|
return R_IMF_IMTYPE_JPEG90;
|
|
}
|
|
|
|
bool BKE_imtype_is_movie(const char imtype)
|
|
{
|
|
switch (imtype) {
|
|
case R_IMF_IMTYPE_AVIRAW:
|
|
case R_IMF_IMTYPE_AVIJPEG:
|
|
case R_IMF_IMTYPE_FFMPEG:
|
|
case R_IMF_IMTYPE_H264:
|
|
case R_IMF_IMTYPE_THEORA:
|
|
case R_IMF_IMTYPE_XVID:
|
|
case R_IMF_IMTYPE_AV1:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool BKE_imtype_supports_compress(const char imtype)
|
|
{
|
|
switch (imtype) {
|
|
case R_IMF_IMTYPE_PNG:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool BKE_imtype_supports_quality(const char imtype)
|
|
{
|
|
switch (imtype) {
|
|
case R_IMF_IMTYPE_JPEG90:
|
|
case R_IMF_IMTYPE_JP2:
|
|
case R_IMF_IMTYPE_AVIJPEG:
|
|
case R_IMF_IMTYPE_WEBP:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool BKE_imtype_requires_linear_float(const char imtype)
|
|
{
|
|
switch (imtype) {
|
|
case R_IMF_IMTYPE_CINEON:
|
|
case R_IMF_IMTYPE_DPX:
|
|
case R_IMF_IMTYPE_RADHDR:
|
|
case R_IMF_IMTYPE_OPENEXR:
|
|
case R_IMF_IMTYPE_MULTILAYER:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
char BKE_imtype_valid_channels(const char imtype, bool write_file)
|
|
{
|
|
char chan_flag = IMA_CHAN_FLAG_RGB; /* Assume all support RGB. */
|
|
|
|
/* Alpha. */
|
|
switch (imtype) {
|
|
case R_IMF_IMTYPE_BMP:
|
|
if (write_file) {
|
|
break;
|
|
}
|
|
ATTR_FALLTHROUGH;
|
|
case R_IMF_IMTYPE_TARGA:
|
|
case R_IMF_IMTYPE_RAWTGA:
|
|
case R_IMF_IMTYPE_IRIS:
|
|
case R_IMF_IMTYPE_PNG:
|
|
case R_IMF_IMTYPE_TIFF:
|
|
case R_IMF_IMTYPE_OPENEXR:
|
|
case R_IMF_IMTYPE_MULTILAYER:
|
|
case R_IMF_IMTYPE_DDS:
|
|
case R_IMF_IMTYPE_JP2:
|
|
case R_IMF_IMTYPE_DPX:
|
|
case R_IMF_IMTYPE_WEBP:
|
|
chan_flag |= IMA_CHAN_FLAG_RGBA;
|
|
break;
|
|
}
|
|
|
|
/* BW. */
|
|
switch (imtype) {
|
|
case R_IMF_IMTYPE_BMP:
|
|
case R_IMF_IMTYPE_PNG:
|
|
case R_IMF_IMTYPE_JPEG90:
|
|
case R_IMF_IMTYPE_TARGA:
|
|
case R_IMF_IMTYPE_RAWTGA:
|
|
case R_IMF_IMTYPE_TIFF:
|
|
case R_IMF_IMTYPE_IRIS:
|
|
chan_flag |= IMA_CHAN_FLAG_BW;
|
|
break;
|
|
}
|
|
|
|
return chan_flag;
|
|
}
|
|
|
|
char BKE_imtype_valid_depths(const char imtype)
|
|
{
|
|
switch (imtype) {
|
|
case R_IMF_IMTYPE_RADHDR:
|
|
return R_IMF_CHAN_DEPTH_32;
|
|
case R_IMF_IMTYPE_TIFF:
|
|
return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_16;
|
|
case R_IMF_IMTYPE_OPENEXR:
|
|
return R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_32;
|
|
case R_IMF_IMTYPE_MULTILAYER:
|
|
return R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_32;
|
|
/* NOTE: CINEON uses an unusual 10bits-LOG per channel. */
|
|
case R_IMF_IMTYPE_DPX:
|
|
return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_10 | R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16;
|
|
case R_IMF_IMTYPE_CINEON:
|
|
return R_IMF_CHAN_DEPTH_10;
|
|
case R_IMF_IMTYPE_JP2:
|
|
return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16;
|
|
case R_IMF_IMTYPE_PNG:
|
|
return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_16;
|
|
/* Most formats are 8bit only. */
|
|
default:
|
|
return R_IMF_CHAN_DEPTH_8;
|
|
}
|
|
}
|
|
|
|
char BKE_imtype_from_arg(const char *imtype_arg)
|
|
{
|
|
if (STREQ(imtype_arg, "TGA")) {
|
|
return R_IMF_IMTYPE_TARGA;
|
|
}
|
|
if (STREQ(imtype_arg, "IRIS")) {
|
|
return R_IMF_IMTYPE_IRIS;
|
|
}
|
|
if (STREQ(imtype_arg, "DDS")) {
|
|
return R_IMF_IMTYPE_DDS;
|
|
}
|
|
if (STREQ(imtype_arg, "JPEG")) {
|
|
return R_IMF_IMTYPE_JPEG90;
|
|
}
|
|
if (STREQ(imtype_arg, "IRIZ")) {
|
|
return R_IMF_IMTYPE_IRIZ;
|
|
}
|
|
if (STREQ(imtype_arg, "RAWTGA")) {
|
|
return R_IMF_IMTYPE_RAWTGA;
|
|
}
|
|
if (STREQ(imtype_arg, "AVIRAW")) {
|
|
return R_IMF_IMTYPE_AVIRAW;
|
|
}
|
|
if (STREQ(imtype_arg, "AVIJPEG")) {
|
|
return R_IMF_IMTYPE_AVIJPEG;
|
|
}
|
|
if (STREQ(imtype_arg, "PNG")) {
|
|
return R_IMF_IMTYPE_PNG;
|
|
}
|
|
if (STREQ(imtype_arg, "BMP")) {
|
|
return R_IMF_IMTYPE_BMP;
|
|
}
|
|
if (STREQ(imtype_arg, "HDR")) {
|
|
return R_IMF_IMTYPE_RADHDR;
|
|
}
|
|
if (STREQ(imtype_arg, "TIFF")) {
|
|
return R_IMF_IMTYPE_TIFF;
|
|
}
|
|
#ifdef WITH_OPENEXR
|
|
if (STREQ(imtype_arg, "OPEN_EXR")) {
|
|
return R_IMF_IMTYPE_OPENEXR;
|
|
}
|
|
if (STREQ(imtype_arg, "OPEN_EXR_MULTILAYER")) {
|
|
return R_IMF_IMTYPE_MULTILAYER;
|
|
}
|
|
if (STREQ(imtype_arg, "EXR")) {
|
|
return R_IMF_IMTYPE_OPENEXR;
|
|
}
|
|
if (STREQ(imtype_arg, "MULTILAYER")) {
|
|
return R_IMF_IMTYPE_MULTILAYER;
|
|
}
|
|
#endif
|
|
if (STREQ(imtype_arg, "FFMPEG")) {
|
|
return R_IMF_IMTYPE_FFMPEG;
|
|
}
|
|
#ifdef WITH_CINEON
|
|
if (STREQ(imtype_arg, "CINEON")) {
|
|
return R_IMF_IMTYPE_CINEON;
|
|
}
|
|
if (STREQ(imtype_arg, "DPX")) {
|
|
return R_IMF_IMTYPE_DPX;
|
|
}
|
|
#endif
|
|
#ifdef WITH_OPENJPEG
|
|
if (STREQ(imtype_arg, "JP2")) {
|
|
return R_IMF_IMTYPE_JP2;
|
|
}
|
|
#endif
|
|
#ifdef WITH_WEBP
|
|
if (STREQ(imtype_arg, "WEBP")) {
|
|
return R_IMF_IMTYPE_WEBP;
|
|
}
|
|
#endif
|
|
|
|
return R_IMF_IMTYPE_INVALID;
|
|
}
|
|
|
|
/* File Paths */
|
|
|
|
static int image_path_ext_from_imformat_impl(const char imtype,
|
|
const ImageFormatData *im_format,
|
|
const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
|
|
{
|
|
int ext_num = 0;
|
|
(void)im_format; /* may be unused, depends on build options */
|
|
|
|
if (imtype == R_IMF_IMTYPE_IRIS) {
|
|
r_ext[ext_num++] = ".rgb";
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_IRIZ) {
|
|
r_ext[ext_num++] = ".rgb";
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_RADHDR) {
|
|
r_ext[ext_num++] = ".hdr";
|
|
}
|
|
else if (ELEM(imtype,
|
|
R_IMF_IMTYPE_PNG,
|
|
R_IMF_IMTYPE_FFMPEG,
|
|
R_IMF_IMTYPE_H264,
|
|
R_IMF_IMTYPE_THEORA,
|
|
R_IMF_IMTYPE_XVID,
|
|
R_IMF_IMTYPE_AV1))
|
|
{
|
|
r_ext[ext_num++] = ".png";
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_DDS) {
|
|
r_ext[ext_num++] = ".dds";
|
|
}
|
|
else if (ELEM(imtype, R_IMF_IMTYPE_TARGA, R_IMF_IMTYPE_RAWTGA)) {
|
|
r_ext[ext_num++] = ".tga";
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_BMP) {
|
|
r_ext[ext_num++] = ".bmp";
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_TIFF) {
|
|
r_ext[ext_num++] = ".tif";
|
|
r_ext[ext_num++] = ".tiff";
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_PSD) {
|
|
r_ext[ext_num++] = ".psd";
|
|
}
|
|
#ifdef WITH_OPENEXR
|
|
else if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
|
|
r_ext[ext_num++] = ".exr";
|
|
}
|
|
#endif
|
|
#ifdef WITH_CINEON
|
|
else if (imtype == R_IMF_IMTYPE_CINEON) {
|
|
r_ext[ext_num++] = ".cin";
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_DPX) {
|
|
r_ext[ext_num++] = ".dpx";
|
|
}
|
|
#endif
|
|
#ifdef WITH_OPENJPEG
|
|
else if (imtype == R_IMF_IMTYPE_JP2) {
|
|
if (im_format) {
|
|
if (im_format->jp2_codec == R_IMF_JP2_CODEC_JP2) {
|
|
r_ext[ext_num++] = ".jp2";
|
|
}
|
|
else if (im_format->jp2_codec == R_IMF_JP2_CODEC_J2K) {
|
|
r_ext[ext_num++] = ".j2c";
|
|
}
|
|
else {
|
|
BLI_assert_msg(0, "Unsupported jp2 codec was specified in im_format->jp2_codec");
|
|
}
|
|
}
|
|
else {
|
|
r_ext[ext_num++] = ".jp2";
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef WITH_WEBP
|
|
else if (imtype == R_IMF_IMTYPE_WEBP) {
|
|
r_ext[ext_num++] = ".webp";
|
|
}
|
|
#endif
|
|
else {
|
|
/* Handles: #R_IMF_IMTYPE_AVIRAW, #R_IMF_IMTYPE_AVIJPEG, #R_IMF_IMTYPE_JPEG90 etc. */
|
|
r_ext[ext_num++] = ".jpg";
|
|
r_ext[ext_num++] = ".jpeg";
|
|
}
|
|
BLI_assert(ext_num < BKE_IMAGE_PATH_EXT_MAX);
|
|
r_ext[ext_num] = nullptr;
|
|
return ext_num;
|
|
}
|
|
|
|
int BKE_image_path_ext_from_imformat(const ImageFormatData *im_format,
|
|
const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
|
|
{
|
|
return image_path_ext_from_imformat_impl(im_format->imtype, im_format, r_ext);
|
|
}
|
|
|
|
int BKE_image_path_ext_from_imtype(const char imtype, const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
|
|
{
|
|
return image_path_ext_from_imformat_impl(imtype, nullptr, r_ext);
|
|
}
|
|
|
|
static bool do_ensure_image_extension(char *filepath,
|
|
const size_t filepath_maxncpy,
|
|
const char imtype,
|
|
const ImageFormatData *im_format)
|
|
{
|
|
const char *ext_array[BKE_IMAGE_PATH_EXT_MAX];
|
|
int ext_array_num = image_path_ext_from_imformat_impl(imtype, im_format, ext_array);
|
|
if (ext_array_num && !BLI_path_extension_check_array(filepath, ext_array)) {
|
|
/* Removing *any* extension may remove part of the user defined name (if they include '.')
|
|
* however in the case there is already a known image extension,
|
|
* remove it to avoid`.png.tga`, for example. */
|
|
if (BLI_path_extension_check_array(filepath, imb_ext_image)) {
|
|
return BLI_path_extension_replace(filepath, filepath_maxncpy, ext_array[0]);
|
|
}
|
|
return BLI_path_extension_ensure(filepath, filepath_maxncpy, ext_array[0]);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int BKE_image_path_ext_from_imformat_ensure(char *filepath,
|
|
const size_t filepath_maxncpy,
|
|
const ImageFormatData *im_format)
|
|
{
|
|
return do_ensure_image_extension(filepath, filepath_maxncpy, im_format->imtype, im_format);
|
|
}
|
|
|
|
int BKE_image_path_ext_from_imtype_ensure(char *filepath,
|
|
const size_t filepath_maxncpy,
|
|
const char imtype)
|
|
{
|
|
return do_ensure_image_extension(filepath, filepath_maxncpy, imtype, nullptr);
|
|
}
|
|
|
|
static void do_makepicstring(char filepath[FILE_MAX],
|
|
const char *base,
|
|
const char *relbase,
|
|
int frame,
|
|
const char imtype,
|
|
const ImageFormatData *im_format,
|
|
const bool use_ext,
|
|
const bool use_frames,
|
|
const char *suffix)
|
|
{
|
|
if (filepath == nullptr) {
|
|
return;
|
|
}
|
|
BLI_strncpy(filepath, base, FILE_MAX - 10); /* weak assumption */
|
|
BLI_path_abs(filepath, relbase);
|
|
|
|
if (use_frames) {
|
|
BLI_path_frame(filepath, FILE_MAX, frame, 4);
|
|
}
|
|
|
|
if (suffix) {
|
|
BLI_path_suffix(filepath, FILE_MAX, suffix, "");
|
|
}
|
|
|
|
if (use_ext) {
|
|
do_ensure_image_extension(filepath, FILE_MAX, imtype, im_format);
|
|
}
|
|
}
|
|
|
|
void BKE_image_path_from_imformat(char *filepath,
|
|
const char *base,
|
|
const char *relbase,
|
|
int frame,
|
|
const ImageFormatData *im_format,
|
|
const bool use_ext,
|
|
const bool use_frames,
|
|
const char *suffix)
|
|
{
|
|
do_makepicstring(
|
|
filepath, base, relbase, frame, im_format->imtype, im_format, use_ext, use_frames, suffix);
|
|
}
|
|
|
|
void BKE_image_path_from_imtype(char *filepath,
|
|
const char *base,
|
|
const char *relbase,
|
|
int frame,
|
|
const char imtype,
|
|
const bool use_ext,
|
|
const bool use_frames,
|
|
const char *suffix)
|
|
{
|
|
do_makepicstring(filepath, base, relbase, frame, imtype, nullptr, use_ext, use_frames, suffix);
|
|
}
|
|
|
|
/* ImBuf Conversion */
|
|
|
|
void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf)
|
|
{
|
|
/* Write to ImBuf in preparation for file writing. */
|
|
char imtype = imf->imtype;
|
|
char compress = imf->compress;
|
|
char quality = imf->quality;
|
|
|
|
/* initialize all from image format */
|
|
ibuf->foptions.flag = 0;
|
|
|
|
if (imtype == R_IMF_IMTYPE_IRIS) {
|
|
ibuf->ftype = IMB_FTYPE_IMAGIC;
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_RADHDR) {
|
|
ibuf->ftype = IMB_FTYPE_RADHDR;
|
|
}
|
|
else if (ELEM(imtype,
|
|
R_IMF_IMTYPE_PNG,
|
|
R_IMF_IMTYPE_FFMPEG,
|
|
R_IMF_IMTYPE_H264,
|
|
R_IMF_IMTYPE_THEORA,
|
|
R_IMF_IMTYPE_XVID,
|
|
R_IMF_IMTYPE_AV1))
|
|
{
|
|
ibuf->ftype = IMB_FTYPE_PNG;
|
|
|
|
if (imtype == R_IMF_IMTYPE_PNG) {
|
|
if (imf->depth == R_IMF_CHAN_DEPTH_16) {
|
|
ibuf->foptions.flag |= PNG_16BIT;
|
|
}
|
|
|
|
ibuf->foptions.quality = compress;
|
|
}
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_DDS) {
|
|
ibuf->ftype = IMB_FTYPE_DDS;
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_BMP) {
|
|
ibuf->ftype = IMB_FTYPE_BMP;
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_TIFF) {
|
|
ibuf->ftype = IMB_FTYPE_TIF;
|
|
|
|
if (imf->depth == R_IMF_CHAN_DEPTH_16) {
|
|
ibuf->foptions.flag |= TIF_16BIT;
|
|
}
|
|
if (imf->tiff_codec == R_IMF_TIFF_CODEC_NONE) {
|
|
ibuf->foptions.flag |= TIF_COMPRESS_NONE;
|
|
}
|
|
else if (imf->tiff_codec == R_IMF_TIFF_CODEC_DEFLATE) {
|
|
ibuf->foptions.flag |= TIF_COMPRESS_DEFLATE;
|
|
}
|
|
else if (imf->tiff_codec == R_IMF_TIFF_CODEC_LZW) {
|
|
ibuf->foptions.flag |= TIF_COMPRESS_LZW;
|
|
}
|
|
else if (imf->tiff_codec == R_IMF_TIFF_CODEC_PACKBITS) {
|
|
ibuf->foptions.flag |= TIF_COMPRESS_PACKBITS;
|
|
}
|
|
}
|
|
#ifdef WITH_OPENEXR
|
|
else if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
|
|
ibuf->ftype = IMB_FTYPE_OPENEXR;
|
|
if (imf->depth == R_IMF_CHAN_DEPTH_16) {
|
|
ibuf->foptions.flag |= OPENEXR_HALF;
|
|
}
|
|
ibuf->foptions.flag |= (imf->exr_codec & OPENEXR_COMPRESS);
|
|
}
|
|
#endif
|
|
#ifdef WITH_CINEON
|
|
else if (imtype == R_IMF_IMTYPE_CINEON) {
|
|
ibuf->ftype = IMB_FTYPE_CINEON;
|
|
if (imf->cineon_flag & R_IMF_CINEON_FLAG_LOG) {
|
|
ibuf->foptions.flag |= CINEON_LOG;
|
|
}
|
|
if (imf->depth == R_IMF_CHAN_DEPTH_16) {
|
|
ibuf->foptions.flag |= CINEON_16BIT;
|
|
}
|
|
else if (imf->depth == R_IMF_CHAN_DEPTH_12) {
|
|
ibuf->foptions.flag |= CINEON_12BIT;
|
|
}
|
|
else if (imf->depth == R_IMF_CHAN_DEPTH_10) {
|
|
ibuf->foptions.flag |= CINEON_10BIT;
|
|
}
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_DPX) {
|
|
ibuf->ftype = IMB_FTYPE_DPX;
|
|
if (imf->cineon_flag & R_IMF_CINEON_FLAG_LOG) {
|
|
ibuf->foptions.flag |= CINEON_LOG;
|
|
}
|
|
if (imf->depth == R_IMF_CHAN_DEPTH_16) {
|
|
ibuf->foptions.flag |= CINEON_16BIT;
|
|
}
|
|
else if (imf->depth == R_IMF_CHAN_DEPTH_12) {
|
|
ibuf->foptions.flag |= CINEON_12BIT;
|
|
}
|
|
else if (imf->depth == R_IMF_CHAN_DEPTH_10) {
|
|
ibuf->foptions.flag |= CINEON_10BIT;
|
|
}
|
|
}
|
|
#endif
|
|
else if (imtype == R_IMF_IMTYPE_TARGA) {
|
|
ibuf->ftype = IMB_FTYPE_TGA;
|
|
}
|
|
else if (imtype == R_IMF_IMTYPE_RAWTGA) {
|
|
ibuf->ftype = IMB_FTYPE_TGA;
|
|
ibuf->foptions.flag = RAWTGA;
|
|
}
|
|
#ifdef WITH_OPENJPEG
|
|
else if (imtype == R_IMF_IMTYPE_JP2) {
|
|
if (quality < 10) {
|
|
quality = 90;
|
|
}
|
|
ibuf->ftype = IMB_FTYPE_JP2;
|
|
ibuf->foptions.quality = quality;
|
|
|
|
if (imf->depth == R_IMF_CHAN_DEPTH_16) {
|
|
ibuf->foptions.flag |= JP2_16BIT;
|
|
}
|
|
else if (imf->depth == R_IMF_CHAN_DEPTH_12) {
|
|
ibuf->foptions.flag |= JP2_12BIT;
|
|
}
|
|
|
|
if (imf->jp2_flag & R_IMF_JP2_FLAG_YCC) {
|
|
ibuf->foptions.flag |= JP2_YCC;
|
|
}
|
|
|
|
if (imf->jp2_flag & R_IMF_JP2_FLAG_CINE_PRESET) {
|
|
ibuf->foptions.flag |= JP2_CINE;
|
|
if (imf->jp2_flag & R_IMF_JP2_FLAG_CINE_48) {
|
|
ibuf->foptions.flag |= JP2_CINE_48FPS;
|
|
}
|
|
}
|
|
|
|
if (imf->jp2_codec == R_IMF_JP2_CODEC_JP2) {
|
|
ibuf->foptions.flag |= JP2_JP2;
|
|
}
|
|
else if (imf->jp2_codec == R_IMF_JP2_CODEC_J2K) {
|
|
ibuf->foptions.flag |= JP2_J2K;
|
|
}
|
|
else {
|
|
BLI_assert_msg(0, "Unsupported jp2 codec was specified in im_format->jp2_codec");
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef WITH_WEBP
|
|
else if (imtype == R_IMF_IMTYPE_WEBP) {
|
|
ibuf->ftype = IMB_FTYPE_WEBP;
|
|
ibuf->foptions.quality = quality;
|
|
}
|
|
#endif
|
|
else {
|
|
/* #R_IMF_IMTYPE_JPEG90, etc. default to JPEG. */
|
|
if (quality < 10) {
|
|
quality = 90;
|
|
}
|
|
ibuf->ftype = IMB_FTYPE_JPG;
|
|
ibuf->foptions.quality = quality;
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
BKE_image_format_init(im_format, false);
|
|
|
|
/* file type */
|
|
if (ftype == IMB_FTYPE_IMAGIC) {
|
|
im_format->imtype = R_IMF_IMTYPE_IRIS;
|
|
}
|
|
else if (ftype == IMB_FTYPE_RADHDR) {
|
|
im_format->imtype = R_IMF_IMTYPE_RADHDR;
|
|
}
|
|
else if (ftype == IMB_FTYPE_PNG) {
|
|
im_format->imtype = R_IMF_IMTYPE_PNG;
|
|
|
|
if (custom_flags & PNG_16BIT) {
|
|
im_format->depth = R_IMF_CHAN_DEPTH_16;
|
|
}
|
|
|
|
im_format->compress = quality;
|
|
}
|
|
else if (ftype == IMB_FTYPE_DDS) {
|
|
im_format->imtype = R_IMF_IMTYPE_DDS;
|
|
}
|
|
else if (ftype == IMB_FTYPE_BMP) {
|
|
im_format->imtype = R_IMF_IMTYPE_BMP;
|
|
}
|
|
else if (ftype == IMB_FTYPE_TIF) {
|
|
im_format->imtype = R_IMF_IMTYPE_TIFF;
|
|
if (custom_flags & TIF_16BIT) {
|
|
im_format->depth = R_IMF_CHAN_DEPTH_16;
|
|
}
|
|
if (custom_flags & TIF_COMPRESS_NONE) {
|
|
im_format->tiff_codec = R_IMF_TIFF_CODEC_NONE;
|
|
}
|
|
if (custom_flags & TIF_COMPRESS_DEFLATE) {
|
|
im_format->tiff_codec = R_IMF_TIFF_CODEC_DEFLATE;
|
|
}
|
|
if (custom_flags & TIF_COMPRESS_LZW) {
|
|
im_format->tiff_codec = R_IMF_TIFF_CODEC_LZW;
|
|
}
|
|
if (custom_flags & TIF_COMPRESS_PACKBITS) {
|
|
im_format->tiff_codec = R_IMF_TIFF_CODEC_PACKBITS;
|
|
}
|
|
}
|
|
|
|
#ifdef WITH_OPENEXR
|
|
else if (ftype == IMB_FTYPE_OPENEXR) {
|
|
im_format->imtype = R_IMF_IMTYPE_OPENEXR;
|
|
if (custom_flags & OPENEXR_HALF) {
|
|
im_format->depth = R_IMF_CHAN_DEPTH_16;
|
|
}
|
|
if (custom_flags & OPENEXR_COMPRESS) {
|
|
im_format->exr_codec = R_IMF_EXR_CODEC_ZIP; /* Can't determine compression */
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef WITH_CINEON
|
|
else if (ftype == IMB_FTYPE_CINEON) {
|
|
im_format->imtype = R_IMF_IMTYPE_CINEON;
|
|
}
|
|
else if (ftype == IMB_FTYPE_DPX) {
|
|
im_format->imtype = R_IMF_IMTYPE_DPX;
|
|
}
|
|
#endif
|
|
else if (ftype == IMB_FTYPE_TGA) {
|
|
if (custom_flags & RAWTGA) {
|
|
im_format->imtype = R_IMF_IMTYPE_RAWTGA;
|
|
}
|
|
else {
|
|
im_format->imtype = R_IMF_IMTYPE_TARGA;
|
|
}
|
|
}
|
|
#ifdef WITH_OPENJPEG
|
|
else if (ftype == IMB_FTYPE_JP2) {
|
|
im_format->imtype = R_IMF_IMTYPE_JP2;
|
|
im_format->quality = quality;
|
|
|
|
if (custom_flags & JP2_16BIT) {
|
|
im_format->depth = R_IMF_CHAN_DEPTH_16;
|
|
}
|
|
else if (custom_flags & JP2_12BIT) {
|
|
im_format->depth = R_IMF_CHAN_DEPTH_12;
|
|
}
|
|
|
|
if (custom_flags & JP2_YCC) {
|
|
im_format->jp2_flag |= R_IMF_JP2_FLAG_YCC;
|
|
}
|
|
|
|
if (custom_flags & JP2_CINE) {
|
|
im_format->jp2_flag |= R_IMF_JP2_FLAG_CINE_PRESET;
|
|
if (custom_flags & JP2_CINE_48FPS) {
|
|
im_format->jp2_flag |= R_IMF_JP2_FLAG_CINE_48;
|
|
}
|
|
}
|
|
|
|
if (custom_flags & JP2_JP2) {
|
|
im_format->jp2_codec = R_IMF_JP2_CODEC_JP2;
|
|
}
|
|
else if (custom_flags & JP2_J2K) {
|
|
im_format->jp2_codec = R_IMF_JP2_CODEC_J2K;
|
|
}
|
|
else {
|
|
BLI_assert_msg(0, "Unsupported jp2 codec was specified in file type");
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef WITH_WEBP
|
|
else if (ftype == IMB_FTYPE_WEBP) {
|
|
im_format->imtype = R_IMF_IMTYPE_WEBP;
|
|
im_format->quality = quality;
|
|
}
|
|
#endif
|
|
|
|
else {
|
|
im_format->imtype = R_IMF_IMTYPE_JPEG90;
|
|
im_format->quality = quality;
|
|
}
|
|
|
|
/* planes */
|
|
im_format->planes = imbuf->planes;
|
|
}
|
|
|
|
bool BKE_image_format_is_byte(const ImageFormatData *imf)
|
|
{
|
|
return (imf->depth == R_IMF_CHAN_DEPTH_8) && (BKE_imtype_valid_depths(imf->imtype) & imf->depth);
|
|
}
|
|
|
|
/* Color Management */
|
|
|
|
void BKE_image_format_color_management_copy(ImageFormatData *imf, const ImageFormatData *imf_src)
|
|
{
|
|
BKE_color_managed_view_settings_free(&imf->view_settings);
|
|
|
|
BKE_color_managed_display_settings_copy(&imf->display_settings, &imf_src->display_settings);
|
|
BKE_color_managed_view_settings_copy(&imf->view_settings, &imf_src->view_settings);
|
|
BKE_color_managed_colorspace_settings_copy(&imf->linear_colorspace_settings,
|
|
&imf_src->linear_colorspace_settings);
|
|
}
|
|
|
|
void BKE_image_format_color_management_copy_from_scene(ImageFormatData *imf, const Scene *scene)
|
|
{
|
|
BKE_color_managed_view_settings_free(&imf->view_settings);
|
|
|
|
BKE_color_managed_display_settings_copy(&imf->display_settings, &scene->display_settings);
|
|
BKE_color_managed_view_settings_copy(&imf->view_settings, &scene->view_settings);
|
|
STRNCPY(imf->linear_colorspace_settings.name,
|
|
IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR));
|
|
}
|
|
|
|
/* Output */
|
|
|
|
void BKE_image_format_init_for_write(ImageFormatData *imf,
|
|
const Scene *scene_src,
|
|
const ImageFormatData *imf_src)
|
|
{
|
|
*imf = (imf_src) ? *imf_src : scene_src->r.im_format;
|
|
|
|
if (imf_src && imf_src->color_management == R_IMF_COLOR_MANAGEMENT_OVERRIDE) {
|
|
/* Use settings specific to one node, image save operation, etc. */
|
|
BKE_color_managed_display_settings_copy(&imf->display_settings, &imf_src->display_settings);
|
|
BKE_color_managed_view_settings_copy(&imf->view_settings, &imf_src->view_settings);
|
|
BKE_color_managed_colorspace_settings_copy(&imf->linear_colorspace_settings,
|
|
&imf_src->linear_colorspace_settings);
|
|
}
|
|
else if (scene_src->r.im_format.color_management == R_IMF_COLOR_MANAGEMENT_OVERRIDE) {
|
|
/* Use scene settings specific to render output. */
|
|
BKE_color_managed_display_settings_copy(&imf->display_settings,
|
|
&scene_src->r.im_format.display_settings);
|
|
BKE_color_managed_view_settings_copy(&imf->view_settings,
|
|
&scene_src->r.im_format.view_settings);
|
|
BKE_color_managed_colorspace_settings_copy(&imf->linear_colorspace_settings,
|
|
&scene_src->r.im_format.linear_colorspace_settings);
|
|
}
|
|
else {
|
|
/* Use general scene settings also used for display. */
|
|
BKE_color_managed_display_settings_copy(&imf->display_settings, &scene_src->display_settings);
|
|
BKE_color_managed_view_settings_copy(&imf->view_settings, &scene_src->view_settings);
|
|
STRNCPY(imf->linear_colorspace_settings.name,
|
|
IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR));
|
|
}
|
|
}
|