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('> 15) & 1 r = (color >> 10) & 31 g = (color >> 5) & 31 b = (color >> 0) & 31 return r << 4, g << 4, b << 4, a * 255 def rgb565(color): r = (color >> 11) & 31 g = (color >> 5) & 63 b = (color >> 0) & 31 return r << 3, g << 2, b << 3 def argb4444(color): a = (color >> 12) & 15 r = (color >> 8) & 15 g = (color >> 4) & 15 b = (color >> 0) & 15 return r << 4, g << 4, b << 4, (a << 4) | 0b1111 def get_colors(buf, codebook_ix, decode_pixel): 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, offset, width, height, decode_pixel, detwiddle=True): codebook = pvrt.data[:codebook_size] indices = pvrt.data[codebook_size + offset:] canvas = [0] * width * height for ty in range(height // 2): for tx in range(width // 2): if detwiddle: index_ix = from_xy(tx, ty, width, height) else: index_ix = ty * (width // 2) + tx codebook_ix = indices[index_ix] codeword = get_colors(codebook, codebook_ix, decode_pixel) 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, offset, width, height, decode_pixel): canvas = [0] * width * height for y in range(height): for x in range(width): ix = offset + from_xy(x, y, width, height) * 2 color, = struct.unpack("