sharp 0.20.8 → 0.21.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -11
- package/binding.gyp +16 -1
- package/docs/api-channel.md +16 -0
- package/docs/api-colour.md +1 -19
- package/docs/api-composite.md +2 -3
- package/docs/api-constructor.md +2 -3
- package/docs/api-input.md +7 -2
- package/docs/api-operation.md +73 -115
- package/docs/api-output.md +9 -0
- package/docs/api-resize.md +160 -108
- package/docs/api-utility.md +4 -7
- package/docs/changelog.md +102 -0
- package/docs/image/sharp-logo.svg +5 -0
- package/docs/index.md +12 -6
- package/docs/install.md +41 -42
- package/docs/performance.md +14 -21
- package/install/libvips.js +28 -24
- package/lib/channel.js +20 -4
- package/lib/colour.js +35 -18
- package/lib/composite.js +2 -3
- package/lib/constructor.js +27 -42
- package/lib/input.js +9 -6
- package/lib/libvips.js +7 -1
- package/lib/operation.js +81 -123
- package/lib/output.js +128 -60
- package/lib/platform.js +4 -1
- package/lib/resize.js +310 -107
- package/lib/utility.js +5 -8
- package/package.json +30 -21
- package/src/common.cc +59 -14
- package/src/common.h +15 -12
- package/src/libvips/cplusplus/VImage.cpp +95 -95
- package/src/libvips/cplusplus/vips-operators.cpp +268 -185
- package/src/metadata.cc +34 -1
- package/src/metadata.h +10 -1
- package/src/operations.cc +47 -49
- package/src/operations.h +13 -2
- package/src/pipeline.cc +101 -95
- package/src/pipeline.h +40 -14
- package/src/sharp.cc +1 -1
- package/src/stats.cc +1 -1
- package/src/stats.h +1 -1
- package/src/utilities.cc +2 -2
- package/src/utilities.h +1 -1
package/lib/libvips.js
CHANGED
|
@@ -44,10 +44,16 @@ const globalLibvipsVersion = function () {
|
|
|
44
44
|
|
|
45
45
|
const hasVendoredLibvips = function () {
|
|
46
46
|
const currentPlatformId = platform();
|
|
47
|
+
const vendorPath = path.join(__dirname, '..', 'vendor');
|
|
48
|
+
let vendorVersionId;
|
|
47
49
|
let vendorPlatformId;
|
|
48
50
|
try {
|
|
49
|
-
|
|
51
|
+
vendorVersionId = require(path.join(vendorPath, 'versions.json')).vips;
|
|
52
|
+
vendorPlatformId = require(path.join(vendorPath, 'platform.json'));
|
|
50
53
|
} catch (err) {}
|
|
54
|
+
if (vendorVersionId && vendorVersionId !== minimumLibvipsVersion) {
|
|
55
|
+
throw new Error(`Found vendored libvips v${vendorVersionId} but require v${minimumLibvipsVersion}. Please remove the 'node_modules/sharp/vendor' directory and run 'npm install'.`);
|
|
56
|
+
}
|
|
51
57
|
if (vendorPlatformId) {
|
|
52
58
|
if (currentPlatformId === vendorPlatformId) {
|
|
53
59
|
return true;
|
package/lib/operation.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const color = require('color');
|
|
3
4
|
const is = require('./is');
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Rotate the output image by either an explicit angle
|
|
7
8
|
* or auto-orient based on the EXIF `Orientation` tag.
|
|
8
9
|
*
|
|
9
|
-
* If an angle is provided, it is converted to a valid
|
|
10
|
+
* If an angle is provided, it is converted to a valid positive degree rotation.
|
|
10
11
|
* For example, `-450` will produce a 270deg rotation.
|
|
11
12
|
*
|
|
13
|
+
* When rotating by an angle other than a multiple of 90,
|
|
14
|
+
* the background colour can be provided with the `background` option.
|
|
15
|
+
*
|
|
12
16
|
* If no angle is provided, it is determined from the EXIF data.
|
|
13
17
|
* Mirroring is supported and may infer the use of a flip operation.
|
|
14
18
|
*
|
|
@@ -28,64 +32,30 @@ const is = require('./is');
|
|
|
28
32
|
* });
|
|
29
33
|
* readableStream.pipe(pipeline);
|
|
30
34
|
*
|
|
31
|
-
* @param {Number} [angle=auto] angle of rotation
|
|
35
|
+
* @param {Number} [angle=auto] angle of rotation.
|
|
36
|
+
* @param {Object} [options] - if present, is an Object with optional attributes.
|
|
37
|
+
* @param {String|Object} [options.background="#000000"] parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
|
|
32
38
|
* @returns {Sharp}
|
|
33
39
|
* @throws {Error} Invalid parameters
|
|
34
40
|
*/
|
|
35
|
-
function rotate (angle) {
|
|
41
|
+
function rotate (angle, options) {
|
|
36
42
|
if (!is.defined(angle)) {
|
|
37
43
|
this.options.useExifOrientation = true;
|
|
38
44
|
} else if (is.integer(angle) && !(angle % 90)) {
|
|
39
45
|
this.options.angle = angle;
|
|
40
|
-
} else {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
*
|
|
49
|
-
|
|
50
|
-
* - Use `extract` after `resize` for post-resize extraction.
|
|
51
|
-
* - Use `extract` before and after for both.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* sharp(input)
|
|
55
|
-
* .extract({ left: left, top: top, width: width, height: height })
|
|
56
|
-
* .toFile(output, function(err) {
|
|
57
|
-
* // Extract a region of the input image, saving in the same format.
|
|
58
|
-
* });
|
|
59
|
-
* @example
|
|
60
|
-
* sharp(input)
|
|
61
|
-
* .extract({ left: leftOffsetPre, top: topOffsetPre, width: widthPre, height: heightPre })
|
|
62
|
-
* .resize(width, height)
|
|
63
|
-
* .extract({ left: leftOffsetPost, top: topOffsetPost, width: widthPost, height: heightPost })
|
|
64
|
-
* .toFile(output, function(err) {
|
|
65
|
-
* // Extract a region, resize, then extract from the resized image
|
|
66
|
-
* });
|
|
67
|
-
*
|
|
68
|
-
* @param {Object} options
|
|
69
|
-
* @param {Number} options.left - zero-indexed offset from left edge
|
|
70
|
-
* @param {Number} options.top - zero-indexed offset from top edge
|
|
71
|
-
* @param {Number} options.width - dimension of extracted image
|
|
72
|
-
* @param {Number} options.height - dimension of extracted image
|
|
73
|
-
* @returns {Sharp}
|
|
74
|
-
* @throws {Error} Invalid parameters
|
|
75
|
-
*/
|
|
76
|
-
function extract (options) {
|
|
77
|
-
const suffix = this.options.width === -1 && this.options.height === -1 ? 'Pre' : 'Post';
|
|
78
|
-
['left', 'top', 'width', 'height'].forEach(function (name) {
|
|
79
|
-
const value = options[name];
|
|
80
|
-
if (is.integer(value) && value >= 0) {
|
|
81
|
-
this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value;
|
|
82
|
-
} else {
|
|
83
|
-
throw new Error('Non-integer value for ' + name + ' of ' + value);
|
|
46
|
+
} else if (is.number(angle)) {
|
|
47
|
+
this.options.rotationAngle = angle;
|
|
48
|
+
if (is.object(options) && options.background) {
|
|
49
|
+
const backgroundColour = color(options.background);
|
|
50
|
+
this.options.rotationBackground = [
|
|
51
|
+
backgroundColour.red(),
|
|
52
|
+
backgroundColour.green(),
|
|
53
|
+
backgroundColour.blue(),
|
|
54
|
+
Math.round(backgroundColour.alpha() * 255)
|
|
55
|
+
];
|
|
84
56
|
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (suffix === 'Pre' && ((this.options.angle % 360) !== 0 || this.options.useExifOrientation === true)) {
|
|
88
|
-
this.options.rotateBeforePreExtract = true;
|
|
57
|
+
} else {
|
|
58
|
+
throw new Error('Unsupported angle: must be a number.');
|
|
89
59
|
}
|
|
90
60
|
return this;
|
|
91
61
|
}
|
|
@@ -201,72 +171,15 @@ function blur (sigma) {
|
|
|
201
171
|
}
|
|
202
172
|
|
|
203
173
|
/**
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
* @example
|
|
208
|
-
* // Resize to 140 pixels wide, then add 10 transparent pixels
|
|
209
|
-
* // to the top, left and right edges and 20 to the bottom edge
|
|
210
|
-
* sharp(input)
|
|
211
|
-
* .resize(140)
|
|
212
|
-
* .background({r: 0, g: 0, b: 0, alpha: 0})
|
|
213
|
-
* .extend({top: 10, bottom: 20, left: 10, right: 10})
|
|
214
|
-
* ...
|
|
215
|
-
*
|
|
216
|
-
* @param {(Number|Object)} extend - single pixel count to add to all edges or an Object with per-edge counts
|
|
217
|
-
* @param {Number} [extend.top]
|
|
218
|
-
* @param {Number} [extend.left]
|
|
219
|
-
* @param {Number} [extend.bottom]
|
|
220
|
-
* @param {Number} [extend.right]
|
|
221
|
-
* @returns {Sharp}
|
|
222
|
-
* @throws {Error} Invalid parameters
|
|
223
|
-
*/
|
|
224
|
-
function extend (extend) {
|
|
225
|
-
if (is.integer(extend) && extend > 0) {
|
|
226
|
-
this.options.extendTop = extend;
|
|
227
|
-
this.options.extendBottom = extend;
|
|
228
|
-
this.options.extendLeft = extend;
|
|
229
|
-
this.options.extendRight = extend;
|
|
230
|
-
} else if (
|
|
231
|
-
is.object(extend) &&
|
|
232
|
-
is.integer(extend.top) && extend.top >= 0 &&
|
|
233
|
-
is.integer(extend.bottom) && extend.bottom >= 0 &&
|
|
234
|
-
is.integer(extend.left) && extend.left >= 0 &&
|
|
235
|
-
is.integer(extend.right) && extend.right >= 0
|
|
236
|
-
) {
|
|
237
|
-
this.options.extendTop = extend.top;
|
|
238
|
-
this.options.extendBottom = extend.bottom;
|
|
239
|
-
this.options.extendLeft = extend.left;
|
|
240
|
-
this.options.extendRight = extend.right;
|
|
241
|
-
} else {
|
|
242
|
-
throw new Error('Invalid edge extension ' + extend);
|
|
243
|
-
}
|
|
244
|
-
return this;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Merge alpha transparency channel, if any, with `background`.
|
|
249
|
-
* @param {Boolean} [flatten=true]
|
|
250
|
-
* @returns {Sharp}
|
|
251
|
-
*/
|
|
252
|
-
function flatten (flatten) {
|
|
253
|
-
this.options.flatten = is.bool(flatten) ? flatten : true;
|
|
254
|
-
return this;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Trim "boring" pixels from all edges that contain values within a percentage similarity of the top-left pixel.
|
|
259
|
-
* @param {Number} [tolerance=10] value between 1 and 99 representing the percentage similarity.
|
|
174
|
+
* Merge alpha transparency channel, if any, with a background.
|
|
175
|
+
* @param {Object} [options]
|
|
176
|
+
* @param {String|Object} [options.background={r: 0, g: 0, b: 0}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black.
|
|
260
177
|
* @returns {Sharp}
|
|
261
|
-
* @throws {Error} Invalid parameters
|
|
262
178
|
*/
|
|
263
|
-
function
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
this.options.trimTolerance = tolerance;
|
|
268
|
-
} else {
|
|
269
|
-
throw new Error('Invalid trim tolerance (1 to 99) ' + tolerance);
|
|
179
|
+
function flatten (options) {
|
|
180
|
+
this.options.flatten = is.bool(options) ? options : true;
|
|
181
|
+
if (is.object(options)) {
|
|
182
|
+
this._setColourOption('flattenBackground', options.background);
|
|
270
183
|
}
|
|
271
184
|
return this;
|
|
272
185
|
}
|
|
@@ -277,11 +190,15 @@ function trim (tolerance) {
|
|
|
277
190
|
* This can improve the perceived brightness of a resized image in non-linear colour spaces.
|
|
278
191
|
* JPEG and WebP input images will not take advantage of the shrink-on-load performance optimisation
|
|
279
192
|
* when applying a gamma correction.
|
|
193
|
+
*
|
|
194
|
+
* Supply a second argument to use a different output gamma value, otherwise the first value is used in both cases.
|
|
195
|
+
*
|
|
280
196
|
* @param {Number} [gamma=2.2] value between 1.0 and 3.0.
|
|
197
|
+
* @param {Number} [gammaOut] value between 1.0 and 3.0. (optional, defaults to same as `gamma`)
|
|
281
198
|
* @returns {Sharp}
|
|
282
199
|
* @throws {Error} Invalid parameters
|
|
283
200
|
*/
|
|
284
|
-
function gamma (gamma) {
|
|
201
|
+
function gamma (gamma, gammaOut) {
|
|
285
202
|
if (!is.defined(gamma)) {
|
|
286
203
|
// Default gamma correction of 2.2 (sRGB)
|
|
287
204
|
this.options.gamma = 2.2;
|
|
@@ -290,6 +207,14 @@ function gamma (gamma) {
|
|
|
290
207
|
} else {
|
|
291
208
|
throw new Error('Invalid gamma correction (1.0 to 3.0) ' + gamma);
|
|
292
209
|
}
|
|
210
|
+
if (!is.defined(gammaOut)) {
|
|
211
|
+
// Default gamma correction for output is same as input
|
|
212
|
+
this.options.gammaOut = this.options.gamma;
|
|
213
|
+
} else if (is.number(gammaOut) && is.inRange(gammaOut, 1, 3)) {
|
|
214
|
+
this.options.gammaOut = gammaOut;
|
|
215
|
+
} else {
|
|
216
|
+
throw new Error('Invalid output gamma correction (1.0 to 3.0) ' + gammaOut);
|
|
217
|
+
}
|
|
293
218
|
return this;
|
|
294
219
|
}
|
|
295
220
|
|
|
@@ -453,22 +378,56 @@ function linear (a, b) {
|
|
|
453
378
|
return this;
|
|
454
379
|
}
|
|
455
380
|
|
|
381
|
+
/**
|
|
382
|
+
* Recomb the image with the specified matrix.
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* sharp(input)
|
|
386
|
+
* .recomb([
|
|
387
|
+
* [0.3588, 0.7044, 0.1368],
|
|
388
|
+
* [0.2990, 0.5870, 0.1140],
|
|
389
|
+
* [0.2392, 0.4696, 0.0912],
|
|
390
|
+
* ])
|
|
391
|
+
* .raw()
|
|
392
|
+
* .toBuffer(function(err, data, info) {
|
|
393
|
+
* // data contains the raw pixel data after applying the recomb
|
|
394
|
+
* // With this example input, a sepia filter has been applied
|
|
395
|
+
* });
|
|
396
|
+
*
|
|
397
|
+
* @param {Array<Array<Number>>} 3x3 Recombination matrix
|
|
398
|
+
* @returns {Sharp}
|
|
399
|
+
* @throws {Error} Invalid parameters
|
|
400
|
+
*/
|
|
401
|
+
function recomb (inputMatrix) {
|
|
402
|
+
if (!Array.isArray(inputMatrix) || inputMatrix.length !== 3 ||
|
|
403
|
+
inputMatrix[0].length !== 3 ||
|
|
404
|
+
inputMatrix[1].length !== 3 ||
|
|
405
|
+
inputMatrix[2].length !== 3
|
|
406
|
+
) {
|
|
407
|
+
// must pass in a kernel
|
|
408
|
+
throw new Error('Invalid Recomb Matrix');
|
|
409
|
+
}
|
|
410
|
+
this.options.recombMatrix = [
|
|
411
|
+
inputMatrix[0][0], inputMatrix[0][1], inputMatrix[0][2],
|
|
412
|
+
inputMatrix[1][0], inputMatrix[1][1], inputMatrix[1][2],
|
|
413
|
+
inputMatrix[2][0], inputMatrix[2][1], inputMatrix[2][2]
|
|
414
|
+
].map(Number);
|
|
415
|
+
return this;
|
|
416
|
+
}
|
|
417
|
+
|
|
456
418
|
/**
|
|
457
419
|
* Decorate the Sharp prototype with operation-related functions.
|
|
458
420
|
* @private
|
|
459
421
|
*/
|
|
460
422
|
module.exports = function (Sharp) {
|
|
461
|
-
|
|
423
|
+
Object.assign(Sharp.prototype, {
|
|
462
424
|
rotate,
|
|
463
|
-
extract,
|
|
464
425
|
flip,
|
|
465
426
|
flop,
|
|
466
427
|
sharpen,
|
|
467
428
|
median,
|
|
468
429
|
blur,
|
|
469
|
-
extend,
|
|
470
430
|
flatten,
|
|
471
|
-
trim,
|
|
472
431
|
gamma,
|
|
473
432
|
negate,
|
|
474
433
|
normalise,
|
|
@@ -476,8 +435,7 @@ module.exports = function (Sharp) {
|
|
|
476
435
|
convolve,
|
|
477
436
|
threshold,
|
|
478
437
|
boolean,
|
|
479
|
-
linear
|
|
480
|
-
|
|
481
|
-
Sharp.prototype[f.name] = f;
|
|
438
|
+
linear,
|
|
439
|
+
recomb
|
|
482
440
|
});
|
|
483
441
|
};
|
package/lib/output.js
CHANGED
|
@@ -32,7 +32,7 @@ const sharp = require('../build/Release/sharp.node');
|
|
|
32
32
|
*/
|
|
33
33
|
function toFile (fileOut, callback) {
|
|
34
34
|
if (!fileOut || fileOut.length === 0) {
|
|
35
|
-
const errOutputInvalid = new Error('
|
|
35
|
+
const errOutputInvalid = new Error('Missing output file path');
|
|
36
36
|
if (is.fn(callback)) {
|
|
37
37
|
callback(errOutputInvalid);
|
|
38
38
|
} else {
|
|
@@ -175,30 +175,30 @@ function jpeg (options) {
|
|
|
175
175
|
throw new Error('Invalid chromaSubsampling (4:2:0, 4:4:4) ' + options.chromaSubsampling);
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
|
-
|
|
179
|
-
if (is.defined(
|
|
180
|
-
this._setBooleanOption('jpegTrellisQuantisation',
|
|
178
|
+
const trellisQuantisation = is.bool(options.trellisQuantization) ? options.trellisQuantization : options.trellisQuantisation;
|
|
179
|
+
if (is.defined(trellisQuantisation)) {
|
|
180
|
+
this._setBooleanOption('jpegTrellisQuantisation', trellisQuantisation);
|
|
181
181
|
}
|
|
182
182
|
if (is.defined(options.overshootDeringing)) {
|
|
183
183
|
this._setBooleanOption('jpegOvershootDeringing', options.overshootDeringing);
|
|
184
184
|
}
|
|
185
|
-
|
|
186
|
-
if (is.defined(
|
|
187
|
-
this._setBooleanOption('jpegOptimiseScans',
|
|
188
|
-
if (
|
|
185
|
+
const optimiseScans = is.bool(options.optimizeScans) ? options.optimizeScans : options.optimiseScans;
|
|
186
|
+
if (is.defined(optimiseScans)) {
|
|
187
|
+
this._setBooleanOption('jpegOptimiseScans', optimiseScans);
|
|
188
|
+
if (optimiseScans) {
|
|
189
189
|
this.options.jpegProgressive = true;
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
|
|
193
|
-
if (is.defined(
|
|
194
|
-
this._setBooleanOption('jpegOptimiseCoding',
|
|
192
|
+
const optimiseCoding = is.bool(options.optimizeCoding) ? options.optimizeCoding : options.optimiseCoding;
|
|
193
|
+
if (is.defined(optimiseCoding)) {
|
|
194
|
+
this._setBooleanOption('jpegOptimiseCoding', optimiseCoding);
|
|
195
195
|
}
|
|
196
|
-
|
|
197
|
-
if (is.defined(
|
|
198
|
-
if (is.integer(
|
|
199
|
-
this.options.jpegQuantisationTable =
|
|
196
|
+
const quantisationTable = is.number(options.quantizationTable) ? options.quantizationTable : options.quantisationTable;
|
|
197
|
+
if (is.defined(quantisationTable)) {
|
|
198
|
+
if (is.integer(quantisationTable) && is.inRange(quantisationTable, 0, 8)) {
|
|
199
|
+
this.options.jpegQuantisationTable = quantisationTable;
|
|
200
200
|
} else {
|
|
201
|
-
throw new Error('Invalid quantisation table (integer, 0-8) ' +
|
|
201
|
+
throw new Error('Invalid quantisation table (integer, 0-8) ' + quantisationTable);
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
}
|
|
@@ -221,6 +221,11 @@ function jpeg (options) {
|
|
|
221
221
|
* @param {Boolean} [options.progressive=false] - use progressive (interlace) scan
|
|
222
222
|
* @param {Number} [options.compressionLevel=9] - zlib compression level, 0-9
|
|
223
223
|
* @param {Boolean} [options.adaptiveFiltering=false] - use adaptive row filtering
|
|
224
|
+
* @param {Boolean} [options.palette=false] - quantise to a palette-based image with alpha transparency support, requires libimagequant
|
|
225
|
+
* @param {Number} [options.quality=100] - use the lowest number of colours needed to achieve given quality, requires libimagequant
|
|
226
|
+
* @param {Number} [options.colours=256] - maximum number of palette entries, requires libimagequant
|
|
227
|
+
* @param {Number} [options.colors=256] - alternative spelling of `options.colours`, requires libimagequant
|
|
228
|
+
* @param {Number} [options.dither=1.0] - level of Floyd-Steinberg error diffusion, requires libimagequant
|
|
224
229
|
* @param {Boolean} [options.force=true] - force PNG output, otherwise attempt to use input format
|
|
225
230
|
* @returns {Sharp}
|
|
226
231
|
* @throws {Error} Invalid options
|
|
@@ -240,6 +245,33 @@ function png (options) {
|
|
|
240
245
|
if (is.defined(options.adaptiveFiltering)) {
|
|
241
246
|
this._setBooleanOption('pngAdaptiveFiltering', options.adaptiveFiltering);
|
|
242
247
|
}
|
|
248
|
+
if (is.defined(options.palette)) {
|
|
249
|
+
this._setBooleanOption('pngPalette', options.palette);
|
|
250
|
+
if (this.options.pngPalette) {
|
|
251
|
+
if (is.defined(options.quality)) {
|
|
252
|
+
if (is.integer(options.quality) && is.inRange(options.quality, 0, 100)) {
|
|
253
|
+
this.options.pngQuality = options.quality;
|
|
254
|
+
} else {
|
|
255
|
+
throw is.invalidParameterError('quality', 'integer between 0 and 100', options.quality);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const colours = options.colours || options.colors;
|
|
259
|
+
if (is.defined(colours)) {
|
|
260
|
+
if (is.integer(colours) && is.inRange(colours, 2, 256)) {
|
|
261
|
+
this.options.pngColours = colours;
|
|
262
|
+
} else {
|
|
263
|
+
throw is.invalidParameterError('colours', 'integer between 2 and 256', colours);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (is.defined(options.dither)) {
|
|
267
|
+
if (is.number(options.dither) && is.inRange(options.dither, 0, 1)) {
|
|
268
|
+
this.options.pngDither = options.dither;
|
|
269
|
+
} else {
|
|
270
|
+
throw is.invalidParameterError('dither', 'number between 0.0 and 1.0', options.dither);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
243
275
|
}
|
|
244
276
|
return this._updateFormatOut('png', options);
|
|
245
277
|
}
|
|
@@ -304,6 +336,10 @@ function webp (options) {
|
|
|
304
336
|
* @param {Boolean} [options.force=true] - force TIFF output, otherwise attempt to use input format
|
|
305
337
|
* @param {Boolean} [options.compression='jpeg'] - compression options: lzw, deflate, jpeg, ccittfax4
|
|
306
338
|
* @param {Boolean} [options.predictor='horizontal'] - compression predictor options: none, horizontal, float
|
|
339
|
+
* @param {Boolean} [options.pyramid=false] - write an image pyramid
|
|
340
|
+
* @param {Boolean} [options.tile=false] - write a tiled tiff
|
|
341
|
+
* @param {Boolean} [options.tileWidth=256] - horizontal tile size
|
|
342
|
+
* @param {Boolean} [options.tileHeight=256] - vertical tile size
|
|
307
343
|
* @param {Number} [options.xres=1.0] - horizontal resolution in pixels/mm
|
|
308
344
|
* @param {Number} [options.yres=1.0] - vertical resolution in pixels/mm
|
|
309
345
|
* @param {Boolean} [options.squash=false] - squash 8-bit images down to 1 bit
|
|
@@ -311,51 +347,83 @@ function webp (options) {
|
|
|
311
347
|
* @throws {Error} Invalid options
|
|
312
348
|
*/
|
|
313
349
|
function tiff (options) {
|
|
314
|
-
if (is.object(options)
|
|
315
|
-
if (is.
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
350
|
+
if (is.object(options)) {
|
|
351
|
+
if (is.defined(options.quality)) {
|
|
352
|
+
if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) {
|
|
353
|
+
this.options.tiffQuality = options.quality;
|
|
354
|
+
} else {
|
|
355
|
+
throw new Error('Invalid quality (integer, 1-100) ' + options.quality);
|
|
356
|
+
}
|
|
319
357
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
358
|
+
if (is.defined(options.squash)) {
|
|
359
|
+
if (is.bool(options.squash)) {
|
|
360
|
+
this.options.tiffSquash = options.squash;
|
|
361
|
+
} else {
|
|
362
|
+
throw new Error('Invalid Value for squash ' + options.squash + ' Only Boolean Values allowed for options.squash.');
|
|
363
|
+
}
|
|
326
364
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
365
|
+
// tiling
|
|
366
|
+
if (is.defined(options.tile)) {
|
|
367
|
+
if (is.bool(options.tile)) {
|
|
368
|
+
this.options.tiffTile = options.tile;
|
|
369
|
+
} else {
|
|
370
|
+
throw new Error('Invalid Value for tile ' + options.tile + ' Only Boolean values allowed for options.tile');
|
|
371
|
+
}
|
|
334
372
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
373
|
+
if (is.defined(options.tileWidth)) {
|
|
374
|
+
if (is.number(options.tileWidth) && options.tileWidth > 0) {
|
|
375
|
+
this.options.tiffTileWidth = options.tileWidth;
|
|
376
|
+
} else {
|
|
377
|
+
throw new Error('Invalid Value for tileWidth ' + options.tileWidth + ' Only positive numeric values allowed for options.tileWidth');
|
|
378
|
+
}
|
|
341
379
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const message = `Invalid compression option "${options.compression}". Should be one of: lzw, deflate, jpeg, ccittfax4, none`;
|
|
349
|
-
throw new Error(message);
|
|
380
|
+
if (is.defined(options.tileHeight)) {
|
|
381
|
+
if (is.number(options.tileHeight) && options.tileHeight > 0) {
|
|
382
|
+
this.options.tiffTileHeight = options.tileHeight;
|
|
383
|
+
} else {
|
|
384
|
+
throw new Error('Invalid Value for tileHeight ' + options.tileHeight + ' Only positive numeric values allowed for options.tileHeight');
|
|
385
|
+
}
|
|
350
386
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
387
|
+
// pyramid
|
|
388
|
+
if (is.defined(options.pyramid)) {
|
|
389
|
+
if (is.bool(options.pyramid)) {
|
|
390
|
+
this.options.tiffPyramid = options.pyramid;
|
|
391
|
+
} else {
|
|
392
|
+
throw new Error('Invalid Value for pyramid ' + options.pyramid + ' Only Boolean values allowed for options.pyramid');
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
// resolution
|
|
396
|
+
if (is.defined(options.xres)) {
|
|
397
|
+
if (is.number(options.xres)) {
|
|
398
|
+
this.options.tiffXres = options.xres;
|
|
399
|
+
} else {
|
|
400
|
+
throw new Error('Invalid Value for xres ' + options.xres + ' Only numeric values allowed for options.xres');
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (is.defined(options.yres)) {
|
|
404
|
+
if (is.number(options.yres)) {
|
|
405
|
+
this.options.tiffYres = options.yres;
|
|
406
|
+
} else {
|
|
407
|
+
throw new Error('Invalid Value for yres ' + options.yres + ' Only numeric values allowed for options.yres');
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
// compression
|
|
411
|
+
if (is.defined(options.compression)) {
|
|
412
|
+
if (is.string(options.compression) && is.inArray(options.compression, ['lzw', 'deflate', 'jpeg', 'ccittfax4', 'none'])) {
|
|
413
|
+
this.options.tiffCompression = options.compression;
|
|
414
|
+
} else {
|
|
415
|
+
const message = `Invalid compression option "${options.compression}". Should be one of: lzw, deflate, jpeg, ccittfax4, none`;
|
|
416
|
+
throw new Error(message);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
// predictor
|
|
420
|
+
if (is.defined(options.predictor)) {
|
|
421
|
+
if (is.string(options.predictor) && is.inArray(options.predictor, ['none', 'horizontal', 'float'])) {
|
|
422
|
+
this.options.tiffPredictor = options.predictor;
|
|
423
|
+
} else {
|
|
424
|
+
const message = `Invalid predictor option "${options.predictor}". Should be one of: none, horizontal, float`;
|
|
425
|
+
throw new Error(message);
|
|
426
|
+
}
|
|
359
427
|
}
|
|
360
428
|
}
|
|
361
429
|
return this._updateFormatOut('tiff', options);
|
|
@@ -505,7 +573,9 @@ function tile (tile) {
|
|
|
505
573
|
* @returns {Sharp}
|
|
506
574
|
*/
|
|
507
575
|
function _updateFormatOut (formatOut, options) {
|
|
508
|
-
|
|
576
|
+
if (!(is.object(options) && options.force === false)) {
|
|
577
|
+
this.options.formatOut = formatOut;
|
|
578
|
+
}
|
|
509
579
|
return this;
|
|
510
580
|
}
|
|
511
581
|
|
|
@@ -641,7 +711,7 @@ function _pipeline (callback) {
|
|
|
641
711
|
* @private
|
|
642
712
|
*/
|
|
643
713
|
module.exports = function (Sharp) {
|
|
644
|
-
|
|
714
|
+
Object.assign(Sharp.prototype, {
|
|
645
715
|
// Public
|
|
646
716
|
toFile,
|
|
647
717
|
toBuffer,
|
|
@@ -658,7 +728,5 @@ module.exports = function (Sharp) {
|
|
|
658
728
|
_setBooleanOption,
|
|
659
729
|
_read,
|
|
660
730
|
_pipeline
|
|
661
|
-
].forEach(function (f) {
|
|
662
|
-
Sharp.prototype[f.name] = f;
|
|
663
731
|
});
|
|
664
732
|
};
|
package/lib/platform.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const detectLibc = require('detect-libc');
|
|
4
|
+
|
|
3
5
|
module.exports = function () {
|
|
4
6
|
const arch = process.env.npm_config_arch || process.arch;
|
|
5
7
|
const platform = process.env.npm_config_platform || process.platform;
|
|
8
|
+
const libc = (platform === 'linux' && detectLibc.isNonGlibcLinux) ? detectLibc.family : '';
|
|
6
9
|
|
|
7
|
-
const platformId = [platform];
|
|
10
|
+
const platformId = [`${platform}${libc}`];
|
|
8
11
|
if (arch === 'arm' || arch === 'armhf' || arch === 'arm64') {
|
|
9
12
|
const armVersion = (arch === 'arm64') ? '8' : process.env.npm_config_armv || process.config.variables.arm_version || '6';
|
|
10
13
|
platformId.push(`armv${armVersion}`);
|