from dataclasses import dataclass import sys import struct from PIL import Image codebook_size = 256 * 2 * 4 @dataclass class PVRT: texture_data_size: int texture_type: int width: int height: int data: list[int] def parse_pvrt_header(buf): header = buf[0:16] #codebook = buf[16:codebook_size + 16] #indices = buf[codebook_size + 16:] data = buf[16:] assert len(header) == 16 assert header[0:4] == b"PVRT" unpacked = struct.unpack('> 11) & 31 g = (color >> 5) & 63 b = (color >> 0) & 31 return r << 3, g << 2, b << 3 def get_colors(buf, codebook_ix): codeword = buf[codebook_ix * 2 * 4:][:2 * 4] assert len(codeword) == 2 * 4 colors = struct.unpack('> i) & 1) << (i * 2 + 0) twiddle_ix |= ((x >> i) & 1) << (i * 2 + 1) elif i < width_max: twiddle_ix |= ((x >> i) & 1) << (i + height_max) elif i < height_max: twiddle_ix |= ((y >> i) & 1) << (i + width_max) else: break i += 1 return twiddle_ix def decode_vq_indices(data, width, height): codebook = data[:codebook_size] indices = data[codebook_size:] canvas = [0] * width * height for ty in range(height // 2): for tx in range(width // 2): codebook_ix = indices[from_xy(tx, ty, width, height)] codeword = get_colors(codebook, codebook_ix) ai = ((ty * 2) + 0) * width + ((tx * 2) + 0) bi = ((ty * 2) + 1) * width + ((tx * 2) + 0) ci = ((ty * 2) + 0) * width + ((tx * 2) + 1) di = ((ty * 2) + 1) * width + ((tx * 2) + 1) #print(width, height, ai, ty, tx) canvas[ai] = codeword[0] canvas[bi] = codeword[1] canvas[ci] = codeword[2] canvas[di] = codeword[3] return canvas def decode_twiddled(data, width, height): canvas = [0] * width * height for y in range(height): for x in range(width): ix = from_xy(x, y, width, height) * 2 color, = struct.unpack("