mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Drop support for versions of Node prior to v4.
Reduce production (sub)depedency count from 93 to 50. Modernise dev tooling, e.g. use nyc, replace jshint with semistandard. Make 'npm test' command consistent across platforms.
This commit is contained in:
parent
3f5e38bb62
commit
36e636dca1
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,3 +14,4 @@ packaging/libvips*
|
||||
packaging/*.log
|
||||
!packaging/build
|
||||
.DS_Store
|
||||
.nyc_output
|
||||
|
@ -1,4 +0,0 @@
|
||||
node_modules
|
||||
test/bench/node_modules
|
||||
test/saliency/humanae/node_modules
|
||||
coverage
|
12
.jshintrc
12
.jshintrc
@ -1,12 +0,0 @@
|
||||
{
|
||||
"strict": true,
|
||||
"node": true,
|
||||
"maxparams": 4,
|
||||
"maxcomplexity": 14,
|
||||
"globals": {
|
||||
"beforeEach": true,
|
||||
"afterEach": true,
|
||||
"describe": true,
|
||||
"it": true
|
||||
}
|
||||
}
|
@ -14,3 +14,4 @@ lib
|
||||
include
|
||||
packaging
|
||||
preinstall.sh
|
||||
.nyc_output
|
||||
|
@ -1,9 +1,8 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.12"
|
||||
- "4"
|
||||
- "6"
|
||||
- "7"
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
@ -18,4 +17,5 @@ osx_image: xcode8
|
||||
before_install:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXX=g++-4.8; fi
|
||||
after_success:
|
||||
- npm install coveralls
|
||||
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
|
||||
|
@ -3,14 +3,13 @@ version: "{build}"
|
||||
build: off
|
||||
platform: x64
|
||||
environment:
|
||||
VIPS_WARNING: 0
|
||||
matrix:
|
||||
- nodejs_version: "0.12"
|
||||
- nodejs_version: "4"
|
||||
- nodejs_version: "6"
|
||||
- nodejs_version: "7"
|
||||
install:
|
||||
- ps: Install-Product node $env:nodejs_version x64
|
||||
- npm install -g npm@latest
|
||||
- npm install
|
||||
test_script:
|
||||
- npm run-script test-win
|
||||
- npm test
|
||||
|
126
binding.js
126
binding.js
@ -1,81 +1,58 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var zlib = require('zlib');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const zlib = require('zlib');
|
||||
|
||||
var semver = require('semver');
|
||||
var request = require('request');
|
||||
var tar = require('tar');
|
||||
const caw = require('caw');
|
||||
const got = require('got');
|
||||
const semver = require('semver');
|
||||
const tar = require('tar');
|
||||
|
||||
var tmp = require('os').tmpdir();
|
||||
|
||||
var distBaseUrl = 'https://dl.bintray.com/lovell/sharp/';
|
||||
const distBaseUrl = 'https://dl.bintray.com/lovell/sharp/';
|
||||
|
||||
// Use NPM-provided environment variable where available, falling back to require-based method for Electron
|
||||
var minimumLibvipsVersion = process.env.npm_package_config_libvips || require('./package.json').config.libvips;
|
||||
const minimumLibvipsVersion = process.env.npm_package_config_libvips || require('./package.json').config.libvips;
|
||||
|
||||
var vipsHeaderPath = path.join(__dirname, 'include', 'vips', 'vips.h');
|
||||
const platform = process.env.npm_config_platform || process.platform;
|
||||
|
||||
var platform = process.env.npm_config_platform || process.platform;
|
||||
|
||||
var arch = process.env.npm_config_arch || process.arch;
|
||||
var arm_version = process.env.npm_config_armv || process.config.variables.arm_version;
|
||||
|
||||
if (arch === 'arch64' || arch === 'armhf') {
|
||||
arch = 'arm';
|
||||
if (arch === 'arch64') arm_version = '8';
|
||||
}
|
||||
const arch = process.env.npm_config_arch || process.arch;
|
||||
|
||||
// -- Helpers
|
||||
|
||||
// Does this file exist?
|
||||
var isFile = function(file) {
|
||||
var exists = false;
|
||||
const isFile = function (file) {
|
||||
try {
|
||||
exists = fs.statSync(file).isFile();
|
||||
return fs.statSync(file).isFile();
|
||||
} catch (err) {}
|
||||
return exists;
|
||||
};
|
||||
|
||||
var unpack = function(tarPath, done) {
|
||||
var extractor = tar.Extract({
|
||||
path: __dirname
|
||||
});
|
||||
const unpack = function (tarPath, done) {
|
||||
const extractor = tar.Extract({ path: __dirname });
|
||||
if (done) {
|
||||
extractor.on('end', done);
|
||||
}
|
||||
extractor.on('error', error);
|
||||
extractor.on('end', function() {
|
||||
if (!isFile(vipsHeaderPath)) {
|
||||
error('Could not unpack ' + tarPath);
|
||||
}
|
||||
if (typeof done === 'function') {
|
||||
done();
|
||||
}
|
||||
});
|
||||
fs.createReadStream(tarPath).on('error', error)
|
||||
fs.createReadStream(tarPath)
|
||||
.on('error', error)
|
||||
.pipe(zlib.Unzip())
|
||||
.pipe(extractor);
|
||||
};
|
||||
|
||||
var platformId = function() {
|
||||
var id = [platform, arch].join('-');
|
||||
if (arch === 'arm') {
|
||||
switch(arm_version) {
|
||||
case '8':
|
||||
id = id + 'v8';
|
||||
break;
|
||||
case '7':
|
||||
id = id + 'v7';
|
||||
break;
|
||||
default:
|
||||
id = id + 'v6';
|
||||
break;
|
||||
const platformId = function () {
|
||||
const platformId = [platform];
|
||||
if (arch === 'arm' || arch === 'armhf' || arch === 'arch64') {
|
||||
const armVersion = (arch === 'arch64') ? '8' : process.env.npm_config_armv || process.config.variables.arm_version || '6';
|
||||
platformId.push('armv' + armVersion);
|
||||
} else {
|
||||
platformId.push(arch);
|
||||
}
|
||||
}
|
||||
return id;
|
||||
return platformId.join('-');
|
||||
};
|
||||
|
||||
// Error
|
||||
var error = function(msg) {
|
||||
const error = function (msg) {
|
||||
if (msg instanceof Error) {
|
||||
msg = msg.message;
|
||||
}
|
||||
@ -87,16 +64,17 @@ var error = function(msg) {
|
||||
|
||||
module.exports.download_vips = function () {
|
||||
// Has vips been installed locally?
|
||||
const vipsHeaderPath = path.join(__dirname, 'include', 'vips', 'vips.h');
|
||||
if (!isFile(vipsHeaderPath)) {
|
||||
// Ensure Intel 64-bit or ARM
|
||||
if (arch === 'ia32') {
|
||||
error('Intel Architecture 32-bit systems require manual installation - please see http://sharp.dimens.io/en/stable/install/');
|
||||
}
|
||||
// Ensure glibc >= 2.15
|
||||
var lddVersion = process.env.LDD_VERSION;
|
||||
const lddVersion = process.env.LDD_VERSION;
|
||||
if (lddVersion) {
|
||||
if (/(glibc|gnu libc)/i.test(lddVersion)) {
|
||||
var glibcVersion = lddVersion ? lddVersion.split(/\n/)[0].split(' ').slice(-1)[0].trim() : '';
|
||||
const glibcVersion = lddVersion ? lddVersion.split(/\n/)[0].split(' ').slice(-1)[0].trim() : '';
|
||||
if (glibcVersion && semver.lt(glibcVersion + '.0', '2.13.0')) {
|
||||
error('glibc version ' + glibcVersion + ' requires manual installation - please see http://sharp.dimens.io/en/stable/install/');
|
||||
}
|
||||
@ -105,47 +83,47 @@ module.exports.download_vips = function() {
|
||||
}
|
||||
}
|
||||
// Arch/platform-specific .tar.gz
|
||||
var tarFilename = ['libvips', minimumLibvipsVersion, platformId()].join('-') + '.tar.gz';
|
||||
var tarPath = path.join(__dirname, 'packaging', tarFilename);
|
||||
if (isFile(tarPath)) {
|
||||
unpack(tarPath);
|
||||
const tarFilename = ['libvips', minimumLibvipsVersion, platformId()].join('-') + '.tar.gz';
|
||||
const tarPathLocal = path.join(__dirname, 'packaging', tarFilename);
|
||||
if (isFile(tarPathLocal)) {
|
||||
unpack(tarPathLocal);
|
||||
} else {
|
||||
// Download to per-process temporary file
|
||||
tarPath = path.join(tmp, process.pid + '-' + tarFilename);
|
||||
var tmpFile = fs.createWriteStream(tarPath).on('finish', function() {
|
||||
unpack(tarPath, function() {
|
||||
const tarPathTemp = path.join(os.tmpdir(), process.pid + '-' + tarFilename);
|
||||
const tmpFile = fs.createWriteStream(tarPathTemp).on('finish', function () {
|
||||
unpack(tarPathTemp, function () {
|
||||
// Attempt to remove temporary file
|
||||
try {
|
||||
fs.unlinkSync(tarPath);
|
||||
fs.unlinkSync(tarPathTemp);
|
||||
} catch (err) {}
|
||||
});
|
||||
});
|
||||
var options = {
|
||||
url: distBaseUrl + tarFilename
|
||||
};
|
||||
const gotOpt = {};
|
||||
if (process.env.npm_config_https_proxy) {
|
||||
// Use the NPM-configured HTTPS proxy
|
||||
options.proxy = process.env.npm_config_https_proxy;
|
||||
gotOpt.agent = caw(process.env.npm_config_https_proxy);
|
||||
}
|
||||
request(options).on('response', function(response) {
|
||||
const url = distBaseUrl + tarFilename;
|
||||
got.stream(url, gotOpt).on('response', function (response) {
|
||||
if (response.statusCode !== 200) {
|
||||
error(distBaseUrl + tarFilename + ' status code ' + response.statusCode);
|
||||
error(url + ' status code ' + response.statusCode);
|
||||
}
|
||||
}).on('error', function (err) {
|
||||
error('Download from ' + distBaseUrl + tarFilename + ' failed: ' + err.message);
|
||||
error('Download of ' + url + ' failed: ' + err.message);
|
||||
}).pipe(tmpFile);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.use_global_vips = function () {
|
||||
var useGlobalVips = false;
|
||||
var globalVipsVersion = process.env.GLOBAL_VIPS_VERSION;
|
||||
const globalVipsVersion = process.env.GLOBAL_VIPS_VERSION;
|
||||
if (globalVipsVersion) {
|
||||
useGlobalVips = semver.gte(
|
||||
const useGlobalVips = semver.gte(
|
||||
globalVipsVersion,
|
||||
minimumLibvipsVersion
|
||||
);
|
||||
}
|
||||
process.stdout.write(useGlobalVips ? 'true' : 'false');
|
||||
} else {
|
||||
process.stdout.write('false');
|
||||
}
|
||||
};
|
||||
|
@ -2,10 +2,12 @@
|
||||
|
||||
### v0.17 - "*quill*"
|
||||
|
||||
Requires libvips v8.4.2
|
||||
Requires libvips v8.4.2.
|
||||
|
||||
#### v0.17.0 - TBD
|
||||
|
||||
* Drop support for versions of Node prior to v4.
|
||||
|
||||
* Deprecate the following output format "option" functions:
|
||||
quality, progressive, compressionLevel, withoutAdaptiveFiltering,
|
||||
withoutChromaSubsampling, trellisQuantisation, trellisQuantization,
|
||||
|
105
index.js
105
index.js
@ -1,23 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var util = require('util');
|
||||
var stream = require('stream');
|
||||
var events = require('events');
|
||||
const path = require('path');
|
||||
const util = require('util');
|
||||
const stream = require('stream');
|
||||
const events = require('events');
|
||||
|
||||
var semver = require('semver');
|
||||
var color = require('color');
|
||||
var BluebirdPromise = require('bluebird');
|
||||
const semver = require('semver');
|
||||
const color = require('color');
|
||||
|
||||
var sharp = require('./build/Release/sharp.node');
|
||||
const sharp = require('./build/Release/sharp.node');
|
||||
|
||||
// Versioning
|
||||
var versions = {
|
||||
let versions = {
|
||||
vips: sharp.libvipsVersion()
|
||||
};
|
||||
(function () {
|
||||
// Does libvips meet minimum requirement?
|
||||
var libvipsVersionMin = require('./package.json').config.libvips;
|
||||
const libvipsVersionMin = require('./package.json').config.libvips;
|
||||
if (semver.lt(versions.vips, libvipsVersionMin)) {
|
||||
throw new Error('Found libvips ' + versions.vips + ' but require at least ' + libvipsVersionMin);
|
||||
}
|
||||
@ -28,14 +27,14 @@ var versions = {
|
||||
})();
|
||||
|
||||
// Limits
|
||||
var maximum = {
|
||||
const maximum = {
|
||||
width: 0x3FFF,
|
||||
height: 0x3FFF,
|
||||
pixels: Math.pow(0x3FFF, 2)
|
||||
};
|
||||
|
||||
// Constructor-factory
|
||||
var Sharp = function(input, options) {
|
||||
const Sharp = function (input, options) {
|
||||
if (!(this instanceof Sharp)) {
|
||||
return new Sharp(input, options);
|
||||
}
|
||||
@ -144,34 +143,34 @@ module.exports.versions = versions;
|
||||
/*
|
||||
Validation helpers
|
||||
*/
|
||||
var isDefined = function(val) {
|
||||
const isDefined = function (val) {
|
||||
return typeof val !== 'undefined' && val !== null;
|
||||
};
|
||||
var isObject = function(val) {
|
||||
const isObject = function (val) {
|
||||
return typeof val === 'object';
|
||||
};
|
||||
var isFunction = function(val) {
|
||||
const isFunction = function (val) {
|
||||
return typeof val === 'function';
|
||||
};
|
||||
var isBoolean = function(val) {
|
||||
const isBoolean = function (val) {
|
||||
return typeof val === 'boolean';
|
||||
};
|
||||
var isBuffer = function(val) {
|
||||
const isBuffer = function (val) {
|
||||
return typeof val === 'object' && val instanceof Buffer;
|
||||
};
|
||||
var isString = function(val) {
|
||||
const isString = function (val) {
|
||||
return typeof val === 'string' && val.length > 0;
|
||||
};
|
||||
var isNumber = function(val) {
|
||||
const isNumber = function (val) {
|
||||
return typeof val === 'number' && !Number.isNaN(val);
|
||||
};
|
||||
var isInteger = function(val) {
|
||||
const isInteger = function (val) {
|
||||
return isNumber(val) && val % 1 === 0;
|
||||
};
|
||||
var inRange = function(val, min, max) {
|
||||
const inRange = function (val, min, max) {
|
||||
return val >= min && val <= max;
|
||||
};
|
||||
var contains = function(val, list) {
|
||||
const contains = function (val, list) {
|
||||
return list.indexOf(val) !== -1;
|
||||
};
|
||||
|
||||
@ -179,7 +178,7 @@ var contains = function(val, list) {
|
||||
Create Object containing input and input-related options
|
||||
*/
|
||||
Sharp.prototype._createInputDescriptor = function (input, inputOptions, containerOptions) {
|
||||
var inputDescriptor = {};
|
||||
const inputDescriptor = {};
|
||||
if (isString(input)) {
|
||||
// filesystem
|
||||
inputDescriptor.file = input;
|
||||
@ -226,7 +225,6 @@ Sharp.prototype._createInputDescriptor = function(input, inputOptions, container
|
||||
Handle incoming chunk on Writable Stream
|
||||
*/
|
||||
Sharp.prototype._write = function (chunk, encoding, callback) {
|
||||
/*jslint unused: false */
|
||||
if (Array.isArray(this.options.input.buffer)) {
|
||||
if (isBuffer(chunk)) {
|
||||
this.options.input.buffer.push(chunk);
|
||||
@ -295,9 +293,9 @@ Sharp.prototype.crop = function(crop) {
|
||||
};
|
||||
|
||||
Sharp.prototype.extract = function (options) {
|
||||
var suffix = this.options.width === -1 && this.options.height === -1 ? 'Pre' : 'Post';
|
||||
const suffix = this.options.width === -1 && this.options.height === -1 ? 'Pre' : 'Post';
|
||||
['left', 'top', 'width', 'height'].forEach(function (name) {
|
||||
var value = options[name];
|
||||
const value = options[name];
|
||||
if (isInteger(value) && value >= 0) {
|
||||
this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value;
|
||||
} else {
|
||||
@ -312,12 +310,13 @@ Sharp.prototype.extract = function(options) {
|
||||
};
|
||||
|
||||
Sharp.prototype.extractChannel = function (channel) {
|
||||
if (channel === 'red')
|
||||
if (channel === 'red') {
|
||||
channel = 0;
|
||||
else if (channel === 'green')
|
||||
} else if (channel === 'green') {
|
||||
channel = 1;
|
||||
else if (channel === 'blue')
|
||||
} else if (channel === 'blue') {
|
||||
channel = 2;
|
||||
}
|
||||
if (isInteger(channel) && inRange(channel, 0, 4)) {
|
||||
this.options.extractChannel = channel;
|
||||
} else {
|
||||
@ -332,7 +331,7 @@ Sharp.prototype.extractChannel = function(channel) {
|
||||
but is liberal in what it accepts, clamping values to sensible min/max.
|
||||
*/
|
||||
Sharp.prototype.background = function (rgba) {
|
||||
var colour = color(rgba);
|
||||
const colour = color(rgba);
|
||||
this.options.background = colour.rgbArray();
|
||||
this.options.background.push(colour.alpha() * 255);
|
||||
return this;
|
||||
@ -514,7 +513,7 @@ Sharp.prototype.convolve = function(kernel) {
|
||||
if (!isObject(kernel) || !Array.isArray(kernel.kernel) ||
|
||||
!isInteger(kernel.width) || !isInteger(kernel.height) ||
|
||||
!inRange(kernel.width, 3, 1001) || !inRange(kernel.height, 3, 1001) ||
|
||||
kernel.height * kernel.width != kernel.kernel.length
|
||||
kernel.height * kernel.width !== kernel.kernel.length
|
||||
) {
|
||||
// must pass in a kernel
|
||||
throw new Error('Invalid convolution kernel');
|
||||
@ -675,52 +674,52 @@ Sharp.prototype.sequentialRead = function(sequentialRead) {
|
||||
|
||||
// Deprecated output options
|
||||
Sharp.prototype.quality = util.deprecate(function (quality) {
|
||||
var formatOut = this.options.formatOut;
|
||||
var options = { quality: quality };
|
||||
const formatOut = this.options.formatOut;
|
||||
const options = { quality: quality };
|
||||
this.jpeg(options).webp(options).tiff(options);
|
||||
this.options.formatOut = formatOut;
|
||||
return this;
|
||||
}, 'quality: use jpeg({ quality: ... }), webp({ quality: ... }) and/or tiff({ quality: ... }) instead');
|
||||
Sharp.prototype.progressive = util.deprecate(function (progressive) {
|
||||
var formatOut = this.options.formatOut;
|
||||
var options = { progressive: (progressive !== false) };
|
||||
const formatOut = this.options.formatOut;
|
||||
const options = { progressive: (progressive !== false) };
|
||||
this.jpeg(options).png(options);
|
||||
this.options.formatOut = formatOut;
|
||||
return this;
|
||||
}, 'progressive: use jpeg({ progressive: ... }) and/or png({ progressive: ... }) instead');
|
||||
Sharp.prototype.compressionLevel = util.deprecate(function (compressionLevel) {
|
||||
var formatOut = this.options.formatOut;
|
||||
const formatOut = this.options.formatOut;
|
||||
this.png({ compressionLevel: compressionLevel });
|
||||
this.options.formatOut = formatOut;
|
||||
return this;
|
||||
}, 'compressionLevel: use png({ compressionLevel: ... }) instead');
|
||||
Sharp.prototype.withoutAdaptiveFiltering = util.deprecate(function (withoutAdaptiveFiltering) {
|
||||
var formatOut = this.options.formatOut;
|
||||
const formatOut = this.options.formatOut;
|
||||
this.png({ adaptiveFiltering: (withoutAdaptiveFiltering === false) });
|
||||
this.options.formatOut = formatOut;
|
||||
return this;
|
||||
}, 'withoutAdaptiveFiltering: use png({ adaptiveFiltering: ... }) instead');
|
||||
Sharp.prototype.withoutChromaSubsampling = util.deprecate(function (withoutChromaSubsampling) {
|
||||
var formatOut = this.options.formatOut;
|
||||
const formatOut = this.options.formatOut;
|
||||
this.jpeg({ chromaSubsampling: (withoutChromaSubsampling === false) ? '4:2:0' : '4:4:4' });
|
||||
this.options.formatOut = formatOut;
|
||||
return this;
|
||||
}, 'withoutChromaSubsampling: use jpeg({ chromaSubsampling: "4:4:4" }) instead');
|
||||
Sharp.prototype.trellisQuantisation = util.deprecate(function (trellisQuantisation) {
|
||||
var formatOut = this.options.formatOut;
|
||||
const formatOut = this.options.formatOut;
|
||||
this.jpeg({ trellisQuantisation: (trellisQuantisation !== false) });
|
||||
this.options.formatOut = formatOut;
|
||||
return this;
|
||||
}, 'trellisQuantisation: use jpeg({ trellisQuantisation: ... }) instead');
|
||||
Sharp.prototype.trellisQuantization = Sharp.prototype.trellisQuantisation;
|
||||
Sharp.prototype.overshootDeringing = util.deprecate(function (overshootDeringing) {
|
||||
var formatOut = this.options.formatOut;
|
||||
const formatOut = this.options.formatOut;
|
||||
this.jpeg({ overshootDeringing: (overshootDeringing !== false) });
|
||||
this.options.formatOut = formatOut;
|
||||
return this;
|
||||
}, 'overshootDeringing: use jpeg({ overshootDeringing: ... }) instead');
|
||||
Sharp.prototype.optimiseScans = util.deprecate(function (optimiseScans) {
|
||||
var formatOut = this.options.formatOut;
|
||||
const formatOut = this.options.formatOut;
|
||||
this.jpeg({ optimiseScans: (optimiseScans !== false) });
|
||||
this.options.formatOut = formatOut;
|
||||
return this;
|
||||
@ -920,19 +919,19 @@ Sharp.prototype.limitInputPixels = function(limit) {
|
||||
*/
|
||||
Sharp.prototype.toFile = function (fileOut, callback) {
|
||||
if (!fileOut || fileOut.length === 0) {
|
||||
var errOutputInvalid = new Error('Invalid output');
|
||||
const errOutputInvalid = new Error('Invalid output');
|
||||
if (isFunction(callback)) {
|
||||
callback(errOutputInvalid);
|
||||
} else {
|
||||
return BluebirdPromise.reject(errOutputInvalid);
|
||||
return Promise.reject(errOutputInvalid);
|
||||
}
|
||||
} else {
|
||||
if (this.options.input.file === fileOut) {
|
||||
var errOutputIsInput = new Error('Cannot use same file for input and output');
|
||||
const errOutputIsInput = new Error('Cannot use same file for input and output');
|
||||
if (isFunction(callback)) {
|
||||
callback(errOutputIsInput);
|
||||
} else {
|
||||
return BluebirdPromise.reject(errOutputIsInput);
|
||||
return Promise.reject(errOutputIsInput);
|
||||
}
|
||||
} else {
|
||||
this.options.fileOut = fileOut;
|
||||
@ -1141,7 +1140,7 @@ Sharp.prototype._read = function() {
|
||||
Supports callback, stream and promise variants
|
||||
*/
|
||||
Sharp.prototype._pipeline = function (callback) {
|
||||
var that = this;
|
||||
const that = this;
|
||||
if (typeof callback === 'function') {
|
||||
// output=file/buffer
|
||||
if (this._isStreamInput()) {
|
||||
@ -1188,7 +1187,7 @@ Sharp.prototype._pipeline = function(callback) {
|
||||
// output=promise
|
||||
if (this._isStreamInput()) {
|
||||
// output=promise, input=stream
|
||||
return new BluebirdPromise(function(resolve, reject) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
that.on('finish', function () {
|
||||
that._flattenBufferIn();
|
||||
sharp.pipeline(that.options, function (err, data) {
|
||||
@ -1202,7 +1201,7 @@ Sharp.prototype._pipeline = function(callback) {
|
||||
});
|
||||
} else {
|
||||
// output=promise, input=file/buffer
|
||||
return new BluebirdPromise(function(resolve, reject) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
sharp.pipeline(that.options, function (err, data) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
@ -1220,7 +1219,7 @@ Sharp.prototype._pipeline = function(callback) {
|
||||
Supports callback, stream and promise variants
|
||||
*/
|
||||
Sharp.prototype.metadata = function (callback) {
|
||||
var that = this;
|
||||
const that = this;
|
||||
if (typeof callback === 'function') {
|
||||
if (this._isStreamInput()) {
|
||||
this.on('finish', function () {
|
||||
@ -1233,7 +1232,7 @@ Sharp.prototype.metadata = function(callback) {
|
||||
return this;
|
||||
} else {
|
||||
if (this._isStreamInput()) {
|
||||
return new BluebirdPromise(function(resolve, reject) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
that.on('finish', function () {
|
||||
that._flattenBufferIn();
|
||||
sharp.metadata(that.options, function (err, metadata) {
|
||||
@ -1246,7 +1245,7 @@ Sharp.prototype.metadata = function(callback) {
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return new BluebirdPromise(function(resolve, reject) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
sharp.metadata(that.options, function (err, metadata) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
@ -1264,9 +1263,9 @@ Sharp.prototype.metadata = function(callback) {
|
||||
Cloned instances share the same input.
|
||||
*/
|
||||
Sharp.prototype.clone = function () {
|
||||
var that = this;
|
||||
const that = this;
|
||||
// Clone existing options
|
||||
var clone = new Sharp();
|
||||
const clone = new Sharp();
|
||||
util._extend(clone.options, this.options);
|
||||
// Pass 'finish' event to clone for Stream-based input
|
||||
this.on('finish', function () {
|
||||
|
28
package.json
28
package.json
@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "sharp",
|
||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
||||
"version": "0.17.0",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"contributors": [
|
||||
@ -29,14 +30,11 @@
|
||||
"Matt Hirsch <mhirsch@media.mit.edu>",
|
||||
"Matthias Thoemmes <thoemmes@gmail.com>"
|
||||
],
|
||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
||||
"scripts": {
|
||||
"clean": "rm -rf node_modules/ build/ include/ lib/ coverage/ test/fixtures/output.*",
|
||||
"test": "VIPS_WARNING=0 node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- --slow=5000 --timeout=30000 ./test/unit/*.js",
|
||||
"test-win": "node ./node_modules/mocha/bin/mocha --slow=5000 --timeout=60000 ./test/unit/*.js",
|
||||
"test": "semistandard && cross-env VIPS_WARNING=0 nyc --reporter=lcov --branches=96 mocha --slow=5000 --timeout=60000 ./test/unit/*.js",
|
||||
"test-leak": "./test/leak/leak.sh",
|
||||
"test-packaging": "./packaging/test-linux-x64.sh",
|
||||
"test-clean": "rm -rf coverage/ test/fixtures/output.* && npm install && npm test"
|
||||
"test-packaging": "./packaging/test-linux-x64.sh"
|
||||
},
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@ -59,24 +57,24 @@
|
||||
"vips"
|
||||
],
|
||||
"dependencies": {
|
||||
"bluebird": "^3.4.6",
|
||||
"caw": "^2.0.0",
|
||||
"color": "^0.11.3",
|
||||
"got": "^6.5.0",
|
||||
"nan": "^2.4.0",
|
||||
"semver": "^5.3.0",
|
||||
"request": "^2.75.0",
|
||||
"tar": "^2.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"async": "^2.1.2",
|
||||
"bufferutil": "^1.2.1",
|
||||
"coveralls": "^2.11.14",
|
||||
"cross-env": "^3.1.3",
|
||||
"exif-reader": "^1.0.1",
|
||||
"icc": "^0.0.2",
|
||||
"istanbul": "^0.4.5",
|
||||
"mocha": "^3.1.2",
|
||||
"mocha-jshint": "^2.3.1",
|
||||
"node-cpplint": "^0.4.0",
|
||||
"nyc": "^8.3.2",
|
||||
"rimraf": "^2.5.4",
|
||||
"semistandard": "^9.1.0",
|
||||
"unzip": "^0.1.11"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
@ -84,6 +82,14 @@
|
||||
"libvips": "8.4.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
"node": ">=4"
|
||||
},
|
||||
"semistandard": {
|
||||
"env": [
|
||||
"mocha"
|
||||
],
|
||||
"ignore": [
|
||||
"test"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
28
test/fixtures/index.js
vendored
28
test/fixtures/index.js
vendored
@ -1,18 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var maxColourDistance = require('../../build/Release/sharp')._maxColourDistance;
|
||||
const path = require('path');
|
||||
const sharp = require('../../index');
|
||||
const maxColourDistance = require('../../build/Release/sharp')._maxColourDistance;
|
||||
|
||||
// Helpers
|
||||
var getPath = function(filename) {
|
||||
const getPath = function (filename) {
|
||||
return path.join(__dirname, filename);
|
||||
};
|
||||
|
||||
// Generates a 64-bit-as-binary-string image fingerprint
|
||||
// Based on the dHash gradient method - see http://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html
|
||||
var fingerprint = function(image, callback) {
|
||||
const fingerprint = function (image, callback) {
|
||||
sharp(image)
|
||||
.greyscale()
|
||||
.normalise()
|
||||
@ -23,12 +22,11 @@ var fingerprint = function(image, callback) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
var fingerprint = '';
|
||||
for (var col = 0; col < 8; col++) {
|
||||
var gradient = 0;
|
||||
for (var row = 0; row < 8; row++) {
|
||||
var left = data[row * 8 + col];
|
||||
var right = data[row * 8 + col + 1];
|
||||
let fingerprint = '';
|
||||
for (let col = 0; col < 8; col++) {
|
||||
for (let row = 0; row < 8; row++) {
|
||||
const left = data[row * 8 + col];
|
||||
const right = data[row * 8 + col + 1];
|
||||
fingerprint = fingerprint + (left < right ? '1' : '0');
|
||||
}
|
||||
}
|
||||
@ -142,8 +140,8 @@ module.exports = {
|
||||
if (err) return callback(err);
|
||||
fingerprint(actualImage, function (err, actualFingerprint) {
|
||||
if (err) return callback(err);
|
||||
var distance = 0;
|
||||
for (var i = 0; i < 64; i++) {
|
||||
let distance = 0;
|
||||
for (let i = 0; i < 64; i++) {
|
||||
if (expectedFingerprint[i] !== actualFingerprint[i]) {
|
||||
distance++;
|
||||
}
|
||||
@ -169,7 +167,7 @@ module.exports = {
|
||||
// Default threshold
|
||||
acceptedDistance = 1;
|
||||
}
|
||||
var distance = maxColourDistance(actualImagePath, expectedImagePath);
|
||||
const distance = maxColourDistance(actualImagePath, expectedImagePath);
|
||||
if (distance > acceptedDistance) {
|
||||
throw new Error('Expected maximum absolute distance of ' + acceptedDistance + ', actual ' + distance);
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var fs = require('fs');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
var BluebirdPromise = require('bluebird');
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
|
||||
const sharp = require('../../index');
|
||||
const fixtures = require('../fixtures');
|
||||
|
||||
describe('Image channel insertion', function () {
|
||||
|
||||
it('Grayscale to RGB, buffer', function (done) {
|
||||
sharp(fixtures.inputPng) // gray -> red
|
||||
.resize(320, 240)
|
||||
@ -86,7 +85,7 @@ describe('Image channel insertion', function() {
|
||||
});
|
||||
|
||||
it('Join raw buffers to RGB', function (done) {
|
||||
BluebirdPromise.all([
|
||||
Promise.all([
|
||||
sharp(fixtures.inputPngTestJoinChannel).toColourspace('b-w').raw().toBuffer(),
|
||||
sharp(fixtures.inputPngStripesH).toColourspace('b-w').raw().toBuffer()
|
||||
])
|
||||
@ -147,5 +146,4 @@ describe('Image channel insertion', function() {
|
||||
.joinChannel();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1 +0,0 @@
|
||||
require('mocha-jshint')();
|
@ -1,23 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const assert = require('assert');
|
||||
|
||||
var async = require('async');
|
||||
var rimraf = require('rimraf');
|
||||
var unzip = require('unzip');
|
||||
const eachLimit = require('async/eachLimit');
|
||||
const rimraf = require('rimraf');
|
||||
const unzip = require('unzip');
|
||||
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
const sharp = require('../../index');
|
||||
const fixtures = require('../fixtures');
|
||||
|
||||
// Verifies all tiles in a given dz output directory are <= size
|
||||
var assertDeepZoomTiles = function(directory, expectedSize, expectedLevels, done) {
|
||||
const assertDeepZoomTiles = function (directory, expectedSize, expectedLevels, done) {
|
||||
// Get levels
|
||||
var levels = fs.readdirSync(directory);
|
||||
const levels = fs.readdirSync(directory);
|
||||
assert.strictEqual(expectedLevels, levels.length);
|
||||
// Get tiles
|
||||
var tiles = [];
|
||||
const tiles = [];
|
||||
levels.forEach(function (level) {
|
||||
// Verify level directory name
|
||||
assert.strictEqual(true, /^[0-9]+$/.test(level));
|
||||
@ -28,7 +28,7 @@ var assertDeepZoomTiles = function(directory, expectedSize, expectedLevels, done
|
||||
});
|
||||
});
|
||||
// Verify each tile is <= expectedSize
|
||||
async.eachSeries(tiles, function(tile, done) {
|
||||
eachLimit(tiles, 8, function (tile, done) {
|
||||
sharp(tile).metadata(function (err, metadata) {
|
||||
if (err) {
|
||||
done(err);
|
||||
@ -47,7 +47,6 @@ var assertDeepZoomTiles = function(directory, expectedSize, expectedLevels, done
|
||||
};
|
||||
|
||||
describe('Tile', function () {
|
||||
|
||||
it('Valid size values pass', function () {
|
||||
[1, 8192].forEach(function (size) {
|
||||
assert.doesNotThrow(function () {
|
||||
@ -142,9 +141,8 @@ describe('Tile', function() {
|
||||
});
|
||||
|
||||
if (sharp.format.dz.output.file) {
|
||||
|
||||
it('Deep Zoom layout', function (done) {
|
||||
var directory = fixtures.path('output.dzi_files');
|
||||
const directory = fixtures.path('output.dzi_files');
|
||||
rimraf(directory, function () {
|
||||
sharp(fixtures.inputJpg)
|
||||
.toFile(fixtures.path('output.dzi'), function (err, info) {
|
||||
@ -156,7 +154,7 @@ describe('Tile', function() {
|
||||
});
|
||||
|
||||
it('Deep Zoom layout with custom size+overlap', function (done) {
|
||||
var directory = fixtures.path('output.512.dzi_files');
|
||||
const directory = fixtures.path('output.512.dzi_files');
|
||||
rimraf(directory, function () {
|
||||
sharp(fixtures.inputJpg)
|
||||
.tile({
|
||||
@ -172,7 +170,7 @@ describe('Tile', function() {
|
||||
});
|
||||
|
||||
it('Zoomify layout', function (done) {
|
||||
var directory = fixtures.path('output.zoomify.dzi');
|
||||
const directory = fixtures.path('output.zoomify.dzi');
|
||||
rimraf(directory, function () {
|
||||
sharp(fixtures.inputJpg)
|
||||
.tile({
|
||||
@ -192,7 +190,7 @@ describe('Tile', function() {
|
||||
});
|
||||
|
||||
it('Google layout', function (done) {
|
||||
var directory = fixtures.path('output.google.dzi');
|
||||
const directory = fixtures.path('output.google.dzi');
|
||||
rimraf(directory, function () {
|
||||
sharp(fixtures.inputJpg)
|
||||
.tile({
|
||||
@ -212,9 +210,9 @@ describe('Tile', function() {
|
||||
});
|
||||
|
||||
it('Write to ZIP container using file extension', function (done) {
|
||||
var container = fixtures.path('output.dz.container.zip');
|
||||
var extractTo = fixtures.path('output.dz.container');
|
||||
var directory = path.join(extractTo, 'output.dz.container_files');
|
||||
const container = fixtures.path('output.dz.container.zip');
|
||||
const extractTo = fixtures.path('output.dz.container');
|
||||
const directory = path.join(extractTo, 'output.dz.container_files');
|
||||
rimraf(directory, function () {
|
||||
sharp(fixtures.inputJpg)
|
||||
.toFile(container, function (err, info) {
|
||||
@ -236,9 +234,9 @@ describe('Tile', function() {
|
||||
});
|
||||
|
||||
it('Write to ZIP container using container tile option', function (done) {
|
||||
var container = fixtures.path('output.dz.containeropt.zip');
|
||||
var extractTo = fixtures.path('output.dz.containeropt');
|
||||
var directory = path.join(extractTo, 'output.dz.containeropt_files');
|
||||
const container = fixtures.path('output.dz.containeropt.zip');
|
||||
const extractTo = fixtures.path('output.dz.containeropt');
|
||||
const directory = path.join(extractTo, 'output.dz.containeropt_files');
|
||||
rimraf(directory, function () {
|
||||
sharp(fixtures.inputJpg)
|
||||
.tile({
|
||||
@ -262,7 +260,5 @@ describe('Tile', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user