#!/usr/bin/python3 import sys import struct import PIL.Image _, inpath, outpath = sys.argv image = PIL.Image.open(inpath) assert image.mode == "RGBA", "image mode is "+image.mode # We measure width and height prior to the rotation width, height = image.width, image.height image = image.transpose(PIL.Image.Transpose.ROTATE_270) with open(outpath, "wb") as out: out.write(struct.pack("=HH", width, height)) for channel in "BGRA": pixelbytes = image.getchannel(channel).tobytes() def rlegroups(): curpixel=None count=0 litrun = b"" for pixel in pixelbytes: if curpixel is None: curpixel = pixel count = 1 elif curpixel != pixel: assert count > 0 if count <= 2: if len(litrun)+count > 127: assert len(litrun) > 0 yield litrun litrun = b"" litrun += bytes([curpixel]) * count else: if litrun != b"": assert len(litrun) > 0 yield litrun litrun = b"" yield (curpixel, count) curpixel = pixel count = 1 else: count += 1 if litrun != b"": assert len(litrun) > 0 yield litrun if count > 0: yield (curpixel, count) for group in rlegroups(): if type(group) == bytes: out.write(struct.pack("=B", len(group)+128) + group) else: pixel, count = group assert count > 0 if count >= 128: out.write(struct.pack("=BIB", 0, count, pixel)) else: out.write(struct.pack("=BB", count, pixel))