mirror of
https://github.com/lovell/sharp.git
synced 2026-02-04 21:56:18 +01:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd5b4a131f | ||
|
|
32c4b9eff1 | ||
|
|
95cf35efc5 | ||
|
|
58e6368525 | ||
|
|
16e0d54b15 | ||
|
|
be381e4440 |
@@ -1,6 +1,7 @@
|
|||||||
build
|
build
|
||||||
node_modules
|
node_modules
|
||||||
coverage
|
coverage
|
||||||
|
.editorconfig
|
||||||
.jshintignore
|
.jshintignore
|
||||||
.jshintrc
|
.jshintrc
|
||||||
.gitignore
|
.gitignore
|
||||||
|
|||||||
@@ -77,7 +77,14 @@ module.exports.download_vips = function() {
|
|||||||
var tmpFile = fs.createWriteStream(tarPath).on('finish', function() {
|
var tmpFile = fs.createWriteStream(tarPath).on('finish', function() {
|
||||||
unpack(tarPath);
|
unpack(tarPath);
|
||||||
});
|
});
|
||||||
request(distBaseUrl + tarFilename).on('response', function(response) {
|
var options = {
|
||||||
|
url: distBaseUrl + tarFilename
|
||||||
|
};
|
||||||
|
if (process.env.npm_config_https_proxy) {
|
||||||
|
// Use the NPM-configured HTTPS proxy
|
||||||
|
options.proxy = process.env.npm_config_https_proxy;
|
||||||
|
}
|
||||||
|
request(options).on('response', function(response) {
|
||||||
if (response.statusCode !== 200) {
|
if (response.statusCode !== 200) {
|
||||||
error(distBaseUrl + tarFilename + ' status code ' + response.statusCode);
|
error(distBaseUrl + tarFilename + ' status code ' + response.statusCode);
|
||||||
}
|
}
|
||||||
|
|||||||
38
docs/api.md
38
docs/api.md
@@ -426,8 +426,6 @@ Use WebP format for the output image.
|
|||||||
|
|
||||||
#### raw()
|
#### raw()
|
||||||
|
|
||||||
_Requires libvips 7.42.0+_
|
|
||||||
|
|
||||||
Provide raw, uncompressed uint8 (unsigned char) image data for Buffer and Stream based output.
|
Provide raw, uncompressed uint8 (unsigned char) image data for Buffer and Stream based output.
|
||||||
|
|
||||||
The number of channels depends on the input image and selected options.
|
The number of channels depends on the input image and selected options.
|
||||||
@@ -497,13 +495,11 @@ An advanced setting for the _zlib_ compression level of the lossless PNG output
|
|||||||
|
|
||||||
#### withoutAdaptiveFiltering()
|
#### withoutAdaptiveFiltering()
|
||||||
|
|
||||||
_Requires libvips 7.42.0+_
|
|
||||||
|
|
||||||
An advanced setting to disable adaptive row filtering for the lossless PNG output format.
|
An advanced setting to disable adaptive row filtering for the lossless PNG output format.
|
||||||
|
|
||||||
#### trellisQuantisation() / trellisQuantization()
|
#### trellisQuantisation() / trellisQuantization()
|
||||||
|
|
||||||
_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
|
_Requires libvips to have been compiled with mozjpeg support_
|
||||||
|
|
||||||
An advanced setting to apply the use of
|
An advanced setting to apply the use of
|
||||||
[trellis quantisation](http://en.wikipedia.org/wiki/Trellis_quantization) with JPEG output.
|
[trellis quantisation](http://en.wikipedia.org/wiki/Trellis_quantization) with JPEG output.
|
||||||
@@ -511,7 +507,7 @@ Reduces file size and slightly increases relative quality at the cost of increas
|
|||||||
|
|
||||||
#### overshootDeringing()
|
#### overshootDeringing()
|
||||||
|
|
||||||
_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
|
_Requires libvips to have been compiled with mozjpeg support_
|
||||||
|
|
||||||
An advanced setting to reduce the effects of
|
An advanced setting to reduce the effects of
|
||||||
[ringing](http://en.wikipedia.org/wiki/Ringing_%28signal%29) in JPEG output,
|
[ringing](http://en.wikipedia.org/wiki/Ringing_%28signal%29) in JPEG output,
|
||||||
@@ -519,7 +515,7 @@ in particular where black text appears on a white background (or vice versa).
|
|||||||
|
|
||||||
#### optimiseScans() / optimizeScans()
|
#### optimiseScans() / optimizeScans()
|
||||||
|
|
||||||
_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
|
_Requires libvips to have been compiled with mozjpeg support_
|
||||||
|
|
||||||
An advanced setting for progressive (interlace) JPEG output.
|
An advanced setting for progressive (interlace) JPEG output.
|
||||||
Calculates which spectrum of DCT coefficients uses the fewest bits.
|
Calculates which spectrum of DCT coefficients uses the fewest bits.
|
||||||
@@ -633,3 +629,31 @@ Provides access to internal task counters.
|
|||||||
```javascript
|
```javascript
|
||||||
var counters = sharp.counters(); // { queue: 2, process: 4 }
|
var counters = sharp.counters(); // { queue: 2, process: 4 }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### sharp.simd([enable])
|
||||||
|
|
||||||
|
_Requires libvips to have been compiled with liborc support_
|
||||||
|
|
||||||
|
Improves the performance of `resize`, `blur` and `sharpen` operations
|
||||||
|
by taking advantage of the SIMD vector unit of the CPU.
|
||||||
|
|
||||||
|
* `enable`, if present, is a boolean where `true` enables and `false` disables the use of SIMD.
|
||||||
|
|
||||||
|
This method always returns the current state.
|
||||||
|
|
||||||
|
This feature is currently disabled by default
|
||||||
|
but future versions may enable it by default.
|
||||||
|
|
||||||
|
When enabled, versions of liborc prior to 0.4.24
|
||||||
|
and versions of libvips prior to 8.2.0
|
||||||
|
have been known to crash under heavy load.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var simd = sharp.simd();
|
||||||
|
// simd is `true` is SIMD is currently enabled
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var simd = sharp.simd(true);
|
||||||
|
// attempts to enable the use of SIMD, returning true if available
|
||||||
|
```
|
||||||
|
|||||||
@@ -2,7 +2,20 @@
|
|||||||
|
|
||||||
### v0.12 - "*look*"
|
### v0.12 - "*look*"
|
||||||
|
|
||||||
#### v0.12.0 - TBD
|
#### v0.12.1 - 12<sup>th</sup> December 2015
|
||||||
|
|
||||||
|
* Allow use of SIMD vector instructions (via liborc) to be toggled on/off.
|
||||||
|
[#172](https://github.com/lovell/sharp/issues/172)
|
||||||
|
[@bkw](https://github.com/bkw)
|
||||||
|
[@puzrin](https://github.com/puzrin)
|
||||||
|
|
||||||
|
* Ensure embedded ICC profiles output with perceptual intent.
|
||||||
|
[#321](https://github.com/lovell/sharp/issues/321)
|
||||||
|
[@vlapo](https://github.com/vlapo)
|
||||||
|
|
||||||
|
* Use the NPM-configured HTTPS proxy, if any, for binary downloads.
|
||||||
|
|
||||||
|
#### v0.12.0 - 23<sup>rd</sup> November 2015
|
||||||
|
|
||||||
* Bundle pre-compiled libvips and its dependencies for 64-bit Linux and Windows.
|
* Bundle pre-compiled libvips and its dependencies for 64-bit Linux and Windows.
|
||||||
[#42](https://github.com/lovell/sharp/issues/42)
|
[#42](https://github.com/lovell/sharp/issues/42)
|
||||||
|
|||||||
12
index.js
12
index.js
@@ -863,3 +863,15 @@ module.exports.concurrency = function(concurrency) {
|
|||||||
module.exports.counters = function() {
|
module.exports.counters = function() {
|
||||||
return sharp.counters();
|
return sharp.counters();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get and set use of SIMD vector unit instructions
|
||||||
|
*/
|
||||||
|
module.exports.simd = function(simd) {
|
||||||
|
if (typeof simd !== 'boolean') {
|
||||||
|
simd = null;
|
||||||
|
}
|
||||||
|
return sharp.simd(simd);
|
||||||
|
};
|
||||||
|
// Switch off default
|
||||||
|
module.exports.simd(false);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sharp",
|
"name": "sharp",
|
||||||
"version": "0.12.0",
|
"version": "0.12.1",
|
||||||
"author": "Lovell Fuller <npm@lovell.info>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Pierre Inglebert <pierre.inglebert@gmail.com>",
|
"Pierre Inglebert <pierre.inglebert@gmail.com>",
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"async": "^1.5.0",
|
"async": "^1.5.0",
|
||||||
"coveralls": "^2.11.4",
|
"coveralls": "^2.11.6",
|
||||||
"exif-reader": "^1.0.0",
|
"exif-reader": "^1.0.0",
|
||||||
"icc": "^0.0.2",
|
"icc": "^0.0.2",
|
||||||
"istanbul": "^0.4.0",
|
"istanbul": "^0.4.0",
|
||||||
|
|||||||
@@ -421,7 +421,10 @@ class PipelineWorker : public AsyncWorker {
|
|||||||
if (HasProfile(image)) {
|
if (HasProfile(image)) {
|
||||||
// Convert to sRGB using embedded profile
|
// Convert to sRGB using embedded profile
|
||||||
VipsImage *transformed;
|
VipsImage *transformed;
|
||||||
if (!vips_icc_transform(image, &transformed, srgbProfile.data(), "embedded", TRUE, nullptr)) {
|
if (
|
||||||
|
!vips_icc_transform(image, &transformed, srgbProfile.data(),
|
||||||
|
"embedded", TRUE, "intent", VIPS_INTENT_PERCEPTUAL, nullptr)
|
||||||
|
) {
|
||||||
// Embedded profile can fail, so only update references on success
|
// Embedded profile can fail, so only update references on success
|
||||||
vips_object_local(hook, transformed);
|
vips_object_local(hook, transformed);
|
||||||
image = transformed;
|
image = transformed;
|
||||||
@@ -430,7 +433,10 @@ class PipelineWorker : public AsyncWorker {
|
|||||||
// Convert to sRGB using default "USWebCoatedSWOP" CMYK profile
|
// Convert to sRGB using default "USWebCoatedSWOP" CMYK profile
|
||||||
std::string cmykProfile = baton->iccProfilePath + "USWebCoatedSWOP.icc";
|
std::string cmykProfile = baton->iccProfilePath + "USWebCoatedSWOP.icc";
|
||||||
VipsImage *transformed;
|
VipsImage *transformed;
|
||||||
if (vips_icc_transform(image, &transformed, srgbProfile.data(), "input_profile", cmykProfile.data(), nullptr)) {
|
if (
|
||||||
|
vips_icc_transform(image, &transformed, srgbProfile.data(),
|
||||||
|
"input_profile", cmykProfile.data(), "intent", VIPS_INTENT_PERCEPTUAL, nullptr)
|
||||||
|
) {
|
||||||
return Error();
|
return Error();
|
||||||
}
|
}
|
||||||
vips_object_local(hook, transformed);
|
vips_object_local(hook, transformed);
|
||||||
|
|||||||
2
src/sharp.cc
Executable file → Normal file
2
src/sharp.cc
Executable file → Normal file
@@ -26,6 +26,8 @@ NAN_MODULE_INIT(init) {
|
|||||||
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(concurrency)).ToLocalChecked());
|
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(concurrency)).ToLocalChecked());
|
||||||
Nan::Set(target, Nan::New("counters").ToLocalChecked(),
|
Nan::Set(target, Nan::New("counters").ToLocalChecked(),
|
||||||
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(counters)).ToLocalChecked());
|
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(counters)).ToLocalChecked());
|
||||||
|
Nan::Set(target, Nan::New("simd").ToLocalChecked(),
|
||||||
|
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(simd)).ToLocalChecked());
|
||||||
Nan::Set(target, Nan::New("libvipsVersion").ToLocalChecked(),
|
Nan::Set(target, Nan::New("libvipsVersion").ToLocalChecked(),
|
||||||
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(libvipsVersion)).ToLocalChecked());
|
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(libvipsVersion)).ToLocalChecked());
|
||||||
Nan::Set(target, Nan::New("format").ToLocalChecked(),
|
Nan::Set(target, Nan::New("format").ToLocalChecked(),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <node.h>
|
#include <node.h>
|
||||||
#include <vips/vips.h>
|
#include <vips/vips.h>
|
||||||
|
#include <vips/vector.h>
|
||||||
|
|
||||||
#include "nan.h"
|
#include "nan.h"
|
||||||
|
|
||||||
@@ -81,6 +82,20 @@ NAN_METHOD(counters) {
|
|||||||
info.GetReturnValue().Set(counters);
|
info.GetReturnValue().Set(counters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get and set use of SIMD vector unit instructions
|
||||||
|
*/
|
||||||
|
NAN_METHOD(simd) {
|
||||||
|
HandleScope();
|
||||||
|
|
||||||
|
// Set state
|
||||||
|
if (info[0]->IsBoolean()) {
|
||||||
|
vips_vector_set_enabled(To<bool>(info[0]).FromJust());
|
||||||
|
}
|
||||||
|
// Get state
|
||||||
|
info.GetReturnValue().Set(New<Boolean>(vips_vector_isenabled()));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get libvips version
|
Get libvips version
|
||||||
*/
|
*/
|
||||||
|
|||||||
1
src/utilities.h
Executable file → Normal file
1
src/utilities.h
Executable file → Normal file
@@ -6,6 +6,7 @@
|
|||||||
NAN_METHOD(cache);
|
NAN_METHOD(cache);
|
||||||
NAN_METHOD(concurrency);
|
NAN_METHOD(concurrency);
|
||||||
NAN_METHOD(counters);
|
NAN_METHOD(counters);
|
||||||
|
NAN_METHOD(simd);
|
||||||
NAN_METHOD(libvipsVersion);
|
NAN_METHOD(libvipsVersion);
|
||||||
NAN_METHOD(format);
|
NAN_METHOD(format);
|
||||||
NAN_METHOD(_maxColourDistance);
|
NAN_METHOD(_maxColourDistance);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"gm": "^1.21.0",
|
"gm": "^1.21.0",
|
||||||
"imagemagick": "^0.1.3",
|
"imagemagick": "^0.1.3",
|
||||||
"imagemagick-native": "elad/node-imagemagick-native",
|
"imagemagick-native": "elad/node-imagemagick-native",
|
||||||
"jimp": "^0.2.19",
|
"jimp": "^0.2.20",
|
||||||
"lwip": "^0.0.8",
|
"lwip": "^0.0.8",
|
||||||
"semver": "^5.1.0"
|
"semver": "^5.1.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ var width = 720;
|
|||||||
var height = 480;
|
var height = 480;
|
||||||
|
|
||||||
sharp.concurrency(1);
|
sharp.concurrency(1);
|
||||||
|
sharp.simd(true);
|
||||||
|
|
||||||
var timer = setInterval(function() {
|
var timer = setInterval(function() {
|
||||||
console.dir(sharp.counters());
|
console.dir(sharp.counters());
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ var magickFilterBicubic = 'Lanczos';
|
|||||||
|
|
||||||
// Disable libvips cache to ensure tests are as fair as they can be
|
// Disable libvips cache to ensure tests are as fair as they can be
|
||||||
sharp.cache(0);
|
sharp.cache(0);
|
||||||
|
// Enable use of SIMD
|
||||||
|
sharp.simd(true);
|
||||||
|
|
||||||
async.series({
|
async.series({
|
||||||
'jpeg-linear': function(callback) {
|
'jpeg-linear': function(callback) {
|
||||||
@@ -496,6 +498,24 @@ async.series({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}).add('sharp-without-simd', {
|
||||||
|
defer: true,
|
||||||
|
fn: function(deferred) {
|
||||||
|
sharp.simd(false);
|
||||||
|
sharp(inputJpgBuffer)
|
||||||
|
.rotate(90)
|
||||||
|
.interpolateWith(sharp.interpolator.bilinear)
|
||||||
|
.resize(width, height)
|
||||||
|
.toBuffer(function(err, buffer) {
|
||||||
|
sharp.simd(true);
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
} else {
|
||||||
|
assert.notStrictEqual(null, buffer);
|
||||||
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}).add('sharp-sequentialRead', {
|
}).add('sharp-sequentialRead', {
|
||||||
defer: true,
|
defer: true,
|
||||||
fn: function(deferred) {
|
fn: function(deferred) {
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ var Benchmark = require('benchmark');
|
|||||||
var sharp = require('../../index');
|
var sharp = require('../../index');
|
||||||
var fixtures = require('../fixtures');
|
var fixtures = require('../fixtures');
|
||||||
|
|
||||||
|
sharp.simd(true);
|
||||||
|
|
||||||
var min = 320;
|
var min = 320;
|
||||||
var max = 960;
|
var max = 960;
|
||||||
|
|
||||||
|
|||||||
BIN
test/fixtures/expected/colourspace.cmyk-without-profile.jpg
vendored
Normal file
BIN
test/fixtures/expected/colourspace.cmyk-without-profile.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
test/fixtures/expected/colourspace.cmyk.jpg
vendored
Normal file
BIN
test/fixtures/expected/colourspace.cmyk.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -61,12 +61,12 @@ describe('Colour space conversion', function() {
|
|||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
.background('white')
|
.background('white')
|
||||||
.embed()
|
.embed()
|
||||||
.toFile(fixtures.path('output.cmyk2srgb.jpg'), function(err, info) {
|
.toBuffer(function(err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual('jpeg', info.format);
|
assert.strictEqual('jpeg', info.format);
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(320, info.width);
|
||||||
assert.strictEqual(240, info.height);
|
assert.strictEqual(240, info.height);
|
||||||
done();
|
fixtures.assertSimilar(fixtures.expected('colourspace.cmyk.jpg'), data, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -75,10 +75,9 @@ describe('Colour space conversion', function() {
|
|||||||
.resize(320)
|
.resize(320)
|
||||||
.toBuffer(function(err, data, info) {
|
.toBuffer(function(err, data, info) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(true, data.length > 0);
|
|
||||||
assert.strictEqual('jpeg', info.format);
|
assert.strictEqual('jpeg', info.format);
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(320, info.width);
|
||||||
done();
|
fixtures.assertSimilar(fixtures.expected('colourspace.cmyk-without-profile.jpg'), data, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,21 @@ describe('Utilities', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('SIMD', function() {
|
||||||
|
it('Can get current state', function() {
|
||||||
|
var simd = sharp.simd();
|
||||||
|
assert.strictEqual(typeof simd, 'boolean');
|
||||||
|
});
|
||||||
|
it('Can disable', function() {
|
||||||
|
var simd = sharp.simd(false);
|
||||||
|
assert.strictEqual(simd, false);
|
||||||
|
});
|
||||||
|
it('Can attempt to enable', function() {
|
||||||
|
var simd = sharp.simd(true);
|
||||||
|
assert.strictEqual(typeof simd, 'boolean');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Format', function() {
|
describe('Format', function() {
|
||||||
it('Contains expected attributes', function() {
|
it('Contains expected attributes', function() {
|
||||||
assert.strictEqual('object', typeof sharp.format);
|
assert.strictEqual('object', typeof sharp.format);
|
||||||
|
|||||||
Reference in New Issue
Block a user