diff --git a/include/vtfpp/ImageConversion.h b/include/vtfpp/ImageConversion.h index aed14cd6..79eb5664 100644 --- a/include/vtfpp/ImageConversion.h +++ b/include/vtfpp/ImageConversion.h @@ -28,6 +28,18 @@ constexpr float DEFAULT_COMPRESSED_QUALITY = -1.f; /// Fails (returns empty vectors) if the input data is empty, the given width is not 2x the height, or an error was encountered. [[nodiscard]] std::array, 6> convertHDRIToCubeMap(std::span imageData, ImageFormat format, uint16_t width, uint16_t height, uint16_t resolution = 0, bool bilinear = true); +/// Takes in RGBA32323232F format image data, returns SOURCEPP_BGRA8888_HDR compressed HDR image data (alias for BGRA8888) +[[nodiscard]] std::vector compressBGRA8888HDR(std::span imageData, float overbrightFactor = 16.f); + +/// Takes in SOURCEPP_BGRA8888_HDR compressed HDR image data (alias for BGRA8888), returns RGBA32323232F format image data +[[nodiscard]] std::vector decompressBGRA8888HDR(std::span imageData, float overbrightFactor = 16.f); + +/// Takes in RGBA32323232F format image data, returns SOURCEPP_RGBA16161616_HDR compressed HDR image data (alias for RGBA16161616) +[[nodiscard]] std::vector compressRGBA16161616HDR(std::span imageData, bool flipExponentAndSignificand = false); + +/// Takes in SOURCEPP_RGBA16161616_HDR compressed HDR image data (alias for RGBA16161616), returns RGBA32323232F format image data +[[nodiscard]] std::vector decompressRGBA16161616HDR(std::span imageData, bool flipExponentAndSignificand = false); + enum class FileFormat { DEFAULT = 0, PNG = 1, diff --git a/include/vtfpp/ImageFormats.h b/include/vtfpp/ImageFormats.h index 14e4995c..60fb6a1e 100644 --- a/include/vtfpp/ImageFormats.h +++ b/include/vtfpp/ImageFormats.h @@ -81,6 +81,12 @@ enum class ImageFormat : int32_t { STRATA_BC7, STRATA_BC6H, // endregion + + // region SourcePP Virtual Formats + SOURCEPP_BGRA8888_HDR = 10000, + SOURCEPP_RGBA16161616_HDR, + SOURCEPP_CONSOLE_RGBA16161616_HDR, + // endregion }; namespace ImageFormatDetails { @@ -157,6 +163,9 @@ namespace ImageFormatDetails { case TFALL2_BC7: case STRATA_BC7: case STRATA_BC6H: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: return -1; } return 0; @@ -182,6 +191,9 @@ namespace ImageFormatDetails { return 8; case TFALL2_BC6H: case STRATA_BC6H: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: return 16; default: break; @@ -262,6 +274,9 @@ namespace ImageFormatDetails { case TFALL2_BC7: case STRATA_BC7: case STRATA_BC6H: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: return -1; } return 0; @@ -287,6 +302,9 @@ namespace ImageFormatDetails { return 8; case TFALL2_BC6H: case STRATA_BC6H: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: return 16; default: break; @@ -366,6 +384,9 @@ namespace ImageFormatDetails { case TFALL2_BC7: case STRATA_BC7: case STRATA_BC6H: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: return -1; } return 0; @@ -391,6 +412,9 @@ namespace ImageFormatDetails { return 8; case TFALL2_BC6H: case STRATA_BC6H: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: return 16; default: break; @@ -470,6 +494,9 @@ namespace ImageFormatDetails { case TFALL2_BC7: case STRATA_BC7: case STRATA_BC6H: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: return -1; } return 0; @@ -497,6 +524,9 @@ namespace ImageFormatDetails { case ATI1N: case TFALL2_BC6H: case STRATA_BC6H: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: return 0; default: break; @@ -520,6 +550,8 @@ namespace ImageFormatDetails { case RGBA16161616F: case RGBA16161616: case CONSOLE_RGBA16161616_LINEAR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: case RG3232F: return 64; case RGBA8888: @@ -531,6 +563,7 @@ namespace ImageFormatDetails { case BGRA8888: case CONSOLE_BGRA8888_LINEAR: case CONSOLE_BGRA8888_LE: + case SOURCEPP_BGRA8888_HDR: case BGRX8888: case CONSOLE_BGRX8888_LINEAR: case CONSOLE_BGRX8888_LE: @@ -602,6 +635,9 @@ namespace ImageFormatDetails { case RGBA32323232F: case TFALL2_BC6H: case STRATA_BC6H: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: return RGBA32323232F; case RGBA16161616: case CONSOLE_RGBA16161616_LINEAR: @@ -676,7 +712,7 @@ namespace ImageFormatDetails { } /** - * Check if the given format is a compressed format (DXT1, DXT3, DXT5, ATI1N, ATI2N, BC7, BC6H). + * Check if the given format is a compressed format (DXT1, DXT3, DXT5, ATI1N, ATI2N, BC7, BC6H, BGRA8888 HDR, RGBA16161616 HDR). * @param format The format to check. * @return True if the given format is compressed. */ @@ -684,6 +720,24 @@ namespace ImageFormatDetails { return red(format) == -1; } +/** + * Check if the given format is a compressed HDR format (not counting BC6H). + * @param format The format to check. + * @return True if the format is a compressed HDR format.. + */ +[[nodiscard]] constexpr bool compressedHDR(ImageFormat format) { + switch (format) { + using enum ImageFormat; + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: + return true; + default: + break; + } + return false; +} + /** * Check if the given format can store transparency. * @param format The format to check. @@ -757,6 +811,42 @@ namespace ImageFormatDetails { case CONSOLE_RGBA16161616_LINEAR: case CONSOLE_BGRX8888_LE: case CONSOLE_BGRA8888_LE: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: + return true; + default: + break; + } + return false; +} + +/** + * Check if the given format is exclusively used by Titanfall 2. + * @param format The format to check. + * @return True if the format is exclusively used by Titanfall 2. + */ +[[nodiscard]] constexpr bool tfall2(ImageFormat format) { + switch (format) { + using enum ImageFormat; + case TFALL2_BC6H: + case TFALL2_BC7: + return true; + default: + break; + } + return false; +} + +/** + * Check if the given format is exclusively used by Strata Source. + * @param format The format to check. + * @return True if the format is exclusively used by Strata Source. + */ +[[nodiscard]] constexpr bool strata(ImageFormat format) { + switch (format) { + using enum ImageFormat; + case STRATA_R8: + case STRATA_BC7: + case STRATA_BC6H: return true; default: break; @@ -869,7 +959,7 @@ namespace ImageFormatDetails { * @return The length in bytes of a texture containing the given format, width, height, and depth. */ [[nodiscard]] constexpr uint32_t getDataLength(ImageFormat format, uint16_t width, uint16_t height, uint16_t depth = 1) { - if (ImageFormatDetails::compressed(format)) { + if (ImageFormatDetails::compressed(format) && !ImageFormatDetails::compressedHDR(format)) { return ((width + 3) / 4) * ((height + 3) / 4) * depth * bpp(format) * 2; } return width * height * depth * (bpp(format) / 8); diff --git a/include/vtfpp/ImagePixel.h b/include/vtfpp/ImagePixel.h index ce8fbcb8..4b048b71 100644 --- a/include/vtfpp/ImagePixel.h +++ b/include/vtfpp/ImagePixel.h @@ -417,6 +417,27 @@ VTFPP_FORMAT( VTFPP_R ); +VTFPP_FORMAT( + SOURCEPP_BGRA8888_HDR, + VTFPP_FORMAT_LE(uint8_t r, g, b, a) + VTFPP_FORMAT_BE(uint8_t a, b, g, r), + VTFPP_R VTFPP_G VTFPP_B VTFPP_A +); + +VTFPP_FORMAT( + SOURCEPP_RGBA16161616_HDR, + VTFPP_FORMAT_LE(uint16_t r, g, b, a) + VTFPP_FORMAT_BE(uint16_t a, b, g, r), + VTFPP_R VTFPP_G VTFPP_B VTFPP_A +); + +VTFPP_FORMAT( + SOURCEPP_CONSOLE_RGBA16161616_HDR, + VTFPP_FORMAT_LE(uint16_t r, g, b, a) + VTFPP_FORMAT_BE(uint16_t a, b, g, r), + VTFPP_R VTFPP_G VTFPP_B VTFPP_A +); + #undef VTFPP_FORMAT #undef VTFPP_FORMAT_BE #undef VTFPP_FORMAT_LE @@ -487,7 +508,10 @@ concept PixelType = std::same_as || std::same_as || std::same_as || - std::same_as; + std::same_as || + std::same_as || + std::same_as || + std::same_as; /// Extracts a single channel from the given image data. /// May have unexpected behavior if called on formats that use bitfields like BGRA5551! diff --git a/include/vtfpp/VTF.h b/include/vtfpp/VTF.h index dabfef7c..d80aa830 100644 --- a/include/vtfpp/VTF.h +++ b/include/vtfpp/VTF.h @@ -228,9 +228,9 @@ class VTF { VTF(); - explicit VTF(std::vector&& vtfData, bool parseHeaderOnly = false); + explicit VTF(std::vector&& vtfData, bool parseHeaderOnly = false, bool hdr = false); - explicit VTF(std::span vtfData, bool parseHeaderOnly = false); + explicit VTF(std::span vtfData, bool parseHeaderOnly = false, bool hdr = false); explicit VTF(const std::filesystem::path& vtfPath, bool parseHeaderOnly = false); diff --git a/lang/c/include/vtfppc/ImageConversion.h b/lang/c/include/vtfppc/ImageConversion.h index 691fa418..dcf8bc7c 100644 --- a/lang/c/include/vtfppc/ImageConversion.h +++ b/lang/c/include/vtfppc/ImageConversion.h @@ -11,8 +11,11 @@ VTFPP_EXTERNVAR const float VTFPP_IMAGE_CONVERSION_DEFAULT_COMPRESSED_QUALITY; VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_image_data_to_format(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e oldFormat, vtfpp_image_format_e newFormat, uint16_t width, uint16_t height, float quality); // REQUIRES MANUAL FREE: sourcepp_buffer_free VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_several_image_data_to_format(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e oldFormat, vtfpp_image_format_e newFormat, uint8_t mipCount, uint16_t frameCount, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t depth, float quality); // REQUIRES MANUAL FREE: sourcepp_buffer_free -VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_hdri_to_cubemap(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height); // REQUIRES MANUAL FREE: sourcepp_buffer_free -VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_hdri_to_cubemap_ex(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, uint16_t resolution, int bilinear); // REQUIRES MANUAL FREE: sourcepp_buffer_free +VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_hdri_to_cubemap(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, uint16_t resolution, int bilinear); // REQUIRES MANUAL FREE: sourcepp_buffer_free +VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_compress_bgra8888_hdr(const unsigned char* buffer, size_t bufferLen, float overbrightFactor); // REQUIRES MANUAL FREE: sourcepp_buffer_free +VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_decompress_bgra8888_hdr(const unsigned char* buffer, size_t bufferLen, float overbrightFactor); // REQUIRES MANUAL FREE: sourcepp_buffer_free +VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_compress_rgba16161616_hdr(const unsigned char* buffer, size_t bufferLen, int flipExponentAndSignificand); // REQUIRES MANUAL FREE: sourcepp_buffer_free +VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_decompress_rgba16161616_hdr(const unsigned char* buffer, size_t bufferLen, int flipExponentAndSignificand); // REQUIRES MANUAL FREE: sourcepp_buffer_free VTFPP_EXTERN typedef enum { VTFPP_IMAGE_CONVERSION_FILE_FORMAT_DEFAULT = 0, diff --git a/lang/c/include/vtfppc/ImageFormats.h b/lang/c/include/vtfppc/ImageFormats.h index 6347e0c6..25f46af2 100644 --- a/lang/c/include/vtfppc/ImageFormats.h +++ b/lang/c/include/vtfppc/ImageFormats.h @@ -62,6 +62,10 @@ VTFPP_EXTERN typedef enum { VTFPP_IMAGE_FORMAT_STRATA_R8 = 69, VTFPP_IMAGE_FORMAT_STRATA_BC7, VTFPP_IMAGE_FORMAT_STRATA_BC6H, + + VTFPP_IMAGE_FORMAT_SOURCEPP_BGRA8888_HDR = 10000, + VTFPP_IMAGE_FORMAT_SOURCEPP_RGBA16161616_HDR, + VTFPP_IMAGE_FORMAT_SOURCEPP_CONSOLE_RGBA16161616_HDR, } vtfpp_image_format_e; VTFPP_API int8_t vtfpp_image_format_details_red(vtfpp_image_format_e format); @@ -77,9 +81,12 @@ VTFPP_API vtfpp_image_format_e vtfpp_image_format_details_container_format(vtfpp VTFPP_API int vtfpp_image_format_details_large(vtfpp_image_format_e format); VTFPP_API int vtfpp_image_format_details_decimal(vtfpp_image_format_e format); VTFPP_API int vtfpp_image_format_details_compressed(vtfpp_image_format_e format); +VTFPP_API int vtfpp_image_format_details_compressed_hdr(vtfpp_image_format_e format); VTFPP_API int vtfpp_image_format_details_transparent(vtfpp_image_format_e format); VTFPP_API int vtfpp_image_format_details_opaque(vtfpp_image_format_e format); VTFPP_API int vtfpp_image_format_details_console(vtfpp_image_format_e format); +VTFPP_API int vtfpp_image_format_details_tfall2(vtfpp_image_format_e format); +VTFPP_API int vtfpp_image_format_details_strata(vtfpp_image_format_e format); VTFPP_API uint16_t vtfpp_image_dimensions_get_mip_dim(uint8_t mip, uint16_t dim, int addCompressedFormatPadding); // Skipping vtfpp::ImageDimensions::getMipDims @@ -100,124 +107,130 @@ namespace sourceppc::convert { inline vtfpp::ImageFormat cast(vtfpp_image_format_e value) { switch (value) { - case VTFPP_IMAGE_FORMAT_RGBA8888: return vtfpp::ImageFormat::RGBA8888; - case VTFPP_IMAGE_FORMAT_ABGR8888: return vtfpp::ImageFormat::ABGR8888; - case VTFPP_IMAGE_FORMAT_RGB888: return vtfpp::ImageFormat::RGB888; - case VTFPP_IMAGE_FORMAT_BGR888: return vtfpp::ImageFormat::BGR888; - case VTFPP_IMAGE_FORMAT_RGB565: return vtfpp::ImageFormat::RGB565; - case VTFPP_IMAGE_FORMAT_I8: return vtfpp::ImageFormat::I8; - case VTFPP_IMAGE_FORMAT_IA88: return vtfpp::ImageFormat::IA88; - case VTFPP_IMAGE_FORMAT_P8: return vtfpp::ImageFormat::P8; - case VTFPP_IMAGE_FORMAT_A8: return vtfpp::ImageFormat::A8; - case VTFPP_IMAGE_FORMAT_RGB888_BLUESCREEN: return vtfpp::ImageFormat::RGB888_BLUESCREEN; - case VTFPP_IMAGE_FORMAT_BGR888_BLUESCREEN: return vtfpp::ImageFormat::BGR888_BLUESCREEN; - case VTFPP_IMAGE_FORMAT_ARGB8888: return vtfpp::ImageFormat::ARGB8888; - case VTFPP_IMAGE_FORMAT_BGRA8888: return vtfpp::ImageFormat::BGRA8888; - case VTFPP_IMAGE_FORMAT_DXT1: return vtfpp::ImageFormat::DXT1; - case VTFPP_IMAGE_FORMAT_DXT3: return vtfpp::ImageFormat::DXT3; - case VTFPP_IMAGE_FORMAT_DXT5: return vtfpp::ImageFormat::DXT5; - case VTFPP_IMAGE_FORMAT_BGRX8888: return vtfpp::ImageFormat::BGRX8888; - case VTFPP_IMAGE_FORMAT_BGR565: return vtfpp::ImageFormat::BGR565; - case VTFPP_IMAGE_FORMAT_BGRX5551: return vtfpp::ImageFormat::BGRX5551; - case VTFPP_IMAGE_FORMAT_BGRA4444: return vtfpp::ImageFormat::BGRA4444; - case VTFPP_IMAGE_FORMAT_DXT1_ONE_BIT_ALPHA: return vtfpp::ImageFormat::DXT1_ONE_BIT_ALPHA; - case VTFPP_IMAGE_FORMAT_BGRA5551: return vtfpp::ImageFormat::BGRA5551; - case VTFPP_IMAGE_FORMAT_UV88: return vtfpp::ImageFormat::UV88; - case VTFPP_IMAGE_FORMAT_UVWQ8888: return vtfpp::ImageFormat::UVWQ8888; - case VTFPP_IMAGE_FORMAT_RGBA16161616F: return vtfpp::ImageFormat::RGBA16161616F; - case VTFPP_IMAGE_FORMAT_RGBA16161616: return vtfpp::ImageFormat::RGBA16161616; - case VTFPP_IMAGE_FORMAT_UVLX8888: return vtfpp::ImageFormat::UVLX8888; - case VTFPP_IMAGE_FORMAT_R32F: return vtfpp::ImageFormat::R32F; - case VTFPP_IMAGE_FORMAT_RGB323232F: return vtfpp::ImageFormat::RGB323232F; - case VTFPP_IMAGE_FORMAT_RGBA32323232F: return vtfpp::ImageFormat::RGBA32323232F; - case VTFPP_IMAGE_FORMAT_RG1616F: return vtfpp::ImageFormat::RG1616F; - case VTFPP_IMAGE_FORMAT_RG3232F: return vtfpp::ImageFormat::RG3232F; - case VTFPP_IMAGE_FORMAT_RGBX8888: return vtfpp::ImageFormat::RGBX8888; - case VTFPP_IMAGE_FORMAT_EMPTY: return vtfpp::ImageFormat::EMPTY; - case VTFPP_IMAGE_FORMAT_ATI2N: return vtfpp::ImageFormat::ATI2N; - case VTFPP_IMAGE_FORMAT_ATI1N: return vtfpp::ImageFormat::ATI1N; - case VTFPP_IMAGE_FORMAT_RGBA1010102: return vtfpp::ImageFormat::RGBA1010102; - case VTFPP_IMAGE_FORMAT_BGRA1010102: return vtfpp::ImageFormat::BGRA1010102; - case VTFPP_IMAGE_FORMAT_R16F: return vtfpp::ImageFormat::R16F; - case VTFPP_IMAGE_FORMAT_CONSOLE_BGRX8888_LINEAR: return vtfpp::ImageFormat::CONSOLE_BGRX8888_LINEAR; - case VTFPP_IMAGE_FORMAT_CONSOLE_RGBA8888_LINEAR: return vtfpp::ImageFormat::CONSOLE_RGBA8888_LINEAR; - case VTFPP_IMAGE_FORMAT_CONSOLE_ABGR8888_LINEAR: return vtfpp::ImageFormat::CONSOLE_ABGR8888_LINEAR; - case VTFPP_IMAGE_FORMAT_CONSOLE_ARGB8888_LINEAR: return vtfpp::ImageFormat::CONSOLE_ARGB8888_LINEAR; - case VTFPP_IMAGE_FORMAT_CONSOLE_BGRA8888_LINEAR: return vtfpp::ImageFormat::CONSOLE_BGRA8888_LINEAR; - case VTFPP_IMAGE_FORMAT_CONSOLE_RGB888_LINEAR: return vtfpp::ImageFormat::CONSOLE_RGB888_LINEAR; - case VTFPP_IMAGE_FORMAT_CONSOLE_BGR888_LINEAR: return vtfpp::ImageFormat::CONSOLE_BGR888_LINEAR; - case VTFPP_IMAGE_FORMAT_CONSOLE_BGRX5551_LINEAR: return vtfpp::ImageFormat::CONSOLE_BGRX5551_LINEAR; - case VTFPP_IMAGE_FORMAT_CONSOLE_I8_LINEAR: return vtfpp::ImageFormat::CONSOLE_I8_LINEAR; - case VTFPP_IMAGE_FORMAT_CONSOLE_RGBA16161616_LINEAR: return vtfpp::ImageFormat::CONSOLE_RGBA16161616_LINEAR; - case VTFPP_IMAGE_FORMAT_CONSOLE_BGRX8888_LE: return vtfpp::ImageFormat::CONSOLE_BGRX8888_LE; - case VTFPP_IMAGE_FORMAT_CONSOLE_BGRA8888_LE: return vtfpp::ImageFormat::CONSOLE_BGRA8888_LE; - case VTFPP_IMAGE_FORMAT_TFALL2_BC6H: return vtfpp::ImageFormat::TFALL2_BC6H; - case VTFPP_IMAGE_FORMAT_TFALL2_BC7: return vtfpp::ImageFormat::TFALL2_BC7; - case VTFPP_IMAGE_FORMAT_STRATA_R8: return vtfpp::ImageFormat::STRATA_R8; - case VTFPP_IMAGE_FORMAT_STRATA_BC7: return vtfpp::ImageFormat::STRATA_BC7; - case VTFPP_IMAGE_FORMAT_STRATA_BC6H: return vtfpp::ImageFormat::STRATA_BC6H; + case VTFPP_IMAGE_FORMAT_RGBA8888: return vtfpp::ImageFormat::RGBA8888; + case VTFPP_IMAGE_FORMAT_ABGR8888: return vtfpp::ImageFormat::ABGR8888; + case VTFPP_IMAGE_FORMAT_RGB888: return vtfpp::ImageFormat::RGB888; + case VTFPP_IMAGE_FORMAT_BGR888: return vtfpp::ImageFormat::BGR888; + case VTFPP_IMAGE_FORMAT_RGB565: return vtfpp::ImageFormat::RGB565; + case VTFPP_IMAGE_FORMAT_I8: return vtfpp::ImageFormat::I8; + case VTFPP_IMAGE_FORMAT_IA88: return vtfpp::ImageFormat::IA88; + case VTFPP_IMAGE_FORMAT_P8: return vtfpp::ImageFormat::P8; + case VTFPP_IMAGE_FORMAT_A8: return vtfpp::ImageFormat::A8; + case VTFPP_IMAGE_FORMAT_RGB888_BLUESCREEN: return vtfpp::ImageFormat::RGB888_BLUESCREEN; + case VTFPP_IMAGE_FORMAT_BGR888_BLUESCREEN: return vtfpp::ImageFormat::BGR888_BLUESCREEN; + case VTFPP_IMAGE_FORMAT_ARGB8888: return vtfpp::ImageFormat::ARGB8888; + case VTFPP_IMAGE_FORMAT_BGRA8888: return vtfpp::ImageFormat::BGRA8888; + case VTFPP_IMAGE_FORMAT_DXT1: return vtfpp::ImageFormat::DXT1; + case VTFPP_IMAGE_FORMAT_DXT3: return vtfpp::ImageFormat::DXT3; + case VTFPP_IMAGE_FORMAT_DXT5: return vtfpp::ImageFormat::DXT5; + case VTFPP_IMAGE_FORMAT_BGRX8888: return vtfpp::ImageFormat::BGRX8888; + case VTFPP_IMAGE_FORMAT_BGR565: return vtfpp::ImageFormat::BGR565; + case VTFPP_IMAGE_FORMAT_BGRX5551: return vtfpp::ImageFormat::BGRX5551; + case VTFPP_IMAGE_FORMAT_BGRA4444: return vtfpp::ImageFormat::BGRA4444; + case VTFPP_IMAGE_FORMAT_DXT1_ONE_BIT_ALPHA: return vtfpp::ImageFormat::DXT1_ONE_BIT_ALPHA; + case VTFPP_IMAGE_FORMAT_BGRA5551: return vtfpp::ImageFormat::BGRA5551; + case VTFPP_IMAGE_FORMAT_UV88: return vtfpp::ImageFormat::UV88; + case VTFPP_IMAGE_FORMAT_UVWQ8888: return vtfpp::ImageFormat::UVWQ8888; + case VTFPP_IMAGE_FORMAT_RGBA16161616F: return vtfpp::ImageFormat::RGBA16161616F; + case VTFPP_IMAGE_FORMAT_RGBA16161616: return vtfpp::ImageFormat::RGBA16161616; + case VTFPP_IMAGE_FORMAT_UVLX8888: return vtfpp::ImageFormat::UVLX8888; + case VTFPP_IMAGE_FORMAT_R32F: return vtfpp::ImageFormat::R32F; + case VTFPP_IMAGE_FORMAT_RGB323232F: return vtfpp::ImageFormat::RGB323232F; + case VTFPP_IMAGE_FORMAT_RGBA32323232F: return vtfpp::ImageFormat::RGBA32323232F; + case VTFPP_IMAGE_FORMAT_RG1616F: return vtfpp::ImageFormat::RG1616F; + case VTFPP_IMAGE_FORMAT_RG3232F: return vtfpp::ImageFormat::RG3232F; + case VTFPP_IMAGE_FORMAT_RGBX8888: return vtfpp::ImageFormat::RGBX8888; + case VTFPP_IMAGE_FORMAT_EMPTY: return vtfpp::ImageFormat::EMPTY; + case VTFPP_IMAGE_FORMAT_ATI2N: return vtfpp::ImageFormat::ATI2N; + case VTFPP_IMAGE_FORMAT_ATI1N: return vtfpp::ImageFormat::ATI1N; + case VTFPP_IMAGE_FORMAT_RGBA1010102: return vtfpp::ImageFormat::RGBA1010102; + case VTFPP_IMAGE_FORMAT_BGRA1010102: return vtfpp::ImageFormat::BGRA1010102; + case VTFPP_IMAGE_FORMAT_R16F: return vtfpp::ImageFormat::R16F; + case VTFPP_IMAGE_FORMAT_CONSOLE_BGRX8888_LINEAR: return vtfpp::ImageFormat::CONSOLE_BGRX8888_LINEAR; + case VTFPP_IMAGE_FORMAT_CONSOLE_RGBA8888_LINEAR: return vtfpp::ImageFormat::CONSOLE_RGBA8888_LINEAR; + case VTFPP_IMAGE_FORMAT_CONSOLE_ABGR8888_LINEAR: return vtfpp::ImageFormat::CONSOLE_ABGR8888_LINEAR; + case VTFPP_IMAGE_FORMAT_CONSOLE_ARGB8888_LINEAR: return vtfpp::ImageFormat::CONSOLE_ARGB8888_LINEAR; + case VTFPP_IMAGE_FORMAT_CONSOLE_BGRA8888_LINEAR: return vtfpp::ImageFormat::CONSOLE_BGRA8888_LINEAR; + case VTFPP_IMAGE_FORMAT_CONSOLE_RGB888_LINEAR: return vtfpp::ImageFormat::CONSOLE_RGB888_LINEAR; + case VTFPP_IMAGE_FORMAT_CONSOLE_BGR888_LINEAR: return vtfpp::ImageFormat::CONSOLE_BGR888_LINEAR; + case VTFPP_IMAGE_FORMAT_CONSOLE_BGRX5551_LINEAR: return vtfpp::ImageFormat::CONSOLE_BGRX5551_LINEAR; + case VTFPP_IMAGE_FORMAT_CONSOLE_I8_LINEAR: return vtfpp::ImageFormat::CONSOLE_I8_LINEAR; + case VTFPP_IMAGE_FORMAT_CONSOLE_RGBA16161616_LINEAR: return vtfpp::ImageFormat::CONSOLE_RGBA16161616_LINEAR; + case VTFPP_IMAGE_FORMAT_CONSOLE_BGRX8888_LE: return vtfpp::ImageFormat::CONSOLE_BGRX8888_LE; + case VTFPP_IMAGE_FORMAT_CONSOLE_BGRA8888_LE: return vtfpp::ImageFormat::CONSOLE_BGRA8888_LE; + case VTFPP_IMAGE_FORMAT_TFALL2_BC6H: return vtfpp::ImageFormat::TFALL2_BC6H; + case VTFPP_IMAGE_FORMAT_TFALL2_BC7: return vtfpp::ImageFormat::TFALL2_BC7; + case VTFPP_IMAGE_FORMAT_STRATA_R8: return vtfpp::ImageFormat::STRATA_R8; + case VTFPP_IMAGE_FORMAT_STRATA_BC7: return vtfpp::ImageFormat::STRATA_BC7; + case VTFPP_IMAGE_FORMAT_STRATA_BC6H: return vtfpp::ImageFormat::STRATA_BC6H; + case VTFPP_IMAGE_FORMAT_SOURCEPP_BGRA8888_HDR: return vtfpp::ImageFormat::SOURCEPP_BGRA8888_HDR; + case VTFPP_IMAGE_FORMAT_SOURCEPP_RGBA16161616_HDR: return vtfpp::ImageFormat::SOURCEPP_RGBA16161616_HDR; + case VTFPP_IMAGE_FORMAT_SOURCEPP_CONSOLE_RGBA16161616_HDR: return vtfpp::ImageFormat::SOURCEPP_CONSOLE_RGBA16161616_HDR; } return vtfpp::ImageFormat::RGBA8888; } inline vtfpp_image_format_e cast(vtfpp::ImageFormat value) { switch (value) { - case vtfpp::ImageFormat::RGBA8888: return VTFPP_IMAGE_FORMAT_RGBA8888; - case vtfpp::ImageFormat::ABGR8888: return VTFPP_IMAGE_FORMAT_ABGR8888; - case vtfpp::ImageFormat::RGB888: return VTFPP_IMAGE_FORMAT_RGB888; - case vtfpp::ImageFormat::BGR888: return VTFPP_IMAGE_FORMAT_BGR888; - case vtfpp::ImageFormat::RGB565: return VTFPP_IMAGE_FORMAT_RGB565; - case vtfpp::ImageFormat::I8: return VTFPP_IMAGE_FORMAT_I8; - case vtfpp::ImageFormat::IA88: return VTFPP_IMAGE_FORMAT_IA88; - case vtfpp::ImageFormat::P8: return VTFPP_IMAGE_FORMAT_P8; - case vtfpp::ImageFormat::A8: return VTFPP_IMAGE_FORMAT_A8; - case vtfpp::ImageFormat::RGB888_BLUESCREEN: return VTFPP_IMAGE_FORMAT_RGB888_BLUESCREEN; - case vtfpp::ImageFormat::BGR888_BLUESCREEN: return VTFPP_IMAGE_FORMAT_BGR888_BLUESCREEN; - case vtfpp::ImageFormat::ARGB8888: return VTFPP_IMAGE_FORMAT_ARGB8888; - case vtfpp::ImageFormat::BGRA8888: return VTFPP_IMAGE_FORMAT_BGRA8888; - case vtfpp::ImageFormat::DXT1: return VTFPP_IMAGE_FORMAT_DXT1; - case vtfpp::ImageFormat::DXT3: return VTFPP_IMAGE_FORMAT_DXT3; - case vtfpp::ImageFormat::DXT5: return VTFPP_IMAGE_FORMAT_DXT5; - case vtfpp::ImageFormat::BGRX8888: return VTFPP_IMAGE_FORMAT_BGRX8888; - case vtfpp::ImageFormat::BGR565: return VTFPP_IMAGE_FORMAT_BGR565; - case vtfpp::ImageFormat::BGRX5551: return VTFPP_IMAGE_FORMAT_BGRX5551; - case vtfpp::ImageFormat::BGRA4444: return VTFPP_IMAGE_FORMAT_BGRA4444; - case vtfpp::ImageFormat::DXT1_ONE_BIT_ALPHA: return VTFPP_IMAGE_FORMAT_DXT1_ONE_BIT_ALPHA; - case vtfpp::ImageFormat::BGRA5551: return VTFPP_IMAGE_FORMAT_BGRA5551; - case vtfpp::ImageFormat::UV88: return VTFPP_IMAGE_FORMAT_UV88; - case vtfpp::ImageFormat::UVWQ8888: return VTFPP_IMAGE_FORMAT_UVWQ8888; - case vtfpp::ImageFormat::RGBA16161616F: return VTFPP_IMAGE_FORMAT_RGBA16161616F; - case vtfpp::ImageFormat::RGBA16161616: return VTFPP_IMAGE_FORMAT_RGBA16161616; - case vtfpp::ImageFormat::UVLX8888: return VTFPP_IMAGE_FORMAT_UVLX8888; - case vtfpp::ImageFormat::R32F: return VTFPP_IMAGE_FORMAT_R32F; - case vtfpp::ImageFormat::RGB323232F: return VTFPP_IMAGE_FORMAT_RGB323232F; - case vtfpp::ImageFormat::RGBA32323232F: return VTFPP_IMAGE_FORMAT_RGBA32323232F; - case vtfpp::ImageFormat::RG1616F: return VTFPP_IMAGE_FORMAT_RG1616F; - case vtfpp::ImageFormat::RG3232F: return VTFPP_IMAGE_FORMAT_RG3232F; - case vtfpp::ImageFormat::RGBX8888: return VTFPP_IMAGE_FORMAT_RGBX8888; - case vtfpp::ImageFormat::EMPTY: return VTFPP_IMAGE_FORMAT_EMPTY; - case vtfpp::ImageFormat::ATI2N: return VTFPP_IMAGE_FORMAT_ATI2N; - case vtfpp::ImageFormat::ATI1N: return VTFPP_IMAGE_FORMAT_ATI1N; - case vtfpp::ImageFormat::RGBA1010102: return VTFPP_IMAGE_FORMAT_RGBA1010102; - case vtfpp::ImageFormat::BGRA1010102: return VTFPP_IMAGE_FORMAT_BGRA1010102; - case vtfpp::ImageFormat::R16F: return VTFPP_IMAGE_FORMAT_R16F; - case vtfpp::ImageFormat::CONSOLE_BGRX8888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_BGRX8888_LINEAR; - case vtfpp::ImageFormat::CONSOLE_RGBA8888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_RGBA8888_LINEAR; - case vtfpp::ImageFormat::CONSOLE_ABGR8888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_ABGR8888_LINEAR; - case vtfpp::ImageFormat::CONSOLE_ARGB8888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_ARGB8888_LINEAR; - case vtfpp::ImageFormat::CONSOLE_BGRA8888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_BGRA8888_LINEAR; - case vtfpp::ImageFormat::CONSOLE_RGB888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_RGB888_LINEAR; - case vtfpp::ImageFormat::CONSOLE_BGR888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_BGR888_LINEAR; - case vtfpp::ImageFormat::CONSOLE_BGRX5551_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_BGRX5551_LINEAR; - case vtfpp::ImageFormat::CONSOLE_I8_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_I8_LINEAR; - case vtfpp::ImageFormat::CONSOLE_RGBA16161616_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_RGBA16161616_LINEAR; - case vtfpp::ImageFormat::CONSOLE_BGRX8888_LE: return VTFPP_IMAGE_FORMAT_CONSOLE_BGRX8888_LE; - case vtfpp::ImageFormat::CONSOLE_BGRA8888_LE: return VTFPP_IMAGE_FORMAT_CONSOLE_BGRA8888_LE; - case vtfpp::ImageFormat::TFALL2_BC6H: return VTFPP_IMAGE_FORMAT_TFALL2_BC6H; - case vtfpp::ImageFormat::TFALL2_BC7: return VTFPP_IMAGE_FORMAT_TFALL2_BC7; - case vtfpp::ImageFormat::STRATA_R8: return VTFPP_IMAGE_FORMAT_STRATA_R8; - case vtfpp::ImageFormat::STRATA_BC7: return VTFPP_IMAGE_FORMAT_STRATA_BC7; - case vtfpp::ImageFormat::STRATA_BC6H: return VTFPP_IMAGE_FORMAT_STRATA_BC6H; + case vtfpp::ImageFormat::RGBA8888: return VTFPP_IMAGE_FORMAT_RGBA8888; + case vtfpp::ImageFormat::ABGR8888: return VTFPP_IMAGE_FORMAT_ABGR8888; + case vtfpp::ImageFormat::RGB888: return VTFPP_IMAGE_FORMAT_RGB888; + case vtfpp::ImageFormat::BGR888: return VTFPP_IMAGE_FORMAT_BGR888; + case vtfpp::ImageFormat::RGB565: return VTFPP_IMAGE_FORMAT_RGB565; + case vtfpp::ImageFormat::I8: return VTFPP_IMAGE_FORMAT_I8; + case vtfpp::ImageFormat::IA88: return VTFPP_IMAGE_FORMAT_IA88; + case vtfpp::ImageFormat::P8: return VTFPP_IMAGE_FORMAT_P8; + case vtfpp::ImageFormat::A8: return VTFPP_IMAGE_FORMAT_A8; + case vtfpp::ImageFormat::RGB888_BLUESCREEN: return VTFPP_IMAGE_FORMAT_RGB888_BLUESCREEN; + case vtfpp::ImageFormat::BGR888_BLUESCREEN: return VTFPP_IMAGE_FORMAT_BGR888_BLUESCREEN; + case vtfpp::ImageFormat::ARGB8888: return VTFPP_IMAGE_FORMAT_ARGB8888; + case vtfpp::ImageFormat::BGRA8888: return VTFPP_IMAGE_FORMAT_BGRA8888; + case vtfpp::ImageFormat::DXT1: return VTFPP_IMAGE_FORMAT_DXT1; + case vtfpp::ImageFormat::DXT3: return VTFPP_IMAGE_FORMAT_DXT3; + case vtfpp::ImageFormat::DXT5: return VTFPP_IMAGE_FORMAT_DXT5; + case vtfpp::ImageFormat::BGRX8888: return VTFPP_IMAGE_FORMAT_BGRX8888; + case vtfpp::ImageFormat::BGR565: return VTFPP_IMAGE_FORMAT_BGR565; + case vtfpp::ImageFormat::BGRX5551: return VTFPP_IMAGE_FORMAT_BGRX5551; + case vtfpp::ImageFormat::BGRA4444: return VTFPP_IMAGE_FORMAT_BGRA4444; + case vtfpp::ImageFormat::DXT1_ONE_BIT_ALPHA: return VTFPP_IMAGE_FORMAT_DXT1_ONE_BIT_ALPHA; + case vtfpp::ImageFormat::BGRA5551: return VTFPP_IMAGE_FORMAT_BGRA5551; + case vtfpp::ImageFormat::UV88: return VTFPP_IMAGE_FORMAT_UV88; + case vtfpp::ImageFormat::UVWQ8888: return VTFPP_IMAGE_FORMAT_UVWQ8888; + case vtfpp::ImageFormat::RGBA16161616F: return VTFPP_IMAGE_FORMAT_RGBA16161616F; + case vtfpp::ImageFormat::RGBA16161616: return VTFPP_IMAGE_FORMAT_RGBA16161616; + case vtfpp::ImageFormat::UVLX8888: return VTFPP_IMAGE_FORMAT_UVLX8888; + case vtfpp::ImageFormat::R32F: return VTFPP_IMAGE_FORMAT_R32F; + case vtfpp::ImageFormat::RGB323232F: return VTFPP_IMAGE_FORMAT_RGB323232F; + case vtfpp::ImageFormat::RGBA32323232F: return VTFPP_IMAGE_FORMAT_RGBA32323232F; + case vtfpp::ImageFormat::RG1616F: return VTFPP_IMAGE_FORMAT_RG1616F; + case vtfpp::ImageFormat::RG3232F: return VTFPP_IMAGE_FORMAT_RG3232F; + case vtfpp::ImageFormat::RGBX8888: return VTFPP_IMAGE_FORMAT_RGBX8888; + case vtfpp::ImageFormat::EMPTY: return VTFPP_IMAGE_FORMAT_EMPTY; + case vtfpp::ImageFormat::ATI2N: return VTFPP_IMAGE_FORMAT_ATI2N; + case vtfpp::ImageFormat::ATI1N: return VTFPP_IMAGE_FORMAT_ATI1N; + case vtfpp::ImageFormat::RGBA1010102: return VTFPP_IMAGE_FORMAT_RGBA1010102; + case vtfpp::ImageFormat::BGRA1010102: return VTFPP_IMAGE_FORMAT_BGRA1010102; + case vtfpp::ImageFormat::R16F: return VTFPP_IMAGE_FORMAT_R16F; + case vtfpp::ImageFormat::CONSOLE_BGRX8888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_BGRX8888_LINEAR; + case vtfpp::ImageFormat::CONSOLE_RGBA8888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_RGBA8888_LINEAR; + case vtfpp::ImageFormat::CONSOLE_ABGR8888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_ABGR8888_LINEAR; + case vtfpp::ImageFormat::CONSOLE_ARGB8888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_ARGB8888_LINEAR; + case vtfpp::ImageFormat::CONSOLE_BGRA8888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_BGRA8888_LINEAR; + case vtfpp::ImageFormat::CONSOLE_RGB888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_RGB888_LINEAR; + case vtfpp::ImageFormat::CONSOLE_BGR888_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_BGR888_LINEAR; + case vtfpp::ImageFormat::CONSOLE_BGRX5551_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_BGRX5551_LINEAR; + case vtfpp::ImageFormat::CONSOLE_I8_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_I8_LINEAR; + case vtfpp::ImageFormat::CONSOLE_RGBA16161616_LINEAR: return VTFPP_IMAGE_FORMAT_CONSOLE_RGBA16161616_LINEAR; + case vtfpp::ImageFormat::CONSOLE_BGRX8888_LE: return VTFPP_IMAGE_FORMAT_CONSOLE_BGRX8888_LE; + case vtfpp::ImageFormat::CONSOLE_BGRA8888_LE: return VTFPP_IMAGE_FORMAT_CONSOLE_BGRA8888_LE; + case vtfpp::ImageFormat::TFALL2_BC6H: return VTFPP_IMAGE_FORMAT_TFALL2_BC6H; + case vtfpp::ImageFormat::TFALL2_BC7: return VTFPP_IMAGE_FORMAT_TFALL2_BC7; + case vtfpp::ImageFormat::STRATA_R8: return VTFPP_IMAGE_FORMAT_STRATA_R8; + case vtfpp::ImageFormat::STRATA_BC7: return VTFPP_IMAGE_FORMAT_STRATA_BC7; + case vtfpp::ImageFormat::STRATA_BC6H: return VTFPP_IMAGE_FORMAT_STRATA_BC6H; + case vtfpp::ImageFormat::SOURCEPP_BGRA8888_HDR: return VTFPP_IMAGE_FORMAT_SOURCEPP_BGRA8888_HDR; + case vtfpp::ImageFormat::SOURCEPP_RGBA16161616_HDR: return VTFPP_IMAGE_FORMAT_SOURCEPP_RGBA16161616_HDR; + case vtfpp::ImageFormat::SOURCEPP_CONSOLE_RGBA16161616_HDR: return VTFPP_IMAGE_FORMAT_SOURCEPP_CONSOLE_RGBA16161616_HDR; } return VTFPP_IMAGE_FORMAT_RGBA8888; } diff --git a/lang/c/include/vtfppc/VTF.h b/lang/c/include/vtfppc/VTF.h index f834959e..84358633 100644 --- a/lang/c/include/vtfppc/VTF.h +++ b/lang/c/include/vtfppc/VTF.h @@ -203,7 +203,7 @@ VTFPP_EXTERN typedef struct { typedef void* vtfpp_vtf_handle_t; VTFPP_API vtfpp_vtf_handle_t vtfpp_vtf_create_empty(); // REQUIRES MANUAL FREE: vtfpp_vtf_close -VTFPP_API vtfpp_vtf_handle_t vtfpp_vtf_open_from_mem(const unsigned char* vtfData, size_t vtfLen, int parseHeaderOnly); // REQUIRES MANUAL FREE: vtfpp_vtf_close +VTFPP_API vtfpp_vtf_handle_t vtfpp_vtf_open_from_mem(const unsigned char* vtfData, size_t vtfLen, int parseHeaderOnly, int hdr); // REQUIRES MANUAL FREE: vtfpp_vtf_close VTFPP_API vtfpp_vtf_handle_t vtfpp_vtf_open_from_file(const char* vtfPath, int parseHeaderOnly); // REQUIRES MANUAL FREE: vtfpp_vtf_close VTFPP_API void vtfpp_vtf_close(vtfpp_vtf_handle_t* handle); VTFPP_API int vtfpp_vtf_is_valid(vtfpp_vtf_handle_t handle); diff --git a/lang/c/src/vtfppc/ImageConversion.cpp b/lang/c/src/vtfppc/ImageConversion.cpp index cd5b6882..12d7d899 100644 --- a/lang/c/src/vtfppc/ImageConversion.cpp +++ b/lang/c/src/vtfppc/ImageConversion.cpp @@ -34,14 +34,14 @@ VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_several_image_data_to return convert::toBuffer(ImageConversion::convertSeveralImageDataToFormat({reinterpret_cast(buffer), bufferLen}, convert::cast(oldFormat), convert::cast(newFormat), mipCount, frameCount, faceCount, width, height, depth, quality)); } -VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_hdri_to_cubemap(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height) { +VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_hdri_to_cubemap(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, uint16_t resolution, int bilinear) { SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); - const auto faces = ImageConversion::convertHDRIToCubeMap({reinterpret_cast(buffer), bufferLen}, convert::cast(format), width, height); + const auto faces = ImageConversion::convertHDRIToCubeMap({reinterpret_cast(buffer), bufferLen}, convert::cast(format), width, height, resolution, bilinear); std::vector out; for (const auto& face : faces) { out.insert(out.end(), face.begin(), face.end()); @@ -49,19 +49,32 @@ VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_hdri_to_cubemap(const return convert::toBuffer(out); } -VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_hdri_to_cubemap_ex(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, uint16_t resolution, int bilinear) { +VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_compress_bgra8888_hdr(const unsigned char* buffer, size_t bufferLen, float overbrightFactor) { SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); - SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); - SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); - SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); - const auto faces = ImageConversion::convertHDRIToCubeMap({reinterpret_cast(buffer), bufferLen}, convert::cast(format), width, height, resolution, bilinear); - std::vector out; - for (const auto& face : faces) { - out.insert(out.end(), face.begin(), face.end()); - } - return convert::toBuffer(out); + return convert::toBuffer(ImageConversion::compressBGRA8888HDR({reinterpret_cast(buffer), bufferLen}, overbrightFactor)); +} + +VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_decompress_bgra8888_hdr(const unsigned char* buffer, size_t bufferLen, float overbrightFactor) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + + return convert::toBuffer(ImageConversion::decompressBGRA8888HDR({reinterpret_cast(buffer), bufferLen}, overbrightFactor)); +} + +VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_compress_rgba16161616_hdr(const unsigned char* buffer, size_t bufferLen, int flipExponentAndSignificand) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + + return convert::toBuffer(ImageConversion::compressRGBA16161616HDR({reinterpret_cast(buffer), bufferLen}, flipExponentAndSignificand)); +} + +VTFPP_API sourcepp_buffer_t vtfpp_image_conversion_decompress_rgba16161616_hdr(const unsigned char* buffer, size_t bufferLen, int flipExponentAndSignificand) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + + return convert::toBuffer(ImageConversion::decompressRGBA16161616HDR({reinterpret_cast(buffer), bufferLen}, flipExponentAndSignificand)); } VTFPP_API vtfpp_image_conversion_file_format_e vtfpp_image_conversion_get_default_file_format_for_image_format(vtfpp_image_format_e format) { diff --git a/lang/c/src/vtfppc/ImageFormats.cpp b/lang/c/src/vtfppc/ImageFormats.cpp index 75143b76..38d110cc 100644 --- a/lang/c/src/vtfppc/ImageFormats.cpp +++ b/lang/c/src/vtfppc/ImageFormats.cpp @@ -59,6 +59,10 @@ VTFPP_API int vtfpp_image_format_details_compressed(vtfpp_image_format_e format) return ImageFormatDetails::compressed(convert::cast(format)); } +VTFPP_API int vtfpp_image_format_details_compressed_hdr(vtfpp_image_format_e format) { + return ImageFormatDetails::compressedHDR(convert::cast(format)); +} + VTFPP_API int vtfpp_image_format_details_transparent(vtfpp_image_format_e format) { return ImageFormatDetails::transparent(convert::cast(format)); } @@ -71,6 +75,14 @@ VTFPP_API int vtfpp_image_format_details_console(vtfpp_image_format_e format) { return ImageFormatDetails::console(convert::cast(format)); } +VTFPP_API int vtfpp_image_format_details_tfall2(vtfpp_image_format_e format) { + return ImageFormatDetails::tfall2(convert::cast(format)); +} + +VTFPP_API int vtfpp_image_format_details_strata(vtfpp_image_format_e format) { + return ImageFormatDetails::strata(convert::cast(format)); +} + VTFPP_API uint16_t vtfpp_image_dimensions_get_mip_dim(uint8_t mip, uint16_t dim, int addCompressedFormatPadding) { return ImageDimensions::getMipDim(mip, dim, addCompressedFormatPadding); } diff --git a/lang/c/src/vtfppc/VTF.cpp b/lang/c/src/vtfppc/VTF.cpp index 560134e2..dc0c966c 100644 --- a/lang/c/src/vtfppc/VTF.cpp +++ b/lang/c/src/vtfppc/VTF.cpp @@ -115,11 +115,11 @@ VTFPP_API vtfpp_vtf_handle_t vtfpp_vtf_create_empty() { return new VTF{}; } -VTFPP_API vtfpp_vtf_handle_t vtfpp_vtf_open_from_mem(const unsigned char* vtfData, size_t vtfLen, int parseHeaderOnly) { +VTFPP_API vtfpp_vtf_handle_t vtfpp_vtf_open_from_mem(const unsigned char* vtfData, size_t vtfLen, int parseHeaderOnly, int hdr) { SOURCEPP_EARLY_RETURN_VAL(vtfData, nullptr); SOURCEPP_EARLY_RETURN_VAL(vtfLen, nullptr); - return new VTF{{reinterpret_cast(vtfData), vtfLen}, static_cast(parseHeaderOnly)}; + return new VTF{{reinterpret_cast(vtfData), vtfLen}, static_cast(parseHeaderOnly), static_cast(hdr)}; } VTFPP_API vtfpp_vtf_handle_t vtfpp_vtf_open_from_file(const char* vtfPath, int parseHeaderOnly) { diff --git a/lang/csharp/src/vtfpp/DLL.cs b/lang/csharp/src/vtfpp/DLL.cs index 6a35febb..7a5fb327 100644 --- a/lang/csharp/src/vtfpp/DLL.cs +++ b/lang/csharp/src/vtfpp/DLL.cs @@ -62,8 +62,20 @@ internal static partial class DLL public static partial sourcepp.DLL.Buffer vtfpp_image_conversion_convert_several_image_data_to_format(ReadOnlySpan buffer, ulong bufferLen, ImageFormat oldFormat, ImageFormat newFormat, byte mipCount, ushort frameCount, byte faceCount, ushort width, ushort height, ushort depth, float quality); [LibraryImport(Name)] - public static partial sourcepp.DLL.Buffer vtfpp_image_conversion_convert_hdri_to_cubemap_ex(ReadOnlySpan buffer, ulong bufferLen, ImageFormat format, ushort width, ushort height, ushort resolution, int bilinear); + public static partial sourcepp.DLL.Buffer vtfpp_image_conversion_convert_hdri_to_cubemap(ReadOnlySpan buffer, ulong bufferLen, ImageFormat format, ushort width, ushort height, ushort resolution, int bilinear); + [LibraryImport(Name)] + public static partial sourcepp.DLL.Buffer vtfpp_image_conversion_compress_bgra8888_hdr(ReadOnlySpan buffer, ulong bufferLen, float overbrightFactor); + + [LibraryImport(Name)] + public static partial sourcepp.DLL.Buffer vtfpp_image_conversion_decompress_bgra8888_hdr(ReadOnlySpan buffer, ulong bufferLen, float overbrightFactor); + + [LibraryImport(Name)] + public static partial sourcepp.DLL.Buffer vtfpp_image_conversion_compress_rgba16161616_hdr(ReadOnlySpan buffer, ulong bufferLen, int flipExponentAndSignificand); + + [LibraryImport(Name)] + public static partial sourcepp.DLL.Buffer vtfpp_image_conversion_decompress_rgba16161616_hdr(ReadOnlySpan buffer, ulong bufferLen, int flipExponentAndSignificand); + [LibraryImport(Name)] public static partial ImageConversion.FileFormat vtfpp_image_conversion_get_default_file_format_for_image_format(ImageFormat format); @@ -133,6 +145,9 @@ internal static partial class DLL [LibraryImport(Name)] public static partial int vtfpp_image_format_details_compressed(ImageFormat format); + [LibraryImport(Name)] + public static partial int vtfpp_image_format_details_compressed_hdr(ImageFormat format); + [LibraryImport(Name)] public static partial int vtfpp_image_format_details_transparent(ImageFormat format); @@ -142,6 +157,12 @@ internal static partial class DLL [LibraryImport(Name)] public static partial int vtfpp_image_format_details_console(ImageFormat format); + [LibraryImport(Name)] + public static partial int vtfpp_image_format_details_tfall2(ImageFormat format); + + [LibraryImport(Name)] + public static partial int vtfpp_image_format_details_strata(ImageFormat format); + [LibraryImport(Name)] public static partial ushort vtfpp_image_dimensions_get_mip_dim(byte mip, ushort dim, int addCompressedFormatPadding); @@ -470,7 +491,7 @@ internal static partial class DLL public static partial nint vtfpp_vtf_create_empty(); [LibraryImport(Name)] - public static partial nint vtfpp_vtf_open_from_mem(ReadOnlySpan vtfData, ulong vtfLen, int parseHeaderOnly); + public static partial nint vtfpp_vtf_open_from_mem(ReadOnlySpan vtfData, ulong vtfLen, int parseHeaderOnly, int hdr); [LibraryImport(Name, StringMarshalling = StringMarshalling.Utf8)] public static partial nint vtfpp_vtf_open_from_file(string vtfPath, int parseHeaderOnly); diff --git a/lang/csharp/src/vtfpp/ImageConversion.cs b/lang/csharp/src/vtfpp/ImageConversion.cs index 5c36375b..55782f07 100644 --- a/lang/csharp/src/vtfpp/ImageConversion.cs +++ b/lang/csharp/src/vtfpp/ImageConversion.cs @@ -19,9 +19,33 @@ public static byte[] ConvertSeveralImageDataToFormat(ReadOnlySpan buffer, public static byte[] ConvertHdriToCubemap(ReadOnlySpan buffer, ImageFormat format, ushort width, ushort height, ushort resolution = 0, bool bilinear = true) { - return new sourcepp.Buffer(DLL.vtfpp_image_conversion_convert_hdri_to_cubemap_ex(buffer, (ulong) buffer.Length, format, width, height, resolution, Convert.ToInt32(bilinear))).Read(); + return new sourcepp.Buffer(DLL.vtfpp_image_conversion_convert_hdri_to_cubemap(buffer, (ulong) buffer.Length, format, width, height, resolution, Convert.ToInt32(bilinear))).Read(); } - + + // ReSharper disable once InconsistentNaming + public static byte[] CompressBGRA8888HDR(ReadOnlySpan buffer, float overbrightFactor = 16.0f) + { + return new sourcepp.Buffer(DLL.vtfpp_image_conversion_compress_bgra8888_hdr(buffer, (ulong)buffer.Length, overbrightFactor)).Read(); + } + + // ReSharper disable once InconsistentNaming + public static byte[] DecompressBGRA8888HDR(ReadOnlySpan buffer, float overbrightFactor = 16.0f) + { + return new sourcepp.Buffer(DLL.vtfpp_image_conversion_decompress_bgra8888_hdr(buffer, (ulong)buffer.Length, overbrightFactor)).Read(); + } + + // ReSharper disable once InconsistentNaming + public static byte[] CompressRGBA16161616HDR(ReadOnlySpan buffer, bool flipExponentAndSignificand = false) + { + return new sourcepp.Buffer(DLL.vtfpp_image_conversion_compress_rgba16161616_hdr(buffer, (ulong)buffer.Length, Convert.ToInt32(flipExponentAndSignificand))).Read(); + } + + // ReSharper disable once InconsistentNaming + public static byte[] DecompressRGBA16161616HDR(ReadOnlySpan buffer, bool flipExponentAndSignificand = false) + { + return new sourcepp.Buffer(DLL.vtfpp_image_conversion_decompress_rgba16161616_hdr(buffer, (ulong)buffer.Length, Convert.ToInt32(flipExponentAndSignificand))).Read(); + } + public enum FileFormat { DEFAULT = 0, PNG = 1, diff --git a/lang/csharp/src/vtfpp/ImageFormats.cs b/lang/csharp/src/vtfpp/ImageFormats.cs index 59fc158e..2978fbb4 100644 --- a/lang/csharp/src/vtfpp/ImageFormats.cs +++ b/lang/csharp/src/vtfpp/ImageFormats.cs @@ -75,6 +75,12 @@ public enum ImageFormat { STRATA_BC7, STRATA_BC6H, #endregion + + #region SourcePP Virtual Formats + SOURCEPP_BGRA8888_HDR = 10000, + SOURCEPP_RGBA16161616_HDR, + SOURCEPP_CONSOLE_RGBA16161616_HDR, + #endregion } public static partial class ImageFormatDetails @@ -144,6 +150,11 @@ public static bool Compressed(ImageFormat format) return Convert.ToBoolean(DLL.vtfpp_image_format_details_compressed(format)); } + public static bool CompressedHDR(ImageFormat format) + { + return Convert.ToBoolean(DLL.vtfpp_image_format_details_compressed_hdr(format)); + } + public static bool Transparent(ImageFormat format) { return Convert.ToBoolean(DLL.vtfpp_image_format_details_transparent(format)); @@ -158,6 +169,16 @@ public static bool Console(ImageFormat format) { return Convert.ToBoolean(DLL.vtfpp_image_format_details_console(format)); } + + public static bool TFall2(ImageFormat format) + { + return Convert.ToBoolean(DLL.vtfpp_image_format_details_tfall2(format)); + } + + public static bool Strata(ImageFormat format) + { + return Convert.ToBoolean(DLL.vtfpp_image_format_details_strata(format)); + } } public static class ImageDimensions diff --git a/lang/csharp/src/vtfpp/VTF.cs b/lang/csharp/src/vtfpp/VTF.cs index 67783816..7201fcb7 100644 --- a/lang/csharp/src/vtfpp/VTF.cs +++ b/lang/csharp/src/vtfpp/VTF.cs @@ -265,14 +265,14 @@ public VTF() : this(DLL.vtfpp_vtf_create_empty()) { } - public VTF(ReadOnlySpan vtfData, bool parseHeaderOnly = false) : this(DLL.vtfpp_vtf_open_from_mem(vtfData, (ulong) vtfData.Length, Convert.ToInt32(parseHeaderOnly))) + public VTF(ReadOnlySpan vtfData, bool parseHeaderOnly = false, bool hdr = false) : this(DLL.vtfpp_vtf_open_from_mem(vtfData, (ulong) vtfData.Length, Convert.ToInt32(parseHeaderOnly), Convert.ToInt32(hdr))) { } - + public VTF(string vtfPath, bool parseHeaderOnly = false) : this(DLL.vtfpp_vtf_open_from_file(vtfPath, Convert.ToInt32(parseHeaderOnly))) { } - + public static implicit operator bool(VTF vtf) { vtf.ThrowIfDisposed(); diff --git a/lang/python/src/vtfpp.h b/lang/python/src/vtfpp.h index 59878d2a..8fa4545c 100644 --- a/lang/python/src/vtfpp.h +++ b/lang/python/src/vtfpp.h @@ -49,62 +49,65 @@ inline void register_python(py::module_& m) { .def("bake_to_file", py::overload_cast(&HOT::bake, py::const_), "hot_path"_a); py::enum_(vtfpp, "ImageFormat") - .value("RGBA8888", ImageFormat::RGBA8888) - .value("ABGR8888", ImageFormat::ABGR8888) - .value("RGB888", ImageFormat::RGB888) - .value("BGR888", ImageFormat::BGR888) - .value("RGB565", ImageFormat::RGB565) - .value("I8", ImageFormat::I8) - .value("IA88", ImageFormat::IA88) - .value("P8", ImageFormat::P8) - .value("A8", ImageFormat::A8) - .value("RGB888_BLUESCREEN", ImageFormat::RGB888_BLUESCREEN) - .value("BGR888_BLUESCREEN", ImageFormat::BGR888_BLUESCREEN) - .value("ARGB8888", ImageFormat::ARGB8888) - .value("BGRA8888", ImageFormat::BGRA8888) - .value("DXT1", ImageFormat::DXT1) - .value("DXT3", ImageFormat::DXT3) - .value("DXT5", ImageFormat::DXT5) - .value("BGRX8888", ImageFormat::BGRX8888) - .value("BGR565", ImageFormat::BGR565) - .value("BGRX5551", ImageFormat::BGRX5551) - .value("BGRA4444", ImageFormat::BGRA4444) - .value("DXT1_ONE_BIT_ALPHA", ImageFormat::DXT1_ONE_BIT_ALPHA) - .value("BGRA5551", ImageFormat::BGRA5551) - .value("UV88", ImageFormat::UV88) - .value("UVWQ8888", ImageFormat::UVWQ8888) - .value("RGBA16161616F", ImageFormat::RGBA16161616F) - .value("RGBA16161616", ImageFormat::RGBA16161616) - .value("UVLX8888", ImageFormat::UVLX8888) - .value("R32F", ImageFormat::R32F) - .value("RGB323232F", ImageFormat::RGB323232F) - .value("RGBA32323232F", ImageFormat::RGBA32323232F) - .value("RG1616F", ImageFormat::RG1616F) - .value("RG3232F", ImageFormat::RG3232F) - .value("RGBX8888", ImageFormat::RGBX8888) - .value("EMPTY", ImageFormat::EMPTY) - .value("ATI2N", ImageFormat::ATI2N) - .value("ATI1N", ImageFormat::ATI1N) - .value("RGBA1010102", ImageFormat::RGBA1010102) - .value("BGRA1010102", ImageFormat::BGRA1010102) - .value("R16F", ImageFormat::R16F) - .value("CONSOLE_BGRX8888_LINEAR", ImageFormat::CONSOLE_BGRX8888_LINEAR) - .value("CONSOLE_RGBA8888_LINEAR", ImageFormat::CONSOLE_RGBA8888_LINEAR) - .value("CONSOLE_ABGR8888_LINEAR", ImageFormat::CONSOLE_ABGR8888_LINEAR) - .value("CONSOLE_ARGB8888_LINEAR", ImageFormat::CONSOLE_ARGB8888_LINEAR) - .value("CONSOLE_BGRA8888_LINEAR", ImageFormat::CONSOLE_BGRA8888_LINEAR) - .value("CONSOLE_RGB888_LINEAR", ImageFormat::CONSOLE_RGB888_LINEAR) - .value("CONSOLE_BGR888_LINEAR", ImageFormat::CONSOLE_BGR888_LINEAR) - .value("CONSOLE_BGRX5551_LINEAR", ImageFormat::CONSOLE_BGRX5551_LINEAR) - .value("CONSOLE_I8_LINEAR", ImageFormat::CONSOLE_I8_LINEAR) - .value("CONSOLE_RGBA16161616_LINEAR", ImageFormat::CONSOLE_RGBA16161616_LINEAR) - .value("CONSOLE_BGRX8888_LE", ImageFormat::CONSOLE_BGRX8888_LE) - .value("CONSOLE_BGRA8888_LE", ImageFormat::CONSOLE_BGRA8888_LE) - .value("TFALL2_BC6H", ImageFormat::TFALL2_BC6H) - .value("TFALL2_BC7", ImageFormat::TFALL2_BC7) - .value("STRATA_R8", ImageFormat::STRATA_R8) - .value("STRATA_BC7", ImageFormat::STRATA_BC7) - .value("STRATA_BC6H", ImageFormat::STRATA_BC6H); + .value("RGBA8888", ImageFormat::RGBA8888) + .value("ABGR8888", ImageFormat::ABGR8888) + .value("RGB888", ImageFormat::RGB888) + .value("BGR888", ImageFormat::BGR888) + .value("RGB565", ImageFormat::RGB565) + .value("I8", ImageFormat::I8) + .value("IA88", ImageFormat::IA88) + .value("P8", ImageFormat::P8) + .value("A8", ImageFormat::A8) + .value("RGB888_BLUESCREEN", ImageFormat::RGB888_BLUESCREEN) + .value("BGR888_BLUESCREEN", ImageFormat::BGR888_BLUESCREEN) + .value("ARGB8888", ImageFormat::ARGB8888) + .value("BGRA8888", ImageFormat::BGRA8888) + .value("DXT1", ImageFormat::DXT1) + .value("DXT3", ImageFormat::DXT3) + .value("DXT5", ImageFormat::DXT5) + .value("BGRX8888", ImageFormat::BGRX8888) + .value("BGR565", ImageFormat::BGR565) + .value("BGRX5551", ImageFormat::BGRX5551) + .value("BGRA4444", ImageFormat::BGRA4444) + .value("DXT1_ONE_BIT_ALPHA", ImageFormat::DXT1_ONE_BIT_ALPHA) + .value("BGRA5551", ImageFormat::BGRA5551) + .value("UV88", ImageFormat::UV88) + .value("UVWQ8888", ImageFormat::UVWQ8888) + .value("RGBA16161616F", ImageFormat::RGBA16161616F) + .value("RGBA16161616", ImageFormat::RGBA16161616) + .value("UVLX8888", ImageFormat::UVLX8888) + .value("R32F", ImageFormat::R32F) + .value("RGB323232F", ImageFormat::RGB323232F) + .value("RGBA32323232F", ImageFormat::RGBA32323232F) + .value("RG1616F", ImageFormat::RG1616F) + .value("RG3232F", ImageFormat::RG3232F) + .value("RGBX8888", ImageFormat::RGBX8888) + .value("EMPTY", ImageFormat::EMPTY) + .value("ATI2N", ImageFormat::ATI2N) + .value("ATI1N", ImageFormat::ATI1N) + .value("RGBA1010102", ImageFormat::RGBA1010102) + .value("BGRA1010102", ImageFormat::BGRA1010102) + .value("R16F", ImageFormat::R16F) + .value("CONSOLE_BGRX8888_LINEAR", ImageFormat::CONSOLE_BGRX8888_LINEAR) + .value("CONSOLE_RGBA8888_LINEAR", ImageFormat::CONSOLE_RGBA8888_LINEAR) + .value("CONSOLE_ABGR8888_LINEAR", ImageFormat::CONSOLE_ABGR8888_LINEAR) + .value("CONSOLE_ARGB8888_LINEAR", ImageFormat::CONSOLE_ARGB8888_LINEAR) + .value("CONSOLE_BGRA8888_LINEAR", ImageFormat::CONSOLE_BGRA8888_LINEAR) + .value("CONSOLE_RGB888_LINEAR", ImageFormat::CONSOLE_RGB888_LINEAR) + .value("CONSOLE_BGR888_LINEAR", ImageFormat::CONSOLE_BGR888_LINEAR) + .value("CONSOLE_BGRX5551_LINEAR", ImageFormat::CONSOLE_BGRX5551_LINEAR) + .value("CONSOLE_I8_LINEAR", ImageFormat::CONSOLE_I8_LINEAR) + .value("CONSOLE_RGBA16161616_LINEAR", ImageFormat::CONSOLE_RGBA16161616_LINEAR) + .value("CONSOLE_BGRX8888_LE", ImageFormat::CONSOLE_BGRX8888_LE) + .value("CONSOLE_BGRA8888_LE", ImageFormat::CONSOLE_BGRA8888_LE) + .value("TFALL2_BC6H", ImageFormat::TFALL2_BC6H) + .value("TFALL2_BC7", ImageFormat::TFALL2_BC7) + .value("STRATA_R8", ImageFormat::STRATA_R8) + .value("STRATA_BC7", ImageFormat::STRATA_BC7) + .value("STRATA_BC6H", ImageFormat::STRATA_BC6H) + .value("SOURCEPP_BGRA8888_HDR", ImageFormat::SOURCEPP_BGRA8888_HDR) + .value("SOURCEPP_RGBA16161616_HDR", ImageFormat::SOURCEPP_RGBA16161616_HDR) + .value("SOURCEPP_CONSOLE_RGBA16161616_HDR", ImageFormat::SOURCEPP_CONSOLE_RGBA16161616_HDR); { using namespace ImageFormatDetails; @@ -124,9 +127,12 @@ inline void register_python(py::module_& m) { .def("large", &large, "format"_a) .def("decimal", &decimal, "format"_a) .def("compressed", &compressed, "format"_a) + .def("compressedHDR", &compressedHDR, "format"_a) .def("transparent", &transparent, "format"_a) .def("opaque", &opaque, "format"_a) - .def("console", &console, "format"_a); + .def("console", &console, "format"_a) + .def("tfall2", &tfall2, "format"_a) + .def("strata", &strata, "format"_a); ImageFormatDetails .def("get_data_length", py::overload_cast(&getDataLength), "format"_a, "width"_a, "height"_a, "depth"_a = 1) @@ -183,6 +189,26 @@ inline void register_python(py::module_& m) { return {py::bytes{ds[0].data(), ds[0].size()}, py::bytes{ds[1].data(), ds[1].size()}, py::bytes{ds[2].data(), ds[2].size()}, py::bytes{ds[3].data(), ds[3].size()}, py::bytes{ds[4].data(), ds[4].size()}, py::bytes{ds[5].data(), ds[5].size()}}; }, "image_data"_a, "format"_a, "width"_a, "height"_a, "resolution"_a = 0, "bilinear"_a = true); + ImageConversion.def("compress_bgra8888_hdr", [](const py::bytes& imageData, float overbrightFactor = 16.f) { + const auto d = compressBGRA8888HDR({static_cast(imageData.data()), imageData.size()}, overbrightFactor); + return py::bytes{d.data(), d.size()}; + }, "image_data"_a, "overbright_factor"_a = 16.f); + + ImageConversion.def("decompress_bgra8888_hdr", [](const py::bytes& imageData, float overbrightFactor = 16.f) { + const auto d = decompressBGRA8888HDR({static_cast(imageData.data()), imageData.size()}, overbrightFactor); + return py::bytes{d.data(), d.size()}; + }, "image_data"_a, "overbright_factor"_a = 16.f); + + ImageConversion.def("compress_rgba16161616_hdr", [](const py::bytes& imageData, bool flipExponentAndSignificand = false) { + const auto d = compressRGBA16161616HDR({static_cast(imageData.data()), imageData.size()}, flipExponentAndSignificand); + return py::bytes{d.data(), d.size()}; + }, "image_data"_a, "flip_exponent_and_significand"_a = false); + + ImageConversion.def("decompress_rgba16161616_hdr", [](const py::bytes& imageData, bool flipExponentAndSignificand = false) { + const auto d = decompressRGBA16161616HDR({static_cast(imageData.data()), imageData.size()}, flipExponentAndSignificand); + return py::bytes{d.data(), d.size()}; + }, "image_data"_a, "flip_exponent_and_significand"_a = false); + py::enum_(ImageConversion, "FileFormat") .value("DEFAULT", FileFormat::DEFAULT) .value("PNG", FileFormat::PNG) @@ -612,9 +638,9 @@ inline void register_python(py::module_& m) { .def_ro_static("FORMAT_UNCHANGED", &VTF::FORMAT_UNCHANGED) .def_ro_static("FORMAT_DEFAULT", &VTF::FORMAT_DEFAULT) .def(py::init()) - .def("__init__", [](VTF* self, const py::bytes& vtfData, bool parseHeaderOnly = false) { - return new(self) VTF{std::span{static_cast(vtfData.data()), vtfData.size()}, parseHeaderOnly}; - }, "vtf_data"_a, "parse_header_only"_a = false) + .def("__init__", [](VTF* self, const py::bytes& vtfData, bool parseHeaderOnly = false, bool hdr = false) { + return new(self) VTF{std::span{static_cast(vtfData.data()), vtfData.size()}, parseHeaderOnly, hdr}; + }, "vtf_data"_a, "parse_header_only"_a = false, "hdr"_a = false) .def(py::init(), "vtf_path"_a, "parse_header_only"_a = false) .def("__bool__", &VTF::operator bool, py::is_operator()) .def_static("create_and_bake", [](const py::bytes& imageData, ImageFormat format, uint16_t width, uint16_t height, const std::filesystem::path& vtfPath, const VTF::CreationOptions& options) { diff --git a/src/vtfpp/ImageConversion.cpp b/src/vtfpp/ImageConversion.cpp index 8d743a76..45bcd94c 100644 --- a/src/vtfpp/ImageConversion.cpp +++ b/src/vtfpp/ImageConversion.cpp @@ -150,6 +150,9 @@ namespace { case CONSOLE_RGBA16161616_LINEAR: case CONSOLE_BGRX8888_LE: case CONSOLE_BGRA8888_LE: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: return CMP_FORMAT_Unknown; } return CMP_FORMAT_Unknown; @@ -224,6 +227,9 @@ namespace { case CONSOLE_RGBA16161616_LINEAR: case CONSOLE_BGRX8888_LE: case CONSOLE_BGRA8888_LE: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: break; } return -1; @@ -292,6 +298,9 @@ namespace { case TFALL2_BC7: case STRATA_BC7: case STRATA_BC6H: + case SOURCEPP_BGRA8888_HDR: + case SOURCEPP_RGBA16161616_HDR: + case SOURCEPP_CONSOLE_RGBA16161616_HDR: break; } return -1; @@ -302,6 +311,39 @@ namespace { return {}; } + if (ImageFormatDetails::compressedHDR(oldFormat)) { + if (newFormat != ImageFormat::RGBA32323232F) { + return {}; + } + switch (oldFormat) { + using enum ImageFormat; + case SOURCEPP_BGRA8888_HDR: + return ImageConversion::decompressBGRA8888HDR(imageData); + case SOURCEPP_RGBA16161616_HDR: + return ImageConversion::decompressRGBA16161616HDR(imageData, false); + case SOURCEPP_CONSOLE_RGBA16161616_HDR: + return ImageConversion::decompressRGBA16161616HDR(imageData, true); + default: + return {}; + } + } + if (ImageFormatDetails::compressedHDR(newFormat)) { + if (oldFormat != ImageFormat::RGBA32323232F) { + return {}; + } + switch (newFormat) { + using enum ImageFormat; + case SOURCEPP_BGRA8888_HDR: + return ImageConversion::compressBGRA8888HDR(imageData); + case SOURCEPP_RGBA16161616_HDR: + return ImageConversion::compressRGBA16161616HDR(imageData, false); + case SOURCEPP_CONSOLE_RGBA16161616_HDR: + return ImageConversion::compressRGBA16161616HDR(imageData, true); + default: + return {}; + } + } + uint16_t unpaddedWidth = width, unpaddedHeight = height; if ((width % 4 != 0 || height % 4 != 0) && ImageFormatDetails::compressed(oldFormat) != ImageFormatDetails::compressed(newFormat)) { uint16_t paddingWidth = (4 - (width % 4)) % 4, paddingHeight = (4 - (height % 4)) % 4; @@ -942,6 +984,91 @@ std::array, 6> ImageConversion::convertHDRIToCubeMap(std: return faceData; } +std::vector ImageConversion::compressBGRA8888HDR(std::span imageData, float overbrightFactor) { + if (imageData.empty()) { + return {}; + } + + return ImagePixel::transform(imageData, [overbrightFactor](ImagePixel::RGBA32323232F pixel) -> ImagePixel::BGRA8888 { + static constexpr auto compressChannel = [](float c, float a, float fac) { + return static_cast(std::clamp(std::round(c / (a * fac) * 255.f), 0.f, 255.f)); + }; + const auto alpha = static_cast(std::clamp(std::round((overbrightFactor != 0.f ? std::max({pixel.r(), pixel.g(), pixel.b()}) : 0.f) * 255.f), 0.f, 255.f)); + return {{ + .b = compressChannel(pixel.b(), alpha, overbrightFactor), + .g = compressChannel(pixel.g(), alpha, overbrightFactor), + .r = compressChannel(pixel.r(), alpha, overbrightFactor), + .a = alpha, + }}; + }); +} + +std::vector ImageConversion::decompressBGRA8888HDR(std::span imageData, float overbrightFactor) { + if (imageData.empty()) { + return {}; + } + + return ImagePixel::transform(imageData, [overbrightFactor](ImagePixel::BGRA8888 pixel) -> ImagePixel::RGBA32323232F { + static constexpr auto decompressChannel = [](uint8_t c, float a, float fac) { + return (static_cast(c) / 255) * a * fac; + }; + const auto alpha = static_cast(pixel.a()); + return {{ + .r = decompressChannel(pixel.r(), alpha, overbrightFactor), + .g = decompressChannel(pixel.g(), alpha, overbrightFactor), + .b = decompressChannel(pixel.b(), alpha, overbrightFactor), + .a = 1.f, + }}; + }); +} + +std::vector ImageConversion::compressRGBA16161616HDR(std::span imageData, bool flipExponentAndSignificand) { + if (imageData.empty()) { + return {}; + } + + return ImagePixel::transform(imageData, [flipExponentAndSignificand](ImagePixel::RGBA32323232F pixel) -> ImagePixel::RGBA16161616 { + static constexpr auto compressChannel = [](float c, bool flip) { + auto out = static_cast(std::round(c * (1 << 12))); + if (flip) { + const uint16_t exponent = out & 0b1111; + out >>= 4; + out |= exponent << 12; + } + return out; + }; + return {{ + .r = compressChannel(pixel.r(), flipExponentAndSignificand), + .g = compressChannel(pixel.g(), flipExponentAndSignificand), + .b = compressChannel(pixel.b(), flipExponentAndSignificand), + .a = compressChannel(1.f, flipExponentAndSignificand), + }}; + }); +} + +std::vector ImageConversion::decompressRGBA16161616HDR(std::span imageData, bool flipExponentAndSignificand) { + if (imageData.empty()) { + return {}; + } + + return ImagePixel::transform(imageData, [flipExponentAndSignificand](ImagePixel::RGBA16161616 pixel) -> ImagePixel::RGBA32323232F { + static constexpr auto decompressChannel = [](uint16_t c, bool flip) { + if (flip) { + const uint16_t exponent = c & 0b1111; + c >>= 4; + c |= exponent << 12; + } + return static_cast(c) / (1 << 12); + }; + return {{ + .r = decompressChannel(pixel.r(), flipExponentAndSignificand), + .g = decompressChannel(pixel.g(), flipExponentAndSignificand), + .b = decompressChannel(pixel.b(), flipExponentAndSignificand), + .a = 1.f, + }}; + }); +} + ImageConversion::FileFormat ImageConversion::getDefaultFileFormatForImageFormat(ImageFormat format) { using enum FileFormat; #ifdef VTFPP_SUPPORT_EXR diff --git a/src/vtfpp/VTF.cpp b/src/vtfpp/VTF.cpp index eb910b7c..f0dc269b 100644 --- a/src/vtfpp/VTF.cpp +++ b/src/vtfpp/VTF.cpp @@ -392,7 +392,7 @@ VTF::VTF() { this->opened = true; } -VTF::VTF(std::vector&& vtfData, bool parseHeaderOnly) +VTF::VTF(std::vector&& vtfData, bool parseHeaderOnly, bool hdr) : data(std::move(vtfData)) { BufferStreamReadOnly stream{this->data}; @@ -501,8 +501,8 @@ VTF::VTF(std::vector&& vtfData, bool parseHeaderOnly) } }; - // HACK: a couple tweaks to fix engine bugs or branch differences - const auto postReadTransform = [this] { + // A couple tweaks to fix engine bugs or branch differences + const auto postHeaderReadTransform = [this, hdr] { // Change the format to DXT1_ONE_BIT_ALPHA to get compressonator to recognize it. // No source game recognizes this format, so we will do additional transform in bake back to DXT1. // We also need to check MULTI_BIT_ALPHA flag because stupid third party tools will sometimes set it??? @@ -514,6 +514,18 @@ VTF::VTF(std::vector&& vtfData, bool parseHeaderOnly) if (this->version < 5 && (this->format == ImageFormat::RGBA1010102 || this->format == ImageFormat::BGRA1010102 || this->format == ImageFormat::R16F)) { this->format = static_cast(static_cast(this->format) - 3); } + // If this is an HDR VTF, and it has one of the following formats, it's actually compressed. + if (hdr) { + if (this->format == ImageFormat::BGRA8888) { + this->format = ImageFormat::SOURCEPP_BGRA8888_HDR; + } else if (this->format == ImageFormat::RGBA16161616) { + if (this->platform == PLATFORM_PC) { + this->format = ImageFormat::SOURCEPP_RGBA16161616_HDR; + } else { + this->format = ImageFormat::SOURCEPP_CONSOLE_RGBA16161616_HDR; + } + } + } // We need to apply this transform because of the broken Borealis skybox in HL2. // Thanks Valve! If this transform isn't applied it breaks conversion to console formats. if (this->flags & FLAG_V0_NO_MIP && this->mipCount > 1) { @@ -540,7 +552,7 @@ VTF::VTF(std::vector&& vtfData, bool parseHeaderOnly) .read(this->format) .read(this->mipCount); - postReadTransform(); + postHeaderReadTransform(); // This will always be DXT1 stream.skip(); @@ -670,7 +682,7 @@ VTF::VTF(std::vector&& vtfData, bool parseHeaderOnly) this->mipCount = (this->flags & FLAG_V0_NO_MIP) ? 1 : ImageDimensions::getMaximumMipCount(this->width, this->height, this->depth); this->fallbackMipCount = (this->flags & FLAG_V0_NO_MIP) ? 1 : ImageDimensions::getMaximumMipCount(this->fallbackWidth, this->fallbackHeight); - postReadTransform(); + postHeaderReadTransform(); // Can't use VTF::getFaceCount yet because there's no image data const auto faceCount = (this->flags & FLAG_V0_ENVMAP) ? 6 : 1; @@ -774,7 +786,7 @@ VTF::VTF(std::vector&& vtfData, bool parseHeaderOnly) .skip() // lowResImageSample (replacement for thumbnail resource, linear color pixel) .skip(); // compressedLength - postReadTransform(); + postHeaderReadTransform(); // Align to 16 bytes if (this->platform == PLATFORM_PS3_PORTAL2) { @@ -829,11 +841,14 @@ VTF::VTF(std::vector&& vtfData, bool parseHeaderOnly) } } -VTF::VTF(std::span vtfData, bool parseHeaderOnly) - : VTF(std::vector{vtfData.begin(), vtfData.end()}, parseHeaderOnly) {} +VTF::VTF(std::span vtfData, bool parseHeaderOnly, bool hdr) + : VTF(std::vector{vtfData.begin(), vtfData.end()}, parseHeaderOnly, hdr) {} VTF::VTF(const std::filesystem::path& vtfPath, bool parseHeaderOnly) - : VTF(fs::readFileBuffer(vtfPath), parseHeaderOnly) {} + : VTF(fs::readFileBuffer(vtfPath), parseHeaderOnly, [](std::string path) { + sourcepp::string::toLower(path); + return path.ends_with(".hdr.vtf") || path.ends_with(".hdr.360.vtf") || path.ends_with(".hdr.ps3.vtf"); + }(vtfPath.filename().string())) {} VTF::VTF(const VTF& other) { *this = other; @@ -2369,17 +2384,24 @@ std::vector VTF::bake() const { return 0; }; - // HACK: no source game supports this format, but they do support the flag with reg. DXT1 + // Miscellaneous fixups to write to the output file auto bakeFormat = this->format; auto bakeFlags = this->flags; + // No source game supports this format, but they do support the flag with reg. DXT1 if (bakeFormat == ImageFormat::DXT1_ONE_BIT_ALPHA) { bakeFormat = ImageFormat::DXT1; bakeFlags |= FLAG_V0_ONE_BIT_ALPHA; } - // HACK: NV_NULL / ATI2N / ATI1N are at a different position based on engine branch + // NV_NULL / ATI2N / ATI1N are at a different position based on engine branch if (this->version < 5 && (this->format == ImageFormat::EMPTY || this->format == ImageFormat::ATI2N || this->format == ImageFormat::ATI1N)) { bakeFormat = static_cast(static_cast(this->format) + 3); } + // Fix up the HDR format + if (bakeFormat == ImageFormat::SOURCEPP_BGRA8888_HDR) { + bakeFormat = ImageFormat::BGRA8888; + } else if (bakeFormat == ImageFormat::SOURCEPP_RGBA16161616_HDR || bakeFormat == ImageFormat::SOURCEPP_CONSOLE_RGBA16161616_HDR) { + bakeFormat = ImageFormat::RGBA16161616; + } switch (this->platform) { case PLATFORM_UNKNOWN: