#!/bin/python3 import sys import re import math import io from PIL import Image from consts import PICTOCHAT_PALETTE DS_TILE_SIZE = 8 TILE_BYTES = 32 # tiles are stored in 32 bytes chunks TILES_HORIZONTAL = 32 # convert a single DS tile (8x8) from packed palette index format to RGB colors def convert_chunk(img, chunk, offset): palette_indices = [] for byte in chunk: palette_indices += [ (byte >> 0) & 0x0f, (byte >> 4) & 0x0f, ] for i, palette_idx in enumerate(palette_indices): color = PICTOCHAT_PALETTE[palette_idx] location = ( i % DS_TILE_SIZE + offset[0], i // DS_TILE_SIZE + offset[1], ) img.putpixel(location, color) # convert a string of tiles into a PNG image def pc2png(data): tile_count = math.floor(len(data) / TILE_BYTES) size = ( TILES_HORIZONTAL * DS_TILE_SIZE, math.ceil(tile_count / TILES_HORIZONTAL) * DS_TILE_SIZE, ) img = Image.new(mode="RGB", size=size) for tile in range(tile_count): chunk_idx = tile * TILE_BYTES chunk = data[chunk_idx:chunk_idx+TILE_BYTES] tile_offset = ( tile % TILES_HORIZONTAL, tile // TILES_HORIZONTAL, ) convert_chunk(img, chunk, [x * DS_TILE_SIZE for x in tile_offset]) output = io.BytesIO() img.save(output, format='PNG') return output.getvalue() def convert_file(input_filename, output_filename): with open(input_filename, 'rb') as input_file: content = input_file.read() output = pc2png(content) with open(output_filename, 'wb+') as output_file: output_file.write(output) if __name__ == "__main__": del sys.argv[0] for input_filename in sys.argv: output_filename = re.sub('.bin$', '.png', input_filename) if not output_filename.endswith('.png'): output_filename += '.png' convert_file(input_filename, output_filename)