JPEG file format

20-02-2012

This articles provides information on how a JPEG file is constructed at binary level. It is accompanied with this article: JPEG scan data. The conversion from a raw bitmap to JPEG is implemented in this tool: JPEG

General structure

The JPEG file format uses markers to denote the beginning of a certain block. These markers are 2 bytes long and start with0xFFfollowed by the marker for the following block. This consequently means that if we were to write a0xFFthat does not denote the beginning of a block, we must escape it by appending0x00right after the0xFF. This means that no block is following and only the0xFFis interpreted as being part of the data.

Markers and segments

The following segments are discussed in the order they’d appear in a basic JPEG file. Some are optional segments and some optional segments are left out of the discussion. If you were to decode a JPEG file, you can often skip those optional segments.

Start Of Image

0xFF 0xD8Marker

APP0

0xFF 0xE0Marker0x?? 0x??Segment length is the length of the segment excluding the marker0x4A46494600Reads JFIF0x01 0x02Version 1.20x00No density units used (defaults to 72 DPI I believe)0x00 0x01Scaling of 100% in the X direction (no scaling)0x00 0x01Scaling of 100% in the Y direction (no scaling)0x00 0x00Width and height of thumbnail are zero

Quantization table

Usually two tables are provided, one for the luminance and one for the chrominance. See bottom of the page for the default quantization tables. The elements must be provided in the serpentine / zigzag order.

0xFF 0xDBMarker0x00 0x43Segment length is the length of the segment excluding the marker (3 + 64)0x0?Insignificant four bits denote the table ID, significant four the precision of its elements (set to 0 for default 8bit per element)...64 values of the quantization table

Start Of Frame

0xFF 0xC0Marker0x00 0x11Segment length is the length of the segment excluding the marker (17 for us)0x08Precision of 8bits0x?? 0x??Height of image in 2 bytes0x?? 0x??Width of image in 2 bytes0x03Three color components0x01 0x11 0x??Component 1 (luminance), 1x1 sample (no subsampling), quantization table ID0x02 0x11 0x??Component 2 (chrominance blue)0x03 0x11 0x??Component 3 (chrominance red)

Huffman table

Usually four tables are provided, two for the luminance and two for the chrominance. Each is split into tables for DC and AC values. See bottom of the page for the default Huffman tables and see JPEG scan data for an explanation to use it.

0xFF 0xC4Marker0x?? 0x??Segment length is the length of the segment excluding the marker (3 + 16 + X)0x??Insignificant four bits denote the table ID, the 5th bit is true for AC and false for DC...16 values for the bit lengths...X values for the codes

Start of Scan

Multiple scans may exist for interlacing. We use only one.

0xFF 0xDAMarker0x00 0x0CSegment length is the length of the segment excluding the marker and scan data (12)0x03Three color components0x01 0x??Component 1 (luminance), huffman table ID0x02 0x??Component 2 (chrominance blue)0x03 0x??Component 3 (chrominance red)0x00 0x3F 0x00Skipping three bytes (no idea what the0x3Fis for…)...Entropy-encoded scan data, see JPEG scan data

End Of Image

0xFF 0xD9Marker

Default quantization tables

/* Luminance */
const uint8_t Qy_[] = {
	16,  11,  10,  16,  24,  40,  51,  61,
	12,  12,  14,  19,  26,  58,  60,  55,
	14,  13,  16,  24,  40,  57,  69,  56,
	14,  17,  22,  29,  51,  87,  80,  62,
	18,  22,  37,  56,  68, 109, 103,  77,
	24,  35,  55,  64,  81, 104, 113,  92,
	49,  64,  78,  87, 103, 121, 120, 101,
	72,  92,  95,  98, 112, 100, 103,  99
};

/* Chrominance */
const uint8_t Qc_[] = {
	17, 18, 24, 47, 99, 99, 99, 99,
	18, 21, 26, 66, 99, 99, 99, 99,
	24, 26, 56, 99, 99, 99, 99, 99,
	47, 66, 99, 99, 99, 99, 99, 99,
	99, 99, 99, 99, 99, 99, 99, 99,
	99, 99, 99, 99, 99, 99, 99, 99,
	99, 99, 99, 99, 99, 99, 99, 99,
	99, 99, 99, 99, 99, 99, 99, 99
};

Default Huffman tables

/* Luminance DC */
const uint8_t Hy_dc_bits[] = {
	0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
};

const uint8_t Hy_dc_val[] = {
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
};

/* Luminance AC */
const uint8_t Hy_ac_bits[] = {
	0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
};

const uint8_t Hy_ac_val[] = {
	0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
	0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
	0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
	0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
	0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
	0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
	0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
	0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
	0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
	0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
	0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
	0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
	0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
	0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
	0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
	0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
	0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
	0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
	0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
	0xf9, 0xfa
};

/* Chrominance DC */
const uint8_t Hc_dc_bits[] = {
	0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
};

const uint8_t Hc_dc_val[] = {
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
};

/* Chrominance AC */
const uint8_t Hc_ac_bits[] = {
	0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
};

const uint8_t Hc_ac_val[] = {
	0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
	0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
	0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
	0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
	0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
	0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
	0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
	0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
	0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
	0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
	0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
	0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
	0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
	0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
	0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
	0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
	0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
	0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
	0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
	0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
	0xf9, 0xfa
};

More information:http://class.ee.iastate.edu/ee528/Reading%20material/JPEG_File_Format.pdf