sharp 0.26.3 → 0.28.0
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 +16 -15
- package/binding.gyp +3 -5
- package/install/dll-copy.js +4 -4
- package/install/libvips.js +65 -31
- package/lib/channel.js +1 -1
- package/lib/colour.js +7 -0
- package/lib/composite.js +10 -7
- package/lib/constructor.js +53 -19
- package/lib/input.js +41 -10
- package/lib/is.js +10 -0
- package/lib/libvips.js +25 -3
- package/lib/operation.js +9 -4
- package/lib/output.js +137 -58
- package/lib/resize.js +42 -15
- package/lib/utility.js +17 -10
- package/package.json +20 -18
- package/src/common.cc +73 -51
- package/src/common.h +10 -3
- package/src/metadata.cc +6 -0
- package/src/metadata.h +1 -0
- package/src/operations.cc +1 -1
- package/src/pipeline.cc +43 -14
- package/src/pipeline.h +12 -5
- package/src/sharp.cc +2 -0
- package/src/utilities.cc +16 -0
- package/src/utilities.h +1 -0
package/lib/operation.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { flatten: flattenArray } = require('array-flatten');
|
|
4
3
|
const color = require('color');
|
|
5
4
|
const is = require('./is');
|
|
6
5
|
|
|
@@ -127,7 +126,7 @@ function flop (flop) {
|
|
|
127
126
|
* @throws {Error} Invalid parameters
|
|
128
127
|
*/
|
|
129
128
|
function affine (matrix, options) {
|
|
130
|
-
const flatMatrix =
|
|
129
|
+
const flatMatrix = [].concat(...matrix);
|
|
131
130
|
if (flatMatrix.length === 4 && flatMatrix.every(is.number)) {
|
|
132
131
|
this.options.affineMatrix = flatMatrix;
|
|
133
132
|
} else {
|
|
@@ -269,7 +268,13 @@ function blur (sigma) {
|
|
|
269
268
|
}
|
|
270
269
|
|
|
271
270
|
/**
|
|
272
|
-
* Merge alpha transparency channel, if any, with a background.
|
|
271
|
+
* Merge alpha transparency channel, if any, with a background, then remove the alpha channel.
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* await sharp(rgbaInput)
|
|
275
|
+
* .flatten('#F0A703')
|
|
276
|
+
* .toBuffer();
|
|
277
|
+
*
|
|
273
278
|
* @param {Object} [options]
|
|
274
279
|
* @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.
|
|
275
280
|
* @returns {Sharp}
|
|
@@ -397,7 +402,7 @@ function convolve (kernel) {
|
|
|
397
402
|
}
|
|
398
403
|
|
|
399
404
|
/**
|
|
400
|
-
* Any pixel value
|
|
405
|
+
* Any pixel value greater than or equal to the threshold value will be set to 255, otherwise it will be set to 0.
|
|
401
406
|
* @param {number} [threshold=128] - a value in the range 0-255 representing the level at which the threshold will be applied.
|
|
402
407
|
* @param {Object} [options]
|
|
403
408
|
* @param {Boolean} [options.greyscale=true] - convert to single channel greyscale.
|
package/lib/output.js
CHANGED
|
@@ -6,6 +6,7 @@ const sharp = require('../build/Release/sharp.node');
|
|
|
6
6
|
const formats = new Map([
|
|
7
7
|
['heic', 'heif'],
|
|
8
8
|
['heif', 'heif'],
|
|
9
|
+
['avif', 'avif'],
|
|
9
10
|
['jpeg', 'jpeg'],
|
|
10
11
|
['jpg', 'jpeg'],
|
|
11
12
|
['png', 'png'],
|
|
@@ -15,11 +16,13 @@ const formats = new Map([
|
|
|
15
16
|
['gif', 'gif']
|
|
16
17
|
]);
|
|
17
18
|
|
|
19
|
+
const errMagickSave = new Error('GIF output requires libvips with support for ImageMagick');
|
|
20
|
+
|
|
18
21
|
/**
|
|
19
22
|
* Write output image data to a file.
|
|
20
23
|
*
|
|
21
24
|
* If an explicit output format is not selected, it will be inferred from the extension,
|
|
22
|
-
* with JPEG, PNG, WebP, TIFF, DZI, and libvips' V format supported.
|
|
25
|
+
* with JPEG, PNG, WebP, AVIF, TIFF, DZI, and libvips' V format supported.
|
|
23
26
|
* Note that raw pixel data is only supported for buffer output.
|
|
24
27
|
*
|
|
25
28
|
* By default all metadata will be removed, which includes EXIF-based orientation.
|
|
@@ -46,32 +49,30 @@ const formats = new Map([
|
|
|
46
49
|
* @throws {Error} Invalid parameters
|
|
47
50
|
*/
|
|
48
51
|
function toFile (fileOut, callback) {
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
let err;
|
|
53
|
+
if (!is.string(fileOut)) {
|
|
54
|
+
err = new Error('Missing output file path');
|
|
55
|
+
} else if (this.options.input.file === fileOut) {
|
|
56
|
+
err = new Error('Cannot use same file for input and output');
|
|
57
|
+
} else if (this.options.formatOut === 'input' && fileOut.toLowerCase().endsWith('.gif') && !this.constructor.format.magick.output.file) {
|
|
58
|
+
err = errMagickSave;
|
|
59
|
+
}
|
|
60
|
+
if (err) {
|
|
51
61
|
if (is.fn(callback)) {
|
|
52
|
-
callback(
|
|
62
|
+
callback(err);
|
|
53
63
|
} else {
|
|
54
|
-
return Promise.reject(
|
|
64
|
+
return Promise.reject(err);
|
|
55
65
|
}
|
|
56
66
|
} else {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (is.fn(callback)) {
|
|
60
|
-
callback(errOutputIsInput);
|
|
61
|
-
} else {
|
|
62
|
-
return Promise.reject(errOutputIsInput);
|
|
63
|
-
}
|
|
64
|
-
} else {
|
|
65
|
-
this.options.fileOut = fileOut;
|
|
66
|
-
return this._pipeline(callback);
|
|
67
|
-
}
|
|
67
|
+
this.options.fileOut = fileOut;
|
|
68
|
+
return this._pipeline(callback);
|
|
68
69
|
}
|
|
69
70
|
return this;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
/**
|
|
73
74
|
* Write output to a Buffer.
|
|
74
|
-
* JPEG, PNG, WebP, TIFF and
|
|
75
|
+
* JPEG, PNG, WebP, AVIF, TIFF and raw pixel data output are supported.
|
|
75
76
|
*
|
|
76
77
|
* If no explicit format is set, the output format will match the input image, except GIF and SVG input which become PNG output.
|
|
77
78
|
*
|
|
@@ -103,6 +104,22 @@ function toFile (fileOut, callback) {
|
|
|
103
104
|
* .then(({ data, info }) => { ... })
|
|
104
105
|
* .catch(err => { ... });
|
|
105
106
|
*
|
|
107
|
+
* @example
|
|
108
|
+
* const { data, info } = await sharp('my-image.jpg')
|
|
109
|
+
* // output the raw pixels
|
|
110
|
+
* .raw()
|
|
111
|
+
* .toBuffer({ resolveWithObject: true });
|
|
112
|
+
*
|
|
113
|
+
* // create a more type safe way to work with the raw pixel data
|
|
114
|
+
* // this will not copy the data, instead it will change `data`s underlying ArrayBuffer
|
|
115
|
+
* // so `data` and `pixelArray` point to the same memory location
|
|
116
|
+
* const pixelArray = new Uint8ClampedArray(data.buffer);
|
|
117
|
+
*
|
|
118
|
+
* // When you are done changing the pixelArray, sharp takes the `pixelArray` as an input
|
|
119
|
+
* const { width, height, channels } = info;
|
|
120
|
+
* await sharp(pixelArray, { raw: { width, height, channels } })
|
|
121
|
+
* .toFile('my-changed-image.jpg');
|
|
122
|
+
*
|
|
106
123
|
* @param {Object} [options]
|
|
107
124
|
* @param {boolean} [options.resolveWithObject] Resolve the Promise with an Object containing `data` and `info` properties instead of resolving only with `data`.
|
|
108
125
|
* @param {Function} [callback]
|
|
@@ -173,7 +190,7 @@ function withMetadata (options) {
|
|
|
173
190
|
* @throws {Error} unsupported format or options
|
|
174
191
|
*/
|
|
175
192
|
function toFormat (format, options) {
|
|
176
|
-
const actualFormat = formats.get(is.object(format) && is.string(format.id) ? format.id : format);
|
|
193
|
+
const actualFormat = formats.get((is.object(format) && is.string(format.id) ? format.id : format).toLowerCase());
|
|
177
194
|
if (!actualFormat) {
|
|
178
195
|
throw is.invalidParameterError('format', `one of: ${[...formats.keys()].join(', ')}`, format);
|
|
179
196
|
}
|
|
@@ -183,8 +200,6 @@ function toFormat (format, options) {
|
|
|
183
200
|
/**
|
|
184
201
|
* Use these JPEG options for output image.
|
|
185
202
|
*
|
|
186
|
-
* Some of these options require the use of a globally-installed libvips compiled with support for mozjpeg.
|
|
187
|
-
*
|
|
188
203
|
* @example
|
|
189
204
|
* // Convert any input to very high quality JPEG output
|
|
190
205
|
* const data = await sharp(input)
|
|
@@ -194,18 +209,25 @@ function toFormat (format, options) {
|
|
|
194
209
|
* })
|
|
195
210
|
* .toBuffer();
|
|
196
211
|
*
|
|
212
|
+
* @example
|
|
213
|
+
* // Use mozjpeg to reduce output JPEG file size (slower)
|
|
214
|
+
* const data = await sharp(input)
|
|
215
|
+
* .jpeg({ mozjpeg: true })
|
|
216
|
+
* .toBuffer();
|
|
217
|
+
*
|
|
197
218
|
* @param {Object} [options] - output options
|
|
198
219
|
* @param {number} [options.quality=80] - quality, integer 1-100
|
|
199
220
|
* @param {boolean} [options.progressive=false] - use progressive (interlace) scan
|
|
200
221
|
* @param {string} [options.chromaSubsampling='4:2:0'] - set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' chroma subsampling
|
|
201
222
|
* @param {boolean} [options.optimiseCoding=true] - optimise Huffman coding tables
|
|
202
223
|
* @param {boolean} [options.optimizeCoding=true] - alternative spelling of optimiseCoding
|
|
203
|
-
* @param {boolean} [options.
|
|
204
|
-
* @param {boolean} [options.
|
|
205
|
-
* @param {boolean} [options.
|
|
206
|
-
* @param {boolean} [options.
|
|
207
|
-
* @param {
|
|
208
|
-
* @param {number} [options.
|
|
224
|
+
* @param {boolean} [options.mozjpeg=false] - use mozjpeg defaults, equivalent to `{ trellisQuantisation: true, overshootDeringing: true, optimiseScans: true, quantisationTable: 3 }`
|
|
225
|
+
* @param {boolean} [options.trellisQuantisation=false] - apply trellis quantisation
|
|
226
|
+
* @param {boolean} [options.overshootDeringing=false] - apply overshoot deringing
|
|
227
|
+
* @param {boolean} [options.optimiseScans=false] - optimise progressive scans, forces progressive
|
|
228
|
+
* @param {boolean} [options.optimizeScans=false] - alternative spelling of optimiseScans
|
|
229
|
+
* @param {number} [options.quantisationTable=0] - quantization table to use, integer 0-8
|
|
230
|
+
* @param {number} [options.quantizationTable=0] - alternative spelling of quantisationTable
|
|
209
231
|
* @param {boolean} [options.force=true] - force JPEG output, otherwise attempt to use input format
|
|
210
232
|
* @returns {Sharp}
|
|
211
233
|
* @throws {Error} Invalid options
|
|
@@ -229,6 +251,23 @@ function jpeg (options) {
|
|
|
229
251
|
throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling);
|
|
230
252
|
}
|
|
231
253
|
}
|
|
254
|
+
const optimiseCoding = is.bool(options.optimizeCoding) ? options.optimizeCoding : options.optimiseCoding;
|
|
255
|
+
if (is.defined(optimiseCoding)) {
|
|
256
|
+
this._setBooleanOption('jpegOptimiseCoding', optimiseCoding);
|
|
257
|
+
}
|
|
258
|
+
if (is.defined(options.mozjpeg)) {
|
|
259
|
+
if (is.bool(options.mozjpeg)) {
|
|
260
|
+
if (options.mozjpeg) {
|
|
261
|
+
this.options.jpegTrellisQuantisation = true;
|
|
262
|
+
this.options.jpegOvershootDeringing = true;
|
|
263
|
+
this.options.jpegOptimiseScans = true;
|
|
264
|
+
this.options.jpegProgressive = true;
|
|
265
|
+
this.options.jpegQuantisationTable = 3;
|
|
266
|
+
}
|
|
267
|
+
} else {
|
|
268
|
+
throw is.invalidParameterError('mozjpeg', 'boolean', options.mozjpeg);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
232
271
|
const trellisQuantisation = is.bool(options.trellisQuantization) ? options.trellisQuantization : options.trellisQuantisation;
|
|
233
272
|
if (is.defined(trellisQuantisation)) {
|
|
234
273
|
this._setBooleanOption('jpegTrellisQuantisation', trellisQuantisation);
|
|
@@ -243,10 +282,6 @@ function jpeg (options) {
|
|
|
243
282
|
this.options.jpegProgressive = true;
|
|
244
283
|
}
|
|
245
284
|
}
|
|
246
|
-
const optimiseCoding = is.bool(options.optimizeCoding) ? options.optimizeCoding : options.optimiseCoding;
|
|
247
|
-
if (is.defined(optimiseCoding)) {
|
|
248
|
-
this._setBooleanOption('jpegOptimiseCoding', optimiseCoding);
|
|
249
|
-
}
|
|
250
285
|
const quantisationTable = is.number(options.quantizationTable) ? options.quantizationTable : options.quantisationTable;
|
|
251
286
|
if (is.defined(quantisationTable)) {
|
|
252
287
|
if (is.integer(quantisationTable) && is.inRange(quantisationTable, 0, 8)) {
|
|
@@ -262,26 +297,31 @@ function jpeg (options) {
|
|
|
262
297
|
/**
|
|
263
298
|
* Use these PNG options for output image.
|
|
264
299
|
*
|
|
265
|
-
* PNG output is
|
|
300
|
+
* By default, PNG output is full colour at 8 or 16 bits per pixel.
|
|
266
301
|
* Indexed PNG input at 1, 2 or 4 bits per pixel is converted to 8 bits per pixel.
|
|
267
|
-
*
|
|
268
|
-
* Some of these options require the use of a globally-installed libvips compiled with support for libimagequant (GPL).
|
|
302
|
+
* Set `palette` to `true` for slower, indexed PNG output.
|
|
269
303
|
*
|
|
270
304
|
* @example
|
|
271
|
-
* // Convert any input to PNG output
|
|
305
|
+
* // Convert any input to full colour PNG output
|
|
272
306
|
* const data = await sharp(input)
|
|
273
307
|
* .png()
|
|
274
308
|
* .toBuffer();
|
|
275
309
|
*
|
|
310
|
+
* @example
|
|
311
|
+
* // Convert any input to indexed PNG output (slower)
|
|
312
|
+
* const data = await sharp(input)
|
|
313
|
+
* .png({ palette: true })
|
|
314
|
+
* .toBuffer();
|
|
315
|
+
*
|
|
276
316
|
* @param {Object} [options]
|
|
277
317
|
* @param {boolean} [options.progressive=false] - use progressive (interlace) scan
|
|
278
|
-
* @param {number} [options.compressionLevel=
|
|
318
|
+
* @param {number} [options.compressionLevel=6] - zlib compression level, 0 (fastest, largest) to 9 (slowest, smallest)
|
|
279
319
|
* @param {boolean} [options.adaptiveFiltering=false] - use adaptive row filtering
|
|
280
|
-
* @param {boolean} [options.palette=false] - quantise to a palette-based image with alpha transparency support
|
|
281
|
-
* @param {number} [options.quality=100] - use the lowest number of colours needed to achieve given quality, sets `palette` to `true
|
|
282
|
-
* @param {number} [options.colours=256] - maximum number of palette entries, sets `palette` to `true
|
|
283
|
-
* @param {number} [options.colors=256] - alternative spelling of `options.colours`, sets `palette` to `true
|
|
284
|
-
* @param {number} [options.dither=1.0] - level of Floyd-Steinberg error diffusion, sets `palette` to `true
|
|
320
|
+
* @param {boolean} [options.palette=false] - quantise to a palette-based image with alpha transparency support
|
|
321
|
+
* @param {number} [options.quality=100] - use the lowest number of colours needed to achieve given quality, sets `palette` to `true`
|
|
322
|
+
* @param {number} [options.colours=256] - maximum number of palette entries, sets `palette` to `true`
|
|
323
|
+
* @param {number} [options.colors=256] - alternative spelling of `options.colours`, sets `palette` to `true`
|
|
324
|
+
* @param {number} [options.dither=1.0] - level of Floyd-Steinberg error diffusion, sets `palette` to `true`
|
|
285
325
|
* @param {boolean} [options.force=true] - force PNG output, otherwise attempt to use input format
|
|
286
326
|
* @returns {Sharp}
|
|
287
327
|
* @throws {Error} Invalid options
|
|
@@ -411,7 +451,7 @@ function webp (options) {
|
|
|
411
451
|
/* istanbul ignore next */
|
|
412
452
|
function gif (options) {
|
|
413
453
|
if (!this.constructor.format.magick.output.buffer) {
|
|
414
|
-
throw
|
|
454
|
+
throw errMagickSave;
|
|
415
455
|
}
|
|
416
456
|
trySetAnimationOptions(options, this.options);
|
|
417
457
|
return this._updateFormatOut('gif', options);
|
|
@@ -471,15 +511,15 @@ function trySetAnimationOptions (source, target) {
|
|
|
471
511
|
* @param {Object} [options] - output options
|
|
472
512
|
* @param {number} [options.quality=80] - quality, integer 1-100
|
|
473
513
|
* @param {boolean} [options.force=true] - force TIFF output, otherwise attempt to use input format
|
|
474
|
-
* @param {
|
|
475
|
-
* @param {
|
|
514
|
+
* @param {string} [options.compression='jpeg'] - compression options: lzw, deflate, jpeg, ccittfax4
|
|
515
|
+
* @param {string} [options.predictor='horizontal'] - compression predictor options: none, horizontal, float
|
|
476
516
|
* @param {boolean} [options.pyramid=false] - write an image pyramid
|
|
477
517
|
* @param {boolean} [options.tile=false] - write a tiled tiff
|
|
478
|
-
* @param {
|
|
479
|
-
* @param {
|
|
518
|
+
* @param {number} [options.tileWidth=256] - horizontal tile size
|
|
519
|
+
* @param {number} [options.tileHeight=256] - vertical tile size
|
|
480
520
|
* @param {number} [options.xres=1.0] - horizontal resolution in pixels/mm
|
|
481
521
|
* @param {number} [options.yres=1.0] - vertical resolution in pixels/mm
|
|
482
|
-
* @param {
|
|
522
|
+
* @param {number} [options.bitdepth=8] - reduce bitdepth to 1, 2 or 4 bit
|
|
483
523
|
* @returns {Sharp}
|
|
484
524
|
* @throws {Error} Invalid options
|
|
485
525
|
*/
|
|
@@ -557,28 +597,43 @@ function tiff (options) {
|
|
|
557
597
|
}
|
|
558
598
|
|
|
559
599
|
/**
|
|
560
|
-
* Use these
|
|
600
|
+
* Use these AVIF options for output image.
|
|
561
601
|
*
|
|
562
|
-
*
|
|
563
|
-
*
|
|
602
|
+
* Whilst it is possible to create AVIF images smaller than 16x16 pixels,
|
|
603
|
+
* most web browsers do not display these properly.
|
|
564
604
|
*
|
|
565
|
-
*
|
|
605
|
+
* @since 0.27.0
|
|
606
|
+
*
|
|
607
|
+
* @param {Object} [options] - output options
|
|
608
|
+
* @param {number} [options.quality=50] - quality, integer 1-100
|
|
609
|
+
* @param {boolean} [options.lossless=false] - use lossless compression
|
|
610
|
+
* @param {number} [options.speed=5] - CPU effort vs file size, 0 (slowest/smallest) to 8 (fastest/largest)
|
|
611
|
+
* @param {string} [options.chromaSubsampling='4:2:0'] - set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' chroma subsampling, requires libvips v8.11.0
|
|
612
|
+
* @returns {Sharp}
|
|
613
|
+
* @throws {Error} Invalid options
|
|
614
|
+
*/
|
|
615
|
+
function avif (options) {
|
|
616
|
+
return this.heif({ ...options, compression: 'av1' });
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Use these HEIF options for output image.
|
|
566
621
|
*
|
|
567
|
-
*
|
|
622
|
+
* Support for patent-encumbered HEIC images requires the use of a
|
|
623
|
+
* globally-installed libvips compiled with support for libheif, libde265 and x265.
|
|
568
624
|
*
|
|
569
625
|
* @since 0.23.0
|
|
570
626
|
*
|
|
571
627
|
* @param {Object} [options] - output options
|
|
572
|
-
* @param {number} [options.quality=
|
|
573
|
-
* @param {
|
|
628
|
+
* @param {number} [options.quality=50] - quality, integer 1-100
|
|
629
|
+
* @param {string} [options.compression='av1'] - compression format: av1, hevc
|
|
574
630
|
* @param {boolean} [options.lossless=false] - use lossless compression
|
|
631
|
+
* @param {number} [options.speed=5] - CPU effort vs file size, 0 (slowest/smallest) to 8 (fastest/largest)
|
|
632
|
+
* @param {string} [options.chromaSubsampling='4:2:0'] - set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' chroma subsampling, requires libvips v8.11.0
|
|
575
633
|
* @returns {Sharp}
|
|
576
634
|
* @throws {Error} Invalid options
|
|
577
635
|
*/
|
|
578
636
|
function heif (options) {
|
|
579
|
-
if (!this.constructor.format.heif.output.buffer) {
|
|
580
|
-
throw new Error('The heif operation requires libvips to have been installed with support for libheif');
|
|
581
|
-
}
|
|
582
637
|
if (is.object(options)) {
|
|
583
638
|
if (is.defined(options.quality)) {
|
|
584
639
|
if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) {
|
|
@@ -595,10 +650,24 @@ function heif (options) {
|
|
|
595
650
|
}
|
|
596
651
|
}
|
|
597
652
|
if (is.defined(options.compression)) {
|
|
598
|
-
if (is.string(options.compression) && is.inArray(options.compression, ['
|
|
653
|
+
if (is.string(options.compression) && is.inArray(options.compression, ['av1', 'hevc'])) {
|
|
599
654
|
this.options.heifCompression = options.compression;
|
|
600
655
|
} else {
|
|
601
|
-
throw is.invalidParameterError('compression', 'one of:
|
|
656
|
+
throw is.invalidParameterError('compression', 'one of: av1, hevc', options.compression);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
if (is.defined(options.speed)) {
|
|
660
|
+
if (is.integer(options.speed) && is.inRange(options.speed, 0, 8)) {
|
|
661
|
+
this.options.heifSpeed = options.speed;
|
|
662
|
+
} else {
|
|
663
|
+
throw is.invalidParameterError('speed', 'integer between 0 and 8', options.speed);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
if (is.defined(options.chromaSubsampling)) {
|
|
667
|
+
if (is.string(options.chromaSubsampling) && is.inArray(options.chromaSubsampling, ['4:2:0', '4:4:4'])) {
|
|
668
|
+
this.options.heifChromaSubsampling = options.chromaSubsampling;
|
|
669
|
+
} else {
|
|
670
|
+
throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling);
|
|
602
671
|
}
|
|
603
672
|
}
|
|
604
673
|
}
|
|
@@ -660,6 +729,7 @@ function raw () {
|
|
|
660
729
|
* @param {string} [options.layout='dz'] filesystem layout, possible values are `dz`, `iiif`, `zoomify` or `google`.
|
|
661
730
|
* @param {boolean} [options.centre=false] centre image in tile.
|
|
662
731
|
* @param {boolean} [options.center=false] alternative spelling of centre.
|
|
732
|
+
* @param {string} [options.id='https://example.com/iiif'] when `layout` is `iiif`, sets the `@id` attribute of `info.json`
|
|
663
733
|
* @returns {Sharp}
|
|
664
734
|
* @throws {Error} Invalid parameters
|
|
665
735
|
*/
|
|
@@ -733,6 +803,14 @@ function tile (options) {
|
|
|
733
803
|
if (is.defined(centre)) {
|
|
734
804
|
this._setBooleanOption('tileCentre', centre);
|
|
735
805
|
}
|
|
806
|
+
// @id attribute for IIIF layout
|
|
807
|
+
if (is.defined(options.id)) {
|
|
808
|
+
if (is.string(options.id)) {
|
|
809
|
+
this.options.tileId = options.id;
|
|
810
|
+
} else {
|
|
811
|
+
throw is.invalidParameterError('id', 'string', options.id);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
736
814
|
}
|
|
737
815
|
// Format
|
|
738
816
|
if (is.inArray(this.options.formatOut, ['jpeg', 'png', 'webp'])) {
|
|
@@ -891,6 +969,7 @@ module.exports = function (Sharp) {
|
|
|
891
969
|
png,
|
|
892
970
|
webp,
|
|
893
971
|
tiff,
|
|
972
|
+
avif,
|
|
894
973
|
heif,
|
|
895
974
|
gif,
|
|
896
975
|
raw,
|
package/lib/resize.js
CHANGED
|
@@ -302,11 +302,20 @@ function resize (width, height, options) {
|
|
|
302
302
|
* })
|
|
303
303
|
* ...
|
|
304
304
|
*
|
|
305
|
+
* @example
|
|
306
|
+
* // Add a row of 10 red pixels to the bottom
|
|
307
|
+
* sharp(input)
|
|
308
|
+
* .extend({
|
|
309
|
+
* bottom: 10,
|
|
310
|
+
* background: 'red'
|
|
311
|
+
* })
|
|
312
|
+
* ...
|
|
313
|
+
*
|
|
305
314
|
* @param {(number|Object)} extend - single pixel count to add to all edges or an Object with per-edge counts
|
|
306
|
-
* @param {number} [extend.top]
|
|
307
|
-
* @param {number} [extend.left]
|
|
308
|
-
* @param {number} [extend.bottom]
|
|
309
|
-
* @param {number} [extend.right]
|
|
315
|
+
* @param {number} [extend.top=0]
|
|
316
|
+
* @param {number} [extend.left=0]
|
|
317
|
+
* @param {number} [extend.bottom=0]
|
|
318
|
+
* @param {number} [extend.right=0]
|
|
310
319
|
* @param {String|Object} [extend.background={r: 0, g: 0, b: 0, alpha: 1}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black without transparency.
|
|
311
320
|
* @returns {Sharp}
|
|
312
321
|
* @throws {Error} Invalid parameters
|
|
@@ -317,17 +326,35 @@ function extend (extend) {
|
|
|
317
326
|
this.options.extendBottom = extend;
|
|
318
327
|
this.options.extendLeft = extend;
|
|
319
328
|
this.options.extendRight = extend;
|
|
320
|
-
} else if (
|
|
321
|
-
is.
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
329
|
+
} else if (is.object(extend)) {
|
|
330
|
+
if (is.defined(extend.top)) {
|
|
331
|
+
if (is.integer(extend.top) && extend.top >= 0) {
|
|
332
|
+
this.options.extendTop = extend.top;
|
|
333
|
+
} else {
|
|
334
|
+
throw is.invalidParameterError('top', 'positive integer', extend.top);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (is.defined(extend.bottom)) {
|
|
338
|
+
if (is.integer(extend.bottom) && extend.bottom >= 0) {
|
|
339
|
+
this.options.extendBottom = extend.bottom;
|
|
340
|
+
} else {
|
|
341
|
+
throw is.invalidParameterError('bottom', 'positive integer', extend.bottom);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (is.defined(extend.left)) {
|
|
345
|
+
if (is.integer(extend.left) && extend.left >= 0) {
|
|
346
|
+
this.options.extendLeft = extend.left;
|
|
347
|
+
} else {
|
|
348
|
+
throw is.invalidParameterError('left', 'positive integer', extend.left);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (is.defined(extend.right)) {
|
|
352
|
+
if (is.integer(extend.right) && extend.right >= 0) {
|
|
353
|
+
this.options.extendRight = extend.right;
|
|
354
|
+
} else {
|
|
355
|
+
throw is.invalidParameterError('right', 'positive integer', extend.right);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
331
358
|
this._setBackgroundColourOption('extendBackground', extend.background);
|
|
332
359
|
} else {
|
|
333
360
|
throw is.invalidParameterError('extend', 'integer or object', extend);
|
package/lib/utility.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const events = require('events');
|
|
4
|
+
const detectLibc = require('detect-libc');
|
|
5
|
+
|
|
4
6
|
const is = require('./is');
|
|
5
7
|
const sharp = require('../build/Release/sharp.node');
|
|
6
8
|
|
|
@@ -84,8 +86,12 @@ cache(true);
|
|
|
84
86
|
/**
|
|
85
87
|
* Gets or, when a concurrency is provided, sets
|
|
86
88
|
* the number of threads _libvips'_ should create to process each image.
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
+
*
|
|
90
|
+
* The default value is the number of CPU cores,
|
|
91
|
+
* except when using glibc-based Linux without jemalloc,
|
|
92
|
+
* where the default is `1` to help reduce memory fragmentation.
|
|
93
|
+
*
|
|
94
|
+
* A value of `0` will reset this to the number of CPU cores.
|
|
89
95
|
*
|
|
90
96
|
* The maximum number of images that can be processed in parallel
|
|
91
97
|
* is limited by libuv's `UV_THREADPOOL_SIZE` environment variable.
|
|
@@ -103,6 +109,11 @@ cache(true);
|
|
|
103
109
|
function concurrency (concurrency) {
|
|
104
110
|
return sharp.concurrency(is.integer(concurrency) ? concurrency : null);
|
|
105
111
|
}
|
|
112
|
+
/* istanbul ignore next */
|
|
113
|
+
if (detectLibc.family === detectLibc.GLIBC && !sharp._isUsingJemalloc()) {
|
|
114
|
+
// Reduce default concurrency to 1 when using glibc memory allocator
|
|
115
|
+
sharp.concurrency(1);
|
|
116
|
+
}
|
|
106
117
|
|
|
107
118
|
/**
|
|
108
119
|
* An EventEmitter that emits a `change` event when a task is either:
|
|
@@ -157,14 +168,10 @@ simd(true);
|
|
|
157
168
|
* @private
|
|
158
169
|
*/
|
|
159
170
|
module.exports = function (Sharp) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
simd
|
|
165
|
-
].forEach(function (f) {
|
|
166
|
-
Sharp[f.name] = f;
|
|
167
|
-
});
|
|
171
|
+
Sharp.cache = cache;
|
|
172
|
+
Sharp.concurrency = concurrency;
|
|
173
|
+
Sharp.counters = counters;
|
|
174
|
+
Sharp.simd = simd;
|
|
168
175
|
Sharp.format = format;
|
|
169
176
|
Sharp.interpolators = interpolators;
|
|
170
177
|
Sharp.versions = versions;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sharp",
|
|
3
|
-
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images",
|
|
4
|
+
"version": "0.28.0",
|
|
5
5
|
"author": "Lovell Fuller <npm@lovell.info>",
|
|
6
6
|
"homepage": "https://github.com/lovell/sharp",
|
|
7
7
|
"contributors": [
|
|
@@ -70,17 +70,21 @@
|
|
|
70
70
|
"Roman Malieiev <aromaleev@gmail.com>",
|
|
71
71
|
"Tomas Szabo <tomas.szabo@deftomat.com>",
|
|
72
72
|
"Robert O'Rourke <robert@o-rourke.org>",
|
|
73
|
-
"Guillermo Alfonso Varela Chouciño <guillevch@gmail.com>"
|
|
73
|
+
"Guillermo Alfonso Varela Chouciño <guillevch@gmail.com>",
|
|
74
|
+
"Christian Flintrup <chr@gigahost.dk>",
|
|
75
|
+
"Manan Jadhav <manan@motionden.com>",
|
|
76
|
+
"Leon Radley <leon@radley.se>",
|
|
77
|
+
"alza54 <alza54@thiocod.in>"
|
|
74
78
|
],
|
|
75
79
|
"scripts": {
|
|
76
80
|
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)",
|
|
77
81
|
"clean": "rm -rf node_modules/ build/ vendor/ .nyc_output/ coverage/ test/fixtures/output.*",
|
|
78
|
-
"test": "semistandard && cpplint && npm run test-unit && npm run test-licensing
|
|
79
|
-
"test-unit": "nyc --reporter=lcov --branches=99 mocha --slow=
|
|
82
|
+
"test": "semistandard && cpplint && npm run test-unit && npm run test-licensing",
|
|
83
|
+
"test-unit": "nyc --reporter=lcov --branches=99 mocha --slow=1000 --timeout=60000 ./test/unit/*.js",
|
|
80
84
|
"test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;MIT\"",
|
|
81
85
|
"test-coverage": "./test/coverage/report.sh",
|
|
82
86
|
"test-leak": "./test/leak/leak.sh",
|
|
83
|
-
"docs-build": "documentation lint lib &&
|
|
87
|
+
"docs-build": "documentation lint lib && node docs/build && node docs/search-index/build",
|
|
84
88
|
"docs-serve": "cd docs && npx serve",
|
|
85
89
|
"docs-publish": "cd docs && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
|
|
86
90
|
},
|
|
@@ -88,7 +92,6 @@
|
|
|
88
92
|
"files": [
|
|
89
93
|
"binding.gyp",
|
|
90
94
|
"install/**",
|
|
91
|
-
"!install/prebuild-ci.js",
|
|
92
95
|
"lib/**",
|
|
93
96
|
"src/**"
|
|
94
97
|
],
|
|
@@ -100,6 +103,7 @@
|
|
|
100
103
|
"jpeg",
|
|
101
104
|
"png",
|
|
102
105
|
"webp",
|
|
106
|
+
"avif",
|
|
103
107
|
"tiff",
|
|
104
108
|
"gif",
|
|
105
109
|
"svg",
|
|
@@ -113,26 +117,24 @@
|
|
|
113
117
|
"vips"
|
|
114
118
|
],
|
|
115
119
|
"dependencies": {
|
|
116
|
-
"array-flatten": "^3.0.0",
|
|
117
120
|
"color": "^3.1.3",
|
|
118
121
|
"detect-libc": "^1.0.3",
|
|
119
|
-
"node-addon-api": "^3.0
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"simple-get": "^4.0.0",
|
|
122
|
+
"node-addon-api": "^3.1.0",
|
|
123
|
+
"prebuild-install": "^6.0.1",
|
|
124
|
+
"semver": "^7.3.5",
|
|
125
|
+
"simple-get": "^3.1.0",
|
|
124
126
|
"tar-fs": "^2.1.1",
|
|
125
127
|
"tunnel-agent": "^0.6.0"
|
|
126
128
|
},
|
|
127
129
|
"devDependencies": {
|
|
128
130
|
"async": "^3.2.0",
|
|
129
|
-
"cc": "^
|
|
130
|
-
"decompress-zip": "^0.3.
|
|
131
|
-
"documentation": "^13.
|
|
131
|
+
"cc": "^3.0.1",
|
|
132
|
+
"decompress-zip": "^0.3.3",
|
|
133
|
+
"documentation": "^13.2.0",
|
|
132
134
|
"exif-reader": "^1.0.3",
|
|
133
135
|
"icc": "^2.0.0",
|
|
134
136
|
"license-checker": "^25.0.1",
|
|
135
|
-
"mocha": "^8.2
|
|
137
|
+
"mocha": "^8.3.2",
|
|
136
138
|
"mock-fs": "^4.13.0",
|
|
137
139
|
"nyc": "^15.1.0",
|
|
138
140
|
"prebuild": "^10.0.1",
|
|
@@ -141,7 +143,7 @@
|
|
|
141
143
|
},
|
|
142
144
|
"license": "Apache-2.0",
|
|
143
145
|
"config": {
|
|
144
|
-
"libvips": "8.10.
|
|
146
|
+
"libvips": "8.10.6",
|
|
145
147
|
"runtime": "napi",
|
|
146
148
|
"target": 3
|
|
147
149
|
},
|