#!/usr/bin/env python3
"""Preview the exact Ch436 vertical-linear SH3 scanout map."""
import math
import sys

from PIL import Image


def blend(a, b, frac, denom):
    return tuple(((denom - frac) * x + frac * y + denom // 2) // denom
                 for x, y in zip(a, b))


def score(a, b):
    ae = 0
    se = 0
    n = a.width * a.height * 3
    for pa, pb in zip(a.getdata(), b.getdata()):
        for ca, cb in zip(pa, pb):
            d = int(ca) - int(cb)
            ae += abs(d)
            se += d * d
    return ae / n, math.sqrt(se / n)


def main(argv):
    if len(argv) != 4:
        raise SystemExit(
            "usage: preview_scanout_ch436.py <fb.png> <reference.png> <out.png>"
        )

    src = Image.open(argv[1]).convert("RGB")
    if src.size != (640, 480):
        raise SystemExit(f"expected 640x480 framebuffer, got {src.size}")
    ref = Image.open(argv[2]).convert("RGB").resize(
        (640, 480), Image.Resampling.BILINEAR
    )

    out = Image.new("RGB", (640, 480))
    px = out.load()
    for y in range(480):
        yn = y * 14
        y0 = 32 + yn // 15
        yf = yn % 15
        y1 = min(y0 + 1, 479)
        for x in range(640):
            x0 = (x * 4) // 5
            px[x, y] = blend(src.getpixel((x0, y0)),
                             src.getpixel((x0, y1)), yf, 15)

    out.save(argv[3])
    mae, rmse = score(out, ref)
    print(f"linear   MAE={mae:.4f} RMSE={rmse:.4f}")
    print(f"wrote {argv[3]}")


if __name__ == "__main__":
    main(sys.argv)
