* ui: bake jpeg exif orientation into uploaded images 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. * ui: move jpeg exif constants into lib/constants * ui: add browser test for jpeg orientation and capping 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.
31 lines
948 B
TypeScript
31 lines
948 B
TypeScript
/**
|
|
* JPEG and EXIF binary format constants for orientation parsing.
|
|
*/
|
|
|
|
/** Bytes of file prefix to scan, the APP1 EXIF segment sits near the start */
|
|
export const EXIF_SCAN_BYTE_LIMIT = 128 * 1024;
|
|
|
|
/** JPEG start of image marker */
|
|
export const JPEG_SOI_MARKER = 0xffd8;
|
|
|
|
/** APP1 segment marker byte, carries the EXIF payload */
|
|
export const APP1_MARKER = 0xe1;
|
|
|
|
/** Start of scan marker byte, compressed data begins and no EXIF follows */
|
|
export const SOS_MARKER = 0xda;
|
|
|
|
/** "Exif" signature opening the APP1 payload, big endian uint32 */
|
|
export const EXIF_SIGNATURE = 0x45786966;
|
|
|
|
/** TIFF byte order mark for little endian ("II") */
|
|
export const TIFF_LITTLE_ENDIAN = 0x4949;
|
|
|
|
/** TIFF magic number following the byte order mark */
|
|
export const TIFF_MAGIC = 42;
|
|
|
|
/** EXIF tag id holding the orientation value */
|
|
export const EXIF_ORIENTATION_TAG = 0x0112;
|
|
|
|
/** Size in bytes of one IFD directory entry */
|
|
export const IFD_ENTRY_SIZE = 12;
|