mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
Port CLIM decoder to Construct 2.8; add more pixel formats
This commit is contained in:
parent
d7c20809e5
commit
c111a56612
1 changed files with 65 additions and 17 deletions
|
@ -1,24 +1,23 @@
|
||||||
import math
|
import math
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
|
import attr
|
||||||
import construct as c
|
import construct as c
|
||||||
|
|
||||||
clim_header_struct = c.Struct(
|
clim_header_struct = c.Struct(
|
||||||
'clim_header',
|
c.Const(b'FLIM'), # TODO 'FLIM' in SUMO
|
||||||
c.Magic(b'FLIM'), # TODO 'FLIM' in SUMO
|
'endianness' / c.Const(c.Int16ul, 0xfeff),
|
||||||
c.Const(c.ULInt16('endianness'), 0xfeff),
|
'header_length' / c.Const(c.Int16ul, 0x14),
|
||||||
c.Const(c.ULInt16('header_length'), 0x14),
|
'version' / c.Int32ul,
|
||||||
c.ULInt32('version'),
|
'file_size' / c.Int32ul,
|
||||||
c.ULInt32('file_size'),
|
'blocks_ct' / c.Int32ul,
|
||||||
c.ULInt32('blocks_ct'),
|
|
||||||
)
|
)
|
||||||
imag_header_struct = c.Struct(
|
imag_header_struct = c.Struct(
|
||||||
'imag_header',
|
c.Const(b'imag'),
|
||||||
c.Magic(b'imag'),
|
'section_length' / c.Const(c.Int32ul, 0x10),
|
||||||
c.Const(c.ULInt32('section_length'), 0x10),
|
'width' / c.Int16ul,
|
||||||
c.ULInt16('width'),
|
'height' / c.Int16ul,
|
||||||
c.ULInt16('height'),
|
'format' / c.Int32ul,
|
||||||
c.ULInt32('format'),
|
|
||||||
# TODO this seems to have been expanded into several things in SUMO
|
# TODO this seems to have been expanded into several things in SUMO
|
||||||
#c.Enum(
|
#c.Enum(
|
||||||
# c.ULInt32('format'),
|
# c.ULInt32('format'),
|
||||||
|
@ -41,17 +40,42 @@ imag_header_struct = c.Struct(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO probably move these to their own module, since they aren't just for
|
||||||
|
# CLIM. pixel deshuffler, too. (which should probably spit out pypng's native
|
||||||
|
# format)
|
||||||
COLOR_DECODERS = {}
|
COLOR_DECODERS = {}
|
||||||
|
|
||||||
|
|
||||||
def _register_color_decoder(name, *, bpp, depth):
|
@attr.s
|
||||||
|
class ColorFormat:
|
||||||
|
name = attr.ib('name')
|
||||||
|
decoder = attr.ib('decoder')
|
||||||
|
bits_per_pixel = attr.ib('bits_per_pixel')
|
||||||
|
bit_depth = attr.ib('bit_depth')
|
||||||
|
alpha = attr.ib('alpha')
|
||||||
|
|
||||||
|
def __call__(self, data):
|
||||||
|
return self.decoder(data)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
# TODO back compat until i fix the below code
|
||||||
|
return iter((self.decoder, self.bits_per_pixel, self.bit_depth))
|
||||||
|
|
||||||
|
|
||||||
|
def _register_color_decoder(name, *, bpp, depth, alpha):
|
||||||
def register(f):
|
def register(f):
|
||||||
COLOR_DECODERS[name] = f, bpp, depth
|
COLOR_DECODERS[name] = ColorFormat(name, f, bpp, depth, alpha)
|
||||||
return f
|
return f
|
||||||
return register
|
return register
|
||||||
|
|
||||||
|
|
||||||
@_register_color_decoder('RGBA4', bpp=2, depth=4)
|
@_register_color_decoder('L8', bpp=1, depth=8, alpha=False)
|
||||||
|
def decode_l8(data):
|
||||||
|
for l in data:
|
||||||
|
yield l, l, l
|
||||||
|
|
||||||
|
|
||||||
|
@_register_color_decoder('RGBA4', bpp=2, depth=4, alpha=True)
|
||||||
def decode_rgba4(data):
|
def decode_rgba4(data):
|
||||||
# The idea is that every uint16 is a packed rrrrggggbbbbaaaa, but when
|
# The idea is that every uint16 is a packed rrrrggggbbbbaaaa, but when
|
||||||
# written out little-endian this becomes bbbbaaaarrrrgggg and there's just
|
# written out little-endian this becomes bbbbaaaarrrrgggg and there's just
|
||||||
|
@ -66,7 +90,31 @@ def decode_rgba4(data):
|
||||||
yield r, g, b, a
|
yield r, g, b, a
|
||||||
|
|
||||||
|
|
||||||
@_register_color_decoder('RGBA5551', bpp=2, depth=5)
|
@_register_color_decoder('RGB8', bpp=3, depth=8, alpha=False)
|
||||||
|
def decode_rgb8(data):
|
||||||
|
for i in range(0, len(data), 3):
|
||||||
|
yield data[i:i + 3]
|
||||||
|
|
||||||
|
|
||||||
|
@_register_color_decoder('RGBA8', bpp=4, depth=8, alpha=True)
|
||||||
|
def decode_rgba8(data):
|
||||||
|
for i in range(0, len(data), 4):
|
||||||
|
yield data[i:i + 4]
|
||||||
|
|
||||||
|
|
||||||
|
@_register_color_decoder('BGR8', bpp=3, depth=8, alpha=False)
|
||||||
|
def decode_bgr8(data):
|
||||||
|
for i in range(0, len(data), 3):
|
||||||
|
yield data[i:i + 3][::-1]
|
||||||
|
|
||||||
|
|
||||||
|
@_register_color_decoder('ABGR8', bpp=4, depth=8, alpha=True)
|
||||||
|
def decode_abgr8(data):
|
||||||
|
for i in range(0, len(data), 4):
|
||||||
|
yield data[i:i + 4][::-1]
|
||||||
|
|
||||||
|
|
||||||
|
@_register_color_decoder('RGBA5551', bpp=2, depth=5, alpha=True)
|
||||||
def decode_rgba5551(data, *, start=0, count=None):
|
def decode_rgba5551(data, *, start=0, count=None):
|
||||||
# I am extremely irritated that construct cannot parse this mess for me
|
# I am extremely irritated that construct cannot parse this mess for me
|
||||||
# rrrrrgggggbbbbba
|
# rrrrrgggggbbbbba
|
||||||
|
|
Loading…
Reference in a new issue