What Is in the JPEG Start of Frame Marker?
The Start of Frame (SOF) marker segment in a JPEG file establishes the core structural and geometric metadata required by decoders to reconstruct the image. This article breaks down the exact binary data fields contained inside the JPEG SOF marker segment, explaining how sample precision, image dimensions, color component definitions, chroma subsampling factors, and quantization table assignments are structured.
Role and Identification of the SOF Marker
In the JPEG standard (ITU-T T.81 / ISO/IEC 10918-1), the Start of
Frame marker signals the beginning of the frame parameters and specifies
the compression process used. The marker itself is a two-byte code
starting with 0xFF followed by a byte ranging from
0xC0 to 0xCF (excluding 0xC4,
0xC8, and 0xCC, which are reserved for other
table types). The most common markers are:
- SOF0 (
0xFFC0): Baseline Sequential Discrete Cosine Transform (DCT) - SOF1 (
0xFFC1): Extended Sequential DCT - SOF2 (
0xFFC2): Progressive DCT - SOF3 (
0xFFC3): Lossless (sequential)
Immediately following the two-byte SOF marker is the payload containing the frame header data.
Detailed Breakdown of the SOF Segment Fields
The payload of an SOF marker contains a sequence of specific fields in a fixed order:
1. Frame Header Length (\(L_f\))
- Size: 16 bits (2 bytes)
- Description: Specifies the total length of the SOF
segment in bytes, including the two length bytes themselves, but
excluding the initial two-byte
0xFFCxmarker code.
2. Sample Precision (\(P\))
- Size: 8 bits (1 byte)
- Description: Defines the bit depth per sample for each component. For standard baseline JPEG (SOF0), this value is almost always 8 bits. Extended JPEG formats can support 12-bit precision.
3. Image Height (\(Y\))
- Size: 16 bits (2 bytes)
- Description: The vertical dimension of the image in pixels (number of lines). A value of zero indicates that the number of lines is defined by an end-of-image (EOI) or restart marker sequence, though this is rarely used.
4. Image Width (\(X\))
- Size: 16 bits (2 bytes)
- Description: The horizontal dimension of the image in pixels (samples per line). Must be greater than zero.
5. Number of Image Components (\(N_f\))
- Size: 8 bits (1 byte)
- Description: The number of color components in the
frame. Typical values are:
1: Grayscale image3: YCbCr or RGB color image4: CMYK or YCCK color image
6. Component Specification Parameters
Following the number of components (\(N_f\)), the SOF segment contains a repeating block of 3 bytes for each component. Therefore, this section is \(N_f \times 3\) bytes long. For each component, the following three parameters are declared:
- Component Identifier (\(C_i\)):
- Size: 8 bits (1 byte)
- Description: A unique identifier for the component.
Typically
1for Y (Luminance),2for Cb (Chrominance blue), and3for Cr (Chrominance red).
- Sampling Factors (\(H_i\)
and \(V_i\)):
- Size: 8 bits (1 byte total; split into two 4-bit nibbles)
- Description:
- Horizontal Sampling Factor (\(H_i\), top 4 bits): Specifies the relative horizontal sampling frequency (1 to 4).
- Vertical Sampling Factor (\(V_i\), bottom 4 bits): Specifies the relative vertical sampling frequency (1 to 4).
- These values dictate the chroma subsampling scheme (e.g., \(H=2, V=2\) for Y alongside \(H=1, V=1\) for Cb and Cr defines standard 4:2:0 subsampling).
- Quantization Table Destination Selector (\(Tq_i\)):
- Size: 8 bits (1 byte)
- Description: Specifies which Quantization Table (defined earlier in a Define Quantization Table / DQT segment) is mapped to this specific component. The value typically ranges from 0 to 3.
Summary of the Binary Layout
| Field | Size | Purpose |
|---|---|---|
| Marker | 2 bytes | Identifies the SOF type
(0xFFC0, 0xFFC2, etc.) |
| \(L_f\) | 2 bytes | Length of the frame header segment |
| \(P\) | 1 byte | Sample precision (bit depth, usually 8) |
| \(Y\) | 2 bytes | Maximum image height in pixels |
| \(X\) | 2 bytes | Maximum image width in pixels |
| \(N_f\) | 1 byte | Number of color components |
| For each component: | ||
| — \(C_i\) | 1 byte | Component ID (e.g., 1=Y, 2=Cb, 3=Cr) |
| — \(H_i / V_i\) | 1 byte | Horizontal and vertical subsampling factors (4 bits each) |
| — \(Tq_i\) | 1 byte | Quantization table index linked to this component |