Refactor: add a function to access images extensions from it's format
Previously accessing the extension needed to ensure an extension on an empty path. This conflicted with DEBUG_STRSIZE as it was assumed the input was FILE_MAX, where as it was a small buffer with RNA, see: !107602. Resolve by separating the function that ensures the extension with the function that finds valid extensions for a format. Also pass the size of the filepath to functions that ensure the extension.
This commit is contained in:
parent
f15889a9f9
commit
6796cce11d
|
@ -45,9 +45,27 @@ void BKE_image_path_from_imtype(char *filepath,
|
|||
bool use_ext,
|
||||
bool use_frames,
|
||||
const char *suffix);
|
||||
int BKE_image_path_ensure_ext_from_imformat(char *filepath,
|
||||
|
||||
/**
|
||||
* The number of extensions an image may have (`.jpg`, `.jpeg` for example).
|
||||
* Add 1 as the array is nil terminated.
|
||||
*/
|
||||
#define BKE_IMAGE_PATH_EXT_MAX 3
|
||||
/**
|
||||
* Fill in an array of acceptable image extensions for the image format.
|
||||
*
|
||||
* \note In the case a file has no valid extension,
|
||||
* the first extension should be used (`r_ext[0]`).
|
||||
* \return the number of extensions assigned to `r_ext`, 0 for unsupported formats.
|
||||
*/
|
||||
int BKE_image_path_ext_from_imformat(const struct ImageFormatData *im_format,
|
||||
const char *r_ext[BKE_IMAGE_PATH_EXT_MAX]);
|
||||
int BKE_image_path_ext_from_imtype(const char imtype, const char *r_ext[BKE_IMAGE_PATH_EXT_MAX]);
|
||||
|
||||
int BKE_image_path_ext_from_imformat_ensure(char *filepath,
|
||||
size_t filepath_maxncpy,
|
||||
const struct ImageFormatData *im_format);
|
||||
int BKE_image_path_ensure_ext_from_imtype(char *filepath, char imtype);
|
||||
int BKE_image_path_ext_from_imtype_ensure(char *filepath, size_t filepath_maxncpy, char imtype);
|
||||
|
||||
/* File Types */
|
||||
|
||||
|
|
|
@ -3315,7 +3315,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface,
|
|||
}
|
||||
#endif
|
||||
BLI_strncpy(output_file, filepath, sizeof(output_file));
|
||||
BKE_image_path_ensure_ext_from_imtype(output_file, format);
|
||||
BKE_image_path_ext_from_imtype_ensure(output_file, sizeof(output_file), format);
|
||||
|
||||
/* Validate output file path */
|
||||
BLI_path_abs(output_file, BKE_main_blendfile_path_from_global());
|
||||
|
|
|
@ -386,28 +386,21 @@ char BKE_imtype_from_arg(const char *imtype_arg)
|
|||
|
||||
/* File Paths */
|
||||
|
||||
static bool do_add_image_extension(char *filepath,
|
||||
const char imtype,
|
||||
const ImageFormatData *im_format)
|
||||
static int image_path_ext_from_imformat_impl(const char imtype,
|
||||
const ImageFormatData *im_format,
|
||||
const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
|
||||
{
|
||||
const char *extension = nullptr;
|
||||
const char *extension_test;
|
||||
int ext_num = 0;
|
||||
(void)im_format; /* may be unused, depends on build options */
|
||||
|
||||
if (imtype == R_IMF_IMTYPE_IRIS) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".rgb")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".rgb";
|
||||
}
|
||||
else if (imtype == R_IMF_IMTYPE_IRIZ) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".rgb")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".rgb";
|
||||
}
|
||||
else if (imtype == R_IMF_IMTYPE_RADHDR) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".hdr")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".hdr";
|
||||
}
|
||||
else if (ELEM(imtype,
|
||||
R_IMF_IMTYPE_PNG,
|
||||
|
@ -417,112 +410,113 @@ static bool do_add_image_extension(char *filepath,
|
|||
R_IMF_IMTYPE_XVID,
|
||||
R_IMF_IMTYPE_AV1))
|
||||
{
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".png")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".png";
|
||||
}
|
||||
else if (imtype == R_IMF_IMTYPE_DDS) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".dds")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".dds";
|
||||
}
|
||||
else if (ELEM(imtype, R_IMF_IMTYPE_TARGA, R_IMF_IMTYPE_RAWTGA)) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".tga")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".tga";
|
||||
}
|
||||
else if (imtype == R_IMF_IMTYPE_BMP) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".bmp")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".bmp";
|
||||
}
|
||||
else if (imtype == R_IMF_IMTYPE_TIFF) {
|
||||
if (!BLI_path_extension_check_n(filepath, extension_test = ".tif", ".tiff", nullptr)) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".tif";
|
||||
r_ext[ext_num++] = ".tiff";
|
||||
}
|
||||
else if (imtype == R_IMF_IMTYPE_PSD) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".psd")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".psd";
|
||||
}
|
||||
#ifdef WITH_OPENEXR
|
||||
else if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".exr")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".exr";
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_CINEON
|
||||
else if (imtype == R_IMF_IMTYPE_CINEON) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".cin")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".cin";
|
||||
}
|
||||
else if (imtype == R_IMF_IMTYPE_DPX) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".dpx")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
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) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".jp2")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".jp2";
|
||||
}
|
||||
else if (im_format->jp2_codec == R_IMF_JP2_CODEC_J2K) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".j2c")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".j2c";
|
||||
}
|
||||
else {
|
||||
BLI_assert_msg(0, "Unsupported jp2 codec was specified in im_format->jp2_codec");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".jp2")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".jp2";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_WEBP
|
||||
else if (imtype == R_IMF_IMTYPE_WEBP) {
|
||||
if (!BLI_path_extension_check(filepath, extension_test = ".webp")) {
|
||||
extension = extension_test;
|
||||
}
|
||||
r_ext[ext_num++] = ".webp";
|
||||
}
|
||||
#endif
|
||||
else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90 etc
|
||||
if (!BLI_path_extension_check_n(filepath, extension_test = ".jpg", ".jpeg", nullptr)) {
|
||||
extension = extension_test;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
if (extension) {
|
||||
/* prefer this in many cases to avoid .png.tga, but in certain cases it breaks */
|
||||
/* remove any other known image extension */
|
||||
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, FILE_MAX, extension);
|
||||
return BLI_path_extension_replace(filepath, filepath_maxncpy, ext_array[0]);
|
||||
}
|
||||
|
||||
return BLI_path_extension_ensure(filepath, FILE_MAX, extension);
|
||||
return BLI_path_extension_ensure(filepath, filepath_maxncpy, ext_array[0]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int BKE_image_path_ensure_ext_from_imformat(char *filepath, const ImageFormatData *im_format)
|
||||
int BKE_image_path_ext_from_imformat_ensure(char *filepath,
|
||||
const size_t filepath_maxncpy,
|
||||
const ImageFormatData *im_format)
|
||||
{
|
||||
return do_add_image_extension(filepath, im_format->imtype, im_format);
|
||||
return do_ensure_image_extension(filepath, filepath_maxncpy, im_format->imtype, im_format);
|
||||
}
|
||||
|
||||
int BKE_image_path_ensure_ext_from_imtype(char *filepath, const char imtype)
|
||||
int BKE_image_path_ext_from_imtype_ensure(char *filepath,
|
||||
const size_t filepath_maxncpy,
|
||||
const char imtype)
|
||||
{
|
||||
return do_add_image_extension(filepath, imtype, nullptr);
|
||||
return do_ensure_image_extension(filepath, filepath_maxncpy, imtype, nullptr);
|
||||
}
|
||||
|
||||
static void do_makepicstring(char filepath[FILE_MAX],
|
||||
|
@ -550,7 +544,7 @@ static void do_makepicstring(char filepath[FILE_MAX],
|
|||
}
|
||||
|
||||
if (use_ext) {
|
||||
do_add_image_extension(filepath, imtype, im_format);
|
||||
do_ensure_image_extension(filepath, FILE_MAX, imtype, im_format);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -978,7 +978,7 @@ bool BKE_image_render_write(ReportList *reports,
|
|||
if (BLI_path_extension_check(filepath, ".exr")) {
|
||||
filepath[strlen(filepath) - 4] = 0;
|
||||
}
|
||||
BKE_image_path_ensure_ext_from_imformat(filepath, &image_format);
|
||||
BKE_image_path_ext_from_imformat_ensure(filepath, sizeof(filepath), &image_format);
|
||||
|
||||
ImBuf *ibuf = RE_render_result_rect_to_ibuf(rr, &image_format, dither, view_id);
|
||||
ibuf->planes = 24;
|
||||
|
@ -1037,7 +1037,7 @@ bool BKE_image_render_write(ReportList *reports,
|
|||
filepath[strlen(filepath) - 4] = 0;
|
||||
}
|
||||
|
||||
BKE_image_path_ensure_ext_from_imformat(filepath, &image_format);
|
||||
BKE_image_path_ext_from_imformat_ensure(filepath, sizeof(filepath), &image_format);
|
||||
ibuf_arr[2]->planes = 24;
|
||||
|
||||
ok = image_render_write_stamp_test(
|
||||
|
|
|
@ -512,7 +512,7 @@ static void unpack_generate_paths(const char *filepath,
|
|||
}
|
||||
if (ftype != IMB_FTYPE_NONE) {
|
||||
const int imtype = BKE_ftype_to_imtype(ftype, NULL);
|
||||
BKE_image_path_ensure_ext_from_imtype(temp_filename, imtype);
|
||||
BKE_image_path_ext_from_imtype_ensure(temp_filename, sizeof(temp_filename), imtype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
|
|||
/* make absolute destination path */
|
||||
|
||||
BLI_strncpy(export_file, name.c_str(), sizeof(export_file));
|
||||
BKE_image_path_ensure_ext_from_imformat(export_file, &imageFormat);
|
||||
BKE_image_path_ext_from_imformat_ensure(export_file, sizeof(export_file), &imageFormat);
|
||||
|
||||
BLI_path_join(export_path, sizeof(export_path), export_dir, export_file);
|
||||
|
||||
|
|
|
@ -408,7 +408,7 @@ static std::string get_in_memory_texture_filename(Image *ima)
|
|||
/* Use the image name for the file name. */
|
||||
strcpy(file_name, ima->id.name + 2);
|
||||
|
||||
BKE_image_path_ensure_ext_from_imformat(file_name, &imageFormat);
|
||||
BKE_image_path_ext_from_imformat_ensure(file_name, &imageFormat);
|
||||
|
||||
return file_name;
|
||||
}
|
||||
|
@ -442,7 +442,7 @@ static void export_in_memory_texture(Image *ima,
|
|||
* So we have to export it. The export will keep the image state intact,
|
||||
* so the exported file will not be associated with the image. */
|
||||
|
||||
BKE_image_path_ensure_ext_from_imformat(file_name, &imageFormat);
|
||||
BKE_image_path_ext_from_imformat_ensure(file_name, &imageFormat);
|
||||
|
||||
char export_path[FILE_MAX];
|
||||
BLI_path_join(export_path, FILE_MAX, export_dir.c_str(), file_name);
|
||||
|
|
|
@ -1513,18 +1513,18 @@ static void rna_ImageFormatSettings_color_management_set(PointerRNA *ptr, int va
|
|||
|
||||
static int rna_SceneRender_file_ext_length(PointerRNA *ptr)
|
||||
{
|
||||
RenderData *rd = (RenderData *)ptr->data;
|
||||
char ext[8];
|
||||
ext[0] = '\0';
|
||||
BKE_image_path_ensure_ext_from_imformat(ext, &rd->im_format);
|
||||
return strlen(ext);
|
||||
const RenderData *rd = (RenderData *)ptr->data;
|
||||
const char *ext_array[BKE_IMAGE_PATH_EXT_MAX];
|
||||
int ext_num = BKE_image_path_ext_from_imformat(&rd->im_format, ext_array);
|
||||
return ext_num ? strlen(ext_array[0]) : 0;
|
||||
}
|
||||
|
||||
static void rna_SceneRender_file_ext_get(PointerRNA *ptr, char *str)
|
||||
static void rna_SceneRender_file_ext_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
RenderData *rd = (RenderData *)ptr->data;
|
||||
str[0] = '\0';
|
||||
BKE_image_path_ensure_ext_from_imformat(str, &rd->im_format);
|
||||
const RenderData *rd = (RenderData *)ptr->data;
|
||||
const char *ext_array[BKE_IMAGE_PATH_EXT_MAX];
|
||||
int ext_num = BKE_image_path_ext_from_imformat(&rd->im_format, ext_array);
|
||||
strcpy(value, ext_num ? ext_array[0] : "");
|
||||
}
|
||||
|
||||
# ifdef WITH_FFMPEG
|
||||
|
|
|
@ -1228,7 +1228,7 @@ bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFor
|
|||
/* Don't NULL check prop, this can only run on ops with a 'filepath'. */
|
||||
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath");
|
||||
RNA_property_string_get(op->ptr, prop, filepath);
|
||||
if (BKE_image_path_ensure_ext_from_imformat(filepath, im_format)) {
|
||||
if (BKE_image_path_ext_from_imformat_ensure(filepath, sizeof(filepath), im_format)) {
|
||||
RNA_property_string_set(op->ptr, prop, filepath);
|
||||
/* NOTE: we could check for and update 'filename' here,
|
||||
* but so far nothing needs this. */
|
||||
|
|
Loading…
Reference in New Issue