modifications for v2.5

This commit is contained in:
Richard Geldreich
2026-07-01 13:16:04 -04:00
parent e5aa8306f3
commit afb3d4aef2
7 changed files with 58 additions and 9 deletions

View File

@@ -101,6 +101,7 @@ class Encoder:
params = enc.new_params()
buf_ptr = None
try:
buf_ptr = enc.alloc(len(bytes_data))
@@ -137,6 +138,7 @@ class Encoder:
params = enc.new_params()
buf_ptr = None
try:
buf_ptr = enc.alloc(len(bytes_data))
enc.write_bytes(buf_ptr, bytes_data)

View File

@@ -46,6 +46,9 @@ class BasisTexFormat:
cASTC_LDR_12x10= 31
cASTC_LDR_12x12= 32
# Supercompressed BC7
cXUBC7 = 33
# ============================================================
# Unified quality level: 1-100 (higher=better quality, 100 disables some codec options)
# ============================================================
@@ -106,6 +109,17 @@ class BasisFlags:
TEXTURE_TYPE_SHIFT = 25
TEXTURE_TYPE_MASK = 3
# ASTC/XUASTC LDR deblocking control (default: deblock block sizes >= 80 texels/block)
DISABLE_DEBLOCKING = 1 << 27
FORCE_DEBLOCKING = 1 << 28
# XUBC7 only: BC7 base-encoder selection, packed into a 3-bit field.
# Field 0 = bc7f (default fast packer); 1-7 = bc7e_scalar at level 0-6 (field = level + 1).
# Build a bc7e_scalar value as: ((level + 1) << XUBC7_BASE_ENCODER_SHIFT)
XUBC7_BASE_ENCODER_BC7F = 0 << 29
XUBC7_BASE_ENCODER_SHIFT = 29
XUBC7_BASE_ENCODER_MASK = 7
VERBOSE = PRINT_STATS | PRINT_STATUS
MIPMAP_CLAMP = GEN_MIPS_CLAMP
MIPMAP_WRAP = GEN_MIPS_WRAP
@@ -175,9 +189,8 @@ class TranscodeDecodeFlags:
TRANSCODE_ALPHA_TO_OPAQUE = 4
BC1_FORBID_THREE_COLOR_BLOCKS = 8
OUTPUT_HAS_ALPHA_INDICES = 16
HIGH_QUALITY = 32
NO_ETC1S_CHROMA_FILTERING = 64
HIGH_QUALITY = 32
NO_ETC1S_CHROMA_FILTERING = 64
NO_DEBLOCK_FILTERING = 128
STRONGER_DEBLOCK_FILTERING = 256
FORCE_DEBLOCK_FILTERING = 512
XUASTC_LDR_DISABLE_FAST_BC7_TRANSCODING = 1024

View File

@@ -103,6 +103,7 @@ class Transcoder:
# basis_tex_format helpers
("basis_tex_format_is_xuastc_ldr", "basis_tex_format_is_xuastc_ldr"),
("basis_tex_format_is_astc_ldr", "basis_tex_format_is_astc_ldr"),
("basis_tex_format_is_xubc7", "basis_tex_format_is_xubc7"),
("basis_tex_format_get_block_width", "basis_tex_format_get_block_width"),
("basis_tex_format_get_block_height", "basis_tex_format_get_block_height"),
("basis_tex_format_is_hdr", "basis_tex_format_is_hdr"),
@@ -138,6 +139,7 @@ class Transcoder:
("ktx2_get_block_width", "ktx2_get_block_width"),
("ktx2_get_block_height", "ktx2_get_block_height"),
("ktx2_get_deblocking_filter_index", "ktx2_get_deblocking_filter_index"),
("ktx2_has_alpha", "ktx2_has_alpha"),
@@ -151,6 +153,7 @@ class Transcoder:
("ktx2_is_uastc_ldr_4x4", "ktx2_is_uastc_ldr_4x4"),
("ktx2_is_xuastc_ldr", "ktx2_is_xuastc_ldr"),
("ktx2_is_astc_ldr", "ktx2_is_astc_ldr"),
("ktx2_is_xubc7", "ktx2_is_xubc7"),
("ktx2_is_video", "ktx2_is_video"),
("ktx2_get_ldr_hdr_upconversion_nit_multiplier", "ktx2_get_ldr_hdr_upconversion_nit_multiplier"),
@@ -250,6 +253,7 @@ class Transcoder:
def is_uastc_ldr_4x4(self, ktx2_handle): return bool(self.ktx2_is_uastc_ldr_4x4(ktx2_handle.handle))
def is_xuastc_ldr(self, ktx2_handle): return bool(self.ktx2_is_xuastc_ldr(ktx2_handle.handle))
def is_astc_ldr(self, ktx2_handle): return bool(self.ktx2_is_astc_ldr(ktx2_handle.handle))
def is_xubc7(self, ktx2_handle): return bool(self.ktx2_is_xubc7(ktx2_handle.handle))
# ---- DFD access
def get_dfd_flags(self, ktx2_handle): return self.ktx2_get_dfd_flags(ktx2_handle.handle)
@@ -263,6 +267,7 @@ class Transcoder:
# ---- Block dimensions ----
def get_block_width(self, ktx2_handle): return self.ktx2_get_block_width(ktx2_handle.handle)
def get_block_height(self, ktx2_handle): return self.ktx2_get_block_height(ktx2_handle.handle)
def get_deblocking_filter_index(self, ktx2_handle): return self.ktx2_get_deblocking_filter_index(ktx2_handle.handle)
# -----------------------------------------------------------------------
# Explicit: start transcoding on an already-open KTX2 file
@@ -502,7 +507,7 @@ class Transcoder:
"PVRTC1", "PVRTC2",
"ETC1", "ETC2", "ETC2_EAC_R11", "ETC2_EAC_RG11",
"ATC", "FXT1",
"RGBA32", "RGB_HALF", "RGBA_HALF", "RGB_FLOAT", "RGBA_FLOAT",
"RGBA32", "RGB_HALF", "RGBA_HALF",
"RGB_9E5"
Returns:
@@ -522,10 +527,10 @@ class Transcoder:
if s in ("RGBA32", "RGBA8", "UNCOMPRESSED"):
tfmt = TranscoderTextureFormat.TF_RGBA32
elif s in ("RGBHALF", "RGB16F", "RGB_FLOAT", "RGBFLOAT"):
elif s in ("RGBHALF", "RGB16F"):
tfmt = TranscoderTextureFormat.TF_RGB_HALF
elif s in ("RGBAHALF", "RGBA16F", "RGBA_FLOAT", "RGBAFLOAT"):
elif s in ("RGBAHALF", "RGBA16F"):
tfmt = TranscoderTextureFormat.TF_RGBA_HALF
elif s in ("RGB9E5", "RGB_9E5"):

View File

@@ -103,6 +103,9 @@ class BasisuWasmTranscoder:
def basis_tex_format_is_astc_ldr(self, basis_tex_fmt_u32: int) -> bool:
return bool(self.exports["bt_basis_tex_format_is_astc_ldr"](self.store, basis_tex_fmt_u32))
def basis_tex_format_is_xubc7(self, basis_tex_fmt_u32: int) -> bool:
return bool(self.exports["bt_basis_tex_format_is_xubc7"](self.store, basis_tex_fmt_u32))
def basis_tex_format_get_block_width(self, basis_tex_fmt_u32: int) -> int:
return self.exports["bt_basis_tex_format_get_block_width"](self.store, basis_tex_fmt_u32)
@@ -211,12 +214,18 @@ class BasisuWasmTranscoder:
def ktx2_is_xuastc_ldr(self, handle: int) -> bool:
return bool(self.exports["bt_ktx2_is_xuastc_ldr"](self.store, handle))
def ktx2_is_xubc7(self, handle: int) -> bool:
return bool(self.exports["bt_ktx2_is_xubc7"](self.store, handle))
def ktx2_get_block_width(self, handle: int) -> int:
return self.exports["bt_ktx2_get_block_width"](self.store, handle)
def ktx2_get_block_height(self, handle: int) -> int:
return self.exports["bt_ktx2_get_block_height"](self.store, handle)
def ktx2_get_deblocking_filter_index(self, handle: int) -> int:
return self.exports["bt_ktx2_get_deblocking_filter_index"](self.store, handle)
def ktx2_has_alpha(self, handle: int) -> bool:
return bool(self.exports["bt_ktx2_has_alpha"](self.store, handle))

View File

@@ -8,7 +8,7 @@
namespace py = pybind11;
// wasm_bool_t is uint32_t convert to Python bool
// wasm_bool_t is uint32_t - convert to Python bool
static inline bool to_bool(wasm_bool_t v) { return v != 0; }
PYBIND11_MODULE(basisu_transcoder_python, m) {
@@ -42,6 +42,9 @@ PYBIND11_MODULE(basisu_transcoder_python, m) {
m.def("basis_tex_format_is_astc_ldr",
[](uint32_t fmt) { return to_bool(bt_basis_tex_format_is_astc_ldr(fmt)); });
m.def("basis_tex_format_is_xubc7",
[](uint32_t fmt) { return to_bool(bt_basis_tex_format_is_xubc7(fmt)); });
m.def("basis_tex_format_get_block_width",
&bt_basis_tex_format_get_block_width);
@@ -138,10 +141,15 @@ PYBIND11_MODULE(basisu_transcoder_python, m) {
m.def("ktx2_is_xuastc_ldr",
[](uint64_t h) { return to_bool(bt_ktx2_is_xuastc_ldr(h)); });
m.def("ktx2_is_xubc7",
[](uint64_t h) { return to_bool(bt_ktx2_is_xubc7(h)); });
m.def("ktx2_get_block_width", &bt_ktx2_get_block_width);
m.def("ktx2_get_block_height", &bt_ktx2_get_block_height);
m.def("ktx2_get_deblocking_filter_index", &bt_ktx2_get_deblocking_filter_index);
m.def("ktx2_has_alpha",
[](uint64_t h) { return to_bool(bt_ktx2_has_alpha(h)); });

View File

@@ -271,11 +271,13 @@ def transcode_ktx2_file(ktx2_data: bytes) -> int:
basis_tex_format = bt.ktx2_get_basis_tex_format(ktx2_handle)
block_width = bt.ktx2_get_block_width(ktx2_handle)
block_height = bt.ktx2_get_block_height(ktx2_handle)
deblocking_filter_index = bt.ktx2_get_deblocking_filter_index(ktx2_handle)
is_srgb = bt.ktx2_is_srgb(ktx2_handle)
print(f"KTX2 Dimensions: {width}x{height}, Levels={levels}, Faces={faces}, Layers={layers}")
print(f"basis_tex_format: {basis_tex_format}")
print(f"Block dimensions: {block_width}x{block_height}")
print(f"deblocking_filter_index: {deblocking_filter_index}")
print(f"is sRGB: {is_srgb}")
if layers < 1:
@@ -314,12 +316,16 @@ def transcode_ktx2_file(ktx2_data: bytes) -> int:
rgba_ofs = bt.alloc(trans_size_rgba)
print(f" RGBA buf ofs=0x{rgba_ofs:x}, size={trans_size_rgba}")
# The transcoder wants the output buffer size in blocks (GPU formats) or pixels (uncompressed),
# NOT bytes -- it's used as a buffer-overrun guard. For RGBA32 that's the pixel count.
rgba_buf_pixels = trans_size_rgba // bt.basis_get_bytes_per_block_or_pixel(TF.TF_RGBA32)
decode_flags = 0
ok = bt.ktx2_transcode_image_level(
ktx2_handle,
level_index, layer_index, face_index,
rgba_ofs,
trans_size_rgba,
rgba_buf_pixels,
TF.TF_RGBA32,
decode_flags,
0, 0, -1, -1,
@@ -346,11 +352,14 @@ def transcode_ktx2_file(ktx2_data: bytes) -> int:
astc_ofs = bt.alloc(trans_size_astc)
print(f" ASTC buf ofs=0x{astc_ofs:x}, size={trans_size_astc}")
# Buffer size in blocks (not bytes) -- ASTC is 16 bytes/block.
astc_buf_blocks = trans_size_astc // bt.basis_get_bytes_per_block_or_pixel(target_tf)
ok = bt.ktx2_transcode_image_level(
ktx2_handle,
level_index, layer_index, face_index,
astc_ofs,
trans_size_astc,
astc_buf_blocks,
target_tf,
0, 0, 0, -1, -1,
trans_state

View File

@@ -80,7 +80,9 @@ def test_backend(name, backend):
print(f" is_uastc_ldr_4x4 = {t.is_uastc_ldr_4x4(raw)}")
print(f" is_xuastc_ldr = {t.is_xuastc_ldr(raw)}")
print(f" is_astc_ldr = {t.is_astc_ldr(raw)}")
print(f" is_xubc7 = {t.is_xubc7(raw)}")
print(f" block dims = {t.get_block_width(raw)} x {t.get_block_height(raw)}")
print(f" deblocking_filter_index = {t.get_deblocking_filter_index(raw)}")
except Exception as e:
print(" [FAIL] get_* metadata error:", e)
@@ -113,6 +115,7 @@ def test_backend(name, backend):
try:
print(f" is_xuastc_ldr = {t.basis_tex_format_is_xuastc_ldr(fmt)}")
print(f" is_astc_ldr = {t.basis_tex_format_is_astc_ldr(fmt)}")
print(f" is_xubc7 = {t.basis_tex_format_is_xubc7(fmt)}")
print(f" block W/H = {t.basis_tex_format_get_block_width(fmt)} x "
f"{t.basis_tex_format_get_block_height(fmt)}")
print(f" is_hdr = {t.basis_tex_format_is_hdr(fmt)}")