sharp 0.33.5 → 0.35.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 +12 -18
- package/dist/channel.cjs +177 -0
- package/{lib/channel.js → dist/channel.mjs} +11 -8
- package/dist/colour.cjs +199 -0
- package/{lib/colour.js → dist/colour.mjs} +42 -23
- package/dist/composite.cjs +213 -0
- package/{lib/composite.js → dist/composite.mjs} +14 -11
- package/{lib/constructor.js → dist/constructor.cjs} +102 -43
- package/dist/constructor.mjs +511 -0
- package/dist/index.cjs +25 -0
- package/dist/index.d.cts +1999 -0
- package/dist/index.d.mts +2046 -0
- package/dist/index.mjs +25 -0
- package/dist/input.cjs +814 -0
- package/{lib/input.js → dist/input.mjs} +232 -76
- package/{lib/is.js → dist/is.cjs} +19 -45
- package/dist/is.mjs +143 -0
- package/{lib/libvips.js → dist/libvips.cjs} +52 -43
- package/dist/libvips.mjs +212 -0
- package/dist/operation.cjs +998 -0
- package/{lib/operation.js → dist/operation.mjs} +131 -91
- package/{lib/output.js → dist/output.cjs} +262 -61
- package/dist/output.mjs +1788 -0
- package/dist/resize.cjs +617 -0
- package/{lib/resize.js → dist/resize.mjs} +65 -35
- package/dist/sharp.cjs +174 -0
- package/dist/sharp.mjs +174 -0
- package/{lib/utility.js → dist/utility.cjs} +30 -25
- package/dist/utility.mjs +301 -0
- package/install/build.js +38 -0
- package/lib/index.d.ts +387 -142
- package/package.json +90 -85
- package/src/binding.gyp +49 -26
- package/src/common.cc +203 -111
- package/src/common.h +68 -40
- package/src/metadata.cc +106 -22
- package/src/metadata.h +15 -5
- package/src/operations.cc +62 -21
- package/src/operations.h +15 -3
- package/src/pipeline.cc +391 -201
- package/src/pipeline.h +36 -7
- package/src/sharp.cc +11 -8
- package/src/stats.cc +16 -13
- package/src/stats.h +6 -3
- package/src/utilities.cc +35 -15
- package/src/utilities.h +5 -2
- package/install/check.js +0 -41
- package/lib/index.js +0 -16
- package/lib/sharp.js +0 -114
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/*!
|
|
2
|
+
Copyright 2013 Lovell Fuller and others.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
5
|
|
|
6
6
|
const path = require('node:path');
|
|
7
|
-
const is = require('./is');
|
|
8
|
-
const sharp = require('./sharp');
|
|
7
|
+
const is = require('./is.cjs');
|
|
8
|
+
const sharp = require('./sharp.cjs');
|
|
9
9
|
|
|
10
10
|
const formats = new Map([
|
|
11
11
|
['heic', 'heif'],
|
|
@@ -43,7 +43,7 @@ const bitdepthFromColourCount = (colours) => 1 << 31 - Math.clz32(Math.ceil(Math
|
|
|
43
43
|
* Note that raw pixel data is only supported for buffer output.
|
|
44
44
|
*
|
|
45
45
|
* By default all metadata will be removed, which includes EXIF-based orientation.
|
|
46
|
-
* See {@link #withmetadata
|
|
46
|
+
* See {@link #withmetadata withMetadata} for control over this.
|
|
47
47
|
*
|
|
48
48
|
* The caller is responsible for ensuring directory structures and permissions exist.
|
|
49
49
|
*
|
|
@@ -76,7 +76,7 @@ function toFile (fileOut, callback) {
|
|
|
76
76
|
err = new Error('Missing output file path');
|
|
77
77
|
} else if (is.string(this.options.input.file) && path.resolve(this.options.input.file) === path.resolve(fileOut)) {
|
|
78
78
|
err = new Error('Cannot use same file for input and output');
|
|
79
|
-
} else if (jp2Regex.test(path.extname(fileOut)) && !this.constructor.format.
|
|
79
|
+
} else if (jp2Regex.test(path.extname(fileOut)) && !this.constructor.format.jp2.output.file) {
|
|
80
80
|
err = errJp2Save();
|
|
81
81
|
}
|
|
82
82
|
if (err) {
|
|
@@ -97,12 +97,12 @@ function toFile (fileOut, callback) {
|
|
|
97
97
|
* Write output to a Buffer.
|
|
98
98
|
* JPEG, PNG, WebP, AVIF, TIFF, GIF and raw pixel data output are supported.
|
|
99
99
|
*
|
|
100
|
-
* Use {@link #toformat
|
|
100
|
+
* Use {@link #toformat toFormat} or one of the format-specific functions such as {@link #jpeg jpeg}, {@link #png png} etc. to set the output format.
|
|
101
101
|
*
|
|
102
102
|
* If no explicit format is set, the output format will match the input image, except SVG input which becomes PNG output.
|
|
103
103
|
*
|
|
104
104
|
* By default all metadata will be removed, which includes EXIF-based orientation.
|
|
105
|
-
* See {@link #withmetadata
|
|
105
|
+
* See {@link #withmetadata withMetadata} for control over this.
|
|
106
106
|
*
|
|
107
107
|
* `callback`, if present, gets three arguments `(err, data, info)` where:
|
|
108
108
|
* - `err` is an error, if any.
|
|
@@ -113,24 +113,20 @@ function toFile (fileOut, callback) {
|
|
|
113
113
|
* Animated output will also contain `pageHeight` and `pages`.
|
|
114
114
|
* May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text.
|
|
115
115
|
*
|
|
116
|
-
*
|
|
116
|
+
* The underlying `ArrayBuffer` may be marked as non-transferable by some JavaScript runtimes.
|
|
117
|
+
* Use {@link #touint8array toUint8Array} for a guaranteed transferable `ArrayBuffer`.
|
|
117
118
|
*
|
|
118
|
-
*
|
|
119
|
-
* sharp(input)
|
|
120
|
-
* .toBuffer((err, data, info) => { ... });
|
|
119
|
+
* A `Promise` is returned when `callback` is not provided.
|
|
121
120
|
*
|
|
122
121
|
* @example
|
|
123
|
-
* sharp(input)
|
|
124
|
-
* .
|
|
125
|
-
* .
|
|
126
|
-
* .catch(err => { ... });
|
|
122
|
+
* const data = await sharp(input)
|
|
123
|
+
* .png()
|
|
124
|
+
* .toBuffer();
|
|
127
125
|
*
|
|
128
126
|
* @example
|
|
129
|
-
* sharp(input)
|
|
127
|
+
* const { data, info } = await sharp(input)
|
|
130
128
|
* .png()
|
|
131
|
-
* .toBuffer({ resolveWithObject: true })
|
|
132
|
-
* .then(({ data, info }) => { ... })
|
|
133
|
-
* .catch(err => { ... });
|
|
129
|
+
* .toBuffer({ resolveWithObject: true });
|
|
134
130
|
*
|
|
135
131
|
* @example
|
|
136
132
|
* const { data, info } = await sharp('my-image.jpg')
|
|
@@ -164,6 +160,64 @@ function toBuffer (options, callback) {
|
|
|
164
160
|
return this._pipeline(is.fn(options) ? options : callback, stack);
|
|
165
161
|
}
|
|
166
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Write output to a `Uint8Array` backed by a transferable `ArrayBuffer`.
|
|
165
|
+
* JPEG, PNG, WebP, AVIF, TIFF, GIF and raw pixel data output are supported.
|
|
166
|
+
*
|
|
167
|
+
* Use {@link #toformat toFormat} or one of the format-specific functions such as {@link #jpeg jpeg}, {@link #png png} etc. to set the output format.
|
|
168
|
+
*
|
|
169
|
+
* If no explicit format is set, the output format will match the input image, except SVG input which becomes PNG output.
|
|
170
|
+
*
|
|
171
|
+
* By default all metadata will be removed, which includes EXIF-based orientation.
|
|
172
|
+
* See {@link #keepexif keepExif} and similar methods for control over this.
|
|
173
|
+
*
|
|
174
|
+
* Resolves with an `Object` containing:
|
|
175
|
+
* - `data` is the output image as a `Uint8Array` backed by a transferable `ArrayBuffer`.
|
|
176
|
+
* - `info` contains properties relating to the output image such as `width` and `height`.
|
|
177
|
+
*
|
|
178
|
+
* @since v0.35.0
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* const { data, info } = await sharp(input).toUint8Array();
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* const { data } = await sharp(input)
|
|
185
|
+
* .avif()
|
|
186
|
+
* .toUint8Array();
|
|
187
|
+
* const base64String = data.toBase64();
|
|
188
|
+
*
|
|
189
|
+
* @returns {Promise<{ data: Uint8Array, info: Object }>}
|
|
190
|
+
*/
|
|
191
|
+
function toUint8Array () {
|
|
192
|
+
this.options.resolveWithObject = true;
|
|
193
|
+
this.options.typedArrayOut = true;
|
|
194
|
+
const stack = Error();
|
|
195
|
+
return this._pipeline(null, stack);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Set output density (DPI) in EXIF metadata.
|
|
200
|
+
*
|
|
201
|
+
* @since 0.35.0
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* const data = await sharp(input)
|
|
205
|
+
* .withDensity(96)
|
|
206
|
+
* .toBuffer();
|
|
207
|
+
*
|
|
208
|
+
* @param {number} density Number of pixels per inch (DPI).
|
|
209
|
+
* @returns {Sharp}
|
|
210
|
+
* @throws {Error} Invalid parameters
|
|
211
|
+
*/
|
|
212
|
+
function withDensity (density) {
|
|
213
|
+
if (is.number(density) && density > 0) {
|
|
214
|
+
this.options.withMetadataDensity = density;
|
|
215
|
+
} else {
|
|
216
|
+
throw is.invalidParameterError('density', 'positive number', density);
|
|
217
|
+
}
|
|
218
|
+
return this.keepExif();
|
|
219
|
+
}
|
|
220
|
+
|
|
167
221
|
/**
|
|
168
222
|
* Keep all EXIF metadata from the input image in the output image.
|
|
169
223
|
*
|
|
@@ -256,7 +310,7 @@ function withExifMerge (exif) {
|
|
|
256
310
|
/**
|
|
257
311
|
* Keep ICC profile from the input image in the output image.
|
|
258
312
|
*
|
|
259
|
-
*
|
|
313
|
+
* When input and output colour spaces differ, use with {@link /api-colour/#tocolourspace toColourspace} and optionally {@link /api-colour/#pipelinecolourspace pipelineColourspace}.
|
|
260
314
|
*
|
|
261
315
|
* @since 0.33.0
|
|
262
316
|
*
|
|
@@ -265,6 +319,13 @@ function withExifMerge (exif) {
|
|
|
265
319
|
* .keepIccProfile()
|
|
266
320
|
* .toBuffer();
|
|
267
321
|
*
|
|
322
|
+
* @example
|
|
323
|
+
* const cmykOutputWithIccProfile = await sharp(cmykInputWithIccProfile)
|
|
324
|
+
* .pipelineColourspace('cmyk')
|
|
325
|
+
* .toColourspace('cmyk')
|
|
326
|
+
* .keepIccProfile()
|
|
327
|
+
* .toBuffer();
|
|
328
|
+
*
|
|
268
329
|
* @returns {Sharp}
|
|
269
330
|
*/
|
|
270
331
|
function keepIccProfile () {
|
|
@@ -312,6 +373,113 @@ function withIccProfile (icc, options) {
|
|
|
312
373
|
return this;
|
|
313
374
|
}
|
|
314
375
|
|
|
376
|
+
/**
|
|
377
|
+
* If the input contains gain map metadata, attempt to process the image and gain map separately,
|
|
378
|
+
* recombining them into a single output image.
|
|
379
|
+
*
|
|
380
|
+
* This approach is faster and should produce better results than {@link #withgainmap withGainMap},
|
|
381
|
+
* however not all operations are supported.
|
|
382
|
+
*
|
|
383
|
+
* Only JPEG input and output are supported.
|
|
384
|
+
* JPEG output options other than `quality` are ignored.
|
|
385
|
+
*
|
|
386
|
+
* This feature is experimental and the API may change.
|
|
387
|
+
*
|
|
388
|
+
* @since 0.35.0
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* const outputWithResizedGainMap = await sharp(inputWithGainMap)
|
|
392
|
+
* .keepGainMap()
|
|
393
|
+
* .resize({ width: 64 })
|
|
394
|
+
* .toBuffer();
|
|
395
|
+
*
|
|
396
|
+
* @returns {Sharp}
|
|
397
|
+
*/
|
|
398
|
+
function keepGainMap() {
|
|
399
|
+
this.options.keepGainMap = true;
|
|
400
|
+
this.options.withGainMap = false;
|
|
401
|
+
this.options.keepMetadata |= 0b100000;
|
|
402
|
+
return this;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* If the input contains gain map metadata, use it to convert the main image to HDR (High Dynamic Range) before further processing.
|
|
407
|
+
* The input gain map is discarded.
|
|
408
|
+
*
|
|
409
|
+
* If the output is JPEG, generate and attach a new ISO 21496-1 gain map.
|
|
410
|
+
* JPEG output options other than `quality` are ignored.
|
|
411
|
+
*
|
|
412
|
+
* This feature is experimental and the API may change.
|
|
413
|
+
*
|
|
414
|
+
* @since 0.35.0
|
|
415
|
+
*
|
|
416
|
+
* @example
|
|
417
|
+
* const outputWithRegeneratedGainMap = await sharp(inputWithGainMap)
|
|
418
|
+
* .withGainMap()
|
|
419
|
+
* .toBuffer();
|
|
420
|
+
*
|
|
421
|
+
* @returns {Sharp}
|
|
422
|
+
*/
|
|
423
|
+
function withGainMap() {
|
|
424
|
+
this.options.withGainMap = true;
|
|
425
|
+
this.options.keepGainMap = false;
|
|
426
|
+
this.options.colourspace = 'scrgb';
|
|
427
|
+
return this;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Keep XMP metadata from the input image in the output image.
|
|
432
|
+
*
|
|
433
|
+
* @since 0.34.3
|
|
434
|
+
*
|
|
435
|
+
* @example
|
|
436
|
+
* const outputWithXmp = await sharp(inputWithXmp)
|
|
437
|
+
* .keepXmp()
|
|
438
|
+
* .toBuffer();
|
|
439
|
+
*
|
|
440
|
+
* @returns {Sharp}
|
|
441
|
+
*/
|
|
442
|
+
function keepXmp () {
|
|
443
|
+
this.options.keepMetadata |= 0b00010;
|
|
444
|
+
return this;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Set XMP metadata in the output image.
|
|
449
|
+
*
|
|
450
|
+
* Supported by PNG, JPEG, WebP, and TIFF output.
|
|
451
|
+
*
|
|
452
|
+
* @since 0.34.3
|
|
453
|
+
*
|
|
454
|
+
* @example
|
|
455
|
+
* const xmpString = `
|
|
456
|
+
* <?xml version="1.0"?>
|
|
457
|
+
* <x:xmpmeta xmlns:x="adobe:ns:meta/">
|
|
458
|
+
* <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
|
459
|
+
* <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
460
|
+
* <dc:creator><rdf:Seq><rdf:li>John Doe</rdf:li></rdf:Seq></dc:creator>
|
|
461
|
+
* </rdf:Description>
|
|
462
|
+
* </rdf:RDF>
|
|
463
|
+
* </x:xmpmeta>`;
|
|
464
|
+
*
|
|
465
|
+
* const data = await sharp(input)
|
|
466
|
+
* .withXmp(xmpString)
|
|
467
|
+
* .toBuffer();
|
|
468
|
+
*
|
|
469
|
+
* @param {string} xmp String containing XMP metadata to be embedded in the output image.
|
|
470
|
+
* @returns {Sharp}
|
|
471
|
+
* @throws {Error} Invalid parameters
|
|
472
|
+
*/
|
|
473
|
+
function withXmp (xmp) {
|
|
474
|
+
if (is.string(xmp) && xmp.length > 0) {
|
|
475
|
+
this.options.withXmp = xmp;
|
|
476
|
+
this.options.keepMetadata |= 0b00010;
|
|
477
|
+
} else {
|
|
478
|
+
throw is.invalidParameterError('xmp', 'non-empty string', xmp);
|
|
479
|
+
}
|
|
480
|
+
return this;
|
|
481
|
+
}
|
|
482
|
+
|
|
315
483
|
/**
|
|
316
484
|
* Keep all metadata (EXIF, ICC, XMP, IPTC) from the input image in the output image.
|
|
317
485
|
*
|
|
@@ -328,7 +496,7 @@ function withIccProfile (icc, options) {
|
|
|
328
496
|
* @returns {Sharp}
|
|
329
497
|
*/
|
|
330
498
|
function keepMetadata () {
|
|
331
|
-
this.options.keepMetadata
|
|
499
|
+
this.options.keepMetadata |= 0b11111;
|
|
332
500
|
return this;
|
|
333
501
|
}
|
|
334
502
|
|
|
@@ -512,7 +680,7 @@ function jpeg (options) {
|
|
|
512
680
|
* Set `palette` to `true` for slower, indexed PNG output.
|
|
513
681
|
*
|
|
514
682
|
* For 16 bits per pixel output, convert to `rgb16` via
|
|
515
|
-
* {@link /api-colour
|
|
683
|
+
* {@link /api-colour/#tocolourspace toColourspace}.
|
|
516
684
|
*
|
|
517
685
|
* @example
|
|
518
686
|
* // Convert any input to full colour PNG output
|
|
@@ -623,12 +791,14 @@ function png (options) {
|
|
|
623
791
|
* @param {boolean} [options.lossless=false] - use lossless compression mode
|
|
624
792
|
* @param {boolean} [options.nearLossless=false] - use near_lossless compression mode
|
|
625
793
|
* @param {boolean} [options.smartSubsample=false] - use high quality chroma subsampling
|
|
794
|
+
* @param {boolean} [options.smartDeblock=false] - auto-adjust the deblocking filter, can improve low contrast edges (slow)
|
|
626
795
|
* @param {string} [options.preset='default'] - named preset for preprocessing/filtering, one of: default, photo, picture, drawing, icon, text
|
|
627
796
|
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 6 (slowest)
|
|
628
797
|
* @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation
|
|
629
798
|
* @param {number|number[]} [options.delay] - delay(s) between animation frames (in milliseconds)
|
|
630
799
|
* @param {boolean} [options.minSize=false] - prevent use of animation key frames to minimise file size (slow)
|
|
631
800
|
* @param {boolean} [options.mixed=false] - allow mixture of lossy and lossless animation frames (slow)
|
|
801
|
+
* @param {boolean} [options.exact=false] - preserve the colour data in transparent pixels
|
|
632
802
|
* @param {boolean} [options.force=true] - force WebP output, otherwise attempt to use input format
|
|
633
803
|
* @returns {Sharp}
|
|
634
804
|
* @throws {Error} Invalid options
|
|
@@ -658,6 +828,9 @@ function webp (options) {
|
|
|
658
828
|
if (is.defined(options.smartSubsample)) {
|
|
659
829
|
this._setBooleanOption('webpSmartSubsample', options.smartSubsample);
|
|
660
830
|
}
|
|
831
|
+
if (is.defined(options.smartDeblock)) {
|
|
832
|
+
this._setBooleanOption('webpSmartDeblock', options.smartDeblock);
|
|
833
|
+
}
|
|
661
834
|
if (is.defined(options.preset)) {
|
|
662
835
|
if (is.string(options.preset) && is.inArray(options.preset, ['default', 'photo', 'picture', 'drawing', 'icon', 'text'])) {
|
|
663
836
|
this.options.webpPreset = options.preset;
|
|
@@ -678,6 +851,9 @@ function webp (options) {
|
|
|
678
851
|
if (is.defined(options.mixed)) {
|
|
679
852
|
this._setBooleanOption('webpMixed', options.mixed);
|
|
680
853
|
}
|
|
854
|
+
if (is.defined(options.exact)) {
|
|
855
|
+
this._setBooleanOption('webpExact', options.exact);
|
|
856
|
+
}
|
|
681
857
|
}
|
|
682
858
|
trySetAnimationOptions(options, this.options);
|
|
683
859
|
return this._updateFormatOut('webp', options);
|
|
@@ -725,6 +901,7 @@ function webp (options) {
|
|
|
725
901
|
* @param {number} [options.dither=1.0] - level of Floyd-Steinberg error diffusion, between 0 (least) and 1 (most)
|
|
726
902
|
* @param {number} [options.interFrameMaxError=0] - maximum inter-frame error for transparency, between 0 (lossless) and 32
|
|
727
903
|
* @param {number} [options.interPaletteMaxError=3] - maximum inter-palette error for palette reuse, between 0 and 256
|
|
904
|
+
* @param {boolean} [options.keepDuplicateFrames=false] - keep duplicate frames in the output instead of combining them
|
|
728
905
|
* @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation
|
|
729
906
|
* @param {number|number[]} [options.delay] - delay(s) between animation frames (in milliseconds)
|
|
730
907
|
* @param {boolean} [options.force=true] - force GIF output, otherwise attempt to use input format
|
|
@@ -748,7 +925,7 @@ function gif (options) {
|
|
|
748
925
|
}
|
|
749
926
|
}
|
|
750
927
|
if (is.defined(options.effort)) {
|
|
751
|
-
if (is.
|
|
928
|
+
if (is.integer(options.effort) && is.inRange(options.effort, 1, 10)) {
|
|
752
929
|
this.options.gifEffort = options.effort;
|
|
753
930
|
} else {
|
|
754
931
|
throw is.invalidParameterError('effort', 'integer between 1 and 10', options.effort);
|
|
@@ -775,18 +952,24 @@ function gif (options) {
|
|
|
775
952
|
throw is.invalidParameterError('interPaletteMaxError', 'number between 0.0 and 256.0', options.interPaletteMaxError);
|
|
776
953
|
}
|
|
777
954
|
}
|
|
955
|
+
if (is.defined(options.keepDuplicateFrames)) {
|
|
956
|
+
if (is.bool(options.keepDuplicateFrames)) {
|
|
957
|
+
this._setBooleanOption('gifKeepDuplicateFrames', options.keepDuplicateFrames);
|
|
958
|
+
} else {
|
|
959
|
+
throw is.invalidParameterError('keepDuplicateFrames', 'boolean', options.keepDuplicateFrames);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
778
962
|
}
|
|
779
963
|
trySetAnimationOptions(options, this.options);
|
|
780
964
|
return this._updateFormatOut('gif', options);
|
|
781
965
|
}
|
|
782
966
|
|
|
783
|
-
/* istanbul ignore next */
|
|
784
967
|
/**
|
|
785
968
|
* Use these JP2 options for output image.
|
|
786
969
|
*
|
|
787
970
|
* Requires libvips compiled with support for OpenJPEG.
|
|
788
971
|
* The prebuilt binaries do not include this - see
|
|
789
|
-
* {@link
|
|
972
|
+
* {@link /install#custom-libvips installing a custom libvips}.
|
|
790
973
|
*
|
|
791
974
|
* @example
|
|
792
975
|
* // Convert any input to lossless JP2 output
|
|
@@ -815,7 +998,8 @@ function gif (options) {
|
|
|
815
998
|
* @throws {Error} Invalid options
|
|
816
999
|
*/
|
|
817
1000
|
function jp2 (options) {
|
|
818
|
-
|
|
1001
|
+
/* node:coverage ignore next 41 */
|
|
1002
|
+
if (!this.constructor.format.jp2.output.buffer) {
|
|
819
1003
|
throw errJp2Save();
|
|
820
1004
|
}
|
|
821
1005
|
if (is.object(options)) {
|
|
@@ -894,7 +1078,7 @@ function trySetAnimationOptions (source, target) {
|
|
|
894
1078
|
/**
|
|
895
1079
|
* Use these TIFF options for output image.
|
|
896
1080
|
*
|
|
897
|
-
* The `density` can be set in pixels/inch via {@link #withmetadata
|
|
1081
|
+
* The `density` can be set in pixels/inch via {@link #withmetadata withMetadata}
|
|
898
1082
|
* instead of providing `xres` and `yres` in pixels/mm.
|
|
899
1083
|
*
|
|
900
1084
|
* @example
|
|
@@ -911,15 +1095,16 @@ function trySetAnimationOptions (source, target) {
|
|
|
911
1095
|
* @param {number} [options.quality=80] - quality, integer 1-100
|
|
912
1096
|
* @param {boolean} [options.force=true] - force TIFF output, otherwise attempt to use input format
|
|
913
1097
|
* @param {string} [options.compression='jpeg'] - compression options: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k
|
|
1098
|
+
* @param {boolean} [options.bigtiff=false] - use BigTIFF variant (has no effect when compression is none)
|
|
914
1099
|
* @param {string} [options.predictor='horizontal'] - compression predictor options: none, horizontal, float
|
|
915
1100
|
* @param {boolean} [options.pyramid=false] - write an image pyramid
|
|
916
1101
|
* @param {boolean} [options.tile=false] - write a tiled tiff
|
|
917
|
-
* @param {number} [options.tileWidth=256] - horizontal tile size
|
|
918
|
-
* @param {number} [options.tileHeight=256] - vertical tile size
|
|
919
|
-
* @param {number} [options.xres=1.0] - horizontal resolution in pixels/mm
|
|
920
|
-
* @param {number} [options.yres=1.0] - vertical resolution in pixels/mm
|
|
1102
|
+
* @param {number} [options.tileWidth=256] - horizontal tile size, valid values are integers in the range 1-32768
|
|
1103
|
+
* @param {number} [options.tileHeight=256] - vertical tile size, valid values are integers in the range 1-32768
|
|
1104
|
+
* @param {number} [options.xres=1.0] - horizontal resolution in pixels/mm, valid values are numbers in the range 0.001-1000000
|
|
1105
|
+
* @param {number} [options.yres=1.0] - vertical resolution in pixels/mm, valid values are numbers in the range 0.001-1000000
|
|
921
1106
|
* @param {string} [options.resolutionUnit='inch'] - resolution unit options: inch, cm
|
|
922
|
-
* @param {number} [options.bitdepth=
|
|
1107
|
+
* @param {number} [options.bitdepth=0] - reduce bitdepth to 1, 2 or 4 bit
|
|
923
1108
|
* @param {boolean} [options.miniswhite=false] - write 1-bit images as miniswhite
|
|
924
1109
|
* @returns {Sharp}
|
|
925
1110
|
* @throws {Error} Invalid options
|
|
@@ -934,10 +1119,10 @@ function tiff (options) {
|
|
|
934
1119
|
}
|
|
935
1120
|
}
|
|
936
1121
|
if (is.defined(options.bitdepth)) {
|
|
937
|
-
if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [1, 2, 4
|
|
1122
|
+
if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [1, 2, 4])) {
|
|
938
1123
|
this.options.tiffBitdepth = options.bitdepth;
|
|
939
1124
|
} else {
|
|
940
|
-
throw is.invalidParameterError('bitdepth', '1, 2
|
|
1125
|
+
throw is.invalidParameterError('bitdepth', '1, 2 or 4', options.bitdepth);
|
|
941
1126
|
}
|
|
942
1127
|
}
|
|
943
1128
|
// tiling
|
|
@@ -945,17 +1130,17 @@ function tiff (options) {
|
|
|
945
1130
|
this._setBooleanOption('tiffTile', options.tile);
|
|
946
1131
|
}
|
|
947
1132
|
if (is.defined(options.tileWidth)) {
|
|
948
|
-
if (is.integer(options.tileWidth) && options.tileWidth
|
|
1133
|
+
if (is.integer(options.tileWidth) && is.inRange(options.tileWidth, 1, 32768)) {
|
|
949
1134
|
this.options.tiffTileWidth = options.tileWidth;
|
|
950
1135
|
} else {
|
|
951
|
-
throw is.invalidParameterError('tileWidth', 'integer
|
|
1136
|
+
throw is.invalidParameterError('tileWidth', 'integer between 1 and 32768', options.tileWidth);
|
|
952
1137
|
}
|
|
953
1138
|
}
|
|
954
1139
|
if (is.defined(options.tileHeight)) {
|
|
955
|
-
if (is.integer(options.tileHeight) && options.tileHeight
|
|
1140
|
+
if (is.integer(options.tileHeight) && is.inRange(options.tileHeight, 1, 32768)) {
|
|
956
1141
|
this.options.tiffTileHeight = options.tileHeight;
|
|
957
1142
|
} else {
|
|
958
|
-
throw is.invalidParameterError('tileHeight', 'integer
|
|
1143
|
+
throw is.invalidParameterError('tileHeight', 'integer between 1 and 32768', options.tileHeight);
|
|
959
1144
|
}
|
|
960
1145
|
}
|
|
961
1146
|
// miniswhite
|
|
@@ -968,17 +1153,17 @@ function tiff (options) {
|
|
|
968
1153
|
}
|
|
969
1154
|
// resolution
|
|
970
1155
|
if (is.defined(options.xres)) {
|
|
971
|
-
if (is.number(options.xres) && options.xres
|
|
1156
|
+
if (is.number(options.xres) && is.inRange(options.xres, 0.001, 1000000)) {
|
|
972
1157
|
this.options.tiffXres = options.xres;
|
|
973
1158
|
} else {
|
|
974
|
-
throw is.invalidParameterError('xres', 'number
|
|
1159
|
+
throw is.invalidParameterError('xres', 'number between 0.001 and 1000000', options.xres);
|
|
975
1160
|
}
|
|
976
1161
|
}
|
|
977
1162
|
if (is.defined(options.yres)) {
|
|
978
|
-
if (is.number(options.yres) && options.yres
|
|
1163
|
+
if (is.number(options.yres) && is.inRange(options.yres, 0.001, 1000000)) {
|
|
979
1164
|
this.options.tiffYres = options.yres;
|
|
980
1165
|
} else {
|
|
981
|
-
throw is.invalidParameterError('yres', 'number
|
|
1166
|
+
throw is.invalidParameterError('yres', 'number between 0.001 and 1000000', options.yres);
|
|
982
1167
|
}
|
|
983
1168
|
}
|
|
984
1169
|
// compression
|
|
@@ -989,6 +1174,10 @@ function tiff (options) {
|
|
|
989
1174
|
throw is.invalidParameterError('compression', 'one of: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k', options.compression);
|
|
990
1175
|
}
|
|
991
1176
|
}
|
|
1177
|
+
// bigtiff
|
|
1178
|
+
if (is.defined(options.bigtiff)) {
|
|
1179
|
+
this._setBooleanOption('tiffBigtiff', options.bigtiff);
|
|
1180
|
+
}
|
|
992
1181
|
// predictor
|
|
993
1182
|
if (is.defined(options.predictor)) {
|
|
994
1183
|
if (is.string(options.predictor) && is.inArray(options.predictor, ['none', 'horizontal', 'float'])) {
|
|
@@ -1013,7 +1202,6 @@ function tiff (options) {
|
|
|
1013
1202
|
* Use these AVIF options for output image.
|
|
1014
1203
|
*
|
|
1015
1204
|
* AVIF image sequences are not supported.
|
|
1016
|
-
* Prebuilt binaries support a bitdepth of 8 only.
|
|
1017
1205
|
*
|
|
1018
1206
|
* @example
|
|
1019
1207
|
* const data = await sharp(input)
|
|
@@ -1033,6 +1221,7 @@ function tiff (options) {
|
|
|
1033
1221
|
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
|
|
1034
1222
|
* @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
|
|
1035
1223
|
* @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit
|
|
1224
|
+
* @param {string} [options.tune='auto'] - tune output for a quality metric, one of 'auto' (default), 'iq', 'psnr' or 'ssim'
|
|
1036
1225
|
* @returns {Sharp}
|
|
1037
1226
|
* @throws {Error} Invalid options
|
|
1038
1227
|
*/
|
|
@@ -1060,6 +1249,7 @@ function avif (options) {
|
|
|
1060
1249
|
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
|
|
1061
1250
|
* @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
|
|
1062
1251
|
* @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit
|
|
1252
|
+
* @param {string} [options.tune='auto'] - tune output for a quality metric, one of 'auto' (default), 'iq', 'psnr' or 'ssim'
|
|
1063
1253
|
* @returns {Sharp}
|
|
1064
1254
|
* @throws {Error} Invalid options
|
|
1065
1255
|
*/
|
|
@@ -1100,14 +1290,22 @@ function heif (options) {
|
|
|
1100
1290
|
}
|
|
1101
1291
|
if (is.defined(options.bitdepth)) {
|
|
1102
1292
|
if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [8, 10, 12])) {
|
|
1103
|
-
if (options.bitdepth !== 8 && this.constructor.versions.heif) {
|
|
1104
|
-
throw is.invalidParameterError('bitdepth when using prebuilt binaries', 8, options.bitdepth);
|
|
1105
|
-
}
|
|
1106
1293
|
this.options.heifBitdepth = options.bitdepth;
|
|
1107
1294
|
} else {
|
|
1108
1295
|
throw is.invalidParameterError('bitdepth', '8, 10 or 12', options.bitdepth);
|
|
1109
1296
|
}
|
|
1110
1297
|
}
|
|
1298
|
+
if (is.defined(options.tune)) {
|
|
1299
|
+
if (is.string(options.tune) && is.inArray(options.tune, ['auto', 'iq', 'psnr', 'ssim'])) {
|
|
1300
|
+
if (this.options.heifLossless && options.tune === 'iq') {
|
|
1301
|
+
this.options.heifTune = 'ssim';
|
|
1302
|
+
} else {
|
|
1303
|
+
this.options.heifTune = options.tune;
|
|
1304
|
+
}
|
|
1305
|
+
} else {
|
|
1306
|
+
throw is.invalidParameterError('tune', 'one of: auto, iq, psnr, ssim', options.tune);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1111
1309
|
} else {
|
|
1112
1310
|
throw is.invalidParameterError('options', 'Object', options);
|
|
1113
1311
|
}
|
|
@@ -1121,9 +1319,7 @@ function heif (options) {
|
|
|
1121
1319
|
*
|
|
1122
1320
|
* Requires libvips compiled with support for libjxl.
|
|
1123
1321
|
* The prebuilt binaries do not include this - see
|
|
1124
|
-
* {@link
|
|
1125
|
-
*
|
|
1126
|
-
* Image metadata (EXIF, XMP) is unsupported.
|
|
1322
|
+
* {@link /install/#custom-libvips installing a custom libvips}.
|
|
1127
1323
|
*
|
|
1128
1324
|
* @since 0.31.3
|
|
1129
1325
|
*
|
|
@@ -1132,7 +1328,9 @@ function heif (options) {
|
|
|
1132
1328
|
* @param {number} [options.quality] - calculate `distance` based on JPEG-like quality, between 1 and 100, overrides distance if specified
|
|
1133
1329
|
* @param {number} [options.decodingTier=0] - target decode speed tier, between 0 (highest quality) and 4 (lowest quality)
|
|
1134
1330
|
* @param {boolean} [options.lossless=false] - use lossless compression
|
|
1135
|
-
* @param {number} [options.effort=7] - CPU effort, between
|
|
1331
|
+
* @param {number} [options.effort=7] - CPU effort, between 1 (fastest) and 9 (slowest)
|
|
1332
|
+
* @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation
|
|
1333
|
+
* @param {number|number[]} [options.delay] - delay(s) between animation frames (in milliseconds)
|
|
1136
1334
|
* @returns {Sharp}
|
|
1137
1335
|
* @throws {Error} Invalid options
|
|
1138
1336
|
*/
|
|
@@ -1169,13 +1367,14 @@ function jxl (options) {
|
|
|
1169
1367
|
}
|
|
1170
1368
|
}
|
|
1171
1369
|
if (is.defined(options.effort)) {
|
|
1172
|
-
if (is.integer(options.effort) && is.inRange(options.effort,
|
|
1370
|
+
if (is.integer(options.effort) && is.inRange(options.effort, 1, 9)) {
|
|
1173
1371
|
this.options.jxlEffort = options.effort;
|
|
1174
1372
|
} else {
|
|
1175
|
-
throw is.invalidParameterError('effort', 'integer between
|
|
1373
|
+
throw is.invalidParameterError('effort', 'integer between 1 and 9', options.effort);
|
|
1176
1374
|
}
|
|
1177
1375
|
}
|
|
1178
1376
|
}
|
|
1377
|
+
trySetAnimationOptions(options, this.options);
|
|
1179
1378
|
return this._updateFormatOut('jxl', options);
|
|
1180
1379
|
}
|
|
1181
1380
|
|
|
@@ -1227,10 +1426,6 @@ function raw (options) {
|
|
|
1227
1426
|
*
|
|
1228
1427
|
* The container will be set to `zip` when the output is a Buffer or Stream, otherwise it will default to `fs`.
|
|
1229
1428
|
*
|
|
1230
|
-
* Requires libvips compiled with support for libgsf.
|
|
1231
|
-
* The prebuilt binaries do not include this - see
|
|
1232
|
-
* {@link https://sharp.pixelplumbing.com/install#custom-libvips installing a custom libvips}.
|
|
1233
|
-
*
|
|
1234
1429
|
* @example
|
|
1235
1430
|
* sharp('input.tiff')
|
|
1236
1431
|
* .png()
|
|
@@ -1437,7 +1632,6 @@ function _setBooleanOption (key, val) {
|
|
|
1437
1632
|
* @private
|
|
1438
1633
|
*/
|
|
1439
1634
|
function _read () {
|
|
1440
|
-
/* istanbul ignore else */
|
|
1441
1635
|
if (!this.options.streamOut) {
|
|
1442
1636
|
this.options.streamOut = true;
|
|
1443
1637
|
const stack = Error();
|
|
@@ -1551,18 +1745,25 @@ function _pipeline (callback, stack) {
|
|
|
1551
1745
|
|
|
1552
1746
|
/**
|
|
1553
1747
|
* Decorate the Sharp prototype with output-related functions.
|
|
1748
|
+
* @module Sharp
|
|
1554
1749
|
* @private
|
|
1555
1750
|
*/
|
|
1556
|
-
module.exports =
|
|
1751
|
+
module.exports = (Sharp) => {
|
|
1557
1752
|
Object.assign(Sharp.prototype, {
|
|
1558
1753
|
// Public
|
|
1559
1754
|
toFile,
|
|
1560
1755
|
toBuffer,
|
|
1756
|
+
toUint8Array,
|
|
1757
|
+
withDensity,
|
|
1561
1758
|
keepExif,
|
|
1562
1759
|
withExif,
|
|
1563
1760
|
withExifMerge,
|
|
1564
1761
|
keepIccProfile,
|
|
1565
1762
|
withIccProfile,
|
|
1763
|
+
keepGainMap,
|
|
1764
|
+
withGainMap,
|
|
1765
|
+
keepXmp,
|
|
1766
|
+
withXmp,
|
|
1566
1767
|
keepMetadata,
|
|
1567
1768
|
withMetadata,
|
|
1568
1769
|
toFormat,
|