Both files are prepended with a 4 bytes large number; apparently the total size of the data that follows. I am ignoring it because the file sizes seem fixed. (Also, for the images the other important data, its width and height, are not stored in the file.)
The palette is a 5 bits per channel BGR, with the highest bit unused. The two bytes are stored in little-endian order. Converting to True Color RGB is therefore a matter of bit shifting; you end up with 16 RGB color triplets.
The image is stored in 16 x 16 blocks, each 8 x 8 pixels, and every two consecutive pixels are packed into a single byte, right pixel first. Every pixel value ranges from 0..15 and maps immediately to the palette.
To unpack a single 8x8 block, all it takes is
for y in range(8):
for x in range(4):
which yields a series of 2-pixel data. I found it more convenient, below, to unpack each two nibbles immediately into 2 separate pixels; then it's a matter of looping over the right x and y axis to reassemble the entire image in a coherent, linear, 128x128 pixel bitmap.
The code below then stores the RGB values for each pixel in a True-color PNG image; alternatively, you could save it as a palettized PNG image as well (or really any other image format you'd like).
Python 3.x code
This code needs
pypng. Adjust the fixed part of the path to your folder structure -- it should end with a slash. Save as
cookie2png.py and call from a command line with
python cookie2png.py Rose/bu_strawberry_LZ.bin\bu_strawberry_anger
i.e., leave off the parts
_spr.bin so the script can find them on its own.
from struct import unpack
path = "/Sprites/Character files/"
# base = 'bu_strawberry2'
base = sys.argv
with open (path+base+'_pal.bin', 'rb') as p:
pal = p.read()
pal = unpack('<I16H', pal)[1:]
pal = [bin(p)[2:].zfill(15) for p in pal]
rgb = [(int(p[10:15]+p[10:13],2),int(p[5:10]+p[5:8],2),int(p[0:5]+p[0:3],2)) for p in pal]
print ('rgb palette', *['%02x%02x%02x' % (r,g,b) for r,g,b in rgb])
with open (path+base+'_spr.bin', 'rb') as i:
img = i.read()
# Strip header
img = img[4:]
# Convert nibbles to bytes
img = [[b & 0x0f,b >> 4] for b in img]
# Unpack list
img = [b for a in img for b in a]
# Linearize image
target = 
for y in range(16):
for yy in range(8):
for x in range(16):
for xx in range(8):
# Convert from palettized into True color
target = [color for rgb in target for color in rgb]
# Split into rows, required by pypng
target = [target[i:i + 3*128] for i in range(0, len(target), 3*128)]
w = png.Writer(128, 128, greyscale=False, bitdepth=8)
with open(path+base+'.png', 'wb') as f:
and the results are as expected. Here is your
bu_strawberry, and a smattering of interesting others: