Skip to content

Transcoder Module Definitions and Classes

Rich Geldreich edited this page Mar 2, 2026 · 45 revisions

This documentation is based off Basis Universal v2.10.

Table of Contents

Intro

Originally, Basis Universal was simply a command line tool (bin/basisu.exe) with a single transcoder .cpp file (transcoder/basisu_transcoder.cpp), so there was no well-defined C++ API for compression. This didn't stop others from building the compressor as a library and calling it like our command line tool does, however.

Over time, as new functionality and codecs were added, we split the encoder into a library of its own and introduced a simple API. The command line tool, C API, and the emscripten JavaScript wrappers internally use this API.

It's recommend to first study our C API before using the C++ API, which is directly layered above the lower level C++ API:

The KTX2 file parser in the transcoder module only supports the specific codecs supported by our compression library, i.e. we don't attempt to support generic KTX2 files using any texture format. See the page KTX2 File Format Support Technical Details.

This page primarily documents the ktx2_transcoder class for transcoding KTX2 files. For transcoding legacy .basis files, see the basisu_transcoder class, which provides a very similar interface with some additional flexibility. It is briefly described at the end of this page.

Our C++17 code doesn't explicitly use C++ exceptions.

There are sharper edges in this API vs. the C API, but the tradeoff is direct access to all features, all low-level codec configuration parameters, etc. We try to keep this API as stable as possible, to avoid breaking external code, our command line tool, or our own C FFI wrappers as new codecs and features are added.

Basis Universal API Architecture

Basis Universal provides multiple API layers to support different platforms and languages:

┌─────────────────────────────────────────────────────────────┐
│                     C++ Core API                            │
│  • Full feature access                                      │
│  • transcoder/basisu_transcoder.h                           │
│  • encoder/basisu_comp.h                                    │
│  • Direct class interfaces (ktx2_transcoder, etc.)          │
└──────────┬──────────────────────┬──────────────┬────────────┘
           │                      │              │
           │                      │              │ (Emscripten embind: webgl/transcoder/basis_wrappers.cpp)
           ↓                      │              ↓
  ┌─────────────────┐             │   ┌──────────────────────┐
  │  basisu Command │             │   │   JavaScript API     │
  │   Line Tool     │             │   │  • Direct C++        │
  │  • bin/basisu   │             │   │    bindings          │
  │  • Compression  │             │   │  • Emscripten        │
  │  • Transcoding  │             │   │  • WebAssembly       │
  │  • Validation   │             │   │  • ktx2_encode_test  │
  └─────────────────┘             │   └──────────────────────┘
                                  │
                                  ↓
                        ┌──────────────────┐
                        │   Pure C API     │
                        │  • Stable ABI    │
                        │  • Handle-based  │
                        │  • basisu_wasm_  │
                        │    api*.h        │
                        └────────┬─────────┘
                                 │
                                 │ (FFI: ctypes, pybind11, etc.)
                                 ↓
                   ┌─────────────────────────────────────┐
                   │    Language Bindings & Platforms    │
                   │  • WebAssembly/WASI Modules         │
                   │  • Python (native FFI or WASI)      │
                   │     • Python tooling (explode_ktx2) |               
                   │  • Other languages via FFI          │
                   └─────────────────────────────────────┘

API Layer Details

Layer Target Users Key Characteristics
C++ Core C++ developers, library integrators Full access to all features, codecs, and configuration parameters, but sharper edges.
Pure C API Native C code, cross-language bindings Stable ABI, opaque handles, comprehensive documentation.
JavaScript Web developers, Node.js Direct Emscripten bindings to C++ classes, WebAssembly optimized: WASM, WASM64, WASM threading.
WASM/Python/FFI WASI modules, Python apps, other languages Uses C API for maximum portability and stability.

Transcoder Global Initialization

This function MUST be called once, and allowed to complete and return, before using any transcoder functionality. It is not mutexed, so if that is important to your use case, you'll need to implement a lock around all calls to this function yourself.

Defined in transcoder/basisu_transcoder.h.

void basisu_transcoder_init();

Low-Level Transcoder Debugging

basisu::enable_debug_printf(bool enabled) globally enables debug printing to stdout. This impacts the compressor, too.

You can set the macro BASISU_FORCE_DEVEL_MESSAGES to 1 in transcoder/basisu.h to enable the transcoder's verbose debug messages printed to stdout. This also enables debug printing.

enum basis_texture_type

Defined in transcoder/basisu_file_headers.h. This enum defines the basic texture types supported by the library: 2D, 2D array, cubemaps, texture video frames, etc. Note volumes are defined here, but we don't support 3D volume textures.

enum basis_texture_type
{
    // An arbitrary array of 2D RGB or RGBA images with optional mipmaps, array size = # images, each image may have a different resolution and # of mipmap levels
    cBASISTexType2D = 0,                

    // An array of 2D RGB or RGBA images with optional mipmaps, array size = # images, each image has the same resolution and mipmap levels
    cBASISTexType2DArray = 1,           
    
    // An array of cubemap levels, total # of images must be divisable by 6, in X+, X-, Y+, Y-, Z+, Z- order, with optional mipmaps
    cBASISTexTypeCubemapArray = 2,      
    
    // An array of 2D video frames, with optional mipmaps, # frames = # images, each image has the same resolution and # of mipmap levels
    cBASISTexTypeVideoFrames = 3,           
    
    // A 3D texture with optional mipmaps, Z dimension = # images, each image has the same resolution and # of mipmap levels
    cBASISTexTypeVolume = 4,            

    cBASISTexTypeTotal
};

enum class basis_tex_format

This enum defines all the Basis Universal supercompressed (latent-based) texture formats, or codecs, supported by the library. It directly corresponds to the BTF_ETC1S etc. macros in the C API.

Defined in transcoder/basisu_file_headers.h.

enum class basis_tex_format
{
    // Original LDR formats
    cETC1S = 0,
    cUASTC_LDR_4x4 = 1,

    // HDR formats
    cUASTC_HDR_4x4 = 2,
    cASTC_HDR_6x6 = 3,
    cUASTC_HDR_6x6_INTERMEDIATE = 4, // or UASTC_HDR_6x6/UASTC_HDR_6x6i

    // XUASTC (supercompressed) LDR variants (the standard ASTC block sizes)
    cXUASTC_LDR_4x4 = 5,
    cXUASTC_LDR_5x4 = 6,
    cXUASTC_LDR_5x5 = 7,
    cXUASTC_LDR_6x5 = 8,

    cXUASTC_LDR_6x6 = 9,
    cXUASTC_LDR_8x5 = 10,
    cXUASTC_LDR_8x6 = 11,
    cXUASTC_LDR_10x5 = 12,

    cXUASTC_LDR_10x6 = 13,
    cXUASTC_LDR_8x8 = 14,
    cXUASTC_LDR_10x8 = 15,
    cXUASTC_LDR_10x10 = 16,

    cXUASTC_LDR_12x10 = 17,
    cXUASTC_LDR_12x12 = 18,
    
    // Standard (non-supercompressed) ASTC LDR variants (the standard ASTC block sizes)
    cASTC_LDR_4x4 = 19,
    cASTC_LDR_5x4 = 20,
    cASTC_LDR_5x5 = 21,
    cASTC_LDR_6x5 = 22,

    cASTC_LDR_6x6 = 23,
    cASTC_LDR_8x5 = 24,
    cASTC_LDR_8x6 = 25,
    cASTC_LDR_10x5 = 26,

    cASTC_LDR_10x6 = 27,
    cASTC_LDR_8x8 = 28,
    cASTC_LDR_10x8 = 29,
    cASTC_LDR_10x10 = 30,

    cASTC_LDR_12x10 = 31,
    cASTC_LDR_12x12 = 32,

    cTotalFormats
};

basis_tex_format introspection helper functions

These functions return basic information about each basis_tex_format format (or codec format) supported by the library.

Defined in transcoder/basisu_file_headers.h or transcoder/basisu_transcoder.h.

These functions directly correspond to the bt_basis_tex_format_get_block_width() etc. helpers in the C API.

inline bool basis_tex_format_is_xuastc_ldr(basis_tex_format tex_fmt)
inline bool basis_tex_format_is_astc_ldr(basis_tex_format tex_fmt)
inline void get_basis_tex_format_block_size(basis_tex_format tex_fmt, uint32_t &width, uint32_t &height)
const char* basis_get_tex_format_name(basis_tex_format fmt);
transcoder_texture_format basis_get_transcoder_texture_format_from_basis_tex_format(basis_tex_format fmt);
bool basis_is_format_supported(transcoder_texture_format tex_type, basis_tex_format fmt);
uint32_t basis_tex_format_get_block_width(basis_tex_format fmt);
uint32_t basis_tex_format_get_block_height(basis_tex_format fmt);
bool basis_tex_format_is_hdr(basis_tex_format fmt);
bool basis_tex_format_is_ldr(basis_tex_format fmt);

enum class transcoder_texture_format

This enum defines all the target texture or pixel formats supported by the transcoder. They directly correspond to the TF_* macros in the C API.

Defined in transcoder/basisu_transcoder.h.

enum class transcoder_texture_format
{
    // Compressed formats

    // ETC1-2
    cTFETC1_RGB = 0,                            // Opaque only, returns RGB or alpha data if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified
    cTFETC2_RGBA = 1,                           // Opaque+alpha, ETC2_EAC_A8 block followed by a ETC1 block, alpha channel will be opaque for opaque .basis files

    // BC1-5, BC7 (desktop, some mobile devices)
    cTFBC1_RGB = 2,                             // Opaque only, no punchthrough alpha support yet, transcodes alpha slice if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified
    cTFBC3_RGBA = 3,                            // Opaque+alpha, BC4 followed by a BC1 block, alpha channel will be opaque for opaque .basis files
    cTFBC4_R = 4,                               // Red only, alpha slice is transcoded to output if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified
    cTFBC5_RG = 5,                              // XY: Two BC4 blocks, X=R and Y=Alpha, .basis file should have alpha data (if not Y will be all 255's)
    cTFBC7_RGBA = 6,                            // RGB or RGBA, mode 5 for ETC1S, modes (1,2,3,5,6,7) for UASTC

    // PVRTC1 4bpp (mobile, PowerVR devices)
    cTFPVRTC1_4_RGB = 8,                        // Opaque only, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified, nearly lowest quality of any texture format.
    cTFPVRTC1_4_RGBA = 9,                       // Opaque+alpha, most useful for simple opacity maps. If .basis file doesn't have alpha cTFPVRTC1_4_RGB will be used instead. Lowest quality of any supported texture format.

    // ASTC (mobile, some Intel CPU's, hopefully all desktop GPU's one day)
    cTFASTC_LDR_4x4_RGBA = 10,                  // LDR. Opaque+alpha, ASTC 4x4, alpha channel will be opaque for opaque .basis files. 
                                                // LDR: Transcoder uses RGB/RGBA/L/LA modes, void extent, and up to two ([0,47] and [0,255]) endpoint precisions.

    // ATC (mobile, Adreno devices, this is a niche format)
    cTFATC_RGB = 11,                            // Opaque, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified. ATI ATC (GL_ATC_RGB_AMD)
    cTFATC_RGBA = 12,                           // Opaque+alpha, alpha channel will be opaque for opaque .basis files. ATI ATC (GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD) 

    // FXT1 (desktop, Intel devices, this is a super obscure format)
    cTFFXT1_RGB = 17,                           // Opaque only, uses exclusively CC_MIXED blocks. Notable for having a 8x4 block size. GL_3DFX_texture_compression_FXT1 is supported on Intel integrated GPU's (such as HD 630).
                                                // Punch-through alpha is relatively easy to support, but full alpha is harder. This format is only here for completeness so opaque-only is fine for now.
                                                // See the BASISU_USE_ORIGINAL_3DFX_FXT1_ENCODING macro in basisu_transcoder_internal.h.

    cTFPVRTC2_4_RGB = 18,                       // Opaque-only, almost BC1 quality, much faster to transcode and supports arbitrary texture dimensions (unlike PVRTC1 RGB).
    cTFPVRTC2_4_RGBA = 19,                      // Opaque+alpha, slower to encode than cTFPVRTC2_4_RGB. Premultiplied alpha is highly recommended, otherwise the color channel can leak into the alpha channel on transparent blocks.

    cTFETC2_EAC_R11 = 20,                       // R only (ETC2 EAC R11 unsigned)
    cTFETC2_EAC_RG11 = 21,                      // RG only (ETC2 EAC RG11 unsigned), R=opaque.r, G=alpha - for tangent space normal maps

    cTFBC6H = 22,                               // HDR, RGB only, unsigned
    cTFASTC_HDR_4x4_RGBA = 23,                  // HDR, RGBA (currently UASTC HDR 4x4 encoders are only RGB), unsigned

    // Uncompressed (raw pixel) formats
    // Note these uncompressed formats (RGBA32, 565, and 4444) can only be transcoded to from LDR input files (ETC1S or UASTC LDR).
    cTFRGBA32 = 13,                             // 32bpp RGBA image stored in raster (not block) order in memory, R is first byte, A is last byte.
    cTFRGB565 = 14,                             // 16bpp RGB image stored in raster (not block) order in memory, R at bit position 11
    cTFBGR565 = 15,                             // 16bpp RGB image stored in raster (not block) order in memory, R at bit position 0
    cTFRGBA4444 = 16,                           // 16bpp RGBA image stored in raster (not block) order in memory, R at bit position 12, A at bit position 0
    
    // Note these uncompressed formats (HALF and 9E5) can only be transcoded to from HDR input files (UASTC HDR 4x4 or ASTC HDR 6x6).
    cTFRGB_HALF = 24,                           // 48bpp RGB half (16-bits/component, 3 components)
    cTFRGBA_HALF = 25,                          // 64bpp RGBA half (16-bits/component, 4 components) (A will always currently 1.0, UASTC_HDR doesn't support alpha)
    cTFRGB_9E5 = 26,                            // 32bpp RGB 9E5 (shared exponent, positive only, see GL_EXT_texture_shared_exponent)

    cTFASTC_HDR_6x6_RGBA = 27,                  // HDR, RGBA (currently our ASTC HDR 6x6 encodes are only RGB), unsigned

    
    // The remaining LDR ASTC block sizes, excluding 4x4 (which is above). There are 14 total valid ASTC LDR/HDR block sizes.
    cTFASTC_LDR_5x4_RGBA = 28,
    cTFASTC_LDR_5x5_RGBA = 29,
    cTFASTC_LDR_6x5_RGBA = 30,
    cTFASTC_LDR_6x6_RGBA = 31,
    cTFASTC_LDR_8x5_RGBA = 32,
    cTFASTC_LDR_8x6_RGBA = 33,
    cTFASTC_LDR_10x5_RGBA = 34,
    cTFASTC_LDR_10x6_RGBA = 35,
    cTFASTC_LDR_8x8_RGBA = 36,
    cTFASTC_LDR_10x8_RGBA = 37,
    cTFASTC_LDR_10x10_RGBA = 38,
    cTFASTC_LDR_12x10_RGBA = 39,
    cTFASTC_LDR_12x12_RGBA = 40,

    cTFTotalTextureFormats = 41,

    // ----- The following are old/legacy enums for compatibility with code compiled against previous versions
    cTFETC1 = cTFETC1_RGB,
    cTFETC2 = cTFETC2_RGBA,
    cTFBC1 = cTFBC1_RGB,
    cTFBC3 = cTFBC3_RGBA,
    cTFBC4 = cTFBC4_R,
    cTFBC5 = cTFBC5_RG,

    // Previously, the caller had some control over which BC7 mode the transcoder output. We've simplified this due to UASTC LDR 4x4, which supports numerous modes.
    cTFBC7_M6_RGB = cTFBC7_RGBA,                // Opaque only, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified. Highest quality of all the non-ETC1 formats.
    cTFBC7_M5_RGBA = cTFBC7_RGBA,               // Opaque+alpha, alpha channel will be opaque for opaque .basis files
    cTFBC7_M6_OPAQUE_ONLY = cTFBC7_RGBA,
    cTFBC7_M5 = cTFBC7_RGBA,
    cTFBC7_ALT = 7,

    cTFASTC_4x4 = cTFASTC_LDR_4x4_RGBA,

    cTFATC_RGBA_INTERPOLATED_ALPHA = cTFATC_RGBA,

    cTFASTC_4x4_RGBA = cTFASTC_LDR_4x4_RGBA
};

Transcode Decode Flags

These flags allow the developer to fine tune the transcoder's behavior. They directly correspond to the DECODE_FLAGS_* macros in the C API.

Defined in transcoder/basisu_transcoder.h.

// Low-level helper classes that do the actual transcoding.
enum basisu_decode_flags
{
    // PVRTC1: decode non-pow2 ETC1S texture level to the next larger power of 2 (not implemented yet, but we're going to support it). Ignored if the slice's dimensions are already a power of 2.
    cDecodeFlagsPVRTCDecodeToNextPow2 = 2,

    // When decoding to an opaque texture format, if the basis file has alpha, decode the alpha slice instead of the color slice to the output texture format.
    // This is primarily to allow decoding of textures with alpha to multiple ETC1 textures (one for color, another for alpha).
    cDecodeFlagsTranscodeAlphaDataToOpaqueFormats = 4,

    // Forbid usage of BC1 3 color blocks (we don't support BC1 punchthrough alpha yet).
    // This flag is used internally when decoding to BC3.
    cDecodeFlagsBC1ForbidThreeColorBlocks = 8,

    // The output buffer contains alpha endpoint/selector indices. 
    // Used internally when decoding formats like ASTC that require both color and alpha data to be available when transcoding to the output format.
    cDecodeFlagsOutputHasAlphaIndices = 16,

    // Enable slower, but higher quality transcoding for some formats.
    // For ASTC/XUASTC->BC7, this enables partially analytical encoding vs. fully analytical.
    cDecodeFlagsHighQuality = 32,

    // Disable ETC1S->BC7 adaptive chroma filtering, for much faster transcoding to BC7.
    cDecodeFlagsNoETC1SChromaFiltering = 64,

    // Disable deblock filtering for XUASTC LDR transcoding to non-ASTC formats. 
    // For ASTC 8x6 or smaller block sizes, deblocking is always disabled unless you force it on using cDecodeFlagsForceDeblockFiltering.
    cDecodeFlagsNoDeblockFiltering = 128,
    
    // More aggressive deblock filtering (only used when it's enabled)
    cDecodeFlagsStrongerDeblockFiltering = 256,
    
    // Always apply deblocking, even for smaller ASTC block sizes (4x4-8x6).
    cDecodeFlagsForceDeblockFiltering = 512, 

    // By default XUASTC LDR 4x4, 6x6 and 8x6 are directly transcoded to BC7 without always requiring a full ASTC block unpack and analytical BC7 encode. This is 1.4x up to 3x faster in WASM.
    // This trade offs some quality. The largest transcoding speed gain is achieved when the source XUASTC data isn't dual plane and only uses 1 subset. Otherwise the actual perf. gain is variable.
    // To disable this optimization for all XUASTC block sizes and always use the fallback encoder, specify cDecodeFlagXUASTCLDRDisableFastBC7Transcoding.
    cDecodeFlagXUASTCLDRDisableFastBC7Transcoding = 1024
};

struct ktx2_image_level_info

This structure contains information about a specific 2D texture "image" in a KTX2 file. It's passed into the ktx2_transcoder::get_image_level_info() introspection method below, which is used to query information about a specific KTX2 level/layer/face.

struct ktx2_image_level_info
{
    // The mipmap level index (0=largest), texture array layer index, and cubemap face index of the image.
    uint32_t m_level_index;
    uint32_t m_layer_index;
    uint32_t m_face_index;

    // The image's ACTUAL (or the original source image's) unpadded width/height in pixels, which may not be divisible by the block size (4-12 pixels).
    uint32_t m_orig_width;
    uint32_t m_orig_height;

    // The image's physical width/height, which will always be divisible by the format's block size (4-12 pixels).
    uint32_t m_width;
    uint32_t m_height;
            
    // The texture's dimensions in 4x4-12x12 texel blocks.
    uint32_t m_num_blocks_x;
    uint32_t m_num_blocks_y;

    // The format's block width/height (4-12).
    uint32_t m_block_width;
    uint32_t m_block_height;

    // The total number of blocks
    uint32_t m_total_blocks;

    // true if the image has alpha data
    bool m_alpha_flag;

    // true if the image is an I-Frame. Currently, for ETC1S textures, the first frame will always be an I-Frame, and subsequent frames will always be P-Frames.
    bool m_iframe_flag;
};

KTX2 Introspection and Transcoding using the ktx2_transcoder class

Construction, Initialization

// Object will be constructed in a fully cleared state (i.e. clear() is called)
ktx2_transcoder::ktx2_transcoder();

// Releases all allocations, sets data KTX2 file data pointer set by init() to nullptr, and clears object.
void ktx2_transcoder::clear();

// Parses the KTD2 header and DFD. The passed in buffer must remain valid unless clear() is called, or the object is destructed.
// Returns true if the KTX2 file is valid and contains a supported format.
bool ktx2_transcoder::init(const void* pData, uint32_t data_size);

// Returns the buffer and size passed into init().
const uint8_t* ktx2_transcoder::get_data() const;
uint32_t ktx2_transcoder::get_data_size() const;

KTX2 File Introspection Methods

The following methods can be used after init() is successfully called:

// Returns the parsed KTX2 header. 
const ktx2_header& ktx2_transcoder::get_header() const;

// Returns the KTX2 level index array.
const basisu::vector<ktx2_level_index>& ktx2_transcoder::get_level_index();

// Returns the texture's width in texels. Always non-zero, unpadded, might not be divisible by the block size.
uint32_t ktx2_transcoder::get_width() const;

// Returns the texture's height in texels. Always non-zero, unpadded, might not be divisible by the block size.
uint32_t ktx2_transcoder::get_height() const;

// Returns the texture's number of mipmap levels. Always returns 1 or higher.
uint32_t ktx2_transcoder::get_levels() const;

// Returns the number of faces. Returns 1 for 2D textures and or 6 for cubemaps.
uint32_t ktx2_transcoder::get_faces() const;

// Returns 0 or the number of layers in the texture array or texture video.
uint32_t ktx2_transcoder::get_layers() const;

// Returns the texture's codec (basis_tex_format): cETC1S, cUASTC4x4, cUASTC_HDR_4x4, etc. 
basist::basis_tex_format ktx2_transcoder::get_basis_tex_format() const;

// Returns true if ETC1S LDR 4x4
bool ktx2_transcoder::is_etc1s() const;

// Returns true if UASTC LDR 4x4 (only)
bool ktx2_transcoder::is_uastc() const;
        
// Returns true if HDR
bool ktx2_transcoder::is_hdr() const;

// Returns true if LDR
bool ktx2_transcoder::is_ldr() const;

// Returns true if UASTC HDR 4x4
bool ktx2_transcoder::is_hdr_4x4() const;

// Returns true if ASTC HDR 6x6 or UASTC HDR 6x6i
bool ktx2_transcoder::is_hdr_6x6() const;
        
// Returns true if ASTC LDR 4x4-12x12 (only)
bool ktx2_transcoder::is_astc_ldr() const;

// Returns true if XUASTC LDR 4x4-12x12 (only)
bool ktx2_transcoder::is_xuastc_ldr() const;

// Returns the file's internal latent block width/height (4x4-12x12)
uint32_t ktx2_transcoder::get_block_width() const;
uint32_t ktx2_transcoder::get_block_height() const;

// Returns true if the file has alpha data.
uint32_t ktx2_transcoder::get_has_alpha() const;

Khronos DFD introspection related methods, valid to call after a successful call to init():

// Returns the entire Data Format Descriptor (DFD) from the KTX2 file. 
const basisu::uint8_vec& ktx2_transcoder::get_dfd() const;

// Some basic DFD accessors.
uint32_t ktx2_transcoder::get_dfd_color_model() const;

// Returns the DFD color primary.
// We do not validate the color primaries, so the returned value may not be in the ktx2_df_color_primaries enum.
ktx2_df_color_primaries ktx2_transcoder::get_dfd_color_primaries() const;

// Returns KTX2_KHR_DF_TRANSFER_LINEAR or KTX2_KHR_DF_TRANSFER_SRGB.
uint32_t ktx2_transcoder::get_dfd_transfer_func() const;

// Returns true if the DFD indicates the SRGB transfer function.
bool ktx2_transcoder::is_srgb() const;

// DFD flags
uint32_t ktx2_transcoder::get_dfd_flags() const;

// Returns 1 (ETC1S/UASTC) or 2 (ETC1S with an internal alpha channel).
uint32_t ktx2_transcoder::get_dfd_total_samples() const;

// Returns the channel mapping for each DFD "sample". UASTC LDR 4x4 always has 1 sample, ETC1S can have one or two. 
// Note the returned value SHOULD be one of the ktx2_df_channel_id enums, but we don't validate that. 
// It's up to the caller to decide what to do if the value isn't in the enum.
ktx2_df_channel_id ktx2_transcoder::get_dfd_channel_id0() const;
ktx2_df_channel_id ktx2_transcoder::get_dfd_channel_id1() const;

KTX2 Key-Value Access

// Key value field data.
struct key_value
{
    // The key field is UTF8 and always zero terminated. 
    // In memory we always append a zero terminator to the key.
    basisu::uint8_vec m_key;

    // The value may be empty. In the KTX2 file it consists of raw bytes which may or may not be zero terminated. 
    // In memory we always append a zero terminator to the value.
    basisu::uint8_vec m_value;
};
typedef basisu::vector<key_value> key_value_vec;

// Returns the array of key-value entries. This may be empty. Valid after init().
// The order of key values fields in this array exactly matches the order they were stored in the file. The keys are supposed to be sorted by their Unicode code points, but we don't validate this.
const key_value_vec& ktx2_transcoder::get_key_values() const;

const basisu::uint8_vec *ktx2_transcoder::find_key(const std::string& key_name) const;

Other Metadata: Texture Video Querying, LDR/SDR->HDR Upconversion Multiplier etc.

// For ETC1S data, if this returns true you must currently transcode the file from first to last frame, in order, without skipping any frames.
// XUASTC LDR texture video is intra-only and supports random access seeking — frames can be transcoded in any order.
bool ktx2_transcoder::is_video() const;

// Defaults to 0, only non-zero if the expected key existed in the source KTX2 file.
float ktx2_transcoder::get_ldr_hdr_upconversion_nit_multiplier() const;

Image Level Introspection: ktx2_transcoder::get_image_level_info()

This method returns detailed information about a specific KTX2 level/layer/face. For texture video, the m_iframe_flag fields won't be valid until after start_transcoding() is called.

bool ktx2_transcoder::get_image_level_info(ktx2_image_level_info& level_info, uint32_t level_index, uint32_t layer_index, uint32_t face_index) const;

Transcoding Methods

ktx2_transcoder::start_transcoding()

start_transcoding() MUST be called before calling transcode_image_level(). This method decompresses the ETC1S global endpoint/selector codebooks, which is not free, so try to avoid calling it excessively.

bool ktx2_transcoder::start_transcoding();

ktx2_transcoder::transcode_image_level()

This method transcodes a specific level/layer/face to a GPU texture or raster image. This methods corresponds to the C API's bt_ktx2_transcode_image_level() function.

For multithreaded transcoding, a user-controlled state object must be created and passed to this method, otherwise it'll use a state object associated with the ktx2_transcoder object (which is not thread safe).

Currently, ETC1S texture video must always be transcoded from first to last frame (or KTX2 "layer"), in order, with no skipping of frames. XUASTC LDR texture video frames are independently decodable and can be transcoded in any order.

If the file is supercompressed with Zstandard, and the file is a texture array or cubemap, it's recommended that each mipmap level is completely transcoded before switching to another level. Every time the mipmap level is changed all supercompressed level data must be decompressed using Zstandard as a single unit.

bool ktx2_transcoder::transcode_image_level(
    uint32_t level_index, uint32_t layer_index, uint32_t face_index,
    void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels,
    basist::transcoder_texture_format fmt,
    uint32_t decode_flags = 0, uint32_t output_row_pitch_in_blocks_or_pixels = 0, uint32_t output_rows_in_pixels = 0, 
    int channel0 = -1, int channel1 = -1,
    ktx2_transcoder_state *pState = nullptr);
Parameter Type Description
level_index uint32_t Mipmap level index (0 = base level).
layer_index uint32_t Array layer index (0 for non-array textures).
face_index uint32_t Cubemap face index (0–5 for cubemaps, 0 for 2D textures).
pOutput_blocks void * Pointer to output buffer.
output_blocks_buf_size_in_blocks_or_pixels uint32_t Size of the output buffer in blocks (for block-compressed formats) or pixels (for uncompressed formats). Important: This is NOT bytes. Used for buffer overflow checking.
fmt basist::transcoder_texture_format Target GPU or pixel format. For ASTC: the target block size must match the source file's block size.
decode_flags uint32_t Bitwise OR of transcoder_texture_format constants, or 0 for defaults.
output_row_pitch_in_blocks_or_pixels uint32_t Output row pitch in blocks or pixels. Pass 0 to use the default (tightly packed rows).
output_rows_in_pixels uint32_t Number of output rows in pixels. Pass 0 to use the default (full image height).
channel0 int First channel remap index for some texture targets. Pass -1 for default behavior.
channel1 int Second channel remap index for some texture targets. Pass -1 for default behavior.
pState ktx2_transcoder_state * Thread-local state, or nullptr to use the default internal state (single-threaded).

Returns: True on success, false on failure.

Transcoding .basis Files using the basisu_transcoder class

For transcoding .basis files (the original Basis Universal container format), use the basisu_transcoder class defined in transcoder/basisu_transcoder.h. Its interface is very similar to ktx2_transcoder — initialization, introspection, start_transcoding(), and per-image-level transcoding all follow the same pattern. The .basis format is slightly less constrained than KTX2: in plain 2D mode (cBASISTexType2D), it supports non-uniform collections of 2D textures where each image may have a different resolution and number of mipmap levels. KTX2 does not support this. (This only applies to plain 2D textures, not 2D texture arrays, cubemaps, or texture video.) See the header for full details.

See Also

Clone this wiki locally