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)