Compare commits

...

4 Commits

Author SHA1 Message Date
Lovell Fuller
aaeded2b67 Add withGainMap to process HDR JPEGs with embedded gain map #4314 2025-12-19 15:41:09 +00:00
Lovell Fuller
f6cdd36559 Bump devDeps 2025-12-18 22:47:14 +00:00
Lovell Fuller
283c7d3f0c Drop Node.js 18, now requires Node.js >= 20.9.0 2025-12-17 15:08:34 +00:00
Lovell Fuller
34c39fa194 Upgrade to libvips v8.18.0-rc.2 2025-12-17 13:26:51 +00:00
40 changed files with 341 additions and 131 deletions

View File

@@ -31,7 +31,7 @@ please open an issue against that package instead.
<!-- Please place an [x] in the relevant box to confirm. --> <!-- Please place an [x] in the relevant box to confirm. -->
- [ ] I am using Node.js with a version that satisfies `^18.17.0 || ^20.3.0 || >=21.0.0` - [ ] I am using Node.js with a version that satisfies `>=20.9.0`
- [ ] I am using Deno - [ ] I am using Deno
- [ ] I am using Bun - [ ] I am using Bun

View File

@@ -9,8 +9,8 @@ jobs:
contents: read contents: read
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- uses: actions/setup-node@v5 - uses: actions/setup-node@v6
with: with:
node-version: "24" node-version: "24"
- run: npm install --ignore-scripts - run: npm install --ignore-scripts
@@ -31,123 +31,129 @@ jobs:
- os: ubuntu-24.04 - os: ubuntu-24.04
container: rockylinux:8 container: rockylinux:8
nodejs_arch: x64 nodejs_arch: x64
nodejs_version: "^18.17.0" nodejs_version: "^20.9.0"
nodejs_version_major: 18 nodejs_version_major: 20
platform: linux-x64 platform: linux-x64
package: true package: true
- os: ubuntu-24.04 - os: ubuntu-24.04
container: rockylinux:8 container: rockylinux:8
nodejs_arch: x64 nodejs_arch: x64
nodejs_version: "^20.3.0" nodejs_version: "^22"
nodejs_version_major: 20
platform: linux-x64
- os: ubuntu-24.04
container: rockylinux:8
nodejs_arch: x64
nodejs_version: "^22.9.0"
nodejs_version_major: 22 nodejs_version_major: 22
platform: linux-x64 platform: linux-x64
- os: ubuntu-24.04 - os: ubuntu-24.04
container: node:18-alpine3.17 container: rockylinux:8
nodejs_version_major: 18 nodejs_arch: x64
platform: linuxmusl-x64 nodejs_version: "^24"
package: true nodejs_version_major: 24
platform: linux-x64
- os: ubuntu-24.04 - os: ubuntu-24.04
container: node:20-alpine3.18 container: node:20-alpine3.18
nodejs_version_major: 20 nodejs_version_major: 20
platform: linuxmusl-x64 platform: linuxmusl-x64
package: true
- os: ubuntu-24.04 - os: ubuntu-24.04
container: node:22-alpine3.20 container: node:22-alpine3.20
nodejs_version_major: 22 nodejs_version_major: 22
platform: linuxmusl-x64 platform: linuxmusl-x64
- os: ubuntu-24.04
container: node:24-alpine3.22
nodejs_version_major: 24
platform: linuxmusl-x64
- os: ubuntu-24.04-arm - os: ubuntu-24.04-arm
container: arm64v8/rockylinux:8 container: arm64v8/rockylinux:8
nodejs_arch: arm64 nodejs_arch: arm64
nodejs_version: "^18.17.0" nodejs_version: "^20.9.0"
nodejs_version_major: 18 nodejs_version_major: 20
platform: linux-arm64 platform: linux-arm64
package: true package: true
- os: ubuntu-24.04-arm - os: ubuntu-24.04-arm
container: arm64v8/rockylinux:8 container: arm64v8/rockylinux:8
nodejs_arch: arm64 nodejs_arch: arm64
nodejs_version: "^20.3.0" nodejs_version: "^22"
nodejs_version_major: 20 nodejs_version_major: 22
platform: linux-arm64
- os: ubuntu-24.04-arm
container: arm64v8/rockylinux:8
nodejs_arch: arm64
nodejs_version: "^24"
nodejs_version_major: 24
platform: linux-arm64 platform: linux-arm64
- os: macos-15-intel - os: macos-15-intel
nodejs_arch: x64 nodejs_arch: x64
nodejs_version: "^18.17.0" nodejs_version: "^20.9.0"
nodejs_version_major: 18 nodejs_version_major: 20
platform: darwin-x64 platform: darwin-x64
package: true package: true
- os: macos-15-intel - os: macos-15-intel
nodejs_arch: x64 nodejs_arch: x64
nodejs_version: "^20.3.0" nodejs_version: "^22"
nodejs_version_major: 20 nodejs_version_major: 22
platform: darwin-x64 platform: darwin-x64
- os: macos-15-intel - os: macos-15-intel
nodejs_arch: x64 nodejs_arch: x64
nodejs_version: "^22.9.0" nodejs_version: "^24"
nodejs_version_major: 22 nodejs_version_major: 24
platform: darwin-x64 platform: darwin-x64
- os: macos-15 - os: macos-15
nodejs_arch: arm64 nodejs_arch: arm64
nodejs_version: "^18.17.0" nodejs_version: "^20.9.0"
nodejs_version_major: 18 nodejs_version_major: 20
platform: darwin-arm64 platform: darwin-arm64
package: true package: true
- os: macos-15 - os: macos-15
nodejs_arch: arm64 nodejs_arch: arm64
nodejs_version: "^20.3.0" nodejs_version: "^22"
nodejs_version_major: 20 nodejs_version_major: 22
platform: darwin-arm64 platform: darwin-arm64
- os: macos-15 - os: macos-15
nodejs_arch: arm64 nodejs_arch: arm64
nodejs_version: "^22.9.0" nodejs_version: "^24"
nodejs_version_major: 22 nodejs_version_major: 24
platform: darwin-arm64 platform: darwin-arm64
- os: windows-2022 - os: windows-2022
nodejs_arch: x86 nodejs_arch: x86
nodejs_version: "18.18.2" # pinned to avoid 18.19.0 and npm 10 nodejs_version: "^20.9.0"
nodejs_version_major: 18 nodejs_version_major: 20
platform: win32-ia32 platform: win32-ia32
package: true package: true
- os: windows-2022 - os: windows-2022
nodejs_arch: x86 nodejs_arch: x86
nodejs_version: "^20.3.0" nodejs_version: "^22"
nodejs_version_major: 20
platform: win32-ia32
- os: windows-2022
nodejs_arch: x86
nodejs_version: "^22.9.0"
nodejs_version_major: 22 nodejs_version_major: 22
platform: win32-ia32 platform: win32-ia32
- os: windows-2022 - os: windows-2022
nodejs_arch: x64 nodejs_arch: x64
nodejs_version: "^18.17.0" nodejs_version: "^20.9.0"
nodejs_version_major: 18 nodejs_version_major: 20
platform: win32-x64 platform: win32-x64
package: true package: true
- os: windows-2022 - os: windows-2022
nodejs_arch: x64 nodejs_arch: x64
nodejs_version: "^20.3.0" nodejs_version: "^22"
nodejs_version_major: 20 nodejs_version_major: 22
platform: win32-x64 platform: win32-x64
- os: windows-2022 - os: windows-2022
nodejs_arch: x64 nodejs_arch: x64
nodejs_version: "^22.9.0" nodejs_version: "^24"
nodejs_version_major: 22 nodejs_version_major: 24
platform: win32-x64 platform: win32-x64
- os: windows-11-arm - os: windows-11-arm
nodejs_arch: arm64 nodejs_arch: arm64
nodejs_version: "^20.3.0" nodejs_version: "^20.9.0"
nodejs_version_major: 20 nodejs_version_major: 20
platform: win32-arm64 platform: win32-arm64
package: true package: true
- os: windows-11-arm - os: windows-11-arm
nodejs_arch: arm64 nodejs_arch: arm64
nodejs_version: "^22.9.0" nodejs_version: "^22"
nodejs_version_major: 22 nodejs_version_major: 22
platform: win32-arm64 platform: win32-arm64
- os: windows-11-arm
nodejs_arch: arm64
nodejs_version: "^24"
nodejs_version_major: 24
platform: win32-arm64
steps: steps:
- name: Dependencies (Rocky Linux glibc) - name: Dependencies (Rocky Linux glibc)
if: contains(matrix.container, 'rockylinux') if: contains(matrix.container, 'rockylinux')
@@ -159,22 +165,22 @@ jobs:
run: apk add build-base git python3 font-noto --update-cache run: apk add build-base git python3 font-noto --update-cache
- name: Dependencies (Python 3.11 - macOS, Windows) - name: Dependencies (Python 3.11 - macOS, Windows)
if: contains(matrix.os, 'macos') || contains(matrix.os, 'windows') if: contains(matrix.os, 'macos') || contains(matrix.os, 'windows')
uses: actions/setup-python@v5 uses: actions/setup-python@v6
with: with:
python-version: "3.12" python-version: "3.12"
- name: Dependencies (Node.js) - name: Dependencies (Node.js)
if: "!contains(matrix.platform, 'linuxmusl')" if: "!contains(matrix.platform, 'linuxmusl')"
uses: actions/setup-node@v5 uses: actions/setup-node@v6
with: with:
node-version: ${{ matrix.nodejs_version }} node-version: ${{ matrix.nodejs_version }}
architecture: ${{ matrix.nodejs_arch }} architecture: ${{ matrix.nodejs_arch }}
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- run: npm install - run: npm install
- run: npm run build - run: npm run build
- run: npm run test-unit - run: npm run test-unit
- if: matrix.package - if: matrix.package
run: npm run package-from-local-build run: npm run package-from-local-build
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v6
if: matrix.package if: matrix.package
with: with:
name: ${{ matrix.platform }} name: ${{ matrix.platform }}
@@ -191,16 +197,18 @@ jobs:
image: ${{ matrix.container }} image: ${{ matrix.container }}
volumes: volumes:
- /opt:/opt:rw,rshared - /opt:/opt:rw,rshared
- /opt:/__e/node20:ro,rshared - /opt:/__e/node24:ro,rshared
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- container: node:18-alpine3.17 - container: node:20-alpine3.20
nodejs_version_major: 18
package: true
- container: node:20-alpine3.18
nodejs_version_major: 20 nodejs_version_major: 20
package: true
- container: node:22-alpine3.20
nodejs_version_major: 22
- container: node:24-alpine3.22
nodejs_version_major: 24
steps: steps:
- name: Allow Linux musl containers on ARM64 runners # https://github.com/actions/runner/issues/801#issuecomment-2394425757 - name: Allow Linux musl containers on ARM64 runners # https://github.com/actions/runner/issues/801#issuecomment-2394425757
shell: sh shell: sh
@@ -211,13 +219,13 @@ jobs:
ln -s /usr/bin/node /opt/bin/node ln -s /usr/bin/node /opt/bin/node
- name: Dependencies - name: Dependencies
run: apk add build-base git python3 font-noto --update-cache run: apk add build-base git python3 font-noto --update-cache
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- run: npm install - run: npm install
- run: npm run build - run: npm run build
- run: npm run test-unit - run: npm run test-unit
- if: matrix.package - if: matrix.package
run: npm run package-from-local-build run: npm run package-from-local-build
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v6
if: matrix.package if: matrix.package
with: with:
name: linuxmusl-arm64 name: linuxmusl-arm64
@@ -238,20 +246,20 @@ jobs:
base_image: "balenalib/rpi-raspbian:bullseye" base_image: "balenalib/rpi-raspbian:bullseye"
nodejs_arch: armv6l nodejs_arch: armv6l
nodejs_hostname: unofficial-builds.nodejs.org nodejs_hostname: unofficial-builds.nodejs.org
nodejs_version: "18.17.0" nodejs_version: "20.9.0"
nodejs_version_major: 18 nodejs_version_major: 20
- platform: linux-s390x - platform: linux-s390x
base_image: "--platform=linux/s390x s390x/debian:bookworm" base_image: "--platform=linux/s390x s390x/debian:bookworm"
nodejs_arch: s390x nodejs_arch: s390x
nodejs_hostname: nodejs.org nodejs_hostname: nodejs.org
nodejs_version: "18.17.0" nodejs_version: "20.9.0"
nodejs_version_major: 18 nodejs_version_major: 20
- platform: linux-ppc64 - platform: linux-ppc64
base_image: "--platform=linux/ppc64le ppc64le/debian:bookworm" base_image: "--platform=linux/ppc64le ppc64le/debian:bookworm"
nodejs_arch: ppc64le nodejs_arch: ppc64le
nodejs_hostname: nodejs.org nodejs_hostname: nodejs.org
nodejs_version: "18.17.0" nodejs_version: "20.9.0"
nodejs_version_major: 18 nodejs_version_major: 20
- platform: linux-riscv64 - platform: linux-riscv64
base_image: "--platform=linux/riscv64 riscv64/debian:trixie" base_image: "--platform=linux/riscv64 riscv64/debian:trixie"
compiler_flags: "-march=rv64gc" compiler_flags: "-march=rv64gc"
@@ -260,7 +268,7 @@ jobs:
nodejs_version: "20.19.5" nodejs_version: "20.19.5"
nodejs_version_major: 20 nodejs_version_major: 20
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- uses: uraimo/run-on-arch-action@v3 - uses: uraimo/run-on-arch-action@v3
with: with:
arch: none arch: none
@@ -279,7 +287,7 @@ jobs:
npm run build npm run build
node --test test/unit/io.js node --test test/unit/io.js
npm run package-from-local-build npm run package-from-local-build
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v6
with: with:
name: ${{ matrix.platform }} name: ${{ matrix.platform }}
path: npm/${{ matrix.platform }} path: npm/${{ matrix.platform }}
@@ -291,7 +299,7 @@ jobs:
needs: lint needs: lint
name: "build-wasm32 [package]" name: "build-wasm32 [package]"
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
container: "emscripten/emsdk:4.0.18" container: "emscripten/emsdk:4.0.21"
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Dependencies - name: Dependencies
@@ -311,7 +319,7 @@ jobs:
test "$EMSCRIPTEN_VERSION_LIBVIPS" = "$EMSCRIPTEN_VERSION_SHARP" test "$EMSCRIPTEN_VERSION_LIBVIPS" = "$EMSCRIPTEN_VERSION_SHARP"
- run: emmake npm run test-unit - run: emmake npm run test-unit
- run: emmake npm run package-from-local-build - run: emmake npm run package-from-local-build
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v6
with: with:
name: wasm32 name: wasm32
path: npm/wasm32 path: npm/wasm32
@@ -329,12 +337,12 @@ jobs:
- build-emscripten - build-emscripten
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v7
with: with:
path: npm path: npm
- name: Create npm workspace tarball - name: Create npm workspace tarball
run: tar -vcaf npm-workspace.tar.xz --directory npm --exclude=from-local-build.js . run: tar -vcaf npm-workspace.tar.xz --directory npm --exclude=from-local-build.js .
- uses: actions/setup-node@v5 - uses: actions/setup-node@v6
with: with:
node-version: '24' node-version: '24'
- name: Create release notes - name: Create release notes

View File

@@ -96,7 +96,7 @@ jobs:
steps: steps:
- name: Install Node.js - name: Install Node.js
if: ${{ matrix.runtime == 'node' }} if: ${{ matrix.runtime == 'node' }}
uses: actions/setup-node@v5 uses: actions/setup-node@v6
with: with:
node-version: 20 node-version: 20
- name: Install pnpm - name: Install pnpm

View File

@@ -8,7 +8,7 @@ smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions
It can be used with all JavaScript runtimes It can be used with all JavaScript runtimes
that provide support for Node-API v9, including that provide support for Node-API v9, including
Node.js (^18.17.0 or >= 20.3.0), Deno and Bun. Node.js (>= 20.9.0), Deno and Bun.
Resizing an image is typically 4x-5x faster than using the Resizing an image is typically 4x-5x faster than using the
quickest ImageMagick and GraphicsMagick settings quickest ImageMagick and GraphicsMagick settings

View File

@@ -1,5 +1,5 @@
{ {
"$schema": "https://biomejs.dev/schemas/2.3.4/schema.json", "$schema": "https://biomejs.dev/schemas/2.3.10/schema.json",
"vcs": { "vcs": {
"enabled": true, "enabled": true,
"clientKind": "git", "clientKind": "git",

View File

@@ -50,6 +50,7 @@ A `Promise` is returned when `callback` is not provided.
- `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present - `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
- `formatMagick`: String containing format for images loaded via *magick - `formatMagick`: String containing format for images loaded via *magick
- `comments`: Array of keyword/text pairs representing PNG text blocks, if present. - `comments`: Array of keyword/text pairs representing PNG text blocks, if present.
- `gainMap.image`: HDR gain map, if present, as compressed JPEG image.

View File

@@ -250,6 +250,27 @@ const outputWithP3 = await sharp(input)
``` ```
## withGainMap
> withGainMap() ⇒ <code>Sharp</code>
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**
```js
const outputWithGainMap = await sharp(inputWithGainMap)
.withGainMap()
.toBuffer();
```
## keepXmp ## keepXmp
> keepXmp() ⇒ <code>Sharp</code> > keepXmp() ⇒ <code>Sharp</code>

View File

@@ -0,0 +1,11 @@
---
title: v0.35.0 - TBC
slug: changelog/v0.35.0
---
* Upgrade to libvips v8.18.0 for upstream bug fixes.
* Drop support for Node.js 18, now requires Node.js >= 20.9.0.
* Add `withGainMap` to process HDR JPEG images with embedded gain maps.
[#4314](https://github.com/lovell/sharp/issues/4314)

View File

@@ -10,7 +10,7 @@ smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions
It can be used with all JavaScript runtimes It can be used with all JavaScript runtimes
that provide support for Node-API v9, including that provide support for Node-API v9, including
Node.js >= 18.17.0, Deno and Bun. Node.js >= 20.9.0, Deno and Bun.
Resizing an image is typically 4x-5x faster than using the Resizing an image is typically 4x-5x faster than using the
quickest ImageMagick and GraphicsMagick settings quickest ImageMagick and GraphicsMagick settings

View File

@@ -39,7 +39,7 @@ deno run --allow-env --allow-ffi --allow-read --allow-sys ...
## Prerequisites ## Prerequisites
* Node-API v9 compatible runtime e.g. Node.js ^18.17.0 or >=20.3.0. * Node-API v9 compatible runtime e.g. Node.js >= 20.9.0.
## Prebuilt binaries ## Prebuilt binaries

View File

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

7
lib/index.d.ts vendored
View File

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

View File

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

View File

@@ -319,6 +319,30 @@ function withIccProfile (icc, options) {
return this; 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. * Keep XMP metadata from the input image in the output image.
* *
@@ -1640,6 +1664,7 @@ module.exports = (Sharp) => {
withExifMerge, withExifMerge,
keepIccProfile, keepIccProfile,
withIccProfile, withIccProfile,
withGainMap,
keepXmp, keepXmp,
withXmp, withXmp,
keepMetadata, keepMetadata,

View File

@@ -15,7 +15,7 @@
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": { "optionalDependencies": {
"@img/sharp-libvips-darwin-arm64": "1.2.4" "@img/sharp-libvips-darwin-arm64": "1.3.0-rc.1"
}, },
"files": [ "files": [
"lib" "lib"
@@ -29,7 +29,7 @@
"./package": "./package.json" "./package": "./package.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"os": [ "os": [
"darwin" "darwin"

View File

@@ -15,7 +15,7 @@
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": { "optionalDependencies": {
"@img/sharp-libvips-darwin-x64": "1.2.4" "@img/sharp-libvips-darwin-x64": "1.3.0-rc.1"
}, },
"files": [ "files": [
"lib" "lib"
@@ -29,7 +29,7 @@
"./package": "./package.json" "./package": "./package.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"os": [ "os": [
"darwin" "darwin"

View File

@@ -15,7 +15,7 @@
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": { "optionalDependencies": {
"@img/sharp-libvips-linux-arm": "1.2.4" "@img/sharp-libvips-linux-arm": "1.3.0-rc.1"
}, },
"files": [ "files": [
"lib" "lib"
@@ -29,7 +29,7 @@
"./package": "./package.json" "./package": "./package.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"config": { "config": {
"glibc": ">=2.31" "glibc": ">=2.31"

View File

@@ -15,7 +15,7 @@
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": { "optionalDependencies": {
"@img/sharp-libvips-linux-arm64": "1.2.4" "@img/sharp-libvips-linux-arm64": "1.3.0-rc.1"
}, },
"files": [ "files": [
"lib" "lib"
@@ -29,7 +29,7 @@
"./package": "./package.json" "./package": "./package.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"config": { "config": {
"glibc": ">=2.26" "glibc": ">=2.26"

View File

@@ -15,7 +15,7 @@
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": { "optionalDependencies": {
"@img/sharp-libvips-linux-ppc64": "1.2.4" "@img/sharp-libvips-linux-ppc64": "1.3.0-rc.1"
}, },
"files": [ "files": [
"lib" "lib"
@@ -29,7 +29,7 @@
"./package": "./package.json" "./package": "./package.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"config": { "config": {
"glibc": ">=2.36" "glibc": ">=2.36"

View File

@@ -15,7 +15,7 @@
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": { "optionalDependencies": {
"@img/sharp-libvips-linux-riscv64": "1.2.4" "@img/sharp-libvips-linux-riscv64": "1.3.0-rc.1"
}, },
"files": [ "files": [
"lib" "lib"
@@ -29,7 +29,7 @@
"./package": "./package.json" "./package": "./package.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"config": { "config": {
"glibc": ">=2.41" "glibc": ">=2.41"

View File

@@ -15,7 +15,7 @@
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": { "optionalDependencies": {
"@img/sharp-libvips-linux-s390x": "1.2.4" "@img/sharp-libvips-linux-s390x": "1.3.0-rc.1"
}, },
"files": [ "files": [
"lib" "lib"
@@ -29,7 +29,7 @@
"./package": "./package.json" "./package": "./package.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"config": { "config": {
"glibc": ">=2.36" "glibc": ">=2.36"

View File

@@ -15,7 +15,7 @@
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": { "optionalDependencies": {
"@img/sharp-libvips-linux-x64": "1.2.4" "@img/sharp-libvips-linux-x64": "1.3.0-rc.1"
}, },
"files": [ "files": [
"lib" "lib"
@@ -29,7 +29,7 @@
"./package": "./package.json" "./package": "./package.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"config": { "config": {
"glibc": ">=2.26" "glibc": ">=2.26"

View File

@@ -15,7 +15,7 @@
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": { "optionalDependencies": {
"@img/sharp-libvips-linuxmusl-arm64": "1.2.4" "@img/sharp-libvips-linuxmusl-arm64": "1.3.0-rc.1"
}, },
"files": [ "files": [
"lib" "lib"
@@ -29,7 +29,7 @@
"./package": "./package.json" "./package": "./package.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"config": { "config": {
"musl": ">=1.2.2" "musl": ">=1.2.2"

View File

@@ -15,7 +15,7 @@
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": { "optionalDependencies": {
"@img/sharp-libvips-linuxmusl-x64": "1.2.4" "@img/sharp-libvips-linuxmusl-x64": "1.3.0-rc.1"
}, },
"files": [ "files": [
"lib" "lib"
@@ -29,7 +29,7 @@
"./package": "./package.json" "./package": "./package.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"config": { "config": {
"musl": ">=1.2.2" "musl": ">=1.2.2"

View File

@@ -28,10 +28,10 @@
"./versions": "./versions.json" "./versions": "./versions.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"dependencies": { "dependencies": {
"@emnapi/runtime": "^1.7.0" "@emnapi/runtime": "^1.7.1"
}, },
"cpu": [ "cpu": [
"wasm32" "wasm32"

View File

@@ -28,7 +28,7 @@
"./versions": "./versions.json" "./versions": "./versions.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"os": [ "os": [
"win32" "win32"

View File

@@ -28,7 +28,7 @@
"./versions": "./versions.json" "./versions": "./versions.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"os": [ "os": [
"win32" "win32"

View File

@@ -28,7 +28,7 @@
"./versions": "./versions.json" "./versions": "./versions.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"os": [ "os": [
"win32" "win32"

View File

@@ -146,16 +146,16 @@
"optionalDependencies": { "optionalDependencies": {
"@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-arm64": "0.34.5",
"@img/sharp-darwin-x64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5",
"@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-arm64": "1.3.0-rc.1",
"@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.3.0-rc.1",
"@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm": "1.3.0-rc.1",
"@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.3.0-rc.1",
"@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.3.0-rc.1",
"@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.3.0-rc.1",
"@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.3.0-rc.1",
"@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linux-x64": "1.3.0-rc.1",
"@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.3.0-rc.1",
"@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.3.0-rc.1",
"@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm": "0.34.5",
"@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-arm64": "0.34.5",
"@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5",
@@ -170,31 +170,31 @@
"@img/sharp-win32-x64": "0.34.5" "@img/sharp-win32-x64": "0.34.5"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^2.3.4", "@biomejs/biome": "^2.3.10",
"@cpplint/cli": "^0.1.0", "@cpplint/cli": "^0.1.0",
"@emnapi/runtime": "^1.7.0", "@emnapi/runtime": "^1.7.1",
"@img/sharp-libvips-dev": "1.2.4", "@img/sharp-libvips-dev": "1.3.0-rc.1",
"@img/sharp-libvips-dev-wasm32": "1.2.4", "@img/sharp-libvips-dev-wasm32": "1.3.0-rc.1",
"@img/sharp-libvips-win32-arm64": "1.2.4", "@img/sharp-libvips-win32-arm64": "1.3.0-rc.1",
"@img/sharp-libvips-win32-ia32": "1.2.4", "@img/sharp-libvips-win32-ia32": "1.3.0-rc.1",
"@img/sharp-libvips-win32-x64": "1.2.4", "@img/sharp-libvips-win32-x64": "1.3.0-rc.1",
"@types/node": "*", "@types/node": "*",
"emnapi": "^1.7.0", "emnapi": "^1.7.1",
"exif-reader": "^2.0.2", "exif-reader": "^2.0.3",
"extract-zip": "^2.0.1", "extract-zip": "^2.0.1",
"icc": "^3.0.0", "icc": "^3.0.0",
"jsdoc-to-markdown": "^9.1.3", "jsdoc-to-markdown": "^9.1.3",
"node-addon-api": "^8.5.0", "node-addon-api": "^8.5.0",
"node-gyp": "^11.5.0", "node-gyp": "^12.1.0",
"tar-fs": "^3.1.1", "tar-fs": "^3.1.1",
"tsd": "^0.33.0" "tsd": "^0.33.0"
}, },
"license": "Apache-2.0", "license": "Apache-2.0",
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0" "node": ">=20.9.0"
}, },
"config": { "config": {
"libvips": ">=8.17.3" "libvips": ">=8.18.0"
}, },
"funding": { "funding": {
"url": "https://opencollective.com/libvips" "url": "https://opencollective.com/libvips"

View File

@@ -289,6 +289,7 @@ namespace sharp {
case ImageType::JXL: id = "jxl"; break; case ImageType::JXL: id = "jxl"; break;
case ImageType::RAD: id = "rad"; break; case ImageType::RAD: id = "rad"; break;
case ImageType::DCRAW: id = "dcraw"; break; case ImageType::DCRAW: id = "dcraw"; break;
case ImageType::UHDR: id = "uhdr"; break;
case ImageType::VIPS: id = "vips"; break; case ImageType::VIPS: id = "vips"; break;
case ImageType::RAW: id = "raw"; break; case ImageType::RAW: id = "raw"; break;
case ImageType::UNKNOWN: id = "unknown"; break; case ImageType::UNKNOWN: id = "unknown"; break;
@@ -339,6 +340,9 @@ namespace sharp {
{ "VipsForeignLoadRadBuffer", ImageType::RAD }, { "VipsForeignLoadRadBuffer", ImageType::RAD },
{ "VipsForeignLoadDcRawFile", ImageType::DCRAW }, { "VipsForeignLoadDcRawFile", ImageType::DCRAW },
{ "VipsForeignLoadDcRawBuffer", ImageType::DCRAW }, { "VipsForeignLoadDcRawBuffer", ImageType::DCRAW },
{ "VipsForeignLoadUhdr", ImageType::UHDR },
{ "VipsForeignLoadUhdrFile", ImageType::UHDR },
{ "VipsForeignLoadUhdrBuffer", ImageType::UHDR },
{ "VipsForeignLoadVips", ImageType::VIPS }, { "VipsForeignLoadVips", ImageType::VIPS },
{ "VipsForeignLoadVipsFile", ImageType::VIPS }, { "VipsForeignLoadVipsFile", ImageType::VIPS },
{ "VipsForeignLoadRaw", ImageType::RAW } { "VipsForeignLoadRaw", ImageType::RAW }
@@ -356,6 +360,9 @@ namespace sharp {
imageType = it->second; imageType = it->second;
} }
} }
if (imageType == ImageType::UHDR) {
imageType = ImageType::JPEG;
}
return imageType; return imageType;
} }
@@ -375,6 +382,9 @@ namespace sharp {
imageType = ImageType::MISSING; imageType = ImageType::MISSING;
} }
} }
if (imageType == ImageType::UHDR) {
imageType = ImageType::JPEG;
}
return imageType; return imageType;
} }
@@ -1127,4 +1137,20 @@ namespace sharp {
} }
return image; return image;
} }
/*
Does this image have a gain map?
*/
bool HasGainMap(VImage image) {
return image.get_typeof("gainmap-data") == VIPS_TYPE_BLOB;
}
/*
Removes gain map, if any.
*/
VImage RemoveGainMap(VImage image) {
VImage copy = image.copy();
copy.remove("gainmap-data");
return copy;
}
} // namespace sharp } // namespace sharp

View File

@@ -18,9 +18,9 @@
// Verify platform and compiler compatibility // Verify platform and compiler compatibility
#if (VIPS_MAJOR_VERSION < 8) || \ #if (VIPS_MAJOR_VERSION < 8) || \
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 17) || \ (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 18) || \
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 17 && VIPS_MICRO_VERSION < 3) (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 18 && VIPS_MICRO_VERSION < 0)
#error "libvips version 8.17.3+ is required - please see https://sharp.pixelplumbing.com/install" #error "libvips version 8.18.0+ is required - please see https://sharp.pixelplumbing.com/install"
#endif #endif
#if defined(__has_include) #if defined(__has_include)
@@ -173,6 +173,7 @@ namespace sharp {
JXL, JXL,
RAD, RAD,
DCRAW, DCRAW,
UHDR,
VIPS, VIPS,
RAW, RAW,
UNKNOWN, UNKNOWN,
@@ -397,6 +398,16 @@ namespace sharp {
*/ */
VImage StaySequential(VImage image, bool condition = true); VImage StaySequential(VImage image, bool condition = true);
/*
Does this image have a gain map?
*/
bool HasGainMap(VImage image);
/*
Removes gain map, if any.
*/
VImage RemoveGainMap(VImage image);
} // namespace sharp } // namespace sharp
#endif // SRC_COMMON_H_ #endif // SRC_COMMON_H_

View File

@@ -141,6 +141,14 @@ class MetadataWorker : public Napi::AsyncWorker {
memcpy(baton->tifftagPhotoshop, tifftagPhotoshop, tifftagPhotoshopLength); memcpy(baton->tifftagPhotoshop, tifftagPhotoshop, tifftagPhotoshopLength);
baton->tifftagPhotoshopLength = tifftagPhotoshopLength; baton->tifftagPhotoshopLength = tifftagPhotoshopLength;
} }
// Gain Map
if (image.get_typeof("gainmap-data") == VIPS_TYPE_BLOB) {
size_t gainMapLength;
void const *gainMap = image.get_blob("gainmap-data", &gainMapLength);
baton->gainMap = static_cast<char *>(g_malloc(gainMapLength));
memcpy(baton->gainMap, gainMap, gainMapLength);
baton->gainMapLength = gainMapLength;
}
// PNG comments // PNG comments
vips_image_map(image.get_image(), readPNGComment, &baton->comments); vips_image_map(image.get_image(), readPNGComment, &baton->comments);
} }
@@ -276,6 +284,12 @@ class MetadataWorker : public Napi::AsyncWorker {
Napi::Buffer<char>::NewOrCopy(env, baton->tifftagPhotoshop, Napi::Buffer<char>::NewOrCopy(env, baton->tifftagPhotoshop,
baton->tifftagPhotoshopLength, sharp::FreeCallback)); baton->tifftagPhotoshopLength, sharp::FreeCallback));
} }
if (baton->gainMapLength > 0) {
Napi::Object gainMap = Napi::Object::New(env);
info.Set("gainMap", gainMap);
gainMap.Set("image",
Napi::Buffer<char>::NewOrCopy(env, baton->gainMap, baton->gainMapLength, sharp::FreeCallback));
}
if (baton->comments.size() > 0) { if (baton->comments.size() > 0) {
int i = 0; int i = 0;
Napi::Array comments = Napi::Array::New(env, baton->comments.size()); Napi::Array comments = Napi::Array::New(env, baton->comments.size());

View File

@@ -53,6 +53,8 @@ struct MetadataBaton {
size_t xmpLength; size_t xmpLength;
char *tifftagPhotoshop; char *tifftagPhotoshop;
size_t tifftagPhotoshopLength; size_t tifftagPhotoshopLength;
char *gainMap;
size_t gainMapLength;
MetadataComments comments; MetadataComments comments;
std::string err; std::string err;
@@ -82,7 +84,9 @@ struct MetadataBaton {
xmp(nullptr), xmp(nullptr),
xmpLength(0), xmpLength(0),
tifftagPhotoshop(nullptr), tifftagPhotoshop(nullptr),
tifftagPhotoshopLength(0) {} tifftagPhotoshopLength(0),
gainMap(nullptr),
gainMapLength(0) {}
}; };
Napi::Value metadata(const Napi::CallbackInfo& info); Napi::Value metadata(const Napi::CallbackInfo& info);

View File

@@ -296,6 +296,14 @@ class PipelineWorker : public Napi::AsyncWorker {
if (baton->input->autoOrient) { if (baton->input->autoOrient) {
image = sharp::RemoveExifOrientation(image); image = sharp::RemoveExifOrientation(image);
} }
if (sharp::HasGainMap(image)) {
if (baton->withGainMap) {
image = image.uhdr2scRGB();
}
image = sharp::RemoveGainMap(image);
} else {
baton->withGainMap = false;
}
// Any pre-shrinking may already have been done // Any pre-shrinking may already have been done
inputWidth = image.width(); inputWidth = image.width();
@@ -335,7 +343,7 @@ class PipelineWorker : public Napi::AsyncWorker {
image.interpretation() != VIPS_INTERPRETATION_LABS && image.interpretation() != VIPS_INTERPRETATION_LABS &&
image.interpretation() != VIPS_INTERPRETATION_GREY16 && image.interpretation() != VIPS_INTERPRETATION_GREY16 &&
baton->colourspacePipeline != VIPS_INTERPRETATION_CMYK && baton->colourspacePipeline != VIPS_INTERPRETATION_CMYK &&
!baton->input->ignoreIcc !baton->input->ignoreIcc && !baton->withGainMap
) { ) {
// Convert to sRGB/P3 using embedded profile // Convert to sRGB/P3 using embedded profile
try { try {
@@ -1706,6 +1714,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
} }
baton->withExifMerge = sharp::AttrAsBool(options, "withExifMerge"); baton->withExifMerge = sharp::AttrAsBool(options, "withExifMerge");
baton->withXmp = sharp::AttrAsStr(options, "withXmp"); baton->withXmp = sharp::AttrAsStr(options, "withXmp");
baton->withGainMap = sharp::AttrAsBool(options, "withGainMap");
baton->timeoutSeconds = sharp::AttrAsUint32(options, "timeoutSeconds"); baton->timeoutSeconds = sharp::AttrAsUint32(options, "timeoutSeconds");
baton->loop = sharp::AttrAsUint32(options, "loop"); baton->loop = sharp::AttrAsUint32(options, "loop");
baton->delay = sharp::AttrAsInt32Vector(options, "delay"); baton->delay = sharp::AttrAsInt32Vector(options, "delay");

View File

@@ -208,6 +208,7 @@ struct PipelineBaton {
std::unordered_map<std::string, std::string> withExif; std::unordered_map<std::string, std::string> withExif;
bool withExifMerge; bool withExifMerge;
std::string withXmp; std::string withXmp;
bool withGainMap;
int timeoutSeconds; int timeoutSeconds;
std::vector<double> convKernel; std::vector<double> convKernel;
int convKernelWidth; int convKernelWidth;
@@ -381,6 +382,7 @@ struct PipelineBaton {
withMetadataOrientation(-1), withMetadataOrientation(-1),
withMetadataDensity(0.0), withMetadataDensity(0.0),
withExifMerge(true), withExifMerge(true),
withGainMap(false),
timeoutSeconds(0), timeoutSeconds(0),
convKernelWidth(0), convKernelWidth(0),
convKernelHeight(0), convKernelHeight(0),

BIN
test/fixtures/gain-map.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -70,6 +70,7 @@ module.exports = {
inputJpgRandom: getPath('random.jpg'), // convert -size 200x200 xc: +noise Random random.jpg inputJpgRandom: getPath('random.jpg'), // convert -size 200x200 xc: +noise Random random.jpg
inputJpgThRandom: getPath('thRandom.jpg'), // convert random.jpg -channel G -threshold 5% -separate +channel -negate thRandom.jpg inputJpgThRandom: getPath('thRandom.jpg'), // convert random.jpg -channel G -threshold 5% -separate +channel -negate thRandom.jpg
inputJpgLossless: getPath('testimgl.jpg'), // Lossless JPEG from ftp://ftp.fu-berlin.de/unix/X11/graphics/ImageMagick/delegates/ljpeg-6b.tar.gz inputJpgLossless: getPath('testimgl.jpg'), // Lossless JPEG from ftp://ftp.fu-berlin.de/unix/X11/graphics/ImageMagick/delegates/ljpeg-6b.tar.gz
inputJpgWithGainMap: getPath('gain-map.jpg'), // https://github.com/libvips/libvips/issues/3799
inputPng: getPath('50020484-00001.png'), // http://c.searspartsdirect.com/lis_png/PLDM/50020484-00001.png inputPng: getPath('50020484-00001.png'), // http://c.searspartsdirect.com/lis_png/PLDM/50020484-00001.png
inputPngGradients: getPath('gradients-rgb8.png'), inputPngGradients: getPath('gradients-rgb8.png'),

69
test/unit/gain-map.js Normal file
View File

@@ -0,0 +1,69 @@
/*!
Copyright 2013 Lovell Fuller and others.
SPDX-License-Identifier: Apache-2.0
*/
const { describe, it } = require('node:test');
const sharp = require('../../');
const fixtures = require('../fixtures');
describe('Gain maps', () => {
it('Metadata contains gainMap', async (t) => {
t.plan(4);
const { format, gainMap } = await sharp(
fixtures.inputJpgWithGainMap,
).metadata();
t.assert.strictEqual(format, 'jpeg');
t.assert.strictEqual(typeof gainMap, 'object');
t.assert.ok(Buffer.isBuffer(gainMap.image));
t.assert.strictEqual(gainMap.image.length, 31738);
});
it('Can be regenerated', async (t) => {
t.plan(4);
const data = await sharp(fixtures.inputJpgWithGainMap)
.withGainMap()
.toBuffer();
const metadata = await sharp(data).metadata();
t.assert.strictEqual(metadata.format, 'jpeg');
t.assert.strictEqual(typeof metadata.gainMap, 'object');
t.assert.ok(Buffer.isBuffer(metadata.gainMap.image));
const {
format,
width,
height,
channels,
depth,
space,
hasProfile,
chromaSubsampling,
} = await sharp(metadata.gainMap.image).metadata();
t.assert.deepEqual(
{
format,
width,
height,
channels,
depth,
space,
hasProfile,
chromaSubsampling,
},
{
format: 'jpeg',
width: 1920,
height: 1080,
channels: 1,
depth: 'uchar',
space: 'b-w',
hasProfile: true,
chromaSubsampling: '4:4:4',
},
);
});
});

View File

@@ -180,7 +180,7 @@ describe('libvips binaries', () => {
process.env.npm_config_arch = 's390x'; process.env.npm_config_arch = 's390x';
process.env.npm_config_libc = ''; process.env.npm_config_libc = '';
const locatorHash = libvips.yarnLocator(); const locatorHash = libvips.yarnLocator();
assert.strictEqual(locatorHash, '4ab19140fd'); assert.strictEqual(locatorHash, '8cdba194cb');
delete process.env.npm_config_platform; delete process.env.npm_config_platform;
delete process.env.npm_config_arch; delete process.env.npm_config_arch;
delete process.env.npm_config_libc; delete process.env.npm_config_libc;

View File

@@ -226,12 +226,11 @@ describe('PNG', () => {
.png({ colours: 2, palette: false }) .png({ colours: 2, palette: false })
.toBuffer(); .toBuffer();
const { channels, isPalette, bitsPerSample, paletteBitDepth, size, space } = await sharp(data).metadata(); const { channels, isPalette, bitsPerSample, paletteBitDepth, space } = await sharp(data).metadata();
assert.strictEqual(channels, 1); assert.strictEqual(channels, 1);
assert.strictEqual(isPalette, false); assert.strictEqual(isPalette, false);
assert.strictEqual(bitsPerSample, 1); assert.strictEqual(bitsPerSample, 1);
assert.strictEqual(paletteBitDepth, undefined); assert.strictEqual(paletteBitDepth, undefined);
assert.strictEqual(size, 89);
assert.strictEqual(space, 'b-w'); assert.strictEqual(space, 'b-w');
}); });