Start FF D8 FF EO 00 01 4a 46 49 46 00 01 01 01 J F I F \0 End FF D9 'FF00' sequence, it should consider just a byte: 0xFF as an usual byte. SOI = Start Of Image = 'FFD8' This marker must be present in any JPG file *once* at the beginning of the file. (Any JPG file starts with the sequence FFD8.) EOI = End Of Image = 'FFD9' Similar to EOI: any JPG file ends with FFD9. RSTi = FFDi (where i is in range 0..7) [ RST0 = FFD0, RST7=FFD7] = Restart Markers These restart markers are used for resync. At regular intervals, they appear in the JPG stream of bytes, during the decoding process (after SOS) (They appear in the order: RST0 -- interval -- RST1 -- interval -- RST2 --... ...-- RST6 -- interval -- RST7 -- interval -- RST0 --... ) (Obs: A lot of JPGs don't have restart markers) ------- Markers... ------- At the end of this doc, I've included a very well written technical explanation of the JPEG/JFIF file format, written by Oliver Fromme, the author of the QPEG viewer. There you'll find a pretty good and complete definition for the markers. But, anyway, here is a list of markers you should check: SOF0 = Start Of Frame 0 = FFC0 SOS = Start Of Scan = FFDA APP0 = it's the marker used to identify a JPG file which uses the JFIF specification = FFE0 COM = Comment = FFFE DNL = Define Number of Lines = FFDC DRI = Define Restart Interval = FFDD DQT = Define Quantization Table = FFDB DHT = Define Huffman Table = FFC4 APP0: JFIF segment marker: ~~~~~~~~~~~~~~~~~~~~~~~~~~ - $ff, $e0 (APP0) - length (high byte, low byte), must be >= 16 - 'JFIF'#0 ($4a, $46, $49, $46, $00), identifies JFIF - major revision number, should be 1 (otherwise error) - minor revision number, should be 0..2 (otherwise try to decode anyway) - units for x/y densities: 0 = no units, x/y-density specify the aspect ratio instead 1 = x/y-density are dots/inch 2 = x/y-density are dots/cm - x-density (high byte, low byte), should be <> 0 - y-density (high byte, low byte), should be <> 0 - thumbnail width (1 byte) - thumbnail height (1 byte) - n bytes for thumbnail (RGB 24 bit), n = width*height*3 Remarks: - If there's no 'JFIF'#0, or the length is < 16, then it is probably not a JFIF segment and should be ignored. - Normally units=0, x-dens=1, y-dens=1, meaning that the aspect ratio is 1:1 (evenly scaled). - JFIF files including thumbnails are very rare, the thumbnail can usually be ignored. If there's no thumbnail, then width=0 and height=0. - If the length doesn't match the thumbnail size, a warning may be printed, then continue decoding. DRI: Define Restart Interval: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - $ff, $dd (DRI) - length (high byte, low byte), must be = 4 - restart interval (high byte, low byte) in units of MCU blocks, meaning that every n MCU blocks a RSTn marker can be found. The first marker will be RST0, then RST1 etc, after RST7 repeating from RST0. DQT: Define Quantization Table: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - $ff, $db (DQT) - length (high byte, low byte) - QT information (1 byte): bit 0..3: number of QT (0..3, otherwise error) bit 4..7: precision of QT, 0 = 8 bit, otherwise 16 bit - n bytes QT, n = 64*(precision+1) Remarks: - A single DQT segment may contain multiple QTs, each with its own information byte. - For precision=1 (16 bit), the order is high-low for each of the 64 words. COM: Comment: - $ff, $fe (COM) SOS: Start Of Scan: - $ff, $da (SOS)