Skip to content
App-Vault

Turn a JPG into an Ultra HDR file with a gain map

One file that is an ordinary JPEG to everything old and a high-dynamic-range image to everything current. The container is parsed again after it is built, and nothing is offered for download until its own headers check out.

DROP · PASTE · CHOOSE

Drop a JPG, PNG or WebP here

or . It is opened in this browser tab and never uploaded — this page has no endpoint to upload it to.

What a gain map actually is

An ordinary JPEG describes brightness on a scale that runs out at white. A screen with high dynamic range can go considerably brighter than that white — several times brighter for small areas — and the format has no way to say which parts of the picture should use that headroom.

A gain map is the missing instruction. It is a second, smaller greyscale image stored alongside the first, in which each value says how much extra brightness the corresponding part of the picture should receive, expressed in stops. A renderer with headroom multiplies; a renderer without it ignores the whole thing and displays the base image. That is the entire idea, and its elegance is that the file degrades perfectly: on a screen from 2012 it is simply a JPEG.

Google shipped this as Ultra HDR with Android 14. The container is an XMP directory naming the two images, plus a Multi-Picture Format index — the CIPA standard originally written for stereoscopic cameras — giving the byte offset of the second one. Apple's HDR photographs use the same underlying idea, and ISO 21496-1 has since formalised it.

The honest version of "convert SDR to HDR"

Searching for this phrase produces a great deal of software promising to add dynamic range to a finished photograph. What is being added is an interpretation, not information.

When a camera clipped a highlight, every channel in that pixel reads 255 and there is nothing behind it. No later process recovers what the sensor did not record; the most an upscaler or a generative model can do is invent something plausible, which is fine for a wallpaper and disqualifying anywhere the picture is meant to be evidence.

What this tool does instead is decide, per pixel, how much of the display's headroom the highlights that do exist should be given, and write that decision down in the form every current HDR pipeline reads. On an HDR screen the result is a brighter, more three-dimensional version of the same photograph — a window that looks like a window rather than a white rectangle, a reflection with some sparkle in it. On every other screen it is byte-for-byte the same picture you started with.

That is a real improvement and a modest one, and the difference between saying so and saying "convert your photos to true HDR" is the whole reason this section exists.

Why only the highlights

The commonest way to make a gain map badly is to apply gain everywhere. It is easy, it makes the image obviously different, and it looks like somebody turned the screen brightness up — which is precisely what it is. Dynamic range is about the distance between the dark parts and the bright parts, so lifting both ends equally adds none of it.

The curve here is zero below about 35 per cent linear luminance and eases in above it with a smoothstep, so midtones and shadows receive no gain at all and the effect concentrates where specular highlights live: a window, sun on water, a chrome edge, a light source in the frame. The receipt reports the maximum gain the image actually asked for, which is usually well under the preset's ceiling — a photograph with no bright highlights gets very little gain no matter which preset you choose, and that is correct behaviour rather than a fault.

The three presets are gentle at one stop, standard at 2 stops, strong at 3 stops. Three stops is roughly what a current phone camera records natively, so it is the honest upper bound for a synthesised map; past that the result stops looking like a photograph.

What is inside the file

The output is a single JPEG. Reading it from the front: the start-of-image marker, a JFIF header, an XMP packet declaring a container directory with two items — a Primary and a GainMap with its exact byte length — then a Multi-Picture Format segment holding a two-entry index, then the ordinary compressed image data of the SDR photograph. After that image's end-of-image marker, a second complete JPEG follows: the gain map, at half the linear resolution, carrying its own XMP with the parameters a renderer needs — the maximum gain in stops, the gamma, the offsets, and the capacity range.

Two numbers in that structure have to agree with reality or the whole thing is inert: the declared length of the gain map, and the byte offset in the MPF index, which is measured from an origin inside the MPF segment itself rather than from the start of the file. That relative origin is the part every implementation gets wrong at least once.

So the tool reads its own output back before offering it. It re-parses the XMP and checks that both items are declared; follows the MPF offset and checks that it lands on a JPEG start-of-image marker; compares the declared length against the bytes actually present; and confirms that the gain map carries a version and a maximum. Every one of those findings is printed in the receipt. If any fails, nothing is produced — a file whose headers lie about their own contents fails somewhere else, later, in a way nobody traces back here.

Where you will and will not see it

The effect appears on Android 14 and later in Google Photos and Chrome, on recent iOS and macOS in Photos and Safari when the display has headroom, and in Chrome on a desktop HDR monitor. A standard office monitor has no headroom to use, so it correctly shows the base image and nothing appears to happen.

That is also the limit of what can be verified here. Nothing running in a browser tab can measure your display's peak luminance or test another device's renderer, so the tool states what it checked — the container — and does not imply anything about what it did not. Where a page on this site cannot check a claim, it says so; that rule is the same one behind the QR generator's refusal to promise that a particular camera will read a particular print.

Software that does not understand gain maps — an older desktop viewer, a print workflow, most content management systems — sees a JPEG with two unfamiliar metadata segments and displays the base image. That is the format working as designed. A few tools will strip the extra segments on re-save, which removes the HDR silently; if a file has to survive a pipeline, check it at the far end.

Cost, and when not to bother

A gain map adds roughly 15 to 30 per cent to the file. Gain maps are smooth by nature and compress well, and half the linear resolution is visually indistinguishable from full because the map is multiplied against a full-resolution image.

It is not worth building one for a picture with no bright highlights — an evenly lit interior, a flat grey sky, a document scan. There is nothing for the headroom to do, the receipt will say the peak gain was near zero, and you will have paid the file size for nothing. It is very much worth it for a sunset, a window, a night scene with light sources in it, or anything with water or metal in the frame.

A genuinely dark photograph is a different problem and wants the brightener, which changes the pixels everyone sees rather than what a capable screen does with them. And as with every tool here that re-encodes, the output carries no metadata from the source: no location, no camera, no serial numbers — the metadata tool is where to look at what a file holds before deciding what to do about it.

WHAT IT DOES NOT DO

The limits, stated here rather than discovered later

  • This does not recover detail that was clipped. A blown-out sky is 255 in every channel and there is nothing behind it; the gain map decides how much brighter the highlights that do exist should be rendered.
  • Whether you see the effect depends on your screen, your operating system and the application. Nothing running in a browser tab can test that, so the tool does not claim to.
  • A viewer that does not understand gain maps shows the SDR base image, unchanged. That is the format working as designed, not a failure.
  • The file is roughly 15-30% larger than the plain JPEG of the same picture, which is the gain map.

What is checked: The produced file is parsed again: the XMP container must declare both items, the MPF offset must land on a real JPEG start marker, the declared and actual gain-map lengths must match, and the gain map must carry its hdrgm parameters.

Questions people ask about this

  1. 01 What is Ultra HDR?
    A format Google introduced with Android 14: a normal SDR JPEG with a second, smaller image appended — a gain map — plus the metadata that tells a renderer how to combine them. On an HDR display the gain map brightens the highlights beyond what SDR can show; on anything else the base JPEG is displayed and the rest is ignored.
  2. 02 Can you really convert an SDR photo to HDR?
    You can build a valid HDR container from it, which is what this does, and on an HDR screen it will genuinely look brighter and more three-dimensional. What you cannot do is recover information the camera never recorded. Anything claiming to add real dynamic range to a finished JPEG is describing an interpretation, not a recovery, and this page says so rather than selling it.
  3. 03 Where will the effect actually show?
    Android 14 and later in Google Photos and Chrome, recent iOS and macOS in Photos and Safari on a display with HDR headroom, and Chrome on a desktop HDR monitor. A standard office monitor has no headroom to use, so you will correctly see the base image.
  4. 04 How big is the gain map?
    Half the linear resolution of the picture, encoded as a JPEG, which typically adds 15-30% to the file. Gain maps are smooth by nature, so they compress well and half resolution is visually indistinguishable from full.
  5. 05 Is my photo uploaded?
    No. Both encodes and the verification pass run in this browser tab.
  6. 06 Why does the tool only brighten the bright parts?
    Because lifting the whole image is a brightness slider, not high dynamic range, and it is what makes a cheap conversion look like a washed-out screen. The gain curve here is zero below about 35% linear luminance and eases in above it, so specular highlights come forward and the rest of the photograph is left alone.
  7. 07 Is this the same as ISO 21496-1?
    It is the widely-deployed predecessor of it. Ultra HDR as shipped by Android uses an XMP container directory plus a CIPA DC-007 Multi-Picture Format index, and the ISO standard formalises the same idea. Files written here are read by the Ultra HDR pipeline on Android, Chrome and Apple platforms.

Other tools on this site

All 10 tools

These tools exist because the same problem keeps turning up underneath the app: a photograph says more than the person sending it meant to. App-Vault is the iPhone side of that — an encrypted vault for the files that should not be in the camera roll at all. What the vault does, the cryptography behind it are documented rather than asserted.

GET STARTED

Seal the vault.

Free to download. The free tier holds one file. Premium removes the limit — Weekly from $3.99 or Yearly from $29.99 with a 7-day free trial.