FA-79031 / Image orientation metadata / Open access
Video rotation matrix is read with math-axis orientation · case 01
Portrait phone videos play upside down: 90 and 270 degree tracks are exchanged.
ROOT CAUSE
The table assumes y points up, so an x axis mapped to +y is read as a counter-clockwise turn.
VERIFIED REPAIR
With screen coordinates (y down) an x axis mapped to +y is a 90 degree clockwise rotation.
Unsuccessful approach: Reading the rotation from the y-axis column (c, d) offsets every result by a quarter turn.
Case contract
Input [matrix, width, height] where matrix is the [a, b, c, d] part of a track display matrix stored as unsigned 32-bit 16.16 fixed-point words (x' = a*x + c*y, y' = b*x + d*y, screen y down). Only signed permutation matrices of unit entries are supported, otherwise "unsupported". A negative determinant means a left-right mirror applied before the rotation; the clockwise rotation is read from the image of the x axis after removing the mirror. Return rotate (0/90/180/270), mirror and the displayed [width, height].
Why this case matters
Camera, phone and scanner images carry an orientation hint separately from the stored pixels; galleries, thumbnailers, editors and upload pipelines must interpret it consistently or photos appear sideways, mirrored or doubly rotated.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
m, w, h = x
U = 65536
m = [v - (1 << 32) if v >= (1 << 31) else v for v in m]
a, b, c, d = m
if any(v not in (-U, 0, U) for v in m):
return 'unsupported'
if not ((b == 0 and c == 0 and a != 0 and d != 0) or (a == 0 and d == 0 and b != 0 and c != 0)):
return 'unsupported'
det = (a * d - b * c) // (U * U)
mirror = det == -1
if mirror:
a, b = -a, -b
deg = {(U, 0): 0, (0, U): 270, (-U, 0): 180, (0, -U): 90}[(a, b)]
if deg in (90, 270):
w, h = h, w
return {'rotate': deg, 'mirror': mirror, 'display': [w, h]}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[0, 4294901760, 4294901760, 0], 760, 3281], {'rotate': 90, 'mirror': True, 'display': [3281, 760]}], [[[0, 4294901760, 4294901760, 0], 1355, 3779], {'rotate': 90, 'mirror': True, 'display': [3779, 1355]}], [[[4294901760, 0, 65536, 4294901760], 3830, 2696], 'unsupported'], [[[0, 65536, 4294901760, 65536], 559, 2713], 'unsupported'], [[[0, 65536, 4294901760, 65536], 1463, 780], 'unsupported'], [[[65536, 4294901760, 65536, 65536], 2751, 608], 'unsupported'], [[[0, 0, 4294901760, 0], 1243, 3391], 'unsupported'], [[[0, 4294901760, 4294901760, 0], 3070, 241], {'rotate': 90, 'mirror': True, 'display': [241, 3070]}]], [[[[0, 65536, 65536, 0], 3389, 3534], {'rotate': 270, 'mirror': True, 'display': [3534, 3389]}], [[[0, 4294901760, 4294901760, 0], 2859, 1281], {'rotate': 90, 'mirror': True, 'display': [1281, 2859]}], [[[4294901760, 0, 4294901760, 4294901760], 2730, 1220], 'unsupported'], [[[65536, 4294901760, 0, 4294901760], 3622, 60], 'unsupported'], [[[0, 4294901760, 65536, 65536], 1290, 2847], 'unsupported'], [[[65536, 0, 4294901760, 65536], 1369, 1577], 'unsupported'], [[[4294920955, 0, 131072, 65536], 2355, 1488], 'unsupported'], [[[0, 65536, 65536, 0], 1609, 1135], {'rotate': 270, 'mirror': True, 'display': [1135, 1609]}]], [[[[0, 65536, 65536, 0], 967, 3689], {'rotate': 270, 'mirror': True, 'display': [3689, 967]}], [[[4294901760, 0, 0, 65536], 3751, 979], {'rotate': 0, 'mirror': True, 'display': [3751, 979]}], [[[0, 65536, 4294901760, 0], 3726, 3245], {'rotate': 90, 'mirror': False, 'display': [3245, 3726]}], [[[4294901760, 0, 65536, 0], 3442, 2421], 'unsupported'], [[[4294901760, 65536, 4294901760, 0], 392, 1027], 'unsupported'], [[[4294901760, 0, 4294901760, 65536], 1363, 2590], 'unsupported'], [[[4294901760, 0, 65536, 0], 3783, 1537], 'unsupported'], [[[0, 65536, 4294901760, 0], 3695, 719], {'rotate': 90, 'mirror': False, 'display': [719, 3695]}]], [[[[0, 65536, 4294901760, 0], 2560, 3677], {'rotate': 90, 'mirror': False, 'display': [3677, 2560]}], [[[4294901760, 0, 0, 4294901760], 2276, 3617], {'rotate': 180, 'mirror': False, 'display': [2276, 3617]}], [[[0, 4294901760, 4294901760, 0], 674, 3659], {'rotate': 90, 'mirror': True, 'display': [3659, 674]}], [[[0, 0, 46341, 0], 991, 438], 'unsupported'], [[[65536, 0, 65536, 65536], 1287, 3950], 'unsupported'], [[[0, 65536, 0, 0], 2790, 437], 'unsupported'], [[[0, 4294901760, 65536, 4294901760], 3527, 100], 'unsupported'], [[[0, 65536, 65536, 0], 3426, 462], {'rotate': 270, 'mirror': True, 'display': [462, 3426]}]], [[[[0, 65536, 4294901760, 0], 1708, 2732], {'rotate': 90, 'mirror': False, 'display': [2732, 1708]}], [[[0, 4294901760, 4294901760, 0], 1874, 407], {'rotate': 90, 'mirror': True, 'display': [407, 1874]}], [[[0, 65536, 65536, 0], 2128, 235], {'rotate': 270, 'mirror': True, 'display': [235, 2128]}], [[[4294901760, 65536, 65536, 0], 1703, 3849], 'unsupported'], [[[65536, 4294901760, 4294901760, 4294901760], 132, 2157], 'unsupported'], [[[0, 4294901760, 0, 0], 3596, 3944], 'unsupported'], [[[4294901760, 32768, 32768, 4294901760], 1623, 1094], 'unsupported'], [[[0, 4294901760, 65536, 0], 1102, 1279], {'rotate': 270, 'mirror': False, 'display': [1279, 1102]}]]]
labels = ["regression: quarter-turn direction table", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: quarter-turn direction table 0 | {'display': [3281, 760], 'mirror': True, 'rotate': 270} | {'display': [3281, 760], 'mirror': True, 'rotate': 90} | Failed |
| repair trap 1 | {'display': [3779, 1355], 'mirror': True, 'rotate': 270} | {'display': [3779, 1355], 'mirror': True, 'rotate': 90} | Failed |
| combined fault 2 | unsupported | unsupported | Passed |
| control 3 | unsupported | unsupported | Passed |
| control 4 | unsupported | unsupported | Passed |
| boundary 5 | unsupported | unsupported | Passed |
| boundary 6 | unsupported | unsupported | Passed |
| control 7 | {'display': [241, 3070], 'mirror': True, 'rotate': 270} | {'display': [241, 3070], 'mirror': True, 'rotate': 90} | Failed |
SHA-256 / 83adbc7bdf0135a42328a880a05966e7085b87b2492aad96efea3344b497e976
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
m, w, h = x
U = 65536
m = [v - (1 << 32) if v >= (1 << 31) else v for v in m]
a, b, c, d = m
if any(v not in (-U, 0, U) for v in m):
return 'unsupported'
if not ((b == 0 and c == 0 and a != 0 and d != 0) or (a == 0 and d == 0 and b != 0 and c != 0)):
return 'unsupported'
det = (a * d - b * c) // (U * U)
mirror = det == -1
if mirror:
a, b = -a, -b
deg = {(U, 0): 0, (0, U): 90, (-U, 0): 180, (0, -U): 270}[(c, d)]
if deg in (90, 270):
w, h = h, w
return {'rotate': deg, 'mirror': mirror, 'display': [w, h]}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[0, 4294901760, 4294901760, 0], 760, 3281], {'rotate': 90, 'mirror': True, 'display': [3281, 760]}], [[[0, 4294901760, 4294901760, 0], 1355, 3779], {'rotate': 90, 'mirror': True, 'display': [3779, 1355]}], [[[4294901760, 0, 65536, 4294901760], 3830, 2696], 'unsupported'], [[[0, 65536, 4294901760, 65536], 559, 2713], 'unsupported'], [[[0, 65536, 4294901760, 65536], 1463, 780], 'unsupported'], [[[65536, 4294901760, 65536, 65536], 2751, 608], 'unsupported'], [[[0, 0, 4294901760, 0], 1243, 3391], 'unsupported'], [[[0, 4294901760, 4294901760, 0], 3070, 241], {'rotate': 90, 'mirror': True, 'display': [241, 3070]}]], [[[[0, 65536, 65536, 0], 3389, 3534], {'rotate': 270, 'mirror': True, 'display': [3534, 3389]}], [[[0, 4294901760, 4294901760, 0], 2859, 1281], {'rotate': 90, 'mirror': True, 'display': [1281, 2859]}], [[[4294901760, 0, 4294901760, 4294901760], 2730, 1220], 'unsupported'], [[[65536, 4294901760, 0, 4294901760], 3622, 60], 'unsupported'], [[[0, 4294901760, 65536, 65536], 1290, 2847], 'unsupported'], [[[65536, 0, 4294901760, 65536], 1369, 1577], 'unsupported'], [[[4294920955, 0, 131072, 65536], 2355, 1488], 'unsupported'], [[[0, 65536, 65536, 0], 1609, 1135], {'rotate': 270, 'mirror': True, 'display': [1135, 1609]}]], [[[[0, 65536, 65536, 0], 967, 3689], {'rotate': 270, 'mirror': True, 'display': [3689, 967]}], [[[4294901760, 0, 0, 65536], 3751, 979], {'rotate': 0, 'mirror': True, 'display': [3751, 979]}], [[[0, 65536, 4294901760, 0], 3726, 3245], {'rotate': 90, 'mirror': False, 'display': [3245, 3726]}], [[[4294901760, 0, 65536, 0], 3442, 2421], 'unsupported'], [[[4294901760, 65536, 4294901760, 0], 392, 1027], 'unsupported'], [[[4294901760, 0, 4294901760, 65536], 1363, 2590], 'unsupported'], [[[4294901760, 0, 65536, 0], 3783, 1537], 'unsupported'], [[[0, 65536, 4294901760, 0], 3695, 719], {'rotate': 90, 'mirror': False, 'display': [719, 3695]}]], [[[[0, 65536, 4294901760, 0], 2560, 3677], {'rotate': 90, 'mirror': False, 'display': [3677, 2560]}], [[[4294901760, 0, 0, 4294901760], 2276, 3617], {'rotate': 180, 'mirror': False, 'display': [2276, 3617]}], [[[0, 4294901760, 4294901760, 0], 674, 3659], {'rotate': 90, 'mirror': True, 'display': [3659, 674]}], [[[0, 0, 46341, 0], 991, 438], 'unsupported'], [[[65536, 0, 65536, 65536], 1287, 3950], 'unsupported'], [[[0, 65536, 0, 0], 2790, 437], 'unsupported'], [[[0, 4294901760, 65536, 4294901760], 3527, 100], 'unsupported'], [[[0, 65536, 65536, 0], 3426, 462], {'rotate': 270, 'mirror': True, 'display': [462, 3426]}]], [[[[0, 65536, 4294901760, 0], 1708, 2732], {'rotate': 90, 'mirror': False, 'display': [2732, 1708]}], [[[0, 4294901760, 4294901760, 0], 1874, 407], {'rotate': 90, 'mirror': True, 'display': [407, 1874]}], [[[0, 65536, 65536, 0], 2128, 235], {'rotate': 270, 'mirror': True, 'display': [235, 2128]}], [[[4294901760, 65536, 65536, 0], 1703, 3849], 'unsupported'], [[[65536, 4294901760, 4294901760, 4294901760], 132, 2157], 'unsupported'], [[[0, 4294901760, 0, 0], 3596, 3944], 'unsupported'], [[[4294901760, 32768, 32768, 4294901760], 1623, 1094], 'unsupported'], [[[0, 4294901760, 65536, 0], 1102, 1279], {'rotate': 270, 'mirror': False, 'display': [1279, 1102]}]]]
labels = ["regression: quarter-turn direction table", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: quarter-turn direction table 0 | {'display': [760, 3281], 'mirror': True, 'rotate': 180} | {'display': [3281, 760], 'mirror': True, 'rotate': 90} | Failed |
| repair trap 1 | {'display': [1355, 3779], 'mirror': True, 'rotate': 180} | {'display': [3779, 1355], 'mirror': True, 'rotate': 90} | Failed |
| combined fault 2 | unsupported | unsupported | Passed |
| control 3 | unsupported | unsupported | Passed |
| control 4 | unsupported | unsupported | Passed |
| boundary 5 | unsupported | unsupported | Passed |
| boundary 6 | unsupported | unsupported | Passed |
| control 7 | {'display': [3070, 241], 'mirror': True, 'rotate': 180} | {'display': [241, 3070], 'mirror': True, 'rotate': 90} | Failed |
SHA-256 / e1ed6a400817b31a9c839e02777082b7041bb1a4deb299964ff623ec8164a6bb
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
m, w, h = x
U = 65536
m = [v - (1 << 32) if v >= (1 << 31) else v for v in m]
a, b, c, d = m
if any(v not in (-U, 0, U) for v in m):
return 'unsupported'
if not ((b == 0 and c == 0 and a != 0 and d != 0) or (a == 0 and d == 0 and b != 0 and c != 0)):
return 'unsupported'
det = (a * d - b * c) // (U * U)
mirror = det == -1
if mirror:
a, b = -a, -b
deg = {(U, 0): 0, (0, U): 90, (-U, 0): 180, (0, -U): 270}[(a, b)]
if deg in (90, 270):
w, h = h, w
return {'rotate': deg, 'mirror': mirror, 'display': [w, h]}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[0, 4294901760, 4294901760, 0], 760, 3281], {'rotate': 90, 'mirror': True, 'display': [3281, 760]}], [[[0, 4294901760, 4294901760, 0], 1355, 3779], {'rotate': 90, 'mirror': True, 'display': [3779, 1355]}], [[[4294901760, 0, 65536, 4294901760], 3830, 2696], 'unsupported'], [[[0, 65536, 4294901760, 65536], 559, 2713], 'unsupported'], [[[0, 65536, 4294901760, 65536], 1463, 780], 'unsupported'], [[[65536, 4294901760, 65536, 65536], 2751, 608], 'unsupported'], [[[0, 0, 4294901760, 0], 1243, 3391], 'unsupported'], [[[0, 4294901760, 4294901760, 0], 3070, 241], {'rotate': 90, 'mirror': True, 'display': [241, 3070]}]], [[[[0, 65536, 65536, 0], 3389, 3534], {'rotate': 270, 'mirror': True, 'display': [3534, 3389]}], [[[0, 4294901760, 4294901760, 0], 2859, 1281], {'rotate': 90, 'mirror': True, 'display': [1281, 2859]}], [[[4294901760, 0, 4294901760, 4294901760], 2730, 1220], 'unsupported'], [[[65536, 4294901760, 0, 4294901760], 3622, 60], 'unsupported'], [[[0, 4294901760, 65536, 65536], 1290, 2847], 'unsupported'], [[[65536, 0, 4294901760, 65536], 1369, 1577], 'unsupported'], [[[4294920955, 0, 131072, 65536], 2355, 1488], 'unsupported'], [[[0, 65536, 65536, 0], 1609, 1135], {'rotate': 270, 'mirror': True, 'display': [1135, 1609]}]], [[[[0, 65536, 65536, 0], 967, 3689], {'rotate': 270, 'mirror': True, 'display': [3689, 967]}], [[[4294901760, 0, 0, 65536], 3751, 979], {'rotate': 0, 'mirror': True, 'display': [3751, 979]}], [[[0, 65536, 4294901760, 0], 3726, 3245], {'rotate': 90, 'mirror': False, 'display': [3245, 3726]}], [[[4294901760, 0, 65536, 0], 3442, 2421], 'unsupported'], [[[4294901760, 65536, 4294901760, 0], 392, 1027], 'unsupported'], [[[4294901760, 0, 4294901760, 65536], 1363, 2590], 'unsupported'], [[[4294901760, 0, 65536, 0], 3783, 1537], 'unsupported'], [[[0, 65536, 4294901760, 0], 3695, 719], {'rotate': 90, 'mirror': False, 'display': [719, 3695]}]], [[[[0, 65536, 4294901760, 0], 2560, 3677], {'rotate': 90, 'mirror': False, 'display': [3677, 2560]}], [[[4294901760, 0, 0, 4294901760], 2276, 3617], {'rotate': 180, 'mirror': False, 'display': [2276, 3617]}], [[[0, 4294901760, 4294901760, 0], 674, 3659], {'rotate': 90, 'mirror': True, 'display': [3659, 674]}], [[[0, 0, 46341, 0], 991, 438], 'unsupported'], [[[65536, 0, 65536, 65536], 1287, 3950], 'unsupported'], [[[0, 65536, 0, 0], 2790, 437], 'unsupported'], [[[0, 4294901760, 65536, 4294901760], 3527, 100], 'unsupported'], [[[0, 65536, 65536, 0], 3426, 462], {'rotate': 270, 'mirror': True, 'display': [462, 3426]}]], [[[[0, 65536, 4294901760, 0], 1708, 2732], {'rotate': 90, 'mirror': False, 'display': [2732, 1708]}], [[[0, 4294901760, 4294901760, 0], 1874, 407], {'rotate': 90, 'mirror': True, 'display': [407, 1874]}], [[[0, 65536, 65536, 0], 2128, 235], {'rotate': 270, 'mirror': True, 'display': [235, 2128]}], [[[4294901760, 65536, 65536, 0], 1703, 3849], 'unsupported'], [[[65536, 4294901760, 4294901760, 4294901760], 132, 2157], 'unsupported'], [[[0, 4294901760, 0, 0], 3596, 3944], 'unsupported'], [[[4294901760, 32768, 32768, 4294901760], 1623, 1094], 'unsupported'], [[[0, 4294901760, 65536, 0], 1102, 1279], {'rotate': 270, 'mirror': False, 'display': [1279, 1102]}]]]
labels = ["regression: quarter-turn direction table", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: quarter-turn direction table 0 | {'display': [3281, 760], 'mirror': True, 'rotate': 90} | {'display': [3281, 760], 'mirror': True, 'rotate': 90} | Passed |
| repair trap 1 | {'display': [3779, 1355], 'mirror': True, 'rotate': 90} | {'display': [3779, 1355], 'mirror': True, 'rotate': 90} | Passed |
| combined fault 2 | unsupported | unsupported | Passed |
| control 3 | unsupported | unsupported | Passed |
| control 4 | unsupported | unsupported | Passed |
| boundary 5 | unsupported | unsupported | Passed |
| boundary 6 | unsupported | unsupported | Passed |
| control 7 | {'display': [241, 3070], 'mirror': True, 'rotate': 90} | {'display': [241, 3070], 'mirror': True, 'rotate': 90} | Passed |
SHA-256 / 4754dd8defff869883977f16c582143ae61b8a77909eebbefeddcc76531bc817
Verification & scope
A deterministic bounded teaching model with a stipulated contract; it makes no claim of conformance to any published specification. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:40.601448+00:00.
Case digest / c3b49d683eeb78b287ccf6a1b0a8eaf05e62abdcc6481cf4fa154fbbde802a6c