HDR Surgery

Ultra HDR JPEG editor and gain map inspector for JavaScript

Inspect and edit Ultra HDR JPEG, JPEG_R, JPEGR, and ISO 21496-1 gain-map images in JavaScript or TypeScript. The work stays in your browser.

Local processingNo image is uploaded to an application server.

Quick answer

PureJsImage can inspect, render, crop, resize, and re-encode an Ultra HDR JPEG without silently discarding its HDR gain map. It keeps an ordinary SDR JPEG as the backward-compatible primary and transforms the primary and gain map over the same image region.

  1. The ordinary SDR JPEG is the backward-compatible primary.
  2. A smaller encoded gain map plus metadata describes highlight recovery.
  3. PureJsImage applies it in linear light for the selected display boost and transforms both images together.

Important: this tool does not create genuine HDR detail from an unrelated SDR image.

Interactive workbench

Adapted result

Current preview geometry, SDR tone map

Move over the preview to inspect preview pixel values.

Highlight map

Current preview geometry, false color

SDR primary

Current preview-scaled base

Encoded gain map

Current preview-scaled map samples

Image summary

Container
Waiting

Source byte ranges

Raw metadata JSON
Waiting for inspection.
Raw execution evidence JSON
Waiting for execution.

How Ultra HDR JPEG gain maps work

An Ultra HDR JPEG stores a normal SDR primary plus a smaller gain-map JPEG. MPF locates the child images. GContainer XMP and Ultra HDR XMP or ISO 21496-1 metadata describe how encoded map samples recover highlight headroom. An ordinary JPEG viewer still reads the SDR primary.

JavaScript API example

import { openGainMapImage } from 'purejsimage/hdr'

const image = await openGainMapImage(bytes)
const output = await image.crop({ x: 0, y: 0, width: 1200, height: 800 })
  .resize({ width: 600, height: 400 })
  .jpeg({ metadataMode: 'dual' })
image.close()

Inspect without decoding pixels

inspectGainMapImage() reads bounded JPEG markers, XMP, ISO metadata, MPF ranges, and dimensions. It does not entropy-decode either child image.

Transform and re-encode both images together

Crop, flip, EXIF auto-orientation, quarter turns, and resize are planned for both images. Large images use an additional preview-only fit while export controls keep the logical output dimensions. extractOriginalBase() and extractOriginalGainMap() always return the byte-exact source children.

ISO 21496-1 versus Ultra HDR XMP

Dual output carries both representations for compatibility. Valid ISO 21496-1 metadata is preferred when both agree. Ultra HDR XMP in this release requires an SDR base. Invalid or conflicting gain metadata fails explicit HDR opening without blocking ordinary SDR JPEG display.

AVIF gain-map support

purejsimage/hdr also opens the documented AVIF gain-map subset, including its proven HDR-base input path. Output is narrower: opaque sRGB SDR base pixels, one semantic gain channel encoded as achromatic YUV, ISO metadata, and constrained first-party AV1 dimensions.

Node.js and browser usage

Node.js accepts bytes and file-backed inputs through the normal source APIs. Browsers accept File, Blob, ArrayBuffer, and Uint8Array. Shared HDR parsing, transforms, and codecs stay in portable strict TypeScript.

Ultra HDR JPEG samples

Limits and non-goals

HDR Surgery does not synthesize HDR from unrelated SDR and HDR images. It does not author C2PA, HEIF, JPEG XL, AVIF animation, arbitrary-angle rotation, drawing, filters, text, or compositing. JPEG gain-map input is SDR-base only in this release.

FAQ

What is an Ultra HDR JPEG?

It is a backward-compatible SDR JPEG plus an encoded HDR gain map and reconstruction metadata.

Is JPEG_R or JPEGR the same as Ultra HDR?

JPEG_R and JPEGR are common names for the gain-map JPEG form used by Ultra HDR workflows.

Can JavaScript edit an Ultra HDR image without discarding its gain map?

Yes. PureJsImage applies supported geometry to both the primary and map, then writes a compound output.

Does the output remain readable by an ordinary JPEG viewer?

Yes. The first child is an ordinary SDR JPEG primary.

What is ISO 21496-1?

It defines gain-map metadata that can describe an alternate rendition and display-capacity behavior.

Does PureJsImage generate HDR from a normal SDR JPEG?

No. It does not invent genuine HDR detail from an unrelated SDR image.

Does it work in Node.js and browsers?

Yes. The portable TypeScript path supports both, with runtime-specific source and sink adapters.

Does it support AVIF gain maps?

It opens the documented AVIF gain-map subset and writes a narrower opaque sRGB, one-channel subset.