mirror of
https://github.com/lovell/sharp.git
synced 2026-02-04 21:56:18 +01:00
Compare commits
39 Commits
v0.34.0
...
v0.34.3-rc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8669fbc936 | ||
|
|
cab02463ec | ||
|
|
5374b036f3 | ||
|
|
327a6d2083 | ||
|
|
751f9992c4 | ||
|
|
01f6cbbaee | ||
|
|
99be893dd4 | ||
|
|
4d1f7e051d | ||
|
|
91f1b58f31 | ||
|
|
6d04b7c1fa | ||
|
|
d4b30b7392 | ||
|
|
7f03502003 | ||
|
|
63b0a11b5b | ||
|
|
c4d6aec48c | ||
|
|
e75ae970ed | ||
|
|
956d72ddc0 | ||
|
|
00e66efbee | ||
|
|
db3a4528eb | ||
|
|
d36fd5064d | ||
|
|
8e17c6f518 | ||
|
|
94481a967e | ||
|
|
32872ef840 | ||
|
|
7c7f960b60 | ||
|
|
0b5f131df8 | ||
|
|
e922ef7450 | ||
|
|
73bec629cf | ||
|
|
758d7e63cc | ||
|
|
eba3e9aeb2 | ||
|
|
701143afb3 | ||
|
|
38b6f44611 | ||
|
|
5b5dfbad77 | ||
|
|
a642767329 | ||
|
|
5cae1abe8f | ||
|
|
66ffc48707 | ||
|
|
3c7dbb8fba | ||
|
|
a9e191328f | ||
|
|
7323dbee98 | ||
|
|
d7a771ca7a | ||
|
|
7d0585fad1 |
@@ -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"
|
||||
@@ -1,5 +1,5 @@
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-0-snap
|
||||
image_family: freebsd-15-0-snap
|
||||
|
||||
task:
|
||||
name: FreeBSD
|
||||
|
||||
207
.github/workflows/ci.yml
vendored
207
.github/workflows/ci.yml
vendored
@@ -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,44 +91,55 @@ 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
|
||||
platform: win32-x64
|
||||
- os: windows-11-arm
|
||||
nodejs_arch: arm64
|
||||
nodejs_version: "^20.3.0"
|
||||
nodejs_version_major: 20
|
||||
platform: win32-arm64
|
||||
package: true
|
||||
- os: windows-11-arm
|
||||
nodejs_arch: arm64
|
||||
nodejs_version: "^22.9.0"
|
||||
nodejs_version_major: 22
|
||||
platform: win32-arm64
|
||||
steps:
|
||||
- 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
|
||||
@@ -130,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
|
||||
@@ -187,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
|
||||
@@ -198,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)
|
||||
@@ -229,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') }}
|
||||
|
||||
12
.github/workflows/npm.yml
vendored
12
.github/workflows/npm.yml
vendored
@@ -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:
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"runtime": "napi",
|
||||
"include-regex": "(sharp-.+\\.node|libvips-.+\\.dll)",
|
||||
"prerelease": true,
|
||||
"strip": true
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# sharp
|
||||
|
||||
<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
|
||||
<img src="https://sharp.pixelplumbing.com/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
|
||||
|
||||
The typical use case for this high speed Node-API module
|
||||
is to convert large images in common formats to
|
||||
|
||||
@@ -18,7 +18,7 @@ export default defineConfig({
|
||||
tag: 'meta',
|
||||
attrs: {
|
||||
'http-equiv': 'Content-Security-Policy',
|
||||
content: "default-src 'self'; connect-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://cdn.jsdelivr.net/gh/lovell/; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://static.cloudflareinsights.com/beacon.min.js/;"
|
||||
content: "default-src 'self'; connect-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://static.cloudflareinsights.com/beacon.min.js/;"
|
||||
}
|
||||
}, {
|
||||
tag: 'link',
|
||||
@@ -70,10 +70,10 @@ export default defineConfig({
|
||||
{ label: 'Performance', slug: 'performance' },
|
||||
{ label: 'Changelog', slug: 'changelog' }
|
||||
],
|
||||
social: {
|
||||
openCollective: 'https://opencollective.com/libvips',
|
||||
github: 'https://github.com/lovell/sharp'
|
||||
}
|
||||
social: [
|
||||
{ icon: 'openCollective', label: 'Open Collective', href: 'https://opencollective.com/libvips' },
|
||||
{ icon: 'github', label: 'GitHub', href: 'https://github.com/lovell/sharp' }
|
||||
]
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
@@ -11,99 +11,6 @@
|
||||
{ "key": "X-Frame-Options", "value": "SAMEORIGIN" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"redirects": [
|
||||
{
|
||||
"source": "**/install/**",
|
||||
"destination": "/install",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "/page/install",
|
||||
"destination": "/install",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/api-constructor/**",
|
||||
"destination": "/api-constructor",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/api-input/**",
|
||||
"destination": "/api-input",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/api-output/**",
|
||||
"destination": "/api-output",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/api-resize/**",
|
||||
"destination": "/api-resize",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/api-compsite/**",
|
||||
"destination": "/api-compsite",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/api-operation/**",
|
||||
"destination": "/api-operation",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/api-colour/**",
|
||||
"destination": "/api-colour",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/api-channel/**",
|
||||
"destination": "/api-channel",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/api-utility/**",
|
||||
"destination": "/api-utility",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "/page/api",
|
||||
"destination": "/api-constructor",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/performance/**",
|
||||
"destination": "/performance",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "/page/performance",
|
||||
"destination": "/performance",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/changelog/**",
|
||||
"destination": "/changelog",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "/page/changelog",
|
||||
"destination": "/changelog",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "/en/**",
|
||||
"destination": "/",
|
||||
"type": 301
|
||||
}
|
||||
],
|
||||
"rewrites": [
|
||||
{
|
||||
"source": "**",
|
||||
"destination": "/index.html"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/starlight": "^0.32.3",
|
||||
"astro": "^5.5.3"
|
||||
"@astrojs/starlight": "^0.34.3",
|
||||
"astro": "^5.7.13"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,3 +317,6 @@ GitHub: https://github.com/florentzabera
|
||||
|
||||
Name: Quentin Pinçon
|
||||
GitHub: https://github.com/qpincon
|
||||
|
||||
Name: Hans Chen
|
||||
GitHub: https://github.com/hans00
|
||||
|
||||
@@ -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. |
|
||||
|
||||
@@ -626,6 +626,9 @@ Use these AVIF options for output image.
|
||||
AVIF image sequences are not supported.
|
||||
Prebuilt binaries support a bitdepth of 8 only.
|
||||
|
||||
This feature is experimental on the Windows ARM64 platform
|
||||
and requires a CPU with ARM64v8.4 or later.
|
||||
|
||||
|
||||
**Throws**:
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ When both a `width` and `height` are provided, the possible methods by which the
|
||||
|
||||
Some of these values are based on the [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) CSS property.
|
||||
|
||||
<img alt="Examples of various values for the fit property when resizing" width="100%" style="aspect-ratio: 998/243" src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/api-resize-fit.svg">
|
||||
<img alt="Examples of various values for the fit property when resizing" width="100%" style="aspect-ratio: 998/243" src="/api-resize-fit.svg">
|
||||
|
||||
When using a **fit** of `cover` or `contain`, the default **position** is `centre`. Other options are:
|
||||
- `sharp.position`: `top`, `right top`, `right`, `right bottom`, `bottom`, `left bottom`, `left`, `left top`.
|
||||
|
||||
@@ -4,7 +4,51 @@ 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
|
||||
|
||||
* Ensure animated GIF to WebP conversion retains loop (regression in 0.34.0).
|
||||
[#3394](https://github.com/lovell/sharp/issues/3394)
|
||||
|
||||
* Ensure `pdfBackground` constructor property is used.
|
||||
[#4207](https://github.com/lovell/sharp/pull/4207)
|
||||
[#4398](https://github.com/lovell/sharp/issues/4398)
|
||||
|
||||
* Add experimental support for prebuilt Windows ARM64 binaries.
|
||||
[#4375](https://github.com/lovell/sharp/pull/4375)
|
||||
[@hans00](https://github.com/hans00)
|
||||
|
||||
* Ensure resizing with a `fit` of `contain` supports multiple alpha channels.
|
||||
[#4382](https://github.com/lovell/sharp/issues/4382)
|
||||
|
||||
* TypeScript: Ensure `metadata` response more closely matches reality.
|
||||
[#4383](https://github.com/lovell/sharp/issues/4383)
|
||||
|
||||
* TypeScript: Ensure `smartDeblock` property is included in WebP definition.
|
||||
[#4387](https://github.com/lovell/sharp/pull/4387)
|
||||
[@Stephen-X](https://github.com/Stephen-X)
|
||||
|
||||
* Ensure support for wide-character filenames on Windows (regression in 0.34.0).
|
||||
[#4391](https://github.com/lovell/sharp/issues/4391)
|
||||
|
||||
### v0.34.1 - 7th April 2025
|
||||
|
||||
* TypeScript: Ensure new `autoOrient` property is optional.
|
||||
[#4362](https://github.com/lovell/sharp/pull/4362)
|
||||
[@styfle](https://github.com/styfle)
|
||||
|
||||
### v0.34.0 - 4th April 2025
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
title: "High performance Node.js image processing"
|
||||
---
|
||||
|
||||
<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
|
||||
<img src="/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
|
||||
|
||||
The typical use case for this high speed Node-API module
|
||||
is to convert large images in common formats to
|
||||
|
||||
@@ -21,7 +21,7 @@ pnpm add sharp
|
||||
```
|
||||
|
||||
When using `pnpm`, you may need to add `sharp` to
|
||||
[ignoredBuiltDependencies](https://pnpm.io/package_json#pnpmignoredbuiltdependencies)
|
||||
[ignoredBuiltDependencies](https://pnpm.io/settings#ignoredbuiltdependencies)
|
||||
to silence warnings.
|
||||
|
||||
```sh
|
||||
@@ -53,6 +53,7 @@ Ready-compiled sharp and libvips binaries are provided for use on the most commo
|
||||
* Linux x64 (glibc >= 2.26, musl >= 1.2.2, CPU with SSE4.2)
|
||||
* Windows x64
|
||||
* Windows x86
|
||||
* Windows ARM64 (experimental, CPU with ARMv8.4 required for all features)
|
||||
|
||||
This provides support for the
|
||||
JPEG, PNG, WebP, AVIF (limited to 8-bit depth), TIFF, GIF and SVG (input) image formats.
|
||||
@@ -93,7 +94,7 @@ Use the [supportedArchitectures](https://yarnpkg.com/configuration/yarnrc#suppor
|
||||
|
||||
### pnpm v8+
|
||||
|
||||
Use the [supportedArchitectures](https://pnpm.io/package_json#pnpmsupportedarchitectures) configuration.
|
||||
Use the [supportedArchitectures](https://pnpm.io/settings#supportedarchitectures) configuration.
|
||||
|
||||
## Custom libvips
|
||||
|
||||
@@ -133,7 +134,7 @@ npm install --save node-addon-api node-gyp
|
||||
```
|
||||
|
||||
When using `pnpm`, you may need to add `sharp` to
|
||||
[onlyBuiltDependencies](https://pnpm.io/package_json#pnpmonlybuiltdependencies)
|
||||
[onlyBuiltDependencies](https://pnpm.io/settings#onlybuiltdependencies)
|
||||
to ensure the installation script can be run.
|
||||
|
||||
For cross-compiling, the `--platform`, `--arch` and `--libc` npm flags
|
||||
@@ -174,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,
|
||||
|
||||
@@ -134,6 +134,26 @@ function toColorspace (colorspace) {
|
||||
return this.toColourspace(colorspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a RGBA colour array from a given value.
|
||||
* @private
|
||||
* @param {string|Object} value
|
||||
* @throws {Error} Invalid value
|
||||
*/
|
||||
function _getBackgroundColourOption (value) {
|
||||
if (is.object(value) || is.string(value)) {
|
||||
const colour = color(value);
|
||||
return [
|
||||
colour.red(),
|
||||
colour.green(),
|
||||
colour.blue(),
|
||||
Math.round(colour.alpha() * 255)
|
||||
];
|
||||
} else {
|
||||
throw is.invalidParameterError('background', 'object or string', value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a colour attribute of the this.options Object.
|
||||
* @private
|
||||
@@ -143,17 +163,7 @@ function toColorspace (colorspace) {
|
||||
*/
|
||||
function _setBackgroundColourOption (key, value) {
|
||||
if (is.defined(value)) {
|
||||
if (is.object(value) || is.string(value)) {
|
||||
const colour = color(value);
|
||||
this.options[key] = [
|
||||
colour.red(),
|
||||
colour.green(),
|
||||
colour.blue(),
|
||||
Math.round(colour.alpha() * 255)
|
||||
];
|
||||
} else {
|
||||
throw is.invalidParameterError('background', 'object or string', value);
|
||||
}
|
||||
this.options[key] = _getBackgroundColourOption(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +183,7 @@ module.exports = function (Sharp) {
|
||||
toColourspace,
|
||||
toColorspace,
|
||||
// Private
|
||||
_getBackgroundColourOption,
|
||||
_setBackgroundColourOption
|
||||
});
|
||||
// Class attributes
|
||||
|
||||
@@ -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.
|
||||
@@ -298,7 +299,7 @@ const Sharp = function (input, options) {
|
||||
withExif: {},
|
||||
withExifMerge: true,
|
||||
resolveWithObject: false,
|
||||
loop: 1,
|
||||
loop: -1,
|
||||
delay: [],
|
||||
// output format
|
||||
jpegQuality: 80,
|
||||
|
||||
63
lib/index.d.ts
vendored
63
lib/index.d.ts
vendored
@@ -971,7 +971,7 @@ declare namespace sharp {
|
||||
*
|
||||
* Using this option will remove the EXIF `Orientation` tag, if any.
|
||||
*/
|
||||
autoOrient?: boolean;
|
||||
autoOrient?: boolean | undefined;
|
||||
/**
|
||||
* When to abort processing of invalid pixel data, one of (in order of sensitivity):
|
||||
* 'none' (least), 'truncated', 'error' or 'warning' (most), highers level imply lower levels, invalid metadata will always abort. (optional, default 'warning')
|
||||
@@ -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. */
|
||||
@@ -1146,13 +1148,13 @@ declare namespace sharp {
|
||||
/** Number value of the EXIF Orientation header, if present */
|
||||
orientation?: number | undefined;
|
||||
/** Name of decoder used to decompress image data e.g. jpeg, png, webp, gif, svg */
|
||||
format?: keyof FormatEnum | undefined;
|
||||
format: keyof FormatEnum;
|
||||
/** Total size of image in bytes, for Stream and Buffer input only */
|
||||
size?: number | undefined;
|
||||
/** Number of pixels wide (EXIF orientation is not taken into consideration) */
|
||||
width?: number | undefined;
|
||||
width: number;
|
||||
/** Number of pixels high (EXIF orientation is not taken into consideration) */
|
||||
height?: number | undefined;
|
||||
height: number;
|
||||
/** Any changed metadata after the image orientation is applied. */
|
||||
autoOrient: {
|
||||
/** Number of pixels wide (EXIF orientation is taken into consideration) */
|
||||
@@ -1161,19 +1163,19 @@ declare namespace sharp {
|
||||
height: number;
|
||||
};
|
||||
/** Name of colour space interpretation */
|
||||
space?: keyof ColourspaceEnum | undefined;
|
||||
space: keyof ColourspaceEnum;
|
||||
/** Number of bands e.g. 3 for sRGB, 4 for CMYK */
|
||||
channels?: Channels | undefined;
|
||||
channels: Channels;
|
||||
/** Name of pixel depth format e.g. uchar, char, ushort, float ... */
|
||||
depth?: string | undefined;
|
||||
depth: keyof DepthEnum;
|
||||
/** Number of pixels per inch (DPI), if present */
|
||||
density?: number | undefined;
|
||||
/** String containing JPEG chroma subsampling, 4:2:0 or 4:4:4 for RGB, 4:2:0:4 or 4:4:4:4 for CMYK */
|
||||
chromaSubsampling?: string | undefined;
|
||||
/** Boolean indicating whether the image is interlaced using a progressive scan */
|
||||
isProgressive?: boolean | undefined;
|
||||
isProgressive: boolean;
|
||||
/** Boolean indicating whether the image is palette-based (GIF, PNG). */
|
||||
isPalette?: boolean | undefined;
|
||||
isPalette: boolean;
|
||||
/** Number of bits per sample for each channel (GIF, PNG). */
|
||||
bitsPerSample?: number | undefined;
|
||||
/** Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP */
|
||||
@@ -1187,9 +1189,9 @@ declare namespace sharp {
|
||||
/** Number of the primary page in a HEIF image */
|
||||
pagePrimary?: number | undefined;
|
||||
/** Boolean indicating the presence of an embedded ICC profile */
|
||||
hasProfile?: boolean | undefined;
|
||||
hasProfile: boolean;
|
||||
/** Boolean indicating the presence of an alpha transparency channel */
|
||||
hasAlpha?: boolean | undefined;
|
||||
hasAlpha: boolean;
|
||||
/** Buffer containing raw EXIF data, if present */
|
||||
exif?: Buffer | undefined;
|
||||
/** Buffer containing raw ICC profile data, if present */
|
||||
@@ -1336,6 +1338,8 @@ declare namespace sharp {
|
||||
nearLossless?: boolean | undefined;
|
||||
/** Use high quality chroma subsampling (optional, default false) */
|
||||
smartSubsample?: boolean | undefined;
|
||||
/** Auto-adjust the deblocking filter, slow but can improve low contrast edges (optional, default false) */
|
||||
smartDeblock?: boolean | undefined;
|
||||
/** Level of CPU effort to reduce file size, integer 0-6 (optional, default 4) */
|
||||
effort?: number | undefined;
|
||||
/** Prevent use of animation key frames to minimise file size (slow) (optional, default false) */
|
||||
@@ -1699,6 +1703,10 @@ declare namespace sharp {
|
||||
/** When using the attention crop strategy, the focal point of the cropped region */
|
||||
attentionX?: number | undefined;
|
||||
attentionY?: number | undefined;
|
||||
/** Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP */
|
||||
pages?: number | undefined;
|
||||
/** Number of pixels high each page in a multi-page image will be. */
|
||||
pageHeight?: number | undefined;
|
||||
}
|
||||
|
||||
interface AvailableFormatInfo {
|
||||
@@ -1739,11 +1747,38 @@ declare namespace sharp {
|
||||
}
|
||||
|
||||
interface ColourspaceEnum {
|
||||
multiband: string;
|
||||
'b-w': string;
|
||||
bw: string;
|
||||
cmc: string;
|
||||
cmyk: string;
|
||||
fourier: string;
|
||||
grey16: string;
|
||||
histogram: string;
|
||||
hsv: string;
|
||||
lab: string;
|
||||
labq: string;
|
||||
labs: string;
|
||||
lch: string;
|
||||
matrix: string;
|
||||
multiband: string;
|
||||
rgb: string;
|
||||
rgb16: string;
|
||||
scrgb: string;
|
||||
srgb: string;
|
||||
xyz: string;
|
||||
yxy: string;
|
||||
}
|
||||
|
||||
interface DepthEnum {
|
||||
char: string;
|
||||
complex: string;
|
||||
double: string;
|
||||
dpcomplex: string;
|
||||
float: string;
|
||||
int: string;
|
||||
short: string;
|
||||
uchar: string;
|
||||
uint: string;
|
||||
ushort: string;
|
||||
}
|
||||
|
||||
type FailOnOptions = 'none' | 'truncated' | 'error' | 'warning';
|
||||
@@ -1812,6 +1847,7 @@ declare namespace sharp {
|
||||
interface FormatEnum {
|
||||
avif: AvailableFormatInfo;
|
||||
dz: AvailableFormatInfo;
|
||||
exr: AvailableFormatInfo;
|
||||
fits: AvailableFormatInfo;
|
||||
gif: AvailableFormatInfo;
|
||||
heif: AvailableFormatInfo;
|
||||
@@ -1825,6 +1861,7 @@ declare namespace sharp {
|
||||
pdf: AvailableFormatInfo;
|
||||
png: AvailableFormatInfo;
|
||||
ppm: AvailableFormatInfo;
|
||||
rad: AvailableFormatInfo;
|
||||
raw: AvailableFormatInfo;
|
||||
svg: AvailableFormatInfo;
|
||||
tiff: AvailableFormatInfo;
|
||||
|
||||
33
lib/input.js
33
lib/input.js
@@ -3,7 +3,6 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const color = require('color');
|
||||
const is = require('./is');
|
||||
const sharp = require('./sharp');
|
||||
|
||||
@@ -28,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;
|
||||
}
|
||||
|
||||
@@ -249,7 +248,15 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
||||
}
|
||||
// PDF background colour
|
||||
if (is.defined(inputOptions.pdfBackground)) {
|
||||
this._setBackgroundColourOption('pdfBackground', 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)) {
|
||||
@@ -288,13 +295,7 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
||||
if (!is.inRange(inputOptions.create.channels, 3, 4)) {
|
||||
throw is.invalidParameterError('create.channels', 'number between 3 and 4', inputOptions.create.channels);
|
||||
}
|
||||
const background = color(inputOptions.create.background);
|
||||
inputDescriptor.createBackground = [
|
||||
background.red(),
|
||||
background.green(),
|
||||
background.blue(),
|
||||
Math.round(background.alpha() * 255)
|
||||
];
|
||||
inputDescriptor.createBackground = this._getBackgroundColourOption(inputOptions.create.background);
|
||||
} else {
|
||||
throw new Error('Expected valid noise or background to create a new input image');
|
||||
}
|
||||
@@ -410,13 +411,7 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
||||
}
|
||||
}
|
||||
if (is.defined(inputOptions.join.background)) {
|
||||
const background = color(inputOptions.join.background);
|
||||
inputDescriptor.joinBackground = [
|
||||
background.red(),
|
||||
background.green(),
|
||||
background.blue(),
|
||||
Math.round(background.alpha() * 255)
|
||||
];
|
||||
inputDescriptor.joinBackground = this._getBackgroundColourOption(inputOptions.join.background);
|
||||
}
|
||||
if (is.defined(inputOptions.join.halign)) {
|
||||
if (is.string(inputOptions.join.halign) && is.string(this.constructor.align[inputOptions.join.halign])) {
|
||||
|
||||
@@ -18,9 +18,9 @@ const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).versio
|
||||
|
||||
const prebuiltPlatforms = [
|
||||
'darwin-arm64', 'darwin-x64',
|
||||
'linux-arm', 'linux-arm64', 'linux-s390x', 'linux-x64',
|
||||
'linux-arm', 'linux-arm64', 'linux-ppc64', 'linux-s390x', 'linux-x64',
|
||||
'linuxmusl-arm64', 'linuxmusl-x64',
|
||||
'win32-ia32', 'win32-x64'
|
||||
'win32-arm64', 'win32-ia32', 'win32-x64'
|
||||
];
|
||||
|
||||
const spawnSyncOptions = {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const color = require('color');
|
||||
const is = require('./is');
|
||||
|
||||
/**
|
||||
@@ -67,13 +66,7 @@ function rotate (angle, options) {
|
||||
} else if (is.number(angle)) {
|
||||
this.options.rotationAngle = angle;
|
||||
if (is.object(options) && options.background) {
|
||||
const backgroundColour = color(options.background);
|
||||
this.options.rotationBackground = [
|
||||
backgroundColour.red(),
|
||||
backgroundColour.green(),
|
||||
backgroundColour.blue(),
|
||||
Math.round(backgroundColour.alpha() * 255)
|
||||
];
|
||||
this._setBackgroundColourOption('rotationBackground', options.background);
|
||||
}
|
||||
} else {
|
||||
throw is.invalidParameterError('angle', 'numeric', angle);
|
||||
|
||||
@@ -1019,6 +1019,9 @@ function tiff (options) {
|
||||
* AVIF image sequences are not supported.
|
||||
* Prebuilt binaries support a bitdepth of 8 only.
|
||||
*
|
||||
* This feature is experimental on the Windows ARM64 platform
|
||||
* and requires a CPU with ARM64v8.4 or later.
|
||||
*
|
||||
* @example
|
||||
* const data = await sharp(input)
|
||||
* .avif({ effort: 2 })
|
||||
|
||||
@@ -129,7 +129,7 @@ function isResizeExpected (options) {
|
||||
*
|
||||
* Some of these values are based on the [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) CSS property.
|
||||
*
|
||||
* <img alt="Examples of various values for the fit property when resizing" width="100%" style="aspect-ratio: 998/243" src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/api-resize-fit.svg">
|
||||
* <img alt="Examples of various values for the fit property when resizing" width="100%" style="aspect-ratio: 998/243" src="/api-resize-fit.svg">
|
||||
*
|
||||
* When using a **fit** of `cover` or `contain`, the default **position** is `centre`. Other options are:
|
||||
* - `sharp.position`: `top`, `right top`, `right`, `right bottom`, `bottom`, `left bottom`, `left`, `left top`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-darwin-arm64",
|
||||
"version": "0.34.0",
|
||||
"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"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-darwin-x64",
|
||||
"version": "0.34.0",
|
||||
"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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linux-arm",
|
||||
"version": "0.34.0",
|
||||
"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"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linux-arm64",
|
||||
"version": "0.34.0",
|
||||
"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"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linux-ppc64",
|
||||
"version": "0.34.0",
|
||||
"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"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linux-s390x",
|
||||
"version": "0.34.0",
|
||||
"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"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linux-x64",
|
||||
"version": "0.34.0",
|
||||
"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"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linuxmusl-arm64",
|
||||
"version": "0.34.0",
|
||||
"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"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-linuxmusl-x64",
|
||||
"version": "0.34.0",
|
||||
"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"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp",
|
||||
"version": "0.34.0",
|
||||
"version": "0.34.3-rc.0",
|
||||
"private": "true",
|
||||
"workspaces": [
|
||||
"darwin-arm64",
|
||||
@@ -13,6 +13,7 @@
|
||||
"linuxmusl-arm64",
|
||||
"linuxmusl-x64",
|
||||
"wasm32",
|
||||
"win32-arm64",
|
||||
"win32-ia32",
|
||||
"win32-x64"
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-wasm32",
|
||||
"version": "0.34.0",
|
||||
"version": "0.34.3-rc.0",
|
||||
"description": "Prebuilt sharp for use with wasm32",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
@@ -31,7 +31,7 @@
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emnapi/runtime": "^1.4.0"
|
||||
"@emnapi/runtime": "^1.4.3"
|
||||
},
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
|
||||
39
npm/win32-arm64/package.json
Normal file
39
npm/win32-arm64/package.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "@img/sharp-win32-arm64",
|
||||
"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",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lovell/sharp.git",
|
||||
"directory": "npm/win32-arm64"
|
||||
},
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"files": [
|
||||
"lib",
|
||||
"versions.json"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"type": "commonjs",
|
||||
"exports": {
|
||||
"./sharp.node": "./lib/sharp-win32-arm64.node",
|
||||
"./package": "./package.json",
|
||||
"./versions": "./versions.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"cpu": [
|
||||
"arm64"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-win32-ia32",
|
||||
"version": "0.34.0",
|
||||
"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",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@img/sharp-win32-x64",
|
||||
"version": "0.34.0",
|
||||
"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",
|
||||
|
||||
81
package.json
81
package.json
@@ -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.0",
|
||||
"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"
|
||||
@@ -138,68 +137,66 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"color": "^4.2.3",
|
||||
"detect-libc": "^2.0.3",
|
||||
"semver": "^7.7.1"
|
||||
"detect-libc": "^2.0.4",
|
||||
"semver": "^7.7.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-darwin-arm64": "0.34.0",
|
||||
"@img/sharp-darwin-x64": "0.34.0",
|
||||
"@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.0",
|
||||
"@img/sharp-linux-arm64": "0.34.0",
|
||||
"@img/sharp-linux-s390x": "0.34.0",
|
||||
"@img/sharp-linux-x64": "0.34.0",
|
||||
"@img/sharp-linuxmusl-arm64": "0.34.0",
|
||||
"@img/sharp-linuxmusl-x64": "0.34.0",
|
||||
"@img/sharp-wasm32": "0.34.0",
|
||||
"@img/sharp-win32-ia32": "0.34.0",
|
||||
"@img/sharp-win32-x64": "0.34.0"
|
||||
"@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.0",
|
||||
"@img/sharp-libvips-dev": "1.1.0",
|
||||
"@img/sharp-libvips-dev-wasm32": "1.1.0",
|
||||
"@img/sharp-libvips-win32-ia32": "1.1.0",
|
||||
"@img/sharp-libvips-win32-x64": "1.1.0",
|
||||
"@emnapi/runtime": "^1.4.3",
|
||||
"@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.0",
|
||||
"emnapi": "^1.4.3",
|
||||
"exif-reader": "^2.0.2",
|
||||
"extract-zip": "^2.0.1",
|
||||
"icc": "^3.0.0",
|
||||
"jsdoc-to-markdown": "^9.1.1",
|
||||
"license-checker": "^25.0.1",
|
||||
"mocha": "^11.1.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",
|
||||
"tsd": "^0.31.2"
|
||||
"tar-fs": "^3.0.9",
|
||||
"tsd": "^0.32.0"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"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"
|
||||
|
||||
@@ -19,7 +19,10 @@
|
||||
'type': 'shared_library',
|
||||
'defines': [
|
||||
'_VIPS_PUBLIC=__declspec(dllexport)',
|
||||
'_ALLOW_KEYWORD_MACROS'
|
||||
'_ALLOW_KEYWORD_MACROS',
|
||||
'G_DISABLE_ASSERT',
|
||||
'G_DISABLE_CAST_CHECKS',
|
||||
'G_DISABLE_CHECKS'
|
||||
],
|
||||
'sources': [
|
||||
'<(sharp_libvips_cplusplus_dir)/VConnection.cpp',
|
||||
@@ -160,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\'',
|
||||
@@ -173,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)'
|
||||
|
||||
@@ -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);
|
||||
@@ -651,22 +661,21 @@ namespace sharp {
|
||||
*/
|
||||
VImage SetAnimationProperties(VImage image, int nPages, int pageHeight, std::vector<int> delay, int loop) {
|
||||
bool hasDelay = !delay.empty();
|
||||
|
||||
// Avoid a copy if none of the animation properties are needed.
|
||||
if (nPages == 1 && !hasDelay && loop == -1) return image;
|
||||
|
||||
if (delay.size() == 1) {
|
||||
// We have just one delay, repeat that value for all frames.
|
||||
delay.insert(delay.end(), nPages - 1, delay[0]);
|
||||
}
|
||||
|
||||
// Attaching metadata, need to copy the image.
|
||||
VImage copy = image.copy();
|
||||
|
||||
// Only set page-height if we have more than one page, or this could
|
||||
// accidentally turn into an animated image later.
|
||||
if (nPages > 1) copy.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||
if (hasDelay) copy.set("delay", delay);
|
||||
if (hasDelay) {
|
||||
if (delay.size() == 1) {
|
||||
// We have just one delay, repeat that value for all frames.
|
||||
delay.insert(delay.end(), nPages - 1, delay[0]);
|
||||
}
|
||||
copy.set("delay", delay);
|
||||
}
|
||||
if (nPages == 1 && !hasDelay && loop == -1) {
|
||||
loop = 1;
|
||||
}
|
||||
if (loop != -1) copy.set("loop", loop);
|
||||
|
||||
return copy;
|
||||
@@ -952,14 +961,6 @@ namespace sharp {
|
||||
return interpretation == VIPS_INTERPRETATION_RGB16 || interpretation == VIPS_INTERPRETATION_GREY16;
|
||||
}
|
||||
|
||||
/*
|
||||
Return the image alpha maximum. Useful for combining alpha bands. scRGB
|
||||
images are 0 - 1 for image data, but the alpha is 0 - 255.
|
||||
*/
|
||||
double MaximumImageAlpha(VipsInterpretation const interpretation) {
|
||||
return Is16Bit(interpretation) ? 65535.0 : 255.0;
|
||||
}
|
||||
|
||||
/*
|
||||
Convert RGBA value to another colourspace
|
||||
*/
|
||||
@@ -1002,16 +1003,16 @@ namespace sharp {
|
||||
0.0722 * colour[2])
|
||||
};
|
||||
}
|
||||
// Add alpha channel to alphaColour colour
|
||||
// Add alpha channel(s) to alphaColour colour
|
||||
if (colour[3] < 255.0 || image.has_alpha()) {
|
||||
alphaColour.push_back(colour[3] * multiplier);
|
||||
int extraBands = image.bands() > 4 ? image.bands() - 3 : 1;
|
||||
alphaColour.insert(alphaColour.end(), extraBands, colour[3] * multiplier);
|
||||
}
|
||||
// Ensure alphaColour colour uses correct colourspace
|
||||
alphaColour = sharp::GetRgbaAsColourspace(alphaColour, image.interpretation(), premultiply);
|
||||
// Add non-transparent alpha channel, if required
|
||||
if (colour[3] < 255.0 && !image.has_alpha()) {
|
||||
image = image.bandjoin(
|
||||
VImage::new_matrix(image.width(), image.height()).new_from_image(255 * multiplier).cast(image.format()));
|
||||
image = image.bandjoin_const({ 255 * multiplier });
|
||||
}
|
||||
return std::make_tuple(image, alphaColour);
|
||||
}
|
||||
@@ -1031,9 +1032,7 @@ namespace sharp {
|
||||
*/
|
||||
VImage EnsureAlpha(VImage image, double const value) {
|
||||
if (!image.has_alpha()) {
|
||||
std::vector<double> alpha;
|
||||
alpha.push_back(value * sharp::MaximumImageAlpha(image.interpretation()));
|
||||
image = image.bandjoin_const(alpha);
|
||||
image = image.bandjoin_const({ value * vips_interpretation_max_alpha(image.interpretation()) });
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
16
src/common.h
16
src/common.h
@@ -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
|
||||
@@ -357,12 +359,6 @@ namespace sharp {
|
||||
*/
|
||||
bool Is16Bit(VipsInterpretation const interpretation);
|
||||
|
||||
/*
|
||||
Return the image alpha maximum. Useful for combining alpha bands. scRGB
|
||||
images are 0 - 1 for image data, but the alpha is 0 - 255.
|
||||
*/
|
||||
double MaximumImageAlpha(VipsInterpretation const interpretation);
|
||||
|
||||
/*
|
||||
Convert RGBA value to another colourspace
|
||||
*/
|
||||
|
||||
@@ -294,6 +294,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
option->set("n", baton->input->pages);
|
||||
option->set("page", baton->input->page);
|
||||
option->set("dpi", baton->input->density);
|
||||
option->set("background", baton->input->pdfBackground);
|
||||
|
||||
if (baton->input->buffer != nullptr) {
|
||||
// Reload PDF buffer
|
||||
@@ -668,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
|
||||
@@ -733,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
|
||||
@@ -759,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);
|
||||
}
|
||||
|
||||
@@ -1359,7 +1363,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
// Add file size to info
|
||||
if (baton->formatOut != "dz" || sharp::IsDzZip(baton->fileOut)) {
|
||||
try {
|
||||
uint32_t const size = static_cast<uint32_t>(std::filesystem::file_size(baton->fileOut));
|
||||
uint32_t const size = static_cast<uint32_t>(
|
||||
std::filesystem::file_size(std::filesystem::u8path(baton->fileOut)));
|
||||
info.Set("size", size);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ struct PipelineBaton {
|
||||
ensureAlpha(-1.0),
|
||||
colourspacePipeline(VIPS_INTERPRETATION_LAST),
|
||||
colourspace(VIPS_INTERPRETATION_LAST),
|
||||
loop(1),
|
||||
loop(-1),
|
||||
tileSize(256),
|
||||
tileOverlap(0),
|
||||
tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS),
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -60,7 +60,7 @@ class StatsWorker : public Napi::AsyncWorker {
|
||||
// Image is not opaque when alpha layer is present and contains a non-mamixa value
|
||||
if (image.has_alpha()) {
|
||||
double const minAlpha = static_cast<double>(stats.getpoint(STAT_MIN_INDEX, bands).front());
|
||||
if (minAlpha != sharp::MaximumImageAlpha(image.interpretation())) {
|
||||
if (minAlpha != vips_interpretation_max_alpha(image.interpretation())) {
|
||||
baton->isOpaque = false;
|
||||
}
|
||||
}
|
||||
|
||||
BIN
test/fixtures/expected/composite-red-scrgb.png
vendored
Normal file
BIN
test/fixtures/expected/composite-red-scrgb.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
test/fixtures/expected/extract.tiff
vendored
BIN
test/fixtures/expected/extract.tiff
vendored
Binary file not shown.
1
test/fixtures/index.js
vendored
1
test/fixtures/index.js
vendored
@@ -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
BIN
test/fixtures/relax_tileparts.jp2
vendored
Normal file
Binary file not shown.
@@ -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();
|
||||
|
||||
@@ -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}`);
|
||||
|
||||
@@ -238,4 +238,15 @@ describe('GIF input', () => {
|
||||
assert.strictEqual(1, loop);
|
||||
}
|
||||
});
|
||||
|
||||
it('Animated GIF to animated WebP merges identical frames', async () => {
|
||||
const webp = await sharp(fixtures.inputGifAnimated, { animated: true })
|
||||
.webp()
|
||||
.toBuffer();
|
||||
|
||||
const { delay, loop, pages } = await sharp(webp).metadata();
|
||||
assert.deepStrictEqual([120, 120, 90, 120, 120, 90, 120, 90, 30], delay);
|
||||
assert.strictEqual(0, loop);
|
||||
assert.strictEqual(9, pages);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1036,4 +1036,21 @@ describe('Input/output', function () {
|
||||
});
|
||||
readable.pipe(inPipeline).pipe(badPipeline);
|
||||
});
|
||||
|
||||
it('supports wide-character filenames', async () => {
|
||||
const filename = fixtures.path('output.图片.jpg');
|
||||
const create = {
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 3,
|
||||
background: 'green'
|
||||
};
|
||||
await sharp({ create }).toFile(filename);
|
||||
|
||||
const { width, height, channels, format } = await sharp(filename).metadata();
|
||||
assert.strictEqual(width, 8);
|
||||
assert.strictEqual(height, 8);
|
||||
assert.strictEqual(channels, 3);
|
||||
assert.strictEqual(format, 'jpeg');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -806,4 +806,33 @@ describe('Resize fit=contain', function () {
|
||||
fixtures.assertSimilar(fixtures.expected('./embedgravitybird/9-c.png'), data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('multiple alpha channels', async () => {
|
||||
const create = {
|
||||
width: 20,
|
||||
height: 12,
|
||||
channels: 4,
|
||||
background: 'green'
|
||||
};
|
||||
const multipleAlphaChannels = await sharp({ create })
|
||||
.joinChannel({ create })
|
||||
.tiff({ compression: 'deflate' })
|
||||
.toBuffer();
|
||||
|
||||
const data = await sharp(multipleAlphaChannels)
|
||||
.resize({
|
||||
width: 8,
|
||||
height: 8,
|
||||
fit: 'contain',
|
||||
background: 'blue'
|
||||
})
|
||||
.tiff({ compression: 'deflate' })
|
||||
.toBuffer();
|
||||
const { format, width, height, space, channels } = await sharp(data).metadata();
|
||||
assert.deepStrictEqual(format, 'tiff');
|
||||
assert.deepStrictEqual(width, 8);
|
||||
assert.deepStrictEqual(height, 8);
|
||||
assert.deepStrictEqual(space, 'srgb');
|
||||
assert.deepStrictEqual(channels, 8);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -59,7 +59,7 @@ describe('Text to image', function () {
|
||||
assert.strictEqual('png', info.format);
|
||||
assert.strictEqual(3, info.channels);
|
||||
assert.ok(inRange(info.width, 400, 600), `Actual width ${info.width}`);
|
||||
assert.ok(inRange(info.height, 300, 500), `Actual height ${info.height}`);
|
||||
assert.ok(inRange(info.height, 290, 500), `Actual height ${info.height}`);
|
||||
assert.ok(inRange(info.textAutofitDpi, 900, 1300), `Actual textAutofitDpi ${info.textAutofitDpi}`);
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -10,18 +10,20 @@ const sharp = require('../../');
|
||||
describe('Utilities', function () {
|
||||
describe('Cache', function () {
|
||||
it('Can be disabled', function (done) {
|
||||
queueMicrotask(() => {
|
||||
sharp.cache(false);
|
||||
const check = setInterval(() => {
|
||||
const cache = sharp.cache(false);
|
||||
assert.strictEqual(cache.memory.current, 0);
|
||||
assert.strictEqual(cache.memory.max, 0);
|
||||
assert.strictEqual(typeof cache.memory.high, 'number');
|
||||
assert.strictEqual(cache.files.current, 0);
|
||||
assert.strictEqual(cache.files.max, 0);
|
||||
assert.strictEqual(cache.items.current, 0);
|
||||
assert.strictEqual(cache.items.max, 0);
|
||||
done();
|
||||
});
|
||||
const empty =
|
||||
cache.memory.current +
|
||||
cache.memory.max +
|
||||
cache.files.current +
|
||||
cache.files.max +
|
||||
cache.items.current +
|
||||
cache.items.max === 0;
|
||||
if (empty) {
|
||||
clearInterval(check);
|
||||
done();
|
||||
}
|
||||
}, 2000);
|
||||
});
|
||||
it('Can be enabled with defaults', function () {
|
||||
const cache = sharp.cache(true);
|
||||
|
||||
Reference in New Issue
Block a user