# Apaga o texto "POed" do item de mesmo nome (nome de um jogo comercial) na folha de imagens do Go-inovation # (ino/internal/assets/images/{color,mono}/ino.png, tile de 16x16 em x=240, y=64) e poe no lugar um icone neutro (um quadrado de # cantos cortados). So biblioteca padrao; deterministico. Aceita PNG RGBA de 8 bits (color) e PNG de paleta de 4 bits (mono) e grava # os dois como RGBA de 8 bits, sem entrelacamento, com zlib nivel 9. import struct, sys, zlib def read(p): d = open(p, 'rb').read() assert d[:8] == b'\x89PNG\r\n\x1a\n' pos, idat, plte, trns = 8, b'', b'', b'' while pos < len(d): n, t = struct.unpack('>I4s', d[pos:pos + 8]) body = d[pos + 8:pos + 8 + n] if t == b'IHDR': w, h, bd, ct, _, _, il = struct.unpack('>IIBBBBB', body) assert (bd, ct, il) in ((8, 6, 0), (4, 3, 0)), (bd, ct, il) elif t == b'PLTE': plte = body elif t == b'tRNS': trns = body elif t == b'IDAT': idat += body pos += 12 + n raw = zlib.decompress(idat) bpp = 4 if ct == 6 else 1 stride = w * 4 if ct == 6 else (w + 1) // 2 lines, prev = [], bytearray(stride) for y in range(h): f = raw[y * (stride + 1)] cur = bytearray(raw[y * (stride + 1) + 1:(y + 1) * (stride + 1)]) for i in range(stride): a = cur[i - bpp] if i >= bpp else 0 b = prev[i] c = prev[i - bpp] if i >= bpp else 0 if f == 1: cur[i] = (cur[i] + a) & 255 elif f == 2: cur[i] = (cur[i] + b) & 255 elif f == 3: cur[i] = (cur[i] + ((a + b) >> 1)) & 255 elif f == 4: pa, pb, pc = abs(b - c), abs(a - c), abs(a + b - 2 * c) pr = a if pa <= pb and pa <= pc else (b if pb <= pc else c) cur[i] = (cur[i] + pr) & 255 lines.append(cur) prev = cur if ct == 6: return w, h, lines rows = [] for cur in lines: r = bytearray() for x in range(w): v = cur[x // 2] idx = (v >> 4) if x % 2 == 0 else (v & 15) r += plte[idx * 3:idx * 3 + 3] + bytes((trns[idx] if idx < len(trns) else 255,)) rows.append(r) return w, h, rows def write(p, w, h, rows): def chunk(t, b): return struct.pack('>I', len(b)) + t + b + struct.pack('>I', zlib.crc32(t + b)) raw = b''.join(b'\0' + bytes(r) for r in rows) open(p, 'wb').write(b'\x89PNG\r\n\x1a\n' + chunk(b'IHDR', struct.pack('>IIBBBBB', w, h, 8, 6, 0, 0, 0)) + chunk(b'IDAT', zlib.compress(raw, 9)) + chunk(b'IEND', b'')) for path, fill in ((sys.argv[1], (232, 51, 93, 255)), (sys.argv[2], (255, 255, 255, 255))): w, h, rows = read(path) for y in range(64, 80): for x in range(240, 256): rows[y][x * 4:x * 4 + 4] = b'\0\0\0\0' for y in range(66, 78): for x in range(242, 254): if x in (242, 253) and y in (66, 77): continue edge = x in (242, 253) or y in (66, 77) rows[y][x * 4:x * 4 + 4] = bytes((0, 0, 0, 255) if edge else fill) write(path, w, h, rows)