Compare commits

..

12 Commits

Author SHA1 Message Date
Lovell Fuller
80d169b7c2 Release v0.30.2 2022-03-02 11:24:35 +00:00
Lovell Fuller
003279a0b0 CI: switch 32-bit Windows from Appveyor to Actions 2022-03-02 11:16:21 +00:00
Lovell Fuller
af80d7e389 Improve error message for missing file that might be SVG 2022-03-02 09:58:55 +00:00
Lovell Fuller
21a960796c Ignore greyscale ICC profiles due to lcms bug #3112 2022-02-28 11:28:08 +00:00
Lovell Fuller
fc3b4a683d Expand pkgconfig search path for wider BSD support #3106 2022-02-27 09:39:21 +00:00
Lovell Fuller
808133e7dc Docs: changelog entry for #3110 2022-02-26 19:40:17 +00:00
Lovell Fuller
801b6fea6c Bump devDeps 2022-02-26 19:39:46 +00:00
Kleis Auke Wolthuizen
c2ecde6a16 Windows: ensure C++ runtime is linked statically (#3110)
And remove the empty invalid parameter handler, which should
be present in the C layer instead.

This partially reverts commit
659cdabd8e,
the added test case in that commit is still preserved.
2022-02-26 19:15:37 +00:00
Lovell Fuller
55efe5602b Bump deps 2022-02-16 19:12:27 +00:00
Lovell Fuller
c62002554b Improve performance and accuracy of multi-image composite #2286 2022-02-16 19:04:23 +00:00
Lovell Fuller
7f83ecd255 Issue templates: small formatting fixes 2022-02-15 10:54:36 +00:00
Lovell Fuller
dc5f4dcd28 Issue templates: improve guidance, increase filtering 2022-02-15 10:50:26 +00:00
22 changed files with 172 additions and 93 deletions

View File

@@ -5,12 +5,24 @@ labels: enhancement
---
What are you trying to achieve?
## Feature request
Have you searched for similar feature requests?
### What are you trying to achieve?
What would you expect the API to look like?
<!-- Please provide context here. -->
What alternatives have you considered?
### When you searched for similar feature requests, what did you find that might be related?
Is there a sample image that helps explain?
<!-- Please demonstrate your research here. -->
### What would you expect the API to look like?
<!-- Please provide your suggestions here. -->
### What alternatives have you considered?
<!-- Please provide your ideas here. -->
### Please provide sample image(s) that help explain this feature
<!-- Please provide links to one or more images here. -->

View File

@@ -7,11 +7,24 @@ labels: installation
<!-- Please try to answer as many of these questions as possible. -->
Did you see the [documentation relating to installation](https://sharp.pixelplumbing.com/install)?
## Possible install-time or require-time problem
Have you ensured the architecture and platform of Node.js used for `npm install` is the same as the architecture and platform of Node.js used at runtime?
<!-- Please place an [x] in the box to confirm. -->
Are you using the latest version? Is the version currently in use as reported by `npm ls sharp` the same as the latest version as reported by `npm view sharp dist-tags.latest`?
- [ ] I have read the [documentation relating to installation](https://sharp.pixelplumbing.com/install).
- [ ] I have ensured that the architecture and platform of Node.js used for `npm install` is the same as the architecture and platform of Node.js used at runtime.
### Are you using the latest version of sharp?
<!-- Please place an [x] in the box to confirm. -->
- [ ] I am using the latest version of `sharp` as reported by `npm view sharp dist-tags.latest`.
If you cannot confirm this, please upgrade to the latest version and try again before opening an issue.
If you are using another package which depends on a version of `sharp` that is not the latest, please open an issue against that package instead.
### Is this a problem with filesystem permissions?
If you are using npm v6 or earlier and installing as a `root` or `sudo` user, have you tried with the `npm install --unsafe-perm` flag?
@@ -19,6 +32,14 @@ If you are using npm v7 or later, does the user running `npm install` own the di
If you are using the `ignore-scripts` feature of `npm`, have you tried with the `npm install --ignore-scripts=false` flag?
What is the complete output of running `npm install --verbose sharp`? Have you checked this output for useful error messages?
### What is the complete output of running `npm install --verbose sharp`?
What is the output of running `npx envinfo --binaries --system`?
<details>
<!-- Please provide output of `npm install --verbose sharp` here. -->
</details>
### What is the output of running `npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp`?
<!-- Please provide output of `npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp` here. -->

View File

@@ -7,14 +7,43 @@ labels: triage
<!-- If this issue relates to installation, please use https://github.com/lovell/sharp/issues/new?labels=installation&template=installation.md instead. -->
Are you using the latest version? Is the version currently in use as reported by `npm ls sharp` the same as the latest version as reported by `npm view sharp dist-tags.latest`?
## Possible bug
What are the steps to reproduce?
### Is this a possible bug in a feature of sharp, unrelated to installation?
What is the expected behaviour?
<!-- Please place an [x] in the box to confirm. -->
Are you able to provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem?
- [ ] Running `npm install sharp` completes without error.
- [ ] Running `node -e "require('sharp')"` completes without error.
Are you able to provide a sample image that helps explain the problem?
If you cannot confirm both of these, please open an [installation issue](https://github.com/lovell/sharp/issues/new?labels=installation&template=installation.md) instead.
What is the output of running `npx envinfo --binaries --system`?
### Are you using the latest version of sharp?
<!-- Please place an [x] in the box to confirm. -->
- [ ] I am using the latest version of `sharp` as reported by `npm view sharp dist-tags.latest`.
If you cannot confirm this, please upgrade to the latest version and try again before opening an issue.
If you are using another package which depends on a version of `sharp` that is not the latest, please open an issue against that package instead.
### What is the output of running `npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp`?
<!-- Please provide output of the above command here. -->
### What are the steps to reproduce?
<!-- Please enter steps to reproduce here. -->
### What is the expected behaviour?
<!-- Please enter the expected behaviour here. -->
### Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem
<!-- Please provide either formatted code or a link to a repo/gist that allows someone else to reproduce here. -->
### Please provide sample image(s) that help explain this problem
<!-- Please provide links to one or more images here. -->

View File

@@ -7,10 +7,20 @@ labels: question
<!-- If this issue relates to installation, please use https://github.com/lovell/sharp/issues/new?labels=installation&template=installation.md instead. -->
What are you trying to achieve?
## Question about an existing feature
Have you searched for similar questions?
### What are you trying to achieve?
Are you able to provide a minimal, standalone code sample that demonstrates this question?
<!-- Please provide context here. -->
Are you able to provide a sample image that helps explain the question?
### When you searched for similar issues, what did you find that might be related?
<!-- Please demonstrate your research here. -->
### Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this question
<!-- Please provide either formatted code or a link to a repo/gist that helps someone else understand here. -->
### Please provide sample image(s) that help explain this question
<!-- Please provide links to one or more images here. -->

View File

@@ -33,17 +33,33 @@ jobs:
- os: macos-10.15
nodejs_version: 12
prebuild: true
nodejs_arch: x64
- os: macos-10.15
nodejs_version: 14
nodejs_arch: x64
- os: macos-10.15
nodejs_version: 16
nodejs_arch: x64
- os: windows-2019
nodejs_version: 12
nodejs_arch: x86
prebuild: true
- os: windows-2019
nodejs_version: 14
nodejs_arch: x86
- os: windows-2019
nodejs_version: 16
nodejs_arch: x86
- os: windows-2019
nodejs_version: 12
nodejs_arch: x64
prebuild: true
- os: windows-2019
nodejs_version: 14
nodejs_arch: x64
- os: windows-2019
nodejs_version: 16
nodejs_arch: x64
steps:
- name: Dependencies (Linux glibc)
if: contains(matrix.container, 'centos')
@@ -57,9 +73,10 @@ jobs:
run: apk add build-base git python3 --update-cache
- name: Dependencies (macOS, Windows)
if: contains(matrix.os, 'macos') || contains(matrix.os, 'windows')
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.nodejs_version }}
architecture: ${{ matrix.nodejs_arch }}
- name: Checkout
uses: actions/checkout@v2
- name: Fix working directory ownership

View File

@@ -1,17 +0,0 @@
os: Visual Studio 2019
version: "{build}"
build: off
platform: x86
environment:
matrix:
- nodejs_version: "12"
prebuild: true
- nodejs_version: "14"
- nodejs_version: "16"
install:
- ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version)
- npm install --build-from-source
test_script:
- npm test
on_success:
- if [%prebuild%] == [true] if [%APPVEYOR_REPO_TAG%] == [true] npx prebuild --runtime napi --target 5

View File

@@ -39,7 +39,6 @@
'VCCLCompilerTool': {
'ExceptionHandling': 1,
'Optimization': 1,
'RuntimeLibrary': '2', # /MD
'WholeProgramOptimization': 'true'
},
'VCLibrarianTool': {
@@ -206,7 +205,6 @@
'VCCLCompilerTool': {
'ExceptionHandling': 1,
'Optimization': 1,
'RuntimeLibrary': '2', # /MD
'WholeProgramOptimization': 'true'
},
'VCLibrarianTool': {

View File

@@ -4,6 +4,21 @@
Requires libvips v8.12.2
### v0.30.2 - 2nd March 2022
* Improve performance and accuracy when compositing multiple images.
[#2286](https://github.com/lovell/sharp/issues/2286)
* Expand pkgconfig search path for wider BSD support.
[#3106](https://github.com/lovell/sharp/issues/3106)
* Ensure Windows C++ runtime is linked statically (regression in 0.30.0).
[#3110](https://github.com/lovell/sharp/pull/3110)
[@kleisauke](https://github.com/kleisauke)
* Temporarily ignore greyscale ICC profiles to workaround lcms bug.
[#3112](https://github.com/lovell/sharp/issues/3112)
### v0.30.1 - 9th February 2022
* Allow use of `toBuffer` and `toFile` on the same instance.

View File

@@ -162,7 +162,6 @@ function composite (images) {
throw is.invalidParameterError('premultiplied', 'boolean', image.premultiplied);
}
}
return composite;
});
return this;

View File

@@ -86,9 +86,14 @@ const removeVendoredLibvips = function () {
const pkgConfigPath = function () {
if (process.platform !== 'win32') {
const brewPkgConfigPath = spawnSync('which brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CONFIG_LIBDIR', spawnSyncOptions).stdout || '';
return [brewPkgConfigPath.trim(), env.PKG_CONFIG_PATH, '/usr/local/lib/pkgconfig', '/usr/lib/pkgconfig']
.filter(function (p) { return !!p; })
.join(':');
return [
brewPkgConfigPath.trim(),
env.PKG_CONFIG_PATH,
'/usr/local/lib/pkgconfig',
'/usr/lib/pkgconfig',
'/usr/local/libdata/pkgconfig',
'/usr/libdata/pkgconfig'
].filter(Boolean).join(':');
} else {
return '';
}

View File

@@ -1,7 +1,7 @@
{
"name": "sharp",
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
"version": "0.30.1",
"version": "0.30.2",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://github.com/lovell/sharp",
"contributors": [
@@ -126,8 +126,8 @@
"vips"
],
"dependencies": {
"color": "^4.2.0",
"detect-libc": "^2.0.0",
"color": "^4.2.1",
"detect-libc": "^2.0.1",
"node-addon-api": "^4.3.0",
"prebuild-install": "^7.0.1",
"semver": "^7.3.5",
@@ -143,7 +143,7 @@
"exif-reader": "^1.0.3",
"icc": "^2.0.0",
"license-checker": "^25.0.1",
"mocha": "^9.2.0",
"mocha": "^9.2.1",
"mock-fs": "^5.1.2",
"nyc": "^15.1.0",
"prebuild": "^11.0.3",

View File

@@ -398,6 +398,10 @@ namespace sharp {
// From filesystem
imageType = DetermineImageType(descriptor->file.data());
if (imageType == ImageType::MISSING) {
if (descriptor->file.find("<svg") != std::string::npos) {
throw vips::VError("Input file is missing, did you mean "
"sharp(Buffer.from('" + descriptor->file.substr(0, 8) + "...')?");
}
throw vips::VError("Input file is missing");
}
if (imageType != ImageType::UNKNOWN) {

View File

@@ -292,7 +292,8 @@ class PipelineWorker : public Napi::AsyncWorker {
if (
sharp::HasProfile(image) &&
image.interpretation() != VIPS_INTERPRETATION_LABS &&
image.interpretation() != VIPS_INTERPRETATION_GREY16
image.interpretation() != VIPS_INTERPRETATION_GREY16 &&
image.interpretation() != VIPS_INTERPRETATION_B_W
) {
// Convert to sRGB/P3 using embedded profile
try {
@@ -581,6 +582,8 @@ class PipelineWorker : public Napi::AsyncWorker {
// Composite
if (shouldComposite) {
std::vector<VImage> images = { image };
std::vector<int> modes, xs, ys;
for (Composite *composite : baton->composite) {
VImage compositeImage;
sharp::ImageType compositeImageType = sharp::ImageType::UNKNOWN;
@@ -626,12 +629,12 @@ 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 premultiplied alpha
// Ensure image to composite is sRGB with unpremultiplied alpha
compositeImage = compositeImage.colourspace(VIPS_INTERPRETATION_sRGB);
if (!sharp::HasAlpha(compositeImage)) {
compositeImage = sharp::EnsureAlpha(compositeImage, 1);
}
if (!composite->premultiplied) compositeImage = compositeImage.premultiply();
if (composite->premultiplied) compositeImage = compositeImage.unpremultiply();
// Calculate position
int left;
int top;
@@ -649,12 +652,12 @@ class PipelineWorker : public Napi::AsyncWorker {
std::tie(left, top) = sharp::CalculateCrop(image.width(), image.height(),
compositeImage.width(), compositeImage.height(), composite->gravity);
}
// Composite
image = image.composite2(compositeImage, composite->mode, VImage::option()
->set("premultiplied", TRUE)
->set("x", left)
->set("y", top));
images.push_back(compositeImage);
modes.push_back(composite->mode);
xs.push_back(left);
ys.push_back(top);
}
image = image.composite(images, modes, VImage::option()->set("x", xs)->set("y", ys));
}
// Reverse premultiplication after all transformations:

View File

@@ -13,7 +13,6 @@
// limitations under the License.
#include <napi.h>
#include <cstdlib>
#include <vips/vips8>
#include "common.h"
@@ -22,14 +21,6 @@
#include "utilities.h"
#include "stats.h"
#if defined(_MSC_VER) && _MSC_VER >= 1400 // MSVC 2005/8
static void empty_invalid_parameter_handler(const wchar_t* expression,
const wchar_t* function, const wchar_t* file, unsigned int line,
uintptr_t reserved) {
// No-op.
}
#endif
static void* sharp_vips_init(void*) {
g_setenv("VIPS_MIN_STACK_SIZE", "2m", FALSE);
vips_init("sharp");
@@ -43,13 +34,6 @@ Napi::Object init(Napi::Env env, Napi::Object exports) {
g_log_set_handler("VIPS", static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING),
static_cast<GLogFunc>(sharp::VipsWarningCallback), nullptr);
// Tell the CRT to not exit the application when an invalid parameter is
// passed. The main issue is that invalid FDs will trigger this behaviour.
// See: https://github.com/libvips/libvips/pull/2571.
#if defined(_MSC_VER) && _MSC_VER >= 1400 // MSVC 2005/8
_set_invalid_parameter_handler(empty_invalid_parameter_handler);
#endif
// Methods available to JavaScript
exports.Set("metadata", Napi::Function::New(env, metadata));
exports.Set("pipeline", Napi::Function::New(env, pipeline));

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 B

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 B

After

Width:  |  Height:  |  Size: 286 B

View File

@@ -45,22 +45,20 @@ const blends = [
// Test
describe('composite', () => {
it('blend', () => Promise.all(
blends.map(blend => {
blends.forEach(blend => {
it(`blend ${blend}`, async () => {
const filename = `composite.blend.${blend}.png`;
const actual = fixtures.path(`output.${filename}`);
const expected = fixtures.expected(filename);
return sharp(redRect)
await sharp(redRect)
.composite([{
input: blueRect,
blend
}])
.toFile(actual)
.then(() => {
fixtures.assertMaxColourDistance(actual, expected);
});
})
));
.toFile(actual);
fixtures.assertMaxColourDistance(actual, expected);
});
});
it('premultiplied true', () => {
const filename = 'composite.premultiplied.png';
@@ -121,11 +119,11 @@ describe('composite', () => {
});
});
it('multiple', () => {
it('multiple', async () => {
const filename = 'composite-multiple.png';
const actual = fixtures.path(`output.${filename}`);
const expected = fixtures.expected(filename);
return sharp(redRect)
await sharp(redRect)
.composite([{
input: blueRect,
gravity: 'northeast'
@@ -133,10 +131,8 @@ describe('composite', () => {
input: greenRect,
gravity: 'southwest'
}])
.toFile(actual)
.then(() => {
fixtures.assertMaxColourDistance(actual, expected);
});
.toFile(actual);
fixtures.assertMaxColourDistance(actual, expected);
});
it('zero offset', done => {

View File

@@ -140,7 +140,7 @@ describe('Extend', function () {
});
it('Premultiply background when compositing', async () => {
const background = '#bf1942cc';
const background = { r: 191, g: 25, b: 66, alpha: 0.8 };
const data = await sharp({
create: {
width: 1, height: 1, channels: 4, background: '#fff0'
@@ -158,10 +158,6 @@ describe('Extend', function () {
})
.raw()
.toBuffer();
const [r1, g1, b1, a1, r2, g2, b2, a2] = data;
assert.strictEqual(true, Math.abs(r2 - r1) < 2);
assert.strictEqual(true, Math.abs(g2 - g1) < 2);
assert.strictEqual(true, Math.abs(b2 - b1) < 2);
assert.strictEqual(true, Math.abs(a2 - a1) < 2);
assert.deepStrictEqual(Array.from(data), [191, 25, 65, 204, 238, 31, 82, 204]);
});
});

View File

@@ -135,4 +135,11 @@ describe('SVG input', function () {
assert.strictEqual(info.height, 240);
assert.strictEqual(info.channels, 4);
});
it('Detects SVG passed as a string', () =>
assert.rejects(
() => sharp('<svg></svg>').toBuffer(),
/Input file is missing, did you mean/
)
);
});