broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(meta):
    from_km = {(0, 0): 1, (0, 1): 2, (2, 0): 3, (2, 1): 4, (3, 1): 5, (1, 0): 6, (1, 1): 7, (3, 0): 8}
    c = meta.get('container')
    if c == 'heif':
        rot = meta.get('irot')
        mir = meta.get('imir')
        rot = 0 if rot is None else rot % 4
        if mir is None:
            return from_km[((-rot) % 4, 0)]
        if mir == 0:
            return from_km[(rot, 1)]
        return from_km[((rot + 2) % 4, 1)]
    e = meta.get('exif')
    if isinstance(e, int) and not isinstance(e, bool) and 1 <= e <= 8:
        return e
    x = meta.get('xmp')
    if isinstance(x, str):
        s = x
        if s in ('1', '2', '3', '4', '5', '6', '7', '8'):
            return int(s)
    return 1
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[{'container': 'tiff', 'exif': True, 'xmp': '7 '}, 7], [{'container': 'jpeg', 'exif': 0, 'xmp': '\t5'}, 5], [{'container': 'png'}, 1], [{'container': 'jpeg', 'xmp': '2'}, 2], [{'container': 'heif', 'xmp': '\t5', 'irot': 3}, 6], [{'container': 'tiff'}, 1], [{'container': 'tiff', 'exif': True}, 1], [{'container': 'jpeg', 'xmp': '7 '}, 7]], [[{'container': 'jpeg', 'exif': 0, 'xmp': '\t5'}, 5], [{'container': 'jpeg', 'exif': 0}, 1], [{'container': 'heif', 'exif': 5, 'xmp': ' 8', 'imir': 0}, 2], [{'container': 'heif', 'exif': 3, 'xmp': 'x', 'irot': 0}, 1], [{'container': 'heif', 'xmp': '\t5', 'irot': 0, 'imir': 1}, 4], [{'container': 'png'}, 1], [{'container': 'heif', 'exif': 3, 'irot': 3, 'imir': 1}, 7], [{'container': 'jpeg', 'xmp': '3\n'}, 3]], [[{'container': 'png', 'xmp': '\t5'}, 5], [{'container': 'tiff', 'exif': 9, 'xmp': '3\n'}, 3], [{'container': 'tiff'}, 1], [{'container': 'jpeg'}, 1], [{'container': 'jpeg', 'exif': 0}, 1], [{'container': 'heif', 'exif': 6, 'xmp': 'x', 'irot': 2}, 3], [{'container': 'png', 'exif': 1}, 1], [{'container': 'jpeg', 'exif': 9, 'xmp': ' 8'}, 8]], [[{'container': 'png', 'exif': 9, 'xmp': '3\n'}, 3], [{'container': 'jpeg', 'exif': 9, 'xmp': '\t5', 'irot': 3, 'imir': 0}, 5], [{'container': 'png', 'xmp': '3\n'}, 3], [{'container': 'jpeg', 'exif': 1}, 1], [{'container': 'heif', 'exif': 1, 'xmp': '7 ', 'irot': 2}, 3], [{'container': 'heif', 'xmp': '\t5'}, 1], [{'container': 'tiff', 'exif': 5}, 5], [{'container': 'jpeg', 'xmp': '7 '}, 7]], [[{'container': 'jpeg', 'xmp': '3\n'}, 3], [{'container': 'jpeg', 'exif': 9, 'xmp': '\t5'}, 5], [{'container': 'heif', 'irot': 2}, 3], [{'container': 'heif', 'xmp': ' 8', 'irot': 1}, 8], [{'container': 'jpeg', 'xmp': 'x'}, 1], [{'container': 'png', 'exif': 7}, 7], [{'container': 'jpeg', 'exif': 7}, 7], [{'container': 'tiff', 'exif': 9, 'xmp': '\t5'}, 5]]]
labels = ["regression: XMP value trimming", "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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(meta):
    from_km = {(0, 0): 1, (0, 1): 2, (2, 0): 3, (2, 1): 4, (3, 1): 5, (1, 0): 6, (1, 1): 7, (3, 0): 8}
    c = meta.get('container')
    if c == 'heif':
        rot = meta.get('irot')
        mir = meta.get('imir')
        rot = 0 if rot is None else rot % 4
        if mir is None:
            return from_km[((-rot) % 4, 0)]
        if mir == 0:
            return from_km[(rot, 1)]
        return from_km[((rot + 2) % 4, 1)]
    e = meta.get('exif')
    if isinstance(e, int) and not isinstance(e, bool) and 1 <= e <= 8:
        return e
    x = meta.get('xmp')
    if isinstance(x, str):
        s = x.strip(' ')
        if s in ('1', '2', '3', '4', '5', '6', '7', '8'):
            return int(s)
    return 1
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[{'container': 'tiff', 'exif': True, 'xmp': '7 '}, 7], [{'container': 'jpeg', 'exif': 0, 'xmp': '\t5'}, 5], [{'container': 'png'}, 1], [{'container': 'jpeg', 'xmp': '2'}, 2], [{'container': 'heif', 'xmp': '\t5', 'irot': 3}, 6], [{'container': 'tiff'}, 1], [{'container': 'tiff', 'exif': True}, 1], [{'container': 'jpeg', 'xmp': '7 '}, 7]], [[{'container': 'jpeg', 'exif': 0, 'xmp': '\t5'}, 5], [{'container': 'jpeg', 'exif': 0}, 1], [{'container': 'heif', 'exif': 5, 'xmp': ' 8', 'imir': 0}, 2], [{'container': 'heif', 'exif': 3, 'xmp': 'x', 'irot': 0}, 1], [{'container': 'heif', 'xmp': '\t5', 'irot': 0, 'imir': 1}, 4], [{'container': 'png'}, 1], [{'container': 'heif', 'exif': 3, 'irot': 3, 'imir': 1}, 7], [{'container': 'jpeg', 'xmp': '3\n'}, 3]], [[{'container': 'png', 'xmp': '\t5'}, 5], [{'container': 'tiff', 'exif': 9, 'xmp': '3\n'}, 3], [{'container': 'tiff'}, 1], [{'container': 'jpeg'}, 1], [{'container': 'jpeg', 'exif': 0}, 1], [{'container': 'heif', 'exif': 6, 'xmp': 'x', 'irot': 2}, 3], [{'container': 'png', 'exif': 1}, 1], [{'container': 'jpeg', 'exif': 9, 'xmp': ' 8'}, 8]], [[{'container': 'png', 'exif': 9, 'xmp': '3\n'}, 3], [{'container': 'jpeg', 'exif': 9, 'xmp': '\t5', 'irot': 3, 'imir': 0}, 5], [{'container': 'png', 'xmp': '3\n'}, 3], [{'container': 'jpeg', 'exif': 1}, 1], [{'container': 'heif', 'exif': 1, 'xmp': '7 ', 'irot': 2}, 3], [{'container': 'heif', 'xmp': '\t5'}, 1], [{'container': 'tiff', 'exif': 5}, 5], [{'container': 'jpeg', 'xmp': '7 '}, 7]], [[{'container': 'jpeg', 'xmp': '3\n'}, 3], [{'container': 'jpeg', 'exif': 9, 'xmp': '\t5'}, 5], [{'container': 'heif', 'irot': 2}, 3], [{'container': 'heif', 'xmp': ' 8', 'irot': 1}, 8], [{'container': 'jpeg', 'xmp': 'x'}, 1], [{'container': 'png', 'exif': 7}, 7], [{'container': 'jpeg', 'exif': 7}, 7], [{'container': 'tiff', 'exif': 9, 'xmp': '\t5'}, 5]]]
labels = ["regression: XMP value trimming", "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)

prompt:
Sidecar-edited photos whose XMP value is serialised with a newline lose their rotation.

Resolve the displayed orientation tag from metadata sources. For HEIF, the container transforms are authoritative and EXIF/XMP are ignored: irot is anticlockwise quarter turns (default 0) applied first, then imir mirrors about the vertical axis (0, left-right) or the horizontal axis (1, top-bottom); the result is mapped to a tag through (k clockwise quarter turns after m mirrors) = {(0,0):1, (0,1):2, (2,0):3, (2,1):4, (3,1):5, (1,0):6, (1,1):7, (3,0):8}. For other containers a valid integer EXIF value 1..8 wins; otherwise an XMP string that is a single digit 1..8 after trimming whitespace; otherwise 1.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(meta):
    from_km = {(0, 0): 1, (0, 1): 2, (2, 0): 3, (2, 1): 4, (3, 1): 5, (1, 0): 6, (1, 1): 7, (3, 0): 8}
    c = meta.get('container')
    if c == 'heif':
        rot = meta.get('irot')
        mir = meta.get('imir')
        rot = 0 if rot is None else rot % 4
        if mir is None:
            return from_km[((-rot) % 4, 0)]
        if mir == 0:
            return from_km[(rot, 1)]
        return from_km[((rot + 2) % 4, 1)]
    x = meta.get('xmp')
    if isinstance(x, str):
        s = x.strip()
        if s in ('1', '2', '3', '4', '5', '6', '7', '8'):
            return int(s)
    e = meta.get('exif')
    if isinstance(e, int) and not isinstance(e, bool) and 1 <= e <= 8:
        return e
    return 1
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[{'container': 'png', 'exif': 1, 'xmp': '2'}, 1], [{'container': 'png', 'exif': 7, 'xmp': ' 8'}, 7], [{'container': 'png'}, 1], [{'container': 'jpeg', 'xmp': '2'}, 2], [{'container': 'heif', 'xmp': '\t5', 'irot': 3}, 6], [{'container': 'tiff'}, 1], [{'container': 'tiff', 'exif': True, 'xmp': '7 '}, 7], [{'container': 'png', 'exif': 7, 'xmp': '6'}, 7]], [[{'container': 'png', 'exif': 6, 'xmp': '7 '}, 6], [{'container': 'png', 'exif': 2, 'xmp': '\t5'}, 2], [{'container': 'png', 'xmp': '3\n'}, 3], [{'container': 'jpeg', 'exif': 0, 'xmp': '\t5'}, 5], [{'container': 'jpeg', 'exif': 0}, 1], [{'container': 'jpeg', 'xmp': '3\n'}, 3], [{'container': 'heif', 'exif': 5, 'xmp': ' 8', 'imir': 0}, 2], [{'container': 'jpeg', 'exif': 1, 'xmp': '3\n'}, 1]], [[{'container': 'tiff', 'exif': 8, 'xmp': '7 '}, 8], [{'container': 'png', 'exif': 7, 'xmp': ' 8'}, 7], [{'container': 'png', 'exif': 1, 'xmp': ' 8'}, 1], [{'container': 'jpeg', 'xmp': '7 '}, 7], [{'container': 'tiff'}, 1], [{'container': 'jpeg'}, 1], [{'container': 'jpeg', 'exif': 0}, 1], [{'container': 'jpeg', 'exif': 7, 'xmp': '6'}, 7]], [[{'container': 'jpeg', 'exif': 1, 'xmp': '\t5'}, 1], [{'container': 'png', 'exif': 5, 'xmp': '3\n'}, 5], [{'container': 'png', 'exif': 3, 'xmp': '7 '}, 3], [{'container': 'jpeg', 'exif': True, 'xmp': ' 8'}, 8], [{'container': 'jpeg', 'exif': 1}, 1], [{'container': 'heif', 'exif': 1, 'xmp': '7 ', 'irot': 2}, 3], [{'container': 'heif', 'xmp': '\t5'}, 1], [{'container': 'tiff', 'exif': 8, 'xmp': '\t5'}, 8]], [[{'container': 'jpeg', 'exif': 7, 'xmp': '\t5'}, 7], [{'container': 'png', 'exif': 6, 'xmp': '7 '}, 6], [{'container': 'png', 'exif': 5, 'xmp': ' 8'}, 5], [{'container': 'png', 'xmp': '7 '}, 7], [{'container': 'heif', 'irot': 2}, 3], [{'container': 'heif', 'xmp': ' 8', 'irot': 1}, 8], [{'container': 'jpeg', 'xmp': 'x'}, 1], [{'container': 'png', 'exif': 2, 'xmp': '3\n', 'irot': 0, 'imir': 1}, 2]]]
labels = ["regression: EXIF over XMP precedence", "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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(meta):
    from_km = {(0, 0): 1, (0, 1): 2, (2, 0): 3, (2, 1): 4, (3, 1): 5, (1, 0): 6, (1, 1): 7, (3, 0): 8}
    c = meta.get('container')
    if c == 'heif':
        rot = meta.get('irot')
        mir = meta.get('imir')
        rot = 0 if rot is None else rot % 4
        if mir is None:
            return from_km[((-rot) % 4, 0)]
        if mir == 0:
            return from_km[(rot, 1)]
        return from_km[((rot + 2) % 4, 1)]
    x = meta.get('xmp')
    if c == 'png' and isinstance(x, str) and x.strip() in ('1', '2', '3', '4', '5', '6', '7', '8'):
        return int(x.strip())
    e = meta.get('exif')
    if isinstance(e, int) and not isinstance(e, bool) and 1 <= e <= 8:
        return e
    if isinstance(x, str):
        s = x.strip()
        if s in ('1', '2', '3', '4', '5', '6', '7', '8'):
            return int(s)
    return 1
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[{'container': 'png', 'exif': 1, 'xmp': '2'}, 1], [{'container': 'png', 'exif': 7, 'xmp': ' 8'}, 7], [{'container': 'png'}, 1], [{'container': 'jpeg', 'xmp': '2'}, 2], [{'container': 'heif', 'xmp': '\t5', 'irot': 3}, 6], [{'container': 'tiff'}, 1], [{'container': 'tiff', 'exif': True, 'xmp': '7 '}, 7], [{'container': 'png', 'exif': 7, 'xmp': '6'}, 7]], [[{'container': 'png', 'exif': 6, 'xmp': '7 '}, 6], [{'container': 'png', 'exif': 2, 'xmp': '\t5'}, 2], [{'container': 'png', 'xmp': '3\n'}, 3], [{'container': 'jpeg', 'exif': 0, 'xmp': '\t5'}, 5], [{'container': 'jpeg', 'exif': 0}, 1], [{'container': 'jpeg', 'xmp': '3\n'}, 3], [{'container': 'heif', 'exif': 5, 'xmp': ' 8', 'imir': 0}, 2], [{'container': 'jpeg', 'exif': 1, 'xmp': '3\n'}, 1]], [[{'container': 'tiff', 'exif': 8, 'xmp': '7 '}, 8], [{'container': 'png', 'exif': 7, 'xmp': ' 8'}, 7], [{'container': 'png', 'exif': 1, 'xmp': ' 8'}, 1], [{'container': 'jpeg', 'xmp': '7 '}, 7], [{'container': 'tiff'}, 1], [{'container': 'jpeg'}, 1], [{'container': 'jpeg', 'exif': 0}, 1], [{'container': 'jpeg', 'exif': 7, 'xmp': '6'}, 7]], [[{'container': 'jpeg', 'exif': 1, 'xmp': '\t5'}, 1], [{'container': 'png', 'exif': 5, 'xmp': '3\n'}, 5], [{'container': 'png', 'exif': 3, 'xmp': '7 '}, 3], [{'container': 'jpeg', 'exif': True, 'xmp': ' 8'}, 8], [{'container': 'jpeg', 'exif': 1}, 1], [{'container': 'heif', 'exif': 1, 'xmp': '7 ', 'irot': 2}, 3], [{'container': 'heif', 'xmp': '\t5'}, 1], [{'container': 'tiff', 'exif': 8, 'xmp': '\t5'}, 8]], [[{'container': 'jpeg', 'exif': 7, 'xmp': '\t5'}, 7], [{'container': 'png', 'exif': 6, 'xmp': '7 '}, 6], [{'container': 'png', 'exif': 5, 'xmp': ' 8'}, 5], [{'container': 'png', 'xmp': '7 '}, 7], [{'container': 'heif', 'irot': 2}, 3], [{'container': 'heif', 'xmp': ' 8', 'irot': 1}, 8], [{'container': 'jpeg', 'xmp': 'x'}, 1], [{'container': 'png', 'exif': 2, 'xmp': '3\n', 'irot': 0, 'imir': 1}, 2]]]
labels = ["regression: EXIF over XMP precedence", "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)

prompt:
After an in-camera rotation the photo displays with the old XMP orientation.

Resolve the displayed orientation tag from metadata sources. For HEIF, the container transforms are authoritative and EXIF/XMP are ignored: irot is anticlockwise quarter turns (default 0) applied first, then imir mirrors about the vertical axis (0, left-right) or the horizontal axis (1, top-bottom); the result is mapped to a tag through (k clockwise quarter turns after m mirrors) = {(0,0):1, (0,1):2, (2,0):3, (2,1):4, (3,1):5, (1,0):6, (1,1):7, (3,0):8}. For other containers a valid integer EXIF value 1..8 wins; otherwise an XMP string that is a single digit 1..8 after trimming whitespace; otherwise 1.

split: open-access


prompt:
Portrait phone videos play upside down: 90 and 270 degree tracks are exchanged.

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].

split: open-access


prompt:
Mirrored front-camera clips report the wrong rotation.

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].

split: open-access


prompt:
Any rotated or mirrored video is reported as unsupported.

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].

split: open-access


prompt:
A mirrored portrait clip shows the right rotation count only by chance and never flips.

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].

split: open-access


prompt:
Rotated videos are laid out in a landscape box and letterboxed.

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].

split: open-access


prompt:
Rotated 4:2:2 JPEGs lose the wrong number of edge pixels or keep a partial block that shifts the image.

Input [w, h, tag, sampling]. A lossless JPEG transform that bakes the orientation can only move whole MCUs (444: 8x8, 422: 16 wide x 8 high, 420: 16x16, 440: 8 wide x 16 high), so any partial MCU column or row that would move to the leading edge is trimmed. The tag decomposes into stored-space flips (fx, fy) followed by an optional transpose; fx trims the width and fy trims the height to a multiple of the MCU size. Invalid tags are treated as 1. Return the displayed [width, height], "refuse" when a trimmed side becomes 0, or "unknown-sampling".

split: open-access


prompt:
Mirrored JPEGs gain a strip of garbage pixels on the left edge.

Input [w, h, tag, sampling]. A lossless JPEG transform that bakes the orientation can only move whole MCUs (444: 8x8, 422: 16 wide x 8 high, 420: 16x16, 440: 8 wide x 16 high), so any partial MCU column or row that would move to the leading edge is trimmed. The tag decomposes into stored-space flips (fx, fy) followed by an optional transpose; fx trims the width and fy trims the height to a multiple of the MCU size. Invalid tags are treated as 1. Return the displayed [width, height], "refuse" when a trimmed side becomes 0, or "unknown-sampling".

split: open-access


prompt:
Clockwise-rotated photos keep a partial bottom MCU row that ends up as a garbage left column.

Input [w, h, tag, sampling]. A lossless JPEG transform that bakes the orientation can only move whole MCUs (444: 8x8, 422: 16 wide x 8 high, 420: 16x16, 440: 8 wide x 16 high), so any partial MCU column or row that would move to the leading edge is trimmed. The tag decomposes into stored-space flips (fx, fy) followed by an optional transpose; fx trims the width and fy trims the height to a multiple of the MCU size. Invalid tags are treated as 1. Return the displayed [width, height], "refuse" when a trimmed side becomes 0, or "unknown-sampling".

split: open-access


prompt:
Tiny images narrower than one MCU produce an empty output instead of a refusal.

Input [w, h, tag, sampling]. A lossless JPEG transform that bakes the orientation can only move whole MCUs (444: 8x8, 422: 16 wide x 8 high, 420: 16x16, 440: 8 wide x 16 high), so any partial MCU column or row that would move to the leading edge is trimmed. The tag decomposes into stored-space flips (fx, fy) followed by an optional transpose; fx trims the width and fy trims the height to a multiple of the MCU size. Invalid tags are treated as 1. Return the displayed [width, height], "refuse" when a trimmed side becomes 0, or "unknown-sampling".

split: open-access


prompt:
Tag 5 and 7 JPEGs are reported with stored width and height after a lossless bake.

Input [w, h, tag, sampling]. A lossless JPEG transform that bakes the orientation can only move whole MCUs (444: 8x8, 422: 16 wide x 8 high, 420: 16x16, 440: 8 wide x 16 high), so any partial MCU column or row that would move to the leading edge is trimmed. The tag decomposes into stored-space flips (fx, fy) followed by an optional transpose; fx trims the width and fy trims the height to a multiple of the MCU size. Invalid tags are treated as 1. Return the displayed [width, height], "refuse" when a trimmed side becomes 0, or "unknown-sampling".

split: open-access


prompt:
Photos taken with the phone lying almost flat get a random orientation from sensor noise.

Input [gx, gy, previous_rotation, camera] with gravity in milli-g in the portrait device frame (x right, y down). Device rotation: keep the previous bucket when the in-plane magnitude is below 300 mg or |gx| == |gy| (hysteresis); otherwise gy dominates -> 0 (gy > 0) or 180, gx dominates -> 90 (gx > 0) or 270. The back sensor is mounted at 90 degrees and needs (90 + r) mod 360 clockwise; the mirrored front sensor is mounted at 270 and needs (270 - r) mod 360 with the mirror bit. The tag comes from (quarter turns, mirror) via 1:(0,0) 2:(0,1) 3:(2,0) 4:(2,1) 5:(3,1) 6:(1,0) 7:(1,1) 8:(3,0). Return [tag, r].

split: open-access


prompt:
Holding the phone at exactly 45 degrees switches the tag on every shot.

Input [gx, gy, previous_rotation, camera] with gravity in milli-g in the portrait device frame (x right, y down). Device rotation: keep the previous bucket when the in-plane magnitude is below 300 mg or |gx| == |gy| (hysteresis); otherwise gy dominates -> 0 (gy > 0) or 180, gx dominates -> 90 (gx > 0) or 270. The back sensor is mounted at 90 degrees and needs (90 + r) mod 360 clockwise; the mirrored front sensor is mounted at 270 and needs (270 - r) mod 360 with the mirror bit. The tag comes from (quarter turns, mirror) via 1:(0,0) 2:(0,1) 3:(2,0) 4:(2,1) 5:(3,1) 6:(1,0) 7:(1,1) 8:(3,0). Return [tag, r].

split: open-access


prompt:
Landscape photos taken with the phone turned clockwise display upside down.

Input [gx, gy, previous_rotation, camera] with gravity in milli-g in the portrait device frame (x right, y down). Device rotation: keep the previous bucket when the in-plane magnitude is below 300 mg or |gx| == |gy| (hysteresis); otherwise gy dominates -> 0 (gy > 0) or 180, gx dominates -> 90 (gx > 0) or 270. The back sensor is mounted at 90 degrees and needs (90 + r) mod 360 clockwise; the mirrored front sensor is mounted at 270 and needs (270 - r) mod 360 with the mirror bit. The tag comes from (quarter turns, mirror) via 1:(0,0) 2:(0,1) 3:(2,0) 4:(2,1) 5:(3,1) 6:(1,0) 7:(1,1) 8:(3,0). Return [tag, r].

split: open-access


prompt:
Landscape selfies are saved upside down.

Input [gx, gy, previous_rotation, camera] with gravity in milli-g in the portrait device frame (x right, y down). Device rotation: keep the previous bucket when the in-plane magnitude is below 300 mg or |gx| == |gy| (hysteresis); otherwise gy dominates -> 0 (gy > 0) or 180, gx dominates -> 90 (gx > 0) or 270. The back sensor is mounted at 90 degrees and needs (90 + r) mod 360 clockwise; the mirrored front sensor is mounted at 270 and needs (270 - r) mod 360 with the mirror bit. The tag comes from (quarter turns, mirror) via 1:(0,0) 2:(0,1) 3:(2,0) 4:(2,1) 5:(3,1) 6:(1,0) 7:(1,1) 8:(3,0). Return [tag, r].

split: open-access


prompt:
Every back-camera photo is tagged a half turn away from upright.

Input [gx, gy, previous_rotation, camera] with gravity in milli-g in the portrait device frame (x right, y down). Device rotation: keep the previous bucket when the in-plane magnitude is below 300 mg or |gx| == |gy| (hysteresis); otherwise gy dominates -> 0 (gy > 0) or 180, gx dominates -> 90 (gx > 0) or 270. The back sensor is mounted at 90 degrees and needs (90 + r) mod 360 clockwise; the mirrored front sensor is mounted at 270 and needs (270 - r) mod 360 with the mirror bit. The tag comes from (quarter turns, mirror) via 1:(0,0) 2:(0,1) 3:(2,0) 4:(2,1) 5:(3,1) 6:(1,0) 7:(1,1) 8:(3,0). Return [tag, r].

split: open-access


prompt:
Selfies are saved with unmirrored tags, so text on shirts reads correctly in the preview but the file shows it reversed.

Input [gx, gy, previous_rotation, camera] with gravity in milli-g in the portrait device frame (x right, y down). Device rotation: keep the previous bucket when the in-plane magnitude is below 300 mg or |gx| == |gy| (hysteresis); otherwise gy dominates -> 0 (gy > 0) or 180, gx dominates -> 90 (gx > 0) or 270. The back sensor is mounted at 90 degrees and needs (90 + r) mod 360 clockwise; the mirrored front sensor is mounted at 270 and needs (270 - r) mod 360 with the mirror bit. The tag comes from (quarter turns, mirror) via 1:(0,0) 2:(0,1) 3:(2,0) 4:(2,1) 5:(3,1) 6:(1,0) 7:(1,1) 8:(3,0). Return [tag, r].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(meta):
    m = dict(meta)
    t = m.get('Orientation', 1)
    if t not in (1, 2, 3, 4, 5, 6, 7, 8):
        t = 1
    if t in (6, 8):
        for a, b in (('PixelXDimension', 'PixelYDimension'), ('ImageWidth', 'ImageLength'), ('XResolution', 'YResolution')):
            va, vb = m.pop(a, None), m.pop(b, None)
            if vb is not None:
                m[a] = vb
            if va is not None:
                m[b] = va
    if 'Orientation' in m:
        m['Orientation'] = 1
    if 'XMP:Orientation' in m:
        m['XMP:Orientation'] = '1'
    m.pop('ThumbOrientation', None)
    return [[k, m[k]] for k in sorted(m)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[{'Orientation': 5, 'PixelXDimension': 3085, 'PixelYDimension': 271, 'XResolution': 264, 'YResolution': 241, 'XMP:Orientation': '1', 'Make': 'Acme'}, [['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 271], ['PixelYDimension', 3085], ['XMP:Orientation', '1'], ['XResolution', 241], ['YResolution', 264]]], [{'Orientation': 5, 'PixelYDimension': 399, 'ImageLength': 3126, 'XResolution': 194, 'YResolution': 247, 'XMP:Orientation': '1', 'Make': 'Acme'}, [['ImageWidth', 3126], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 399], ['XMP:Orientation', '1'], ['XResolution', 247], ['YResolution', 194]]], [{'Orientation': 2, 'PixelXDimension': 3483, 'PixelYDimension': 682, 'ImageWidth': 1196, 'ImageLength': 620, 'XMP:Orientation': '6', 'ThumbOrientation': 6}, [['ImageLength', 620], ['ImageWidth', 1196], ['Orientation', 1], ['PixelXDimension', 3483], ['PixelYDimension', 682], ['XMP:Orientation', '1']]], [{'PixelXDimension': 3713, 'PixelYDimension': 3107, 'ImageWidth': 3378, 'ImageLength': 411, 'YResolution': 121}, [['ImageLength', 411], ['ImageWidth', 3378], ['PixelXDimension', 3713], ['PixelYDimension', 3107], ['YResolution', 121]]], [{'PixelXDimension': 3102, 'PixelYDimension': 263, 'ImageWidth': 1654, 'ImageLength': 2684}, [['ImageLength', 2684], ['ImageWidth', 1654], ['PixelXDimension', 3102], ['PixelYDimension', 263]]], [{'Orientation': 0, 'ImageWidth': 4760, 'ImageLength': 4173, 'XResolution': 182, 'Make': 'Acme'}, [['ImageLength', 4173], ['ImageWidth', 4760], ['Make', 'Acme'], ['Orientation', 1], ['XResolution', 182]]], [{'Orientation': 8, 'PixelXDimension': 3494, 'PixelYDimension': 3689, 'ImageLength': 3230, 'XResolution': 115, 'XMP:Orientation': '6', 'ThumbOrientation': 1, 'Make': 'Acme'}, [['ImageWidth', 3230], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 3689], ['PixelYDimension', 3494], ['XMP:Orientation', '1'], ['YResolution', 115]]], [{'Orientation': 7, 'PixelXDimension': 2873, 'PixelYDimension': 1191, 'ImageWidth': 2585, 'ImageLength': 4554}, [['ImageLength', 2585], ['ImageWidth', 4554], ['Orientation', 1], ['PixelXDimension', 1191], ['PixelYDimension', 2873]]]], [[{'Orientation': 7, 'PixelXDimension': 692, 'PixelYDimension': 4405, 'ImageWidth': 4045, 'ImageLength': 1814, 'XResolution': 327, 'YResolution': 215}, [['ImageLength', 4045], ['ImageWidth', 1814], ['Orientation', 1], ['PixelXDimension', 4405], ['PixelYDimension', 692], ['XResolution', 215], ['YResolution', 327]]], [{'Orientation': 5, 'ImageLength': 631}, [['ImageWidth', 631], ['Orientation', 1]]], [{'Orientation': 5, 'PixelXDimension': 1942, 'PixelYDimension': 3465, 'ImageWidth': 2311, 'ImageLength': 1274, 'XResolution': 348, 'YResolution': 400, 'ThumbOrientation': 6}, [['ImageLength', 2311], ['ImageWidth', 1274], ['Orientation', 1], ['PixelXDimension', 3465], ['PixelYDimension', 1942], ['XResolution', 400], ['YResolution', 348]]], [{'PixelXDimension': 611, 'PixelYDimension': 1679, 'ImageWidth': 4933, 'ImageLength': 565, 'XMP:Orientation': '1', 'ThumbOrientation': 6, 'Make': 'Acme'}, [['ImageLength', 565], ['ImageWidth', 4933], ['Make', 'Acme'], ['PixelXDimension', 611], ['PixelYDimension', 1679], ['XMP:Orientation', '1']]], [{'Orientation': 0, 'PixelYDimension': 4669, 'ImageWidth': 1458, 'ImageLength': 3813, 'XResolution': 143, 'YResolution': 303}, [['ImageLength', 3813], ['ImageWidth', 1458], ['Orientation', 1], ['PixelYDimension', 4669], ['XResolution', 143], ['YResolution', 303]]], [{'Orientation': 9, 'PixelXDimension': 1450, 'PixelYDimension': 714, 'ImageWidth': 3388, 'ImageLength': 3368, 'YResolution': 224, 'ThumbOrientation': 8, 'Make': 'Acme'}, [['ImageLength', 3368], ['ImageWidth', 3388], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 1450], ['PixelYDimension', 714], ['YResolution', 224]]], [{'PixelXDimension': 2501, 'ImageWidth': 4285, 'ImageLength': 4215, 'XResolution': 212, 'YResolution': 316, 'XMP:Orientation': '1', 'ThumbOrientation': 8}, [['ImageLength', 4215], ['ImageWidth', 4285], ['PixelXDimension', 2501], ['XMP:Orientation', '1'], ['XResolution', 212], ['YResolution', 316]]], [{'Orientation': 5, 'PixelXDimension': 3884, 'PixelYDimension': 595, 'ImageWidth': 537, 'ImageLength': 3701, 'XResolution': 241, 'YResolution': 324}, [['ImageLength', 537], ['ImageWidth', 3701], ['Orientation', 1], ['PixelXDimension', 595], ['PixelYDimension', 3884], ['XResolution', 324], ['YResolution', 241]]]], [[{'Orientation': 7, 'PixelXDimension': 3388, 'PixelYDimension': 4213, 'ImageWidth': 1704}, [['ImageLength', 1704], ['Orientation', 1], ['PixelXDimension', 4213], ['PixelYDimension', 3388]]], [{'Orientation': 5, 'PixelYDimension': 3841, 'ImageWidth': 4299, 'ThumbOrientation': 1, 'Make': 'Acme'}, [['ImageLength', 4299], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 3841]]], [{'Orientation': 5, 'PixelXDimension': 4630, 'PixelYDimension': 3429, 'ImageWidth': 2850, 'XResolution': 300, 'YResolution': 94}, [['ImageLength', 2850], ['Orientation', 1], ['PixelXDimension', 3429], ['PixelYDimension', 4630], ['XResolution', 94], ['YResolution', 300]]], [{'Orientation': 1, 'PixelYDimension': 4637, 'ImageWidth': 844, 'ImageLength': 4281, 'XResolution': 123, 'XMP:Orientation': '1'}, [['ImageLength', 4281], ['ImageWidth', 844], ['Orientation', 1], ['PixelYDimension', 4637], ['XMP:Orientation', '1'], ['XResolution', 123]]], [{'Orientation': 9, 'PixelXDimension': 2099, 'PixelYDimension': 2710, 'XResolution': 330, 'YResolution': 270, 'Make': 'Acme'}, [['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 2099], ['PixelYDimension', 2710], ['XResolution', 330], ['YResolution', 270]]], [{'Orientation': 8, 'PixelXDimension': 4471, 'PixelYDimension': 854, 'ImageWidth': 4083, 'ImageLength': 2109}, [['ImageLength', 4083], ['ImageWidth', 2109], ['Orientation', 1], ['PixelXDimension', 854], ['PixelYDimension', 4471]]], [{'Orientation': 6, 'PixelYDimension': 2320, 'ImageWidth': 4268, 'ImageLength': 4198, 'XResolution': 376, 'YResolution': 302, 'ThumbOrientation': 1}, [['ImageLength', 4268], ['ImageWidth', 4198], ['Orientation', 1], ['PixelXDimension', 2320], ['XResolution', 302], ['YResolution', 376]]], [{'Orientation': 5, 'PixelXDimension': 3958, 'PixelYDimension': 4449, 'ImageLength': 2850, 'XResolution': 243, 'YResolution': 171, 'XMP:Orientation': '8'}, [['ImageWidth', 2850], ['Orientation', 1], ['PixelXDimension', 4449], ['PixelYDimension', 3958], ['XMP:Orientation', '1'], ['XResolution', 171], ['YResolution', 243]]]], [[{'Orientation': 5, 'ImageWidth': 2748, 'YResolution': 177, 'XMP:Orientation': '3'}, [['ImageLength', 2748], ['Orientation', 1], ['XMP:Orientation', '1'], ['XResolution', 177]]], [{'Orientation': 5, 'PixelXDimension': 4104, 'PixelYDimension': 2711, 'ImageWidth': 409, 'ImageLength': 3239, 'YResolution': 300, 'ThumbOrientation': 6}, [['ImageLength', 409], ['ImageWidth', 3239], ['Orientation', 1], ['PixelXDimension', 2711], ['PixelYDimension', 4104], ['XResolution', 300]]], [{'Orientation': 2, 'PixelXDimension': 4921, 'PixelYDimension': 3995, 'ImageWidth': 1616, 'XResolution': 341, 'XMP:Orientation': '6'}, [['ImageWidth', 1616], ['Orientation', 1], ['PixelXDimension', 4921], ['PixelYDimension', 3995], ['XMP:Orientation', '1'], ['XResolution', 341]]], [{'PixelXDimension': 1405, 'PixelYDimension': 3697, 'ImageWidth': 3644, 'ImageLength': 3874, 'YResolution': 207, 'XMP:Orientation': '1'}, [['ImageLength', 3874], ['ImageWidth', 3644], ['PixelXDimension', 1405], ['PixelYDimension', 3697], ['XMP:Orientation', '1'], ['YResolution', 207]]], [{'Orientation': 8, 'ImageWidth': 4397, 'ImageLength': 4112, 'XResolution': 282, 'ThumbOrientation': 8, 'Make': 'Acme'}, [['ImageLength', 4397], ['ImageWidth', 4112], ['Make', 'Acme'], ['Orientation', 1], ['YResolution', 282]]], [{'Orientation': 6, 'PixelXDimension': 2290, 'ImageWidth': 1257, 'ImageLength': 2949, 'XResolution': 142, 'YResolution': 251, 'XMP:Orientation': '8'}, [['ImageLength', 1257], ['ImageWidth', 2949], ['Orientation', 1], ['PixelYDimension', 2290], ['XMP:Orientation', '1'], ['XResolution', 251], ['YResolution', 142]]], [{'Orientation': 3, 'PixelXDimension': 317, 'PixelYDimension': 1770, 'ImageWidth': 3506, 'XResolution': 328, 'YResolution': 264}, [['ImageWidth', 3506], ['Orientation', 1], ['PixelXDimension', 317], ['PixelYDimension', 1770], ['XResolution', 328], ['YResolution', 264]]], [{'Orientation': 5, 'ImageWidth': 4453, 'ImageLength': 2889, 'XResolution': 346, 'YResolution': 99, 'Make': 'Acme'}, [['ImageLength', 4453], ['ImageWidth', 2889], ['Make', 'Acme'], ['Orientation', 1], ['XResolution', 99], ['YResolution', 346]]]], [[{'Orientation': 5, 'PixelXDimension': 4580, 'XResolution': 206, 'YResolution': 392, 'XMP:Orientation': '8'}, [['Orientation', 1], ['PixelYDimension', 4580], ['XMP:Orientation', '1'], ['XResolution', 392], ['YResolution', 206]]], [{'Orientation': 5, 'PixelXDimension': 2631, 'PixelYDimension': 811, 'ImageLength': 4347, 'XResolution': 306, 'YResolution': 141, 'XMP:Orientation': '3'}, [['ImageWidth', 4347], ['Orientation', 1], ['PixelXDimension', 811], ['PixelYDimension', 2631], ['XMP:Orientation', '1'], ['XResolution', 141], ['YResolution', 306]]], [{'Orientation': 5, 'PixelXDimension': 1756, 'PixelYDimension': 1545, 'ImageWidth': 2249, 'ThumbOrientation': 6}, [['ImageLength', 2249], ['Orientation', 1], ['PixelXDimension', 1545], ['PixelYDimension', 1756]]], [{'Orientation': 2, 'PixelXDimension': 2531, 'PixelYDimension': 3008, 'ImageWidth': 4056, 'YResolution': 253}, [['ImageWidth', 4056], ['Orientation', 1], ['PixelXDimension', 2531], ['PixelYDimension', 3008], ['YResolution', 253]]], [{'Orientation': 4, 'PixelYDimension': 1209, 'ImageWidth': 3039, 'ImageLength': 4709, 'XResolution': 133, 'YResolution': 298, 'XMP:Orientation': '3', 'ThumbOrientation': 1, 'Make': 'Acme'}, [['ImageLength', 4709], ['ImageWidth', 3039], ['Make', 'Acme'], ['Orientation', 1], ['PixelYDimension', 1209], ['XMP:Orientation', '1'], ['XResolution', 133], ['YResolution', 298]]], [{'Orientation': 1, 'XResolution': 149, 'YResolution': 285, 'XMP:Orientation': '3', 'ThumbOrientation': 1}, [['Orientation', 1], ['XMP:Orientation', '1'], ['XResolution', 149], ['YResolution', 285]]], [{'PixelXDimension': 385, 'ImageWidth': 1099, 'ImageLength': 3036, 'XMP:Orientation': '8', 'ThumbOrientation': 8}, [['ImageLength', 3036], ['ImageWidth', 1099], ['PixelXDimension', 385], ['XMP:Orientation', '1']]], [{'Orientation': 5, 'PixelYDimension': 4522, 'XResolution': 74, 'YResolution': 301, 'ThumbOrientation': 6, 'Make': 'Acme'}, [['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 4522], ['XResolution', 301], ['YResolution', 74]]]]]
labels = ["regression: axis-swapping orientation set", "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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(meta):
    m = dict(meta)
    t = m.get('Orientation', 1)
    if t not in (1, 2, 3, 4, 5, 6, 7, 8):
        t = 1
    if t > 5:
        for a, b in (('PixelXDimension', 'PixelYDimension'), ('ImageWidth', 'ImageLength'), ('XResolution', 'YResolution')):
            va, vb = m.pop(a, None), m.pop(b, None)
            if vb is not None:
                m[a] = vb
            if va is not None:
                m[b] = va
    if 'Orientation' in m:
        m['Orientation'] = 1
    if 'XMP:Orientation' in m:
        m['XMP:Orientation'] = '1'
    m.pop('ThumbOrientation', None)
    return [[k, m[k]] for k in sorted(m)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[{'Orientation': 5, 'PixelXDimension': 3085, 'PixelYDimension': 271, 'XResolution': 264, 'YResolution': 241, 'XMP:Orientation': '1', 'Make': 'Acme'}, [['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 271], ['PixelYDimension', 3085], ['XMP:Orientation', '1'], ['XResolution', 241], ['YResolution', 264]]], [{'Orientation': 5, 'PixelYDimension': 399, 'ImageLength': 3126, 'XResolution': 194, 'YResolution': 247, 'XMP:Orientation': '1', 'Make': 'Acme'}, [['ImageWidth', 3126], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 399], ['XMP:Orientation', '1'], ['XResolution', 247], ['YResolution', 194]]], [{'Orientation': 2, 'PixelXDimension': 3483, 'PixelYDimension': 682, 'ImageWidth': 1196, 'ImageLength': 620, 'XMP:Orientation': '6', 'ThumbOrientation': 6}, [['ImageLength', 620], ['ImageWidth', 1196], ['Orientation', 1], ['PixelXDimension', 3483], ['PixelYDimension', 682], ['XMP:Orientation', '1']]], [{'PixelXDimension': 3713, 'PixelYDimension': 3107, 'ImageWidth': 3378, 'ImageLength': 411, 'YResolution': 121}, [['ImageLength', 411], ['ImageWidth', 3378], ['PixelXDimension', 3713], ['PixelYDimension', 3107], ['YResolution', 121]]], [{'PixelXDimension': 3102, 'PixelYDimension': 263, 'ImageWidth': 1654, 'ImageLength': 2684}, [['ImageLength', 2684], ['ImageWidth', 1654], ['PixelXDimension', 3102], ['PixelYDimension', 263]]], [{'Orientation': 0, 'ImageWidth': 4760, 'ImageLength': 4173, 'XResolution': 182, 'Make': 'Acme'}, [['ImageLength', 4173], ['ImageWidth', 4760], ['Make', 'Acme'], ['Orientation', 1], ['XResolution', 182]]], [{'Orientation': 8, 'PixelXDimension': 3494, 'PixelYDimension': 3689, 'ImageLength': 3230, 'XResolution': 115, 'XMP:Orientation': '6', 'ThumbOrientation': 1, 'Make': 'Acme'}, [['ImageWidth', 3230], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 3689], ['PixelYDimension', 3494], ['XMP:Orientation', '1'], ['YResolution', 115]]], [{'Orientation': 7, 'PixelXDimension': 2873, 'PixelYDimension': 1191, 'ImageWidth': 2585, 'ImageLength': 4554}, [['ImageLength', 2585], ['ImageWidth', 4554], ['Orientation', 1], ['PixelXDimension', 1191], ['PixelYDimension', 2873]]]], [[{'Orientation': 7, 'PixelXDimension': 692, 'PixelYDimension': 4405, 'ImageWidth': 4045, 'ImageLength': 1814, 'XResolution': 327, 'YResolution': 215}, [['ImageLength', 4045], ['ImageWidth', 1814], ['Orientation', 1], ['PixelXDimension', 4405], ['PixelYDimension', 692], ['XResolution', 215], ['YResolution', 327]]], [{'Orientation': 5, 'ImageLength': 631}, [['ImageWidth', 631], ['Orientation', 1]]], [{'Orientation': 5, 'PixelXDimension': 1942, 'PixelYDimension': 3465, 'ImageWidth': 2311, 'ImageLength': 1274, 'XResolution': 348, 'YResolution': 400, 'ThumbOrientation': 6}, [['ImageLength', 2311], ['ImageWidth', 1274], ['Orientation', 1], ['PixelXDimension', 3465], ['PixelYDimension', 1942], ['XResolution', 400], ['YResolution', 348]]], [{'PixelXDimension': 611, 'PixelYDimension': 1679, 'ImageWidth': 4933, 'ImageLength': 565, 'XMP:Orientation': '1', 'ThumbOrientation': 6, 'Make': 'Acme'}, [['ImageLength', 565], ['ImageWidth', 4933], ['Make', 'Acme'], ['PixelXDimension', 611], ['PixelYDimension', 1679], ['XMP:Orientation', '1']]], [{'Orientation': 0, 'PixelYDimension': 4669, 'ImageWidth': 1458, 'ImageLength': 3813, 'XResolution': 143, 'YResolution': 303}, [['ImageLength', 3813], ['ImageWidth', 1458], ['Orientation', 1], ['PixelYDimension', 4669], ['XResolution', 143], ['YResolution', 303]]], [{'Orientation': 9, 'PixelXDimension': 1450, 'PixelYDimension': 714, 'ImageWidth': 3388, 'ImageLength': 3368, 'YResolution': 224, 'ThumbOrientation': 8, 'Make': 'Acme'}, [['ImageLength', 3368], ['ImageWidth', 3388], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 1450], ['PixelYDimension', 714], ['YResolution', 224]]], [{'PixelXDimension': 2501, 'ImageWidth': 4285, 'ImageLength': 4215, 'XResolution': 212, 'YResolution': 316, 'XMP:Orientation': '1', 'ThumbOrientation': 8}, [['ImageLength', 4215], ['ImageWidth', 4285], ['PixelXDimension', 2501], ['XMP:Orientation', '1'], ['XResolution', 212], ['YResolution', 316]]], [{'Orientation': 5, 'PixelXDimension': 3884, 'PixelYDimension': 595, 'ImageWidth': 537, 'ImageLength': 3701, 'XResolution': 241, 'YResolution': 324}, [['ImageLength', 537], ['ImageWidth', 3701], ['Orientation', 1], ['PixelXDimension', 595], ['PixelYDimension', 3884], ['XResolution', 324], ['YResolution', 241]]]], [[{'Orientation': 7, 'PixelXDimension': 3388, 'PixelYDimension': 4213, 'ImageWidth': 1704}, [['ImageLength', 1704], ['Orientation', 1], ['PixelXDimension', 4213], ['PixelYDimension', 3388]]], [{'Orientation': 5, 'PixelYDimension': 3841, 'ImageWidth': 4299, 'ThumbOrientation': 1, 'Make': 'Acme'}, [['ImageLength', 4299], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 3841]]], [{'Orientation': 5, 'PixelXDimension': 4630, 'PixelYDimension': 3429, 'ImageWidth': 2850, 'XResolution': 300, 'YResolution': 94}, [['ImageLength', 2850], ['Orientation', 1], ['PixelXDimension', 3429], ['PixelYDimension', 4630], ['XResolution', 94], ['YResolution', 300]]], [{'Orientation': 1, 'PixelYDimension': 4637, 'ImageWidth': 844, 'ImageLength': 4281, 'XResolution': 123, 'XMP:Orientation': '1'}, [['ImageLength', 4281], ['ImageWidth', 844], ['Orientation', 1], ['PixelYDimension', 4637], ['XMP:Orientation', '1'], ['XResolution', 123]]], [{'Orientation': 9, 'PixelXDimension': 2099, 'PixelYDimension': 2710, 'XResolution': 330, 'YResolution': 270, 'Make': 'Acme'}, [['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 2099], ['PixelYDimension', 2710], ['XResolution', 330], ['YResolution', 270]]], [{'Orientation': 8, 'PixelXDimension': 4471, 'PixelYDimension': 854, 'ImageWidth': 4083, 'ImageLength': 2109}, [['ImageLength', 4083], ['ImageWidth', 2109], ['Orientation', 1], ['PixelXDimension', 854], ['PixelYDimension', 4471]]], [{'Orientation': 6, 'PixelYDimension': 2320, 'ImageWidth': 4268, 'ImageLength': 4198, 'XResolution': 376, 'YResolution': 302, 'ThumbOrientation': 1}, [['ImageLength', 4268], ['ImageWidth', 4198], ['Orientation', 1], ['PixelXDimension', 2320], ['XResolution', 302], ['YResolution', 376]]], [{'Orientation': 5, 'PixelXDimension': 3958, 'PixelYDimension': 4449, 'ImageLength': 2850, 'XResolution': 243, 'YResolution': 171, 'XMP:Orientation': '8'}, [['ImageWidth', 2850], ['Orientation', 1], ['PixelXDimension', 4449], ['PixelYDimension', 3958], ['XMP:Orientation', '1'], ['XResolution', 171], ['YResolution', 243]]]], [[{'Orientation': 5, 'ImageWidth': 2748, 'YResolution': 177, 'XMP:Orientation': '3'}, [['ImageLength', 2748], ['Orientation', 1], ['XMP:Orientation', '1'], ['XResolution', 177]]], [{'Orientation': 5, 'PixelXDimension': 4104, 'PixelYDimension': 2711, 'ImageWidth': 409, 'ImageLength': 3239, 'YResolution': 300, 'ThumbOrientation': 6}, [['ImageLength', 409], ['ImageWidth', 3239], ['Orientation', 1], ['PixelXDimension', 2711], ['PixelYDimension', 4104], ['XResolution', 300]]], [{'Orientation': 2, 'PixelXDimension': 4921, 'PixelYDimension': 3995, 'ImageWidth': 1616, 'XResolution': 341, 'XMP:Orientation': '6'}, [['ImageWidth', 1616], ['Orientation', 1], ['PixelXDimension', 4921], ['PixelYDimension', 3995], ['XMP:Orientation', '1'], ['XResolution', 341]]], [{'PixelXDimension': 1405, 'PixelYDimension': 3697, 'ImageWidth': 3644, 'ImageLength': 3874, 'YResolution': 207, 'XMP:Orientation': '1'}, [['ImageLength', 3874], ['ImageWidth', 3644], ['PixelXDimension', 1405], ['PixelYDimension', 3697], ['XMP:Orientation', '1'], ['YResolution', 207]]], [{'Orientation': 8, 'ImageWidth': 4397, 'ImageLength': 4112, 'XResolution': 282, 'ThumbOrientation': 8, 'Make': 'Acme'}, [['ImageLength', 4397], ['ImageWidth', 4112], ['Make', 'Acme'], ['Orientation', 1], ['YResolution', 282]]], [{'Orientation': 6, 'PixelXDimension': 2290, 'ImageWidth': 1257, 'ImageLength': 2949, 'XResolution': 142, 'YResolution': 251, 'XMP:Orientation': '8'}, [['ImageLength', 1257], ['ImageWidth', 2949], ['Orientation', 1], ['PixelYDimension', 2290], ['XMP:Orientation', '1'], ['XResolution', 251], ['YResolution', 142]]], [{'Orientation': 3, 'PixelXDimension': 317, 'PixelYDimension': 1770, 'ImageWidth': 3506, 'XResolution': 328, 'YResolution': 264}, [['ImageWidth', 3506], ['Orientation', 1], ['PixelXDimension', 317], ['PixelYDimension', 1770], ['XResolution', 328], ['YResolution', 264]]], [{'Orientation': 5, 'ImageWidth': 4453, 'ImageLength': 2889, 'XResolution': 346, 'YResolution': 99, 'Make': 'Acme'}, [['ImageLength', 4453], ['ImageWidth', 2889], ['Make', 'Acme'], ['Orientation', 1], ['XResolution', 99], ['YResolution', 346]]]], [[{'Orientation': 5, 'PixelXDimension': 4580, 'XResolution': 206, 'YResolution': 392, 'XMP:Orientation': '8'}, [['Orientation', 1], ['PixelYDimension', 4580], ['XMP:Orientation', '1'], ['XResolution', 392], ['YResolution', 206]]], [{'Orientation': 5, 'PixelXDimension': 2631, 'PixelYDimension': 811, 'ImageLength': 4347, 'XResolution': 306, 'YResolution': 141, 'XMP:Orientation': '3'}, [['ImageWidth', 4347], ['Orientation', 1], ['PixelXDimension', 811], ['PixelYDimension', 2631], ['XMP:Orientation', '1'], ['XResolution', 141], ['YResolution', 306]]], [{'Orientation': 5, 'PixelXDimension': 1756, 'PixelYDimension': 1545, 'ImageWidth': 2249, 'ThumbOrientation': 6}, [['ImageLength', 2249], ['Orientation', 1], ['PixelXDimension', 1545], ['PixelYDimension', 1756]]], [{'Orientation': 2, 'PixelXDimension': 2531, 'PixelYDimension': 3008, 'ImageWidth': 4056, 'YResolution': 253}, [['ImageWidth', 4056], ['Orientation', 1], ['PixelXDimension', 2531], ['PixelYDimension', 3008], ['YResolution', 253]]], [{'Orientation': 4, 'PixelYDimension': 1209, 'ImageWidth': 3039, 'ImageLength': 4709, 'XResolution': 133, 'YResolution': 298, 'XMP:Orientation': '3', 'ThumbOrientation': 1, 'Make': 'Acme'}, [['ImageLength', 4709], ['ImageWidth', 3039], ['Make', 'Acme'], ['Orientation', 1], ['PixelYDimension', 1209], ['XMP:Orientation', '1'], ['XResolution', 133], ['YResolution', 298]]], [{'Orientation': 1, 'XResolution': 149, 'YResolution': 285, 'XMP:Orientation': '3', 'ThumbOrientation': 1}, [['Orientation', 1], ['XMP:Orientation', '1'], ['XResolution', 149], ['YResolution', 285]]], [{'PixelXDimension': 385, 'ImageWidth': 1099, 'ImageLength': 3036, 'XMP:Orientation': '8', 'ThumbOrientation': 8}, [['ImageLength', 3036], ['ImageWidth', 1099], ['PixelXDimension', 385], ['XMP:Orientation', '1']]], [{'Orientation': 5, 'PixelYDimension': 4522, 'XResolution': 74, 'YResolution': 301, 'ThumbOrientation': 6, 'Make': 'Acme'}, [['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 4522], ['XResolution', 301], ['YResolution', 74]]]]]
labels = ["regression: axis-swapping orientation set", "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)

prompt:
Tag-5 and tag-7 photos report landscape pixel dimensions after being baked to portrait.

After pixels have been baked upright, rewrite the metadata dictionary. When the (valid) Orientation is 5..8, exchange PixelXDimension/PixelYDimension, ImageWidth/ImageLength and XResolution/YResolution, moving a lone member of a pair to its partner key. Invalid or missing Orientation values mean no swap. Orientation is set to 1 only if the key exists; XMP:Orientation, if present, becomes the string "1"; ThumbOrientation is removed because the thumbnail is regenerated. Return sorted [key, value] pairs.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(meta):
    m = dict(meta)
    t = m.get('Orientation', 1)
    if t not in (1, 2, 3, 4, 5, 6, 7, 8):
        t = 1
    if t >= 5:
        for a, b in (('PixelXDimension', 'PixelYDimension'), ('ImageWidth', 'ImageLength')):
            va, vb = m.pop(a, None), m.pop(b, None)
            if vb is not None:
                m[a] = vb
            if va is not None:
                m[b] = va
    if 'Orientation' in m:
        m['Orientation'] = 1
    if 'XMP:Orientation' in m:
        m['XMP:Orientation'] = '1'
    m.pop('ThumbOrientation', None)
    return [[k, m[k]] for k in sorted(m)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[{'Orientation': 5, 'PixelXDimension': 3085, 'PixelYDimension': 271, 'XResolution': 264, 'YResolution': 241, 'XMP:Orientation': '1', 'Make': 'Acme'}, [['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 271], ['PixelYDimension', 3085], ['XMP:Orientation', '1'], ['XResolution', 241], ['YResolution', 264]]], [{'Orientation': 8, 'PixelXDimension': 3494, 'PixelYDimension': 3689, 'ImageLength': 3230, 'XResolution': 115, 'XMP:Orientation': '6', 'ThumbOrientation': 1, 'Make': 'Acme'}, [['ImageWidth', 3230], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 3689], ['PixelYDimension', 3494], ['XMP:Orientation', '1'], ['YResolution', 115]]], [{'Orientation': 6, 'PixelYDimension': 2215, 'ImageWidth': 3631, 'YResolution': 135, 'XMP:Orientation': '6'}, [['ImageLength', 3631], ['Orientation', 1], ['PixelXDimension', 2215], ['XMP:Orientation', '1'], ['XResolution', 135]]], [{'Orientation': 2, 'PixelXDimension': 3483, 'PixelYDimension': 682, 'ImageWidth': 1196, 'ImageLength': 620, 'XMP:Orientation': '6', 'ThumbOrientation': 6}, [['ImageLength', 620], ['ImageWidth', 1196], ['Orientation', 1], ['PixelXDimension', 3483], ['PixelYDimension', 682], ['XMP:Orientation', '1']]], [{'PixelXDimension': 3713, 'PixelYDimension': 3107, 'ImageWidth': 3378, 'ImageLength': 411, 'YResolution': 121}, [['ImageLength', 411], ['ImageWidth', 3378], ['PixelXDimension', 3713], ['PixelYDimension', 3107], ['YResolution', 121]]], [{'PixelXDimension': 3102, 'PixelYDimension': 263, 'ImageWidth': 1654, 'ImageLength': 2684}, [['ImageLength', 2684], ['ImageWidth', 1654], ['PixelXDimension', 3102], ['PixelYDimension', 263]]], [{'Orientation': 0, 'ImageWidth': 4760, 'ImageLength': 4173, 'XResolution': 182, 'Make': 'Acme'}, [['ImageLength', 4173], ['ImageWidth', 4760], ['Make', 'Acme'], ['Orientation', 1], ['XResolution', 182]]], [{'Orientation': 6, 'PixelXDimension': 640, 'PixelYDimension': 1787, 'ImageWidth': 2123, 'XResolution': 295}, [['ImageLength', 2123], ['Orientation', 1], ['PixelXDimension', 1787], ['PixelYDimension', 640], ['YResolution', 295]]]], [[{'Orientation': 6, 'ImageWidth': 3998, 'XResolution': 106, 'YResolution': 377, 'ThumbOrientation': 1}, [['ImageLength', 3998], ['Orientation', 1], ['XResolution', 377], ['YResolution', 106]]], [{'Orientation': 8, 'PixelXDimension': 2357, 'ImageWidth': 4348, 'ImageLength': 2027, 'XResolution': 114, 'XMP:Orientation': '3', 'Make': 'Acme'}, [['ImageLength', 4348], ['ImageWidth', 2027], ['Make', 'Acme'], ['Orientation', 1], ['PixelYDimension', 2357], ['XMP:Orientation', '1'], ['YResolution', 114]]], [{'Orientation': 8, 'PixelXDimension': 4972, 'ImageWidth': 1028, 'ImageLength': 1331, 'XResolution': 377, 'YResolution': 144, 'XMP:Orientation': '6', 'ThumbOrientation': 8}, [['ImageLength', 1028], ['ImageWidth', 1331], ['Orientation', 1], ['PixelYDimension', 4972], ['XMP:Orientation', '1'], ['XResolution', 144], ['YResolution', 377]]], [{'PixelXDimension': 611, 'PixelYDimension': 1679, 'ImageWidth': 4933, 'ImageLength': 565, 'XMP:Orientation': '1', 'ThumbOrientation': 6, 'Make': 'Acme'}, [['ImageLength', 565], ['ImageWidth', 4933], ['Make', 'Acme'], ['PixelXDimension', 611], ['PixelYDimension', 1679], ['XMP:Orientation', '1']]], [{'Orientation': 0, 'PixelYDimension': 4669, 'ImageWidth': 1458, 'ImageLength': 3813, 'XResolution': 143, 'YResolution': 303}, [['ImageLength', 3813], ['ImageWidth', 1458], ['Orientation', 1], ['PixelYDimension', 4669], ['XResolution', 143], ['YResolution', 303]]], [{'Orientation': 9, 'PixelXDimension': 1450, 'PixelYDimension': 714, 'ImageWidth': 3388, 'ImageLength': 3368, 'YResolution': 224, 'ThumbOrientation': 8, 'Make': 'Acme'}, [['ImageLength', 3368], ['ImageWidth', 3388], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 1450], ['PixelYDimension', 714], ['YResolution', 224]]], [{'PixelXDimension': 2501, 'ImageWidth': 4285, 'ImageLength': 4215, 'XResolution': 212, 'YResolution': 316, 'XMP:Orientation': '1', 'ThumbOrientation': 8}, [['ImageLength', 4215], ['ImageWidth', 4285], ['PixelXDimension', 2501], ['XMP:Orientation', '1'], ['XResolution', 212], ['YResolution', 316]]], [{'Orientation': 6, 'PixelXDimension': 1877, 'PixelYDimension': 3253, 'ImageWidth': 1194, 'ImageLength': 3586, 'XResolution': 126, 'YResolution': 287, 'Make': 'Acme'}, [['ImageLength', 1194], ['ImageWidth', 3586], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 3253], ['PixelYDimension', 1877], ['XResolution', 287], ['YResolution', 126]]]], [[{'Orientation': 6, 'PixelXDimension': 1678, 'PixelYDimension': 2248, 'ImageWidth': 1422, 'ImageLength': 2871, 'YResolution': 243, 'XMP:Orientation': '1'}, [['ImageLength', 1422], ['ImageWidth', 2871], ['Orientation', 1], ['PixelXDimension', 2248], ['PixelYDimension', 1678], ['XMP:Orientation', '1'], ['XResolution', 243]]], [{'Orientation': 6, 'PixelYDimension': 2320, 'ImageWidth': 4268, 'ImageLength': 4198, 'XResolution': 376, 'YResolution': 302, 'ThumbOrientation': 1}, [['ImageLength', 4268], ['ImageWidth', 4198], ['Orientation', 1], ['PixelXDimension', 2320], ['XResolution', 302], ['YResolution', 376]]], [{'Orientation': 7, 'PixelXDimension': 1680, 'ImageLength': 3872, 'XResolution': 257, 'YResolution': 304}, [['ImageWidth', 3872], ['Orientation', 1], ['PixelYDimension', 1680], ['XResolution', 304], ['YResolution', 257]]], [{'Orientation': 1, 'PixelYDimension': 4637, 'ImageWidth': 844, 'ImageLength': 4281, 'XResolution': 123, 'XMP:Orientation': '1'}, [['ImageLength', 4281], ['ImageWidth', 844], ['Orientation', 1], ['PixelYDimension', 4637], ['XMP:Orientation', '1'], ['XResolution', 123]]], [{'Orientation': 9, 'PixelXDimension': 2099, 'PixelYDimension': 2710, 'XResolution': 330, 'YResolution': 270, 'Make': 'Acme'}, [['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 2099], ['PixelYDimension', 2710], ['XResolution', 330], ['YResolution', 270]]], [{'Orientation': 4, 'PixelYDimension': 2321, 'ImageWidth': 1769, 'XResolution': 96, 'YResolution': 275, 'XMP:Orientation': '3'}, [['ImageWidth', 1769], ['Orientation', 1], ['PixelYDimension', 2321], ['XMP:Orientation', '1'], ['XResolution', 96], ['YResolution', 275]]], [{'Orientation': 0, 'PixelXDimension': 3801, 'PixelYDimension': 833, 'ImageWidth': 655, 'ImageLength': 2578, 'XResolution': 340}, [['ImageLength', 2578], ['ImageWidth', 655], ['Orientation', 1], ['PixelXDimension', 3801], ['PixelYDimension', 833], ['XResolution', 340]]], [{'Orientation': 5, 'PixelXDimension': 3958, 'PixelYDimension': 4449, 'ImageLength': 2850, 'XResolution': 243, 'YResolution': 171, 'XMP:Orientation': '8'}, [['ImageWidth', 2850], ['Orientation', 1], ['PixelXDimension', 4449], ['PixelYDimension', 3958], ['XMP:Orientation', '1'], ['XResolution', 171], ['YResolution', 243]]]], [[{'Orientation': 5, 'ImageWidth': 4453, 'ImageLength': 2889, 'XResolution': 346, 'YResolution': 99, 'Make': 'Acme'}, [['ImageLength', 4453], ['ImageWidth', 2889], ['Make', 'Acme'], ['Orientation', 1], ['XResolution', 99], ['YResolution', 346]]], [{'Orientation': 8, 'PixelXDimension': 2766, 'PixelYDimension': 597, 'ImageWidth': 1819, 'XResolution': 357, 'YResolution': 78}, [['ImageLength', 1819], ['Orientation', 1], ['PixelXDimension', 597], ['PixelYDimension', 2766], ['XResolution', 78], ['YResolution', 357]]], [{'Orientation': 2, 'PixelXDimension': 4921, 'PixelYDimension': 3995, 'ImageWidth': 1616, 'XResolution': 341, 'XMP:Orientation': '6'}, [['ImageWidth', 1616], ['Orientation', 1], ['PixelXDimension', 4921], ['PixelYDimension', 3995], ['XMP:Orientation', '1'], ['XResolution', 341]]], [{'PixelXDimension': 1405, 'PixelYDimension': 3697, 'ImageWidth': 3644, 'ImageLength': 3874, 'YResolution': 207, 'XMP:Orientation': '1'}, [['ImageLength', 3874], ['ImageWidth', 3644], ['PixelXDimension', 1405], ['PixelYDimension', 3697], ['XMP:Orientation', '1'], ['YResolution', 207]]], [{'Orientation': 3, 'PixelXDimension': 317, 'PixelYDimension': 1770, 'ImageWidth': 3506, 'XResolution': 328, 'YResolution': 264}, [['ImageWidth', 3506], ['Orientation', 1], ['PixelXDimension', 317], ['PixelYDimension', 1770], ['XResolution', 328], ['YResolution', 264]]], [{'Orientation': 1, 'PixelXDimension': 717, 'ImageWidth': 4963, 'ImageLength': 644, 'XResolution': 201, 'YResolution': 305, 'XMP:Orientation': '1'}, [['ImageLength', 644], ['ImageWidth', 4963], ['Orientation', 1], ['PixelXDimension', 717], ['XMP:Orientation', '1'], ['XResolution', 201], ['YResolution', 305]]], [{'Orientation': 3, 'PixelXDimension': 1081, 'PixelYDimension': 160, 'ImageWidth': 4451, 'ImageLength': 4974, 'XResolution': 180, 'YResolution': 379, 'XMP:Orientation': '8', 'ThumbOrientation': 8, 'Make': 'Acme'}, [['ImageLength', 4974], ['ImageWidth', 4451], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 1081], ['PixelYDimension', 160], ['XMP:Orientation', '1'], ['XResolution', 180], ['YResolution', 379]]], [{'Orientation': 8, 'ImageWidth': 4397, 'ImageLength': 4112, 'XResolution': 282, 'ThumbOrientation': 8, 'Make': 'Acme'}, [['ImageLength', 4397], ['ImageWidth', 4112], ['Make', 'Acme'], ['Orientation', 1], ['YResolution', 282]]]], [[{'Orientation': 8, 'PixelXDimension': 522, 'XResolution': 367, 'XMP:Orientation': '3'}, [['Orientation', 1], ['PixelYDimension', 522], ['XMP:Orientation', '1'], ['YResolution', 367]]], [{'Orientation': 8, 'PixelXDimension': 1349, 'PixelYDimension': 887, 'ImageLength': 4267, 'ThumbOrientation': 8}, [['ImageWidth', 4267], ['Orientation', 1], ['PixelXDimension', 887], ['PixelYDimension', 1349]]], [{'Orientation': 5, 'PixelXDimension': 3532, 'PixelYDimension': 3753, 'ImageWidth': 1702, 'XResolution': 370, 'XMP:Orientation': '8'}, [['ImageLength', 1702], ['Orientation', 1], ['PixelXDimension', 3753], ['PixelYDimension', 3532], ['XMP:Orientation', '1'], ['YResolution', 370]]], [{'Orientation': 1, 'XResolution': 149, 'YResolution': 285, 'XMP:Orientation': '3', 'ThumbOrientation': 1}, [['Orientation', 1], ['XMP:Orientation', '1'], ['XResolution', 149], ['YResolution', 285]]], [{'PixelXDimension': 385, 'ImageWidth': 1099, 'ImageLength': 3036, 'XMP:Orientation': '8', 'ThumbOrientation': 8}, [['ImageLength', 3036], ['ImageWidth', 1099], ['PixelXDimension', 385], ['XMP:Orientation', '1']]], [{'Orientation': 9, 'PixelXDimension': 4218, 'PixelYDimension': 1148, 'ImageWidth': 1525, 'XResolution': 171, 'YResolution': 311, 'XMP:Orientation': '6', 'Make': 'Acme'}, [['ImageWidth', 1525], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 4218], ['PixelYDimension', 1148], ['XMP:Orientation', '1'], ['XResolution', 171], ['YResolution', 311]]], [{'Orientation': 0, 'PixelXDimension': 1579, 'PixelYDimension': 2508, 'ImageWidth': 104, 'ImageLength': 3875, 'XResolution': 311, 'YResolution': 283, 'ThumbOrientation': 8}, [['ImageLength', 3875], ['ImageWidth', 104], ['Orientation', 1], ['PixelXDimension', 1579], ['PixelYDimension', 2508], ['XResolution', 311], ['YResolution', 283]]], [{'Orientation': 5, 'PixelXDimension': 2301, 'PixelYDimension': 1707, 'ImageWidth': 1166, 'ImageLength': 3560, 'XResolution': 383, 'ThumbOrientation': 8}, [['ImageLength', 1166], ['ImageWidth', 3560], ['Orientation', 1], ['PixelXDimension', 1707], ['PixelYDimension', 2301], ['YResolution', 383]]]]]
labels = ["regression: resolution pair swap", "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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(meta):
    m = dict(meta)
    t = m.get('Orientation', 1)
    if t not in (1, 2, 3, 4, 5, 6, 7, 8):
        t = 1
    if t >= 5:
        for a, b in (('PixelXDimension', 'PixelYDimension'), ('XResolution', 'YResolution')):
            va, vb = m.pop(a, None), m.pop(b, None)
            if vb is not None:
                m[a] = vb
            if va is not None:
                m[b] = va
    if 'Orientation' in m:
        m['Orientation'] = 1
    if 'XMP:Orientation' in m:
        m['XMP:Orientation'] = '1'
    m.pop('ThumbOrientation', None)
    return [[k, m[k]] for k in sorted(m)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[{'Orientation': 5, 'PixelXDimension': 3085, 'PixelYDimension': 271, 'XResolution': 264, 'YResolution': 241, 'XMP:Orientation': '1', 'Make': 'Acme'}, [['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 271], ['PixelYDimension', 3085], ['XMP:Orientation', '1'], ['XResolution', 241], ['YResolution', 264]]], [{'Orientation': 8, 'PixelXDimension': 3494, 'PixelYDimension': 3689, 'ImageLength': 3230, 'XResolution': 115, 'XMP:Orientation': '6', 'ThumbOrientation': 1, 'Make': 'Acme'}, [['ImageWidth', 3230], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 3689], ['PixelYDimension', 3494], ['XMP:Orientation', '1'], ['YResolution', 115]]], [{'Orientation': 6, 'PixelYDimension': 2215, 'ImageWidth': 3631, 'YResolution': 135, 'XMP:Orientation': '6'}, [['ImageLength', 3631], ['Orientation', 1], ['PixelXDimension', 2215], ['XMP:Orientation', '1'], ['XResolution', 135]]], [{'Orientation': 2, 'PixelXDimension': 3483, 'PixelYDimension': 682, 'ImageWidth': 1196, 'ImageLength': 620, 'XMP:Orientation': '6', 'ThumbOrientation': 6}, [['ImageLength', 620], ['ImageWidth', 1196], ['Orientation', 1], ['PixelXDimension', 3483], ['PixelYDimension', 682], ['XMP:Orientation', '1']]], [{'PixelXDimension': 3713, 'PixelYDimension': 3107, 'ImageWidth': 3378, 'ImageLength': 411, 'YResolution': 121}, [['ImageLength', 411], ['ImageWidth', 3378], ['PixelXDimension', 3713], ['PixelYDimension', 3107], ['YResolution', 121]]], [{'PixelXDimension': 3102, 'PixelYDimension': 263, 'ImageWidth': 1654, 'ImageLength': 2684}, [['ImageLength', 2684], ['ImageWidth', 1654], ['PixelXDimension', 3102], ['PixelYDimension', 263]]], [{'Orientation': 0, 'ImageWidth': 4760, 'ImageLength': 4173, 'XResolution': 182, 'Make': 'Acme'}, [['ImageLength', 4173], ['ImageWidth', 4760], ['Make', 'Acme'], ['Orientation', 1], ['XResolution', 182]]], [{'Orientation': 6, 'PixelXDimension': 640, 'PixelYDimension': 1787, 'ImageWidth': 2123, 'XResolution': 295}, [['ImageLength', 2123], ['Orientation', 1], ['PixelXDimension', 1787], ['PixelYDimension', 640], ['YResolution', 295]]]], [[{'Orientation': 6, 'ImageWidth': 3998, 'XResolution': 106, 'YResolution': 377, 'ThumbOrientation': 1}, [['ImageLength', 3998], ['Orientation', 1], ['XResolution', 377], ['YResolution', 106]]], [{'Orientation': 8, 'PixelXDimension': 2357, 'ImageWidth': 4348, 'ImageLength': 2027, 'XResolution': 114, 'XMP:Orientation': '3', 'Make': 'Acme'}, [['ImageLength', 4348], ['ImageWidth', 2027], ['Make', 'Acme'], ['Orientation', 1], ['PixelYDimension', 2357], ['XMP:Orientation', '1'], ['YResolution', 114]]], [{'Orientation': 8, 'PixelXDimension': 4972, 'ImageWidth': 1028, 'ImageLength': 1331, 'XResolution': 377, 'YResolution': 144, 'XMP:Orientation': '6', 'ThumbOrientation': 8}, [['ImageLength', 1028], ['ImageWidth', 1331], ['Orientation', 1], ['PixelYDimension', 4972], ['XMP:Orientation', '1'], ['XResolution', 144], ['YResolution', 377]]], [{'PixelXDimension': 611, 'PixelYDimension': 1679, 'ImageWidth': 4933, 'ImageLength': 565, 'XMP:Orientation': '1', 'ThumbOrientation': 6, 'Make': 'Acme'}, [['ImageLength', 565], ['ImageWidth', 4933], ['Make', 'Acme'], ['PixelXDimension', 611], ['PixelYDimension', 1679], ['XMP:Orientation', '1']]], [{'Orientation': 0, 'PixelYDimension': 4669, 'ImageWidth': 1458, 'ImageLength': 3813, 'XResolution': 143, 'YResolution': 303}, [['ImageLength', 3813], ['ImageWidth', 1458], ['Orientation', 1], ['PixelYDimension', 4669], ['XResolution', 143], ['YResolution', 303]]], [{'Orientation': 9, 'PixelXDimension': 1450, 'PixelYDimension': 714, 'ImageWidth': 3388, 'ImageLength': 3368, 'YResolution': 224, 'ThumbOrientation': 8, 'Make': 'Acme'}, [['ImageLength', 3368], ['ImageWidth', 3388], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 1450], ['PixelYDimension', 714], ['YResolution', 224]]], [{'PixelXDimension': 2501, 'ImageWidth': 4285, 'ImageLength': 4215, 'XResolution': 212, 'YResolution': 316, 'XMP:Orientation': '1', 'ThumbOrientation': 8}, [['ImageLength', 4215], ['ImageWidth', 4285], ['PixelXDimension', 2501], ['XMP:Orientation', '1'], ['XResolution', 212], ['YResolution', 316]]], [{'Orientation': 6, 'PixelXDimension': 1877, 'PixelYDimension': 3253, 'ImageWidth': 1194, 'ImageLength': 3586, 'XResolution': 126, 'YResolution': 287, 'Make': 'Acme'}, [['ImageLength', 1194], ['ImageWidth', 3586], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 3253], ['PixelYDimension', 1877], ['XResolution', 287], ['YResolution', 126]]]], [[{'Orientation': 6, 'PixelXDimension': 1678, 'PixelYDimension': 2248, 'ImageWidth': 1422, 'ImageLength': 2871, 'YResolution': 243, 'XMP:Orientation': '1'}, [['ImageLength', 1422], ['ImageWidth', 2871], ['Orientation', 1], ['PixelXDimension', 2248], ['PixelYDimension', 1678], ['XMP:Orientation', '1'], ['XResolution', 243]]], [{'Orientation': 6, 'PixelYDimension': 2320, 'ImageWidth': 4268, 'ImageLength': 4198, 'XResolution': 376, 'YResolution': 302, 'ThumbOrientation': 1}, [['ImageLength', 4268], ['ImageWidth', 4198], ['Orientation', 1], ['PixelXDimension', 2320], ['XResolution', 302], ['YResolution', 376]]], [{'Orientation': 7, 'PixelXDimension': 1680, 'ImageLength': 3872, 'XResolution': 257, 'YResolution': 304}, [['ImageWidth', 3872], ['Orientation', 1], ['PixelYDimension', 1680], ['XResolution', 304], ['YResolution', 257]]], [{'Orientation': 1, 'PixelYDimension': 4637, 'ImageWidth': 844, 'ImageLength': 4281, 'XResolution': 123, 'XMP:Orientation': '1'}, [['ImageLength', 4281], ['ImageWidth', 844], ['Orientation', 1], ['PixelYDimension', 4637], ['XMP:Orientation', '1'], ['XResolution', 123]]], [{'Orientation': 9, 'PixelXDimension': 2099, 'PixelYDimension': 2710, 'XResolution': 330, 'YResolution': 270, 'Make': 'Acme'}, [['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 2099], ['PixelYDimension', 2710], ['XResolution', 330], ['YResolution', 270]]], [{'Orientation': 4, 'PixelYDimension': 2321, 'ImageWidth': 1769, 'XResolution': 96, 'YResolution': 275, 'XMP:Orientation': '3'}, [['ImageWidth', 1769], ['Orientation', 1], ['PixelYDimension', 2321], ['XMP:Orientation', '1'], ['XResolution', 96], ['YResolution', 275]]], [{'Orientation': 0, 'PixelXDimension': 3801, 'PixelYDimension': 833, 'ImageWidth': 655, 'ImageLength': 2578, 'XResolution': 340}, [['ImageLength', 2578], ['ImageWidth', 655], ['Orientation', 1], ['PixelXDimension', 3801], ['PixelYDimension', 833], ['XResolution', 340]]], [{'Orientation': 5, 'PixelXDimension': 3958, 'PixelYDimension': 4449, 'ImageLength': 2850, 'XResolution': 243, 'YResolution': 171, 'XMP:Orientation': '8'}, [['ImageWidth', 2850], ['Orientation', 1], ['PixelXDimension', 4449], ['PixelYDimension', 3958], ['XMP:Orientation', '1'], ['XResolution', 171], ['YResolution', 243]]]], [[{'Orientation': 5, 'ImageWidth': 4453, 'ImageLength': 2889, 'XResolution': 346, 'YResolution': 99, 'Make': 'Acme'}, [['ImageLength', 4453], ['ImageWidth', 2889], ['Make', 'Acme'], ['Orientation', 1], ['XResolution', 99], ['YResolution', 346]]], [{'Orientation': 8, 'PixelXDimension': 2766, 'PixelYDimension': 597, 'ImageWidth': 1819, 'XResolution': 357, 'YResolution': 78}, [['ImageLength', 1819], ['Orientation', 1], ['PixelXDimension', 597], ['PixelYDimension', 2766], ['XResolution', 78], ['YResolution', 357]]], [{'Orientation': 2, 'PixelXDimension': 4921, 'PixelYDimension': 3995, 'ImageWidth': 1616, 'XResolution': 341, 'XMP:Orientation': '6'}, [['ImageWidth', 1616], ['Orientation', 1], ['PixelXDimension', 4921], ['PixelYDimension', 3995], ['XMP:Orientation', '1'], ['XResolution', 341]]], [{'PixelXDimension': 1405, 'PixelYDimension': 3697, 'ImageWidth': 3644, 'ImageLength': 3874, 'YResolution': 207, 'XMP:Orientation': '1'}, [['ImageLength', 3874], ['ImageWidth', 3644], ['PixelXDimension', 1405], ['PixelYDimension', 3697], ['XMP:Orientation', '1'], ['YResolution', 207]]], [{'Orientation': 3, 'PixelXDimension': 317, 'PixelYDimension': 1770, 'ImageWidth': 3506, 'XResolution': 328, 'YResolution': 264}, [['ImageWidth', 3506], ['Orientation', 1], ['PixelXDimension', 317], ['PixelYDimension', 1770], ['XResolution', 328], ['YResolution', 264]]], [{'Orientation': 1, 'PixelXDimension': 717, 'ImageWidth': 4963, 'ImageLength': 644, 'XResolution': 201, 'YResolution': 305, 'XMP:Orientation': '1'}, [['ImageLength', 644], ['ImageWidth', 4963], ['Orientation', 1], ['PixelXDimension', 717], ['XMP:Orientation', '1'], ['XResolution', 201], ['YResolution', 305]]], [{'Orientation': 3, 'PixelXDimension': 1081, 'PixelYDimension': 160, 'ImageWidth': 4451, 'ImageLength': 4974, 'XResolution': 180, 'YResolution': 379, 'XMP:Orientation': '8', 'ThumbOrientation': 8, 'Make': 'Acme'}, [['ImageLength', 4974], ['ImageWidth', 4451], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 1081], ['PixelYDimension', 160], ['XMP:Orientation', '1'], ['XResolution', 180], ['YResolution', 379]]], [{'Orientation': 8, 'ImageWidth': 4397, 'ImageLength': 4112, 'XResolution': 282, 'ThumbOrientation': 8, 'Make': 'Acme'}, [['ImageLength', 4397], ['ImageWidth', 4112], ['Make', 'Acme'], ['Orientation', 1], ['YResolution', 282]]]], [[{'Orientation': 8, 'PixelXDimension': 522, 'XResolution': 367, 'XMP:Orientation': '3'}, [['Orientation', 1], ['PixelYDimension', 522], ['XMP:Orientation', '1'], ['YResolution', 367]]], [{'Orientation': 8, 'PixelXDimension': 1349, 'PixelYDimension': 887, 'ImageLength': 4267, 'ThumbOrientation': 8}, [['ImageWidth', 4267], ['Orientation', 1], ['PixelXDimension', 887], ['PixelYDimension', 1349]]], [{'Orientation': 5, 'PixelXDimension': 3532, 'PixelYDimension': 3753, 'ImageWidth': 1702, 'XResolution': 370, 'XMP:Orientation': '8'}, [['ImageLength', 1702], ['Orientation', 1], ['PixelXDimension', 3753], ['PixelYDimension', 3532], ['XMP:Orientation', '1'], ['YResolution', 370]]], [{'Orientation': 1, 'XResolution': 149, 'YResolution': 285, 'XMP:Orientation': '3', 'ThumbOrientation': 1}, [['Orientation', 1], ['XMP:Orientation', '1'], ['XResolution', 149], ['YResolution', 285]]], [{'PixelXDimension': 385, 'ImageWidth': 1099, 'ImageLength': 3036, 'XMP:Orientation': '8', 'ThumbOrientation': 8}, [['ImageLength', 3036], ['ImageWidth', 1099], ['PixelXDimension', 385], ['XMP:Orientation', '1']]], [{'Orientation': 9, 'PixelXDimension': 4218, 'PixelYDimension': 1148, 'ImageWidth': 1525, 'XResolution': 171, 'YResolution': 311, 'XMP:Orientation': '6', 'Make': 'Acme'}, [['ImageWidth', 1525], ['Make', 'Acme'], ['Orientation', 1], ['PixelXDimension', 4218], ['PixelYDimension', 1148], ['XMP:Orientation', '1'], ['XResolution', 171], ['YResolution', 311]]], [{'Orientation': 0, 'PixelXDimension': 1579, 'PixelYDimension': 2508, 'ImageWidth': 104, 'ImageLength': 3875, 'XResolution': 311, 'YResolution': 283, 'ThumbOrientation': 8}, [['ImageLength', 3875], ['ImageWidth', 104], ['Orientation', 1], ['PixelXDimension', 1579], ['PixelYDimension', 2508], ['XResolution', 311], ['YResolution', 283]]], [{'Orientation': 5, 'PixelXDimension': 2301, 'PixelYDimension': 1707, 'ImageWidth': 1166, 'ImageLength': 3560, 'XResolution': 383, 'ThumbOrientation': 8}, [['ImageLength', 1166], ['ImageWidth', 3560], ['Orientation', 1], ['PixelXDimension', 1707], ['PixelYDimension', 2301], ['YResolution', 383]]]]]
labels = ["regression: resolution pair swap", "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)

prompt:
Anisotropic scans print stretched after their pixels were rotated upright.

After pixels have been baked upright, rewrite the metadata dictionary. When the (valid) Orientation is 5..8, exchange PixelXDimension/PixelYDimension, ImageWidth/ImageLength and XResolution/YResolution, moving a lone member of a pair to its partner key. Invalid or missing Orientation values mean no swap. Orientation is set to 1 only if the key exists; XMP:Orientation, if present, becomes the string "1"; ThumbOrientation is removed because the thumbnail is regenerated. Return sorted [key, value] pairs.

split: open-access