Files
Sylpheed/tools/port/edge-residual-kind
Sylpheed port agent 8101a93229 port: run the peer's shift-vs-blur discriminator -- the menu is not misregistered
They proposed the test and said they had not run it. It needs the port's render
beside the capture, so it was mine: a shift makes the signed residual track the
gradient (and the fitted slope is the shift in pixels), a blur makes it track the
laplacian. New tool, tools/port/edge-residual-kind.

Controls first, and they are not optional: a known +1 px shift reads back as
+0.938 px (r +0.789), a known blur as r -0.896 on the laplacian, neither leaking
into the other's channel.

Result: -0.010 px, -0.009 px, laplacian r +0.103. Flat. Any whole-frame
translation is under a hundredth of a pixel, and the weak blur term has the
opposite sign to the blur control. Misregistration is excluded.

Reach: whole-frame fit. One misplaced element is a small share of 38 752 edge
pixels and would not move these numbers -- this excludes a GLOBAL translation,
not a local one. A misplaced soft element remains untouched.

Exit codes 0 or 2, no 1 -- it classifies, it does not judge. The control-failure
branch verified by raising the thresholds: report suppressed, exit 2.

Also: GP_DIALOG 2/3 restored to authored/flow.json. I declined to re-add it on a
relay; they have now taken the ja capture (HANDOFF at 5a7f34d) -- 1.82 % of pixels
in four bands, EASY/NORMAL/HARD not among them because JP keeps Latin script. My
objection stands as an objection: adjacency never implied a language pair, and 26
of 65 adjacent pairs differ in button count. The claim now rests on a capture
instead of on that inference.
2026-08-31 04:56:58 +00:00

139 lines
5.5 KiB
Python
Executable File

#!/usr/bin/env python3
"""What KIND of error is left at the edges after tone is accounted for?
tools/port/edge-residual-kind [screen] # default main_menu
`verify-capture`'s `diff` column thresholds at 25 % and so only sees GROSS
displacement. Fitting a per-level LUT removes everything a tone effect can
explain. What is left on the main menu is concentrated 3.2x on edge pixels
(DECISIONS.md, 2026-08-31) -- and three things produce that: a misregistration,
an antialiasing difference, or a genuinely misplaced element.
THE DISCRIMINATOR IS THE SIGN, and it is the Decoder's, from their reply on
2026-08-31: a shift gives a residual with a CONSISTENT DIRECTION along the edge,
an antialiasing difference does not. Made concrete:
* shifted by (dx,dy): residual ~ dx*d/dx + dy*d/dy -- and the fitted SLOPE
IS THE SHIFT IN PIXELS
* blurred/sharpened : residual ~ -k * laplacian -- symmetric, no direction
EXIT CODES. 0 the report is trustworthy, 2 A CONTROL FAILED so the numbers below
it mean nothing. There is no 1: this tool classifies, it does not judge. A
correlation this tool reports is worthless without the two controls above it,
which is why they are not optional and not a flag.
"""
import math, os, subprocess, sys, tempfile
CAPS = "docs/re/captures/title-builds"
SCREEN = sys.argv[1] if len(sys.argv) > 1 else "main_menu"
# The captures are a 1279x675 top-left crop of the 1280x720 guest surface, so the
# render is cropped to match and NOTHING IS SCALED -- resampling would manufacture
# exactly the edge signal this tool measures. See verify-capture, same reason.
W, H = 1279, 675
EDGE = 12 # |grad| above which a pixel is an edge
PASS_SHIFT, PASS_BLUR = 0.70, -0.70
def gray(png, out):
subprocess.run(["convert", png, "-colorspace", "Gray", "-depth", "8",
"gray:" + out], check=True)
return open(out, "rb").read()
def lutfit(a, b):
tot = [0] * 256; cnt = [0] * 256
for i in range(len(a)):
tot[a[i]] += b[i]; cnt[a[i]] += 1
return [(tot[v] // cnt[v]) if cnt[v] else v for v in range(256)]
def analyse(a, b):
lut = lutfit(a, b)
gx = []; gy = []; lp = []; rs = []
for y in range(1, H - 1):
o = y * W
for x in range(1, W - 1):
i = o + x
ax = (a[i + 1] - a[i - 1]) * 0.5
ay = (a[i + W] - a[i - W]) * 0.5
if abs(ax) + abs(ay) < EDGE:
continue
gx.append(ax); gy.append(ay)
lp.append(float(a[i + 1] + a[i - 1] + a[i + W] + a[i - W] - 4 * a[i]))
rs.append(float(lut[a[i]] - b[i]))
n = len(rs)
if n < 1000:
print(f" 🔴 only {n} edge pixels -- nothing to classify"); sys.exit(2)
mr = sum(rs) / n
def fit(u):
mu = sum(u) / n
suu = sum((v - mu) ** 2 for v in u)
srr = sum((v - mr) ** 2 for v in rs)
sur = sum((u[k] - mu) * (rs[k] - mr) for k in range(n))
return (0.0, 0.0) if suu <= 0 or srr <= 0 else (sur / suu, sur / math.sqrt(suu * srr))
return n, fit(gx), fit(gy), fit(lp)
def row(label, res):
n, (sx, rx), (sy, ry), (sl, rl) = res
print(f" {label} (n={n})")
print(f" horizontal shift : r={rx:+.3f} slope={sx:+.3f} px")
print(f" vertical shift : r={ry:+.3f} slope={sy:+.3f} px")
print(f" blur / sharpness : r={rl:+.3f} coef ={sl:+.3f}")
return rx, ry, rl
def shifted(a, dx):
out = bytearray(a)
for y in range(H):
for x in range(W):
out[y * W + x] = a[y * W + min(W - 1, max(0, x - dx))]
return bytes(out)
def blurred(a):
out = bytearray(a)
for y in range(1, H - 1):
o = y * W
for x in range(1, W - 1):
i = o + x
out[i] = (a[i] * 4 + a[i + 1] + a[i - 1] + a[i + W] + a[i - W]) // 8
return bytes(out)
tmp = tempfile.mkdtemp()
cap_png = f"{CAPS}/live-{SCREEN.replace('_', '-')}.png"
if not os.path.exists(cap_png):
print(f" 🔴 no capture: {cap_png}"); sys.exit(2)
render = os.environ.get("RENDER") or f"{tmp}/render.png"
if not os.path.exists(render):
print(f" 🔴 no render at {render} -- set RENDER=<png>"); sys.exit(2)
subprocess.run(["convert", render, "-crop", f"{W}x{H}+0+0", "+repage",
f"{tmp}/crop.png"], check=True)
r = gray(f"{tmp}/crop.png", f"{tmp}/r.gray")
c = gray(cap_png, f"{tmp}/c.gray")
print("CONTROLS -- the render against a deliberately damaged copy of itself.")
print("A correlation below is meaningless unless these two recover what was done.\n")
ra = analyse(r, shifted(r, 1))
rxa, _, rla = row("known +1 px HORIZONTAL shift", ra)
rb = analyse(r, blurred(r))
_, _, rlb = row("known BLUR, no shift", rb)
bad = []
if rxa < PASS_SHIFT: bad.append(f"shift control r={rxa:+.3f} < {PASS_SHIFT}")
if rlb > PASS_BLUR: bad.append(f"blur control r={rlb:+.3f} > {PASS_BLUR}")
if bad:
print("\n 🔴 CONTROL FAILED: " + "; ".join(bad))
print(" The discriminator cannot see what it is for. Report suppressed.")
sys.exit(2)
print(f"\n ✅ controls pass -- a 1 px shift reads as {ra[1][0]:+.3f} px\n")
print(f"THE REAL PAIR -- {SCREEN}\n")
rx, ry, rl = row(f"{SCREEN} render vs oracle capture", analyse(r, c))
print()
if max(abs(rx), abs(ry)) < 0.15 and abs(rl) < 0.3:
print(" => NEITHER a global shift NOR a uniform blur.")
print(" ⚠️ REACH: this is a WHOLE-FRAME fit. One misplaced element is a small")
print(" share of the edge pixels and would not move these numbers. This")
print(" excludes a global translation; it does not exclude a local one.")