#!/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 ") 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)