FA-78941 / Image orientation metadata / Open access
Metadata rotation confuses transpose with transverse · case 01
Rotating a tag-5 selfie in the editor lands on a tag that shows it upside down.
ROOT CAUSE
The (k, m) table assigns mirror-then-clockwise to tag 5 and mirror-then-counter-clockwise to tag 7.
THE FAILURE
The (k, m) table assigns mirror-then-clockwise to tag 5 and mirror-then-counter-clockwise to tag 7.
Unsuccessful approach: Changing the tag-6 entry breaks the pure rotations and makes the table non-invertible.
Case contract
A photo editor rotates and flips losslessly by rewriting only the orientation tag. An orientation is modelled as (k, m): mirror horizontally m times, then rotate k quarter turns clockwise (tag table 1:(0,0) 2:(0,1) 3:(2,0) 4:(2,1) 5:(3,1) 6:(1,0) 7:(1,1) 8:(3,0)). Editor operations act on the displayed image: cw, ccw, r180, flip_h (mirror left-right) and flip_v (mirror top-bottom). Invalid starting tags count as 1; an unknown operation returns {"error": "unknown-op", "op": op}. Return the final tag.
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(tag, ops):
to_km = {1: (0, 0), 2: (0, 1), 3: (2, 0), 4: (2, 1), 5: (1, 1), 6: (1, 0), 7: (3, 1), 8: (3, 0)}
from_km = {v: t for t, v in to_km.items()}
if tag not in to_km:
tag = 1
k, m = to_km[tag]
for op in ops:
if op == 'cw':
k = (k + 1) % 4
elif op == 'ccw':
k = (k + 3) % 4
elif op == 'r180':
k = (k + 2) % 4
elif op == 'flip_h':
k, m = (-k) % 4, 1 - m
elif op == 'flip_v':
k, m = (2 - k) % 4, 1 - m
else:
return {'error': 'unknown-op', 'op': op}
return from_km[(k, m)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[(8, ['ccw', 'flip_h', 'ccw']), 7], [(6, []), 6], [(6, ['flip_v']), 7], [(8, ['ccw', 'cw']), 8], [(3, ['rotate']), {'error': 'unknown-op', 'op': 'rotate'}], [(1, ['cw', 'ccw', 'r180', 'cw']), 8], [(0, ['flip_v']), 4], [(7, ['flip_v', 'ccw', 'r180']), 3]], [[(1, ['ccw', 'flip_v']), 5], [(6, ['flip_v', 'ccw', 'flip_h', 'r180']), 3], [(6, ['r180', 'flip_v']), 5], [(8, ['CW']), {'error': 'unknown-op', 'op': 'CW'}], [(0, []), 1], [(8, ['ccw', 'r180']), 1], [(4, ['mirror', 'flip_v', 'cw', 'r180']), {'error': 'unknown-op', 'op': 'mirror'}], [(4, ['ccw']), 7]], [[(5, ['r180', 'flip_h', 'ccw']), 3], [(6, ['cw', 'ccw']), 6], [(6, ['flip_h', 'r180']), 7], [(1, ['ccw', 'ccw', 'r180']), 1], [(11, ['r180', 'cw', 'flip_v', 'cw']), 2], [(11, ['cw', 'flip_v', 'flip_h']), 8], [(2, ['flip_v', 'cw', 'cw']), 1], [(9, ['cw', 'r180', 'flip_h']), 7]], [[(7, ['r180', 'cw', 'r180', 'flip_v']), 1], [(6, []), 6], [(6, ['flip_h', 'ccw', 'r180', 'cw']), 7], [(0, ['flip_v']), 4], [(8, ['rotate']), {'error': 'unknown-op', 'op': 'rotate'}], [(11, ['r180']), 3], [(1, ['r180', 'flip_h', 'cw', 'flip_v']), 8], [(2, ['ccw', 'r180', 'flip_h', 'flip_v']), 5]], [[(5, ['ccw']), 4], [(6, ['ccw', 'flip_v', 'cw', 'flip_h']), 6], [(6, ['r180', 'flip_h']), 7], [(2, ['flip_v', 'flip_v']), 2], [(1, []), 1], [(5, ['r180']), 7], [(0, ['ccw', 'cw']), 1], [(2, ['cw']), 7]]]
labels = ["regression: transpose and transverse table entries", "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: transpose and transverse table entries 0 | 5 | 7 | Failed |
| repair trap 1 | 6 | 6 | Passed |
| combined fault 2 | 5 | 7 | Failed |
| control 3 | 8 | 8 | Passed |
| control 4 | {'error': 'unknown-op', 'op': 'rotate'} | {'error': 'unknown-op', 'op': 'rotate'} | Passed |
| boundary 5 | 8 | 8 | Passed |
| boundary 6 | 4 | 4 | Passed |
| control 7 | 1 | 3 | Failed |
SHA-256 / e60c1cf97e1290dd65e325d1b53381ad628930b7815219405b9b6f5aa547f52a
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(tag, ops):
to_km = {1: (0, 0), 2: (0, 1), 3: (2, 0), 4: (2, 1), 5: (3, 1), 6: (3, 0), 7: (1, 1), 8: (3, 0)}
from_km = {v: t for t, v in to_km.items()}
if tag not in to_km:
tag = 1
k, m = to_km[tag]
for op in ops:
if op == 'cw':
k = (k + 1) % 4
elif op == 'ccw':
k = (k + 3) % 4
elif op == 'r180':
k = (k + 2) % 4
elif op == 'flip_h':
k, m = (-k) % 4, 1 - m
elif op == 'flip_v':
k, m = (2 - k) % 4, 1 - m
else:
return {'error': 'unknown-op', 'op': op}
return from_km[(k, m)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[(8, ['ccw', 'flip_h', 'ccw']), 7], [(6, []), 6], [(6, ['flip_v']), 7], [(8, ['ccw', 'cw']), 8], [(3, ['rotate']), {'error': 'unknown-op', 'op': 'rotate'}], [(1, ['cw', 'ccw', 'r180', 'cw']), 8], [(0, ['flip_v']), 4], [(7, ['flip_v', 'ccw', 'r180']), 3]], [[(1, ['ccw', 'flip_v']), 5], [(6, ['flip_v', 'ccw', 'flip_h', 'r180']), 3], [(6, ['r180', 'flip_v']), 5], [(8, ['CW']), {'error': 'unknown-op', 'op': 'CW'}], [(0, []), 1], [(8, ['ccw', 'r180']), 1], [(4, ['mirror', 'flip_v', 'cw', 'r180']), {'error': 'unknown-op', 'op': 'mirror'}], [(4, ['ccw']), 7]], [[(5, ['r180', 'flip_h', 'ccw']), 3], [(6, ['cw', 'ccw']), 6], [(6, ['flip_h', 'r180']), 7], [(1, ['ccw', 'ccw', 'r180']), 1], [(11, ['r180', 'cw', 'flip_v', 'cw']), 2], [(11, ['cw', 'flip_v', 'flip_h']), 8], [(2, ['flip_v', 'cw', 'cw']), 1], [(9, ['cw', 'r180', 'flip_h']), 7]], [[(7, ['r180', 'cw', 'r180', 'flip_v']), 1], [(6, []), 6], [(6, ['flip_h', 'ccw', 'r180', 'cw']), 7], [(0, ['flip_v']), 4], [(8, ['rotate']), {'error': 'unknown-op', 'op': 'rotate'}], [(11, ['r180']), 3], [(1, ['r180', 'flip_h', 'cw', 'flip_v']), 8], [(2, ['ccw', 'r180', 'flip_h', 'flip_v']), 5]], [[(5, ['ccw']), 4], [(6, ['ccw', 'flip_v', 'cw', 'flip_h']), 6], [(6, ['r180', 'flip_h']), 7], [(2, ['flip_v', 'flip_v']), 2], [(1, []), 1], [(5, ['r180']), 7], [(0, ['ccw', 'cw']), 1], [(2, ['cw']), 7]]]
labels = ["regression: transpose and transverse table entries", "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: transpose and transverse table entries 0 | 7 | 7 | Passed |
| repair trap 1 | 8 | 6 | Failed |
| combined fault 2 | 5 | 7 | Failed |
| control 3 | 8 | 8 | Passed |
| control 4 | {'error': 'unknown-op', 'op': 'rotate'} | {'error': 'unknown-op', 'op': 'rotate'} | Passed |
| boundary 5 | 8 | 8 | Passed |
| boundary 6 | 4 | 4 | Passed |
| control 7 | 3 | 3 | Passed |
SHA-256 / 4f99a80971d063f18151b4b88eec81e4ebb1cadd7be07cfaf3c388d8a78b1679
HELD IN THE MEMBER ARCHIVE
The verified repair and its recorded checks are member-only.
This mechanism has 8 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.
Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.
Member access is invitation-based. Sign in with your invited account to inspect the repair.
Sign in to the archive ↗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:39.883745+00:00.
Case digest / 29844ea3c41d7a7e79e5253ae01dbe5cc2b037bb03711d5ee03e3d0e26051fa8