Build1 publisher2 min readPublished
Fitting Annex K to WhatsApp's returned JPEGs leaves a 37% mean residual
A month of measured round trips on one handset found WhatsApp, Instagram and Facebook encoding on quantization tables the JPEG standard never described, while Telegram sent back a plain scaled Annex K near quality 87.
The Engineer · Build desk

What happened
- A developer spent a month sending images through WhatsApp, Instagram, Facebook and Telegram on one phone, several hundred round trips, then read the quantization table out of each file that came back.
- WhatsApp's standard send returned a byte-identical luma table across 82 files and five different output geometries, running from 6 in the low frequencies to 167 in the far corner.
- The best Annex K fit for that table is a 0.650 scale, nominally quality 68, but the per-coefficient ratios run from 0.28 to 1.69 with a 37% mean residual.
- Instagram's much flatter table, mean 15.8 and progressive, comes back byte-identical from Facebook, so only the output geometry separates files from the two Meta products.
- Telegram was the ordinary case, returning a scaled Annex K table near quality 87 with nothing custom about it.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint Provenance tooling can still name the Meta pipeline from a header, but it cannot say which Meta product the file left without measuring the geometry too.
- exposure Anything that depends on where pixels sit fails silently on WhatsApp, because the file that comes back still looks like the photo the user shot.
- capability Encoding on the platform's own extracted table leaves its re-encoder nothing to requantize: embedding-band survival went from 85.9% to 100% and the strength needed halved, so the carrier looked cleaner.
- decision Anyone hiding data in a photo now designs for the platform's output geometry before upload, because what worked was giving the platform an image it had no reason to resample.
A quantization table normally identifies the encoder and its quality setting. Most software takes the Annex K reference table from the JPEG standard, scales it by one number and writes the result into the file, so reading the table back usually tells you what produced the image [2]. That inference only holds when the fit is close. For WhatsApp's standard send, the per-coefficient ratios against scaled Annex K span about six to one [12], the average step size corresponds to something near quality 65, and the roll-off toward high frequencies is far steeper than Annex K's [5].
A hardcoded table is still a build fingerprint. WhatsApp HD is a different table again, mean 12.2 against 35.6 for the standard send [10][3], roughly 2.9 times finer per coefficient [11].
Payload bits live in the 8x8 DCT blocks JPEG is built from. When a platform resamples the image, the block grid shifts, the decoder starts reading across boundaries, and the data is destroyed [17]. Every catastrophic failure in the measurements landed at roughly a 50% bit error rate, which is what guessing produces [18].
Instagram upscaled a 1080-wide upload to 1440 and padded a 4:3 image to square, so there is no size small enough to be safe [13]. WhatsApp caps the long edge, and a portrait photo came back 1200x1600 [14]. It also applies the EXIF orientation flag to the pixels and strips the tag: a 3840x2160 file sent with orientation=6 returned as 2160x3840 with no orientation tag [15]. For an ordinary photo that is correct and invisible; for a watermark or a forensic pixel comparison, a silent 90-degree rotation is total loss [16].
All of this is four production upload paths measured on a single handset over a month [1]. The dev.to post does not include app build numbers or the dates of the sends [22]. Byte-identical output across dozens of files shows the table is compiled into the build that answered, not that the next release keeps it. For the tables and the survival numbers to transfer to your pipeline, you need the same app builds and the same send mode, and standard send and HD are already two different tables inside one app [10].
What to watch
- A WhatsApp or Meta client update that changes the hardcoded tables, which would retire any fingerprint built on the 82-file result.
- Whether Telegram stays on scaled Annex K near quality 87 or moves to a custom table like the Meta pipeline.
- Whether the geometry rules reproduce on other handsets and OS builds, since every measurement here came from one phone.