def main(argv=None): import pb16, incruniq args = parse_argv(argv or sys.argv) # Read input files with open(args.paltxtfile, "r") as infp: lines = list(infp) palettes = load_palette_spec(lines) if not args.image: with open(args.outfile, "wb") as outfp: outfp.writelines(subpalette_to_bin(row) for row in palettes) return im = Image.open(args.image) result = im_to_gbc(im, palettes) imfinal, utiles, tilemap_lo, tilemap_hi = result if args.preview: imfinal.save(args.preview) # Compress tiles with PB16, nametable with IUR, and # attributes with PB16 ctilemap_lo = incruniq.iur_encode_tilemap(tilemap_lo) ctiles = b"".join(pb16.pb16(b"".join(utiles))) ctilemap_hi = b"".join(pb16.pb16(tilemap_hi)) halfnamsize = -(-len(tilemap_lo) // 2) out = bytearray([len(utiles)]) out.extend(ctiles) out.append(halfnamsize) out.extend(ctilemap_lo) out.extend(ctilemap_hi) with open(args.outfile, 'wb') as outfp: outfp.write(out)
def main(argv=None): argv = argv or sys.argv infilename, outfilename = argv[1:3] im = Image.open(infilename) tiles = pilbmp2chr(im, formatTile=snesformat) utiles, tilemap = flipuniq(tiles) assert len(utiles) <= 64 pbtiles = b"".join(pb16.pb16(b"".join(utiles))) tmrows = [bytes(tilemap[i:i + 32]) for i in range(0, len(tilemap), 32)] utmrows, tmrowmap = uniq(tmrows) iutmrows = iur_encode_tilemap(b''.join(utmrows)) palette = im.getpalette()[:48] snespalette = bytearray() for i in range(0, 48, 3): r = palette[i] >> 3 g = palette[i + 1] >> 3 b = palette[i + 2] >> 3 bgr = (b << 10) | (g << 5) | r snespalette.append(bgr & 0xFF) snespalette.append(bgr >> 8) out = b"".join( (bytes([len(utiles) * 2]), pbtiles, bytes([16 * len(utmrows)]), iutmrows, bytes(tmrowmap), snespalette)) with open(outfilename, "wb") as outfp: outfp.write(out)
def iur_encode(chrdata, *, report=False): """Test experimental IUR tilemap codec""" utiles, tilemap = uniq(chrdata) # Test type stickiness (brand new uniques vs. horizontal runs) lastwasnew, lastbyte, maxsofar = False, 0, 0 newnew = oldmatches = matchafternew = newafternonnew = diffold = 0 out = BitByteInterleave() for t in tilemap: isnew = t > maxsofar eqlast = t == lastbyte ismatch = isnew if lastwasnew else eqlast if ismatch: # 0: Same run type as last time out.putbits(0) if isnew: newnew += 1 else: oldmatches += 1 elif isnew: # 10: Switch run type from non-new to new out.putbits(0b10, 2) newafternonnew += 1 elif eqlast: # 10: Switch run type from new to non-new out.putbits(0b10, 2) matchafternew += 1 else: # 11: Literal byte follows out.putbits(0b11, 2) out.putbyte(t) diffold += 1 lastbyte, lastwasnew = t, isnew maxsofar = max(t, maxsofar) if report: pbunique = b''.join(pb16.pb16(b''.join(utiles))) sameas1ago = [l for l, r in zip(tilemap, tilemap[1:]) if l == r] sameas2ago = [l for l, r in zip(tilemap, tilemap[2:]) if l == r] sameaslplus1 = [l for l, r in zip(tilemap, tilemap[1:]) if l + 1 == r] print("%d map entries match left; %d match 2 to the left; %d match left + 1" % (len(sameas1ago), len(sameas2ago), len(sameaslplus1))) mapbits = (newnew + oldmatches + 2 * matchafternew + 2 * newafternonnew + 10 * diffold) mapbytes = -(-mapbits // 8) line = ("mapsz=%d utiles=%3d nn=%3d om=%3d man=%3d nao=%3d do=%3d bits=%4d" % (len(chrdata), len(utiles), newnew, oldmatches, matchafternew, newafternonnew, diffold, mapbits)) print(line) print("%d bytes tiles, %d bytes map, %d bytes total" % (len(pbunique), mapbytes, len(pbunique) + mapbytes)) assert len(out) == mapbytes return bytes(out)
def main(argv=None): argv = argv or sys.argv infilename, outfilename = argv[1:3] im = Image.open(infilename) tiles = pilbmp2chr(im, formatTile=snesformat) utiles, tilemap = flipuniq(tiles) assert len(utiles) <= 64 pbtiles = b"".join(pb16.pb16(b"".join(utiles))) tmrows = [bytes(tilemap[i:i + 32]) for i in range(0, len(tilemap), 32)] use_utmrows = False use_iur = False if use_utmrows: from uniq import uniq utmrows, tmrowmap = uniq(tmrows) if len(utmrows) >= 16: raise ValueError("%s: too many unique rows: %d > 15" % (infilename, len(utmrows))) else: utmrows, tmrowmap = tmrows, list(range(len(tmrows))) if use_iur: from incruniq import iur_encode_tilemap iutmrows = iur_encode_tilemap(b''.join(utmrows)) else: iutmrows = b''.join(pb16.pb16(b''.join(utmrows))) palette = im.getpalette()[:48] snespalette = bytearray() for i in range(0, 48, 3): r = palette[i] >> 3 g = palette[i + 1] >> 3 b = palette[i + 2] >> 3 bgr = (b << 10) | (g << 5) | r snespalette.append(bgr & 0xFF) snespalette.append(bgr >> 8) print(snespalette.hex()) out = b"".join( (bytes([len(utiles) * 2]), pbtiles, bytes([len(utmrows) * 16]) if use_utmrows else b"", iutmrows, bytes(tmrowmap) if use_utmrows else b"", snespalette)) with open(outfilename, "wb") as outfp: outfp.write(out)
def main(argv=None): args = parse_argv(argv or sys.argv) with open(args.srcfile, "rb") as infp: data = infp.read() print(len(data)) block_size = 16 data = [data[i:i + block_size] for i in range(0, len(data), block_size)] alltiles, firstsingleton, nam = incruniq(data) out = bytearray() out.append(len(alltiles)) out.extend(b''.join(pb16(b''.join(alltiles)))) nampb16size = -(-len(nam) // 16) out.append(nampb16size) out.append(firstsingleton) out.extend(b''.join(pb16(nam))) print(len(out)) with open(args.iufile, "wb") as outfp: outfp.write(out)
def main(argv=None): args = parse_argv(argv or sys.argv) with open(args.srcfile, "rb") as infp: tiles = infp.read() block_size = 16 tiles = [tiles[i:i + block_size] for i in range(0, len(tiles), block_size)] utiles, iurdata = iur_encode(tiles) out = bytearray() out.append(len(utiles)) out.extend(b''.join(pb16(b''.join(utiles)))) halfnamsize = -(-len(tiles) // 2) print("%d tiles" % len(tiles)) out.append(halfnamsize) out.extend(iurdata) with open(args.iufile, "wb") as outfp: outfp.write(out)