Add withGainMap to process HDR JPEGs with embedded gain map #4314

This commit is contained in:
Lovell Fuller
2025-12-19 15:04:19 +00:00
parent f6cdd36559
commit aaeded2b67
16 changed files with 197 additions and 2 deletions

View File

@@ -313,6 +313,7 @@ const Sharp = function (input, options) {
withExif: {},
withExifMerge: true,
withXmp: '',
withGainMap: false,
resolveWithObject: false,
loop: -1,
delay: [],

7
lib/index.d.ts vendored
View File

@@ -1277,6 +1277,8 @@ declare namespace sharp {
formatMagick?: string | undefined;
/** Array of keyword/text pairs representing PNG text blocks, if present. */
comments?: CommentsMetadata[] | undefined;
/** HDR gain map, if present */
gainMap?: GainMapMetadata | undefined;
}
interface LevelMetadata {
@@ -1289,6 +1291,11 @@ declare namespace sharp {
text: string;
}
interface GainMapMetadata {
/** JPEG image */
image: Buffer;
}
interface Stats {
/** Array of channel statistics for each channel in the image. */
channels: ChannelStats[];

View File

@@ -607,6 +607,7 @@ function _isStreamInput () {
* - `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
* - `formatMagick`: String containing format for images loaded via *magick
* - `comments`: Array of keyword/text pairs representing PNG text blocks, if present.
* - `gainMap.image`: HDR gain map, if present, as compressed JPEG image.
*
* @example
* const metadata = await sharp(input).metadata();

View File

@@ -319,6 +319,30 @@ function withIccProfile (icc, options) {
return this;
}
/**
* If the input contains gain map metadata, use it to convert the main image to HDR (High Dynamic Range) before further processing.
* The input gain map is discarded.
*
* If the output is JPEG, generate and attach a new ISO 21496-1 gain map.
* JPEG output options other than `quality` are ignored.
*
* This feature is experimental and the API may change.
*
* @since 0.35.0
*
* @example
* const outputWithGainMap = await sharp(inputWithGainMap)
* .withGainMap()
* .toBuffer();
*
* @returns {Sharp}
*/
function withGainMap() {
this.options.withGainMap = true;
this.options.colourspace = 'scrgb';
return this;
}
/**
* Keep XMP metadata from the input image in the output image.
*
@@ -1640,6 +1664,7 @@ module.exports = (Sharp) => {
withExifMerge,
keepIccProfile,
withIccProfile,
withGainMap,
keepXmp,
withXmp,
keepMetadata,