XUASTC LDR - log_astc_block Structure
Copyright (C) 2025-2026 Binomial LLC. All rights reserved except as granted under the Apache 2.0 LICENSE. If you modify the Basis Universal source code, specifications, or wiki documents and redistribute the files, you must cause any modified files to carry prominent notices stating that you changed the files (see Apache 2.0 §4(b)).
Introduction
This document provides a minimal specification for the log_astc_block structure and associated ASTC specific constants, which represents the logical (decoded) form of a physical 128-bit ASTC (Adaptive Scalable Texture Compression) block. The log_astc_block is heavily used in XUASTC LDR decoding within the Basis Universal library, losslessly abstracting an ASTC block's configuration, endpoints, weights, and partitions for efficient transcoding and decompression.
At a high level, log_astc_block parses or holds the decoded components extracted from physical ASTC blocks: flags for errors or solid colors, weight grid dimensions, mode flags (e.g., dual-plane), weight and endpoint quantization ranges (ISE/BISE), partition details, per-partition Color Endpoint Mode (CEM) indices, weight grid values, and CEM encoded endpoint values. It interacts with packing/unpacking routines (e.g., pack_astc_block, unpack_block) to convert between physical (bitstream) and logical forms.
This spec covers only this structure, its members, and directly associated constants/enums. Refer to the full Khronos ASTC specification for broader format details. This spec is structured with constants/limits first, followed by enums, then the structure with field descriptions.
Also see List of Available Software ASTC Decoders, which has a section on known ASTC spec issues, and links to two logical to physical ASTC block packers.
Constants and Limits
These define bounds and limits for the logical block, ensuring valid configurations during decoding/packing. They control grid sizes, partitions, weights, endpoints, and ISE ranges, preventing overflows or invalid states.
MIN_GRID_DIM: 2 (minimum dimension of a block's weight grid).MIN_BLOCK_DIM: 4 (minimum texel block dimension).MAX_BLOCK_DIM: 12 (maximum texel block dimension).MAX_BLOCK_PIXELS: 144 (maximum texels per block, 12x12).MAX_GRID_WEIGHTS: 64 (maximum weight grid values per block).MAX_CEM_ENDPOINT_VALS: 8 (maximum endpoint ISE values to encode any CEM, minimum 2).NUM_MODE0_ENDPOINTS: 2 (LDR endpoints for CEM 0).NUM_MODE4_ENDPOINTS: 4 (LDR endpoints for CEM 4).NUM_MODE6_ENDPOINTS: 4 (LDR RGB endpoints for CEM 6).NUM_MODE7_ENDPOINTS: 4 (HDR-specific endpoints for CEM 7).NUM_MODE8_ENDPOINTS: 6 (LDR RGB endpoints for CEM 8).NUM_MODE9_ENDPOINTS: 6 (LDR RGB endpoints for CEM 9).NUM_MODE10_ENDPOINTS: 6 (LDR RGB endpoints for CEM 10).NUM_MODE11_ENDPOINTS: 6 (HDR-specific endpoints for CEM 11).NUM_MODE12_ENDPOINTS: 8 (LDR RGBA endpoints for CEM 12).NUM_MODE13_ENDPOINTS: 8 (LDR RGBA endpoints for CEM 13).MAX_WEIGHTS: 32 (maximum # of weights or "selector" ISE values for the least quantized weight ISE range).MAX_WEIGHT_VALUE: 64 (weight interpolant range [0,64]).NUM_ASTC_BLOCK_SIZES: 14 (unique 2D block dimensions supported by ASTC).MAX_PARTITIONS: 4 (maximum partitions/subsets in single-plane mode).MAX_DUAL_PLANE_PARTITIONS: 3 (maximum partitions/subsets in dual-plane mode).NUM_PARTITION_PATTERNS: 1024 (total partition pattern seeds, 10-bits).MAX_ENDPOINTS: 18 (maximum endpoint ISE values per block).FIRST_VALID_ENDPOINT_ISE_RANGE: 4 (start of valid BISE ranges for endpoints).LAST_VALID_ENDPOINT_ISE_RANGE: 20 (end of valid BISE ranges for endpoints).TOTAL_ENDPOINT_ISE_RANGES: 17 (total valid endpoint BISE ranges).FIRST_VALID_WEIGHT_ISE_RANGE: 0 (start of valid BISE ranges for weights).LAST_VALID_WEIGHT_ISE_RANGE: 11 (end of valid BISE ranges for weights).TOTAL_WEIGHT_ISE_RANGES: 12 (total valid weight BISE ranges).TOTAL_ISE_RANGES: 21 (total BISE ranges across endpoints/weights).
log_astc_block Structure
This structure holds the logical decoded state of an ASTC block, used for unpacking from physical bitstream or packing to it. It abstracts configuration for LDR decoding (integer endpoints/weights) while supporting HDR flags/values. Fields are validated during pack/unpack; invalid configs set error flag.
m_error_flag: bool, indicates invalid block configuration (e.g., illegal encoding, overflow); set during physical block unpacking if decoding fails.m_solid_color_flag_ldr: bool, true for LDR void-extent/solid color block (uniform color, no weights/endpoints).m_solid_color_flag_hdr: bool, true for HDR void-extent/solid color block (uniform FP16 color).m_solid_color[4]: array of uint16_t (size 4), solid color values (LDR: replicated 8-bit; HDR: FP16).
These members are only valid if the block is not an error block and not solid color (void-extent):
m_grid_width: uint8_t, weight grid width (2-12; note not texel block dimension).m_grid_height: uint8_t, weight grid height (2-12; note not texel block dimension).m_dual_plane: bool, true if dual-plane mode (two weight grids; max 3 partitions).m_weight_ise_range: uint8_t, BISE range for weights (0-11).m_endpoint_ise_range: uint8_t, BISE range for endpoints (4-20; inferred from config/remaining bits during physical block decoding/encoding).m_color_component_selector: uint8_t, CCS enum (0-3) for dual-plane channel selection.m_num_partitions: uint8_t, number of subsets/partitions (1-4; 1-3 if dual-plane).m_partition_id: uint16_t, 10-bit seed for partition pattern (0 if 1 partition).m_color_endpoint_modes[MAX_PARTITIONS]: array of uint8_t (size MAX_PARTITIONS=4), CEM enum per partition. (Note for XUASTC LDR only: all CEM values must be the same for all subsets.)m_weights[MAX_GRID_WEIGHTS]: array of uint8_t (size MAX_GRID_WEIGHTS=64), ISE weight grid values; dual-plane interleaves planes (p0,p1,...).m_endpoints[MAX_ENDPOINTS]: array of uint8_t (size MAX_ENDPOINTS=18), ISE endpoint values per partition/CEM