JPEG file format
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 with0xFF
followed by the marker for the following block. This consequently means that if we were to write a0xFF
that does not denote the beginning of a block, we must escape it by appending0x00
right after the0xFF
. This means that no block is following and only the0xFF
is 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 0xD8
Marker
APP0
0xFF 0xE0
Marker0x?? 0x??
Segment length is the length of the segment excluding the marker0x4A46494600
Reads JFIF0x01 0x02
Version 1.20x00
No density units used (defaults to 72 DPI I believe)0x00 0x01
Scaling of 100% in the X direction (no scaling)0x00 0x01
Scaling of 100% in the Y direction (no scaling)0x00 0x00
Width 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 0xDB
Marker0x00 0x43
Segment 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 0xC0
Marker0x00 0x11
Segment length is the length of the segment excluding the marker (17 for us)0x08
Precision of 8bits0x?? 0x??
Height of image in 2 bytes0x?? 0x??
Width of image in 2 bytes0x03
Three 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 0xC4
Marker0x?? 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 0xDA
Marker0x00 0x0C
Segment length is the length of the segment excluding the marker and scan data (12)0x03
Three color components0x01 0x??
Component 1 (luminance), huffman table ID0x02 0x??
Component 2 (chrominance blue)0x03 0x??
Component 3 (chrominance red)0x00 0x3F 0x00
Skipping three bytes (no idea what the0x3F
is for…)...
Entropy-encoded scan data, see JPEG scan data
End Of Image
0xFF 0xD9
Marker
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