Compare commits

..

9 Commits

Author SHA1 Message Date
Lovell Fuller
8669fbc936 Prerelease v0.34.3-rc.0 2025-06-14 21:49:24 +01:00
Lovell Fuller
cab02463ec Remove prebuild dependency
Every CI build task tagged with 'package' now populates and
publishes the relevant npm/platform directory as an artefact.
These are aggregated by a fan-in release task at the end to
create a complete npm workspace zipfile. If the commit is
tagged, a release is created and the npm workspace attached.
2025-06-14 17:49:17 +01:00
Lovell Fuller
5374b036f3 CI: Switch ARM64 from CircleCI to GitHub Actions 2025-06-13 14:08:19 +01:00
Kleis Auke Wolthuizen
327a6d2083 Docs: update link to concurrency API (#4414) 2025-06-13 10:48:32 +01:00
Michael B. Klein
751f9992c4 Expose JPEG 2000 oneshot decoder option #4262
Requires libvips compiled with support for JP2 images

Co-authored-by: Kleis Auke Wolthuizen <github@kleisauke.nl>
2025-06-13 08:46:36 +01:00
Lovell Fuller
01f6cbbaee Upgrade to sharp-libvips v1.2.0-rc.2 2025-06-12 14:59:13 +01:00
Lovell Fuller
99be893dd4 Upgrade to libvips v8.17.0
CI: Use more recent, non-deprecated Windows runners

Bump devDeps
2025-06-12 11:27:26 +01:00
Kleis Auke Wolthuizen
4d1f7e051d Support composite op with non-sRGB pipeline colourspace (#4412) 2025-06-12 10:32:24 +01:00
Kleis Auke Wolthuizen
91f1b58f31 Tests: Regenerate expected fixtures ahead of libvips v8.17.0 (#4402) 2025-06-08 23:31:07 +01:00
41 changed files with 365 additions and 350 deletions

View File

@@ -1,105 +0,0 @@
version: 2.1
workflows:
build:
jobs:
- linux-arm64-glibc-node-18:
filters:
tags:
only: /^v.*/
- linux-arm64-musl-node-18:
filters:
tags:
only: /^v.*/
- linux-arm64-glibc-node-20:
filters:
tags:
only: /^v.*/
- linux-arm64-musl-node-20:
filters:
tags:
only: /^v.*/
jobs:
linux-arm64-glibc-node-18:
resource_class: arm.medium
machine:
image: ubuntu-2204:current
steps:
- checkout
- run: |
sudo docker run -dit --name sharp --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp arm64v8/debian:bullseye
sudo docker exec sharp sh -c "apt-get update && apt-get install -y build-essential git python3 curl fonts-noto-core"
sudo docker exec sharp sh -c "mkdir -p /etc/apt/keyrings"
sudo docker exec sharp sh -c "curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg"
sudo docker exec sharp sh -c "echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main' | tee /etc/apt/sources.list.d/nodesource.list"
sudo docker exec sharp sh -c "apt-get update && apt-get install -y nodejs"
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
- run: sudo docker exec sharp sh -c "npm test"
- run: |
sudo docker exec sharp sh -c "npm run package-from-local-build"
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@img/sharp-linux-arm64=file:./npm/linux-arm64\""
sudo docker exec sharp sh -c "npm run clean"
sudo docker exec sharp sh -c "npm install --ignore-scripts"
sudo docker exec sharp sh -c "npm test"
- run: "[[ -n $CIRCLE_TAG ]] && sudo docker exec --env prebuild_upload sharp sh -c \"cd src && ln -s ../package.json && npx prebuild --upload=$prebuild_upload\" || true"
linux-arm64-glibc-node-20:
resource_class: arm.medium
machine:
image: ubuntu-2204:current
steps:
- checkout
- run: |
sudo docker run -dit --name sharp --workdir /mnt/sharp arm64v8/debian:bullseye
sudo docker exec sharp sh -c "apt-get update && apt-get install -y build-essential git python3 curl fonts-noto-core"
sudo docker exec sharp sh -c "mkdir -p /etc/apt/keyrings"
sudo docker exec sharp sh -c "curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg"
sudo docker exec sharp sh -c "echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main' | tee /etc/apt/sources.list.d/nodesource.list"
sudo docker exec sharp sh -c "apt-get update && apt-get install -y nodejs"
sudo docker exec sharp sh -c "mkdir -p /mnt/sharp"
sudo docker cp . sharp:/mnt/sharp/.
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
- run: sudo docker exec sharp sh -c "npm test"
- run: |
sudo docker exec sharp sh -c "npm run package-from-local-build"
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@img/sharp-linux-arm64=file:./npm/linux-arm64\""
sudo docker exec sharp sh -c "npm run clean"
sudo docker exec sharp sh -c "npm install --ignore-scripts"
sudo docker exec sharp sh -c "npm test"
linux-arm64-musl-node-18:
resource_class: arm.medium
machine:
image: ubuntu-2204:current
steps:
- checkout
- run: |
sudo docker run -dit --name sharp --volume "${PWD}:/mnt/sharp" --workdir /mnt/sharp node:18-alpine3.17
sudo docker exec sharp sh -c "apk add build-base git python3 font-noto --update-cache"
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
- run: sudo docker exec sharp sh -c "npm test"
- run: |
sudo docker exec sharp sh -c "npm run package-from-local-build"
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@img/sharp-linuxmusl-arm64=file:./npm/linuxmusl-arm64\""
sudo docker exec sharp sh -c "npm run clean"
sudo docker exec sharp sh -c "npm install --ignore-scripts"
sudo docker exec sharp sh -c "npm test"
- run: "[[ -n $CIRCLE_TAG ]] && sudo docker exec --env prebuild_upload sharp sh -c \"cd src && ln -s ../package.json && npx prebuild --upload=$prebuild_upload\" || true"
linux-arm64-musl-node-20:
resource_class: arm.medium
machine:
image: ubuntu-2204:current
steps:
- checkout
- run: |
sudo docker run -dit --name sharp --workdir /mnt/sharp node:20-alpine3.18
sudo docker exec sharp sh -c "apk add build-base git python3 font-noto --update-cache"
sudo docker exec sharp sh -c "mkdir -p /mnt/sharp"
sudo docker cp . sharp:/mnt/sharp/.
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
- run: sudo docker exec sharp sh -c "npm test"
- run: |
sudo docker exec sharp sh -c "npm run package-from-local-build"
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@img/sharp-linuxmusl-arm64=file:./npm/linuxmusl-arm64\""
sudo docker exec sharp sh -c "npm run clean"
sudo docker exec sharp sh -c "npm install --ignore-scripts"
sudo docker exec sharp sh -c "npm test"

View File

@@ -1,5 +1,5 @@
freebsd_instance:
image_family: freebsd-14-0-snap
image_family: freebsd-15-0-snap
task:
name: FreeBSD

View File

@@ -4,10 +4,10 @@ on:
- pull_request
permissions: {}
jobs:
github-runner:
build-native:
permissions:
contents: write
name: ${{ matrix.platform }} - Node.js ${{ matrix.nodejs_version_major }} ${{ matrix.prebuild && '- prebuild' }}
contents: read
name: "build-${{ matrix.platform }} [Node.js ${{ matrix.nodejs_version_major }}] ${{ matrix.package && '[package]' }}"
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
strategy:
@@ -20,7 +20,7 @@ jobs:
nodejs_version: "^18.17.0"
nodejs_version_major: 18
platform: linux-x64
prebuild: true
package: true
- os: ubuntu-24.04
container: rockylinux:8
nodejs_arch: x64
@@ -37,7 +37,7 @@ jobs:
container: node:18-alpine3.17
nodejs_version_major: 18
platform: linuxmusl-x64
prebuild: true
package: true
- os: ubuntu-24.04
container: node:20-alpine3.18
nodejs_version_major: 20
@@ -46,12 +46,25 @@ jobs:
container: node:22-alpine3.20
nodejs_version_major: 22
platform: linuxmusl-x64
- os: ubuntu-24.04-arm
container: arm64v8/rockylinux:8
nodejs_arch: arm64
nodejs_version: "^18.17.0"
nodejs_version_major: 18
platform: linux-arm64
package: true
- os: ubuntu-24.04-arm
container: arm64v8/rockylinux:8
nodejs_arch: arm64
nodejs_version: "^20.3.0"
nodejs_version_major: 20
platform: linux-arm64
- os: macos-13
nodejs_arch: x64
nodejs_version: "^18.17.0"
nodejs_version_major: 18
platform: darwin-x64
prebuild: true
package: true
- os: macos-13
nodejs_arch: x64
nodejs_version: "^20.3.0"
@@ -67,7 +80,7 @@ jobs:
nodejs_version: "^18.17.0"
nodejs_version_major: 18
platform: darwin-arm64
prebuild: true
package: true
- os: macos-14
nodejs_arch: arm64
nodejs_version: "^20.3.0"
@@ -78,34 +91,34 @@ jobs:
nodejs_version: "^22.9.0"
nodejs_version_major: 22
platform: darwin-arm64
- os: windows-2019
- os: windows-2022
nodejs_arch: x86
nodejs_version: "18.18.2" # pinned to avoid 18.19.0 and npm 10
nodejs_version_major: 18
platform: win32-ia32
prebuild: true
- os: windows-2019
package: true
- os: windows-2022
nodejs_arch: x86
nodejs_version: "^20.3.0"
nodejs_version_major: 20
platform: win32-ia32
- os: windows-2019
- os: windows-2022
nodejs_arch: x86
nodejs_version: "^22.9.0"
nodejs_version_major: 22
platform: win32-ia32
- os: windows-2019
- os: windows-2022
nodejs_arch: x64
nodejs_version: "^18.17.0"
nodejs_version_major: 18
platform: win32-x64
prebuild: true
- os: windows-2019
package: true
- os: windows-2022
nodejs_arch: x64
nodejs_version: "^20.3.0"
nodejs_version_major: 20
platform: win32-x64
- os: windows-2019
- os: windows-2022
nodejs_arch: x64
nodejs_version: "^22.9.0"
nodejs_version_major: 22
@@ -115,7 +128,7 @@ jobs:
nodejs_version: "^20.3.0"
nodejs_version_major: 20
platform: win32-arm64
prebuild: true
package: true
- os: windows-11-arm
nodejs_arch: arm64
nodejs_version: "^22.9.0"
@@ -125,8 +138,8 @@ jobs:
- name: Dependencies (Rocky Linux glibc)
if: contains(matrix.container, 'rockylinux')
run: |
dnf install -y gcc-toolset-11-gcc-c++ make git python3.12 fontconfig google-noto-sans-fonts
echo "/opt/rh/gcc-toolset-11/root/usr/bin" >> $GITHUB_PATH
dnf install -y gcc-toolset-14-gcc-c++ make git python3.12 fontconfig google-noto-sans-fonts
echo "/opt/rh/gcc-toolset-14/root/usr/bin" >> $GITHUB_PATH
- name: Dependencies (Linux musl)
if: contains(matrix.container, 'alpine')
run: apk add build-base git python3 font-noto --update-cache
@@ -141,31 +154,70 @@ jobs:
with:
node-version: ${{ matrix.nodejs_version }}
architecture: ${{ matrix.nodejs_arch }}
- name: Checkout
uses: actions/checkout@v4
- uses: actions/checkout@v4
- name: Install
run: npm install --build-from-source
- name: Test
run: npm test
- name: Test packaging
run: |
npm run package-from-local-build
npm pkg set "optionalDependencies.@img/sharp-${{ matrix.platform }}=file:./npm/${{ matrix.platform }}"
npm run clean
npm install --ignore-scripts
npm test
- name: Prebuild
if: matrix.prebuild && startsWith(github.ref, 'refs/tags/')
env:
prebuild_upload: ${{ secrets.GITHUB_TOKEN }}
run: |
node -e "require('fs').cpSync('package.json', 'src/package.json')"
cd src
npx prebuild
github-runner-qemu:
- name: Populate npm package
if: matrix.package
run: npm run package-from-local-build
- uses: actions/upload-artifact@v4
if: matrix.package
with:
name: ${{ matrix.platform }}
path: npm/${{ matrix.platform }}
retention-days: 1
if-no-files-found: error
build-linuxmusl-arm-64:
permissions:
contents: write
name: ${{ matrix.platform }} - Node.js ${{ matrix.nodejs_version_major }} - prebuild
contents: read
name: "build-linuxmusl-arm64 [Node.js ${{ matrix.nodejs_version_major }}] ${{ matrix.package && '[package]' }}"
runs-on: ubuntu-24.04-arm
container:
image: ${{ matrix.container }}
volumes:
- /:/host
strategy:
fail-fast: false
matrix:
include:
- container: node:18-alpine3.17
nodejs_version_major: 18
package: true
- container: node:20-alpine3.18
nodejs_version_major: 20
steps:
- name: Allow Linux musl containers on ARM64 runners # https://github.com/actions/runner/issues/801#issuecomment-2394425757
shell: sh
run: |
apk add nodejs
sed -i "s:ID=alpine:ID=NotpineForGHA:" /etc/os-release
cd /host/home/runner/runners/*/externals/
rm -rf node20/*
mkdir node20/bin
ln -s /usr/bin/node node20/bin/node
- name: Dependencies
run: apk add build-base git python3 font-noto --update-cache
- uses: actions/checkout@v4
- name: Install
run: npm install --build-from-source
- name: Test
run: npm test
- name: Populate npm package
if: matrix.package
run: npm run package-from-local-build
- uses: actions/upload-artifact@v4
if: matrix.package
with:
name: linuxmusl-arm64
path: npm/linuxmusl-arm64
retention-days: 1
if-no-files-found: error
build-qemu:
permissions:
contents: read
name: "build-${{ matrix.platform }} [Node.js ${{ matrix.nodejs_version_major }}] [package]"
runs-on: ubuntu-24.04
strategy:
fail-fast: false
@@ -198,8 +250,6 @@ jobs:
with:
arch: ${{ matrix.run_on_arch }}
distro: ${{ matrix.distro }}
env: |
prebuild_upload: "${{ startsWith(github.ref, 'refs/tags/') && secrets.GITHUB_TOKEN || '' }}"
run: |
apt-get update
apt-get install -y curl g++ git libatomic1 make python3 xz-utils
@@ -209,20 +259,20 @@ jobs:
npm install --build-from-source
npx mocha --no-config --spec=test/unit/io.js --timeout=30000
npm run package-from-local-build
npm pkg set "optionalDependencies.@img/sharp-${{ matrix.platform }}=file:./npm/${{ matrix.platform }}"
npm run clean
npm install --ignore-scripts
npx mocha --no-config --spec=test/unit/io.js --timeout=30000
[[ -n $prebuild_upload ]] && cd src && ln -s ../package.json && npx prebuild || true
github-runner-emscripten:
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.platform }}
path: npm/${{ matrix.platform }}
retention-days: 1
if-no-files-found: error
build-emscripten:
permissions:
contents: write
name: wasm32 - prebuild
contents: read
name: "build-wasm32 [package]"
runs-on: ubuntu-24.04
container: "emscripten/emsdk:4.0.6"
container: "emscripten/emsdk:4.0.10"
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/checkout@v4
- name: Dependencies
run: apt-get update && apt-get install -y pkg-config
- name: Dependencies (Node.js)
@@ -240,17 +290,35 @@ jobs:
test "$EMSCRIPTEN_VERSION_LIBVIPS" = "$EMSCRIPTEN_VERSION_SHARP"
- name: Test
run: emmake npm test
- name: Test packaging
run: |
emmake npm run package-from-local-build
npm pkg set "optionalDependencies.@img/sharp-wasm32=file:./npm/wasm32"
npm run clean
rm -rf node_modules/@img/sharp-linux-x64
npm install --cpu=wasm32
npm test
- name: Prebuild
if: startsWith(github.ref, 'refs/tags/')
env:
npm_config_nodedir: emscripten
prebuild_upload: ${{ secrets.GITHUB_TOKEN }}
run: cd src && ln -s ../package.json && emmake npx prebuild --platform=emscripten --arch=wasm32 --strip=0
- name: Populate npm package
run: emmake npm run package-from-local-build
- uses: actions/upload-artifact@v4
with:
name: wasm32
path: npm/wasm32
retention-days: 1
if-no-files-found: error
release:
permissions:
contents: write
runs-on: ubuntu-24.04
needs:
- build-native
- build-linuxmusl-arm-64
- build-qemu
- build-emscripten
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: npm
- name: Create npm workspace tarball
run: tar -vcaf npm-workspace.tar.xz --directory npm --exclude=from-local-build.js .
- name: Create GitHub release for tag
if: startsWith(github.ref, 'refs/tags/v')
uses: ncipollo/release-action@v1
with:
artifacts: npm-workspace.tar.xz
artifactContentType: application/x-xz
prerelease: ${{ contains(github.ref, '-rc') }}
makeLatest: ${{ !contains(github.ref, '-rc') }}

View File

@@ -70,27 +70,27 @@ jobs:
runtime: bun
- name: win32-x64-node-npm
runs-on: windows-2019
runs-on: windows-2022
runtime: node
package-manager: npm
- name: win32-x64-node-pnpm
runs-on: windows-2019
runs-on: windows-2022
runtime: node
package-manager: pnpm
- name: win32-x64-node-yarn
runs-on: windows-2019
runs-on: windows-2022
runtime: node
package-manager: yarn
- name: win32-x64-node-yarn-pnp
runs-on: windows-2019
runs-on: windows-2022
runtime: node
package-manager: yarn-pnp
- name: win32-x64-node-yarn-v1
runs-on: windows-2019
runs-on: windows-2022
runtime: node
package-manager: yarn-v1
- name: win32-x64-deno
runs-on: windows-2019
runs-on: windows-2022
runtime: deno
steps:

View File

@@ -1,6 +0,0 @@
{
"runtime": "napi",
"include-regex": "(sharp-.+\\.node|libvips-.+\\.dll)",
"prerelease": true,
"strip": true
}

View File

@@ -47,6 +47,7 @@ where the overall height is the `pageHeight` multiplied by the number of `pages`
| [options.subifd] | <code>number</code> | <code>-1</code> | subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image. |
| [options.level] | <code>number</code> | <code>0</code> | level to extract from a multi-level input (OpenSlide), zero based. |
| [options.pdfBackground] | <code>string</code> \| <code>Object</code> | | Background colour to use when PDF is partially transparent. Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick. |
| [options.jp2Oneshot] | <code>boolean</code> | <code>false</code> | Set to `true` to decode tiled JPEG 2000 images in a single operation, improving compatibility. |
| [options.animated] | <code>boolean</code> | <code>false</code> | Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`. |
| [options.raw] | <code>Object</code> | | describes raw pixel input image data. See `raw()` for pixel ordering. |
| [options.raw.width] | <code>number</code> | | integral number of pixels wide. |

View File

@@ -4,7 +4,19 @@ title: Changelog
## v0.34 - *hat*
Requires libvips v8.16.1
Requires libvips v8.17.0
### v0.34.3 - TBD
* Upgrade to libvips v8.17.0 for upstream bug fixes.
* Expose JPEG 2000 `oneshot` decoder option.
[#4262](https://github.com/lovell/sharp/pull/4262)
[@mbklein](https://github.com/mbklein)
* Support composite operation with non-sRGB pipeline colourspace.
[#4412](https://github.com/lovell/sharp/pull/4412)
[@kleisauke](https://github.com/kleisauke)
### v0.34.2 - 20th May 2025

View File

@@ -175,7 +175,7 @@ The default memory allocator on most glibc-based Linux systems
processes that involve lots of small memory allocations.
For this reason, by default, sharp will limit the use of thread-based
[concurrency](api-utility#concurrency) when the glibc allocator is
[concurrency](/api-utility#concurrency) when the glibc allocator is
detected at runtime.
To help avoid fragmentation and improve performance on these systems,

View File

@@ -156,6 +156,7 @@ const debuglog = util.debuglog('sharp');
* @param {number} [options.subifd=-1] - subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image.
* @param {number} [options.level=0] - level to extract from a multi-level input (OpenSlide), zero based.
* @param {string|Object} [options.pdfBackground] - Background colour to use when PDF is partially transparent. Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick.
* @param {boolean} [options.jp2Oneshot=false] - Set to `true` to decode tiled JPEG 2000 images in a single operation, improving compatibility.
* @param {boolean} [options.animated=false] - Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`.
* @param {Object} [options.raw] - describes raw pixel input image data. See `raw()` for pixel ordering.
* @param {number} [options.raw.width] - integral number of pixels wide.

2
lib/index.d.ts vendored
View File

@@ -1009,6 +1009,8 @@ declare namespace sharp {
level?: number | undefined;
/** Background colour to use when PDF is partially transparent. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick. */
pdfBackground?: Colour | Color | undefined;
/** Set to `true` to load JPEG 2000 images using [oneshot mode](https://github.com/libvips/libvips/issues/4205) */
jp2Oneshot?: boolean | undefined;
/** Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`). (optional, default false) */
animated?: boolean | undefined;
/** Describes raw pixel input image data. See raw() for pixel ordering. */

View File

@@ -27,9 +27,9 @@ const align = {
* @private
*/
function _inputOptionsFromObject (obj) {
const { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground, autoOrient } = obj;
return [raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground, autoOrient].some(is.defined)
? { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground, autoOrient }
const { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground, autoOrient, jp2Oneshot } = obj;
return [raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground, autoOrient, jp2Oneshot].some(is.defined)
? { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground, autoOrient, jp2Oneshot }
: undefined;
}
@@ -250,6 +250,14 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
if (is.defined(inputOptions.pdfBackground)) {
inputDescriptor.pdfBackground = this._getBackgroundColourOption(inputOptions.pdfBackground);
}
// JP2 oneshot
if (is.defined(inputOptions.jp2Oneshot)) {
if (is.bool(inputOptions.jp2Oneshot)) {
inputDescriptor.jp2Oneshot = inputOptions.jp2Oneshot;
} else {
throw is.invalidParameterError('jp2Oneshot', 'boolean', inputOptions.jp2Oneshot);
}
}
// Create new image
if (is.defined(inputOptions.create)) {
if (

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-darwin-arm64",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with macOS 64-bit ARM",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
@@ -15,7 +15,7 @@
},
"preferUnplugged": true,
"optionalDependencies": {
"@img/sharp-libvips-darwin-arm64": "1.1.0"
"@img/sharp-libvips-darwin-arm64": "1.2.0-rc.2"
},
"files": [
"lib"

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-darwin-x64",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with macOS x64",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
@@ -15,7 +15,7 @@
},
"preferUnplugged": true,
"optionalDependencies": {
"@img/sharp-libvips-darwin-x64": "1.1.0"
"@img/sharp-libvips-darwin-x64": "1.2.0-rc.2"
},
"files": [
"lib"

View File

@@ -1,73 +0,0 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
// Populate contents of all packages with the current GitHub release
const { readFile, writeFile, appendFile, copyFile, rm } = require('node:fs/promises');
const path = require('node:path');
const { Readable } = require('node:stream');
const { pipeline } = require('node:stream/promises');
const { createGunzip } = require('node:zlib');
const { extract } = require('tar-fs');
const { workspaces } = require('./package.json');
const { version } = require('../package.json');
const mapTarballEntry = (header) => {
header.name = path.basename(header.name);
return header;
};
const licensing = `
## Licensing
Copyright 2013 Lovell Fuller and others.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
`;
workspaces.map(async platform => {
const prebuildPlatform = platform === 'wasm32' ? 'emscripten-wasm32' : platform;
const url = `https://github.com/lovell/sharp/releases/download/v${version}/sharp-v${version}-napi-v9-${prebuildPlatform}.tar.gz`;
const dir = path.join(__dirname, platform);
const response = await fetch(url);
if (!response.ok) {
console.log(`Skipping ${platform}: ${response.statusText}`);
return;
}
// Extract prebuild tarball
const lib = path.join(dir, 'lib');
await rm(lib, { force: true, recursive: true });
await pipeline(
Readable.fromWeb(response.body),
createGunzip(),
extract(lib, { map: mapTarballEntry })
);
// Generate README
const { name, description } = require(`./${platform}/package.json`);
await writeFile(path.join(dir, 'README.md'), `# \`${name}\`\n\n${description}.\n${licensing}`);
// Copy Apache-2.0 LICENSE
await copyFile(path.join(__dirname, '..', 'LICENSE'), path.join(dir, 'LICENSE'));
// Copy files for packages without an explicit sharp-libvips dependency (Windows, wasm)
if (platform.startsWith('win') || platform.startsWith('wasm')) {
const libvipsPlatform = platform === 'wasm32' ? 'dev-wasm32' : platform;
const sharpLibvipsDir = path.join(require(`@img/sharp-libvips-${libvipsPlatform}/lib`), '..');
// Copy versions.json
await copyFile(path.join(sharpLibvipsDir, 'versions.json'), path.join(dir, 'versions.json'));
// Append third party licensing to README
const readme = await readFile(path.join(sharpLibvipsDir, 'README.md'), { encoding: 'utf-8' });
const thirdParty = readme.substring(readme.indexOf('\nThis software contains'));
appendFile(path.join(dir, 'README.md'), thirdParty);
}
});

View File

@@ -3,24 +3,62 @@
'use strict';
// Populate contents of a single npm/sharpen-sharp-<build-platform> package
// with the local/CI build directory for local/CI prebuild testing
// Populate the npm package for the current platform with the local build
const fs = require('node:fs');
const path = require('node:path');
const { copyFileSync, cpSync, readFileSync, writeFileSync, appendFileSync } = require('node:fs');
const { basename, join } = require('node:path');
const { buildPlatformArch } = require('../lib/libvips');
const platform = buildPlatformArch();
const dest = path.join(__dirname, platform);
// Use same config as prebuild to copy binary files
const release = path.join(__dirname, '..', 'src', 'build', 'Release');
const prebuildrc = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '.prebuildrc'), 'utf8'));
const include = new RegExp(prebuildrc['include-regex'], 'i');
fs.cpSync(release, path.join(dest, 'lib'), {
const licensing = `
## Licensing
Copyright 2013 Lovell Fuller and others.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
`;
const platform = buildPlatformArch();
const destDir = join(__dirname, platform);
console.log(`Populating npm package for platform: ${platform}`);
// Copy binaries
const releaseDir = join(__dirname, '..', 'src', 'build', 'Release');
const libDir = join(destDir, 'lib');
cpSync(releaseDir, libDir, {
recursive: true,
filter: (file) => {
const name = path.basename(file);
return name === 'Release' || include.test(name);
const name = basename(file);
return name === 'Release' ||
(name.startsWith('sharp-') && name.includes('.node')) ||
(name.startsWith('libvips-') && name.endsWith('.dll'));
}
});
// Generate README
const { name, description } = require(`./${platform}/package.json`);
writeFileSync(join(destDir, 'README.md'), `# \`${name}\`\n\n${description}.\n${licensing}`);
// Copy Apache-2.0 LICENSE
copyFileSync(join(__dirname, '..', 'LICENSE'), join(destDir, 'LICENSE'));
// Copy files for packages without an explicit sharp-libvips dependency (Windows, wasm)
if (platform.startsWith('win') || platform.startsWith('wasm')) {
const libvipsPlatform = platform === 'wasm32' ? 'dev-wasm32' : platform;
const sharpLibvipsDir = join(require(`@img/sharp-libvips-${libvipsPlatform}/lib`), '..');
// Copy versions.json
copyFileSync(join(sharpLibvipsDir, 'versions.json'), join(destDir, 'versions.json'));
// Append third party licensing to README
const readme = readFileSync(join(sharpLibvipsDir, 'README.md'), { encoding: 'utf-8' });
const thirdParty = readme.substring(readme.indexOf('\nThis software contains'));
appendFileSync(join(destDir, 'README.md'), thirdParty);
}

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-linux-arm",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with Linux (glibc) ARM (32-bit)",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
@@ -15,7 +15,7 @@
},
"preferUnplugged": true,
"optionalDependencies": {
"@img/sharp-libvips-linux-arm": "1.1.0"
"@img/sharp-libvips-linux-arm": "1.2.0-rc.2"
},
"files": [
"lib"

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-linux-arm64",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with Linux (glibc) 64-bit ARM",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
@@ -15,7 +15,7 @@
},
"preferUnplugged": true,
"optionalDependencies": {
"@img/sharp-libvips-linux-arm64": "1.1.0"
"@img/sharp-libvips-linux-arm64": "1.2.0-rc.2"
},
"files": [
"lib"

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-linux-ppc64",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with Linux (glibc) ppc64",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
@@ -15,7 +15,7 @@
},
"preferUnplugged": true,
"optionalDependencies": {
"@img/sharp-libvips-linux-ppc64": "1.1.0"
"@img/sharp-libvips-linux-ppc64": "1.2.0-rc.2"
},
"files": [
"lib"

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-linux-s390x",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with Linux (glibc) s390x",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
@@ -15,7 +15,7 @@
},
"preferUnplugged": true,
"optionalDependencies": {
"@img/sharp-libvips-linux-s390x": "1.1.0"
"@img/sharp-libvips-linux-s390x": "1.2.0-rc.2"
},
"files": [
"lib"

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-linux-x64",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with Linux (glibc) x64",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
@@ -15,7 +15,7 @@
},
"preferUnplugged": true,
"optionalDependencies": {
"@img/sharp-libvips-linux-x64": "1.1.0"
"@img/sharp-libvips-linux-x64": "1.2.0-rc.2"
},
"files": [
"lib"

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-linuxmusl-arm64",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with Linux (musl) 64-bit ARM",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
@@ -15,7 +15,7 @@
},
"preferUnplugged": true,
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-arm64": "1.1.0"
"@img/sharp-libvips-linuxmusl-arm64": "1.2.0-rc.2"
},
"files": [
"lib"

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-linuxmusl-x64",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with Linux (musl) x64",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
@@ -15,7 +15,7 @@
},
"preferUnplugged": true,
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-x64": "1.1.0"
"@img/sharp-libvips-linuxmusl-x64": "1.2.0-rc.2"
},
"files": [
"lib"

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"private": "true",
"workspaces": [
"darwin-arm64",

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-wasm32",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with wasm32",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-win32-arm64",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with Windows 64-bit ARM",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-win32-ia32",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with Windows x86 (32-bit)",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",

View File

@@ -1,6 +1,6 @@
{
"name": "@img/sharp-win32-x64",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"description": "Prebuilt sharp for use with Windows x64",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",

View File

@@ -1,7 +1,7 @@
{
"name": "sharp",
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
"version": "0.34.2",
"version": "0.34.3-rc.0",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
"contributors": [
@@ -92,7 +92,7 @@
"Don Denton <don@happycollision.com>"
],
"scripts": {
"install": "node install/check",
"install": "node install/check.js",
"clean": "rm -rf src/build/ .nyc_output/ coverage/ test/fixtures/output.*",
"test": "npm run test-lint && npm run test-unit && npm run test-licensing && npm run test-types",
"test-lint": "semistandard && cpplint",
@@ -100,8 +100,7 @@
"test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;LGPL-3.0-or-later;MIT\"",
"test-leak": "./test/leak/leak.sh",
"test-types": "tsd",
"package-from-local-build": "node npm/from-local-build",
"package-from-github-release": "node npm/from-github-release",
"package-from-local-build": "node npm/from-local-build.js",
"docs-build": "node docs/build.mjs",
"docs-serve": "cd docs && npm start",
"docs-publish": "cd docs && npm run build && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
@@ -142,35 +141,36 @@
"semver": "^7.7.2"
},
"optionalDependencies": {
"@img/sharp-darwin-arm64": "0.34.2",
"@img/sharp-darwin-x64": "0.34.2",
"@img/sharp-libvips-darwin-arm64": "1.1.0",
"@img/sharp-libvips-darwin-x64": "1.1.0",
"@img/sharp-libvips-linux-arm": "1.1.0",
"@img/sharp-libvips-linux-arm64": "1.1.0",
"@img/sharp-libvips-linux-ppc64": "1.1.0",
"@img/sharp-libvips-linux-s390x": "1.1.0",
"@img/sharp-libvips-linux-x64": "1.1.0",
"@img/sharp-libvips-linuxmusl-arm64": "1.1.0",
"@img/sharp-libvips-linuxmusl-x64": "1.1.0",
"@img/sharp-linux-arm": "0.34.2",
"@img/sharp-linux-arm64": "0.34.2",
"@img/sharp-linux-s390x": "0.34.2",
"@img/sharp-linux-x64": "0.34.2",
"@img/sharp-linuxmusl-arm64": "0.34.2",
"@img/sharp-linuxmusl-x64": "0.34.2",
"@img/sharp-wasm32": "0.34.2",
"@img/sharp-win32-arm64": "0.34.2",
"@img/sharp-win32-ia32": "0.34.2",
"@img/sharp-win32-x64": "0.34.2"
"@img/sharp-darwin-arm64": "0.34.3-rc.0",
"@img/sharp-darwin-x64": "0.34.3-rc.0",
"@img/sharp-libvips-darwin-arm64": "1.2.0-rc.2",
"@img/sharp-libvips-darwin-x64": "1.2.0-rc.2",
"@img/sharp-libvips-linux-arm": "1.2.0-rc.2",
"@img/sharp-libvips-linux-arm64": "1.2.0-rc.2",
"@img/sharp-libvips-linux-ppc64": "1.2.0-rc.2",
"@img/sharp-libvips-linux-s390x": "1.2.0-rc.2",
"@img/sharp-libvips-linux-x64": "1.2.0-rc.2",
"@img/sharp-libvips-linuxmusl-arm64": "1.2.0-rc.2",
"@img/sharp-libvips-linuxmusl-x64": "1.2.0-rc.2",
"@img/sharp-linux-arm": "0.34.3-rc.0",
"@img/sharp-linux-arm64": "0.34.3-rc.0",
"@img/sharp-linux-ppc64": "0.34.3-rc.0",
"@img/sharp-linux-s390x": "0.34.3-rc.0",
"@img/sharp-linux-x64": "0.34.3-rc.0",
"@img/sharp-linuxmusl-arm64": "0.34.3-rc.0",
"@img/sharp-linuxmusl-x64": "0.34.3-rc.0",
"@img/sharp-wasm32": "0.34.3-rc.0",
"@img/sharp-win32-arm64": "0.34.3-rc.0",
"@img/sharp-win32-ia32": "0.34.3-rc.0",
"@img/sharp-win32-x64": "0.34.3-rc.0"
},
"devDependencies": {
"@emnapi/runtime": "^1.4.3",
"@img/sharp-libvips-dev": "1.1.0",
"@img/sharp-libvips-dev-wasm32": "1.1.0",
"@img/sharp-libvips-win32-arm64": "1.1.0",
"@img/sharp-libvips-win32-ia32": "1.1.0",
"@img/sharp-libvips-win32-x64": "1.1.0",
"@img/sharp-libvips-dev": "1.2.0-rc.2",
"@img/sharp-libvips-dev-wasm32": "1.2.0-rc.2",
"@img/sharp-libvips-win32-arm64": "1.2.0-rc.2",
"@img/sharp-libvips-win32-ia32": "1.2.0-rc.2",
"@img/sharp-libvips-win32-x64": "1.2.0-rc.2",
"@types/node": "*",
"cc": "^3.0.1",
"emnapi": "^1.4.3",
@@ -179,12 +179,12 @@
"icc": "^3.0.0",
"jsdoc-to-markdown": "^9.1.1",
"license-checker": "^25.0.1",
"mocha": "^11.4.0",
"mocha": "^11.6.0",
"node-addon-api": "^8.3.1",
"node-gyp": "^11.2.0",
"nyc": "^17.1.0",
"prebuild": "^13.0.1",
"semistandard": "^17.0.0",
"tar-fs": "^3.0.8",
"tar-fs": "^3.0.9",
"tsd": "^0.32.0"
},
"license": "Apache-2.0",
@@ -192,16 +192,11 @@
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"config": {
"libvips": ">=8.16.1"
"libvips": ">=8.17.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"binary": {
"napi_versions": [
9
]
},
"semistandard": {
"env": [
"mocha"

View File

@@ -163,6 +163,8 @@
},
'xcode_settings': {
'OTHER_LDFLAGS': [
'-Wl,-s',
'-Wl,-dead_strip',
# Ensure runtime linking is relative to sharp.node
'-Wl,-rpath,\'@loader_path/../../sharp-libvips-<(platform_and_arch)/lib\'',
'-Wl,-rpath,\'@loader_path/../../../sharp-libvips-<(platform_and_arch)/<(sharp_libvips_version)/lib\'',
@@ -176,6 +178,9 @@
'defines': [
'_GLIBCXX_USE_CXX11_ABI=1'
],
'cflags_cc': [
'<!(node -p "require(\'detect-libc\').isNonGlibcLinuxSync() ? \'\' : \'-flto=auto\'")'
],
'link_settings': {
'libraries': [
'-l:libvips-cpp.so.<(vips_version)'

View File

@@ -113,6 +113,10 @@ namespace sharp {
if (HasAttr(input, "pdfBackground")) {
descriptor->pdfBackground = AttrAsVectorOfDouble(input, "pdfBackground");
}
// Use JPEG 2000 oneshot mode?
if (HasAttr(input, "jp2Oneshot")) {
descriptor->jp2Oneshot = AttrAsBool(input, "jp2Oneshot");
}
// Create new image
if (HasAttr(input, "createChannels")) {
descriptor->createChannels = AttrAsUint32(input, "createChannels");
@@ -434,6 +438,9 @@ namespace sharp {
if (imageType == ImageType::PDF) {
option->set("background", descriptor->pdfBackground);
}
if (imageType == ImageType::JP2) {
option->set("oneshot", descriptor->jp2Oneshot);
}
image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
image = SetDensity(image, descriptor->density);
@@ -541,6 +548,9 @@ namespace sharp {
if (imageType == ImageType::PDF) {
option->set("background", descriptor->pdfBackground);
}
if (imageType == ImageType::JP2) {
option->set("oneshot", descriptor->jp2Oneshot);
}
image = VImage::new_from_file(descriptor->file.data(), option);
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
image = SetDensity(image, descriptor->density);

View File

@@ -15,9 +15,9 @@
// Verify platform and compiler compatibility
#if (VIPS_MAJOR_VERSION < 8) || \
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 16) || \
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 16 && VIPS_MICRO_VERSION < 1)
#error "libvips version 8.16.1+ is required - please see https://sharp.pixelplumbing.com/install"
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 17) || \
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 17 && VIPS_MICRO_VERSION < 0)
#error "libvips version 8.17.0+ is required - please see https://sharp.pixelplumbing.com/install"
#endif
#if defined(__has_include)
@@ -78,6 +78,7 @@ namespace sharp {
VipsAlign joinHalign;
VipsAlign joinValign;
std::vector<double> pdfBackground;
bool jp2Oneshot;
InputDescriptor():
autoOrient(false),
@@ -120,7 +121,8 @@ namespace sharp {
joinBackground{ 0.0, 0.0, 0.0, 255.0 },
joinHalign(VIPS_ALIGN_LOW),
joinValign(VIPS_ALIGN_LOW),
pdfBackground{ 255.0, 255.0, 255.0, 255.0 } {}
pdfBackground{ 255.0, 255.0, 255.0, 255.0 },
jp2Oneshot(false) {}
};
// Convenience methods to access the attributes of a Napi::Object

View File

@@ -669,7 +669,6 @@ class PipelineWorker : public Napi::AsyncWorker {
sharp::ImageType compositeImageType = sharp::ImageType::UNKNOWN;
composite->input->access = access;
std::tie(compositeImage, compositeImageType) = sharp::OpenInput(composite->input);
compositeImage = sharp::EnsureColourspace(compositeImage, baton->colourspacePipeline);
if (composite->input->autoOrient) {
// Respect EXIF Orientation
@@ -734,8 +733,7 @@ class PipelineWorker : public Napi::AsyncWorker {
// gravity was used for extract_area, set it back to its default value of 0
composite->gravity = 0;
}
// Ensure image to composite is sRGB with unpremultiplied alpha
compositeImage = compositeImage.colourspace(VIPS_INTERPRETATION_sRGB);
// Ensure image to composite is with unpremultiplied alpha
compositeImage = sharp::EnsureAlpha(compositeImage, 1);
if (composite->premultiplied) compositeImage = compositeImage.unpremultiply();
// Calculate position
@@ -760,7 +758,12 @@ class PipelineWorker : public Napi::AsyncWorker {
xs.push_back(left);
ys.push_back(top);
}
image = VImage::composite(images, modes, VImage::option()->set("x", xs)->set("y", ys));
image = VImage::composite(images, modes, VImage::option()
->set("compositing_space", baton->colourspacePipeline == VIPS_INTERPRETATION_LAST
? VIPS_INTERPRETATION_sRGB
: baton->colourspacePipeline)
->set("x", xs)
->set("y", ys));
image = sharp::RemoveGifPalette(image);
}

View File

@@ -18,8 +18,10 @@ Napi::Object init(Napi::Env env, Napi::Object exports) {
vips_init("sharp");
});
g_log_set_handler("VIPS", static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING),
static_cast<GLogFunc>(sharp::VipsWarningCallback), nullptr);
for (auto domain : { "VIPS", "vips2tiff" }) {
g_log_set_handler(domain, static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING),
static_cast<GLogFunc>(sharp::VipsWarningCallback), nullptr);
}
// Methods available to JavaScript
exports.Set("metadata", Napi::Function::New(env, metadata));

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

View File

@@ -117,6 +117,7 @@ module.exports = {
inputTiffFogra: getPath('fogra-0-100-100-0.tif'), // https://github.com/lovell/sharp/issues/4045
inputJp2: getPath('relax.jp2'), // https://www.fnordware.com/j2k/relax.jp2
inputJp2TileParts: getPath('relax_tileparts.jp2'), // kdu_expand -i relax.jp2 -o relax-tmp.tif ; kdu_compress -i relax-tmp.tif -o relax_tileparts.jp2 -jp2_space sRGB Clayers=8 -rate 1.0,0.04 Stiles='{128,128}' ORGtparts=L ; rm relax-tmp.tif
inputGif: getPath('Crash_test.gif'), // http://upload.wikimedia.org/wikipedia/commons/e/e3/Crash_test.gif
inputGifGreyPlusAlpha: getPath('grey-plus-alpha.gif'), // http://i.imgur.com/gZ5jlmE.gif
inputGifAnimated: getPath('rotating-squares.gif'), // CC0 https://loading.io/spinner/blocks/-rotating-squares-preloader-gif

BIN
test/fixtures/relax_tileparts.jp2 vendored Normal file

Binary file not shown.

View File

@@ -721,6 +721,9 @@ const color: sharp.Color = '#fff';
sharp({ pdfBackground: colour });
sharp({ pdfBackground: color });
sharp({ jp2Oneshot: true });
sharp({ jp2Oneshot: false });
sharp({ autoOrient: true });
sharp({ autoOrient: false });
sharp().autoOrient();

View File

@@ -122,6 +122,26 @@ describe('composite', () => {
});
});
it('scrgb pipeline', () => {
const filename = 'composite-red-scrgb.png';
const actual = fixtures.path(`output.${filename}`);
const expected = fixtures.expected(filename);
return sharp({
create: {
width: 32, height: 32, channels: 4, background: red
}
})
.pipelineColourspace('scrgb')
.composite([{
input: fixtures.inputPngWithTransparency16bit,
blend: 'color-burn'
}])
.toFile(actual)
.then(() => {
fixtures.assertMaxColourDistance(actual, expected);
});
});
it('multiple', async () => {
const filename = 'composite-multiple.png';
const actual = fixtures.path(`output.${filename}`);

View File

@@ -93,10 +93,38 @@ describe('JP2 output', () => {
});
});
it('Invalid JP2 chromaSubsampling value throws error', function () {
assert.throws(function () {
sharp().jpeg({ chromaSubsampling: '4:2:2' });
it('can use the jp2Oneshot option to handle multi-part tiled JPEG 2000 file', async () => {
const outputJpg = fixtures.path('output.jpg');
await assert.rejects(
() => sharp(fixtures.inputJp2TileParts).toFile(outputJpg)
);
await assert.doesNotReject(async () => {
await sharp(fixtures.inputJp2TileParts, { jp2Oneshot: true }).toFile(outputJpg);
const { format, width, height } = await sharp(outputJpg).metadata();
assert.strictEqual(format, 'jpeg');
assert.strictEqual(width, 320);
assert.strictEqual(height, 240);
});
});
it('Invalid JP2 chromaSubsampling value throws error', () => {
assert.throws(
() => sharp().jp2({ chromaSubsampling: '4:2:2' }),
/Expected one of 4:2:0, 4:4:4 but received 4:2:2 of type string/
);
});
}
it('valid JP2 oneshot value does not throw error', () => {
assert.doesNotThrow(
() => sharp(fixtures.inputJp2TileParts, { jp2Oneshot: true })
);
});
it('invalid JP2 oneshot value throws error', () => {
assert.throws(
() => sharp(fixtures.inputJp2TileParts, { jp2Oneshot: 'fail' }),
/Expected boolean for jp2Oneshot but received fail of type string/
);
});
});

View File

@@ -179,7 +179,7 @@ describe('libvips binaries', function () {
process.env.npm_config_arch = 's390x';
process.env.npm_config_libc = '';
const locatorHash = libvips.yarnLocator();
assert.strictEqual(locatorHash, '9b2ea457de');
assert.strictEqual(locatorHash, 'e23686d7dd');
delete process.env.npm_config_platform;
delete process.env.npm_config_arch;
delete process.env.npm_config_libc;