diff --git a/CMakeLists.txt b/CMakeLists.txt index 2477ab1679e..2f8e3460f09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -333,10 +333,7 @@ option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" ON) # Image format support option(WITH_IMAGE_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON) option(WITH_IMAGE_OPENJPEG "Enable OpenJpeg Support (http://www.openjpeg.org)" ON) -option(WITH_IMAGE_TIFF "Enable LibTIFF Support" ON) -option(WITH_IMAGE_DDS "Enable DDS Image Support" ON) option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON) -option(WITH_IMAGE_HDR "Enable HDR Image Support" ON) option(WITH_IMAGE_WEBP "Enable WebP Image Support" ON) # Audio/Video format support @@ -896,9 +893,6 @@ set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_ALEMBIC OFF) set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_VULKAN_BACKEND OFF) set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_CYCLES_OSL OFF) -# Haru needs `TIFFFaxBlackCodes` & `TIFFFaxWhiteCodes` symbols from TIFF. -set_and_warn_dependency(WITH_IMAGE_TIFF WITH_HARU OFF) - # auto enable openimageio for cycles if(WITH_CYCLES) # auto enable llvm for cycles_osl @@ -1941,11 +1935,8 @@ if(FIRST_RUN) info_cfg_text("Image Formats:") info_cfg_option(WITH_IMAGE_CINEON) - info_cfg_option(WITH_IMAGE_DDS) - info_cfg_option(WITH_IMAGE_HDR) info_cfg_option(WITH_IMAGE_OPENEXR) info_cfg_option(WITH_IMAGE_OPENJPEG) - info_cfg_option(WITH_IMAGE_TIFF) info_cfg_text("Audio:") info_cfg_option(WITH_CODEC_AVI) diff --git a/build_files/cmake/config/blender_full.cmake b/build_files/cmake/config/blender_full.cmake index b44250b011b..384ab56b19e 100644 --- a/build_files/cmake/config/blender_full.cmake +++ b/build_files/cmake/config/blender_full.cmake @@ -26,11 +26,8 @@ set(WITH_HARU ON CACHE BOOL "" FORCE) set(WITH_IK_ITASC ON CACHE BOOL "" FORCE) set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE) set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE) -set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE) -set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE) -set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE) set(WITH_IMAGE_WEBP ON CACHE BOOL "" FORCE) set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE) set(WITH_INPUT_IME ON CACHE BOOL "" FORCE) diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake index 942c6cf395e..2dbccc95bdf 100644 --- a/build_files/cmake/config/blender_lite.cmake +++ b/build_files/cmake/config/blender_lite.cmake @@ -27,11 +27,8 @@ set(WITH_HARU OFF CACHE BOOL "" FORCE) set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE) set(WITH_IK_SOLVER OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE) -set(WITH_IMAGE_DDS OFF CACHE BOOL "" FORCE) -set(WITH_IMAGE_HDR OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENEXR OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENJPEG OFF CACHE BOOL "" FORCE) -set(WITH_IMAGE_TIFF OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_WEBP OFF CACHE BOOL "" FORCE) set(WITH_INPUT_IME OFF CACHE BOOL "" FORCE) set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE) diff --git a/build_files/cmake/config/blender_release.cmake b/build_files/cmake/config/blender_release.cmake index 10805728574..bcee440adcb 100644 --- a/build_files/cmake/config/blender_release.cmake +++ b/build_files/cmake/config/blender_release.cmake @@ -27,11 +27,8 @@ set(WITH_HARU ON CACHE BOOL "" FORCE) set(WITH_IK_ITASC ON CACHE BOOL "" FORCE) set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE) set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE) -set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE) -set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE) -set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE) set(WITH_IMAGE_WEBP ON CACHE BOOL "" FORCE) set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE) set(WITH_INPUT_IME ON CACHE BOOL "" FORCE) diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index 326830ae0fa..942e86f617d 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -221,10 +221,8 @@ find_package(PNG REQUIRED) set(JPEG_ROOT ${LIBDIR}/jpeg) find_package(JPEG REQUIRED) -if(WITH_IMAGE_TIFF) - set(TIFF_ROOT ${LIBDIR}/tiff) - find_package(TIFF REQUIRED) -endif() +set(TIFF_ROOT ${LIBDIR}/tiff) +find_package(TIFF REQUIRED) if(WITH_IMAGE_WEBP) set(WEBP_ROOT_DIR ${LIBDIR}/webp) diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index 6adc39ab703..5ce2791bc29 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -109,6 +109,10 @@ find_package_wrapper(ZLIB REQUIRED) find_package_wrapper(Zstd REQUIRED) find_package_wrapper(Epoxy REQUIRED) +# XXX Linking errors with debian static tiff :/ +# find_package_wrapper(TIFF REQUIRED) +find_package(TIFF) + if(WITH_VULKAN_BACKEND) find_package_wrapper(Vulkan REQUIRED) find_package_wrapper(ShaderC REQUIRED) @@ -190,13 +194,6 @@ if(WITH_IMAGE_OPENJPEG) set_and_warn_library_found("OpenJPEG" OPENJPEG_FOUND WITH_IMAGE_OPENJPEG) endif() -if(WITH_IMAGE_TIFF) - # XXX Linking errors with debian static tiff :/ -# find_package_wrapper(TIFF) - find_package(TIFF) - set_and_warn_library_found("TIFF" TIFF_FOUND WITH_IMAGE_TIFF) -endif() - if(WITH_OPENAL) find_package_wrapper(OpenAL) set_and_warn_library_found("OpenAL" OPENAL_FOUND WITH_OPENAL) diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index c7bad653098..9b7256a2120 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -487,14 +487,12 @@ if(WITH_IMAGE_OPENEXR) endif() endif() -if(WITH_IMAGE_TIFF) - # Try to find tiff first then complain and set static and maybe wrong paths - windows_find_package(TIFF) - if(NOT TIFF_FOUND) - warn_hardcoded_paths(libtiff) - set(TIFF_LIBRARY ${LIBDIR}/tiff/lib/libtiff.lib) - set(TIFF_INCLUDE_DIR ${LIBDIR}/tiff/include) - endif() +# Try to find tiff first then complain and set static and maybe wrong paths +windows_find_package(TIFF) +if(NOT TIFF_FOUND) + warn_hardcoded_paths(libtiff) + set(TIFF_LIBRARY ${LIBDIR}/tiff/lib/libtiff.lib) + set(TIFF_INCLUDE_DIR ${LIBDIR}/tiff/include) endif() if(WITH_JACK) diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 8dd363e5f2a..554f1d4b057 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -165,10 +165,6 @@ if(WITH_IMAGE_OPENEXR) add_subdirectory(imbuf/intern/openexr) endif() -if(WITH_IMAGE_DDS) - add_subdirectory(imbuf/intern/dds) -endif() - if(WITH_IMAGE_CINEON) add_subdirectory(imbuf/intern/cineon) endif() diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 76324facc9d..c193570a2f8 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -594,26 +594,14 @@ if(WITH_IMAGE_OPENEXR) add_definitions(-DWITH_OPENEXR) endif() -if(WITH_IMAGE_TIFF) - add_definitions(-DWITH_TIFF) -endif() - if(WITH_IMAGE_OPENJPEG) add_definitions(-DWITH_OPENJPEG) endif() -if(WITH_IMAGE_DDS) - add_definitions(-DWITH_DDS) -endif() - if(WITH_IMAGE_CINEON) add_definitions(-DWITH_CINEON) endif() -if(WITH_IMAGE_HDR) - add_definitions(-DWITH_HDR) -endif() - if(WITH_IMAGE_WEBP) add_definitions(-DWITH_WEBP) endif() diff --git a/source/blender/blenkernel/intern/image_format.cc b/source/blender/blenkernel/intern/image_format.cc index a4759216ca1..9d134129c06 100644 --- a/source/blender/blenkernel/intern/image_format.cc +++ b/source/blender/blenkernel/intern/image_format.cc @@ -80,28 +80,22 @@ int BKE_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options) if (imtype == R_IMF_IMTYPE_IRIS) { return IMB_FTYPE_IMAGIC; } -#ifdef WITH_HDR if (imtype == R_IMF_IMTYPE_RADHDR) { return IMB_FTYPE_RADHDR; } -#endif if (imtype == R_IMF_IMTYPE_PNG) { r_options->quality = 15; return IMB_FTYPE_PNG; } -#ifdef WITH_DDS if (imtype == R_IMF_IMTYPE_DDS) { return IMB_FTYPE_DDS; } -#endif if (imtype == R_IMF_IMTYPE_BMP) { return IMB_FTYPE_BMP; } -#ifdef WITH_TIFF if (imtype == R_IMF_IMTYPE_TIFF) { return IMB_FTYPE_TIF; } -#endif if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) { return IMB_FTYPE_OPENEXR; } @@ -139,27 +133,21 @@ char BKE_ftype_to_imtype(const int ftype, const ImbFormatOptions *options) if (ftype == IMB_FTYPE_IMAGIC) { return R_IMF_IMTYPE_IRIS; } -#ifdef WITH_HDR if (ftype == IMB_FTYPE_RADHDR) { return R_IMF_IMTYPE_RADHDR; } -#endif if (ftype == IMB_FTYPE_PNG) { return R_IMF_IMTYPE_PNG; } -#ifdef WITH_DDS if (ftype == IMB_FTYPE_DDS) { return R_IMF_IMTYPE_DDS; } -#endif if (ftype == IMB_FTYPE_BMP) { return R_IMF_IMTYPE_BMP; } -#ifdef WITH_TIFF if (ftype == IMB_FTYPE_TIF) { return R_IMF_IMTYPE_TIFF; } -#endif if (ftype == IMB_FTYPE_OPENEXR) { return R_IMF_IMTYPE_OPENEXR; } @@ -327,11 +315,9 @@ char BKE_imtype_from_arg(const char *imtype_arg) if (STREQ(imtype_arg, "IRIS")) { return R_IMF_IMTYPE_IRIS; } -#ifdef WITH_DDS if (STREQ(imtype_arg, "DDS")) { return R_IMF_IMTYPE_DDS; } -#endif if (STREQ(imtype_arg, "JPEG")) { return R_IMF_IMTYPE_JPEG90; } @@ -353,16 +339,12 @@ char BKE_imtype_from_arg(const char *imtype_arg) if (STREQ(imtype_arg, "BMP")) { return R_IMF_IMTYPE_BMP; } -#ifdef WITH_HDR if (STREQ(imtype_arg, "HDR")) { return R_IMF_IMTYPE_RADHDR; } -#endif -#ifdef WITH_TIFF if (STREQ(imtype_arg, "TIFF")) { return R_IMF_IMTYPE_TIFF; } -#endif #ifdef WITH_OPENEXR if (STREQ(imtype_arg, "OPEN_EXR")) { return R_IMF_IMTYPE_OPENEXR; @@ -422,13 +404,11 @@ static bool do_add_image_extension(char *string, extension = extension_test; } } -#ifdef WITH_HDR else if (imtype == R_IMF_IMTYPE_RADHDR) { if (!BLI_path_extension_check(string, extension_test = ".hdr")) { extension = extension_test; } } -#endif else if (ELEM(imtype, R_IMF_IMTYPE_PNG, R_IMF_IMTYPE_FFMPEG, @@ -440,13 +420,11 @@ static bool do_add_image_extension(char *string, extension = extension_test; } } -#ifdef WITH_DDS else if (imtype == R_IMF_IMTYPE_DDS) { if (!BLI_path_extension_check(string, extension_test = ".dds")) { extension = extension_test; } } -#endif else if (ELEM(imtype, R_IMF_IMTYPE_TARGA, R_IMF_IMTYPE_RAWTGA)) { if (!BLI_path_extension_check(string, extension_test = ".tga")) { extension = extension_test; @@ -457,13 +435,11 @@ static bool do_add_image_extension(char *string, extension = extension_test; } } -#ifdef WITH_TIFF else if (imtype == R_IMF_IMTYPE_TIFF) { if (!BLI_path_extension_check_n(string, extension_test = ".tif", ".tiff", nullptr)) { extension = extension_test; } } -#endif else if (imtype == R_IMF_IMTYPE_PSD) { if (!BLI_path_extension_check(string, extension_test = ".psd")) { extension = extension_test; @@ -617,11 +593,9 @@ void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf) if (imtype == R_IMF_IMTYPE_IRIS) { ibuf->ftype = IMB_FTYPE_IMAGIC; } -#ifdef WITH_HDR else if (imtype == R_IMF_IMTYPE_RADHDR) { ibuf->ftype = IMB_FTYPE_RADHDR; } -#endif else if (ELEM(imtype, R_IMF_IMTYPE_PNG, R_IMF_IMTYPE_FFMPEG, @@ -639,15 +613,12 @@ void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf) ibuf->foptions.quality = compress; } } -#ifdef WITH_DDS else if (imtype == R_IMF_IMTYPE_DDS) { ibuf->ftype = IMB_FTYPE_DDS; } -#endif else if (imtype == R_IMF_IMTYPE_BMP) { ibuf->ftype = IMB_FTYPE_BMP; } -#ifdef WITH_TIFF else if (imtype == R_IMF_IMTYPE_TIFF) { ibuf->ftype = IMB_FTYPE_TIF; @@ -667,7 +638,6 @@ void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf) ibuf->foptions.flag |= TIF_COMPRESS_PACKBITS; } } -#endif #ifdef WITH_OPENEXR else if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) { ibuf->ftype = IMB_FTYPE_OPENEXR; @@ -787,11 +757,9 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf) if (ftype == IMB_FTYPE_IMAGIC) { im_format->imtype = R_IMF_IMTYPE_IRIS; } -#ifdef WITH_HDR else if (ftype == IMB_FTYPE_RADHDR) { im_format->imtype = R_IMF_IMTYPE_RADHDR; } -#endif else if (ftype == IMB_FTYPE_PNG) { im_format->imtype = R_IMF_IMTYPE_PNG; @@ -801,16 +769,12 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf) im_format->compress = quality; } - -#ifdef WITH_DDS else if (ftype == IMB_FTYPE_DDS) { im_format->imtype = R_IMF_IMTYPE_DDS; } -#endif else if (ftype == IMB_FTYPE_BMP) { im_format->imtype = R_IMF_IMTYPE_BMP; } -#ifdef WITH_TIFF else if (ftype == IMB_FTYPE_TIF) { im_format->imtype = R_IMF_IMTYPE_TIFF; if (custom_flags & TIF_16BIT) { @@ -829,7 +793,6 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf) im_format->tiff_codec = R_IMF_TIFF_CODEC_PACKBITS; } } -#endif #ifdef WITH_OPENEXR else if (ftype == IMB_FTYPE_OPENEXR) { diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt index 0a1e8f27af4..76768d16d01 100644 --- a/source/blender/editors/space_file/CMakeLists.txt +++ b/source/blender/editors/space_file/CMakeLists.txt @@ -66,26 +66,14 @@ if(WITH_IMAGE_OPENEXR) add_definitions(-DWITH_OPENEXR) endif() -if(WITH_IMAGE_TIFF) - add_definitions(-DWITH_TIFF) -endif() - if(WITH_IMAGE_OPENJPEG) add_definitions(-DWITH_OPENJPEG) endif() -if(WITH_IMAGE_DDS) - add_definitions(-DWITH_DDS) -endif() - if(WITH_IMAGE_CINEON) add_definitions(-DWITH_CINEON) endif() -if(WITH_IMAGE_HDR) - add_definitions(-DWITH_HDR) -endif() - if(WITH_IMAGE_WEBP) add_definitions(-DWITH_WEBP) endif() diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt index 81e457eaea6..e708dc4e63e 100644 --- a/source/blender/editors/space_image/CMakeLists.txt +++ b/source/blender/editors/space_image/CMakeLists.txt @@ -54,10 +54,6 @@ if(WITH_IMAGE_OPENEXR) add_definitions(-DWITH_OPENEXR) endif() -if(WITH_IMAGE_TIFF) - add_definitions(-DWITH_TIFF) -endif() - if(WITH_IMAGE_CINEON) add_definitions(-DWITH_CINEON) endif() diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 070131a186e..df021f12d68 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -738,10 +738,6 @@ if(WITH_MOD_FLUID) add_definitions(-DWITH_FLUID) endif() -if(WITH_IMAGE_DDS) - add_definitions(-DWITH_DDS) -endif() - if(WITH_OPENCOLORIO) add_definitions(-DWITH_OCIO) endif() diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index 654e6fac323..600cf7b5172 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -16,7 +16,6 @@ set(INC set(INC_SYS ${JPEG_INCLUDE_DIR} - ${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} ${OPENIMAGEIO_INCLUDE_DIRS} ) @@ -24,13 +23,19 @@ set(INC_SYS set(SRC intern/allocimbuf.c intern/anim_movie.c - intern/bmp.c intern/colormanagement.c intern/colormanagement_inline.c intern/divers.c intern/filetype.c intern/filter.c + intern/format_bmp.cc + intern/format_dds.cc + intern/format_dpx.cc + intern/format_hdr.cc + intern/format_png.cc intern/format_psd.cc + intern/format_targa.cc + intern/format_tiff.cc intern/imageprocess.c intern/indexer.c intern/iris.c @@ -38,13 +43,11 @@ set(SRC intern/metadata.c intern/module.c intern/moviecache.cc - intern/png.c intern/readimage.c intern/rectop.c intern/rotate.c intern/scaling.c intern/stereoimbuf.c - intern/targa.c intern/thumbs.c intern/thumbs_blend.c intern/thumbs_font.c @@ -81,7 +84,6 @@ set(LIB bf_intern_memutil bf_intern_opencolorio - ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ) @@ -96,19 +98,6 @@ else() ) endif() -if(WITH_IMAGE_TIFF) - list(APPEND INC_SYS - ${TIFF_INCLUDE_DIR} - ) - list(APPEND SRC - intern/tiff.c - ) - list(APPEND LIB - ${TIFF_LIBRARY} - ) - add_definitions(-DWITH_TIFF) -endif() - if(WITH_IMAGE_OPENJPEG) list(APPEND INC_SYS ${OPENJPEG_INCLUDE_DIRS} @@ -147,13 +136,6 @@ if(WITH_CODEC_FFMPEG) add_definitions(-DWITH_FFMPEG) endif() -if(WITH_IMAGE_DDS) - list(APPEND LIB - bf_imbuf_dds - ) - add_definitions(-DWITH_DDS) -endif() - if(WITH_IMAGE_CINEON) list(APPEND LIB bf_imbuf_cineon @@ -161,13 +143,6 @@ if(WITH_IMAGE_CINEON) add_definitions(-DWITH_CINEON) endif() -if(WITH_IMAGE_HDR) - list(APPEND SRC - intern/radiance_hdr.c - ) - add_definitions(-DWITH_HDR) -endif() - if(WITH_IMAGE_WEBP) list(APPEND SRC intern/webp.c diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index c5bd60358b0..d8e0106b957 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -63,20 +63,14 @@ enum eImbFileType { #ifdef WITH_OPENJPEG IMB_FTYPE_JP2 = 8, #endif -#ifdef WITH_HDR IMB_FTYPE_RADHDR = 9, -#endif -#ifdef WITH_TIFF IMB_FTYPE_TIF = 10, -#endif #ifdef WITH_CINEON IMB_FTYPE_CINEON = 11, IMB_FTYPE_DPX = 12, #endif -#ifdef WITH_DDS IMB_FTYPE_DDS = 13, -#endif #ifdef WITH_WEBP IMB_FTYPE_WEBP = 14, #endif @@ -113,13 +107,11 @@ enum eImbFileType { #define RAWTGA 1 -#ifdef WITH_TIFF -# define TIF_16BIT (1 << 8) -# define TIF_COMPRESS_NONE (1 << 7) -# define TIF_COMPRESS_DEFLATE (1 << 6) -# define TIF_COMPRESS_LZW (1 << 5) -# define TIF_COMPRESS_PACKBITS (1 << 4) -#endif +#define TIF_16BIT (1 << 8) +#define TIF_COMPRESS_NONE (1 << 7) +#define TIF_COMPRESS_DEFLATE (1 << 6) +#define TIF_COMPRESS_LZW (1 << 5) +#define TIF_COMPRESS_PACKBITS (1 << 4) typedef struct ImbFormatOptions { short flag; @@ -295,25 +287,24 @@ enum { /** \} */ /* dds */ -#ifdef WITH_DDS -# ifndef DDS_MAKEFOURCC -# define DDS_MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((unsigned long)(unsigned char)(ch0) | ((unsigned long)(unsigned char)(ch1) << 8) | \ - ((unsigned long)(unsigned char)(ch2) << 16) | ((unsigned long)(unsigned char)(ch3) << 24)) -# endif /* DDS_MAKEFOURCC */ +#ifndef DDS_MAKEFOURCC +# define DDS_MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((unsigned long)(unsigned char)(ch0) | ((unsigned long)(unsigned char)(ch1) << 8) | \ + ((unsigned long)(unsigned char)(ch2) << 16) | ((unsigned long)(unsigned char)(ch3) << 24)) +#endif /* DDS_MAKEFOURCC */ /* * FOURCC codes for DX compressed-texture pixel formats. */ -# define FOURCC_DDS (DDS_MAKEFOURCC('D', 'D', 'S', ' ')) -# define FOURCC_DXT1 (DDS_MAKEFOURCC('D', 'X', 'T', '1')) -# define FOURCC_DXT2 (DDS_MAKEFOURCC('D', 'X', 'T', '2')) -# define FOURCC_DXT3 (DDS_MAKEFOURCC('D', 'X', 'T', '3')) -# define FOURCC_DXT4 (DDS_MAKEFOURCC('D', 'X', 'T', '4')) -# define FOURCC_DXT5 (DDS_MAKEFOURCC('D', 'X', 'T', '5')) +#define FOURCC_DDS (DDS_MAKEFOURCC('D', 'D', 'S', ' ')) +#define FOURCC_DX10 (DDS_MAKEFOURCC('D', 'X', '1', '0')) +#define FOURCC_DXT1 (DDS_MAKEFOURCC('D', 'X', 'T', '1')) +#define FOURCC_DXT2 (DDS_MAKEFOURCC('D', 'X', 'T', '2')) +#define FOURCC_DXT3 (DDS_MAKEFOURCC('D', 'X', 'T', '3')) +#define FOURCC_DXT4 (DDS_MAKEFOURCC('D', 'X', 'T', '4')) +#define FOURCC_DXT5 (DDS_MAKEFOURCC('D', 'X', 'T', '5')) -#endif /* DDS */ extern const char *imb_ext_image[]; extern const char *imb_ext_movie[]; extern const char *imb_ext_audio[]; diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h index 4a226cbc9fd..005b56ba7b4 100644 --- a/source/blender/imbuf/intern/IMB_filetype.h +++ b/source/blender/imbuf/intern/IMB_filetype.h @@ -80,11 +80,11 @@ void imb_filetypes_exit(void); * \{ */ bool imb_is_a_png(const unsigned char *mem, size_t size); -struct ImBuf *imb_loadpng(const unsigned char *mem, - size_t size, - int flags, - char colorspace[IM_MAX_SPACE]); -bool imb_savepng(struct ImBuf *ibuf, const char *filepath, int flags); +struct ImBuf *imb_load_png(const unsigned char *mem, + size_t size, + int flags, + char colorspace[IM_MAX_SPACE]); +bool imb_save_png(struct ImBuf *ibuf, const char *filepath, int flags); /** \} */ @@ -92,12 +92,12 @@ bool imb_savepng(struct ImBuf *ibuf, const char *filepath, int flags); /** \name Format: TARGA (#IMB_FTYPE_TGA) * \{ */ -bool imb_is_a_targa(const unsigned char *buf, size_t size); -struct ImBuf *imb_loadtarga(const unsigned char *mem, - size_t size, - int flags, - char colorspace[IM_MAX_SPACE]); -bool imb_savetarga(struct ImBuf *ibuf, const char *filepath, int flags); +bool imb_is_a_tga(const unsigned char *mem, size_t size); +struct ImBuf *imb_load_tga(const unsigned char *mem, + size_t size, + int flags, + char colorspace[IM_MAX_SPACE]); +bool imb_save_tga(struct ImBuf *ibuf, const char *filepath, int flags); /** \} */ @@ -157,12 +157,12 @@ struct ImBuf *imb_thumbnail_jpeg(const char *filepath, * \{ */ bool imb_is_a_bmp(const unsigned char *buf, size_t size); -struct ImBuf *imb_bmp_decode(const unsigned char *mem, - size_t size, - int flags, - char colorspace[IM_MAX_SPACE]); +struct ImBuf *imb_load_bmp(const unsigned char *mem, + size_t size, + int flags, + char colorspace[IM_MAX_SPACE]); /* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */ -bool imb_savebmp(struct ImBuf *ibuf, const char *filepath, int flags); +bool imb_save_bmp(struct ImBuf *ibuf, const char *filepath, int flags); /** \} */ @@ -197,11 +197,11 @@ struct ImBuf *imb_load_dpx(const unsigned char *mem, * \{ */ bool imb_is_a_hdr(const unsigned char *buf, size_t size); -struct ImBuf *imb_loadhdr(const unsigned char *mem, - size_t size, - int flags, - char colorspace[IM_MAX_SPACE]); -bool imb_savehdr(struct ImBuf *ibuf, const char *filepath, int flags); +struct ImBuf *imb_load_hdr(const unsigned char *mem, + size_t size, + int flags, + char colorspace[IM_MAX_SPACE]); +bool imb_save_hdr(struct ImBuf *ibuf, const char *filepath, int flags); /** \} */ @@ -209,7 +209,6 @@ bool imb_savehdr(struct ImBuf *ibuf, const char *filepath, int flags); /** \name Format: TIFF (#IMB_FTYPE_TIF) * \{ */ -void imb_inittiff(void); bool imb_is_a_tiff(const unsigned char *buf, size_t size); /** * Loads a TIFF file. @@ -220,10 +219,10 @@ bool imb_is_a_tiff(const unsigned char *buf, size_t size); * * \return A newly allocated #ImBuf structure if successful, otherwise NULL. */ -struct ImBuf *imb_loadtiff(const unsigned char *mem, - size_t size, - int flags, - char colorspace[IM_MAX_SPACE]); +struct ImBuf *imb_load_tiff(const unsigned char *mem, + size_t size, + int flags, + char colorspace[IM_MAX_SPACE]); /** * Saves a TIFF file. * @@ -238,12 +237,12 @@ struct ImBuf *imb_loadtiff(const unsigned char *mem, * * \return 1 if the function is successful, 0 on failure. */ -bool imb_savetiff(struct ImBuf *ibuf, const char *filepath, int flags); +bool imb_save_tiff(struct ImBuf *ibuf, const char *filepath, int flags); /** \} */ /* -------------------------------------------------------------------- */ -/** \name Format: TIFF (#IMB_FTYPE_WEBP) +/** \name Format: WEBP (#IMB_FTYPE_WEBP) * \{ */ bool imb_is_a_webp(const unsigned char *buf, size_t size); @@ -261,13 +260,26 @@ bool imb_savewebp(struct ImBuf *ibuf, const char *name, int flags); /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Format: DDS (#IMB_FTYPE_DDS) + * \{ */ + +bool imb_is_a_dds(const unsigned char *buf, size_t size); + +struct ImBuf *imb_load_dds(const unsigned char *mem, + size_t size, + int flags, + char colorspace[IM_MAX_SPACE]); + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Format: PSD (#IMB_FTYPE_PSD) * \{ */ bool imb_is_a_psd(const unsigned char *buf, size_t size); -struct ImBuf *imb_load_psd(const uchar *mem, +struct ImBuf *imb_load_psd(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]); diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c deleted file mode 100644 index 495ec286de3..00000000000 --- a/source/blender/imbuf/intern/bmp.c +++ /dev/null @@ -1,383 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2001-2002 NaN Holding BV. All rights reserved. */ - -/** \file - * \ingroup imbuf - */ - -#include - -#include "BLI_fileops.h" -#include "BLI_utildefines.h" - -#include "imbuf.h" - -#include "IMB_filetype.h" -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "IMB_colormanagement.h" -#include "IMB_colormanagement_intern.h" - -/* Some code copied from article on microsoft.com, - * copied here for enhanced BMP support in the future: - * http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0197/mfcp1/mfcp1.htm&nav=/msj/0197/newnav.htm - */ - -typedef struct BMPINFOHEADER { - uint biSize; - uint biWidth; - uint biHeight; - ushort biPlanes; - ushort biBitCount; - uint biCompression; - uint biSizeImage; - uint biXPelsPerMeter; - uint biYPelsPerMeter; - uint biClrUsed; - uint biClrImportant; -} BMPINFOHEADER; - -#if 0 -typedef struct BMPHEADER { - ushort biType; - uint biSize; - ushort biRes1; - ushort biRes2; - uint biOffBits; -} BMPHEADER; -#endif - -#define BMP_FILEHEADER_SIZE 14 - -#define CHECK_HEADER_FIELD(_mem, _field) ((_mem[0] == _field[0]) && (_mem[1] == _field[1])) -#define CHECK_HEADER_FIELD_BMP(_mem) \ - (CHECK_HEADER_FIELD(_mem, "BM") || CHECK_HEADER_FIELD(_mem, "BA") || \ - CHECK_HEADER_FIELD(_mem, "CI") || CHECK_HEADER_FIELD(_mem, "CP") || \ - CHECK_HEADER_FIELD(_mem, "IC") || CHECK_HEADER_FIELD(_mem, "PT")) - -static bool checkbmp(const uchar *mem, const size_t size) -{ - if (size < (BMP_FILEHEADER_SIZE + sizeof(BMPINFOHEADER))) { - return false; - } - - if (!CHECK_HEADER_FIELD_BMP(mem)) { - return false; - } - - bool ok = false; - BMPINFOHEADER bmi; - uint u; - - /* Skip file-header. */ - mem += BMP_FILEHEADER_SIZE; - - /* for systems where an int needs to be 4 bytes aligned */ - memcpy(&bmi, mem, sizeof(bmi)); - - u = LITTLE_LONG(bmi.biSize); - /* we only support uncompressed images for now. */ - if (u >= sizeof(BMPINFOHEADER)) { - if (bmi.biCompression == 0) { - u = LITTLE_SHORT(bmi.biBitCount); - if (u > 0 && u <= 32) { - ok = true; - } - } - } - - return ok; -} - -bool imb_is_a_bmp(const uchar *buf, size_t size) -{ - return checkbmp(buf, size); -} - -static size_t imb_bmp_calc_row_size_in_bytes(size_t x, size_t depth) -{ - /* https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader#calculating-surface-stride - */ - return (((x * depth) + 31) & ~31) >> 3; -} - -ImBuf *imb_bmp_decode(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) -{ - ImBuf *ibuf = NULL; - BMPINFOHEADER bmi; - int ibuf_depth; - const uchar *bmp; - uchar *rect; - ushort col; - bool top_to_bottom = false; - - if (checkbmp(mem, size) == 0) { - return NULL; - } - - colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); - - /* For systems where an int needs to be 4 bytes aligned. */ - memcpy(&bmi, mem + BMP_FILEHEADER_SIZE, sizeof(bmi)); - - const size_t palette_offset = (size_t)BMP_FILEHEADER_SIZE + LITTLE_LONG(bmi.biSize); - const int depth = LITTLE_SHORT(bmi.biBitCount); - const int xppm = LITTLE_LONG(bmi.biXPelsPerMeter); - const int yppm = LITTLE_LONG(bmi.biYPelsPerMeter); - const int x = LITTLE_LONG(bmi.biWidth); - int y = LITTLE_LONG(bmi.biHeight); - - /* Negative height means bitmap is stored top-to-bottom. */ - if (y < 0) { - y = -y; - top_to_bottom = true; - } - - /* Validate and cross-check offsets and sizes. */ - if (x < 1 || !ELEM(depth, 1, 4, 8, 16, 24, 32)) { - return NULL; - } - - const size_t pixel_data_offset = (size_t)LITTLE_LONG(*(int *)(mem + 10)); - const size_t header_bytes = BMP_FILEHEADER_SIZE + sizeof(BMPINFOHEADER); - const size_t num_actual_data_bytes = size - pixel_data_offset; - const size_t row_size_in_bytes = imb_bmp_calc_row_size_in_bytes(x, depth); - const size_t num_expected_data_bytes = row_size_in_bytes * y; - if (num_actual_data_bytes < num_expected_data_bytes || num_actual_data_bytes > size || - pixel_data_offset < header_bytes || pixel_data_offset > (size - num_expected_data_bytes) || - palette_offset < header_bytes || palette_offset > pixel_data_offset) { - return NULL; - } - - if (depth <= 8) { - ibuf_depth = 24; - } - else { - ibuf_depth = depth; - } - - bmp = mem + pixel_data_offset; - -#if 0 - printf("palette_offset: %d, x: %d y: %d, depth: %d\n", palette_offset, x, y, depth); -#endif - - if (flags & IB_test) { - ibuf = IMB_allocImBuf(x, y, ibuf_depth, 0); - } - else { - ibuf = IMB_allocImBuf(x, y, ibuf_depth, IB_rect); - if (!ibuf) { - return NULL; - } - - rect = (uchar *)ibuf->rect; - - if (depth <= 8) { - const char(*palette)[4] = (const char(*)[4])(mem + palette_offset); - const int startmask = ((1 << depth) - 1) << 8; - for (size_t i = y; i > 0; i--) { - int bitoffs = 8; - int bitmask = startmask; - int nbytes = 0; - const char *pcol; - if (top_to_bottom) { - rect = (uchar *)&ibuf->rect[(i - 1) * x]; - } - for (size_t j = x; j > 0; j--) { - bitoffs -= depth; - bitmask >>= depth; - const int index = (bmp[0] & bitmask) >> bitoffs; - pcol = palette[index]; - /* intentionally BGR -> RGB */ - rect[0] = pcol[2]; - rect[1] = pcol[1]; - rect[2] = pcol[0]; - - rect[3] = 255; - rect += 4; - if (bitoffs == 0) { - /* Advance to the next byte */ - bitoffs = 8; - bitmask = startmask; - nbytes += 1; - bmp += 1; - } - } - /* Advance to the next row */ - bmp += (row_size_in_bytes - nbytes); - } - } - else if (depth == 16) { - for (size_t i = y; i > 0; i--) { - if (top_to_bottom) { - rect = (uchar *)&ibuf->rect[(i - 1) * x]; - } - for (size_t j = x; j > 0; j--) { - col = bmp[0] + (bmp[1] << 8); - rect[0] = ((col >> 10) & 0x1f) << 3; - rect[1] = ((col >> 5) & 0x1f) << 3; - rect[2] = ((col >> 0) & 0x1f) << 3; - - rect[3] = 255; - rect += 4; - bmp += 2; - } - } - } - else if (depth == 24) { - const int x_pad = x % 4; - for (size_t i = y; i > 0; i--) { - if (top_to_bottom) { - rect = (uchar *)&ibuf->rect[(i - 1) * x]; - } - for (size_t j = x; j > 0; j--) { - rect[0] = bmp[2]; - rect[1] = bmp[1]; - rect[2] = bmp[0]; - - rect[3] = 255; - rect += 4; - bmp += 3; - } - /* for 24-bit images, rows are padded to multiples of 4 */ - bmp += x_pad; - } - } - else if (depth == 32) { - for (size_t i = y; i > 0; i--) { - if (top_to_bottom) { - rect = (uchar *)&ibuf->rect[(i - 1) * x]; - } - for (size_t j = x; j > 0; j--) { - rect[0] = bmp[2]; - rect[1] = bmp[1]; - rect[2] = bmp[0]; - rect[3] = bmp[3]; - rect += 4; - bmp += 4; - } - } - } - } - - if (ibuf) { - ibuf->ppm[0] = xppm; - ibuf->ppm[1] = yppm; - ibuf->ftype = IMB_FTYPE_BMP; - } - - return ibuf; -} - -#undef CHECK_HEADER_FIELD_BMP -#undef CHECK_HEADER_FIELD - -/* Couple of helper functions for writing our data */ -static int putIntLSB(uint ui, FILE *ofile) -{ - putc((ui >> 0) & 0xFF, ofile); - putc((ui >> 8) & 0xFF, ofile); - putc((ui >> 16) & 0xFF, ofile); - return putc((ui >> 24) & 0xFF, ofile); -} - -static int putShortLSB(ushort us, FILE *ofile) -{ - putc((us >> 0) & 0xFF, ofile); - return putc((us >> 8) & 0xFF, ofile); -} - -bool imb_savebmp(ImBuf *ibuf, const char *filepath, int UNUSED(flags)) -{ - BMPINFOHEADER infoheader; - - const size_t bytes_per_pixel = (ibuf->planes + 7) >> 3; - BLI_assert(ELEM(bytes_per_pixel, 1, 3)); - - const size_t pad_bytes_per_scanline = (4 - ibuf->x * bytes_per_pixel % 4) % 4; - const size_t bytesize = (ibuf->x * bytes_per_pixel + pad_bytes_per_scanline) * ibuf->y; - - const uchar *data = (const uchar *)ibuf->rect; - FILE *ofile = BLI_fopen(filepath, "wb"); - if (ofile == NULL) { - return 0; - } - - const bool is_grayscale = bytes_per_pixel == 1; - const size_t palette_size = is_grayscale ? 255 * 4 : 0; /* RGBA32 */ - const size_t pixel_array_start = BMP_FILEHEADER_SIZE + sizeof(infoheader) + palette_size; - - putShortLSB(19778, ofile); /* "BM" */ - putIntLSB(bytesize + pixel_array_start, ofile); /* Total file size */ - putShortLSB(0, ofile); /* Res1 */ - putShortLSB(0, ofile); /* Res2 */ - putIntLSB(pixel_array_start, ofile); /* offset to start of pixel array */ - - putIntLSB(sizeof(infoheader), ofile); - putIntLSB(ibuf->x, ofile); - putIntLSB(ibuf->y, ofile); - putShortLSB(1, ofile); - putShortLSB(is_grayscale ? 8 : 24, ofile); - putIntLSB(0, ofile); - putIntLSB(bytesize, ofile); - putIntLSB(round(ibuf->ppm[0]), ofile); - putIntLSB(round(ibuf->ppm[1]), ofile); - putIntLSB(0, ofile); - putIntLSB(0, ofile); - - /* color palette table, which is just every grayscale color, full alpha */ - if (is_grayscale) { - for (char i = 0; i < 255; i++) { - putc(i, ofile); - putc(i, ofile); - putc(i, ofile); - putc(0xFF, ofile); - } - } - - if (is_grayscale) { - for (size_t y = 0; y < ibuf->y; y++) { - for (size_t x = 0; x < ibuf->x; x++) { - const size_t ptr = (x + y * ibuf->x) * 4; - if (putc(data[ptr], ofile) == EOF) { - return 0; - } - } - /* Add padding here. */ - for (size_t t = 0; t < pad_bytes_per_scanline; t++) { - if (putc(0, ofile) == EOF) { - return 0; - } - } - } - } - else { - /* Need to write out padded image data in BGR format. */ - for (size_t y = 0; y < ibuf->y; y++) { - for (size_t x = 0; x < ibuf->x; x++) { - const size_t ptr = (x + y * ibuf->x) * 4; - if (putc(data[ptr + 2], ofile) == EOF) { - return 0; - } - if (putc(data[ptr + 1], ofile) == EOF) { - return 0; - } - if (putc(data[ptr], ofile) == EOF) { - return 0; - } - } - /* Add padding here. */ - for (size_t t = 0; t < pad_bytes_per_scanline; t++) { - if (putc(0, ofile) == EOF) { - return 0; - } - } - } - } - - fflush(ofile); - fclose(ofile); - return 1; -} diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c index 3bff8184b19..e6ee1144ff7 100644 --- a/source/blender/imbuf/intern/cineon/cineon_dpx.c +++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c @@ -182,21 +182,3 @@ ImBuf *imb_load_cineon(const uchar *mem, size_t size, int flags, char colorspace } return imb_load_dpx_cineon(mem, size, 1, flags, colorspace); } - -bool imb_save_dpx(struct ImBuf *buf, const char *filepath, int flags) -{ - return imb_save_dpx_cineon(buf, filepath, 0, flags); -} - -bool imb_is_a_dpx(const uchar *buf, size_t size) -{ - return logImageIsDpx(buf, size); -} - -ImBuf *imb_load_dpx(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) -{ - if (!imb_is_a_dpx(mem, size)) { - return NULL; - } - return imb_load_dpx_cineon(mem, size, 0, flags, colorspace); -} diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c index aef1088efd4..fd62ee087d8 100644 --- a/source/blender/imbuf/intern/filetype.c +++ b/source/blender/imbuf/intern/filetype.c @@ -20,10 +20,6 @@ # include "openexr/openexr_api.h" #endif -#ifdef WITH_DDS -# include "dds/dds_api.h" -#endif - const ImFileType IMB_FILE_TYPES[] = { { .init = NULL, @@ -41,10 +37,10 @@ const ImFileType IMB_FILE_TYPES[] = { .init = NULL, .exit = NULL, .is_a = imb_is_a_png, - .load = imb_loadpng, + .load = imb_load_png, .load_filepath = NULL, .load_filepath_thumbnail = NULL, - .save = imb_savepng, + .save = imb_save_png, .flag = 0, .filetype = IMB_FTYPE_PNG, .default_save_role = COLOR_ROLE_DEFAULT_BYTE, @@ -53,10 +49,10 @@ const ImFileType IMB_FILE_TYPES[] = { .init = NULL, .exit = NULL, .is_a = imb_is_a_bmp, - .load = imb_bmp_decode, + .load = imb_load_bmp, .load_filepath = NULL, .load_filepath_thumbnail = NULL, - .save = imb_savebmp, + .save = imb_save_bmp, .flag = 0, .filetype = IMB_FTYPE_BMP, .default_save_role = COLOR_ROLE_DEFAULT_BYTE, @@ -64,11 +60,11 @@ const ImFileType IMB_FILE_TYPES[] = { { .init = NULL, .exit = NULL, - .is_a = imb_is_a_targa, - .load = imb_loadtarga, + .is_a = imb_is_a_tga, + .load = imb_load_tga, .load_filepath = NULL, .load_filepath_thumbnail = NULL, - .save = imb_savetarga, + .save = imb_save_tga, .flag = 0, .filetype = IMB_FTYPE_TGA, .default_save_role = COLOR_ROLE_DEFAULT_BYTE, @@ -85,7 +81,6 @@ const ImFileType IMB_FILE_TYPES[] = { .filetype = IMB_FTYPE_IMAGIC, .default_save_role = COLOR_ROLE_DEFAULT_BYTE, }, -#ifdef WITH_CINEON { .init = NULL, .exit = NULL, @@ -98,6 +93,7 @@ const ImFileType IMB_FILE_TYPES[] = { .filetype = IMB_FTYPE_DPX, .default_save_role = COLOR_ROLE_DEFAULT_FLOAT, }, +#ifdef WITH_CINEON { .init = NULL, .exit = NULL, @@ -111,34 +107,30 @@ const ImFileType IMB_FILE_TYPES[] = { .default_save_role = COLOR_ROLE_DEFAULT_FLOAT, }, #endif -#ifdef WITH_TIFF { - .init = imb_inittiff, + .init = NULL, .exit = NULL, .is_a = imb_is_a_tiff, - .load = imb_loadtiff, + .load = imb_load_tiff, .load_filepath = NULL, .load_filepath_thumbnail = NULL, - .save = imb_savetiff, + .save = imb_save_tiff, .flag = 0, .filetype = IMB_FTYPE_TIF, .default_save_role = COLOR_ROLE_DEFAULT_BYTE, }, -#endif -#ifdef WITH_HDR { .init = NULL, .exit = NULL, .is_a = imb_is_a_hdr, - .load = imb_loadhdr, + .load = imb_load_hdr, .load_filepath = NULL, .load_filepath_thumbnail = NULL, - .save = imb_savehdr, + .save = imb_save_hdr, .flag = IM_FTYPE_FLOAT, .filetype = IMB_FTYPE_RADHDR, .default_save_role = COLOR_ROLE_DEFAULT_FLOAT, }, -#endif #ifdef WITH_OPENEXR { .init = imb_initopenexr, @@ -167,7 +159,6 @@ const ImFileType IMB_FILE_TYPES[] = { .default_save_role = COLOR_ROLE_DEFAULT_BYTE, }, #endif -#ifdef WITH_DDS { .init = NULL, .exit = NULL, @@ -180,7 +171,6 @@ const ImFileType IMB_FILE_TYPES[] = { .filetype = IMB_FTYPE_DDS, .default_save_role = COLOR_ROLE_DEFAULT_BYTE, }, -#endif { .init = NULL, .exit = NULL, diff --git a/source/blender/imbuf/intern/format_bmp.cc b/source/blender/imbuf/intern/format_bmp.cc new file mode 100644 index 00000000000..b0a66e3a605 --- /dev/null +++ b/source/blender/imbuf/intern/format_bmp.cc @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "oiio/openimageio_support.hh" + +#include "IMB_filetype.h" +#include "IMB_imbuf_types.h" + +OIIO_NAMESPACE_USING +using namespace blender::imbuf; + +extern "C" { + +bool imb_is_a_bmp(const uchar *mem, size_t size) +{ + return imb_oiio_check(mem, size, "bmp"); +} + +ImBuf *imb_load_bmp(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +{ + ImageSpec config, spec; + + /* Keep historical behavior - do not use a 1-channel format for a black-white image. */ + config.attribute("bmp:monochrome_detect", 0); + + ReadContext ctx{mem, size, "bmp", IMB_FTYPE_BMP, flags}; + return imb_oiio_read(ctx, config, colorspace, spec); +} + +bool imb_save_bmp(struct ImBuf *ibuf, const char *filepath, int flags) +{ + const int file_channels = ibuf->planes >> 3; + const TypeDesc data_format = TypeDesc::UINT8; + + WriteContext ctx = imb_create_write_context("bmp", ibuf, flags, false); + ImageSpec file_spec = imb_create_write_spec(ctx, file_channels, data_format); + + return imb_oiio_write(ctx, filepath, file_spec); +} +} diff --git a/source/blender/imbuf/intern/format_dds.cc b/source/blender/imbuf/intern/format_dds.cc new file mode 100644 index 00000000000..dbebf93dd3c --- /dev/null +++ b/source/blender/imbuf/intern/format_dds.cc @@ -0,0 +1,319 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later AND BSD-3-Clause + * Copyright 2009 Google Inc. All rights reserved. (BSD-3-Clause) + * Copyright 2023 Blender Foundation (GPL-2.0-or-later). */ + +/** + * Some portions of this file are from the Chromium project and have been adapted + * for Blender use when flipping DDS images to the OpenGL convention. + */ + +#include +#include + +#include "oiio/openimageio_support.hh" + +#include "IMB_filetype.h" +#include "IMB_imbuf_types.h" + +#ifdef __BIG_ENDIAN__ +# include "BLI_endian_switch.h" +#endif + +OIIO_NAMESPACE_USING +using namespace blender::imbuf; + +using std::unique_ptr; + +extern "C" { + +static void LoadDXTCImage(ImBuf *ibuf, Filesystem::IOMemReader &mem_reader); + +bool imb_is_a_dds(const uchar *buf, size_t size) +{ + return imb_oiio_check(buf, size, "dds"); +} + +ImBuf *imb_load_dds(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +{ + ImageSpec config, spec; + ReadContext ctx{mem, size, "dds", IMB_FTYPE_DDS, flags}; + + ImBuf *ibuf = imb_oiio_read(ctx, config, colorspace, spec); + + /* Load compressed DDS information if available. */ + if (ibuf && (flags & IB_test) == 0) { + Filesystem::IOMemReader mem_reader(cspan(mem, size)); + LoadDXTCImage(ibuf, mem_reader); + } + + return ibuf; +} + +/* A function that flips a DXTC block. */ +using FlipBlockFunction = void (*)(uint8_t *block); + +/* Flips a full DXT1 block in the y direction. */ +static void FlipDXT1BlockFull(uint8_t *block) +{ + /* A DXT1 block layout is: + * [0-1] color0. + * [2-3] color1. + * [4-7] color bitmap, 2 bits per pixel. + * So each of the 4-7 bytes represents one line, flipping a block is just + * flipping those bytes. */ + uint8_t tmp = block[4]; + block[4] = block[7]; + block[7] = tmp; + tmp = block[5]; + block[5] = block[6]; + block[6] = tmp; +} + +/* Flips the first 2 lines of a DXT1 block in the y direction. */ +static void FlipDXT1BlockHalf(uint8_t *block) +{ + /* See layout above. */ + uint8_t tmp = block[4]; + block[4] = block[5]; + block[5] = tmp; +} + +/* Flips a full DXT3 block in the y direction. */ +static void FlipDXT3BlockFull(uint8_t *block) +{ + /* A DXT3 block layout is: + * [0-7] alpha bitmap, 4 bits per pixel. + * [8-15] a DXT1 block. */ + + /* We can flip the alpha bits at the byte level (2 bytes per line). */ + uint8_t tmp = block[0]; + + block[0] = block[6]; + block[6] = tmp; + tmp = block[1]; + block[1] = block[7]; + block[7] = tmp; + tmp = block[2]; + block[2] = block[4]; + block[4] = tmp; + tmp = block[3]; + block[3] = block[5]; + block[5] = tmp; + + /* And flip the DXT1 block using the above function. */ + FlipDXT1BlockFull(block + 8); +} + +/* Flips the first 2 lines of a DXT3 block in the y direction. */ +static void FlipDXT3BlockHalf(uint8_t *block) +{ + /* See layout above. */ + uint8_t tmp = block[0]; + + block[0] = block[2]; + block[2] = tmp; + tmp = block[1]; + block[1] = block[3]; + block[3] = tmp; + FlipDXT1BlockHalf(block + 8); +} + +/* Flips a full DXT5 block in the y direction. */ +static void FlipDXT5BlockFull(uint8_t *block) +{ + /* A DXT5 block layout is: + * [0] alpha0. + * [1] alpha1. + * [2-7] alpha bitmap, 3 bits per pixel. + * [8-15] a DXT1 block. */ + + /* The alpha bitmap doesn't easily map lines to bytes, so we have to + * interpret it correctly. Extracted from + * http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt : + * + * The 6 "bits" bytes of the block are decoded into one 48-bit integer: + * + * bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 + + * 256 * (bits_4 + 256 * bits_5)))) + * + * bits is a 48-bit unsigned-integer, from which a three-bit control code + * is extracted for a texel at location (x,y) in the block using: + * + * code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0] + * + * where bit 47 is the most significant and bit 0 is the least + * significant bit. */ + uint line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]); + uint line_2_3 = block[5] + 256 * (block[6] + 256 * block[7]); + /* swap lines 0 and 1 in line_0_1. */ + uint line_1_0 = ((line_0_1 & 0x000fff) << 12) | ((line_0_1 & 0xfff000) >> 12); + /* swap lines 2 and 3 in line_2_3. */ + uint line_3_2 = ((line_2_3 & 0x000fff) << 12) | ((line_2_3 & 0xfff000) >> 12); + + block[2] = line_3_2 & 0xff; + block[3] = (line_3_2 & 0xff00) >> 8; + block[4] = (line_3_2 & 0xff0000) >> 16; + block[5] = line_1_0 & 0xff; + block[6] = (line_1_0 & 0xff00) >> 8; + block[7] = (line_1_0 & 0xff0000) >> 16; + + /* And flip the DXT1 block using the above function. */ + FlipDXT1BlockFull(block + 8); +} + +/* Flips the first 2 lines of a DXT5 block in the y direction. */ +static void FlipDXT5BlockHalf(uint8_t *block) +{ + /* See layout above. */ + uint line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]); + uint line_1_0 = ((line_0_1 & 0x000fff) << 12) | ((line_0_1 & 0xfff000) >> 12); + block[2] = line_1_0 & 0xff; + block[3] = (line_1_0 & 0xff00) >> 8; + block[4] = (line_1_0 & 0xff0000) >> 16; + FlipDXT1BlockHalf(block + 8); +} + +/** + * Flips a DXTC image, by flipping and swapping DXTC blocks as appropriate. + * + * Use to flip vertically to fit OpenGL convention. + */ +static void FlipDXTCImage(ImBuf *ibuf) +{ + uint32_t width = ibuf->x; + uint32_t height = ibuf->y; + uint32_t levels = ibuf->dds_data.nummipmaps; + int fourcc = ibuf->dds_data.fourcc; + uint8_t *data = ibuf->dds_data.data; + int data_size = ibuf->dds_data.size; + + uint32_t *num_valid_levels = &ibuf->dds_data.nummipmaps; + *num_valid_levels = 0; + + /* Must have valid dimensions. */ + if (width == 0 || height == 0) { + return; + } + /* Height must be a power-of-two. */ + if ((height & (height - 1)) != 0) { + return; + } + + FlipBlockFunction full_block_function; + FlipBlockFunction half_block_function; + uint block_bytes = 0; + + switch (fourcc) { + case FOURCC_DXT1: + full_block_function = FlipDXT1BlockFull; + half_block_function = FlipDXT1BlockHalf; + block_bytes = 8; + break; + case FOURCC_DXT3: + full_block_function = FlipDXT3BlockFull; + half_block_function = FlipDXT3BlockHalf; + block_bytes = 16; + break; + case FOURCC_DXT5: + full_block_function = FlipDXT5BlockFull; + half_block_function = FlipDXT5BlockHalf; + block_bytes = 16; + break; + default: + return; + } + + *num_valid_levels = levels; + + uint mip_width = width; + uint mip_height = height; + + const uint8_t *data_end = data + data_size; + + for (uint i = 0; i < levels; i++) { + uint blocks_per_row = (mip_width + 3) / 4; + uint blocks_per_col = (mip_height + 3) / 4; + uint blocks = blocks_per_row * blocks_per_col; + + if (data + block_bytes * blocks > data_end) { + /* Stop flipping when running out of data to be modified, avoiding possible buffer overrun + * on a malformed files. */ + *num_valid_levels = i; + break; + } + + if (mip_height == 1) { + /* no flip to do, and we're done. */ + break; + } + if (mip_height == 2) { + /* flip the first 2 lines in each block. */ + for (uint i = 0; i < blocks_per_row; i++) { + half_block_function(data + i * block_bytes); + } + } + else { + /* flip each block. */ + for (uint i = 0; i < blocks; i++) { + full_block_function(data + i * block_bytes); + } + + /* Swap each block line in the first half of the image with the + * corresponding one in the second half. + * note that this is a no-op if mip_height is 4. */ + uint row_bytes = block_bytes * blocks_per_row; + uint8_t *temp_line = new uint8_t[row_bytes]; + + for (uint y = 0; y < blocks_per_col / 2; y++) { + uint8_t *line1 = data + y * row_bytes; + uint8_t *line2 = data + (blocks_per_col - y - 1) * row_bytes; + + memcpy(temp_line, line1, row_bytes); + memcpy(line1, line2, row_bytes); + memcpy(line2, temp_line, row_bytes); + } + + delete[] temp_line; + } + + /* mip levels are contiguous. */ + data += block_bytes * blocks; + mip_width = std::max(1U, mip_width >> 1); + mip_height = std::max(1U, mip_height >> 1); + } +} + +static void LoadDXTCImage(ImBuf *ibuf, Filesystem::IOMemReader &mem_reader) +{ + /* Reach into memory and pull out the pixel format flags and mipmap counts. This is safe if + * we've made it this far. */ + uint32_t flags = 0; + mem_reader.pread(&flags, sizeof(uint32_t), 8); + mem_reader.pread(&ibuf->dds_data.nummipmaps, sizeof(uint32_t), 28); + mem_reader.pread(&ibuf->dds_data.fourcc, sizeof(uint32_t), 84); + +#ifdef __BIG_ENDIAN__ + BLI_endian_switch_uint32(&ibuf->dds_data.nummipmaps); +#endif + + const uint32_t DDSD_MIPMAPCOUNT = 0x00020000U; + if ((flags & DDSD_MIPMAPCOUNT) == 0) { + ibuf->dds_data.nummipmaps = 1; + } + + /* Load the compressed data. */ + if (ibuf->dds_data.fourcc != FOURCC_DDS) { + uint32_t dds_header_size = 128; + if (ibuf->dds_data.fourcc == FOURCC_DX10) { + dds_header_size += 20; + } + + ibuf->dds_data.size = mem_reader.size() - dds_header_size; + ibuf->dds_data.data = (uchar *)malloc(ibuf->dds_data.size); + mem_reader.pread(ibuf->dds_data.data, ibuf->dds_data.size, dds_header_size); + + /* Flip compressed image data to match OpenGL convention. */ + FlipDXTCImage(ibuf); + } +} +} diff --git a/source/blender/imbuf/intern/format_dpx.cc b/source/blender/imbuf/intern/format_dpx.cc new file mode 100644 index 00000000000..f8a09e581a9 --- /dev/null +++ b/source/blender/imbuf/intern/format_dpx.cc @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "oiio/openimageio_support.hh" + +#include "IMB_colormanagement.h" +#include "IMB_filetype.h" +#include "IMB_imbuf_types.h" + +OIIO_NAMESPACE_USING +using namespace blender::imbuf; + +extern "C" { +bool imb_is_a_dpx(const uchar *mem, size_t size) +{ + return imb_oiio_check(mem, size, "dpx"); +} + +ImBuf *imb_load_dpx(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +{ + ImageSpec config, spec; + + ReadContext ctx{mem, size, "dpx", IMB_FTYPE_DPX, flags}; + + ctx.use_colorspace_role = COLOR_ROLE_DEFAULT_FLOAT; + + ImBuf *ibuf = imb_oiio_read(ctx, config, colorspace, spec); + if (ibuf) { + if (flags & IB_alphamode_detect) { + ibuf->flags |= IB_alphamode_premul; + } + } + + return ibuf; +} + +bool imb_save_dpx(struct ImBuf *ibuf, const char *filepath, int flags) +{ + int bits_per_sample = 8; + if (ibuf->foptions.flag & CINEON_10BIT) { + bits_per_sample = 10; + } + else if (ibuf->foptions.flag & CINEON_12BIT) { + bits_per_sample = 12; + } + else if (ibuf->foptions.flag & CINEON_16BIT) { + bits_per_sample = 16; + } + + const int file_channels = ibuf->planes >> 3; + const TypeDesc data_format = bits_per_sample == 8 ? TypeDesc::UINT8 : TypeDesc::UINT16; + + WriteContext ctx = imb_create_write_context("dpx", ibuf, flags); + ImageSpec file_spec = imb_create_write_spec(ctx, file_channels, data_format); + + const float max_value = powf(2, bits_per_sample) - 1.0f; + file_spec.attribute("oiio:BitsPerSample", bits_per_sample); + file_spec.attribute("dpx:WhiteLevel", 685.0f / 1023.0f * max_value); + file_spec.attribute("dpx:BlackLevel", 95.0f / 1023.0f * max_value); + file_spec.attribute("dpx:HighData", max_value); + file_spec.attribute("dpx:LowData", 0); + file_spec.attribute("dpx:LowQuantity", 0.0f); + + if (ibuf->foptions.flag & CINEON_LOG) { + /* VERIFY: This matches previous code but seems odd. Needs a comment if confirmed. */ + file_spec.attribute("dpx:Transfer", "Printing density"); + file_spec.attribute("dpx:HighQuantity", 2.048f); + } + else { + file_spec.attribute("dpx:Transfer", "Linear"); + file_spec.attribute("dpx:HighQuantity", max_value); + } + + if (ELEM(bits_per_sample, 8, 16)) { + file_spec.attribute("dpx:Packing", "Packed"); + } + else { + file_spec.attribute("dpx:Packing", "Filled, method A"); + } + + return imb_oiio_write(ctx, filepath, file_spec); +} +} diff --git a/source/blender/imbuf/intern/format_hdr.cc b/source/blender/imbuf/intern/format_hdr.cc new file mode 100644 index 00000000000..3378247361c --- /dev/null +++ b/source/blender/imbuf/intern/format_hdr.cc @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "oiio/openimageio_support.hh" + +#include "IMB_filetype.h" +#include "IMB_imbuf_types.h" + +OIIO_NAMESPACE_USING +using namespace blender::imbuf; + +extern "C" { + +bool imb_is_a_hdr(const uchar *mem, size_t size) +{ + return imb_oiio_check(mem, size, "hdr"); +} + +ImBuf *imb_load_hdr(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +{ + ImageSpec config, spec; + + ReadContext ctx{mem, size, "hdr", IMB_FTYPE_RADHDR, flags}; + + /* Always create ImBufs with a 4th alpha channel despite the format only supporting 3. */ + ctx.use_all_planes = true; + + ImBuf *ibuf = imb_oiio_read(ctx, config, colorspace, spec); + if (ibuf) { + if (flags & IB_alphamode_detect) { + ibuf->flags |= IB_alphamode_premul; + } + if (flags & IB_rect) { + IMB_rect_from_float(ibuf); + } + } + + return ibuf; +} + +bool imb_save_hdr(struct ImBuf *ibuf, const char *filepath, int flags) +{ + const int file_channels = 3; + const TypeDesc data_format = TypeDesc::FLOAT; + + WriteContext ctx = imb_create_write_context("hdr", ibuf, flags); + ImageSpec file_spec = imb_create_write_spec(ctx, file_channels, data_format); + + return imb_oiio_write(ctx, filepath, file_spec); +} +} diff --git a/source/blender/imbuf/intern/format_png.cc b/source/blender/imbuf/intern/format_png.cc new file mode 100644 index 00000000000..c00b7057588 --- /dev/null +++ b/source/blender/imbuf/intern/format_png.cc @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "oiio/openimageio_support.hh" + +#include "IMB_colormanagement.h" +#include "IMB_filetype.h" +#include "IMB_imbuf_types.h" + +OIIO_NAMESPACE_USING +using namespace blender::imbuf; + +extern "C" { + +bool imb_is_a_png(const uchar *mem, size_t size) +{ + return imb_oiio_check(mem, size, "png"); +} + +ImBuf *imb_load_png(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +{ + ImageSpec config, spec; + config.attribute("oiio:UnassociatedAlpha", 1); + + ReadContext ctx{mem, size, "png", IMB_FTYPE_PNG, flags}; + + /* Both 8 and 16 bit PNGs should be in default byte colorspace. */ + ctx.use_colorspace_role = COLOR_ROLE_DEFAULT_BYTE; + + ImBuf *ibuf = imb_oiio_read(ctx, config, colorspace, spec); + if (ibuf) { + if (spec.format == TypeDesc::UINT16) { + ibuf->flags |= PNG_16BIT; + } + } + + return ibuf; +} + +bool imb_save_png(struct ImBuf *ibuf, const char *filepath, int flags) +{ + const bool is_16bit = (ibuf->foptions.flag & PNG_16BIT); + const int file_channels = ibuf->planes >> 3; + const TypeDesc data_format = is_16bit ? TypeDesc::UINT16 : TypeDesc::UINT8; + + WriteContext ctx = imb_create_write_context("png", ibuf, flags, is_16bit); + ImageSpec file_spec = imb_create_write_spec(ctx, file_channels, data_format); + + /* Skip if the float buffer was managed already. */ + if (is_16bit && (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA))) { + file_spec.attribute("oiio:UnassociatedAlpha", 0); + } + else { + file_spec.attribute("oiio:UnassociatedAlpha", 1); + } + + int compression = (int)((float)ibuf->foptions.quality / 11.1111f); + compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression); + file_spec.attribute("png:compressionLevel", compression); + + return imb_oiio_write(ctx, filepath, file_spec); +} +} diff --git a/source/blender/imbuf/intern/format_targa.cc b/source/blender/imbuf/intern/format_targa.cc new file mode 100644 index 00000000000..f2b2f0dc617 --- /dev/null +++ b/source/blender/imbuf/intern/format_targa.cc @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "oiio/openimageio_support.hh" + +#include "IMB_filetype.h" +#include "IMB_imbuf_types.h" + +OIIO_NAMESPACE_USING +using namespace blender::imbuf; + +extern "C" { + +bool imb_is_a_tga(const uchar *mem, size_t size) +{ + return imb_oiio_check(mem, size, "tga"); +} + +ImBuf *imb_load_tga(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +{ + ImageSpec config, spec; + config.attribute("oiio:UnassociatedAlpha", 1); + + ReadContext ctx{mem, size, "tga", IMB_FTYPE_TGA, flags}; + return imb_oiio_read(ctx, config, colorspace, spec); +} + +bool imb_save_tga(struct ImBuf *ibuf, const char *filepath, int flags) +{ + const int file_channels = ibuf->planes >> 3; + const TypeDesc data_format = TypeDesc::UINT8; + + WriteContext ctx = imb_create_write_context("tga", ibuf, flags, false); + ImageSpec file_spec = imb_create_write_spec(ctx, file_channels, data_format); + file_spec.attribute("oiio:UnassociatedAlpha", 1); + file_spec.attribute("compression", (ibuf->foptions.flag & RAWTGA) ? "none" : "rle"); + + return imb_oiio_write(ctx, filepath, file_spec); +} +} diff --git a/source/blender/imbuf/intern/format_tiff.cc b/source/blender/imbuf/intern/format_tiff.cc new file mode 100644 index 00000000000..b779e3973de --- /dev/null +++ b/source/blender/imbuf/intern/format_tiff.cc @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "oiio/openimageio_support.hh" + +#include "IMB_colormanagement.h" +#include "IMB_filetype.h" +#include "IMB_imbuf_types.h" + +OIIO_NAMESPACE_USING +using namespace blender::imbuf; + +extern "C" { + +bool imb_is_a_tiff(const uchar *mem, size_t size) +{ + return imb_oiio_check(mem, size, "tif"); +} + +ImBuf *imb_load_tiff(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +{ + ImageSpec config, spec; + config.attribute("oiio:UnassociatedAlpha", 1); + + ReadContext ctx{mem, size, "tif", IMB_FTYPE_TIF, flags}; + + /* All TIFFs should be in default byte colorspace. */ + ctx.use_colorspace_role = COLOR_ROLE_DEFAULT_BYTE; + + ImBuf *ibuf = imb_oiio_read(ctx, config, colorspace, spec); + if (ibuf) { + if (flags & IB_alphamode_detect) { + if (spec.nchannels == 4 && spec.format == TypeDesc::UINT16) { + ibuf->flags |= IB_alphamode_premul; + } + } + } + + return ibuf; +} + +bool imb_save_tiff(struct ImBuf *ibuf, const char *filepath, int flags) +{ + const bool is_16bit = ((ibuf->foptions.flag & TIF_16BIT) && ibuf->rect_float); + const int file_channels = ibuf->planes >> 3; + const TypeDesc data_format = is_16bit ? TypeDesc::UINT16 : TypeDesc::UINT8; + + WriteContext ctx = imb_create_write_context("tif", ibuf, flags, is_16bit); + ImageSpec file_spec = imb_create_write_spec(ctx, file_channels, data_format); + + if (is_16bit && file_channels == 4) { + file_spec.attribute("oiio:UnassociatedAlpha", 0); + } + else { + file_spec.attribute("oiio:UnassociatedAlpha", 1); + } + + if (ibuf->foptions.flag & TIF_COMPRESS_DEFLATE) { + file_spec.attribute("compression", "zip"); + } + else if (ibuf->foptions.flag & TIF_COMPRESS_LZW) { + file_spec.attribute("compression", "lzw"); + } + else if (ibuf->foptions.flag & TIF_COMPRESS_PACKBITS) { + file_spec.attribute("compression", "packbits"); + } + + return imb_oiio_write(ctx, filepath, file_spec); +} +} diff --git a/source/blender/imbuf/intern/oiio/openimageio_support.cc b/source/blender/imbuf/intern/oiio/openimageio_support.cc index 6be6d94ae0d..b1395cefddd 100644 --- a/source/blender/imbuf/intern/oiio/openimageio_support.cc +++ b/source/blender/imbuf/intern/oiio/openimageio_support.cc @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "openimageio_support.hh" +#include +#include #include "BLI_blenlib.h" @@ -289,10 +291,19 @@ bool imb_oiio_write(const WriteContext &ctx, const char *filepath, const ImageSp return false; } - auto write_op = [&out, &ctx]() { - return out->write_image( - ctx.mem_format, ctx.mem_start, ctx.mem_xstride, -ctx.mem_ystride, AutoStride); - }; + ImageBuf orig_buf(ctx.mem_spec, ctx.mem_start, ctx.mem_xstride, -ctx.mem_ystride, AutoStride); + ImageBuf final_buf{}; + + /* Grayscale images need to be based on luminance weights rather than only + * using a single channel from the source. */ + if (file_spec.nchannels == 1) { + float weights[3]; + IMB_colormanagement_get_luminance_coefficients(weights); + ImageBufAlgo::channel_sum(final_buf, orig_buf, weights); + } + else { + final_buf = std::move(orig_buf); + } bool ok = false; if (ctx.flags & IB_mem) { @@ -302,11 +313,11 @@ bool imb_oiio_write(const WriteContext &ctx, const char *filepath, const ImageSp imb_addencodedbufferImBuf(ctx.ibuf); out->set_ioproxy(&writer); out->open("", file_spec); - ok = write_op(); + ok = final_buf.write(out.get()); } else { out->open(filepath, file_spec); - ok = write_op(); + ok = final_buf.write(out.get()); } out->close(); @@ -330,15 +341,15 @@ WriteContext imb_create_write_context(const char *file_format, const int mem_channels = ibuf->channels ? ibuf->channels : 4; ctx.mem_xstride = sizeof(float) * mem_channels; ctx.mem_ystride = width * ctx.mem_xstride; - ctx.mem_format = TypeDesc::FLOAT; ctx.mem_start = reinterpret_cast(ibuf->rect_float); + ctx.mem_spec = ImageSpec(width, height, mem_channels, TypeDesc::FLOAT); } else { const int mem_channels = 4; ctx.mem_xstride = sizeof(uchar) * mem_channels; ctx.mem_ystride = width * ctx.mem_xstride; - ctx.mem_format = TypeDesc::UINT8; ctx.mem_start = reinterpret_cast(ibuf->rect); + ctx.mem_spec = ImageSpec(width, height, mem_channels, TypeDesc::UINT8); } /* We always write using a negative y-stride so ensure we start at the end. */ diff --git a/source/blender/imbuf/intern/oiio/openimageio_support.hh b/source/blender/imbuf/intern/oiio/openimageio_support.hh index f6bf8bda9bc..0910910826a 100644 --- a/source/blender/imbuf/intern/oiio/openimageio_support.hh +++ b/source/blender/imbuf/intern/oiio/openimageio_support.hh @@ -40,13 +40,12 @@ struct ReadContext { struct WriteContext { const char *file_format; ImBuf *ibuf; + int flags; + uchar *mem_start; OIIO::stride_t mem_xstride; OIIO::stride_t mem_ystride; - OIIO::TypeDesc mem_format; - uchar *mem_start; - - int flags; + OIIO::ImageSpec mem_spec; }; /** diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c deleted file mode 100644 index 1736329cbff..00000000000 --- a/source/blender/imbuf/intern/png.c +++ /dev/null @@ -1,814 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2001-2002 NaN Holding BV. All rights reserved. */ - -/** \file - * \ingroup imbuf - * - * \todo Save floats as 16 bits per channel, currently readonly. - */ - -#include - -#include "BLI_fileops.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "BKE_global.h" -#include "BKE_idprop.h" - -#include "DNA_ID.h" /* ID property definitions. */ - -#include "MEM_guardedalloc.h" - -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "IMB_allocimbuf.h" -#include "IMB_filetype.h" -#include "IMB_metadata.h" - -#include "IMB_colormanagement.h" -#include "IMB_colormanagement_intern.h" - -typedef struct PNGReadStruct { - const uchar *data; - uint size; - uint seek; -} PNGReadStruct; - -static void ReadData(png_structp png_ptr, png_bytep data, png_size_t length); -static void WriteData(png_structp png_ptr, png_bytep data, png_size_t length); -static void Flush(png_structp png_ptr); - -BLI_INLINE ushort UPSAMPLE_8_TO_16(const uchar _val) -{ - return (_val << 8) + _val; -} - -bool imb_is_a_png(const uchar *mem, size_t size) -{ - const int num_to_check = 8; - if (size < num_to_check) { - return false; - } - bool ok = false; - -#if (PNG_LIBPNG_VER_MAJOR == 1) && (PNG_LIBPNG_VER_MINOR == 2) - /* Older version of libpng doesn't use const pointer to memory. */ - ok = !png_sig_cmp((png_bytep)mem, 0, num_to_check); -#else - ok = !png_sig_cmp(mem, 0, num_to_check); -#endif - return ok; -} - -static void Flush(png_structp png_ptr) -{ - (void)png_ptr; -} - -static void WriteData(png_structp png_ptr, png_bytep data, png_size_t length) -{ - ImBuf *ibuf = (ImBuf *)png_get_io_ptr(png_ptr); - - /* if buffer is too small increase it. */ - while (ibuf->encodedsize + length > ibuf->encodedbuffersize) { - imb_enlargeencodedbufferImBuf(ibuf); - } - - memcpy(ibuf->encodedbuffer + ibuf->encodedsize, data, length); - ibuf->encodedsize += length; -} - -static void ReadData(png_structp png_ptr, png_bytep data, png_size_t length) -{ - PNGReadStruct *rs = (PNGReadStruct *)png_get_io_ptr(png_ptr); - - if (rs) { - if (length <= rs->size - rs->seek) { - memcpy(data, rs->data + rs->seek, length); - rs->seek += length; - return; - } - } - - printf("Reached EOF while decoding PNG\n"); - longjmp(png_jmpbuf(png_ptr), 1); -} - -static float channel_colormanage_noop(float value) -{ - return value; -} - -/* wrap to avoid macro calling functions multiple times */ -BLI_INLINE ushort ftoshort(float val) -{ - return unit_float_to_ushort_clamp(val); -} - -bool imb_savepng(struct ImBuf *ibuf, const char *filepath, int flags) -{ - png_structp png_ptr; - png_infop info_ptr; - - uchar *pixels = NULL; - uchar *from, *to; - ushort *pixels16 = NULL, *to16; - float *from_float, from_straight[4]; - png_bytepp row_pointers = NULL; - int i, bytesperpixel, color_type = PNG_COLOR_TYPE_GRAY; - FILE *fp = NULL; - - bool is_16bit = (ibuf->foptions.flag & PNG_16BIT) != 0; - bool has_float = (ibuf->rect_float != NULL); - int channels_in_float = ibuf->channels ? ibuf->channels : 4; - - float (*chanel_colormanage_cb)(float); - size_t num_bytes; - - /* use the jpeg quality setting for compression */ - int compression; - compression = (int)((float)(ibuf->foptions.quality) / 11.1111f); - compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression); - - if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) { - /* float buffer was managed already, no need in color space conversion */ - chanel_colormanage_cb = channel_colormanage_noop; - } - else { - /* Standard linear-to-SRGB conversion if float buffer wasn't managed. */ - chanel_colormanage_cb = linearrgb_to_srgb; - } - - /* for prints */ - if (flags & IB_mem) { - filepath = ""; - } - - bytesperpixel = (ibuf->planes + 7) >> 3; - if ((bytesperpixel > 4) || (bytesperpixel == 2)) { - printf( - "imb_savepng: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, filepath); - return 0; - } - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (png_ptr == NULL) { - printf("imb_savepng: Cannot png_create_write_struct for file: '%s'\n", filepath); - return 0; - } - - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - printf("imb_savepng: Cannot png_create_info_struct for file: '%s'\n", filepath); - return 0; - } - - /* copy image data */ - num_bytes = ((size_t)ibuf->x) * ibuf->y * bytesperpixel; - if (is_16bit) { - pixels16 = MEM_mallocN(num_bytes * sizeof(ushort), "png 16bit pixels"); - } - else { - pixels = MEM_mallocN(num_bytes * sizeof(uchar), "png 8bit pixels"); - } - if (pixels == NULL && pixels16 == NULL) { - printf( - "imb_savepng: Cannot allocate pixels array of %dx%d, %d bytes per pixel for file: " - "'%s'\n", - ibuf->x, - ibuf->y, - bytesperpixel, - filepath); - } - - /* allocate memory for an array of row-pointers */ - row_pointers = (png_bytepp)MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers"); - if (row_pointers == NULL) { - printf("imb_savepng: Cannot allocate row-pointers array for file '%s'\n", filepath); - } - - if ((pixels == NULL && pixels16 == NULL) || (row_pointers == NULL) || - setjmp(png_jmpbuf(png_ptr))) { - /* On error jump here, and free any resources. */ - png_destroy_write_struct(&png_ptr, &info_ptr); - if (pixels) { - MEM_freeN(pixels); - } - if (pixels16) { - MEM_freeN(pixels16); - } - if (row_pointers) { - MEM_freeN(row_pointers); - } - if (fp) { - fflush(fp); - fclose(fp); - } - return 0; - } - - from = (uchar *)ibuf->rect; - to = pixels; - from_float = ibuf->rect_float; - to16 = pixels16; - - switch (bytesperpixel) { - case 4: - color_type = PNG_COLOR_TYPE_RGBA; - if (is_16bit) { - if (has_float) { - if (channels_in_float == 4) { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - premul_to_straight_v4_v4(from_straight, from_float); - to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0])); - to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1])); - to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2])); - to16[3] = ftoshort(chanel_colormanage_cb(from_straight[3])); - to16 += 4; - from_float += 4; - } - } - else if (channels_in_float == 3) { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - to16[0] = ftoshort(chanel_colormanage_cb(from_float[0])); - to16[1] = ftoshort(chanel_colormanage_cb(from_float[1])); - to16[2] = ftoshort(chanel_colormanage_cb(from_float[2])); - to16[3] = 65535; - to16 += 4; - from_float += 3; - } - } - else { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - to16[0] = ftoshort(chanel_colormanage_cb(from_float[0])); - to16[2] = to16[1] = to16[0]; - to16[3] = 65535; - to16 += 4; - from_float++; - } - } - } - else { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - to16[0] = UPSAMPLE_8_TO_16(from[0]); - to16[1] = UPSAMPLE_8_TO_16(from[1]); - to16[2] = UPSAMPLE_8_TO_16(from[2]); - to16[3] = UPSAMPLE_8_TO_16(from[3]); - to16 += 4; - from += 4; - } - } - } - else { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - to[0] = from[0]; - to[1] = from[1]; - to[2] = from[2]; - to[3] = from[3]; - to += 4; - from += 4; - } - } - break; - case 3: - color_type = PNG_COLOR_TYPE_RGB; - if (is_16bit) { - if (has_float) { - if (channels_in_float == 4) { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - premul_to_straight_v4_v4(from_straight, from_float); - to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0])); - to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1])); - to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2])); - to16 += 3; - from_float += 4; - } - } - else if (channels_in_float == 3) { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - to16[0] = ftoshort(chanel_colormanage_cb(from_float[0])); - to16[1] = ftoshort(chanel_colormanage_cb(from_float[1])); - to16[2] = ftoshort(chanel_colormanage_cb(from_float[2])); - to16 += 3; - from_float += 3; - } - } - else { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - to16[0] = ftoshort(chanel_colormanage_cb(from_float[0])); - to16[2] = to16[1] = to16[0]; - to16 += 3; - from_float++; - } - } - } - else { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - to16[0] = UPSAMPLE_8_TO_16(from[0]); - to16[1] = UPSAMPLE_8_TO_16(from[1]); - to16[2] = UPSAMPLE_8_TO_16(from[2]); - to16 += 3; - from += 4; - } - } - } - else { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - to[0] = from[0]; - to[1] = from[1]; - to[2] = from[2]; - to += 3; - from += 4; - } - } - break; - case 1: - color_type = PNG_COLOR_TYPE_GRAY; - if (is_16bit) { - if (has_float) { - float rgb[3]; - if (channels_in_float == 4) { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - premul_to_straight_v4_v4(from_straight, from_float); - rgb[0] = chanel_colormanage_cb(from_straight[0]); - rgb[1] = chanel_colormanage_cb(from_straight[1]); - rgb[2] = chanel_colormanage_cb(from_straight[2]); - to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb)); - to16++; - from_float += 4; - } - } - else if (channels_in_float == 3) { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - rgb[0] = chanel_colormanage_cb(from_float[0]); - rgb[1] = chanel_colormanage_cb(from_float[1]); - rgb[2] = chanel_colormanage_cb(from_float[2]); - to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb)); - to16++; - from_float += 3; - } - } - else { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - to16[0] = ftoshort(chanel_colormanage_cb(from_float[0])); - to16++; - from_float++; - } - } - } - else { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - to16[0] = UPSAMPLE_8_TO_16(from[0]); - to16++; - from += 4; - } - } - } - else { - for (i = ibuf->x * ibuf->y; i > 0; i--) { - to[0] = from[0]; - to++; - from += 4; - } - } - break; - } - - if (flags & IB_mem) { - /* create image in memory */ - imb_addencodedbufferImBuf(ibuf); - ibuf->encodedsize = 0; - - png_set_write_fn(png_ptr, (png_voidp)ibuf, WriteData, Flush); - } - else { - fp = BLI_fopen(filepath, "wb"); - if (!fp) { - png_destroy_write_struct(&png_ptr, &info_ptr); - if (pixels) { - MEM_freeN(pixels); - } - if (pixels16) { - MEM_freeN(pixels16); - } - MEM_freeN(row_pointers); - printf("imb_savepng: Cannot open file for writing: '%s'\n", filepath); - return 0; - } - png_init_io(png_ptr, fp); - } - -#if 0 - png_set_filter(png_ptr, - 0, - PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | - PNG_FILTER_UP | PNG_FILTER_VALUE_UP | PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG | - PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH | PNG_ALL_FILTERS); -#endif - - png_set_compression_level(png_ptr, compression); - - /* png image settings */ - png_set_IHDR(png_ptr, - info_ptr, - ibuf->x, - ibuf->y, - is_16bit ? 16 : 8, - color_type, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - - /* image text info */ - if (ibuf->metadata) { - png_text *metadata; - IDProperty *prop; - - int num_text = 0; - - for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) { - if (prop->type == IDP_STRING) { - num_text++; - } - } - - metadata = MEM_callocN(num_text * sizeof(png_text), "png_metadata"); - num_text = 0; - for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) { - if (prop->type == IDP_STRING) { - metadata[num_text].compression = PNG_TEXT_COMPRESSION_NONE; - metadata[num_text].key = prop->name; - metadata[num_text].text = IDP_String(prop); - num_text++; - } - } - - png_set_text(png_ptr, info_ptr, metadata, num_text); - MEM_freeN(metadata); - } - - if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) { - png_set_pHYs(png_ptr, - info_ptr, - (uint)(ibuf->ppm[0] + 0.5), - (uint)(ibuf->ppm[1] + 0.5), - PNG_RESOLUTION_METER); - } - - /* write the file header information */ - png_write_info(png_ptr, info_ptr); - -#ifdef __LITTLE_ENDIAN__ - png_set_swap(png_ptr); -#endif - - /* set the individual row-pointers to point at the correct offsets */ - if (is_16bit) { - for (i = 0; i < ibuf->y; i++) { - row_pointers[ibuf->y - 1 - i] = (png_bytep)((ushort *)pixels16 + - (((size_t)i) * ibuf->x) * bytesperpixel); - } - } - else { - for (i = 0; i < ibuf->y; i++) { - row_pointers[ibuf->y - 1 - i] = (png_bytep)((uchar *)pixels + (((size_t)i) * ibuf->x) * - bytesperpixel * - sizeof(uchar)); - } - } - - /* write out the entire image data in one call */ - png_write_image(png_ptr, row_pointers); - - /* write the additional chunks to the PNG file (not really needed) */ - png_write_end(png_ptr, info_ptr); - - /* clean up */ - if (pixels) { - MEM_freeN(pixels); - } - if (pixels16) { - MEM_freeN(pixels16); - } - MEM_freeN(row_pointers); - png_destroy_write_struct(&png_ptr, &info_ptr); - - if (fp) { - fflush(fp); - fclose(fp); - } - - return 1; -} - -static void imb_png_warning(png_structp UNUSED(png_ptr), png_const_charp message) -{ - /* We suppress iCCP warnings. That's how Blender always used to behave, - * and with new libpng it became too much picky, giving a warning on - * the splash screen even. - */ - if ((G.debug & G_DEBUG) == 0 && STRPREFIX(message, "iCCP")) { - return; - } - fprintf(stderr, "libpng warning: %s\n", message); -} - -static void imb_png_error(png_structp UNUSED(png_ptr), png_const_charp message) -{ - fprintf(stderr, "libpng error: %s\n", message); -} - -ImBuf *imb_loadpng(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) -{ - struct ImBuf *ibuf = NULL; - png_structp png_ptr; - png_infop info_ptr; - uchar *pixels = NULL; - ushort *pixels16 = NULL; - png_bytepp row_pointers = NULL; - png_uint_32 width, height; - int bit_depth, color_type; - PNGReadStruct ps; - - uchar *from, *to; - ushort *from16; - float *to_float; - uint channels; - - if (imb_is_a_png(mem, size) == 0) { - return NULL; - } - - /* both 8 and 16 bit PNGs are default to standard byte colorspace */ - colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); - - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (png_ptr == NULL) { - printf("Cannot png_create_read_struct\n"); - return NULL; - } - - png_set_error_fn(png_ptr, NULL, imb_png_error, imb_png_warning); - - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - printf("Cannot png_create_info_struct\n"); - return NULL; - } - - ps.size = size; /* XXX, 4gig limit! */ - ps.data = mem; - ps.seek = 0; - - png_set_read_fn(png_ptr, (void *)&ps, ReadData); - - if (setjmp(png_jmpbuf(png_ptr))) { - /* On error jump here, and free any resources. */ - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - if (pixels) { - MEM_freeN(pixels); - } - if (pixels16) { - MEM_freeN(pixels16); - } - if (row_pointers) { - MEM_freeN(row_pointers); - } - if (ibuf) { - IMB_freeImBuf(ibuf); - } - return NULL; - } - - // png_set_sig_bytes(png_ptr, 8); - - png_read_info(png_ptr, info_ptr); - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); - - channels = png_get_channels(png_ptr, info_ptr); - - switch (color_type) { - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - break; - case PNG_COLOR_TYPE_PALETTE: - png_set_palette_to_rgb(png_ptr); - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - channels = 4; - } - else { - channels = 3; - } - break; - case PNG_COLOR_TYPE_GRAY: - case PNG_COLOR_TYPE_GRAY_ALPHA: - if (bit_depth < 8) { - png_set_expand(png_ptr); - bit_depth = 8; - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - /* PNG_COLOR_TYPE_GRAY may also have alpha 'values', like with palette. */ - channels = 2; - } - } - break; - default: - printf("PNG format not supported\n"); - longjmp(png_jmpbuf(png_ptr), 1); - } - - ibuf = IMB_allocImBuf(width, height, 8 * channels, 0); - - if (ibuf) { - ibuf->ftype = IMB_FTYPE_PNG; - if (bit_depth == 16) { - ibuf->foptions.flag |= PNG_16BIT; - } - - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) { - int unit_type; - png_uint_32 xres, yres; - - if (png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type)) { - if (unit_type == PNG_RESOLUTION_METER) { - ibuf->ppm[0] = xres; - ibuf->ppm[1] = yres; - } - } - } - } - else { - printf("Couldn't allocate memory for PNG image\n"); - } - - if (ibuf && ((flags & IB_test) == 0)) { - if (bit_depth == 16) { - imb_addrectfloatImBuf(ibuf, 4); - png_set_swap(png_ptr); - - pixels16 = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(png_uint_16), "pixels"); - if (pixels16 == NULL || ibuf->rect_float == NULL) { - printf("Cannot allocate pixels array\n"); - longjmp(png_jmpbuf(png_ptr), 1); - } - - /* allocate memory for an array of row-pointers */ - row_pointers = (png_bytepp)MEM_mallocN((size_t)ibuf->y * sizeof(png_uint_16p), - "row_pointers"); - if (row_pointers == NULL) { - printf("Cannot allocate row-pointers array\n"); - longjmp(png_jmpbuf(png_ptr), 1); - } - - /* set the individual row-pointers to point at the correct offsets */ - for (size_t i = 0; i < ibuf->y; i++) { - row_pointers[ibuf->y - 1 - i] = (png_bytep)((png_uint_16 *)pixels16 + - (i * ibuf->x) * channels); - } - - png_read_image(png_ptr, row_pointers); - - /* copy image data */ - - to_float = ibuf->rect_float; - from16 = pixels16; - - switch (channels) { - case 4: - for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) { - to_float[0] = from16[0] / 65535.0; - to_float[1] = from16[1] / 65535.0; - to_float[2] = from16[2] / 65535.0; - to_float[3] = from16[3] / 65535.0; - to_float += 4; - from16 += 4; - } - break; - case 3: - for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) { - to_float[0] = from16[0] / 65535.0; - to_float[1] = from16[1] / 65535.0; - to_float[2] = from16[2] / 65535.0; - to_float[3] = 1.0; - to_float += 4; - from16 += 3; - } - break; - case 2: - for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) { - to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0; - to_float[3] = from16[1] / 65535.0; - to_float += 4; - from16 += 2; - } - break; - case 1: - for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) { - to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0; - to_float[3] = 1.0; - to_float += 4; - from16++; - } - break; - } - } - else { - imb_addrectImBuf(ibuf); - - pixels = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(uchar), "pixels"); - if (pixels == NULL || ibuf->rect == NULL) { - printf("Cannot allocate pixels array\n"); - longjmp(png_jmpbuf(png_ptr), 1); - } - - /* allocate memory for an array of row-pointers */ - row_pointers = (png_bytepp)MEM_mallocN((size_t)ibuf->y * sizeof(png_bytep), "row_pointers"); - if (row_pointers == NULL) { - printf("Cannot allocate row-pointers array\n"); - longjmp(png_jmpbuf(png_ptr), 1); - } - - /* set the individual row-pointers to point at the correct offsets */ - for (int i = 0; i < ibuf->y; i++) { - row_pointers[ibuf->y - 1 - i] = (png_bytep)((uchar *)pixels + (((size_t)i) * ibuf->x) * - channels * - sizeof(uchar)); - } - - png_read_image(png_ptr, row_pointers); - - /* copy image data */ - - to = (uchar *)ibuf->rect; - from = pixels; - - switch (channels) { - case 4: - for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) { - to[0] = from[0]; - to[1] = from[1]; - to[2] = from[2]; - to[3] = from[3]; - to += 4; - from += 4; - } - break; - case 3: - for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) { - to[0] = from[0]; - to[1] = from[1]; - to[2] = from[2]; - to[3] = 0xff; - to += 4; - from += 3; - } - break; - case 2: - for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) { - to[0] = to[1] = to[2] = from[0]; - to[3] = from[1]; - to += 4; - from += 2; - } - break; - case 1: - for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) { - to[0] = to[1] = to[2] = from[0]; - to[3] = 0xff; - to += 4; - from++; - } - break; - } - } - - if (flags & IB_metadata) { - png_text *text_chunks; - int count = png_get_text(png_ptr, info_ptr, &text_chunks, NULL); - IMB_metadata_ensure(&ibuf->metadata); - for (int i = 0; i < count; i++) { - IMB_metadata_set_field(ibuf->metadata, text_chunks[i].key, text_chunks[i].text); - ibuf->flags |= IB_metadata; - } - } - - png_read_end(png_ptr, info_ptr); - } - - /* clean up */ - if (pixels) { - MEM_freeN(pixels); - } - if (pixels16) { - MEM_freeN(pixels16); - } - if (row_pointers) { - MEM_freeN(row_pointers); - } - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - - return ibuf; -} diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c deleted file mode 100644 index 00ef12a54f8..00000000000 --- a/source/blender/imbuf/intern/radiance_hdr.c +++ /dev/null @@ -1,438 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/** \file - * \ingroup imbuf - * Radiance High Dynamic Range image file IO - * For description and code for reading/writing of radiance hdr files - * by Greg Ward, refer to: - * http://radsite.lbl.gov/radiance/refer/Notes/picture_format.html - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_fileops.h" -#include "BLI_utildefines.h" - -#include "imbuf.h" - -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "IMB_allocimbuf.h" -#include "IMB_filetype.h" - -#include "IMB_colormanagement.h" -#include "IMB_colormanagement_intern.h" - -/* needed constants */ -#define MINELEN 8 -#define MAXELEN 0x7fff -#define MINRUN 4 /* minimum run length */ -#define RED 0 -#define GRN 1 -#define BLU 2 -#define EXP 3 -#define COLXS 128 -typedef uchar RGBE[4]; -typedef float fCOLOR[3]; - -/* copy source -> dest */ -#define COPY_RGBE(c1, c2) \ - (c2[RED] = c1[RED], c2[GRN] = c1[GRN], c2[BLU] = c1[BLU], c2[EXP] = c1[EXP]) - -/* read routines */ -static const uchar *oldreadcolrs(RGBE *scan, const uchar *mem, int xmax, const uchar *mem_eof) -{ - size_t i, rshift = 0, len = xmax; - while (len > 0) { - if (UNLIKELY(mem_eof - mem < 4)) { - return NULL; - } - scan[0][RED] = *mem++; - scan[0][GRN] = *mem++; - scan[0][BLU] = *mem++; - scan[0][EXP] = *mem++; - if (scan[0][RED] == 1 && scan[0][GRN] == 1 && scan[0][BLU] == 1) { - for (i = scan[0][EXP] << rshift; i > 0 && len > 0; i--) { - COPY_RGBE(scan[-1], scan[0]); - scan++; - len--; - } - rshift += 8; - } - else { - scan++; - len--; - rshift = 0; - } - } - return mem; -} - -static const uchar *freadcolrs(RGBE *scan, const uchar *mem, int xmax, const uchar *mem_eof) -{ - if (UNLIKELY(mem_eof - mem < 4)) { - return NULL; - } - - if (UNLIKELY((xmax < MINELEN) | (xmax > MAXELEN))) { - return oldreadcolrs(scan, mem, xmax, mem_eof); - } - - int val = *mem++; - if (val != 2) { - return oldreadcolrs(scan, mem - 1, xmax, mem_eof); - } - - scan[0][GRN] = *mem++; - scan[0][BLU] = *mem++; - - val = *mem++; - - if (scan[0][GRN] != 2 || scan[0][BLU] & 128) { - scan[0][RED] = 2; - scan[0][EXP] = val; - return oldreadcolrs(scan + 1, mem, xmax - 1, mem_eof); - } - - if (UNLIKELY(((scan[0][BLU] << 8) | val) != xmax)) { - return NULL; - } - - for (size_t i = 0; i < 4; i++) { - if (UNLIKELY(mem_eof - mem < 2)) { - return NULL; - } - for (size_t j = 0; j < xmax;) { - int code = *mem++; - if (code > 128) { - code &= 127; - if (UNLIKELY(code + j > xmax)) { - return NULL; - } - val = *mem++; - while (code--) { - scan[j++][i] = (uchar)val; - } - } - else { - if (UNLIKELY(mem_eof - mem < code)) { - return NULL; - } - if (UNLIKELY(code + j > xmax)) { - return NULL; - } - while (code--) { - scan[j++][i] = *mem++; - } - } - } - } - - return mem; -} - -/* helper functions */ - -/* rgbe -> float color */ -static void RGBE2FLOAT(RGBE rgbe, fCOLOR fcol) -{ - if (rgbe[EXP] == 0) { - fcol[RED] = fcol[GRN] = fcol[BLU] = 0; - } - else { - float f = ldexp(1.0, rgbe[EXP] - (COLXS + 8)); - fcol[RED] = f * (rgbe[RED] + 0.5f); - fcol[GRN] = f * (rgbe[GRN] + 0.5f); - fcol[BLU] = f * (rgbe[BLU] + 0.5f); - } -} - -/* float color -> rgbe */ -static void FLOAT2RGBE(const fCOLOR fcol, RGBE rgbe) -{ - int e; - float d = (fcol[RED] > fcol[GRN]) ? fcol[RED] : fcol[GRN]; - if (fcol[BLU] > d) { - d = fcol[BLU]; - } - if (d <= 1e-32f) { - rgbe[RED] = rgbe[GRN] = rgbe[BLU] = rgbe[EXP] = 0; - } - else { - d = (float)frexp(d, &e) * 256.0f / d; - rgbe[RED] = (uchar)(fcol[RED] * d); - rgbe[GRN] = (uchar)(fcol[GRN] * d); - rgbe[BLU] = (uchar)(fcol[BLU] * d); - rgbe[EXP] = (uchar)(e + COLXS); - } -} - -/* ImBuf read */ - -bool imb_is_a_hdr(const uchar *buf, const size_t size) -{ - /* NOTE: `#?RADIANCE` is used by other programs such as `ImageMagik`, - * Although there are some files in the wild that only use `#?` (from looking online). - * If this is ever a problem we could check for the longer header since this is part of the spec. - * - * We could check `32-bit_rle_rgbe` or `32-bit_rle_xyze` too since this is part of the format. - * Currently this isn't needed. - * - * See: http://paulbourke.net/dataformats/pic/ - */ - const uchar magic[2] = {'#', '?'}; - if (size < sizeof(magic)) { - return false; - } - return memcmp(buf, magic, sizeof(magic)) == 0; -} - -struct ImBuf *imb_loadhdr(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) -{ - struct ImBuf *ibuf; - RGBE *sline; - fCOLOR fcol; - float *rect_float; - int found = 0; - int width = 0, height = 0; - const uchar *ptr, *mem_eof = mem + size; - char oriY[3], oriX[3]; - - if (!imb_is_a_hdr(mem, size)) { - return NULL; - } - - colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT); - - /* find empty line, next line is resolution info */ - size_t x; - for (x = 1; x < size; x++) { - if ((mem[x - 1] == '\n') && (mem[x] == '\n')) { - found = 1; - break; - } - } - - if ((found && (x < (size - 1))) == 0) { - /* Data not found! */ - return NULL; - } - - x++; - - /* sscanf requires a null-terminated buffer argument */ - char buf[32] = {0}; - memcpy(buf, &mem[x], MIN2(sizeof(buf) - 1, size - x)); - - if (sscanf(buf, "%2s %d %2s %d", (char *)&oriY, &height, (char *)&oriX, &width) != 4) { - return NULL; - } - - if (width < 1 || height < 1) { - return NULL; - } - - /* Checking that width x height does not extend past mem_eof is not easily possible - * since the format uses RLE compression. Can cause excessive memory allocation to occur. */ - - /* find end of this line, data right behind it */ - ptr = (const uchar *)strchr((const char *)&mem[x], '\n'); - if (ptr == NULL || ptr >= mem_eof) { - return NULL; - } - ptr++; - - if (flags & IB_test) { - ibuf = IMB_allocImBuf(width, height, 32, 0); - } - else { - ibuf = IMB_allocImBuf(width, height, 32, (flags & IB_rect) | IB_rectfloat); - } - - if (UNLIKELY(ibuf == NULL)) { - return NULL; - } - - ibuf->ftype = IMB_FTYPE_RADHDR; - - if (flags & IB_alphamode_detect) { - ibuf->flags |= IB_alphamode_premul; - } - - if (flags & IB_test) { - return ibuf; - } - - /* read in and decode the actual data */ - sline = (RGBE *)MEM_mallocN(sizeof(*sline) * width, __func__); - rect_float = ibuf->rect_float; - - for (size_t y = 0; y < height; y++) { - ptr = freadcolrs(sline, ptr, width, mem_eof); - if (ptr == NULL) { - printf("WARNING! HDR decode error, image may be just truncated, or completely wrong...\n"); - break; - } - for (x = 0; x < width; x++) { - /* Convert to LDR. */ - RGBE2FLOAT(sline[x], fcol); - *rect_float++ = fcol[RED]; - *rect_float++ = fcol[GRN]; - *rect_float++ = fcol[BLU]; - *rect_float++ = 1.0f; - } - } - MEM_freeN(sline); - if (oriY[0] == '-') { - IMB_flipy(ibuf); - } - - if (flags & IB_rect) { - IMB_rect_from_float(ibuf); - } - - return ibuf; -} - -/* ImBuf write */ -static int fwritecolrs( - FILE *file, int width, int channels, const uchar *ibufscan, const float *fpscan) -{ - int beg, c2, count = 0; - fCOLOR fcol; - RGBE rgbe, *rgbe_scan; - - if (UNLIKELY((ibufscan == NULL) && (fpscan == NULL))) { - return 0; - } - - rgbe_scan = (RGBE *)MEM_mallocN(sizeof(RGBE) * width, "radhdr_write_tmpscan"); - - /* Convert scan-line. */ - for (size_t i = 0, j = 0; i < width; i++) { - if (fpscan) { - fcol[RED] = fpscan[j]; - fcol[GRN] = (channels >= 2) ? fpscan[j + 1] : fpscan[j]; - fcol[BLU] = (channels >= 3) ? fpscan[j + 2] : fpscan[j]; - } - else { - fcol[RED] = (float)ibufscan[j] / 255.0f; - fcol[GRN] = (float)((channels >= 2) ? ibufscan[j + 1] : ibufscan[j]) / 255.0f; - fcol[BLU] = (float)((channels >= 3) ? ibufscan[j + 2] : ibufscan[j]) / 255.0f; - } - FLOAT2RGBE(fcol, rgbe); - COPY_RGBE(rgbe, rgbe_scan[i]); - j += channels; - } - - if ((width < MINELEN) | (width > MAXELEN)) { /* OOBs, write out flat */ - int x = fwrite((char *)rgbe_scan, sizeof(RGBE), width, file) - width; - MEM_freeN(rgbe_scan); - return x; - } - /* put magic header */ - putc(2, file); - putc(2, file); - putc((uchar)(width >> 8), file); - putc((uchar)(width & 255), file); - /* put components separately */ - for (size_t i = 0; i < 4; i++) { - for (size_t j = 0; j < width; j += count) { /* find next run */ - for (beg = j; beg < width; beg += count) { - for (count = 1; (count < 127) && ((beg + count) < width) && - (rgbe_scan[beg + count][i] == rgbe_scan[beg][i]); - count++) { - /* pass */ - } - if (count >= MINRUN) { - break; /* long enough */ - } - } - if (((beg - j) > 1) && ((beg - j) < MINRUN)) { - c2 = j + 1; - while (rgbe_scan[c2++][i] == rgbe_scan[j][i]) { - if (c2 == beg) { /* short run */ - putc((uchar)(128 + beg - j), file); - putc((uchar)(rgbe_scan[j][i]), file); - j = beg; - break; - } - } - } - while (j < beg) { /* write out non-run */ - if ((c2 = beg - j) > 128) { - c2 = 128; - } - putc((uchar)(c2), file); - while (c2--) { - putc(rgbe_scan[j++][i], file); - } - } - if (count >= MINRUN) { /* write out run */ - putc((uchar)(128 + count), file); - putc(rgbe_scan[beg][i], file); - } - else { - count = 0; - } - } - } - MEM_freeN(rgbe_scan); - return (ferror(file) ? -1 : 0); -} - -static void writeHeader(FILE *file, int width, int height) -{ - fprintf(file, "#?RADIANCE"); - fputc(10, file); - fprintf(file, "# %s", "Created with Blender"); - fputc(10, file); - fprintf(file, "EXPOSURE=%25.13f", 1.0); - fputc(10, file); - fprintf(file, "FORMAT=32-bit_rle_rgbe"); - fputc(10, file); - fputc(10, file); - fprintf(file, "-Y %d +X %d", height, width); - fputc(10, file); -} - -bool imb_savehdr(struct ImBuf *ibuf, const char *filepath, int flags) -{ - FILE *file = BLI_fopen(filepath, "wb"); - float *fp = NULL; - size_t width = ibuf->x, height = ibuf->y; - uchar *cp = NULL; - - (void)flags; /* unused */ - - if (file == NULL) { - return 0; - } - - writeHeader(file, width, height); - - if (ibuf->rect) { - cp = (uchar *)ibuf->rect + ibuf->channels * (height - 1) * width; - } - if (ibuf->rect_float) { - fp = ibuf->rect_float + ibuf->channels * (height - 1) * width; - } - - for (size_t y = 0; y < height; y++) { - if (fwritecolrs(file, width, ibuf->channels, cp, fp) < 0) { - fclose(file); - printf("HDR write error\n"); - return 0; - } - if (cp) { - cp -= ibuf->channels * width; - } - if (fp) { - fp -= ibuf->channels * width; - } - } - - fclose(file); - return 1; -} diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c deleted file mode 100644 index 6c2f1eb6dd2..00000000000 --- a/source/blender/imbuf/intern/targa.c +++ /dev/null @@ -1,791 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2001-2002 NaN Holding BV. All rights reserved. */ - -/** \file - * \ingroup imbuf - */ - -#ifdef WIN32 -# include -#endif - -#include "BLI_fileops.h" -#include "BLI_utildefines.h" - -#include "MEM_guardedalloc.h" - -#include "imbuf.h" - -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "IMB_filetype.h" - -#include "IMB_colormanagement.h" -#include "IMB_colormanagement_intern.h" - -/* this one is only def-ed once, strangely... related to GS? */ -#define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0]) - -/***/ - -typedef struct TARGA { - uchar numid; - uchar maptyp; - uchar imgtyp; - short maporig; - short mapsize; - uchar mapbits; - short xorig; - short yorig; - short xsize; - short ysize; - uchar pixsize; - uchar imgdes; -} TARGA; - -/** - * On-disk header size. - * - * \note In theory it's possible padding would make the struct and on-disk size differ, - * so use a constant instead of `sizeof(TARGA)`. - */ -#define TARGA_HEADER_SIZE 18 - -/***/ - -static int tga_out1(uint data, FILE *file) -{ - uchar *p; - - p = (uchar *)&data; - if (putc(p[0], file) == EOF) { - return EOF; - } - return ~EOF; -} - -static int tga_out2(uint data, FILE *file) -{ - uchar *p; - - p = (uchar *)&data; - if (putc(p[0], file) == EOF) { - return EOF; - } - if (putc(p[1], file) == EOF) { - return EOF; - } - return ~EOF; -} - -static int tga_out3(uint data, FILE *file) -{ - uchar *p; - - p = (uchar *)&data; - if (putc(p[2], file) == EOF) { - return EOF; - } - if (putc(p[1], file) == EOF) { - return EOF; - } - if (putc(p[0], file) == EOF) { - return EOF; - } - return ~EOF; -} - -static int tga_out4(uint data, FILE *file) -{ - uchar *p; - - p = (uchar *)&data; - /* Order = BGRA. */ - if (putc(p[2], file) == EOF) { - return EOF; - } - if (putc(p[1], file) == EOF) { - return EOF; - } - if (putc(p[0], file) == EOF) { - return EOF; - } - if (putc(p[3], file) == EOF) { - return EOF; - } - return ~EOF; -} - -static bool makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(uint, FILE *)) -{ - int last, this; - int copy, bytes; - uint *rect, *rectstart, *temp; - int y; - - for (y = 0; y < ibuf->y; y++) { - bytes = ibuf->x - 1; - rectstart = rect = ibuf->rect + (y * ibuf->x); - last = *rect++; - this = *rect++; - copy = last ^ this; - while (bytes > 0) { - if (copy) { - do { - last = this; - this = *rect++; - if (last == this) { - if (this == rect[-3]) { /* three the same? */ - bytes--; /* set bytes */ - break; - } - } - } while (--bytes != 0); - - copy = rect - rectstart; - copy--; - if (bytes) { - copy -= 2; - } - - temp = rect; - rect = rectstart; - - while (copy) { - last = copy; - if (copy >= 128) { - last = 128; - } - copy -= last; - if (fputc(last - 1, file) == EOF) { - return 0; - } - do { - if (out(*rect++, file) == EOF) { - return 0; - } - } while (--last != 0); - } - rectstart = rect; - rect = temp; - last = this; - - copy = 0; - } - else { - while (*rect++ == this) { /* seek for first different byte */ - if (--bytes == 0) { - break; /* Or end of line. */ - } - } - rect--; - copy = rect - rectstart; - rectstart = rect; - bytes--; - this = *rect++; - - while (copy) { - if (copy > 128) { - if (fputc(255, file) == EOF) { - return 0; - } - copy -= 128; - } - else { - if (copy == 1) { - if (fputc(0, file) == EOF) { - return 0; - } - } - else if (fputc(127 + copy, file) == EOF) { - return 0; - } - copy = 0; - } - if (out(last, file) == EOF) { - return 0; - } - } - copy = 1; - } - } - } - return 1; -} - -static bool dumptarga(struct ImBuf *ibuf, FILE *file) -{ - int size; - uchar *rect; - - if (ibuf == NULL) { - return 0; - } - if (ibuf->rect == NULL) { - return 0; - } - - size = ibuf->x * ibuf->y; - rect = (uchar *)ibuf->rect; - - if (ibuf->planes <= 8) { - while (size > 0) { - if (putc(*rect, file) == EOF) { - return 0; - } - size--; - rect += 4; - } - } - else if (ibuf->planes <= 16) { - while (size > 0) { - putc(rect[0], file); - if (putc(rect[1], file) == EOF) { - return 0; - } - size--; - rect += 4; - } - } - else if (ibuf->planes <= 24) { - while (size > 0) { - putc(rect[2], file); - putc(rect[1], file); - if (putc(rect[0], file) == EOF) { - return 0; - } - size--; - rect += 4; - } - } - else if (ibuf->planes <= 32) { - while (size > 0) { - putc(rect[2], file); - putc(rect[1], file); - putc(rect[0], file); - if (putc(rect[3], file) == EOF) { - return 0; - } - size--; - rect += 4; - } - } - else { - return 0; - } - - return 1; -} - -bool imb_savetarga(struct ImBuf *ibuf, const char *filepath, int UNUSED(flags)) -{ - char buf[TARGA_HEADER_SIZE] = {0}; - FILE *fildes; - bool ok = false; - - buf[16] = (ibuf->planes + 0x7) & ~0x7; - if (ibuf->planes > 8) { - buf[2] = 10; - } - else { - buf[2] = 11; - } - - if (ibuf->foptions.flag & RAWTGA) { - buf[2] &= ~8; - } - - buf[8] = 0; - buf[9] = 0; - buf[10] = 0; - buf[11] = 0; - - buf[12] = ibuf->x & 0xff; - buf[13] = ibuf->x >> 8; - buf[14] = ibuf->y & 0xff; - buf[15] = ibuf->y >> 8; - - /* Don't forget to indicate that your 32 bit - * targa uses 8 bits for the alpha channel! */ - if (ibuf->planes == 32) { - buf[17] |= 0x08; - } - fildes = BLI_fopen(filepath, "wb"); - if (!fildes) { - return 0; - } - - if (fwrite(buf, 1, TARGA_HEADER_SIZE, fildes) != TARGA_HEADER_SIZE) { - fclose(fildes); - return 0; - } - - if (ibuf->foptions.flag & RAWTGA) { - ok = dumptarga(ibuf, fildes); - } - else { - switch ((ibuf->planes + 7) >> 3) { - case 1: - ok = makebody_tga(ibuf, fildes, tga_out1); - break; - case 2: - ok = makebody_tga(ibuf, fildes, tga_out2); - break; - case 3: - ok = makebody_tga(ibuf, fildes, tga_out3); - break; - case 4: - ok = makebody_tga(ibuf, fildes, tga_out4); - break; - } - } - - fclose(fildes); - return ok; -} - -static bool checktarga(TARGA *tga, const uchar *mem, const size_t size) -{ - if (size < TARGA_HEADER_SIZE) { - return false; - } - - tga->numid = mem[0]; - tga->maptyp = mem[1]; - tga->imgtyp = mem[2]; - - tga->maporig = GSS(mem + 3); - tga->mapsize = GSS(mem + 5); - tga->mapbits = mem[7]; - tga->xorig = GSS(mem + 8); - tga->yorig = GSS(mem + 10); - tga->xsize = GSS(mem + 12); - tga->ysize = GSS(mem + 14); - tga->pixsize = mem[16]; - tga->imgdes = mem[17]; - - if (tga->maptyp > 1) { - return false; - } - switch (tga->imgtyp) { - case 1: /* raw cmap */ - case 2: /* raw rgb */ - case 3: /* raw b&w */ - case 9: /* cmap */ - case 10: /* rgb */ - case 11: /* b&w */ - break; - default: - return false; - } - if (tga->mapsize && tga->mapbits > 32) { - return false; - } - if (tga->xsize <= 0) { - return false; - } - if (tga->ysize <= 0) { - return false; - } - if (tga->pixsize > 32) { - return false; - } - if (tga->pixsize == 0) { - return false; - } - return true; -} - -bool imb_is_a_targa(const uchar *buf, size_t size) -{ - TARGA tga; - - return checktarga(&tga, buf, size); -} - -static void complete_partial_load(struct ImBuf *ibuf, uint *rect) -{ - int size = (ibuf->x * ibuf->y) - (rect - ibuf->rect); - if (size) { - printf("decodetarga: incomplete file, %.1f%% missing\n", - 100 * ((float)size / (ibuf->x * ibuf->y))); - - /* Not essential but makes displaying partially rendered TGA's less ugly. */ - memset(rect, 0, size); - } - else { - /* shouldn't happen */ - printf("decodetarga: incomplete file, all pixels written\n"); - } -} - -static void decodetarga(struct ImBuf *ibuf, const uchar *mem, size_t mem_size, int psize) -{ - const uchar *mem_end = mem + mem_size; - int count, col, size; - uint *rect; - uchar *cp = (uchar *)&col; - - if (ibuf == NULL) { - return; - } - if (ibuf->rect == NULL) { - return; - } - - size = ibuf->x * ibuf->y; - rect = ibuf->rect; - - /* set alpha */ - cp[0] = 0xff; - cp[1] = cp[2] = 0; - - while (size > 0) { - count = *mem++; - - if (mem > mem_end) { - goto partial_load; - } - - if (count >= 128) { - // if (count == 128) printf("TARGA: 128 in file !\n"); - count -= 127; - - if (psize & 2) { - if (psize & 1) { - /* Order = BGRA. */ - cp[0] = mem[3]; - cp[1] = mem[0]; - cp[2] = mem[1]; - cp[3] = mem[2]; - // col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2]; - mem += 4; - } - else { - cp[1] = mem[0]; - cp[2] = mem[1]; - cp[3] = mem[2]; - // col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2]; - mem += 3; - } - } - else { - if (psize & 1) { - cp[0] = mem[0]; - cp[1] = mem[1]; - mem += 2; - } - else { - col = *mem++; - } - } - - size -= count; - if (size >= 0) { - while (count > 0) { - *rect++ = col; - count--; - } - } - } - else { - count++; - size -= count; - if (size >= 0) { - while (count > 0) { - if (psize & 2) { - if (psize & 1) { - /* Order = BGRA. */ - cp[0] = mem[3]; - cp[1] = mem[0]; - cp[2] = mem[1]; - cp[3] = mem[2]; - // col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2]; - mem += 4; - } - else { - cp[1] = mem[0]; - cp[2] = mem[1]; - cp[3] = mem[2]; - // col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2]; - mem += 3; - } - } - else { - if (psize & 1) { - cp[0] = mem[0]; - cp[1] = mem[1]; - mem += 2; - } - else { - col = *mem++; - } - } - *rect++ = col; - count--; - - if (mem > mem_end) { - goto partial_load; - } - } - - if (mem > mem_end) { - goto partial_load; - } - } - } - } - if (size) { - printf("decodetarga: count would overwrite %d pixels\n", -size); - } - return; - -partial_load: - complete_partial_load(ibuf, rect); -} - -static void ldtarga(struct ImBuf *ibuf, const uchar *mem, size_t mem_size, int psize) -{ - const uchar *mem_end = mem + mem_size; - int col, size; - uint *rect; - uchar *cp = (uchar *)&col; - - if (ibuf == NULL) { - return; - } - if (ibuf->rect == NULL) { - return; - } - - size = ibuf->x * ibuf->y; - rect = ibuf->rect; - - /* set alpha */ - cp[0] = 0xff; - cp[1] = cp[2] = 0; - - while (size > 0) { - if (mem > mem_end) { - goto partial_load; - } - - if (psize & 2) { - if (psize & 1) { - /* Order = BGRA. */ - cp[0] = mem[3]; - cp[1] = mem[0]; - cp[2] = mem[1]; - cp[3] = mem[2]; - // col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2]; - mem += 4; - } - else { - /* set alpha for 24 bits colors */ - cp[1] = mem[0]; - cp[2] = mem[1]; - cp[3] = mem[2]; - // col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2]; - mem += 3; - } - } - else { - if (psize & 1) { - cp[0] = mem[0]; - cp[1] = mem[1]; - mem += 2; - } - else { - col = *mem++; - } - } - *rect++ = col; - size--; - } - return; - -partial_load: - complete_partial_load(ibuf, rect); -} - -ImBuf *imb_loadtarga(const uchar *mem, size_t mem_size, int flags, char colorspace[IM_MAX_SPACE]) -{ - TARGA tga; - struct ImBuf *ibuf; - int count, size; - uint *rect, *cmap = NULL /*, mincol = 0*/, cmap_max = 0; - int32_t cp_data; - uchar *cp = (uchar *)&cp_data; - - if (checktarga(&tga, mem, mem_size) == 0) { - return NULL; - } - - colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); - - if (flags & IB_test) { - ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, tga.pixsize, 0); - } - else { - ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, (tga.pixsize + 0x7) & ~0x7, IB_rect); - } - - if (ibuf == NULL) { - return NULL; - } - ibuf->ftype = IMB_FTYPE_TGA; - if (tga.imgtyp < 4) { - ibuf->foptions.flag |= RAWTGA; - } - mem = mem + TARGA_HEADER_SIZE + tga.numid; - - cp[0] = 0xff; - cp[1] = cp[2] = 0; - - if (tga.mapsize) { - /* Load color map. */ - // mincol = tga.maporig; /* UNUSED */ - cmap_max = tga.mapsize; - cmap = MEM_callocN(sizeof(uint) * cmap_max, "targa cmap"); - - for (count = 0; count < cmap_max; count++) { - switch (tga.mapbits >> 3) { - case 4: - cp[0] = mem[3]; - cp[1] = mem[0]; - cp[2] = mem[1]; - cp[3] = mem[2]; - mem += 4; - break; - case 3: - cp[1] = mem[0]; - cp[2] = mem[1]; - cp[3] = mem[2]; - mem += 3; - break; - case 2: - cp[1] = mem[1]; - cp[0] = mem[0]; - mem += 2; - break; - case 1: - cp_data = *mem++; - break; - } - cmap[count] = cp_data; - } - - ibuf->planes = tga.mapbits; - if (tga.mapbits != 32) { /* Set alpha bits. */ - cmap[0] &= BIG_LONG(0x00ffffffl); - } - } - - if (flags & IB_test) { - if (cmap) { - MEM_freeN(cmap); - } - return ibuf; - } - - if (!ELEM(tga.imgtyp, 1, 9)) { /* happens sometimes (ugh) */ - if (cmap) { - MEM_freeN(cmap); - cmap = NULL; - } - } - - switch (tga.imgtyp) { - case 1: - case 2: - case 3: - if (tga.pixsize <= 8) { - ldtarga(ibuf, mem, mem_size, 0); - } - else if (tga.pixsize <= 16) { - ldtarga(ibuf, mem, mem_size, 1); - } - else if (tga.pixsize <= 24) { - ldtarga(ibuf, mem, mem_size, 2); - } - else if (tga.pixsize <= 32) { - ldtarga(ibuf, mem, mem_size, 3); - } - break; - case 9: - case 10: - case 11: - if (tga.pixsize <= 8) { - decodetarga(ibuf, mem, mem_size, 0); - } - else if (tga.pixsize <= 16) { - decodetarga(ibuf, mem, mem_size, 1); - } - else if (tga.pixsize <= 24) { - decodetarga(ibuf, mem, mem_size, 2); - } - else if (tga.pixsize <= 32) { - decodetarga(ibuf, mem, mem_size, 3); - } - break; - } - - if (cmap) { - /* apply color map */ - rect = ibuf->rect; - for (size = ibuf->x * ibuf->y; size > 0; size--, rect++) { - int cmap_index = *rect; - if (cmap_index >= 0 && cmap_index < cmap_max) { - *rect = cmap[cmap_index]; - } - } - - MEM_freeN(cmap); - } - - if (tga.pixsize == 16) { - uint col; - rect = ibuf->rect; - for (size = ibuf->x * ibuf->y; size > 0; size--, rect++) { - col = *rect; - cp = (uchar *)rect; - mem = (uchar *)&col; - - cp[3] = ((mem[1] << 1) & 0xf8); - cp[2] = ((mem[0] & 0xe0) >> 2) + ((mem[1] & 0x03) << 6); - cp[1] = ((mem[0] << 3) & 0xf8); - cp[1] += cp[1] >> 5; - cp[2] += cp[2] >> 5; - cp[3] += cp[3] >> 5; - cp[0] = 0xff; - } - ibuf->planes = 24; - } - - if (ELEM(tga.imgtyp, 3, 11)) { - uchar *crect; - uint *lrect, col; - - crect = (uchar *)ibuf->rect; - lrect = (uint *)ibuf->rect; - - for (size = ibuf->x * ibuf->y; size > 0; size--) { - col = *lrect++; - - crect[0] = 255; - crect[1] = crect[2] = crect[3] = col; - crect += 4; - } - } - - if (tga.imgdes & 0x20) { - IMB_flipy(ibuf); - } - - if (ibuf->rect) { - IMB_convert_rgba_to_abgr(ibuf); - } - - return ibuf; -} diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c deleted file mode 100644 index 8ba06165df4..00000000000 --- a/source/blender/imbuf/intern/tiff.c +++ /dev/null @@ -1,832 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/** \file - * \ingroup imbuf - */ - -/** - * Provides TIFF file loading and saving for Blender, via libtiff. - * - * The task of loading is complicated somewhat by the fact that Blender has - * already loaded the file into a memory buffer. libtiff is not well - * configured to handle files in memory, so a client wrapper is written to - * surround the memory and turn it into a virtual file. Currently, reading - * of TIFF files is done using libtiff's RGBAImage support. This is a - * high-level routine that loads all images as 32-bit RGBA, handling all the - * required conversions between many different TIFF types internally. - * - * Saving supports RGB, RGBA and BW (gray-scale) images correctly, with - * 8 bits per channel in all cases. The "deflate" compression algorithm is - * used to compress images. - */ - -#include - -#include "imbuf.h" - -#include "BLI_endian_defines.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "BKE_global.h" - -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "IMB_filetype.h" - -#include "IMB_colormanagement.h" -#include "IMB_colormanagement_intern.h" - -#include - -#ifdef WIN32 -# include "utfconv.h" -#endif - -/* -------------------------------------------------------------------- */ -/** \name Local Declarations - * \{ */ - -/* Reading and writing of an in-memory TIFF file. */ -static tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n); -static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n); -static toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence); -static int imb_tiff_CloseProc(thandle_t handle); -static toff_t imb_tiff_SizeProc(thandle_t handle); -static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t *pbase, toff_t *psize); -static void imb_tiff_DummyUnmapProc(thandle_t fd, tdata_t base, toff_t size); - -/** Structure for in-memory TIFF file. */ -typedef struct ImbTIFFMemFile { - /** Location of first byte of TIFF file. */ - const uchar *mem; - /** Current offset within the file. */ - toff_t offset; - /** Size of the TIFF file. */ - tsize_t size; -} ImbTIFFMemFile; -#define IMB_TIFF_GET_MEMFILE(x) ((ImbTIFFMemFile *)(x)) - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Function Implementations - * \{ */ - -static void imb_tiff_DummyUnmapProc( - thandle_t fd, - tdata_t base, - /* Cannot be const, because this function implements #TIFFUnmapFileProc. - * NOLINTNEXTLINE: readability-non-const-parameter. */ - toff_t size) -{ - (void)fd; - (void)base; - (void)size; -} - -static int imb_tiff_DummyMapProc( - thandle_t fd, - tdata_t *pbase, - /* Cannot be const, because this function implements #TIFFMapFileProc. - * NOLINTNEXTLINE: readability-non-const-parameter. */ - toff_t *psize) -{ - (void)fd; - (void)pbase; - (void)psize; - - return 0; -} - -/** - * Reads data from an in-memory TIFF file. - * - * \param handle: Handle of the TIFF file (pointer to #ImbTIFFMemFile). - * \param data: Buffer to contain data (treat as (void *)). - * \param n: Number of bytes to read. - * - * \return Number of bytes actually read. - * 0 = EOF. - */ -static tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n) -{ - tsize_t nRemaining, nCopy; - ImbTIFFMemFile *mfile; - void *srcAddr; - - /* get the pointer to the in-memory file */ - mfile = IMB_TIFF_GET_MEMFILE(handle); - if (!mfile || !mfile->mem) { - fprintf(stderr, "imb_tiff_ReadProc: !mfile || !mfile->mem!\n"); - return 0; - } - - /* find the actual number of bytes to read (copy) */ - nCopy = n; - if ((tsize_t)mfile->offset >= mfile->size) { - nRemaining = 0; - } - else { - nRemaining = mfile->size - mfile->offset; - } - - if (nCopy > nRemaining) { - nCopy = nRemaining; - } - - /* on EOF, return immediately and read (copy) nothing */ - if (nCopy <= 0) { - return 0; - } - - /* all set -> do the read (copy) */ - srcAddr = (void *)&(mfile->mem[mfile->offset]); - memcpy((void *)data, srcAddr, nCopy); - mfile->offset += nCopy; /* advance file ptr by copied bytes */ - return nCopy; -} - -/** - * Writes data to an in-memory TIFF file. - * - * NOTE: The current Blender implementation should not need this function. - * It is simply a stub. - */ -static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n) -{ - (void)handle; - (void)data; - (void)n; - - printf("imb_tiff_WriteProc: this function should not be called.\n"); - return (-1); -} - -/** - * Seeks to a new location in an in-memory TIFF file. - * - * \param handle: Handle of the TIFF file (pointer to #ImbTIFFMemFile). - * \param ofs: Offset value (interpreted according to whence below). - * \param whence: This can be one of three values: - * SEEK_SET - The offset is set to ofs bytes. - * SEEK_CUR - The offset is set to its current location plus ofs bytes. - * SEEK_END - (This is unsupported and will return -1, indicating an - * error). - * - * \return Resulting offset location within the file, measured in bytes from - * the beginning of the file. (-1) indicates an error. - */ -static toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence) -{ - ImbTIFFMemFile *mfile; - toff_t new_offset; - - /* get the pointer to the in-memory file */ - mfile = IMB_TIFF_GET_MEMFILE(handle); - if (!mfile || !mfile->mem) { - fprintf(stderr, "imb_tiff_SeekProc: !mfile || !mfile->mem!\n"); - return (-1); - } - - /* find the location we plan to seek to */ - switch (whence) { - case SEEK_SET: - new_offset = ofs; - break; - case SEEK_CUR: - new_offset = mfile->offset + ofs; - break; - default: - /* no other types are supported - return an error */ - fprintf(stderr, - "imb_tiff_SeekProc: " - "Unsupported TIFF SEEK type.\n"); - return (-1); - } - - /* set the new location */ - mfile->offset = new_offset; - return mfile->offset; -} - -/** - * Closes (virtually) an in-memory TIFF file. - * - * NOTE: All this function actually does is sets the data pointer within the - * TIFF file to NULL. That should trigger assertion errors if attempts - * are made to access the file after that point. However, no such - * attempts should ever be made (in theory). - * - * \param handle: Handle of the TIFF file (pointer to #ImbTIFFMemFile). - * - * \return 0 - */ -static int imb_tiff_CloseProc(thandle_t handle) -{ - ImbTIFFMemFile *mfile; - - /* get the pointer to the in-memory file */ - mfile = IMB_TIFF_GET_MEMFILE(handle); - if (!mfile || !mfile->mem) { - fprintf(stderr, "imb_tiff_CloseProc: !mfile || !mfile->mem!\n"); - return 0; - } - - /* virtually close the file */ - mfile->mem = NULL; - mfile->offset = 0; - mfile->size = 0; - - return 0; -} - -/** - * Returns the size of an in-memory TIFF file in bytes. - * - * \return Size of file (in bytes). - */ -static toff_t imb_tiff_SizeProc(thandle_t handle) -{ - ImbTIFFMemFile *mfile; - - /* get the pointer to the in-memory file */ - mfile = IMB_TIFF_GET_MEMFILE(handle); - if (!mfile || !mfile->mem) { - fprintf(stderr, "imb_tiff_SizeProc: !mfile || !mfile->mem!\n"); - return 0; - } - - /* return the size */ - return (toff_t)(mfile->size); -} - -static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, const uchar *mem, size_t size) -{ - /* open the TIFF client layer interface to the in-memory file */ - memFile->mem = mem; - memFile->offset = 0; - memFile->size = size; - - return TIFFClientOpen("(Blender TIFF Interface Layer)", - "r", - (thandle_t)(memFile), - imb_tiff_ReadProc, - imb_tiff_WriteProc, - imb_tiff_SeekProc, - imb_tiff_CloseProc, - imb_tiff_SizeProc, - imb_tiff_DummyMapProc, - imb_tiff_DummyUnmapProc); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Load TIFF - * \{ */ - -/** - * Checks whether a given memory buffer contains a TIFF file. - * - * This method uses the format identifiers from: - * http://www.faqs.org/faqs/graphics/fileformats-faq/part4/section-9.html - * The first four bytes of big-endian and little-endian TIFF files - * respectively are (hex): - * 4d 4d 00 2a - * 49 49 2a 00 - * Note that TIFF files on *any* platform can be either big- or little-endian; - * it's not platform-specific. - * - * AFAICT, libtiff doesn't provide a method to do this automatically, and - * hence my manual comparison. - Jonathan Merritt (lancelet) 4th Sept 2005. - */ -#define IMB_TIFF_NCB 4 /* number of comparison bytes used */ -bool imb_is_a_tiff(const uchar *buf, size_t size) -{ - const char big_endian[IMB_TIFF_NCB] = {0x4d, 0x4d, 0x00, 0x2a}; - const char lil_endian[IMB_TIFF_NCB] = {0x49, 0x49, 0x2a, 0x00}; - if (size < IMB_TIFF_NCB) { - return false; - } - - return ((memcmp(big_endian, buf, IMB_TIFF_NCB) == 0) || - (memcmp(lil_endian, buf, IMB_TIFF_NCB) == 0)); -} - -static void scanline_contig_16bit(float *rectf, const ushort *sbuf, int scanline_w, int spp) -{ - int i; - for (i = 0; i < scanline_w; i++) { - rectf[i * 4 + 0] = sbuf[i * spp + 0] / 65535.0; - rectf[i * 4 + 1] = (spp >= 3) ? sbuf[i * spp + 1] / 65535.0 : sbuf[i * spp + 0] / 65535.0; - rectf[i * 4 + 2] = (spp >= 3) ? sbuf[i * spp + 2] / 65535.0 : sbuf[i * spp + 0] / 65535.0; - rectf[i * 4 + 3] = (spp == 4) ? (sbuf[i * spp + 3] / 65535.0) : 1.0; - } -} - -static void scanline_contig_32bit(float *rectf, const float *fbuf, int scanline_w, int spp) -{ - int i; - for (i = 0; i < scanline_w; i++) { - rectf[i * 4 + 0] = fbuf[i * spp + 0]; - rectf[i * 4 + 1] = (spp >= 3) ? fbuf[i * spp + 1] : fbuf[i * spp + 0]; - rectf[i * 4 + 2] = (spp >= 3) ? fbuf[i * spp + 2] : fbuf[i * spp + 0]; - rectf[i * 4 + 3] = (spp == 4) ? fbuf[i * spp + 3] : 1.0f; - } -} - -static void scanline_separate_16bit(float *rectf, const ushort *sbuf, int scanline_w, int chan) -{ - int i; - for (i = 0; i < scanline_w; i++) { - rectf[i * 4 + chan] = sbuf[i] / 65535.0; - } -} - -static void scanline_separate_32bit(float *rectf, const float *fbuf, int scanline_w, int chan) -{ - int i; - for (i = 0; i < scanline_w; i++) { - rectf[i * 4 + chan] = fbuf[i]; - } -} - -static void imb_read_tiff_resolution(ImBuf *ibuf, TIFF *image) -{ - uint16_t unit; - float xres; - float yres; - - TIFFGetFieldDefaulted(image, TIFFTAG_RESOLUTIONUNIT, &unit); - TIFFGetFieldDefaulted(image, TIFFTAG_XRESOLUTION, &xres); - TIFFGetFieldDefaulted(image, TIFFTAG_YRESOLUTION, &yres); - - if (unit == RESUNIT_CENTIMETER) { - ibuf->ppm[0] = (double)xres * 100.0; - ibuf->ppm[1] = (double)yres * 100.0; - } - else { - ibuf->ppm[0] = (double)xres / 0.0254; - ibuf->ppm[1] = (double)yres / 0.0254; - } -} - -/* - * Use the libTIFF scanline API to read a TIFF image. - * This method is most flexible and can handle multiple different bit depths - * and RGB channel orderings. - */ -static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image) -{ - ImBuf *tmpibuf = NULL; - int success = 0; - short bitspersample, spp, config; - size_t scanline; - int ib_flag = 0, row, chan; - float *fbuf = NULL; - ushort *sbuf = NULL; - - TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample); - TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); /* number of 'channels' */ - TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config); - - if (spp == 4) { - /* HACK: this is really tricky hack, which is only needed to force libtiff - * do not touch RGB channels when there's alpha channel present - * The thing is: libtiff will premul RGB if alpha mode is set to - * unassociated, which really conflicts with blender's assumptions - * - * Alternative would be to unpremul after load, but it'll be really - * lossy and unwanted behavior - * - * So let's keep this thing here for until proper solution is found (sergey) - */ - - ushort extraSampleTypes[1]; - extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA; - TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1, extraSampleTypes); - } - - imb_read_tiff_resolution(ibuf, image); - - scanline = TIFFScanlineSize(image); - - if (bitspersample == 32) { - ib_flag = IB_rectfloat; - fbuf = (float *)_TIFFmalloc(scanline); - if (!fbuf) { - goto cleanup; - } - } - else if (bitspersample == 16) { - ib_flag = IB_rectfloat; - sbuf = (ushort *)_TIFFmalloc(scanline); - if (!sbuf) { - goto cleanup; - } - } - else { - ib_flag = IB_rect; - } - - tmpibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, ib_flag); - if (!tmpibuf) { - goto cleanup; - } - - /* simple RGBA image */ - if (!ELEM(bitspersample, 32, 16)) { - success |= TIFFReadRGBAImage(image, ibuf->x, ibuf->y, tmpibuf->rect, 0); - } - /* contiguous channels: RGBRGBRGB */ - else if (config == PLANARCONFIG_CONTIG) { - for (row = 0; row < ibuf->y; row++) { - size_t ib_offset = (size_t)ibuf->x * 4 * ((size_t)ibuf->y - ((size_t)row + 1)); - - if (bitspersample == 32) { - success |= TIFFReadScanline(image, fbuf, row, 0); - scanline_contig_32bit(tmpibuf->rect_float + ib_offset, fbuf, ibuf->x, spp); - } - else if (bitspersample == 16) { - success |= TIFFReadScanline(image, sbuf, row, 0); - scanline_contig_16bit(tmpibuf->rect_float + ib_offset, sbuf, ibuf->x, spp); - } - } - /* Separate channels: RRRGGGBBB. */ - } - else if (config == PLANARCONFIG_SEPARATE) { - - /* imbufs always have 4 channels of data, so we iterate over all of them - * but only fill in from the TIFF scanline where necessary. */ - for (chan = 0; chan < 4; chan++) { - for (row = 0; row < ibuf->y; row++) { - size_t ib_offset = (size_t)ibuf->x * 4 * ((size_t)ibuf->y - ((size_t)row + 1)); - - if (bitspersample == 32) { - if (chan == 3 && spp == 3) { /* fill alpha if only RGB TIFF */ - copy_vn_fl(fbuf, ibuf->x, 1.0f); - } - else if (chan >= spp) { /* For gray-scale, duplicate first channel into G and B. */ - success |= TIFFReadScanline(image, fbuf, row, 0); - } - else { - success |= TIFFReadScanline(image, fbuf, row, chan); - } - scanline_separate_32bit(tmpibuf->rect_float + ib_offset, fbuf, ibuf->x, chan); - } - else if (bitspersample == 16) { - if (chan == 3 && spp == 3) { /* fill alpha if only RGB TIFF */ - copy_vn_ushort(sbuf, ibuf->x, 65535); - } - else if (chan >= spp) { /* For gray-scale, duplicate first channel into G and B. */ - success |= TIFFReadScanline(image, fbuf, row, 0); - } - else { - success |= TIFFReadScanline(image, sbuf, row, chan); - } - scanline_separate_16bit(tmpibuf->rect_float + ib_offset, sbuf, ibuf->x, chan); - } - } - } - } - - if (success) { - /* Code seems to be not needed for 16 bits TIFF, on PPC G5 OSX (ton) */ - if (bitspersample < 16) { - if (ENDIAN_ORDER == B_ENDIAN) { - IMB_convert_rgba_to_abgr(tmpibuf); - } - } - - /* assign rect last */ - if (tmpibuf->rect_float) { - ibuf->rect_float = tmpibuf->rect_float; - } - else { - ibuf->rect = tmpibuf->rect; - } - ibuf->mall |= ib_flag; - ibuf->flags |= ib_flag; - - tmpibuf->mall &= ~ib_flag; - } - -cleanup: - if (bitspersample == 32) { - _TIFFfree(fbuf); - } - else if (bitspersample == 16) { - _TIFFfree(sbuf); - } - - IMB_freeImBuf(tmpibuf); - - return success; -} - -void imb_inittiff(void) -{ - if (!(G.debug & G_DEBUG)) { - TIFFSetErrorHandler(NULL); - } -} - -ImBuf *imb_loadtiff(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) -{ - TIFF *image = NULL; - ImBuf *ibuf = NULL; - ImbTIFFMemFile memFile; - uint32_t width, height; - short spp; - int ib_depth; - - /* Check whether or not we have a TIFF file. */ - if (imb_is_a_tiff(mem, size) == 0) { - return NULL; - } - - /* both 8 and 16 bit PNGs are default to standard byte colorspace */ - colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); - - image = imb_tiff_client_open(&memFile, mem, size); - - if (image == NULL) { - printf("imb_loadtiff: could not open TIFF IO layer.\n"); - return NULL; - } - - /* allocate the image buffer */ - TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height); - TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); - - ib_depth = spp * 8; - - ibuf = IMB_allocImBuf(width, height, ib_depth, 0); - if (ibuf) { - ibuf->ftype = IMB_FTYPE_TIF; - } - else { - fprintf(stderr, - "imb_loadtiff: could not allocate memory for TIFF " - "image.\n"); - TIFFClose(image); - return NULL; - } - - /* get alpha mode from file header */ - if (flags & IB_alphamode_detect) { - if (spp == 4) { - ushort extra, *extraSampleTypes; - const int found = TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &extra, &extraSampleTypes); - - if (found && (extraSampleTypes[0] == EXTRASAMPLE_ASSOCALPHA)) { - ibuf->flags |= IB_alphamode_premul; - } - } - } - - /* if testing, we're done */ - if (flags & IB_test) { - TIFFClose(image); - return ibuf; - } - - /* read pixels */ - if (!imb_read_tiff_pixels(ibuf, image)) { - fprintf(stderr, "imb_loadtiff: Failed to read tiff image.\n"); - TIFFClose(image); - return NULL; - } - - /* close the client layer interface to the in-memory file */ - TIFFClose(image); - - /* return successfully */ - return ibuf; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Save TIFF - * \{ */ - -bool imb_savetiff(ImBuf *ibuf, const char *filepath, int flags) -{ - TIFF *image = NULL; - uint16_t samplesperpixel, bitspersample; - size_t npixels; - uchar *pixels = NULL; - uchar *from = NULL, *to = NULL; - ushort *pixels16 = NULL, *to16 = NULL; - float *fromf = NULL; - float xres, yres; - int x, y, from_i, to_i, i; - int compress_mode = COMPRESSION_NONE; - - /* check for a valid number of bytes per pixel. Like the PNG writer, - * the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding - * to gray, RGB, RGBA respectively. */ - samplesperpixel = (uint16_t)((ibuf->planes + 7) >> 3); - if ((samplesperpixel > 4) || (samplesperpixel == 2)) { - fprintf(stderr, - "imb_savetiff: unsupported number of bytes per " - "pixel: %d\n", - samplesperpixel); - return 0; - } - - if ((ibuf->foptions.flag & TIF_16BIT) && ibuf->rect_float) { - bitspersample = 16; - } - else { - bitspersample = 8; - } - - if (ibuf->foptions.flag & TIF_COMPRESS_DEFLATE) { - compress_mode = COMPRESSION_DEFLATE; - } - else if (ibuf->foptions.flag & TIF_COMPRESS_LZW) { - compress_mode = COMPRESSION_LZW; - } - else if (ibuf->foptions.flag & TIF_COMPRESS_PACKBITS) { - compress_mode = COMPRESSION_PACKBITS; - } - - /* open TIFF file for writing */ - if (flags & IB_mem) { - /* Failed to allocate TIFF in memory. */ - fprintf(stderr, - "imb_savetiff: creation of in-memory TIFF files is " - "not yet supported.\n"); - return 0; - } - - /* create image as a file */ -#ifdef WIN32 - wchar_t *wname = alloc_utf16_from_8(filepath, 0); - image = TIFFOpenW(wname, "w"); - free(wname); -#else - image = TIFFOpen(filepath, "w"); -#endif - - if (image == NULL) { - fprintf(stderr, "imb_savetiff: could not open TIFF for writing.\n"); - return 0; - } - - /* allocate array for pixel data */ - npixels = ibuf->x * ibuf->y; - if (bitspersample == 16) { - pixels16 = (ushort *)_TIFFmalloc(npixels * samplesperpixel * sizeof(ushort)); - } - else { - pixels = (uchar *)_TIFFmalloc(npixels * samplesperpixel * sizeof(uchar)); - } - - if (pixels == NULL && pixels16 == NULL) { - fprintf(stderr, "imb_savetiff: could not allocate pixels array.\n"); - TIFFClose(image); - return 0; - } - - /* setup pointers */ - if (bitspersample == 16) { - fromf = ibuf->rect_float; - to16 = pixels16; - } - else { - from = (uchar *)ibuf->rect; - to = pixels; - } - - /* setup samples per pixel */ - TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, bitspersample); - TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); - - if (samplesperpixel == 4) { - ushort extraSampleTypes[1]; - - if (bitspersample == 16) { - extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA; - } - else { - extraSampleTypes[0] = EXTRASAMPLE_UNASSALPHA; - } - - /* RGBA images */ - TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1, extraSampleTypes); - TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); - } - else if (samplesperpixel == 3) { - /* RGB images */ - TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); - } - else if (samplesperpixel == 1) { - /* Gray-scale images, 1 channel */ - TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); - } - - /* copy pixel data. While copying, we flip the image vertically. */ - const int channels_in_float = ibuf->channels ? ibuf->channels : 4; - for (x = 0; x < ibuf->x; x++) { - for (y = 0; y < ibuf->y; y++) { - from_i = ((size_t)channels_in_float) * (y * ibuf->x + x); - to_i = samplesperpixel * ((ibuf->y - y - 1) * ibuf->x + x); - - if (pixels16) { - /* convert from float source */ - float rgb[4]; - - if (ELEM(channels_in_float, 3, 4)) { - if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) { - /* Float buffer was managed already, no need in color - * space conversion. - */ - copy_v3_v3(rgb, &fromf[from_i]); - } - else { - /* Standard linear-to-SRGB conversion if float buffer wasn't managed. */ - linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]); - } - if (channels_in_float == 4) { - rgb[3] = fromf[from_i + 3]; - } - else { - rgb[3] = 1.0f; - } - } - else { - if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) { - rgb[0] = fromf[from_i]; - } - else { - rgb[0] = linearrgb_to_srgb(fromf[from_i]); - } - rgb[1] = rgb[2] = rgb[0]; - rgb[3] = 1.0f; - } - - for (i = 0; i < samplesperpixel; i++, to_i++) { - to16[to_i] = unit_float_to_ushort_clamp(rgb[i]); - } - } - else { - for (i = 0; i < samplesperpixel; i++, to_i++, from_i++) { - to[to_i] = from[from_i]; - } - } - } - } - - /* write the actual TIFF file */ - TIFFSetField(image, TIFFTAG_IMAGEWIDTH, ibuf->x); - TIFFSetField(image, TIFFTAG_IMAGELENGTH, ibuf->y); - TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, ibuf->y); - TIFFSetField(image, TIFFTAG_COMPRESSION, compress_mode); - TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); - TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - - if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) { - xres = (float)(ibuf->ppm[0] * 0.0254); - yres = (float)(ibuf->ppm[1] * 0.0254); - } - else { - xres = yres = IMB_DPI_DEFAULT; - } - - TIFFSetField(image, TIFFTAG_XRESOLUTION, xres); - TIFFSetField(image, TIFFTAG_YRESOLUTION, yres); - TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); - if (TIFFWriteEncodedStrip(image, - 0, - (bitspersample == 16) ? (uchar *)pixels16 : pixels, - (size_t)ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == - -1) { - fprintf(stderr, "imb_savetiff: Could not write encoded TIFF.\n"); - TIFFClose(image); - if (pixels) { - _TIFFfree(pixels); - } - if (pixels16) { - _TIFFfree(pixels16); - } - return 1; - } - - /* close the TIFF file */ - TIFFClose(image); - if (pixels) { - _TIFFfree(pixels); - } - if (pixels16) { - _TIFFfree(pixels16); - } - return 1; -} - -/** \} */ diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index d2fb6dc584d..1543ac1c7f2 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -41,26 +41,18 @@ #define UTIL_DEBUG 0 const char *imb_ext_image[] = { - ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb", ".rgba", -#ifdef WITH_TIFF - ".tif", ".tiff", ".tx", -#endif + ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb", ".rgba", ".tif", ".tiff", ".tx", #ifdef WITH_OPENJPEG ".jp2", ".j2c", #endif -#ifdef WITH_HDR - ".hdr", -#endif -#ifdef WITH_DDS - ".dds", -#endif + ".hdr", ".dds", #ifdef WITH_CINEON ".dpx", ".cin", #endif #ifdef WITH_OPENEXR ".exr", #endif - ".psd", ".pdd", ".psb", + ".psd", ".pdd", ".psb", #ifdef WITH_WEBP ".webp", #endif diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c index 6ea3bf73363..5128776d0d6 100644 --- a/source/blender/imbuf/intern/util_gpu.c +++ b/source/blender/imbuf/intern/util_gpu.c @@ -80,7 +80,6 @@ static const char *imb_gpu_get_swizzle(const ImBuf *ibuf) } /* Return false if no suitable format was found. */ -#ifdef WITH_DDS static bool IMB_gpu_get_compressed_format(const ImBuf *ibuf, eGPUTextureFormat *r_texture_format) { /* For DDS we only support data, scene linear and sRGB. Converting to @@ -102,7 +101,6 @@ static bool IMB_gpu_get_compressed_format(const ImBuf *ibuf, eGPUTextureFormat * } return true; } -#endif /** * Apply colormanagement and scale buffer if needed. @@ -326,7 +324,6 @@ GPUTexture *IMB_create_gpu_texture(const char *name, } } -#ifdef WITH_DDS if (ibuf->ftype == IMB_FTYPE_DDS) { eGPUTextureFormat compressed_format; if (!IMB_gpu_get_compressed_format(ibuf, &compressed_format)) { @@ -356,7 +353,6 @@ GPUTexture *IMB_create_gpu_texture(const char *name, /* Fallback to uncompressed texture. */ fprintf(stderr, " falling back to uncompressed.\n"); } -#endif eGPUDataFormat data_format; eGPUTextureFormat tex_format; diff --git a/source/blender/io/gpencil/CMakeLists.txt b/source/blender/io/gpencil/CMakeLists.txt index 725919a1622..120c813d9e4 100644 --- a/source/blender/io/gpencil/CMakeLists.txt +++ b/source/blender/io/gpencil/CMakeLists.txt @@ -70,6 +70,11 @@ if(WITH_HARU) ) list(APPEND LIB ${HARU_LIBRARIES} + + # Haru needs `TIFFFaxBlackCodes` & `TIFFFaxWhiteCodes` symbols from TIFF. + # Can be removed with Haru 2.4.0. They should be shipping with their own + # Fax codes defined by default from that version onwards. + ${TIFF_LIBRARY} ) add_definitions(-DWITH_HARU) endif() diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 46dd420bbf0..5d5e5cdcbb3 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -245,26 +245,14 @@ if(WITH_IMAGE_OPENEXR) add_definitions(-DWITH_OPENEXR) endif() -if(WITH_IMAGE_TIFF) - add_definitions(-DWITH_TIFF) -endif() - if(WITH_IMAGE_OPENJPEG) add_definitions(-DWITH_OPENJPEG) endif() -if(WITH_IMAGE_DDS) - add_definitions(-DWITH_DDS) -endif() - if(WITH_IMAGE_CINEON) add_definitions(-DWITH_CINEON) endif() -if(WITH_IMAGE_HDR) - add_definitions(-DWITH_HDR) -endif() - if(WITH_IMAGE_WEBP) add_definitions(-DWITH_WEBP) endif() diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 9bf2cf21107..fe8ec52f1ef 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -280,12 +280,8 @@ const EnumPropertyItem rna_enum_curve_fit_method_items[] = { "Output image in uncompressed Targa format"}, #if 0 /* UNUSED (so far) */ -# ifdef WITH_DDS -# define R_IMF_ENUM_DDS \ - {R_IMF_IMTYPE_DDS, "DDS", ICON_FILE_IMAGE, "DDS", "Output image in DDS format"}, -# else -# define R_IMF_ENUM_DDS -# endif +# define R_IMF_ENUM_DDS \ + {R_IMF_IMTYPE_DDS, "DDS", ICON_FILE_IMAGE, "DDS", "Output image in DDS format"}, #endif #ifdef WITH_OPENJPEG @@ -327,23 +323,15 @@ const EnumPropertyItem rna_enum_curve_fit_method_items[] = { # define R_IMF_ENUM_EXR #endif -#ifdef WITH_HDR -# define R_IMF_ENUM_HDR \ - {R_IMF_IMTYPE_RADHDR, \ - "HDR", \ - ICON_FILE_IMAGE, \ - "Radiance HDR", \ - "Output image in Radiance HDR format"}, -#else -# define R_IMF_ENUM_HDR -#endif +#define R_IMF_ENUM_HDR \ + {R_IMF_IMTYPE_RADHDR, \ + "HDR", \ + ICON_FILE_IMAGE, \ + "Radiance HDR", \ + "Output image in Radiance HDR format"}, -#ifdef WITH_TIFF -# define R_IMF_ENUM_TIFF \ - {R_IMF_IMTYPE_TIFF, "TIFF", ICON_FILE_IMAGE, "TIFF", "Output image in TIFF format"}, -#else -# define R_IMF_ENUM_TIFF -#endif +#define R_IMF_ENUM_TIFF \ + {R_IMF_IMTYPE_TIFF, "TIFF", ICON_FILE_IMAGE, "TIFF", "Output image in TIFF format"}, #ifdef WITH_WEBP # define R_IMF_ENUM_WEBP \ @@ -5726,7 +5714,6 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna) }; # endif -# ifdef WITH_TIFF static const EnumPropertyItem tiff_codec_items[] = { {R_IMF_TIFF_CODEC_NONE, "NONE", 0, "None", ""}, {R_IMF_TIFF_CODEC_DEFLATE, "DEFLATE", 0, "Deflate", ""}, @@ -5734,7 +5721,6 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna) {R_IMF_TIFF_CODEC_PACKBITS, "PACKBITS", 0, "Pack Bits", ""}, {0, NULL, 0, NULL, NULL}, }; -# endif static const EnumPropertyItem color_management_items[] = { {R_IMF_COLOR_MANAGEMENT_FOLLOW_SCENE, "FOLLOW_SCENE", 0, "Follow Scene", ""}, @@ -5851,14 +5837,12 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); # endif -# ifdef WITH_TIFF /* TIFF */ prop = RNA_def_property(srna, "tiff_codec", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "tiff_codec"); RNA_def_property_enum_items(prop, tiff_codec_items); RNA_def_property_ui_text(prop, "Compression", "Compression mode for TIFF"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); -# endif /* Cineon and DPX */ diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index aa24ca385c1..ab857f1c16c 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -208,14 +208,6 @@ if(WITH_IMAGE_CINEON) add_definitions(-DWITH_CINEON) endif() -if(WITH_IMAGE_DDS) - add_definitions(-DWITH_DDS) -endif() - -if(WITH_IMAGE_HDR) - add_definitions(-DWITH_HDR) -endif() - if(WITH_IMAGE_OPENEXR) add_definitions(-DWITH_OPENEXR) endif() @@ -224,10 +216,6 @@ if(WITH_IMAGE_OPENJPEG) add_definitions(-DWITH_OPENJPEG) endif() -if(WITH_IMAGE_TIFF) - add_definitions(-DWITH_TIFF) -endif() - if(WITH_WEBP) add_definitions(-DWITH_WEBP) endif() diff --git a/source/blender/python/intern/bpy_app_build_options.c b/source/blender/python/intern/bpy_app_build_options.c index f4596f50cd0..e6aeb7a6628 100644 --- a/source/blender/python/intern/bpy_app_build_options.c +++ b/source/blender/python/intern/bpy_app_build_options.c @@ -135,17 +135,11 @@ static PyObject *make_builtopts_info(void) SetObjIncref(Py_False); #endif -#ifdef WITH_DDS + /* DDS */ SetObjIncref(Py_True); -#else - SetObjIncref(Py_False); -#endif -#ifdef WITH_HDR + /* HDR */ SetObjIncref(Py_True); -#else - SetObjIncref(Py_False); -#endif #ifdef WITH_OPENEXR SetObjIncref(Py_True); @@ -159,11 +153,8 @@ static PyObject *make_builtopts_info(void) SetObjIncref(Py_False); #endif -#ifdef WITH_TIFF + /* TIFF */ SetObjIncref(Py_True); -#else - SetObjIncref(Py_False); -#endif #ifdef WITH_INPUT_NDOF SetObjIncref(Py_True); diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 7c5b785d846..224aa983175 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -946,18 +946,12 @@ else() if(WITH_IMAGE_CINEON) set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} CINEON") endif() - if(WITH_IMAGE_HDR) - set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} HDR") - endif() if(WITH_IMAGE_OPENEXR) set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} OPENEXR") endif() if(WITH_IMAGE_OPENJPEG) set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} OPENJPEG") endif() - if(WITH_IMAGE_TIFF) - set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} TIFF") - endif() if(WITH_IMAGE_WEBP) set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} WEBP") endif() diff --git a/tests/python/bl_imbuf_load.py b/tests/python/bl_imbuf_load.py index 5e0559aaef5..9ccc25168e4 100644 --- a/tests/python/bl_imbuf_load.py +++ b/tests/python/bl_imbuf_load.py @@ -119,16 +119,12 @@ class ImBufLoadTest(ImBufTest): self.check("*.exr") def test_load_hdr(self): - self.skip_if_format_missing("HDR") - self.check("*.hdr") def test_load_targa(self): self.check("*.tga") def test_load_tiff(self): - self.skip_if_format_missing("TIFF") - self.check("*.tif") def test_load_jpeg(self): @@ -141,8 +137,6 @@ class ImBufLoadTest(ImBufTest): self.check("*.j2c") def test_load_dpx(self): - self.skip_if_format_missing("CINEON") - self.check("*.dpx") def test_load_cineon(self): diff --git a/tests/python/bl_imbuf_save.py b/tests/python/bl_imbuf_save.py index 33c249365ae..acebfbf881b 100644 --- a/tests/python/bl_imbuf_save.py +++ b/tests/python/bl_imbuf_save.py @@ -130,8 +130,6 @@ class ImBufSaveTest(ImBufTest): self.check(src="rgba32", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "RGBA", "color_depth": "32", "exr_codec": "ZIP"}) def test_save_hdr(self): - self.skip_if_format_missing("HDR") - self.check(src="rgba08", ext="hdr", settings={"file_format": "HDR", "color_mode": "BW"}) self.check(src="rgba08", ext="hdr", settings={"file_format": "HDR", "color_mode": "RGB"}) @@ -157,8 +155,6 @@ class ImBufSaveTest(ImBufTest): self.check(src="rgba32", ext="tga", settings={"file_format": "TARGA_RAW", "color_mode": "RGBA"}) def test_save_tiff(self): - self.skip_if_format_missing("TIFF") - self.check(src="rgba08", ext="tif", settings={"file_format": "TIFF", "color_mode": "BW", "color_depth": "8", "tiff_codec": "DEFLATE"}) self.check(src="rgba08", ext="tif", settings={"file_format": "TIFF", "color_mode": "RGB", "color_depth": "8", "tiff_codec": "LZW"}) self.check(src="rgba08", ext="tif", settings={"file_format": "TIFF", "color_mode": "RGBA", "color_depth": "8", "tiff_codec": "PACKBITS"}) @@ -216,8 +212,6 @@ class ImBufSaveTest(ImBufTest): self.check(src="rgba32", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGBA", "color_depth": "16", "jpeg2k_codec": "JP2", "use_jpeg2k_cinema_preset": False, "use_jpeg2k_cinema_48": False, "use_jpeg2k_ycc": True, "quality": 70}) def test_save_dpx(self): - self.skip_if_format_missing("CINEON") - self.check(src="rgba08", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGB", "color_depth": "8", "use_cineon_log": False}) self.check(src="rgba08", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGB", "color_depth": "12", "use_cineon_log": False}) self.check(src="rgba08", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGB", "color_depth": "16", "use_cineon_log": False})