All formats

JPEG (Joint Photographic Experts Group)

Full nameJPEG (Joint Photographic Experts Group), file format JFIF or Exif
Extensions.jpg, .jpeg, .jpe, .jfif
MIME typeimage/jpeg
Typeraster image, lossy compression (DCT)
Starts withFF D8 FF (SOI marker followed by the next marker)
SpecificationITU-T T.81 / ISO/IEC 10918-1 (compression), ITU-T T.871 (JFIF file format)
Maintained byITU-T and ISO/IEC JTC 1/SC 29 (the JPEG committee); Exif by CIPA and JEITA
Licenseopen; baseline JPEG is royalty-free, the arithmetic coding patents have expired

JPEG is the most common format for photographs. It compresses an image by throwing away detail the eye barely notices, which makes a photo 5-10 times smaller than a lossless PNG. Every camera, phone, browser and image program reads and writes it. The quality setting (usually 0-100) trades file size for visible artifacts.

“JPEG” is the compression method; the files are JFIF (the generic file format, with an APP0 segment) or Exif (what cameras write, with an APP1 segment that holds camera settings, date, GPS position and orientation). Both are JPEG files with the .jpg extension and all programs treat them the same way.

When to use JPEG#

File structure#

A JPEG file is a sequence of segments. Each segment starts with a 2-byte marker: FF followed by a code byte. Most markers are followed by a 2-byte big-endian length that counts itself and the data, but not the marker. The compressed image data (the entropy-coded scan) follows the SOS segment and has no length: the decoder reads it until the next marker.

FF D8                          SOI: start of image
FF E0 00 10                    APP0, length 16
   4A 46 49 46 00              "JFIF\0"
   01 01                       version 1.01
   01 00 48 00 48              density units 1 (dpi), 72 x 72
   00 00                       no thumbnail
FF E1 xx xx 45 78 69 66 00 00  APP1 "Exif\0\0", then a TIFF header (49 49 2A 00 ...)
FF DB 00 43 00 ...             DQT: quantization table 0 (64 values)
FF C0 00 11 08                 SOF0 (baseline), length 17, 8 bits per sample
   01 E0 02 80                 height 480, width 640
   03                          3 components
   01 22 00                    Y:  sampling 2x2, quant table 0
   02 11 01                    Cb: sampling 1x1, quant table 1
   03 11 01                    Cr: sampling 1x1, quant table 1  (= 4:2:0)
FF C4 ...                      DHT: Huffman tables
FF DA 00 0C 03 ...             SOS: start of scan, followed by compressed data
...                            entropy-coded data
FF D9                          EOI: end of image

Markers#

Marker Code Purpose
SOI FF D8 start of image. No length, always first
APP0-APP15 FF E0-FF EF application data, identified by a zero-terminated string at the start (see below)
DQT FF DB define quantization tables (8 or 16 bit values, 64 per table)
SOF0 FF C0 start of frame, baseline DCT: precision, height, width, components and their sampling factors
SOF1 / SOF2 / SOF3 FF C1 / FF C2 / FF C3 extended sequential (12-bit), progressive, lossless
SOF9-SOF11 FF C9-FF CB the same with arithmetic coding instead of Huffman
DHT FF C4 define Huffman tables
DRI FF DD define restart interval (number of MCUs between RST markers)
SOS FF DA start of scan: which components and tables the following compressed data uses
RST0-RST7 FF D0-FF D7 restart markers inside scan data, let a decoder resync after corruption. No length
COM FF FE text comment
EOI FF D9 end of image

Inside scan data a literal FF byte is written as FF 00 (“byte stuffing”) so it isn’t mistaken for a marker. A baseline file has one SOS; a progressive file has several (often 6-10), each followed by its own data and sometimes new DHT tables.

APP segments#

Segment Identifier Contents
APP0 JFIF\0 JFIF version, pixel density, optional thumbnail
APP0 JFXX\0 JFIF extension thumbnail
APP1 Exif\0\0 Exif metadata: a TIFF structure (IFD0, Exif IFD, GPS IFD, thumbnail in IFD1)
APP1 http://ns.adobe.com/xap/1.0/\0 XMP metadata (XML)
APP2 ICC_PROFILE\0 ICC color profile, split into chunks of at most 64 KB
APP2 MPF\0 Multi-Picture Format: extra images (stereo .mpo, HDR gain maps)
APP13 Photoshop 3.0\0 Photoshop image resources, including IPTC captions and keywords
APP14 Adobe color transform flag: tells whether a ¾ component image is YCbCr/YCCK or RGB/CMYK

A segment is at most 65,535 bytes, so large ICC profiles and extended XMP are split across several segments.

Exif orientation#

Cameras store pixels in sensor order and record how the camera was held in the Exif Orientation tag (0x0112): 1 = normal, 3 = rotated 180°, 6 = rotate 90° clockwise to display, 8 = rotate 90° counter-clockwise, 2/4/5/7 add a mirror flip. Browsers and most viewers apply it; many libraries return raw pixels and leave it to you. When you resize or convert a photo, apply the orientation to the pixels and then remove or reset the tag, or the result shows up rotated.

How compression works#

  1. Color conversion: RGB is converted to YCbCr (brightness Y plus two color-difference channels).
  2. Chroma subsampling: the color channels are stored at lower resolution (see below).
  3. DCT: each channel is split into 8x8 blocks; each block is transformed with the discrete cosine transform into 64 frequency coefficients.
  4. Quantization: each coefficient is divided by a value from the quantization table and rounded. This is where data is lost. The quality setting scales the tables: lower quality means larger divisors and more coefficients become 0.
  5. Entropy coding: coefficients are ordered in a zig-zag pattern and compressed losslessly with Huffman coding (almost all files) or arithmetic coding.

A block group that covers the largest sampling factor is a minimum coded unit (MCU): 16x16 pixels for 4:2:0, 8x8 for 4:4:4. Images whose size isn’t a multiple of the MCU are padded.

Chroma subsampling#

Notation Sampling factors (Y, Cb, Cr) Color resolution Typical use
4:4:4 1x1, 1x1, 1x1 full high quality, text and graphics, quality 90+
4:2:2 2x1, 1x1, 1x1 half horizontal video-derived images, some cameras
4:2:0 2x2, 1x1, 1x1 half horizontal and vertical default of most encoders, smallest files

The eye is much less sensitive to color detail than to brightness, so 4:2:0 saves about a third of the file size with little visible change in photos. It makes thin colored lines and red text look blurry.

Baseline and progressive#

Converting between baseline and progressive is lossless: jpegtran -progressive in.jpg > out.jpg.

Lossless operations#

The DCT coefficients can be changed without decoding to pixels, so these operations don’t lose quality: rotate by 90°/180°/270°, flip, crop on MCU boundaries (multiples of 8 or 16 pixels), switching baseline/progressive, re-optimizing Huffman tables and removing metadata. Use jpegtran (from libjpeg-turbo or mozjpeg) or exiftool for metadata.

Making JPEG files smaller#

Specifications and documentation#

Software that opens JPEG files#

SoftwareWindowsmacOSLinuxWebCanNotes
SumatraPDF✓viewfree, open source; also opens JPEG inside archives and comic books
Web browsers✓✓✓✓viewChrome, Edge, Firefox, Safari; apply Exif orientation. Also on Android and iOS
Microsoft Photos✓view, editbuilt into Windows
Paint✓view, edit, createbuilt into Windows
macOS Preview✓view, edit, convertbuilt into macOS
GIMP✓✓✓view, edit, create, convertfree, open source
darktable✓✓✓view, edit, convertfree, open source photo workflow
Paint.NET✓view, edit, create, convertfree
Adobe Photoshop✓✓view, edit, create, convertcommercial
IrfanView✓view, convertfree for non-commercial use; lossless JPEG rotation
XnView MP✓✓✓view, convertfree for private use; lossless rotation and crop
ImageMagick✓✓✓convert, createcommand line, open source
Photopea✓view, edit, create, convertfree, runs in the browser
Squoosh✓convertcompress with mozjpeg in the browser
ExifTool✓✓✓editread and write Exif, XMP, IPTC metadata; command line
jpegoptim✓✓✓convertlossless and lossy JPEG optimizer, command line

Libraries#

Open-source libraries that read and write JPEG. See all JPEG libraries for a comparison.

C/C++libjpeg-turbo, mozjpeg, stb_image
C#ImageSharp, Magick.NET, MetadataExtractor, SkiaSharp
JavaImageIO, metadata-extractor, TwelveMonkeys
Goimage/jpeg, imaging
PythonOpenCV, Pillow
RubyMiniMagick, ruby-vips
Rustimage, zune-jpeg
PHPGD, Imagick, Intervention Image