mirror of
https://github.com/BinomialLLC/basis_universal.git
synced 2026-08-10 15:19:33 +00:00
adding new files
This commit is contained in:
83
python/astc_writer.py
Normal file
83
python/astc_writer.py
Normal file
@@ -0,0 +1,83 @@
|
||||
# astc_writer.py
|
||||
#
|
||||
# Minimal ASTC writer that mirrors the C/C++ write_astc_file() logic from example_capi.c.
|
||||
# Writes a valid single-slice 2D ASTC texture file (no array slices, no 3D, no mips).
|
||||
#
|
||||
# Usage:
|
||||
# from astc_writer import write_astc_file
|
||||
# write_astc_file("output.astc", blocks, block_width, block_height, width, height)
|
||||
#
|
||||
# "blocks" must be a bytes-like object containing the full ASTC block data
|
||||
# using 16 bytes per block (standard ASTC block size).
|
||||
|
||||
|
||||
def write_astc_file(
|
||||
filename: str,
|
||||
blocks: bytes,
|
||||
block_width: int,
|
||||
block_height: int,
|
||||
width: int,
|
||||
height: int
|
||||
) -> None:
|
||||
"""
|
||||
Write an ASTC file to disk.
|
||||
|
||||
Parameters:
|
||||
filename : Output filename ("something.astc")
|
||||
blocks : Bytes-like object containing ASTC blocks (16 bytes per block)
|
||||
block_width : ASTC block width (e.g. 4-12)
|
||||
block_height : ASTC block height (e.g. 4-12)
|
||||
width : Original image width in pixels
|
||||
height : Original image height in pixels
|
||||
|
||||
Notes:
|
||||
- ASTC files use 2D blocks; depth is always 1.
|
||||
- Block layout goes row-major: (num_blocks_y num_blocks_x) blocks.
|
||||
- No mipmaps are stored in this format.
|
||||
"""
|
||||
|
||||
# Validate block dimensions
|
||||
if block_width < 4 or block_width > 12:
|
||||
raise ValueError(f"ASTC block_width {block_width} out of range (412)")
|
||||
if block_height < 4 or block_height > 12:
|
||||
raise ValueError(f"ASTC block_height {block_height} out of range (412)")
|
||||
|
||||
# Compute block grid
|
||||
num_blocks_x = (width + block_width - 1) // block_width
|
||||
num_blocks_y = (height + block_height - 1) // block_height
|
||||
total_blocks = num_blocks_x * num_blocks_y
|
||||
expected_size = total_blocks * 16 # 16 bytes per ASTC block (always)
|
||||
|
||||
if len(blocks) != expected_size:
|
||||
raise ValueError(
|
||||
f"ASTC block buffer incorrect size: expected {expected_size}, got {len(blocks)}"
|
||||
)
|
||||
|
||||
# Write file
|
||||
with open(filename, "wb") as f:
|
||||
# ASTC magic number (0x13AB A15C)
|
||||
f.write(bytes([0x13, 0xAB, 0xA1, 0x5C]))
|
||||
|
||||
# Block dims: x, y, z (z=1)
|
||||
f.write(bytes([
|
||||
block_width & 0xFF,
|
||||
block_height & 0xFF,
|
||||
1
|
||||
]))
|
||||
|
||||
# ASTC stores width/height/depth as 24-bit LE
|
||||
def write_24bit_le(v: int):
|
||||
f.write(bytes([
|
||||
v & 0xFF,
|
||||
(v >> 8) & 0xFF,
|
||||
(v >> 16) & 0xFF
|
||||
]))
|
||||
|
||||
write_24bit_le(width)
|
||||
write_24bit_le(height)
|
||||
write_24bit_le(1) # depth
|
||||
|
||||
# Write actual block payload
|
||||
f.write(blocks)
|
||||
|
||||
print(f"[ASTC Writer] Wrote: {filename} ({width}x{height}, {block_width}x{block_height} blocks)")
|
||||
Reference in New Issue
Block a user