How JPEG Detects the End of an Entropy-Coded Segment
A JPEG decoder determines the end of a compressed entropy-coded segment not by reading a predefined length field, but by parsing the bitstream sequentially until it encounters an unescaped marker code. Because entropy-coded data (such as Huffman- or arithmetic-coded scan data) varies in length, the JPEG standard relies on an in-band signaling system known as byte stuffing alongside trailing bit padding to distinguish legitimate compressed data from structural markers such as the End of Image (EOI) or Restart (RST) markers.
The Absence of Length Headers in Scans
Unlike structural metadata segments in a JPEG file (such as
APP0 or DQT), which include a two-byte length
parameter directly following their marker bytes, the Start of Scan
(SOS, marker 0xFFDA) does not specify the byte
count of the entropy-coded data that follows it. The compressed image
payload begins immediately after the scan header and continues
indefinitely until a subsequent marker appears in the stream.
Byte Stuffing (0xFF00)
All JPEG markers begin with the prefix byte 0xFF.
Because variable-length entropy coding can naturally produce an
0xFF byte as part of its valid payload, the JPEG encoder
uses byte stuffing to prevent false marker detection:
- Whenever the encoder generates a raw data byte with the value
0xFF, it immediately inserts a0x00byte (stuff byte) directly after it into the bitstream. - When the decoder is processing entropy data and encounters the
sequence
0xFF 0x00, it discards the0x00byte and treats the0xFFstrictly as compressed data. - If the decoder encounters an
0xFFbyte followed by any non-zero byte, it recognizes that the entropy-coded segment has officially ended, and a JPEG marker has begun.
Bit Padding and Byte Alignment
Entropy-coded data consists of individual variable-length bit
sequences that rarely align perfectly to an 8-bit byte boundary when the
final Minimum Coded Unit (MCU) is processed. To prepare for the
subsequent marker, the encoder pads the remaining bits of the final byte
with 1s (binary 111...).
The decoder knows how many blocks and MCUs to expect based on image dimensions and sampling factors. Once the expected number of image blocks are decoded, the decoder consumes any remaining padding bits up to the next byte boundary and checks for the terminating marker.
Terminating Markers
Once the decoder reaches a byte boundary and detects an
0xFF followed by a non-zero byte, it evaluates the marker
to decide its next action:
- End of Image (
0xFFD9): Indicates the complete end of the image and the final termination of all entropy-coded data. - Restart Markers (
0xFFD0through0xFFD7): Indicate the end of a localized entropy segment (restart interval). The decoder resets its prediction values, clears its internal buffers, aligns to the byte boundary, and begins reading the next entropy segment. - Subsequent Start of Scan (
0xFFDA): In progressive or multi-scan JPEGs, this indicates the end of the current scan pass and the start of the next pass's scan header. - Define Number of Lines (
0xFFDC): Used in rare cases where the vertical line count was unknown when the scan began.