Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5ecc537af | ||
|
|
c7a49054fd | ||
|
|
a2314c4aa0 | ||
|
|
1717173f17 | ||
|
|
e44c12f029 | ||
|
|
1a98c390fc | ||
|
|
91902740e4 | ||
|
|
6aa6a93b44 | ||
|
|
b4135ac9b3 | ||
|
|
78906e6551 |
2
.github/ISSUE_TEMPLATE/installation.md
vendored
@@ -7,7 +7,7 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Did you see the [documentation relating to installation](https://sharp.pixelplumbing.com/en/stable/install/)?
|
||||
Did you see the [documentation relating to installation](https://sharp.pixelplumbing.com/install)?
|
||||
|
||||
Have you ensured the platform and version of Node.js used for `npm install` is the same as the platform and version of Node.js used at runtime?
|
||||
|
||||
|
||||
@@ -90,10 +90,10 @@ readableStream
|
||||
### Documentation
|
||||
|
||||
Visit [sharp.pixelplumbing.com](https://sharp.pixelplumbing.com/) for complete
|
||||
[installation instructions](https://sharp.pixelplumbing.com/page/install),
|
||||
[API documentation](https://sharp.pixelplumbing.com/page/api),
|
||||
[benchmark tests](https://sharp.pixelplumbing.com/page/performance) and
|
||||
[changelog](https://sharp.pixelplumbing.com/page/changelog).
|
||||
[installation instructions](https://sharp.pixelplumbing.com/install),
|
||||
[API documentation](https://sharp.pixelplumbing.com/api-constructor),
|
||||
[benchmark tests](https://sharp.pixelplumbing.com/performance) and
|
||||
[changelog](https://sharp.pixelplumbing.com/changelog).
|
||||
|
||||
### Contributing
|
||||
|
||||
|
||||
@@ -88,9 +88,9 @@ image
|
||||
|
||||
Returns **[Promise][5]<[Object][6]>**
|
||||
|
||||
[1]: https://github.com/libvips/libvips/blob/master/libvips/iofuncs/enumtypes.c#L636
|
||||
[1]: https://libvips.github.io/libvips/API/current/VipsImage.html#VipsInterpretation
|
||||
|
||||
[2]: https://github.com/libvips/libvips/blob/master/libvips/iofuncs/enumtypes.c#L672
|
||||
[2]: https://libvips.github.io/libvips/API/current/VipsImage.html#VipsBandFormat
|
||||
|
||||
[3]: https://www.npmjs.com/package/icc
|
||||
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
|
||||
Requires libvips v8.9.0.
|
||||
|
||||
### v0.24.1 - 15<sup>th</sup> February 2020
|
||||
|
||||
* Prevent use of sequentialRead for EXIF-based rotate operation.
|
||||
[#2042](https://github.com/lovell/sharp/issues/2042)
|
||||
|
||||
* Ensure RGBA LZW TIFF returns correct channel count.
|
||||
[#2064](https://github.com/lovell/sharp/issues/2064)
|
||||
|
||||
### v0.24.0 - 16<sup>th</sup> January 2020
|
||||
|
||||
* Drop support for Node.js 8.
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
"destination": "/install",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "/page/install",
|
||||
"destination": "/install",
|
||||
"type": 301
|
||||
},
|
||||
{
|
||||
"source": "**/api-constructor/**",
|
||||
"destination": "/api-constructor",
|
||||
@@ -70,16 +75,31 @@
|
||||
"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": "/",
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
docuteGoogleAnalytics('UA-13034748-12'),
|
||||
docuteApiTitlePlugin
|
||||
],
|
||||
sourcePath: 'https://cdn.jsdelivr.net/gh/lovell/sharp@v0.24.0/docs',
|
||||
sourcePath: 'https://cdn.jsdelivr.net/gh/lovell/sharp@v0.24.1/docs',
|
||||
nav: [
|
||||
{
|
||||
title: 'Funding',
|
||||
|
||||
@@ -54,6 +54,8 @@ must be the same as the platform and major version of Node.js used at runtime.
|
||||
|
||||
The `npm install --unsafe-perm` flag must be used when installing as `root` or a `sudo` user.
|
||||
|
||||
The `npm install --ignore-scripts=false` flag must be used when `npm` has been configured to ignore installation scripts.
|
||||
|
||||
Check the output of running `npm install --verbose sharp` for useful error messages.
|
||||
|
||||
## Custom libvips
|
||||
|
||||
@@ -16,6 +16,8 @@ try {
|
||||
help.push('- Ensure the version of Node.js used at install time matches that used at runtime');
|
||||
} else if (/invalid ELF header/.test(err.message)) {
|
||||
help.push(`- Ensure "${process.platform}" is used at install time as well as runtime`);
|
||||
} else if (/dylib/.test(err.message) && /Incompatible library version/.test(err.message)) {
|
||||
help.push('- Run "brew update && brew upgrade vips"');
|
||||
} else if (/Cannot find module/.test(err.message)) {
|
||||
help.push('- Run "npm rebuild --verbose sharp" and look for errors');
|
||||
} else {
|
||||
|
||||
@@ -187,9 +187,9 @@ function _isStreamInput () {
|
||||
* - `size`: Total size of image in bytes, for Stream and Buffer input only
|
||||
* - `width`: Number of pixels wide (EXIF orientation is not taken into consideration)
|
||||
* - `height`: Number of pixels high (EXIF orientation is not taken into consideration)
|
||||
* - `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://github.com/libvips/libvips/blob/master/libvips/iofuncs/enumtypes.c#L636)
|
||||
* - `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://libvips.github.io/libvips/API/current/VipsImage.html#VipsInterpretation)
|
||||
* - `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
|
||||
* - `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://github.com/libvips/libvips/blob/master/libvips/iofuncs/enumtypes.c#L672)
|
||||
* - `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://libvips.github.io/libvips/API/current/VipsImage.html#VipsBandFormat)
|
||||
* - `density`: Number of pixels per inch (DPI), if present
|
||||
* - `chromaSubsampling`: 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
|
||||
* - `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
|
||||
|
||||
12
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "sharp",
|
||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
||||
"version": "0.24.0",
|
||||
"version": "0.24.1",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://github.com/lovell/sharp",
|
||||
"contributors": [
|
||||
@@ -112,25 +112,25 @@
|
||||
"nan": "^2.14.0",
|
||||
"npmlog": "^4.1.2",
|
||||
"prebuild-install": "^5.3.3",
|
||||
"semver": "^7.1.1",
|
||||
"semver": "^7.1.3",
|
||||
"simple-get": "^3.1.0",
|
||||
"tar": "^5.0.5",
|
||||
"tar": "^6.0.1",
|
||||
"tunnel-agent": "^0.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"async": "^3.1.0",
|
||||
"async": "^3.1.1",
|
||||
"cc": "^2.0.1",
|
||||
"decompress-zip": "^0.3.2",
|
||||
"documentation": "^12.1.4",
|
||||
"exif-reader": "^1.0.3",
|
||||
"icc": "^1.0.0",
|
||||
"license-checker": "^25.0.1",
|
||||
"mocha": "^7.0.0",
|
||||
"mocha": "^7.0.1",
|
||||
"mock-fs": "^4.10.4",
|
||||
"nyc": "^15.0.0",
|
||||
"prebuild": "^10.0.0",
|
||||
"prebuild-ci": "^3.1.0",
|
||||
"rimraf": "^3.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"semistandard": "^14.2.0"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -764,6 +764,7 @@ class PipelineWorker : public Nan::AsyncWorker {
|
||||
// Write TIFF to buffer
|
||||
if (baton->tiffCompression == VIPS_FOREIGN_TIFF_COMPRESSION_JPEG) {
|
||||
sharp::AssertImageTypeDimensions(image, ImageType::JPEG);
|
||||
baton->channels = std::min(baton->channels, 3);
|
||||
}
|
||||
// Cast pixel values to float, if required
|
||||
if (baton->tiffPredictor == VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT) {
|
||||
@@ -786,7 +787,6 @@ class PipelineWorker : public Nan::AsyncWorker {
|
||||
area->free_fn = nullptr;
|
||||
vips_area_unref(area);
|
||||
baton->formatOut = "tiff";
|
||||
baton->channels = std::min(baton->channels, 3);
|
||||
} else if (baton->formatOut == "heif" || (baton->formatOut == "input" && inputImageType == ImageType::HEIF)) {
|
||||
// Write HEIF to buffer
|
||||
VipsArea *area = VIPS_AREA(image.heifsave_buffer(VImage::option()
|
||||
@@ -887,6 +887,7 @@ class PipelineWorker : public Nan::AsyncWorker {
|
||||
// Write TIFF to file
|
||||
if (baton->tiffCompression == VIPS_FOREIGN_TIFF_COMPRESSION_JPEG) {
|
||||
sharp::AssertImageTypeDimensions(image, ImageType::JPEG);
|
||||
baton->channels = std::min(baton->channels, 3);
|
||||
}
|
||||
image.tiffsave(const_cast<char*>(baton->fileOut.data()), VImage::option()
|
||||
->set("strip", !baton->withMetadata)
|
||||
@@ -901,7 +902,6 @@ class PipelineWorker : public Nan::AsyncWorker {
|
||||
->set("xres", baton->tiffXres)
|
||||
->set("yres", baton->tiffYres));
|
||||
baton->formatOut = "tiff";
|
||||
baton->channels = std::min(baton->channels, 3);
|
||||
} else if (baton->formatOut == "heif" || (mightMatchInput && isHeif) ||
|
||||
(willMatchInput && inputImageType == ImageType::HEIF)) {
|
||||
// Write HEIF to file
|
||||
@@ -1404,7 +1404,9 @@ NAN_METHOD(pipeline) {
|
||||
baton->trimThreshold > 0.0 ||
|
||||
baton->normalise ||
|
||||
baton->position == 16 || baton->position == 17 ||
|
||||
baton->angle != 0 || baton->rotationAngle != 0.0
|
||||
baton->angle % 360 != 0 ||
|
||||
fmod(baton->rotationAngle, 360.0) != 0.0 ||
|
||||
baton->useExifOrientation
|
||||
) {
|
||||
baton->input->access = VIPS_ACCESS_RANDOM;
|
||||
}
|
||||
|
||||
BIN
test/fixtures/expected/overlay-offset-0.jpg
vendored
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
test/fixtures/expected/overlay-offset-with-tile.jpg
vendored
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 2.9 KiB |
@@ -141,7 +141,7 @@ describe('composite', () => {
|
||||
|
||||
it('zero offset', done => {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.resize(80)
|
||||
.composite([{
|
||||
input: fixtures.inputPngWithTransparency16bit,
|
||||
top: 0,
|
||||
@@ -157,7 +157,7 @@ describe('composite', () => {
|
||||
|
||||
it('offset and gravity', done => {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.resize(80)
|
||||
.composite([{
|
||||
input: fixtures.inputPngWithTransparency16bit,
|
||||
left: 10,
|
||||
@@ -174,7 +174,7 @@ describe('composite', () => {
|
||||
|
||||
it('offset, gravity and tile', done => {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.resize(80)
|
||||
.composite([{
|
||||
input: fixtures.inputPngWithTransparency16bit,
|
||||
left: 10,
|
||||
@@ -192,7 +192,7 @@ describe('composite', () => {
|
||||
|
||||
it('offset and tile', done => {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(400)
|
||||
.resize(80)
|
||||
.composite([{
|
||||
input: fixtures.inputPngWithTransparency16bit,
|
||||
left: 10,
|
||||
|
||||
@@ -208,11 +208,48 @@ describe('TIFF', function () {
|
||||
.toFile(fixtures.outputTiff, (err, info) => {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('tiff', info.format);
|
||||
assert.strictEqual(3, info.channels);
|
||||
assert(info.size < startSize);
|
||||
rimraf(fixtures.outputTiff, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('TIFF LZW RGBA toFile', () =>
|
||||
sharp({
|
||||
create: {
|
||||
width: 1,
|
||||
height: 1,
|
||||
channels: 4,
|
||||
background: 'red'
|
||||
}
|
||||
})
|
||||
.tiff({
|
||||
compression: 'lzw'
|
||||
})
|
||||
.toFile(fixtures.outputTiff)
|
||||
.then(info => {
|
||||
assert.strictEqual(4, info.channels);
|
||||
})
|
||||
);
|
||||
|
||||
it('TIFF LZW RGBA toBuffer', () =>
|
||||
sharp({
|
||||
create: {
|
||||
width: 1,
|
||||
height: 1,
|
||||
channels: 4,
|
||||
background: 'red'
|
||||
}
|
||||
})
|
||||
.tiff({
|
||||
compression: 'lzw'
|
||||
})
|
||||
.toBuffer({ resolveWithObject: true })
|
||||
.then(({ info }) => {
|
||||
assert.strictEqual(4, info.channels);
|
||||
})
|
||||
);
|
||||
|
||||
it('TIFF ccittfax4 compression shrinks b-w test file', function (done) {
|
||||
const startSize = fs.statSync(fixtures.inputTiff).size;
|
||||
sharp(fixtures.inputTiff)
|
||||
|
||||