Give any photo a gain map so highlights can go brighter than white on an HDR display. If your camera already captured one, we carry it through untouched. If it did not, we build a plausible one.
Which lane your file takes is decided by the file itself, not by a setting. Drop it in and Mochify checks whether a gain map is already there.
Your file already carries a gain map
Ultra HDR JPEGs from Pixel and recent Android phones, Apple Adaptive HDR JPEGs shared out of iPhone
The map your camera measured is carried through resize, crop and rotate, then re-encoded verbatim. Nothing is recomputed, because a derived map is measurably worse than the one the sensor produced.
Your file is plain SDR
Ordinary JPEGs, PNGs, WebP, AVIF, and HEIC or HIF photos, which never carry a gain map Mochify can read
A gain map is synthesised from the highlights already in the frame: a smooth ramp that starts around three-quarters brightness and climbs to roughly 1.5 stops, tempered by local contrast so a bright sky lifts differently from a white shirt.
Generated headroom is invented, not recovered. Nothing can retrieve detail your camera never wrote down. Synthesis reads the highlights that did survive and builds a brightness curve from them, which looks convincing on an HDR screen but is an effect rather than measured data. Every response says which one you got: the X-Mochify-HDR header returns true for preserved, generated for synthesised, and false when the result carries none.
An ordinary photo tops out at white. A phone screen can go several times brighter than that, and a gain map is how a single file uses the extra range: a small, smooth, half-resolution brightness multiplier stored next to the normal picture.
An HDR display multiplies one by the other and gets a brighter rendition. Everything else ignores the map entirely and shows the plain image. That is why the output here is still a JPEG that opens anywhere, and why there is no second file to keep track of.
Brightness alone cannot distinguish a specular highlight from a blown sky from a white shirt, so a curve on brightness alone lifts all three equally and the result looks flat and artificial. The map here starts from a smooth ramp above roughly three-quarters brightness, climbing to about 1.5 stops, then corrects it by local contrast so isolated bright detail lifts more than a broad pale region.
We deliberately do not run a neural model. A gain map gets low-passed to half resolution and compressed hard before it reaches the file, and the invented structure a model contributes does not survive that. A curve produces the same surviving result without the cost.
An Ultra HDR file is two pictures in one wrapper: the standard-range base everything sees, and the gain map on top of it. That makes the JPEG encoder matter more here than it does for an ordinary photo, because you are paying for the extra layer out of the same byte budget.
Mochify swaps the system JPEG library for Google's jpegli across the whole encoder, so the HDR path writes through it too. Better quality-per-byte on the base image is what keeps the gain map close to free: the map itself is stored at half resolution and compressed hard, so the extra usually lands in the low single-digit percentages.
Ultra HDR: an ordinary JPEG with a gain map attached. The only output here that can carry one.
No gain map concept. HDR lives in the pixels as linear float, so it works from a real HDR source but there is nothing to synthesise into.
Our encoder path flattens to 8-bit sRGB before AVIF is written, which clips every highlight above white. Claiming HDR here would be a lie.
The format cannot represent HDR in any form.
The format cannot represent HDR in any form.
A gain map is a ratio to the image underneath it. Change that image and the ratio stops meaning what it meant, so these operations return a clean standard-range file instead of one labelled HDR that no longer is.
A gain map is a ratio to its base image. Shift the base and the ratio now means something different.
Sharpening round-trips through a bounded 16-bit Lab space, which clips everything above standard white on the way in.
Matting runs on standard-range pixels and composites against 0-255 colours, which are meaningless against the 0-1 scale HDR works in.
Same reason as background removal: the compositing step has no notion of headroom.
One parameter. Use hdr=true to preserve only, or hdr=generate to preserve and synthesise, which is what this page sends.
curl -X POST "https://api.mochify.app/v1/squish?type=jpg&hdr=generate" \
-H "X-API-Key: $MOCHIFY_KEY" \
--data-binary @photo.jpg \
-D headers.txt -o photo-hdr.jpg
grep X-Mochify-HDR headers.txt
# X-Mochify-HDR: generatedOne caveat worth knowing if you script this: on the HDR path only quality reaches the encoder. optimizeForWeb is accepted but has no effect, because progressive scan and 4:2:0 chroma belong to the plain JPEG writer that an Ultra HDR request does not go through. Full parameter reference lives in the API documentation.
Also available