Skip to content

UI/jpeg exif orientation#24196

Merged
ServeurpersoCom merged 3 commits into
ggml-org:masterfrom
ServeurpersoCom:ui/jpeg-exif-orientation
Jun 12, 2026
Merged

UI/jpeg exif orientation#24196
ServeurpersoCom merged 3 commits into
ggml-org:masterfrom
ServeurpersoCom:ui/jpeg-exif-orientation

Conversation

@ServeurpersoCom

Copy link
Copy Markdown
Contributor

Overview

stb_image in mtmd ignores EXIF, so rotated smartphone photos reach the model sideways. The webui now reads the orientation tag at send time and bakes the rotation through the existing capImageDataURLSize canvas pass. At most one re-encode per image: capped images come out upright for free, uncapped rotated ones get a single redraw, everything else passes through untouched.

Additional information

Tested across orientations 1/3/5/6/8 with Qwen3.6 VLM, with and without resize.

Unit test covers the EXIF parser against synthetic JPEGs (both endiannesses, malformed inputs). Browser test covers capImageDataURLSize end to end in chromium with real fixtures: upright pixels, expected dimensions, strict passthrough when nothing needs rewriting.

Closes #20870

Prompt for manual E2E tests: "Which color is the top edge, and which direction does the arrow point?"
Manuals-E2E-Tests.zip
Expected answer for all images: red / up.

Requirements

stb_image in mtmd ignores exif metadata, so rotated smartphone photos
reach the model with raw pixel orientation. The webui now reads the
exif orientation tag at send time and feeds it into the existing
capImageDataURLSize canvas pass: the browser applies the rotation when
decoding, so capped images come out upright for free, and images under
the cap threshold get a single plain redraw when orientation > 1.

At most one re-encode ever happens per image. Upright jpegs with
capping disabled pass through untouched, bit perfect.

Adds jpeg-orientation.ts with a minimal exif parser working on a
bounded base64 prefix (both endianness, returns 1 on any malformed
input) and unit tests against handcrafted jpeg byte streams.
Covers capImageDataURLSize end to end in chromium with real Pillow
generated jpeg fixtures across exif orientations 1/3/5/6/8: upright
quadrant colors checked pixel-wise, expected dimensions with and
without capping, no orientation tag left in the output, and strict
passthrough when nothing needs rewriting.
@allozaur allozaur requested a review from ggerganov June 11, 2026 12:06
@ServeurpersoCom ServeurpersoCom merged commit 6471e3c into ggml-org:master Jun 12, 2026
6 checks passed
DFveloper added a commit to DFveloper/aikar-engine that referenced this pull request Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Eval bug: server/MTMD ignores jpeg EXIF orientation metadata

3 participants