[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]

From: inof@asterix.rz.tu-clausthal.de (Oliver Fromme (TBH))

> I need to be able to get the size and colors from a JPEG/JFIF image file..
> Nothing more, nothing less... Structures would do, regardless of
> language (C, Asm, Pas, Basic). Anyone?


This file was written by:

   Oliver Fromme
   Leibnizstr. 18-61
   38678 Clausthal

Email:  fromme@rz.tu-clausthal.de

General Notes:

  - All product names mentioned in this file are trademarks or registered
    trademarks of their respective owners.
  - This file contains information about the JPEG/JFIF format
  - This is NO official documentation, for private purposes only.
    There may be bugs and errors in this file.  Use the information
    on your own risk.
  - This file does NOT explain the principles of JPEG coding/decoding,
    i.e. DCT/IDCT, quantization, entropy codec.  I assume that the reader
    is familiar with these algorithms.
  - For further information please refer to the JPEG ISO standard.
  - The JPEG/JFIF format uses Motorola format for words, NOT Intel format,
    i.e. high byte first, low byte last.

JPEG/JFIF file format:

  - header (2 bytes):  $ff, $d8 (SOI) (these two identify a JPEG/JFIF file)
  - for JFIF files, an APP0 segment is immediately following the SOI marker,
    see below
  - any number of "segments" (similar to IFF chunks), see below
  - trailer (2 bytes): $ff, $d9 (EOI)

Segment format:

  - header (4 bytes):
       $ff     identifies segment
        n      type of segment (one byte)
       sh, sl  size of the segment, including these two bytes, but not
               including the $ff and the type byte. Note, not intel order:
               high byte first, low byte last!
  - contents of the segment, max. 65533 bytes.

  - There are parameterless segments (denoted with a '*' below) that DON'T
    have a size specification (and no contents), just $ff and the type byte.
  - Any number of $ff bytes between segments is legal and must be skipped.

Segment types:

   *TEM   = $01   usually causes a decoding error, may be ignored

    SOF0  = $c0   Start Of Frame (baseline JPEG), for details see below
    SOF1  = $c1   dito
    SOF2  = $c2   usually unsupported
    SOF3  = $c3   usually unsupported

    SOF5  = $c5   usually unsupported
    SOF6  = $c6   usually unsupported
    SOF7  = $c7   usually unsupported

    SOF9  = $c9   for arithmetic coding, usually unsupported
    SOF10 = $ca   usually unsupported
    SOF11 = $cb   usually unsupported

    SOF13 = $cd   usually unsupported
    SOF14 = $ce   usually unsupported
    SOF15 = $cf   usually unsupported

    DHT   = $c4   Define Huffman Table, for details see below
    JPG   = $c8   undefined/reserved (causes decoding error)
    DAC   = $cc   Define Arithmetic Table, usually unsupported

   *RST0  = $d0   RSTn are used for resync, may be ignored
   *RST1  = $d1
   *RST2  = $d2
   *RST3  = $d3
   *RST4  = $d4
   *RST5  = $d5
   *RST6  = $d6
   *RST7  = $d7

    SOI   = $d8   Start Of Image
    EOI   = $d9   End Of Image
    SOS   = $da   Start Of Scan, for details see below
    DQT   = $db   Define Quantization Table, for details see below
    DNL   = $dc   usually unsupported, ignore
    DRI   = $dd   Define Restart Interval, for details see below
    DHP   = $de   ignore (skip)
    EXP   = $df   ignore (skip)

    APP0  = $e0   JFIF APP0 segment marker, for details see below
    APP15 = $ef   ignore

    JPG0  = $f0   ignore (skip)
    JPG13 = $fd   ignore (skip)
    COM   = $fe   Comment, may be ignored

 All other segment types are reserved and should be ignored (skipped).

SOF0: Start Of Frame 0:

  - $ff, $c0 (SOF0)
  - length (high byte, low byte), 8+components*3
  - data precision (1 byte) in bits/sample, usually 8 (12 and 16 not
    supported by most software)
  - image height (2 bytes, Hi-Lo), must be >0 if DNL not supported
  - image width (2 bytes, Hi-Lo), must be >0 if DNL not supported
  - number of components (1 byte), usually 1 = grey scaled, 3 = color YCbCr
    or YIQ, 4 = color CMYK)
  - for each component: 3 bytes
     - component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q)
     - sampling factors (bit 0-3 vert., 4-7 hor.)
     - quantization table number

  - JFIF uses either 1 component (Y, greyscaled) or 3 components (YCbCr,
    sometimes called YUV, colour).

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

  - 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)

  - 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.

DAC: Define Arithmetic Table:

 Current software does not support arithmetic coding for legal reasons.
 JPEG files using arithmetic coding can not be processed.

DHT: Define Huffman Table:

  - $ff, $c4 (DHT)
  - length (high byte, low byte)
  - HT information (1 byte):
     bit 0..3: number of HT (0..3, otherwise error)
     bit 4   : type of HT, 0 = DC table, 1 = AC table
     bit 5..7: not used, must be 0
  - 16 bytes: number of symbols with codes of length 1..16, the sum of these
    bytes is the total number of codes, which must be <= 256
  - n bytes: table containing the symbols in order of increasing code length
    (n = total number of codes)

  - A single DHT segment may contain multiple HTs, each with its own
    information byte.

SOS: Start Of Scan:

  - $ff, $da (SOS)
  - length (high byte, low byte), must be 6+2*(number of components in scan)
  - number of components in scan (1 byte), must be >= 1 and <=4 (otherwise
    error), usually 1 or 3
  - for each component: 2 bytes
     - component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q), see SOF0
     - Huffman table to use:
        - bit 0..3: AC table (0..3)
        - bit 4..7: DC table (0..3)
  - 3 bytes to be ignored (???)

  - The image data (scans) is immediately following the SOS segment.

End of part 1.

I've written a JPEG Decoding Unit for Borland/Turbo Pascal 7.0.  It's very
fast, since it uses Assembly routines for the critical algorithms.
Check out the program QPEG which is a shareware image viewer (JPEG, GIF,
Targa, PCX, BMP) -- it uses that unit.  The QPEG package also contains a
more detailed description of the JPEG unit and an order form for it
(including source code).  I'm also writing a JPEG decoding DLL which will
be available soon.

If you have access to the Internet, then you can get QPEG via FTP from one
of these sites:
   ftp.tu-clausthal.de  /pub/msdos/graphics (primary site, Germany)
   ftp.rahul.net        /pub/bryanw/qpeg
   wuarchive.wustl.edu  /pub/msdos_uploads/graphics
If you don't have Internet access, just send 5 $US or 5 DM (cash) to me
(to cover my expenses), and you'll get the shareware version of QPEG.
You must have at least a 386 processor and a VGA graphics card.

See my address (normal mail and electronic mail) at the top of this file.


[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]