Skip to content

Commit af8d6f7

Browse files
vtfpp: add support for compressed HDR formats
1 parent 4db8d44 commit af8d6f7

17 files changed

Lines changed: 620 additions & 212 deletions

File tree

include/vtfpp/ImageConversion.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ constexpr float DEFAULT_COMPRESSED_QUALITY = -1.f;
2828
/// Fails (returns empty vectors) if the input data is empty, the given width is not 2x the height, or an error was encountered.
2929
[[nodiscard]] std::array<std::vector<std::byte>, 6> convertHDRIToCubeMap(std::span<const std::byte> imageData, ImageFormat format, uint16_t width, uint16_t height, uint16_t resolution = 0, bool bilinear = true);
3030

31+
/// Takes in RGBA32323232F format image data, returns SOURCEPP_BGRA8888_HDR compressed HDR image data (alias for BGRA8888)
32+
[[nodiscard]] std::vector<std::byte> compressBGRA8888HDR(std::span<const std::byte> imageData, float overbrightFactor = 16.f);
33+
34+
/// Takes in SOURCEPP_BGRA8888_HDR compressed HDR image data (alias for BGRA8888), returns RGBA32323232F format image data
35+
[[nodiscard]] std::vector<std::byte> decompressBGRA8888HDR(std::span<const std::byte> imageData, float overbrightFactor = 16.f);
36+
37+
/// Takes in RGBA32323232F format image data, returns SOURCEPP_RGBA16161616_HDR compressed HDR image data (alias for RGBA16161616)
38+
[[nodiscard]] std::vector<std::byte> compressRGBA16161616HDR(std::span<const std::byte> imageData, bool flipExponentAndSignificand = false);
39+
40+
/// Takes in SOURCEPP_RGBA16161616_HDR compressed HDR image data (alias for RGBA16161616), returns RGBA32323232F format image data
41+
[[nodiscard]] std::vector<std::byte> decompressRGBA16161616HDR(std::span<const std::byte> imageData, bool flipExponentAndSignificand = false);
42+
3143
enum class FileFormat {
3244
DEFAULT = 0,
3345
PNG = 1,

include/vtfpp/ImageFormats.h

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ enum class ImageFormat : int32_t {
8181
STRATA_BC7,
8282
STRATA_BC6H,
8383
// endregion
84+
85+
// region SourcePP Virtual Formats
86+
SOURCEPP_BGRA8888_HDR = 10000,
87+
SOURCEPP_RGBA16161616_HDR,
88+
SOURCEPP_CONSOLE_RGBA16161616_HDR,
89+
// endregion
8490
};
8591

8692
namespace ImageFormatDetails {
@@ -157,6 +163,9 @@ namespace ImageFormatDetails {
157163
case TFALL2_BC7:
158164
case STRATA_BC7:
159165
case STRATA_BC6H:
166+
case SOURCEPP_BGRA8888_HDR:
167+
case SOURCEPP_RGBA16161616_HDR:
168+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
160169
return -1;
161170
}
162171
return 0;
@@ -182,6 +191,9 @@ namespace ImageFormatDetails {
182191
return 8;
183192
case TFALL2_BC6H:
184193
case STRATA_BC6H:
194+
case SOURCEPP_BGRA8888_HDR:
195+
case SOURCEPP_RGBA16161616_HDR:
196+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
185197
return 16;
186198
default:
187199
break;
@@ -262,6 +274,9 @@ namespace ImageFormatDetails {
262274
case TFALL2_BC7:
263275
case STRATA_BC7:
264276
case STRATA_BC6H:
277+
case SOURCEPP_BGRA8888_HDR:
278+
case SOURCEPP_RGBA16161616_HDR:
279+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
265280
return -1;
266281
}
267282
return 0;
@@ -287,6 +302,9 @@ namespace ImageFormatDetails {
287302
return 8;
288303
case TFALL2_BC6H:
289304
case STRATA_BC6H:
305+
case SOURCEPP_BGRA8888_HDR:
306+
case SOURCEPP_RGBA16161616_HDR:
307+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
290308
return 16;
291309
default:
292310
break;
@@ -366,6 +384,9 @@ namespace ImageFormatDetails {
366384
case TFALL2_BC7:
367385
case STRATA_BC7:
368386
case STRATA_BC6H:
387+
case SOURCEPP_BGRA8888_HDR:
388+
case SOURCEPP_RGBA16161616_HDR:
389+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
369390
return -1;
370391
}
371392
return 0;
@@ -391,6 +412,9 @@ namespace ImageFormatDetails {
391412
return 8;
392413
case TFALL2_BC6H:
393414
case STRATA_BC6H:
415+
case SOURCEPP_BGRA8888_HDR:
416+
case SOURCEPP_RGBA16161616_HDR:
417+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
394418
return 16;
395419
default:
396420
break;
@@ -470,6 +494,9 @@ namespace ImageFormatDetails {
470494
case TFALL2_BC7:
471495
case STRATA_BC7:
472496
case STRATA_BC6H:
497+
case SOURCEPP_BGRA8888_HDR:
498+
case SOURCEPP_RGBA16161616_HDR:
499+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
473500
return -1;
474501
}
475502
return 0;
@@ -497,6 +524,9 @@ namespace ImageFormatDetails {
497524
case ATI1N:
498525
case TFALL2_BC6H:
499526
case STRATA_BC6H:
527+
case SOURCEPP_BGRA8888_HDR:
528+
case SOURCEPP_RGBA16161616_HDR:
529+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
500530
return 0;
501531
default:
502532
break;
@@ -520,6 +550,8 @@ namespace ImageFormatDetails {
520550
case RGBA16161616F:
521551
case RGBA16161616:
522552
case CONSOLE_RGBA16161616_LINEAR:
553+
case SOURCEPP_RGBA16161616_HDR:
554+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
523555
case RG3232F:
524556
return 64;
525557
case RGBA8888:
@@ -531,6 +563,7 @@ namespace ImageFormatDetails {
531563
case BGRA8888:
532564
case CONSOLE_BGRA8888_LINEAR:
533565
case CONSOLE_BGRA8888_LE:
566+
case SOURCEPP_BGRA8888_HDR:
534567
case BGRX8888:
535568
case CONSOLE_BGRX8888_LINEAR:
536569
case CONSOLE_BGRX8888_LE:
@@ -602,6 +635,9 @@ namespace ImageFormatDetails {
602635
case RGBA32323232F:
603636
case TFALL2_BC6H:
604637
case STRATA_BC6H:
638+
case SOURCEPP_BGRA8888_HDR:
639+
case SOURCEPP_RGBA16161616_HDR:
640+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
605641
return RGBA32323232F;
606642
case RGBA16161616:
607643
case CONSOLE_RGBA16161616_LINEAR:
@@ -676,14 +712,32 @@ namespace ImageFormatDetails {
676712
}
677713

678714
/**
679-
* Check if the given format is a compressed format (DXT1, DXT3, DXT5, ATI1N, ATI2N, BC7, BC6H).
715+
* Check if the given format is a compressed format (DXT1, DXT3, DXT5, ATI1N, ATI2N, BC7, BC6H, BGRA8888 HDR, RGBA16161616 HDR).
680716
* @param format The format to check.
681717
* @return True if the given format is compressed.
682718
*/
683719
[[nodiscard]] constexpr bool compressed(ImageFormat format) {
684720
return red(format) == -1;
685721
}
686722

723+
/**
724+
* Check if the given format is a compressed HDR format (not counting BC6H).
725+
* @param format The format to check.
726+
* @return True if the format is a compressed HDR format..
727+
*/
728+
[[nodiscard]] constexpr bool compressedHDR(ImageFormat format) {
729+
switch (format) {
730+
using enum ImageFormat;
731+
case SOURCEPP_BGRA8888_HDR:
732+
case SOURCEPP_RGBA16161616_HDR:
733+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
734+
return true;
735+
default:
736+
break;
737+
}
738+
return false;
739+
}
740+
687741
/**
688742
* Check if the given format can store transparency.
689743
* @param format The format to check.
@@ -757,6 +811,42 @@ namespace ImageFormatDetails {
757811
case CONSOLE_RGBA16161616_LINEAR:
758812
case CONSOLE_BGRX8888_LE:
759813
case CONSOLE_BGRA8888_LE:
814+
case SOURCEPP_CONSOLE_RGBA16161616_HDR:
815+
return true;
816+
default:
817+
break;
818+
}
819+
return false;
820+
}
821+
822+
/**
823+
* Check if the given format is exclusively used by Titanfall 2.
824+
* @param format The format to check.
825+
* @return True if the format is exclusively used by Titanfall 2.
826+
*/
827+
[[nodiscard]] constexpr bool tfall2(ImageFormat format) {
828+
switch (format) {
829+
using enum ImageFormat;
830+
case TFALL2_BC6H:
831+
case TFALL2_BC7:
832+
return true;
833+
default:
834+
break;
835+
}
836+
return false;
837+
}
838+
839+
/**
840+
* Check if the given format is exclusively used by Strata Source.
841+
* @param format The format to check.
842+
* @return True if the format is exclusively used by Strata Source.
843+
*/
844+
[[nodiscard]] constexpr bool strata(ImageFormat format) {
845+
switch (format) {
846+
using enum ImageFormat;
847+
case STRATA_R8:
848+
case STRATA_BC7:
849+
case STRATA_BC6H:
760850
return true;
761851
default:
762852
break;
@@ -869,7 +959,7 @@ namespace ImageFormatDetails {
869959
* @return The length in bytes of a texture containing the given format, width, height, and depth.
870960
*/
871961
[[nodiscard]] constexpr uint32_t getDataLength(ImageFormat format, uint16_t width, uint16_t height, uint16_t depth = 1) {
872-
if (ImageFormatDetails::compressed(format)) {
962+
if (ImageFormatDetails::compressed(format) && !ImageFormatDetails::compressedHDR(format)) {
873963
return ((width + 3) / 4) * ((height + 3) / 4) * depth * bpp(format) * 2;
874964
}
875965
return width * height * depth * (bpp(format) / 8);

include/vtfpp/ImagePixel.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,27 @@ VTFPP_FORMAT(
417417
VTFPP_R
418418
);
419419

420+
VTFPP_FORMAT(
421+
SOURCEPP_BGRA8888_HDR,
422+
VTFPP_FORMAT_LE(uint8_t r, g, b, a)
423+
VTFPP_FORMAT_BE(uint8_t a, b, g, r),
424+
VTFPP_R VTFPP_G VTFPP_B VTFPP_A
425+
);
426+
427+
VTFPP_FORMAT(
428+
SOURCEPP_RGBA16161616_HDR,
429+
VTFPP_FORMAT_LE(uint16_t r, g, b, a)
430+
VTFPP_FORMAT_BE(uint16_t a, b, g, r),
431+
VTFPP_R VTFPP_G VTFPP_B VTFPP_A
432+
);
433+
434+
VTFPP_FORMAT(
435+
SOURCEPP_CONSOLE_RGBA16161616_HDR,
436+
VTFPP_FORMAT_LE(uint16_t r, g, b, a)
437+
VTFPP_FORMAT_BE(uint16_t a, b, g, r),
438+
VTFPP_R VTFPP_G VTFPP_B VTFPP_A
439+
);
440+
420441
#undef VTFPP_FORMAT
421442
#undef VTFPP_FORMAT_BE
422443
#undef VTFPP_FORMAT_LE
@@ -487,7 +508,10 @@ concept PixelType =
487508
std::same_as<T, CONSOLE_RGBA16161616_LINEAR> ||
488509
std::same_as<T, CONSOLE_BGRX8888_LE> ||
489510
std::same_as<T, CONSOLE_BGRA8888_LE> ||
490-
std::same_as<T, STRATA_R8>;
511+
std::same_as<T, STRATA_R8> ||
512+
std::same_as<T, SOURCEPP_BGRA8888_HDR> ||
513+
std::same_as<T, SOURCEPP_RGBA16161616_HDR> ||
514+
std::same_as<T, SOURCEPP_CONSOLE_RGBA16161616_HDR>;
491515

492516
/// Extracts a single channel from the given image data.
493517
/// May have unexpected behavior if called on formats that use bitfields like BGRA5551!

include/vtfpp/VTF.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,9 @@ class VTF {
228228

229229
VTF();
230230

231-
explicit VTF(std::vector<std::byte>&& vtfData, bool parseHeaderOnly = false);
231+
explicit VTF(std::vector<std::byte>&& vtfData, bool parseHeaderOnly = false, bool hdr = false);
232232

233-
explicit VTF(std::span<const std::byte> vtfData, bool parseHeaderOnly = false);
233+
explicit VTF(std::span<const std::byte> vtfData, bool parseHeaderOnly = false, bool hdr = false);
234234

235235
explicit VTF(const std::filesystem::path& vtfPath, bool parseHeaderOnly = false);
236236

lang/c/include/vtfppc/ImageConversion.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ VTFPP_EXTERNVAR const float VTFPP_IMAGE_CONVERSION_DEFAULT_COMPRESSED_QUALITY;
1111

1212
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
1313
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
14-
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
15-
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
14+
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
15+
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
16+
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
17+
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
18+
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
1619

1720
VTFPP_EXTERN typedef enum {
1821
VTFPP_IMAGE_CONVERSION_FILE_FORMAT_DEFAULT = 0,

0 commit comments

Comments
 (0)