Compare commits

...

15 Commits

Author SHA1 Message Date
Lovell Fuller
a9aa7339ce Prerelease 0.33.0-alpha.3 2023-10-06 09:48:44 +01:00
Lovell Fuller
08108f5fad Use std::once for vips_init call 2023-10-06 09:44:57 +01:00
Lovell Fuller
58e3c4c70e Ensure all package files make use of commonjs explicit 2023-10-05 20:00:32 +01:00
Lovell Fuller
f8cf25ca56 Ensure correct interp of 16-bit raw input #3808 2023-10-05 14:05:36 +01:00
Lovell Fuller
ca95979ecc Prefix node builtins, skips cache lookup 2023-10-05 12:09:19 +01:00
Lovell Fuller
392f6afb5e Commit fcc7e84 but do it properly this time 2023-10-04 21:30:05 +01:00
Lovell Fuller
7c97aabaf8 Ensure win32 packages contain version/notice files 2023-10-04 21:12:16 +01:00
Lovell Fuller
fcc7e84bee Revert target names as these are used for DLLs 2023-10-04 20:46:25 +01:00
Lovell Fuller
226a9a13ef Packaging: prerelease version bump 2023-10-04 15:48:23 +01:00
Lovell Fuller
4d3c9ae3d1 Packaging: clear existing lib directories 2023-10-04 15:47:57 +01:00
Lovell Fuller
f31011d759 CI: increase linux-arm timeout 2023-10-04 15:47:35 +01:00
Lovell Fuller
7cf4ae5648 Prerelease 0.33.0-alpha.2 2023-10-04 10:16:35 +01:00
Lovell Fuller
9161c605e1 Clarify extract-resize-extract operation ordering 2023-10-03 19:28:18 +01:00
Lovell Fuller
70ac6905c7 Use std::atomic for counters 2023-09-30 14:01:04 +01:00
Lovell Fuller
265d70111a Add licensing info to npm readme files 2023-09-28 15:42:13 +01:00
29 changed files with 157 additions and 71 deletions

View File

@@ -141,7 +141,7 @@ jobs:
npm pkg set "optionalDependencies.@sharpen/sharp-linux-arm=file:./npm/linux-arm" npm pkg set "optionalDependencies.@sharpen/sharp-linux-arm=file:./npm/linux-arm"
npm run clean npm run clean
npm install --ignore-scripts npm install --ignore-scripts
npx mocha --no-config --spec=test/unit/io.js npx mocha --no-config --spec=test/unit/io.js --timeout=30000
[[ -n $prebuild_upload ]] && npx prebuild || true [[ -n $prebuild_upload ]] && npx prebuild || true
macstadium-runner: macstadium-runner:
permissions: permissions:

View File

@@ -10,7 +10,7 @@
'sharp_libvips_lib_dir': '<!(node -p "require(\'./lib/libvips\').buildSharpLibvipsLibDir()")' 'sharp_libvips_lib_dir': '<!(node -p "require(\'./lib/libvips\').buildSharpLibvipsLibDir()")'
}, },
'targets': [{ 'targets': [{
'target_name': 'win-libvips-cpp', 'target_name': 'libvips-cpp',
'conditions': [ 'conditions': [
['OS == "win"', { ['OS == "win"', {
# Build libvips C++ binding for Windows due to MSVC std library ABI changes # Build libvips C++ binding for Windows due to MSVC std library ABI changes
@@ -81,7 +81,7 @@
], ],
'dependencies': [ 'dependencies': [
'<!(node -p "require(\'node-addon-api\').gyp")', '<!(node -p "require(\'node-addon-api\').gyp")',
'win-libvips-cpp' 'libvips-cpp'
], ],
'variables': { 'variables': {
'conditions': [ 'conditions': [
@@ -243,7 +243,7 @@
} }
}, },
}, { }, {
'target_name': 'win-copy-dlls', 'target_name': 'copy-dll',
'type': 'none', 'type': 'none',
'dependencies': [ 'dependencies': [
'sharp-<(platform_and_arch)' 'sharp-<(platform_and_arch)'

View File

@@ -214,7 +214,7 @@ Extract/crop a region of the image.
- Use `extract` before `resize` for pre-resize extraction. - Use `extract` before `resize` for pre-resize extraction.
- Use `extract` after `resize` for post-resize extraction. - Use `extract` after `resize` for post-resize extraction.
- Use `extract` before and after for both. - Use `extract` twice and `resize` once for extract-then-resize-then-extract in a fixed operation order.
**Throws**: **Throws**:

View File

@@ -13,6 +13,9 @@ Requires libvips v8.14.5
* Make `compression` option of `heif` mandatory to help reduce HEIF vs HEIC confusion. * Make `compression` option of `heif` mandatory to help reduce HEIF vs HEIC confusion.
[#3740](https://github.com/lovell/sharp/issues/3740) [#3740](https://github.com/lovell/sharp/issues/3740)
* Ensure correct interpretation of 16-bit raw input.
[#3808](https://github.com/lovell/sharp/issues/3808)
## v0.32 - *flow* ## v0.32 - *flow*
Requires libvips v8.14.5 Requires libvips v8.14.5

View File

@@ -3,8 +3,8 @@
'use strict'; 'use strict';
const util = require('util'); const util = require('node:util');
const stream = require('stream'); const stream = require('node:stream');
const is = require('./is'); const is = require('./is');
require('./sharp'); require('./sharp');

View File

@@ -3,7 +3,7 @@
'use strict'; 'use strict';
const spawnSync = require('child_process').spawnSync; const { spawnSync } = require('node:child_process');
const semverCoerce = require('semver/functions/coerce'); const semverCoerce = require('semver/functions/coerce');
const semverGreaterThanOrEqualTo = require('semver/functions/gte'); const semverGreaterThanOrEqualTo = require('semver/functions/gte');
const detectLibc = require('detect-libc'); const detectLibc = require('detect-libc');

View File

@@ -3,7 +3,7 @@
'use strict'; 'use strict';
const path = require('path'); const path = require('node:path');
const is = require('./is'); const is = require('./is');
const sharp = require('./sharp'); const sharp = require('./sharp');

View File

@@ -250,6 +250,9 @@ function resize (widthOrOptions, height, options) {
if (isResizeExpected(this.options)) { if (isResizeExpected(this.options)) {
this.options.debuglog('ignoring previous resize options'); this.options.debuglog('ignoring previous resize options');
} }
if (this.options.widthPost !== -1) {
this.options.debuglog('operation order will be: extract, resize, extract');
}
if (is.defined(widthOrOptions)) { if (is.defined(widthOrOptions)) {
if (is.object(widthOrOptions) && !is.defined(options)) { if (is.object(widthOrOptions) && !is.defined(options)) {
options = widthOrOptions; options = widthOrOptions;
@@ -437,7 +440,7 @@ function extend (extend) {
* *
* - Use `extract` before `resize` for pre-resize extraction. * - Use `extract` before `resize` for pre-resize extraction.
* - Use `extract` after `resize` for post-resize extraction. * - Use `extract` after `resize` for post-resize extraction.
* - Use `extract` before and after for both. * - Use `extract` twice and `resize` once for extract-then-resize-then-extract in a fixed operation order.
* *
* @example * @example
* sharp(input) * sharp(input)

View File

@@ -3,7 +3,7 @@
'use strict'; 'use strict';
const events = require('events'); const events = require('node:events');
const detectLibc = require('detect-libc'); const detectLibc = require('detect-libc');
const is = require('./is'); const is = require('./is');

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sharpen/sharp-darwin-arm64", "name": "@sharpen/sharp-darwin-arm64",
"version": "0.0.1-alpha.1", "version": "0.0.1-alpha.3",
"description": "Prebuilt sharp for use with macOS ARM64", "description": "Prebuilt sharp for use with macOS ARM64",
"homepage": "https://sharp.pixelplumbing.com", "homepage": "https://sharp.pixelplumbing.com",
"repository": { "repository": {
@@ -22,6 +22,7 @@
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"type": "commonjs",
"exports": { "exports": {
"./sharp.node": "./lib/sharp-darwin-arm64.node", "./sharp.node": "./lib/sharp-darwin-arm64.node",
"./package": "./package.json" "./package": "./package.json"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sharpen/sharp-darwin-x64", "name": "@sharpen/sharp-darwin-x64",
"version": "0.0.1-alpha.1", "version": "0.0.1-alpha.3",
"description": "Prebuilt sharp for use with macOS x64", "description": "Prebuilt sharp for use with macOS x64",
"homepage": "https://sharp.pixelplumbing.com", "homepage": "https://sharp.pixelplumbing.com",
"repository": { "repository": {
@@ -19,6 +19,10 @@
"files": [ "files": [
"lib" "lib"
], ],
"publishConfig": {
"access": "public"
},
"type": "commonjs",
"exports": { "exports": {
"./sharp.node": "./lib/sharp-darwin-x64.node", "./sharp.node": "./lib/sharp-darwin-x64.node",
"./package": "./package.json" "./package": "./package.json"

View File

@@ -5,7 +5,7 @@
// Populate contents of all packages with the current GitHub release // Populate contents of all packages with the current GitHub release
const { writeFile, copyFile } = require('node:fs/promises'); const { writeFile, copyFile, rm } = require('node:fs/promises');
const path = require('node:path'); const path = require('node:path');
const { Readable } = require('node:stream'); const { Readable } = require('node:stream');
const { pipeline } = require('node:stream/promises'); const { pipeline } = require('node:stream/promises');
@@ -20,8 +20,25 @@ const mapTarballEntry = (header) => {
return header; 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 => { workspaces.map(async platform => {
const url = `https://github.com/lovell/sharp/releases/download/v${version}/sharp-v${version}-napi-v7-${platform}.tar.gz`; const url = `https://github.com/lovell/sharp/releases/download/v${version}/sharp-v${version}-napi-v9-${platform}.tar.gz`;
const dir = path.join(__dirname, platform); const dir = path.join(__dirname, platform);
const response = await fetch(url); const response = await fetch(url);
if (!response.ok) { if (!response.ok) {
@@ -29,14 +46,16 @@ workspaces.map(async platform => {
return; return;
} }
// Extract prebuild tarball // Extract prebuild tarball
const lib = path.join(dir, 'lib');
await rm(lib, { recursive: true });
await pipeline( await pipeline(
Readable.fromWeb(response.body), Readable.fromWeb(response.body),
createGunzip(), createGunzip(),
extract(path.join(dir, 'lib'), { map: mapTarballEntry }) extract(lib, { map: mapTarballEntry })
); );
// Generate README // Generate README
const { name, description } = require(`./${platform}/package.json`); const { name, description } = require(`./${platform}/package.json`);
await writeFile(path.join(dir, 'README.md'), `# ${name}\n${description}`); await writeFile(path.join(dir, 'README.md'), `# \`${name}\`\n\n${description}.\n${licensing}`);
// Copy Apache-2.0 LICENSE // Copy Apache-2.0 LICENSE
await copyFile(path.join(__dirname, '..', 'LICENSE'), path.join(dir, 'LICENSE')); await copyFile(path.join(__dirname, '..', 'LICENSE'), path.join(dir, 'LICENSE'));
// Copy Windows-specific files // Copy Windows-specific files

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sharpen/sharp-linux-arm", "name": "@sharpen/sharp-linux-arm",
"version": "0.0.1-alpha.1", "version": "0.0.1-alpha.3",
"description": "Prebuilt sharp for use with Linux (glibc) ARM (32-bit)", "description": "Prebuilt sharp for use with Linux (glibc) ARM (32-bit)",
"homepage": "https://sharp.pixelplumbing.com", "homepage": "https://sharp.pixelplumbing.com",
"repository": { "repository": {
@@ -22,6 +22,7 @@
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"type": "commonjs",
"exports": { "exports": {
"./sharp.node": "./lib/sharp-linux-arm.node", "./sharp.node": "./lib/sharp-linux-arm.node",
"./package": "./package.json" "./package": "./package.json"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sharpen/sharp-linux-arm64", "name": "@sharpen/sharp-linux-arm64",
"version": "0.0.1-alpha.1", "version": "0.0.1-alpha.3",
"description": "Prebuilt sharp for use with Linux (glibc) ARM64", "description": "Prebuilt sharp for use with Linux (glibc) ARM64",
"homepage": "https://sharp.pixelplumbing.com", "homepage": "https://sharp.pixelplumbing.com",
"repository": { "repository": {
@@ -22,6 +22,7 @@
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"type": "commonjs",
"exports": { "exports": {
"./sharp.node": "./lib/sharp-linux-arm64.node", "./sharp.node": "./lib/sharp-linux-arm64.node",
"./package": "./package.json" "./package": "./package.json"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sharpen/sharp-linux-x64", "name": "@sharpen/sharp-linux-x64",
"version": "0.0.1-alpha.1", "version": "0.0.1-alpha.3",
"description": "Prebuilt sharp for use with Linux (glibc) x64", "description": "Prebuilt sharp for use with Linux (glibc) x64",
"homepage": "https://sharp.pixelplumbing.com", "homepage": "https://sharp.pixelplumbing.com",
"repository": { "repository": {
@@ -22,6 +22,7 @@
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"type": "commonjs",
"exports": { "exports": {
"./sharp.node": "./lib/sharp-linux-x64.node", "./sharp.node": "./lib/sharp-linux-x64.node",
"./package": "./package.json" "./package": "./package.json"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sharpen/sharp-linuxmusl-arm64", "name": "@sharpen/sharp-linuxmusl-arm64",
"version": "0.0.1-alpha.1", "version": "0.0.1-alpha.3",
"description": "Prebuilt sharp for use with Linux (musl) ARM64", "description": "Prebuilt sharp for use with Linux (musl) ARM64",
"homepage": "https://sharp.pixelplumbing.com", "homepage": "https://sharp.pixelplumbing.com",
"repository": { "repository": {
@@ -22,6 +22,7 @@
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"type": "commonjs",
"exports": { "exports": {
"./sharp.node": "./lib/sharp-linuxmusl-arm64.node", "./sharp.node": "./lib/sharp-linuxmusl-arm64.node",
"./package": "./package.json" "./package": "./package.json"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sharpen/sharp-linuxmusl-x64", "name": "@sharpen/sharp-linuxmusl-x64",
"version": "0.0.1-alpha.1", "version": "0.0.1-alpha.3",
"description": "Prebuilt sharp for use with Linux (musl) x64", "description": "Prebuilt sharp for use with Linux (musl) x64",
"homepage": "https://sharp.pixelplumbing.com", "homepage": "https://sharp.pixelplumbing.com",
"repository": { "repository": {
@@ -22,6 +22,7 @@
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"type": "commonjs",
"exports": { "exports": {
"./sharp.node": "./lib/sharp-linuxmusl-x64.node", "./sharp.node": "./lib/sharp-linuxmusl-x64.node",
"./package": "./package.json" "./package": "./package.json"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sharpen/sharp-win32-ia32", "name": "@sharpen/sharp-win32-ia32",
"version": "0.0.1-alpha.1", "version": "0.0.1-alpha.3",
"description": "Prebuilt sharp for use with Windows x86 (32-bit)", "description": "Prebuilt sharp for use with Windows x86 (32-bit)",
"homepage": "https://sharp.pixelplumbing.com", "homepage": "https://sharp.pixelplumbing.com",
"repository": { "repository": {
@@ -13,18 +13,19 @@
"url": "https://opencollective.com/libvips" "url": "https://opencollective.com/libvips"
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": {
"@sharpen/sharp-libvips-win32-ia32": "0.0.1-alpha.1"
},
"files": [ "files": [
"lib" "lib",
"versions.json",
"THIRD-PARTY-NOTICES.md"
], ],
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"type": "commonjs",
"exports": { "exports": {
"./sharp.node": "./lib/sharp-win32-ia32.node", "./sharp.node": "./lib/sharp-win32-ia32.node",
"./package": "./package.json" "./package": "./package.json",
"./versions": "./versions.json"
}, },
"engines": { "engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0", "node": "^18.17.0 || ^20.3.0 || >=21.0.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sharpen/sharp-win32-x64", "name": "@sharpen/sharp-win32-x64",
"version": "0.0.1-alpha.1", "version": "0.0.1-alpha.3",
"description": "Prebuilt sharp for use with Windows x64", "description": "Prebuilt sharp for use with Windows x64",
"homepage": "https://sharp.pixelplumbing.com", "homepage": "https://sharp.pixelplumbing.com",
"repository": { "repository": {
@@ -13,15 +13,15 @@
"url": "https://opencollective.com/libvips" "url": "https://opencollective.com/libvips"
}, },
"preferUnplugged": true, "preferUnplugged": true,
"optionalDependencies": {
"@sharpen/sharp-libvips-win32-x64": "0.0.1-alpha.1"
},
"files": [ "files": [
"lib" "lib",
"versions.json",
"THIRD-PARTY-NOTICES.md"
], ],
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"type": "commonjs",
"exports": { "exports": {
"./sharp.node": "./lib/sharp-win32-x64.node", "./sharp.node": "./lib/sharp-win32-x64.node",
"./package": "./package.json" "./package": "./package.json"

View File

@@ -1,7 +1,7 @@
{ {
"name": "sharp", "name": "sharp",
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images", "description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
"version": "0.33.0-alpha.1", "version": "0.33.0-alpha.3",
"author": "Lovell Fuller <npm@lovell.info>", "author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://github.com/lovell/sharp", "homepage": "https://github.com/lovell/sharp",
"contributors": [ "contributors": [
@@ -103,13 +103,14 @@
"docs-serve": "cd docs && npx serve", "docs-serve": "cd docs && npx serve",
"docs-publish": "cd docs && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp" "docs-publish": "cd docs && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
}, },
"type": "commonjs",
"main": "lib/index.js", "main": "lib/index.js",
"types": "lib/index.d.ts", "types": "lib/index.d.ts",
"files": [ "files": [
"binding.gyp", "binding.gyp",
"install/**", "install",
"lib/**", "lib",
"src/**" "src"
], ],
"repository": { "repository": {
"type": "git", "type": "git",
@@ -140,15 +141,15 @@
"semver": "^7.5.4" "semver": "^7.5.4"
}, },
"optionalDependencies": { "optionalDependencies": {
"@sharpen/sharp-darwin-arm64": "0.0.1-alpha.1", "@sharpen/sharp-darwin-arm64": "0.0.1-alpha.3",
"@sharpen/sharp-darwin-x64": "0.0.1-alpha.1", "@sharpen/sharp-darwin-x64": "0.0.1-alpha.3",
"@sharpen/sharp-linux-arm": "0.0.1-alpha.1", "@sharpen/sharp-linux-arm": "0.0.1-alpha.3",
"@sharpen/sharp-linux-arm64": "0.0.1-alpha.1", "@sharpen/sharp-linux-arm64": "0.0.1-alpha.3",
"@sharpen/sharp-linux-x64": "0.0.1-alpha.1", "@sharpen/sharp-linux-x64": "0.0.1-alpha.3",
"@sharpen/sharp-linuxmusl-arm64": "0.0.1-alpha.1", "@sharpen/sharp-linuxmusl-arm64": "0.0.1-alpha.3",
"@sharpen/sharp-linuxmusl-x64": "0.0.1-alpha.1", "@sharpen/sharp-linuxmusl-x64": "0.0.1-alpha.3",
"@sharpen/sharp-win32-ia32": "0.0.1-alpha.1", "@sharpen/sharp-win32-ia32": "0.0.1-alpha.3",
"@sharpen/sharp-win32-x64": "0.0.1-alpha.1" "@sharpen/sharp-win32-x64": "0.0.1-alpha.3"
}, },
"devDependencies": { "devDependencies": {
"@sharpen/sharp-libvips-darwin-arm64": "0.0.1-alpha.1", "@sharpen/sharp-libvips-darwin-arm64": "0.0.1-alpha.1",

View File

@@ -166,10 +166,10 @@ namespace sharp {
} }
// How many tasks are in the queue? // How many tasks are in the queue?
volatile int counterQueue = 0; std::atomic<int> counterQueue{0};
// How many tasks are being processed? // How many tasks are being processed?
volatile int counterProcess = 0; std::atomic<int> counterProcess{0};
// Filename extension checkers // Filename extension checkers
static bool EndsWith(std::string const &str, std::string const &end) { static bool EndsWith(std::string const &str, std::string const &end) {
@@ -363,12 +363,13 @@ namespace sharp {
if (descriptor->isBuffer) { if (descriptor->isBuffer) {
if (descriptor->rawChannels > 0) { if (descriptor->rawChannels > 0) {
// Raw, uncompressed pixel data // Raw, uncompressed pixel data
bool const is8bit = vips_band_format_is8bit(descriptor->rawDepth);
image = VImage::new_from_memory(descriptor->buffer, descriptor->bufferLength, image = VImage::new_from_memory(descriptor->buffer, descriptor->bufferLength,
descriptor->rawWidth, descriptor->rawHeight, descriptor->rawChannels, descriptor->rawDepth); descriptor->rawWidth, descriptor->rawHeight, descriptor->rawChannels, descriptor->rawDepth);
if (descriptor->rawChannels < 3) { if (descriptor->rawChannels < 3) {
image.get_image()->Type = VIPS_INTERPRETATION_B_W; image.get_image()->Type = is8bit ? VIPS_INTERPRETATION_B_W : VIPS_INTERPRETATION_GREY16;
} else { } else {
image.get_image()->Type = VIPS_INTERPRETATION_sRGB; image.get_image()->Type = is8bit ? VIPS_INTERPRETATION_sRGB : VIPS_INTERPRETATION_RGB16;
} }
if (descriptor->rawPremultiplied) { if (descriptor->rawPremultiplied) {
image = image.unpremultiply(); image = image.unpremultiply();

View File

@@ -7,6 +7,7 @@
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <vector> #include <vector>
#include <atomic>
#include <napi.h> #include <napi.h>
#include <vips/vips8> #include <vips/vips8>
@@ -161,10 +162,10 @@ namespace sharp {
}; };
// How many tasks are in the queue? // How many tasks are in the queue?
extern volatile int counterQueue; extern std::atomic<int> counterQueue;
// How many tasks are being processed? // How many tasks are being processed?
extern volatile int counterProcess; extern std::atomic<int> counterProcess;
// Filename extension checkers // Filename extension checkers
bool IsJpeg(std::string const &str); bool IsJpeg(std::string const &str);

View File

@@ -18,7 +18,7 @@ class MetadataWorker : public Napi::AsyncWorker {
void Execute() { void Execute() {
// Decrement queued task counter // Decrement queued task counter
g_atomic_int_dec_and_test(&sharp::counterQueue); sharp::counterQueue--;
vips::VImage image; vips::VImage image;
sharp::ImageType imageType = sharp::ImageType::UNKNOWN; sharp::ImageType imageType = sharp::ImageType::UNKNOWN;
@@ -281,7 +281,7 @@ Napi::Value metadata(const Napi::CallbackInfo& info) {
worker->Queue(); worker->Queue();
// Increment queued task counter // Increment queued task counter
g_atomic_int_inc(&sharp::counterQueue); sharp::counterQueue++;
return info.Env().Undefined(); return info.Env().Undefined();
} }

View File

@@ -44,9 +44,9 @@ class PipelineWorker : public Napi::AsyncWorker {
// libuv worker // libuv worker
void Execute() { void Execute() {
// Decrement queued task counter // Decrement queued task counter
g_atomic_int_dec_and_test(&sharp::counterQueue); sharp::counterQueue--;
// Increment processing task counter // Increment processing task counter
g_atomic_int_inc(&sharp::counterProcess); sharp::counterProcess++;
try { try {
// Open input // Open input
@@ -1289,8 +1289,8 @@ class PipelineWorker : public Napi::AsyncWorker {
delete baton; delete baton;
// Decrement processing task counter // Decrement processing task counter
g_atomic_int_dec_and_test(&sharp::counterProcess); sharp::counterProcess--;
Napi::Number queueLength = Napi::Number::New(env, static_cast<double>(sharp::counterQueue)); Napi::Number queueLength = Napi::Number::New(env, static_cast<int>(sharp::counterQueue));
queueListener.MakeCallback(Receiver().Value(), { queueLength }); queueListener.MakeCallback(Receiver().Value(), { queueLength });
} }
@@ -1707,8 +1707,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
worker->Queue(); worker->Queue();
// Increment queued task counter // Increment queued task counter
g_atomic_int_inc(&sharp::counterQueue); Napi::Number queueLength = Napi::Number::New(info.Env(), static_cast<int>(++sharp::counterQueue));
Napi::Number queueLength = Napi::Number::New(info.Env(), static_cast<double>(sharp::counterQueue));
queueListener.MakeCallback(info.This(), { queueLength }); queueListener.MakeCallback(info.This(), { queueLength });
return info.Env().Undefined(); return info.Env().Undefined();

View File

@@ -1,6 +1,8 @@
// Copyright 2013 Lovell Fuller and others. // Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#include <mutex> // NOLINT(build/c++11)
#include <napi.h> #include <napi.h>
#include <vips/vips8> #include <vips/vips8>
@@ -10,14 +12,11 @@
#include "utilities.h" #include "utilities.h"
#include "stats.h" #include "stats.h"
static void* sharp_vips_init(void*) {
vips_init("sharp");
return nullptr;
}
Napi::Object init(Napi::Env env, Napi::Object exports) { Napi::Object init(Napi::Env env, Napi::Object exports) {
static GOnce sharp_vips_init_once = G_ONCE_INIT; static std::once_flag sharp_vips_init_once;
g_once(&sharp_vips_init_once, static_cast<GThreadFunc>(sharp_vips_init), nullptr); std::call_once(sharp_vips_init_once, []() {
vips_init("sharp");
});
g_log_set_handler("VIPS", static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING), g_log_set_handler("VIPS", static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING),
static_cast<GLogFunc>(sharp::VipsWarningCallback), nullptr); static_cast<GLogFunc>(sharp::VipsWarningCallback), nullptr);

View File

@@ -30,7 +30,7 @@ class StatsWorker : public Napi::AsyncWorker {
void Execute() { void Execute() {
// Decrement queued task counter // Decrement queued task counter
g_atomic_int_dec_and_test(&sharp::counterQueue); sharp::counterQueue--;
vips::VImage image; vips::VImage image;
sharp::ImageType imageType = sharp::ImageType::UNKNOWN; sharp::ImageType imageType = sharp::ImageType::UNKNOWN;
@@ -177,7 +177,7 @@ Napi::Value stats(const Napi::CallbackInfo& info) {
worker->Queue(); worker->Queue();
// Increment queued task counter // Increment queued task counter
g_atomic_int_inc(&sharp::counterQueue); sharp::counterQueue++;
return info.Env().Undefined(); return info.Env().Undefined();
} }

View File

@@ -70,8 +70,8 @@ Napi::Value concurrency(const Napi::CallbackInfo& info) {
*/ */
Napi::Value counters(const Napi::CallbackInfo& info) { Napi::Value counters(const Napi::CallbackInfo& info) {
Napi::Object counters = Napi::Object::New(info.Env()); Napi::Object counters = Napi::Object::New(info.Env());
counters.Set("queue", sharp::counterQueue); counters.Set("queue", static_cast<int>(sharp::counterQueue));
counters.Set("process", sharp::counterProcess); counters.Set("process", static_cast<int>(sharp::counterProcess));
return counters; return counters;
} }

View File

@@ -319,5 +319,16 @@ describe('Partial image extraction', function () {
s.extract(options); s.extract(options);
assert.strictEqual(warningMessage, 'ignoring previous extract options'); assert.strictEqual(warningMessage, 'ignoring previous extract options');
}); });
it('Multiple extract+resize emits warning', () => {
let warningMessage = '';
const s = sharp();
s.on('warning', function (msg) { warningMessage = msg; });
const options = { top: 0, left: 0, width: 1, height: 1 };
s.extract(options).extract(options);
assert.strictEqual(warningMessage, '');
s.resize(1);
assert.strictEqual(warningMessage, 'operation order will be: extract, resize, extract');
});
}); });
}); });

View File

@@ -284,4 +284,42 @@ describe('Raw pixel data', function () {
); );
} }
}); });
describe('16-bit roundtrip', () => {
it('grey', async () => {
const grey = 42000;
const png = await sharp(
Uint16Array.from([grey]),
{ raw: { width: 1, height: 1, channels: 1 } }
)
.toColourspace('grey16')
.png({ compressionLevel: 0 })
.toBuffer();
const raw = await sharp(png)
.toColourspace('grey16')
.raw({ depth: 'ushort' })
.toBuffer();
assert.strictEqual(raw.readUint16LE(0), grey);
});
it('RGB', async () => {
const rgb = [10946, 28657, 46368];
const png = await sharp(
Uint16Array.from(rgb),
{ raw: { width: 1, height: 1, channels: 3 } }
)
.toColourspace('rgb16')
.png({ compressionLevel: 0 })
.toBuffer();
const raw = await sharp(png)
.toColourspace('rgb16')
.raw({ depth: 'ushort' })
.toBuffer();
assert.strictEqual(raw.readUint16LE(0), rgb[0]);
assert.strictEqual(raw.readUint16LE(2), rgb[1]);
assert.strictEqual(raw.readUint16LE(4), rgb[2]);
});
});
}); });