# JPEG Segments _(no submodules)_ ## Purpose Parses the segment structure of a JPEG file and identifies metadata segments (EXIF, XMP, IPTC). JPEG is a container format: each segment is introduced by a 2-byte marker (`0xFF` + type), followed by a 2-byte big-endian length and payload. This module provides the structural parser that upstream readers (EXIF, IPTC, XMP) rely on to locate their data. ## Features - `parseJpegSegments` — iterates all APP/marker segments up to and including SOS - Handles padding bytes (multiple consecutive `0xFF`) between segments - `isExifSegment` — identifies APP1 segments with the `Exif\0\0` header - `isXmpSegment` — identifies APP1 segments with the XMP namespace header - `isIptcSegment` — identifies APP13 segments with the `Photoshop 3.0\0` header - Bounds-checking with `ExifError(PARSE_ERROR)` on malformed input ## Usage: Basic Example ```ts import { parseJpegSegments, isExifSegment } from "@suaveplan/exif"; const segments = parseJpegSegments(jpegBuffer); const exifSeg = segments.find(isExifSegment); if (exifSeg) { console.log("EXIF data found, length:", exifSeg.data.length); } ``` ## Usage: Advanced Example ```ts import { parseJpegSegments, isExifSegment, isXmpSegment, isIptcSegment } from "@suaveplan/exif"; const segments = parseJpegSegments(jpegBuffer); for (const seg of segments) { if (isExifSegment(seg)) { console.log(`EXIF APP1 at offset ${seg.offset}, ${seg.data.length} bytes`); } else if (isXmpSegment(seg)) { console.log(`XMP APP1 at offset ${seg.offset}`); } else if (isIptcSegment(seg)) { console.log(`IPTC APP13 at offset ${seg.offset}`); } } ``` ## API Reference ### `JpegSegment` ```ts interface JpegSegment { marker: number; // e.g. 0xFFE1 for APP1 data: Uint8Array; // payload (length field excluded) offset: number; // byte offset of marker in original buffer } ``` ### `parseJpegSegments(buffer: Uint8Array): JpegSegment[]` Parses all JPEG segments from `buffer`. Returns segments from SOI through SOS (inclusive). Throws `ExifError(PARSE_ERROR)` if: - The buffer does not start with `FF D8` (SOI) - A segment's length field is less than 2 - A segment's data extends beyond the buffer ### `isExifSegment(seg: JpegSegment): boolean` Returns `true` if `seg` is an APP1 segment (`0xFFE1`) whose payload begins with `Exif\0\0`. ### `isXmpSegment(seg: JpegSegment): boolean` Returns `true` if `seg` is an APP1 segment whose payload begins with `http://ns.adobe.com/xap/1.0/\0`. ### `isIptcSegment(seg: JpegSegment): boolean` Returns `true` if `seg` is an APP13 segment (`0xFFED`) whose payload begins with `Photoshop 3.0\0`. ## Implementation Notes The parser skips padding `0xFF` bytes between markers as permitted by the JFIF specification. Standalone markers (SOI, EOI, RST0–RST7) have no length field and are handled as zero-data segments. Parsing stops at the SOS marker to avoid processing compressed image data as segments. The `data` field of each segment excludes the 2-byte length field, so `data.length === segmentLength - 2`.