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)