Two things prevented the transcoder from compiling with
BASISD_SUPPORT_KTX2 set to 0:
- ktx2_image_level_info was defined inside the #if BASISD_SUPPORT_KTX2
block, but dds_transcoder::get_image_level_info() takes it by
reference and is compiled unconditionally. Move the struct ahead of
that block so it is always defined; it has no KTX2-specific members.
- The "#include ../zstd/zstd.h" was nested inside #if BASISD_SUPPORT_KTX2,
but the Zstd decompressor (zstd_decompress()) is compiled whenever
BASISD_SUPPORT_KTX2_ZSTD is set, independent of KTX2 (Zstd is also used
by other codecs). With KTX2 off but Zstd on, the ZSTD_* symbols were
referenced without the header being included. Gate the include on
BASISD_SUPPORT_KTX2_ZSTD alone, matching where the symbols are used.
BASISD_SUPPORT_KTX2_ZSTD still defaults to 1 (unchanged). The default
build (KTX2 and Zstd both enabled) is unaffected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The KTX2 level and supercompression-global-data (SGD) offset/length
fields are full 64-bit values read from the file. init() validated them
with "offset + length > m_data_size", where the addition can wrap around
and incorrectly pass for out-of-range values. Rewrite both checks as
"offset > m_data_size || length > (uint64_t)m_data_size - offset", which
cannot overflow (offset is confirmed <= m_data_size before the
subtraction, so it can't underflow either). The result is identical to
the original for every in-range input.
Also in init():
- Reject a level whose byte_length is 0. This case already logged an
error but fell through without returning false.
- Add KTX2_MAX_SUPPORTED_LAYER_COUNT (65535) and reject files whose
layer_count exceeds it, mirroring KTX2_MAX_SUPPORTED_LEVEL_COUNT, so
layer_count * face_count * level_count stays bounded.
read_slice_offset_len_global_data(): compute image_count in 64-bit,
verify m_sgd_byte_length == image_count * descriptor_size before sizing
the descriptor array, and use try_resize() (returns false on failure)
instead of resize() (which aborts the process) so an out-of-range count
fails cleanly instead of attempting an oversized allocation. Also
compute image_count in 64-bit in decompress_etc1s_global_data().
Valid files are handled exactly as before.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This update impacts the UASTC HDR 4x4, UASTC HDR 6x6i, and XUASTC LDR formats. New KTX2 files in these specific formats using v2.1 can't be loaded using v2.0, however we've kept backwards compatibility with all of our previously written KTX2 files. (v2.1 can transcode all previously written files.)
This is part of our effort to be compatible with Khronos's specification.
bc6hf encoder's smooth block path updated to handle inputs with texels close to MAX_HALF_FLOAT.
Adding command line options to basisu tool so it can write either v2.0 or v1.6 compatible UASTC HDR 6x6i files. The default is v1.6.
Updating WebGL KTX2 testbed so on ASTC devices it automatically switches between sRGB or linear internal formats for the created texture.
- Minor fix to basisu_frontend::optimize_selector_codebook() so the new_selector_cluster_indices array is initialized correctly. (The backend doesn't use this array so no harm was being done.)
- Optimized ETC1S encoder (3-4.5x faster)
- Added optional SSE 4.1 support to encoder
- Switched from std::vector to a custom vector in the encoder and transcoder
- Added CppSPMD (SSE only for now)
- UASTC RDO is now more effective, but the command line parameter controlling qualiy has changed (to "lambda")
Encoder is now a library in the "encoder" directory
JavaScript wrappers now expose the entire codec: encoder, transcoder, container independent transcoding, and .basis file information
- Removing BC7 mode 6 support from transcoder (will alway use the much smaller mode 5 tables now)
- Adding BMP support
- Adding -bench mode, for development
- CMakeLists.txt file now compatible with Visual Studio 2019 (MSVC)
- Renaming -no_auto_global_sel_pal to -auto_global_sel_pal, disabling global selector palette usage by default to speed up compression on small images
- Renaming texture format enums
- Fixing uninitialized memory issue in front end - it wouldn't have affected the correctness of the output, or output quality
- Bumping command line tool up to v1.10
- For PVRTC1, we now memset() any extra blocks after the blocks we know will be transcoded into. This is done because in GL there is padding that occurs on textures smaller than 8x8.
- Removing all OpenMP usage and replacing it with a basis C++11 job system.
- Fixing TSVQ class so it can split very long "thin" clusters that before weren't being split. This improves endpoint quantization on videos and complex 2D textures.
- More frontend perf. optimizations.
Tested on OSX, Linux with gcc/clang, and Win using MSVC 2019.
Increasing the max codebook size to 16K vs. 8K, for a major increase in the max achievable quality.
Adding exception catching to command line tool.
Enabling debug iterators on MSVC.
Refining command line options, adding "-individual" flag to create multiple .basis files (vs. a texture array).
Changing default colorspace to sRGB, because that's probably the best default. -linear disables this and uses linear colorspace metrics.
PNG reader in 32-bit builds checks the size of the file before loading to avoid out of memory exceptions.
Adding new fields to the basis header: texture type and framerate. Texture type may be 2D, 2D array, video, volume, or cubemap array. The compressor makes sure that anything other than pure 2D follows certain constraints (cubemap arrays must have a multiple of 6 input images, videos/texture array images all must have the same resolution/# of mipmaps, etc.)
When unpacking cubemaps, the -unpack command now writes cubemap .KTX files which various tools like PVRTexTool support.
Adding new GPU texture format decoders for BC1/4/5, ETC2 EAC alpha, and BC7 mode 6
Adding GPU texture unpack failure checks and warnings
Adding support for 3 color blocks to transcoder, and making sure that BC3 blocks will never use 3 color (punchthrough alpha) blocks.