#!/usr/bin/env python3
"""Preview and score the Ch418 captured SH3 scanout presentation map.

RTL maps source_x=floor(output_x*4/5) and
source_y=32+floor(output_y*14/15).  This host utility applies the same
integer mapping to a 640x480 framebuffer PNG, saves the expected HDMI
presentation, and reports RGB MAE/RMSE against a 640x480 reference.
"""
import math
import sys
from PIL import Image


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_ch418.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)
    mapped = Image.new("RGB", (640, 480))
    mapped.putdata([
        src.getpixel(((x * 4) // 5, 32 + (y * 14) // 15))
        for y in range(480) for x in range(640)
    ])
    mapped.save(argv[3])
    raw_mae, raw_rmse = score(src, ref)
    map_mae, map_rmse = score(mapped, ref)
    print(f"raw      MAE={raw_mae:.4f} RMSE={raw_rmse:.4f}")
    print(f"mapped   MAE={map_mae:.4f} RMSE={map_rmse:.4f}")
    print(f"delta    MAE={map_mae-raw_mae:+.4f} RMSE={map_rmse-raw_rmse:+.4f}")
    print(f"wrote {argv[3]}")


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