ByteScope

JPEG file format

A lossy-compressed raster image format, ubiquitous for photos.

MIME type
image/jpeg
Extensions
.jpg, .jpeg
Category
Images

Magic-number signature

0x00000000FFD8FF···Start-Of-Image marker

About the JPEG format

JPEG uses discrete-cosine-transform compression tuned for photographic images, trading a small, mostly invisible amount of quality for a large drop in file size. Files begin with the Start-Of-Image marker FF D8 and end with FF D9. Everything between those two markers is a chain of segments, each introduced by FF followed by a marker byte, and almost all of them carry a two-byte big-endian length right after the marker — which is what lets a parser walk a JPEG without understanding a single one of its segments. The pixel data itself lives in the entropy-coded stream after the Start-Of-Scan marker, and that stream is the one part of the file with no length field at all: a decoder finds its end by scanning for the next real marker.

Header layout, byte by byte

OffsetLengthFieldMeaning
02Start of Image markerFF D8. One of the handful of markers that carry no length and no payload. The catalog signature reads three bytes rather than two because the FF that opens the next marker follows immediately, and requiring it rules out a file that happens to start with FF D8 by accident.
22First application markerFF E0 introduces APP0 and means the file follows JFIF; FF E1 introduces APP1 and usually means Exif. Cameras and phones write APP1, image editors tend to write APP0 first and APP1 after it, and a file with both is completely normal.
42Segment lengthBig-endian byte count of the segment, counting these two bytes but not the two marker bytes before them. An APP0 with no thumbnail reads 00 10 — sixteen — so the next marker starts at 4 plus 16, which is offset 20.
65JFIF identifier4A 46 49 46 00, the ASCII letters JFIF and a NUL. When APP1 came first instead, offset 6 holds the six bytes 45 78 69 66 00 00 and the whole segment is Exif rather than JFIF.
112JFIF versionMajor then minor as two single bytes: 01 01 is version 1.01, 01 02 is 1.02. Present only when APP0 is the first segment; in an Exif-first file these bytes are part of the TIFF structure instead.
131Density units0 means the density numbers express only an aspect ratio, 1 means dots per inch, 2 means dots per centimetre. Plenty of encoders write 0 here and then still fill in 72 and 72, which is why print sizes derived from a JPEG are so often meaningless.
144Horizontal and vertical densityTwo big-endian 16-bit numbers, X then Y, interpreted by the units byte before them. This is the JFIF answer to what a PNG stores in pHYs, and the two are not kept in sync by anything.
182Thumbnail width and heightOne byte each, almost always 00 00. If they are not zero, three times width times height bytes of uncompressed RGB follow at offset 20 and the segment length at offset 4 grows to match — an easy consistency check by hand.
-22End of Image markerFF D9, and like the SOI it has no length. Trailing bytes after it are legal enough that decoders ignore them, which is how ZIP archives and shell scripts get smuggled into image files.

Telling it apart from its neighbours

Easily confused withHow to tell
JFIF/ExifBoth are JPEG, and the split is decided entirely by the marker at offset 2. FF E0 with 4A 46 49 46 00 at offset 6 is JFIF, and everything you can learn from it is the density pair. FF E1 with 45 78 69 66 00 00 at offset 6 is Exif, and at offset 12 a complete TIFF header begins — 49 49 2A 00 or 4D 4D 00 2A, then a four-byte offset to the first directory. That is where camera model, exposure, orientation and GPS live. A file can carry both segments, in which case the Exif one is the one worth reading.
HEICThe two formats compete for the same job on the same phones, and the setting that switches between them is one toggle deep in the camera app. JPEG is FF D8 FF at offset 0. HEIC has nothing at offset 0 but a box length, and reads 66 74 79 70 68 65 69 63 at offset 4. Photos exported from an iPhone in Most Compatible mode are JPEG, everything else is HEIC.
PNGFF D8 FF against 89 50 4E 47. Worth checking rather than trusting the extension, because a JPEG saved as .png stays a JPEG and every browser renders it anyway, and because re-encoding a screenshot to JPEG is the single most common reason text in an image goes fuzzy.
JPEG 2000A different codec that only shares a name. A raw JPEG 2000 codestream begins FF 4F FF 51; the boxed JP2 file form begins 00 00 00 0C 6A 50 20 20 0D 0A 87 0A. Neither will decode in a browser, which is why a .jp2 downloaded from a scientific or archival source appears broken.

How these files break

  • Truncation. The header survives so a viewer knows the dimensions and paints the top of the picture, then the entropy-coded stream runs out and the rest of the frame stays grey or repeats the last block. The tell is the last two bytes: an intact JPEG ends FF D9.
  • A byte inserted or dropped inside the scan data. Huffman coding has no byte alignment to resynchronise against, so every block after the damage decodes with the wrong DC prediction and the image dissolves into shifted colour bands from that row down. Unless the encoder wrote restart markers, nothing recovers.
  • Text-mode transfer. The same line-ending translation that ruins a PNG rewrites 0D 0A inside compressed data here too, and JPEG has no per-segment checksum to notice. The file opens, the header is perfect, and the bottom two-thirds are smeared.
  • A broken Exif directory. The APP1 segment length is right but an offset inside the TIFF structure points past the end of the segment, so photos lose their orientation tag and appear rotated ninety degrees in some apps and upright in others. Stripping the segment fixes the display and destroys the metadata.
  • Bytes prepended by a server error page or a stray BOM. FF D8 FF is no longer at offset 0, so strict decoders reject the file outright while lenient ones scan forward and open it, producing the familiar situation where an image works in the browser and fails in the build.

Where the format stands today

JPEG is thirty years old and still the format almost every photograph on the internet is delivered in. Nothing else is decoded by literally every camera, phone, browser, printer, scanner and photo frame ever made, and that universality is worth more than the twenty to fifty percent that WebP, AVIF and HEIC would save. Where it genuinely loses is anything with hard edges — screenshots, diagrams, text, line art — because the block transform smears exactly the high-frequency detail those images are made of, and anything that will be edited and saved repeatedly, since every save is a fresh lossy encode and the damage accumulates. It has no alpha channel at all, so a logo that needs transparency cannot be a JPEG. The intended successor, JPEG XL, offers lossless recompression of existing JPEGs and better quality per byte, but browser support stalled and it is not a delivery option today. In practice the modern answer is to keep JPEG as the fallback inside a picture element and serve WebP or AVIF to everything that will take them.

Open JPEG files on this site

Every one of these runs in your browser — the file never leaves your machine.

Related formats

Formats that are easy to confuse with JPEG — compare their leading bytes.

FormatFirst bytesExtension
PNG89 50 4E 47 0D 0A.png
WebP52 49 46 46.webp
HEIC66 74 79 70.heic
GIF47 49 46 38 39 61.gif

Frequently asked questions

What is a magic number in a file?

The first few bytes of a file, which identify its format regardless of what the name says. A PNG always starts with 89 50 4E 47; a ZIP with 50 4B 03 04. Operating systems, browsers and the file command all read these bytes rather than trusting the extension, which is why renaming a file does not change what it actually is.

How do I check a file's magic number myself?

On macOS or Linux, xxd -l 16 yourfile prints the first 16 bytes; on Windows, Format-Hex -Path yourfile -Count 16 in PowerShell. Or drop the file into the File Type Identifier on this site, which reads the bytes locally and names the format for you — nothing is uploaded.

Why do two formats share the same magic number?

Because one is built on the other. Every docx, xlsx, pptx, apk, jar and epub begins with the ZIP signature, since all of them are ZIP archives underneath; telling them apart means looking at the entries inside. Java class files and macOS universal binaries both start with CA FE BA BE and are distinguished by the field that follows.

Can a file have no magic number at all?

Yes. Text-based formats — XML, HTML, JSON, SVG, CSV — have no fixed byte signature, so they are recognized structurally instead: a leading <?xml declaration, a <svg element, or a { followed by a quoted key. That detection is a good guess rather than a certainty, which is why this reference marks those formats as probe-detected.

Does a matching magic number mean the file is safe?

No. It tells you what the format is, not whether the contents are harmless — a genuine PDF or docx can still carry a malicious payload. Identifying the true type is a useful first check, especially when the extension disagrees with the bytes, but it is not a malware scan.

Have a file that might be in the JPEG format? Identify it with the File Type Identifier — it reads the magic number locally, nothing is uploaded. Or browse all formats.