Compare commits

...

4 Commits

Author SHA1 Message Date
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
12 changed files with 64 additions and 30 deletions

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

@@ -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

@@ -19,6 +19,9 @@
"files": [ "files": [
"lib" "lib"
], ],
"publishConfig": {
"access": "public"
},
"exports": { "exports": {
"./sharp.node": "./lib/sharp-darwin-x64.node", "./sharp.node": "./lib/sharp-darwin-x64.node",
"./package": "./package.json" "./package": "./package.json"

View File

@@ -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) {
@@ -36,7 +53,7 @@ workspaces.map(async platform => {
); );
// 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,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.2",
"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": [
@@ -140,15 +140,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.2",
"@sharpen/sharp-darwin-x64": "0.0.1-alpha.1", "@sharpen/sharp-darwin-x64": "0.0.1-alpha.2",
"@sharpen/sharp-linux-arm": "0.0.1-alpha.1", "@sharpen/sharp-linux-arm": "0.0.1-alpha.2",
"@sharpen/sharp-linux-arm64": "0.0.1-alpha.1", "@sharpen/sharp-linux-arm64": "0.0.1-alpha.2",
"@sharpen/sharp-linux-x64": "0.0.1-alpha.1", "@sharpen/sharp-linux-x64": "0.0.1-alpha.2",
"@sharpen/sharp-linuxmusl-arm64": "0.0.1-alpha.1", "@sharpen/sharp-linuxmusl-arm64": "0.0.1-alpha.2",
"@sharpen/sharp-linuxmusl-x64": "0.0.1-alpha.1", "@sharpen/sharp-linuxmusl-x64": "0.0.1-alpha.2",
"@sharpen/sharp-win32-ia32": "0.0.1-alpha.1", "@sharpen/sharp-win32-ia32": "0.0.1-alpha.2",
"@sharpen/sharp-win32-x64": "0.0.1-alpha.1" "@sharpen/sharp-win32-x64": "0.0.1-alpha.2"
}, },
"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) {

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

@@ -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');
});
}); });
}); });