# The rings in the real cutscene, counted: contour pixels (a step between neighbours with a flat run
# of 8 on each side, experiment.flat_steps) per megapixel, in the two crops of the rift beat's warm
# pool (frames/pool-before.png from main, frames/pool-after.png from this branch; cutframe.mjs.txt drew them).
#   python3 poolsteps.py [before.png after.png]
import sys, zlib, struct
import numpy as np
from experiment import flat_steps

def read_png(path):
    """A minimal PNG reader: 8-bit RGB or RGBA, non-interlaced (what the browser's screenshot gives)."""
    data = open(path, 'rb').read(); pos = 8; idat = b''
    while pos < len(data):
        n, kind = struct.unpack('>I4s', data[pos:pos + 8]); body = data[pos + 8:pos + 8 + n]; pos += 12 + n
        if kind == b'IHDR': w, h, depth, ctype = struct.unpack('>IIBB', body[:10])
        elif kind == b'IDAT': idat += body
    assert depth == 8 and ctype in (2, 6), 'only 8-bit RGB/RGBA'
    bpp = 3 if ctype == 2 else 4
    raw = np.frombuffer(zlib.decompress(idat), np.uint8).reshape(h, w * bpp + 1)
    out = np.zeros((h, w * bpp), np.int32)
    for y in range(h):
        f, line = raw[y, 0], raw[y, 1:].astype(np.int32)
        prev = out[y - 1] if y else np.zeros(w * bpp, np.int32)
        if f == 0: cur = line
        elif f == 2: cur = (line + prev) & 255
        else:
            cur = np.zeros(w * bpp, np.int32)
            for x in range(w * bpp):
                a = cur[x - bpp] if x >= bpp else 0; b = prev[x]; c = prev[x - bpp] if x >= bpp else 0
                if f == 1: p = a
                elif f == 3: p = (a + b) // 2
                else:
                    pa, pb, pc = abs(b - c), abs(a - c), abs(a + b - 2 * c)
                    p = a if pa <= pb and pa <= pc else b if pb <= pc else c
                cur[x] = (line[x] + p) & 255
        out[y] = cur
    return out.reshape(h, w, bpp)[..., :3]

if __name__ == '__main__':
    files = sys.argv[1:3] or ['frames/pool-before.png', 'frames/pool-after.png']
    for label, f in zip(('before', 'after'), files):
        img = read_png(f)
        code = (img @ np.array([1, 256, 65536])).astype(np.int64)
        print(f'{label}: {flat_steps(code) / (code.size / 1e6):.0f} contour pixels per megapixel')
