Groundtruth · the specimen is yours
The Thumbnail That Was Not Edited
A photograph can carry a second, smaller photograph inside its metadata. Open yours locally, follow every pointer to it, and ask what the two pictures and their clocks can actually establish. The comparison can expose forgotten content. It cannot authenticate the file or prove an edit.
Published anchor first · CIPA Exif 2.32, 2019
The standard says a compressed thumbnail lives through the 1st IFD mechanism. Its Compression value is 6. Tag 513 (0x0201) gives a TIFF-base-relative offset to JPEG SOI; tag 514 (0x0202) gives its byte length. The stream is continuous from SOI to EOI.
Opening the shipped fallback and walking its bytes now.
The miniature on this page is not a preview made by the page. It is a JPEG stream already inside the specimen. The fallback starts open so the standard is reproduced before the instrument touches anything of yours.
Choose or drop a JPEG here. It is read once with File.arrayBuffer(). Nothing is uploaded. Files above 96 MiB are refused before reading, and images above 40 megapixels are not sent to the browser decoder.
The second picture, if there is one
First comes structure, not resemblance. An ordinary JPEG with no Exif is a complete negative result. An Exif JPEG can have no 1st IFD. A 1st IFD can omit a thumbnail. All are normal because recording a thumbnail is optional: Exif 2.32 4.5.8 says in the same paragraph that no limit is placed on the size of thumbnail images and that recording them is optional.
The mechanism also explains why a second picture can survive an edit without anyone intending it. Tag 513 is an offset from the TIFF header, not from the start of the file, so a program that keeps the metadata by copying the whole APP1 segment out and back in keeps a self-consistent pointer for free, wherever the segment lands. Nothing in that cheap path regenerates the miniature. Nothing in the standard requires it to. That is a mechanism, not a rule about editors: plenty of software does regenerate the thumbnail, and plenty strips the metadata entirely.
A difference is not a verdict
A raw mismatch has several ordinary causes: crop, rotation, mirroring, camera preview processing, colour handling, or decoder behaviour. The controls make those choices explicit. In automatic mode all eight quarter-turn and mirror candidates are scored, and the lowest unthresholded mean absolute channel difference is shown. No score is translated into edited or authentic.
Two choices in that sentence are load-bearing, and both are made in the reader's favour rather than the instrument's. Contain, not crop. When the main image and the thumbnail have different aspect ratios, DCF 2.0 (CIPA DC-009-2010) 4.4.6.4 requires the difference to be adjusted by padding, with padding data black, image position centred, and without cutting out part of the image. A comparison that centre-crops instead is measuring a picture the camera never claimed to have stored, and on a conformant file it will disagree with an unedited thumbnail for a reason that has nothing to do with editing. Centre crop stays available because not every writer is conformant, but contain is the default and the standard is why.
Absolute difference, not correlation. The obvious alternative is to correlate the two pictures and threshold the correlation. That measure is invariant to a global brightness and contrast change by construction, which means it cannot see a tone edit at all: brighten a photograph, keep the metadata, and a correlation check reports a perfect match. Mean absolute difference is not invariant to it, so a tone change moves this number. The price is that the number also moves for innocent reasons, which is precisely why it is shown raw, with all eight candidates, and never turned into a verdict.
A compressed thumbnail is required for comparison.
MAD / 255 = unavailable
Colour decode path: browser JPEG decoder to canvas sRGB-like RGBA. The raw images and byte hashes remain primary because browser colour management can differ.
No comparison is current.
Two of the three controls above are named free choices that often cannot move the number, and saying so is part of the result. The eight alignment candidates are the eight symmetries of the rectangle, so in best-of-eight mode pre-applying an Orientation only reshuffles the score list. The shipped fallback compounds this: its main image is 640 by 400 and its thumbnail grid is 160 by 100, the same 1.6 ratio, so contain and centre crop resample to the same pixels. The check panel recomputes both facts on your file rather than asserting them.
A second indicator, cheaper than pixels
Exif also stores the main image's size, as PixelXDimension (40962) and PixelYDimension (40963), separately from the size in the compressed frame header. Those two claims can fall out of step with the actual SOF when software rewrites pixels and copies metadata. Note what makes it an indicator at all: the SOF number is read from the image data, while the tag is read from the copied metadata. Comparing the tag against the tag would agree after any edit whatever, which is a comparison that cannot come back negative.
No stored PixelXDimension or PixelYDimension claim is current.
The clocks do not form one clock
Exif stores claims made by software. They are mutable and unauthenticated. Its three offset tags apply only to their paired base timestamps. A local timestamp without its offset cannot safely be ordered against UTC, GPS, or the picker's modification time. The picker exposes only File.lastModified, never birth time or access time.
Two limits on the table below. The offset tags are recent: OffsetTime, OffsetTimeOriginal, and OffsetTimeDigitized do not appear anywhere in Exif 2.3 (CIPA DC-008-2012) and first appear in Exif 2.31 (DC-008-2016), so an unqualified local wall clock is the ordinary case rather than the exception. And this table is not every clock in your file: MakerNote often carries vendor timestamps this page refuses to decode, and XMP or IPTC blocks in other segments are not read at all. It lists the standard Exif and GPS time fields it recognises, and nothing more.
| stored component | source | raw value | standard meaning | zone and comparison |
|---|
Waiting for stored time components.
Read the table as a third indicator rather than as support for the pictures above. DateTime is defined as file change time and DateTimeOriginal as when the original image data was generated, so software that rewrites a file and updates one of them leaves a gap that has nothing to do with whether the thumbnail was regenerated. The two indicators disagree often, and neither is the ground truth for the other. Equal values are also completely ordinary.
Bytes the page declines to interpret
MakerNote is manufacturer-controlled UNDEFINED data. The instrument shows its complete bounded span, count, hash, and bytes. It does not guess a vendor schema or follow private internal pointers. GPS can be sensitive. Presence is reported, but coordinates stay behind a deliberate reveal and are never sent to a map or geocoder.
No MakerNote has been read.
GPS tags not yet inspected
The check
Waiting for the fallback.
Every line below is recomputed from the complete current file, and the lines are labelled by what they can actually catch, because a check that cannot fail is decoration. A line marked PARSER POSTCONDITION restates something the parser already refused to proceed without, so it shows you the value but cannot come back red on a file the parser accepted. A line marked INDEPENDENT recomputes the same quantity a second time by a separate route and can disagree: the thumbnail offsets are decoded again from the raw twelve entry bytes without the parser's arithmetic, the file is re-sliced at those independently obtained offsets and re-hashed, the mean absolute difference is summed again outside comparePixels, and the eight alignment candidates are checked for the group property that makes the Orientation control redundant in automatic mode. Lines marked FILE, ANCHOR, SECOND INDICATOR, or CONFORMANCE are statements about your specimen rather than about the instrument, and red there means your file lacks the named property, which is information and not a fault. The same parser is imported by the offline verifier, which constructs wrong magic, truncation, lying JPEG length, cyclic IFD, out-of-bounds thumbnail, bad thumbnail SOI, unsupported compression, malformed clocks, and missing EOI specimens, requires every refusal code in the parser to be reached by an executed case, and asserts the exact refusal code and byte.
Every parsed IFD entry
| IFD | tag | type | count | entry byte | value form and bounded range |
|---|
JPEG marker walk
| marker | marker byte | declared length | data range |
|---|
Every free choice and uncertainty
- Exif selection: first structurally valid Exif APP1 in file order.
- Orientation: apply each image's own Orientation.
- Alignment: best of eight deterministic transforms.
- Fit: contain with black outside.
- Resampler: fixed source-code bilinear, pixel-centre mapping.
- Decode: browser JPEG decoder, imageOrientation none when createImageBitmap honours it, then canvas RGBA.
- Difference: absolute RGB channels, divided by 3 × 255 × pixel count; continuous heatmap; no threshold.
- Uncertainty: browser JPEG colour management and rounding can change decoded pixels. Raw slices and SHA-256 hashes are decoder-independent.
- Second indicator: stored PixelXDimension and PixelYDimension against the actual frame header, which is metadata against pixels and not metadata against itself.
- Clock ranges: this page's own bounds, not the standard's, are UTC offsets within plus or minus 14:00 and seconds within 0 to 59.
- Safety caps: 96 MiB source read, 40 megapixel decode, 1,024 entries per IFD, 32 MiB per TIFF value. The source is refused, never truncated or uploaded.
The local boundary, made visible
The current file is consumed only by arrayBuffer() and short-lived blob: URLs used by the browser decoder. It is never passed to a network API. Open your browser's Network panel and repeat the drop if you want an independent view. Page modules, fonts, and the home banner may appear as same-origin resources coming into the page. Your file will not appear.
Active Content Security Policy
default-src 'self'; connect-src 'none'; img-src 'self' blob: data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self'; object-src 'none'; base-uri 'none'; form-action 'self'
form-action 'self' rather than 'none': the site banner injects a same-origin search form, and 'none' left that control visible but dead. Your file is never in a form, and connect-src 'none' still forbids every fetch, XHR, WebSocket, EventSource, and beacon destination.