// basisu_transcoder.h // Copyright (C) 2019-2024 Binomial LLC. All Rights Reserved. // Important: If compiling with gcc, be sure strict aliasing is disabled: -fno-strict-aliasing // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once // By default KTX2 support is enabled to simplify compilation. This implies the need for the Zstandard library (which we distribute as a single source file in the "zstd" directory) by default. // Set BASISD_SUPPORT_KTX2 to 0 to completely disable KTX2 support as well as Zstd/miniz usage which is only required for UASTC supercompression in KTX2 files. // Also see BASISD_SUPPORT_KTX2_ZSTD in basisu_transcoder.cpp, which individually disables Zstd usage. #ifndef BASISD_SUPPORT_KTX2 #define BASISD_SUPPORT_KTX2 … #endif // Set BASISD_SUPPORT_KTX2_ZSTD to 0 to disable Zstd usage and KTX2 UASTC Zstd supercompression support #ifndef BASISD_SUPPORT_KTX2_ZSTD #define BASISD_SUPPORT_KTX2_ZSTD … #endif // Set BASISU_FORCE_DEVEL_MESSAGES to 1 to enable debug printf()'s whenever an error occurs, for easier debugging during development. #ifndef BASISU_FORCE_DEVEL_MESSAGES // TODO - disable before checking in #define BASISU_FORCE_DEVEL_MESSAGES … #endif #include "basisu_transcoder_internal.h" #include "basisu_transcoder_uastc.h" #include "basisu_file_headers.h" namespace basist { // High-level composite texture formats supported by the transcoder. // Each of these texture formats directly correspond to OpenGL/D3D/Vulkan etc. texture formats. // Notes: // - If you specify a texture format that supports alpha, but the .basis file doesn't have alpha, the transcoder will automatically output a // fully opaque (255) alpha channel. // - The PVRTC1 texture formats only support power of 2 dimension .basis files, but this may be relaxed in a future version. // - The PVRTC1 transcoders are real-time encoders, so don't expect the highest quality. We may add a slower encoder with improved quality. // - These enums must be kept in sync with Javascript code that calls the transcoder. enum class transcoder_texture_format { … }; // For compressed texture formats, this returns the # of bytes per block. For uncompressed, it returns the # of bytes per pixel. // NOTE: Previously, this function was called basis_get_bytes_per_block(), and it always returned 16*bytes_per_pixel for uncompressed formats which was confusing. uint32_t basis_get_bytes_per_block_or_pixel(transcoder_texture_format fmt); // Returns format's name in ASCII const char* basis_get_format_name(transcoder_texture_format fmt); // Returns block format name in ASCII const char* basis_get_block_format_name(block_format fmt); // Returns true if the format supports an alpha channel. bool basis_transcoder_format_has_alpha(transcoder_texture_format fmt); // Returns true if the format is HDR. bool basis_transcoder_format_is_hdr(transcoder_texture_format fmt); // Returns the basisu::texture_format corresponding to the specified transcoder_texture_format. basisu::texture_format basis_get_basisu_texture_format(transcoder_texture_format fmt); // Returns the texture type's name in ASCII. const char* basis_get_texture_type_name(basis_texture_type tex_type); // Returns true if the transcoder texture type is an uncompressed (raw pixel) format. bool basis_transcoder_format_is_uncompressed(transcoder_texture_format tex_type); // Returns the # of bytes per pixel for uncompressed formats, or 0 for block texture formats. uint32_t basis_get_uncompressed_bytes_per_pixel(transcoder_texture_format fmt); // Returns the block width for the specified texture format, which is currently either 4 or 8 for FXT1. uint32_t basis_get_block_width(transcoder_texture_format tex_type); // Returns the block height for the specified texture format, which is currently always 4. uint32_t basis_get_block_height(transcoder_texture_format tex_type); // Returns true if the specified format was enabled at compile time, and is supported for the specific basis/ktx2 texture format (ETC1S, UASTC, or UASTC HDR). bool basis_is_format_supported(transcoder_texture_format tex_type, basis_tex_format fmt = basis_tex_format::cETC1S); // Validates that the output buffer is large enough to hold the entire transcoded texture. // For uncompressed texture formats, most input parameters are in pixels, not blocks. Blocks are 4x4 pixels. bool basis_validate_output_buffer_size(transcoder_texture_format target_format, uint32_t output_blocks_buf_size_in_blocks_or_pixels, uint32_t orig_width, uint32_t orig_height, uint32_t output_row_pitch_in_blocks_or_pixels, uint32_t output_rows_in_pixels, uint32_t total_slice_blocks); class basisu_transcoder; // This struct holds all state used during transcoding. For video, it needs to persist between image transcodes (it holds the previous frame). // For threading you can use one state per thread. struct basisu_transcoder_state { … }; // Low-level helper class that does the actual transcoding. class basisu_lowlevel_etc1s_transcoder { … }; enum basisu_decode_flags { … }; class basisu_lowlevel_uastc_transcoder { … }; class basisu_lowlevel_uastc_hdr_transcoder { … }; struct basisu_slice_info { … }; basisu_slice_info_vec; struct basisu_image_info { … }; struct basisu_image_level_info { … }; struct basisu_file_info { … }; // High-level transcoder class which accepts .basis file data and allows the caller to query information about the file and transcode image levels to various texture formats. // If you're just starting out this is the class you care about. class basisu_transcoder { … }; // basisu_transcoder_init() MUST be called before a .basis file can be transcoded. void basisu_transcoder_init(); enum debug_flags_t { … }; uint32_t get_debug_flags(); void set_debug_flags(uint32_t f); // ------------------------------------------------------------------------------------------------------ // Optional .KTX2 file format support // KTX2 reading optionally requires miniz or Zstd decompressors for supercompressed UASTC files. // ------------------------------------------------------------------------------------------------------ #if BASISD_SUPPORT_KTX2 #pragma pack(push) #pragma pack(1) struct ktx2_header { … }; struct ktx2_level_index { … }; struct ktx2_etc1s_global_data_header { … }; struct ktx2_etc1s_image_desc { … }; struct ktx2_animdata { … }; #pragma pack(pop) const uint32_t KTX2_VK_FORMAT_UNDEFINED = …; const uint32_t KTX2_FORMAT_UASTC_4x4_SFLOAT_BLOCK = …; // TODO, is this correct? const uint32_t KTX2_KDF_DF_MODEL_UASTC = …; const uint32_t KTX2_KDF_DF_MODEL_UASTC_HDR = …; const uint32_t KTX2_KDF_DF_MODEL_ETC1S = …; const uint32_t KTX2_IMAGE_IS_P_FRAME = …; const uint32_t KTX2_UASTC_BLOCK_SIZE = …; // also the block size for UASTC_HDR const uint32_t KTX2_MAX_SUPPORTED_LEVEL_COUNT = …; // this is an implementation specific constraint and can be increased // The KTX2 transfer functions supported by KTX2 const uint32_t KTX2_KHR_DF_TRANSFER_LINEAR = …; const uint32_t KTX2_KHR_DF_TRANSFER_SRGB = …; enum ktx2_supercompression { … }; extern const uint8_t g_ktx2_file_identifier[12]; enum ktx2_df_channel_id { … }; inline const char* ktx2_get_etc1s_df_channel_id_str(ktx2_df_channel_id id) { … } inline const char* ktx2_get_uastc_df_channel_id_str(ktx2_df_channel_id id) { … } enum ktx2_df_color_primaries { … }; inline const char* ktx2_get_df_color_primaries_str(ktx2_df_color_primaries p) { … } // Information about a single 2D texture "image" in a KTX2 file. struct ktx2_image_level_info { … }; // Thread-specific ETC1S/supercompressed UASTC transcoder state. (If you're not doing multithreading transcoding you can ignore this.) struct ktx2_transcoder_state { … }; // This class is quite similar to basisu_transcoder. It treats KTX2 files as a simple container for ETC1S/UASTC texture data. // It does not support 1D or 3D textures. // It only supports 2D and cubemap textures, with or without mipmaps, texture arrays of 2D/cubemap textures, and texture video files. // It only supports raw non-supercompressed UASTC, ETC1S, UASTC+Zstd, or UASTC+zlib compressed files. // DFD (Data Format Descriptor) parsing is purposely as simple as possible. // If you need to know how to interpret the texture channels you'll need to parse the DFD yourself after calling get_dfd(). class ktx2_transcoder { … }; #endif // BASISD_SUPPORT_KTX2 // Returns true if the transcoder was compiled with KTX2 support. bool basisu_transcoder_supports_ktx2(); // Returns true if the transcoder was compiled with Zstandard support. bool basisu_transcoder_supports_ktx2_zstd(); } // namespace basisu