Groundtruth · the specimen is yours

The Table Your JPEG Carries

Drop a JPEG and read its quantization and Huffman tables straight from the bytes. Then ask a harder question of the pixels: do different parts behave as if they passed through different compression qualities? A matching table can establish compatibility with a published encoder family. It cannot name a camera, certify an untouched original, or tell whether the scene happened.

Nothing leaves this device 0 resource requests have begun since the current specimen was selected. The policy in this page's head sets connect-src 'none'. Open the browser Network panel and watch it yourself.

1. The published table first

The JPEG standard prints two 8 by 8 example quantization tables in Annex K.1. That annex is headed this annex does not form an integral part of this Recommendation, and K.1 calls the tables examples only. They are examples, not defaults and not camera signatures. The standard constrains an 8-bit table entry to 1 through 255 and says nothing about its value. Before this page accepts your file, its parser reads the shipped JPEG and compares all 128 natural-order cells against those printed values.

What that 128 can and cannot mean: the shipped card was saved at IJG quality 50, and 50 is the one quality where the integer scale factor is 100 and the scaling arithmetic is the identity. So any file any libjpeg-derived encoder ever wrote at quality 50 carries these exact bytes. This anchor is therefore a test of this parser, of marker walking, segment lengths, Pq and Tq, and the zig-zag permutation, and not evidence about JPEGs in the world. Treat it as the instrument's calibration, not as a result.

Published anchor · ITU-T T.81 Annex K.1

reading the shipped codestream

0 / 128 cells

The same parser used below is locating FF DB, reading Pq and Tq, undoing zig-zag order, and comparing the result.

K.1 luminance, table 0

K.2 chrominance, table 1

Fallback: jpeg-ghost-testcard-q30-in-q50.jpg, 512 by 384 pixels. It was generated for this page from geometry and deterministic noise, with no outside image. A 160 by 160 region at x=176, y=112 was saved at IJG Q30, decoded, returned to the same 8 by 8 lattice, then the whole card was saved at IJG Q50 in 4:4:4. The pixels and file are dedicated to the public domain under CC0 1.0. The generator ships beside this page.

2. Bring one JPEG

The file is not uploaded. The browser turns your File into an ArrayBuffer; a local worker scans the entire codestream, including markers after every scan.

The anchor must pass first.

Limit: 20 MiB compressed, 4,000,000 decoded pixels. A refusal names the byte or limit that caused it. Selecting a file clears every measurement of the previous one first, so nothing on this page is ever left describing a specimen you replaced.

EXIF orientation is ignored on purpose. The pixels are decoded in codestream order, the order the encoder's own 8 by 8 lattice was built in, so a rotated phone photo is analysed rather than refused, and is shown sideways if its camera stored it sideways.

Layer one · the bytes

waiting

DQT FFDBDHT FFC4framescan
No table claim yet.
Huffman definitions and canonical codes

What the header can carry

A JPEG quality number is not stored in the format. This page may print an IJG quality only when every observed value exactly equals a table generated by the pinned IJG scaling curve. Even then the word is compatible. Shared tables, copied headers, repeated saves, adaptive tables, and software defaults prevent unique attribution.

The final encoder can replace definitions written by an earlier save. The header describes tables active for scans in this codestream, not every table the pixels have met.

A rule this page changed after seeing data. The first version of this parser called the last definition for each destination the active one. An adversarial reviewer then appended a quality 30 table pair to the shipped test card after its only scan, 134 bytes before EOI, and the page dutifully reported the file as compatible with Q=30. Those tables cannot have encoded anything: no scan follows them. The rule is now that a definition is active only if some scan falls between it and the next definition for the same destination. Definitions that pass no scan are still shown, and counted, and labelled as never in effect. Both specimens are in the verifier.

Layer two · recompression history

draw a region, then run

Drag a rectangle over a suspected region. The default on the shipped card is the known Q30 insert. The worker resaves the decoded pixels at each chosen IJG quality, decodes each result, computes the mean of squared RGB differences, averages it in non-overlapping 16 by 16 windows, then normalizes each location across quality. That is the sequence in Farid's JPEG ghost equations 2 through 4.

ROI x=176 y=112 w=160 h=160

The region is operable without a pointer. Focus the image and use the arrow keys to move the rectangle by one 16 pixel window, or shift with the arrow keys to resize it. Its coordinates are announced above and repeated in the visible choices.

Windowed raw RGB squared error at the ELA quality below. Uniform blocks are a consequence of the 16 by 16 averaging, not hidden pixels.
Ordinary one-quality ELA: one unnormalized resave difference slice, shown with a free display gain. It is a resave difference, not a lie detector.

The ELA quality below starts at 50, which is this test card's own final save. That is the setting where the resave is closest to a fixed point and the difference collapses toward zero everywhere: a property of the setting, not of the picture. Move the slider away from it.

A bright edge is not an edit. The unedited rings, texture, noise and colour boundaries in the fallback light up because JPEG resaving changes them too. No automatic authentic or tampered verdict is produced.

The privacy receipt

This instrument makes its boundary inspectable. The current file name and byte count, the browser API that began processing, every loaded resource origin, and the number of resources begun after selection are printed below. The CSP blocks all connections, including same-origin fetch(), after the page's scripts have loaded.

No specimen receipt yet.

What this does not prove

It does not identify a unique camera, software package, author, capture time, or original file. It does not prove that a picture is authentic or edited, and it cannot certify that a depicted event happened. An exact IJG or Huffman match establishes compatibility with a published family only. A JPEG ghost or ELA pattern is evidence about recompression behaviour under the stated assumptions, not a tampering verdict.

Jesse Kornblum reported shared tables, adaptive tables, false positives, and ambiguity between software and hardware. The useful result is narrower and sturdier: a byte-for-byte table comparison can exclude a reference family or establish exact compatibility with it. It cannot turn a shared convention into provenance.

There is a measurement of how far it falls short. Hany Farid partitioned 337,626 Flickr photographs, spanning 10,153 distinct pairings of camera make, model, resolution and quantization table over 48 manufacturers and 859 models. Partitioned on the quantization table alone, the classes run from size 1 to 899, with mean 273.6 and median 254, and only 517 entries, 5.1 percent, have a table nobody else uses. Pairing table with image resolution raises that to 2,704 entries, 26.6 percent, with a median class of 5. His own summary is the honest ceiling: the table is clearly not unique, and paired with resolution it is reasonably effective at narrowing the source of an image to a single camera make and model or to a small set of possible cameras. Narrowing to a class is the true claim. Naming the camera is wrong by roughly the median class size.

Sources and pinned material

  1. CCITT and ISO/IEC Joint Photographic Experts Group. Information technology: Digital compression and coding of continuous-tone still images: Requirements and guidelines. Recommendation T.81 and ISO/IEC 10918-1:1994. Marker syntax in B.2.4.1 and B.2.4.2, canonical Huffman construction in Annex C, example quantization tables in K.1, typical Huffman tables in K.3.www.w3.org/Graphics/JPEG/itu-t81.pdf
  2. Independent JPEG Group and libjpeg-turbo project. jcparam.c and jstdhuff.c, release 3.1.4.1. The page pins the table arrays and integer scaling curve from these files.jcparam.c SHA-256 653c5dff550c3947e32f6702c8f2f650d490c6390867c108efef2042ec547fdd
    jstdhuff.c SHA-256 79e2cbf605326ce6349a60f58695b97d574510662f8b089474f30c07bf06be28
  3. Jesse D. Kornblum. Using JPEG quantization tables to identify imagery processed by software. Digital Investigation 5, Supplement, 2008, S21 to S25. DOI 10.1016/j.diin.2008.05.004. Used for the IJG curve and the explicit attribution limits.
  4. Hany Farid. Digital Image Ballistics from JPEG Quantization: A Followup Study. Technical Report TR2008-638, Department of Computer Science, Dartmouth College, 2008. Used for the measured limits of table-based attribution: 337,626 images, 10,153 make, model, resolution and table pairings, class sizes 1 to 899, mean 273.6, median 254, and 517 entries (5.1 percent) with a unique table.
  5. Hany Farid. Exposing Digital Forgeries from JPEG Ghosts. IEEE Transactions on Information Forensics and Security 4(1), 2009, 154 to 160. DOI 10.1109/TIFS.2008.2012215. Used for equations 2 through 5, qualities 30 through 90, 16 by 16 averaging, normalization, low-detail exclusion, lattice search, and limitations.
  6. Neal Krawetz. A Picture's Worth: Digital Image Analysis and Forensics. Black Hat USA, 2007, section 3.4.2. Used for the one-quality resave difference called ELA.
  7. Adobe Systems Incorporated, Andreas Ritter, and Eugene Ware. jpeg-js 0.4.4 baseline encoder, BSD licensed, bundled locally. Used only for controlled recompression. The browser's own decoder reads the result.
  8. Lovell Fuller and contributors. sharp 0.34.5, Apache-2.0 licensed. Used at build time only for the fallback generation recipe. It is not loaded by the page.