THE JPEG ROUND TRIP / ORIGINAL BYTES
A smaller envelope.
The same JPEG inside.
A JPEG XL file can preserve an existing JPEG for exact reconstruction. Exporting a new JPEG at quality 100 is a different operation. We ran both paths on the same original.
source.jpg
133,370 bytes
Our illustration encoded as an ordinary JPEG.jpeg-preserved.jxl
92,291 bytes
Encoded with lossless_jpeg=1.restored.jpg
133,370 bytes
Byte-for-byte equal to source.jpg.The equality is in the file.
The original and reconstructed JPEG have the same SHA-256 digest:
c6597fa19f5fcaebca4139b43a5f23acd614e91073826729e2a2bd9496d39d9bWe also compared every byte directly. Both checks matched. For this sample, the JXL file is 30.8% smaller than its source JPEG. This says nothing about how much another JPEG will shrink, and it does not repair quality already lost when the original JPEG was made.
Run the deliberate path.
Use the full option names. The short -j flag means different things in the encoder and decoder; the verbose names make the intended operation explicit.
cjxl source.jpg jpeg-preserved.jxl --lossless_jpeg=1 -e 7
djxl jpeg-preserved.jxl restored.jpg --reconstruct_jpeg
cmp source.jpg restored.jpg
shasum -a 256 source.jpg restored.jpgIn a terminal, cmp returning exit status 0 with no difference output means the bytes match. A matching hash is a convenient additional record. On systems without these commands, use a binary file comparison and SHA-256 utility. The downloadable files let you check the result without re-encoding anything.
THE DETOUR THAT CHANGES THE RESULT
“Quality 100” is a new JPEG.
djxl jpeg-preserved.jxl quality-100.jpg --pixels_to_jpeg --jpeg_quality=100This command decodes pixels and encodes a new JPEG. Our result grew to 654,553 bytes and its digest changed to 203cc6532c1a51066977bdcaf2a3f7b23b9e728b31d3f839fad6b5677e3bc596
It also changed 1,366,491 decoded RGB channel values relative to the source JPEG in our local comparison. A high quality setting is a choice for a new lossy encoding, not an instruction to restore original bytes. The larger file did not recover the pre-JPEG illustration either.
Download the re-encoded JPEG · Inspect the actual command log
Check the files you actually kept.
A screenshot of matching hashes is useful documentation. It does not check the two files now in your Downloads folder. A renamed file, an older result or a saved error page can make a visually plausible folder that contains the wrong pair.
Download the original reference-file checker. Put it beside the source JPEG and reconstructed JPEG, then run it with Node 20 or later:
node verify-roundtrip.mjs source.jpg restored.jpgThe checker reads only the two local files you name and prints a JSON record. It does not connect to a server, encode an image or write a file. It calculates each SHA-256, compares the actual byte buffers, and checks that the source matches this page’s published reference digest. That last condition stops two identical wrong files from being mistaken for this particular experiment.
Expected reference pair
sourceMatchesPublishedSample: true
restoredBytesEqualSource: true
exit status: 0Both files are 133,370 bytes. We ran this checker against the supplied pair and obtained both true results.
The deliberate negative control
node verify-roundtrip.mjs source.jpg quality-100.jpgThe source still matches, but byte equality is false and the process exits with status 1. This control was also run. The re-encoded image can look related while being the wrong answer to a preservation requirement.
If the check fails, keep the evidence.
First read which condition failed. A false source-reference check means this is not the exact published source; it says nothing by itself about whether your own image is good or bad. A true source check with false equality means the second file differs. Inspect the filenames, sizes and digests before deciding whether the cause was conversion, a different version or a failed download.
The script intentionally knows this one synthetic source. It is not an archive crawler or a general JPEG validator. For another collection, establish each original’s identity and keep an independently recorded manifest before using a similar comparison. Do not edit the expected hash merely to make an unexplained mismatch disappear.
Keep three conclusions separate.
Same bytes answers whether this JPEG was reconstructed exactly. Same decoded pixels requires the pixel comparison in the illustrated study. Same appearance depends on the display path and cannot be established by either a filename or a file-size reduction. State the conclusion your evidence actually supports when sharing the result.
Keep preservation claims narrow.
This round trip used a synthetic JPEG with no imported EXIF collection. We did not test a camera archive, damaged files or all JPEG variants. Metadata removal or later edits can affect reconstruction; do not assume a JXL remains reconstructable after a separate program rewrites it. Test the final retained file, not only the first encoder output.
For your own archive, retain originals and backups while testing a copy of representative files. Record the encoder version and compare reconstructed bytes. A successful sample here is a worked example, not permission to delete your original collection.
The full pixel experiment answers another question: can the decoded colour values survive exactly? Return to the illustrated study, or follow the image onto a public page.
Primary references: cjxl manual, djxl manual, libjxl 0.12.0 release. Commands were actually executed with that version.