Inside every JFIF file, the first few bytes tell you exactly what kind of JPEG you are dealing with. The JFIF header begins right after the mandatory Start of Image marker. Here is a section‑by‑section breakdown of those bytes: the APP0 marker, the JFIF identifier, version numbers, density units, and the optional embedded preview. Use this when you need to parse or generate JFIF files yourself, or when you need to know what separates a JFIF file from a plain JPEG.

The SOI Marker Every JPEG Starts Here

Every JPEG file begins with the Start of Image (SOI) marker. That marker is the two bytes FF D8. A JFIF file is no exception. The SOI marker tells a decoder that a JPEG image follows. After those two bytes, a JFIF file places its signature block: the APP0 marker.

APP0 Marker and the JFIF Identifier

Immediately after the SOI marker, a JFIF file writes the APP0 marker: the two bytes FF E0. This is a JPEG application marker that carries metadata. The next two bytes give the length of the APP0 segment (including the length bytes themselves). Then comes the identifier: the five bytes 4A 46 49 46 00, which spell out 'JFIF' followed by a null byte. Any decoder that sees this exact sequence knows the file conforms to the JFIF specification.

Version Bytes

Right after the null byte, two more bytes encode the JFIF version: a major version byte and a minor version byte. For release 1.02, the major byte is 01 and the minor byte is 02. These bytes tell software which JFIF rules to follow. The release 1.02 specification was published in 1992 by Eric Hamilton of C‑Cube Microsystems. Later, JFIF was standardised as ITU‑T T.871 and ISO/IEC 10918‑5.

Density Units and Pixel Aspect Ratio

The next byte after the version is the density unit. It can hold one of three values:

  • 0, no physical dimensions; the X and Y densities define an aspect ratio only.
  • 1, density is given in dots per inch (dpi).
  • 2, density is given in dots per centimetre (dpcm).

Following the unit byte are two two‑byte integers: X density and Y density. If the unit is 0, these numbers still appear but they only describe the relative width and height of the pixels. The density unit field is one of the most practical parts of the header for anyone converting between image formats. It tells an image viewer or printer how to display the photo at its intended physical size.

Optional Embedded Preview in the APP0 Segment

The APP0 segment can also contain a small, uncompressed preview image. Two bytes specify the preview width in pixels, and two bytes specify the preview height. If both are zero, there is no preview. If they are non‑zero, the preview data follows immediately: each pixel is stored as three bytes (one each for Y, Cb, and Cr components, in that order). The JFIF file structure guarantees that the preview, if present, is always uncompressed and small enough to fit within the APP0 segment length.

Why the Preview Exists

The original JFIF designers included the preview so that file managers could show a tiny image without decoding the full JPEG. Most modern JFIF files set the preview width and height to zero, leaving the APP0 segment compact. Always check those two bytes before trying to read preview pixels.

From JFIF to Standard JPEG What Changes

If you have a JFIF file and you want a plain JPEG file, the only structural difference is the presence of the APP0 marker with the JFIF identifier. A standard JPEG can have any APP marker, or none at all. The rest of the compressed image data (the entropy‑coded segments, the quantization tables, the Huffman tables) is identical. The file still ends with the End of Image marker FF D9. JFIF also specifies that colour images use the YCbCr colour space, but that is not a byte‑level requirement; it is a rule for the decoder.

To convert a JFIF to a plain JPEG, either remove the APP0 segment or replace it with a different marker. The SOI marker, the image data, and the EOI marker stay untouched. If the APP0 segment contains a preview, discard it. The resulting file opens in any application that reads standard JPEG.

Parsing the APP0 Header in Practice

When writing code to read a JFIF file, follow these steps:

  1. Read the first two bytes. They should be FF D8 (SOI).
  2. Read the next two bytes. They should be FF E0 (APP0).
  3. Read the next two bytes as a big‑endian unsigned integer. That is the segment length, including these two bytes.
  4. Read the next five bytes. They must equal 4A 46 49 46 00 for a valid JFIF header.
  5. Read the next two bytes for the major and minor version number.
  6. Read the next byte for the density unit (0, 1, or 2).
  7. Read the next four bytes as two big‑endian unsigned integers: X density, then Y density.
  8. Read the next four bytes as two big‑endian unsigned integers: preview width, then preview height.
  9. If preview width and height are both non‑zero, read (width × height × 3) bytes for the uncompressed YCbCr preview.

The APP0 marker and its structure are fully defined by the JFIF specification. Once you have parsed these bytes, decide whether to keep, modify, or discard the segment.

Why the JFIF Header Still Matters

JFIF is decades old. Yet many cameras and image editors still produce files with the JFIF APP0 header. Understanding the JFIF file structure lets you handle those files correctly: identify them, extract metadata, and convert them to plain JPEG without losing any image quality. When you need a quick way to turn a stubborn JFIF file into a standard JPG, tools like jfiftojpgconverter.com do it for you.