@revizly/sharp 0.33.2-revizly3
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +191 -0
- package/README.md +118 -0
- package/install/check.js +41 -0
- package/lib/channel.js +174 -0
- package/lib/colour.js +182 -0
- package/lib/composite.js +210 -0
- package/lib/constructor.js +444 -0
- package/lib/index.d.ts +1723 -0
- package/lib/index.js +16 -0
- package/lib/input.js +657 -0
- package/lib/is.js +169 -0
- package/lib/libvips.js +195 -0
- package/lib/operation.js +921 -0
- package/lib/output.js +1572 -0
- package/lib/resize.js +582 -0
- package/lib/sharp.js +115 -0
- package/lib/utility.js +286 -0
- package/package.json +218 -0
- package/src/binding.gyp +280 -0
- package/src/common.cc +1090 -0
- package/src/common.h +393 -0
- package/src/metadata.cc +287 -0
- package/src/metadata.h +82 -0
- package/src/operations.cc +471 -0
- package/src/operations.h +125 -0
- package/src/pipeline.cc +1741 -0
- package/src/pipeline.h +385 -0
- package/src/sharp.cc +40 -0
- package/src/stats.cc +183 -0
- package/src/stats.h +59 -0
- package/src/utilities.cc +269 -0
- package/src/utilities.h +19 -0
@@ -0,0 +1,444 @@
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
3
|
+
|
4
|
+
'use strict';
|
5
|
+
|
6
|
+
const util = require('node:util');
|
7
|
+
const stream = require('node:stream');
|
8
|
+
const is = require('./is');
|
9
|
+
|
10
|
+
require('./sharp');
|
11
|
+
|
12
|
+
// Use NODE_DEBUG=sharp to enable libvips warnings
|
13
|
+
const debuglog = util.debuglog('sharp');
|
14
|
+
|
15
|
+
/**
|
16
|
+
* Constructor factory to create an instance of `sharp`, to which further methods are chained.
|
17
|
+
*
|
18
|
+
* JPEG, PNG, WebP, GIF, AVIF or TIFF format image data can be streamed out from this object.
|
19
|
+
* When using Stream based output, derived attributes are available from the `info` event.
|
20
|
+
*
|
21
|
+
* Non-critical problems encountered during processing are emitted as `warning` events.
|
22
|
+
*
|
23
|
+
* Implements the [stream.Duplex](http://nodejs.org/api/stream.html#stream_class_stream_duplex) class.
|
24
|
+
*
|
25
|
+
* When loading more than one page/frame of an animated image,
|
26
|
+
* these are combined as a vertically-stacked "toilet roll" image
|
27
|
+
* where the overall height is the `pageHeight` multiplied by the number of `pages`.
|
28
|
+
*
|
29
|
+
* @constructs Sharp
|
30
|
+
*
|
31
|
+
* @emits Sharp#info
|
32
|
+
* @emits Sharp#warning
|
33
|
+
*
|
34
|
+
* @example
|
35
|
+
* sharp('input.jpg')
|
36
|
+
* .resize(300, 200)
|
37
|
+
* .toFile('output.jpg', function(err) {
|
38
|
+
* // output.jpg is a 300 pixels wide and 200 pixels high image
|
39
|
+
* // containing a scaled and cropped version of input.jpg
|
40
|
+
* });
|
41
|
+
*
|
42
|
+
* @example
|
43
|
+
* // Read image data from readableStream,
|
44
|
+
* // resize to 300 pixels wide,
|
45
|
+
* // emit an 'info' event with calculated dimensions
|
46
|
+
* // and finally write image data to writableStream
|
47
|
+
* var transformer = sharp()
|
48
|
+
* .resize(300)
|
49
|
+
* .on('info', function(info) {
|
50
|
+
* console.log('Image height is ' + info.height);
|
51
|
+
* });
|
52
|
+
* readableStream.pipe(transformer).pipe(writableStream);
|
53
|
+
*
|
54
|
+
* @example
|
55
|
+
* // Create a blank 300x200 PNG image of semi-translucent red pixels
|
56
|
+
* sharp({
|
57
|
+
* create: {
|
58
|
+
* width: 300,
|
59
|
+
* height: 200,
|
60
|
+
* channels: 4,
|
61
|
+
* background: { r: 255, g: 0, b: 0, alpha: 0.5 }
|
62
|
+
* }
|
63
|
+
* })
|
64
|
+
* .png()
|
65
|
+
* .toBuffer()
|
66
|
+
* .then( ... );
|
67
|
+
*
|
68
|
+
* @example
|
69
|
+
* // Convert an animated GIF to an animated WebP
|
70
|
+
* await sharp('in.gif', { animated: true }).toFile('out.webp');
|
71
|
+
*
|
72
|
+
* @example
|
73
|
+
* // Read a raw array of pixels and save it to a png
|
74
|
+
* const input = Uint8Array.from([255, 255, 255, 0, 0, 0]); // or Uint8ClampedArray
|
75
|
+
* const image = sharp(input, {
|
76
|
+
* // because the input does not contain its dimensions or how many channels it has
|
77
|
+
* // we need to specify it in the constructor options
|
78
|
+
* raw: {
|
79
|
+
* width: 2,
|
80
|
+
* height: 1,
|
81
|
+
* channels: 3
|
82
|
+
* }
|
83
|
+
* });
|
84
|
+
* await image.toFile('my-two-pixels.png');
|
85
|
+
*
|
86
|
+
* @example
|
87
|
+
* // Generate RGB Gaussian noise
|
88
|
+
* await sharp({
|
89
|
+
* create: {
|
90
|
+
* width: 300,
|
91
|
+
* height: 200,
|
92
|
+
* channels: 3,
|
93
|
+
* noise: {
|
94
|
+
* type: 'gaussian',
|
95
|
+
* mean: 128,
|
96
|
+
* sigma: 30
|
97
|
+
* }
|
98
|
+
* }
|
99
|
+
* }).toFile('noise.png');
|
100
|
+
*
|
101
|
+
* @example
|
102
|
+
* // Generate an image from text
|
103
|
+
* await sharp({
|
104
|
+
* text: {
|
105
|
+
* text: 'Hello, world!',
|
106
|
+
* width: 400, // max width
|
107
|
+
* height: 300 // max height
|
108
|
+
* }
|
109
|
+
* }).toFile('text_bw.png');
|
110
|
+
*
|
111
|
+
* @example
|
112
|
+
* // Generate an rgba image from text using pango markup and font
|
113
|
+
* await sharp({
|
114
|
+
* text: {
|
115
|
+
* text: '<span foreground="red">Red!</span><span background="cyan">blue</span>',
|
116
|
+
* font: 'sans',
|
117
|
+
* rgba: true,
|
118
|
+
* dpi: 300
|
119
|
+
* }
|
120
|
+
* }).toFile('text_rgba.png');
|
121
|
+
*
|
122
|
+
* @param {(Buffer|ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|Uint16Array|Int16Array|Uint32Array|Int32Array|Float32Array|Float64Array|string)} [input] - if present, can be
|
123
|
+
* a Buffer / ArrayBuffer / Uint8Array / Uint8ClampedArray containing JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image data, or
|
124
|
+
* a TypedArray containing raw pixel image data, or
|
125
|
+
* a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file.
|
126
|
+
* JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
|
127
|
+
* @param {Object} [options] - if present, is an Object with optional attributes.
|
128
|
+
* @param {string} [options.failOn='warning'] - When to abort processing of invalid pixel data, one of (in order of sensitivity, least to most): 'none', 'truncated', 'error', 'warning'. Higher levels imply lower levels. Invalid metadata will always abort.
|
129
|
+
* @param {number|boolean} [options.limitInputPixels=268402689] - Do not process input images where the number of pixels
|
130
|
+
* (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted.
|
131
|
+
* An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF).
|
132
|
+
* @param {boolean} [options.unlimited=false] - Set this to `true` to remove safety features that help prevent memory exhaustion (JPEG, PNG, SVG, HEIF).
|
133
|
+
* @param {boolean} [options.sequentialRead=true] - Set this to `false` to use random access rather than sequential read. Some operations will do this automatically.
|
134
|
+
* @param {number} [options.density=72] - number representing the DPI for vector images in the range 1 to 100000.
|
135
|
+
* @param {number} [options.ignoreIcc=false] - should the embedded ICC profile, if any, be ignored.
|
136
|
+
* @param {number} [options.pages=1] - Number of pages to extract for multi-page input (GIF, WebP, TIFF), use -1 for all pages.
|
137
|
+
* @param {number} [options.page=0] - Page number to start extracting from for multi-page input (GIF, WebP, TIFF), zero based.
|
138
|
+
* @param {number} [options.subifd=-1] - subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image.
|
139
|
+
* @param {number} [options.level=0] - level to extract from a multi-level input (OpenSlide), zero based.
|
140
|
+
* @param {boolean} [options.animated=false] - Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`.
|
141
|
+
* @param {Object} [options.raw] - describes raw pixel input image data. See `raw()` for pixel ordering.
|
142
|
+
* @param {number} [options.raw.width] - integral number of pixels wide.
|
143
|
+
* @param {number} [options.raw.height] - integral number of pixels high.
|
144
|
+
* @param {number} [options.raw.channels] - integral number of channels, between 1 and 4.
|
145
|
+
* @param {boolean} [options.raw.premultiplied] - specifies that the raw input has already been premultiplied, set to `true`
|
146
|
+
* to avoid sharp premultiplying the image. (optional, default `false`)
|
147
|
+
* @param {Object} [options.create] - describes a new image to be created.
|
148
|
+
* @param {number} [options.create.width] - integral number of pixels wide.
|
149
|
+
* @param {number} [options.create.height] - integral number of pixels high.
|
150
|
+
* @param {number} [options.create.channels] - integral number of channels, either 3 (RGB) or 4 (RGBA).
|
151
|
+
* @param {string|Object} [options.create.background] - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
|
152
|
+
* @param {Object} [options.create.noise] - describes a noise to be created.
|
153
|
+
* @param {string} [options.create.noise.type] - type of generated noise, currently only `gaussian` is supported.
|
154
|
+
* @param {number} [options.create.noise.mean] - mean of pixels in generated noise.
|
155
|
+
* @param {number} [options.create.noise.sigma] - standard deviation of pixels in generated noise.
|
156
|
+
* @param {Object} [options.text] - describes a new text image to be created.
|
157
|
+
* @param {string} [options.text.text] - text to render as a UTF-8 string. It can contain Pango markup, for example `<i>Le</i>Monde`.
|
158
|
+
* @param {string} [options.text.font] - font name to render with.
|
159
|
+
* @param {string} [options.text.fontfile] - absolute filesystem path to a font file that can be used by `font`.
|
160
|
+
* @param {number} [options.text.width=0] - Integral number of pixels to word-wrap at. Lines of text wider than this will be broken at word boundaries.
|
161
|
+
* @param {number} [options.text.height=0] - Maximum integral number of pixels high. When defined, `dpi` will be ignored and the text will automatically fit the pixel resolution defined by `width` and `height`. Will be ignored if `width` is not specified or set to 0.
|
162
|
+
* @param {string} [options.text.align='left'] - Alignment style for multi-line text (`'left'`, `'centre'`, `'center'`, `'right'`).
|
163
|
+
* @param {boolean} [options.text.justify=false] - set this to true to apply justification to the text.
|
164
|
+
* @param {number} [options.text.dpi=72] - the resolution (size) at which to render the text. Does not take effect if `height` is specified.
|
165
|
+
* @param {boolean} [options.text.rgba=false] - set this to true to enable RGBA output. This is useful for colour emoji rendering, or support for pango markup features like `<span foreground="red">Red!</span>`.
|
166
|
+
* @param {number} [options.text.spacing=0] - text line height in points. Will use the font line height if none is specified.
|
167
|
+
* @param {string} [options.text.wrap='word'] - word wrapping style when width is provided, one of: 'word', 'char', 'charWord' (prefer char, fallback to word) or 'none'.
|
168
|
+
* @returns {Sharp}
|
169
|
+
* @throws {Error} Invalid parameters
|
170
|
+
*/
|
171
|
+
const Sharp = function (input, options) {
|
172
|
+
if (arguments.length === 1 && !is.defined(input)) {
|
173
|
+
throw new Error('Invalid input');
|
174
|
+
}
|
175
|
+
if (!(this instanceof Sharp)) {
|
176
|
+
return new Sharp(input, options);
|
177
|
+
}
|
178
|
+
stream.Duplex.call(this);
|
179
|
+
this.options = {
|
180
|
+
// resize options
|
181
|
+
topOffsetPre: -1,
|
182
|
+
leftOffsetPre: -1,
|
183
|
+
widthPre: -1,
|
184
|
+
heightPre: -1,
|
185
|
+
topOffsetPost: -1,
|
186
|
+
leftOffsetPost: -1,
|
187
|
+
widthPost: -1,
|
188
|
+
heightPost: -1,
|
189
|
+
width: -1,
|
190
|
+
height: -1,
|
191
|
+
canvas: 'crop',
|
192
|
+
position: 0,
|
193
|
+
resizeBackground: [0, 0, 0, 255],
|
194
|
+
useExifOrientation: false,
|
195
|
+
angle: 0,
|
196
|
+
rotationAngle: 0,
|
197
|
+
rotationBackground: [0, 0, 0, 255],
|
198
|
+
rotateBeforePreExtract: false,
|
199
|
+
flip: false,
|
200
|
+
flop: false,
|
201
|
+
extendTop: 0,
|
202
|
+
extendBottom: 0,
|
203
|
+
extendLeft: 0,
|
204
|
+
extendRight: 0,
|
205
|
+
extendBackground: [0, 0, 0, 255],
|
206
|
+
extendWith: 'background',
|
207
|
+
withoutEnlargement: false,
|
208
|
+
withoutReduction: false,
|
209
|
+
affineMatrix: [],
|
210
|
+
affineBackground: [0, 0, 0, 255],
|
211
|
+
affineIdx: 0,
|
212
|
+
affineIdy: 0,
|
213
|
+
affineOdx: 0,
|
214
|
+
affineOdy: 0,
|
215
|
+
affineInterpolator: this.constructor.interpolators.bilinear,
|
216
|
+
kernel: 'lanczos3',
|
217
|
+
fastShrinkOnLoad: true,
|
218
|
+
// operations
|
219
|
+
tint: [-1, 0, 0, 0],
|
220
|
+
flatten: false,
|
221
|
+
flattenBackground: [0, 0, 0],
|
222
|
+
unflatten: false,
|
223
|
+
negate: false,
|
224
|
+
negateAlpha: true,
|
225
|
+
medianSize: 0,
|
226
|
+
blurSigma: 0,
|
227
|
+
sharpenSigma: 0,
|
228
|
+
sharpenM1: 1,
|
229
|
+
sharpenM2: 2,
|
230
|
+
sharpenX1: 2,
|
231
|
+
sharpenY2: 10,
|
232
|
+
sharpenY3: 20,
|
233
|
+
threshold: 0,
|
234
|
+
thresholdGrayscale: true,
|
235
|
+
trimBackground: [],
|
236
|
+
trimThreshold: -1,
|
237
|
+
trimLineArt: false,
|
238
|
+
gamma: 0,
|
239
|
+
gammaOut: 0,
|
240
|
+
greyscale: false,
|
241
|
+
normalise: false,
|
242
|
+
normaliseLower: 1,
|
243
|
+
normaliseUpper: 99,
|
244
|
+
claheWidth: 0,
|
245
|
+
claheHeight: 0,
|
246
|
+
claheMaxSlope: 3,
|
247
|
+
brightness: 1,
|
248
|
+
saturation: 1,
|
249
|
+
hue: 0,
|
250
|
+
lightness: 0,
|
251
|
+
booleanBufferIn: null,
|
252
|
+
booleanFileIn: '',
|
253
|
+
joinChannelIn: [],
|
254
|
+
extractChannel: -1,
|
255
|
+
removeAlpha: false,
|
256
|
+
ensureAlpha: -1,
|
257
|
+
colourspace: 'srgb',
|
258
|
+
colourspaceInput: 'last',
|
259
|
+
composite: [],
|
260
|
+
// output
|
261
|
+
fileOut: '',
|
262
|
+
formatOut: 'input',
|
263
|
+
streamOut: false,
|
264
|
+
keepMetadata: 0,
|
265
|
+
withMetadataOrientation: -1,
|
266
|
+
withMetadataDensity: 0,
|
267
|
+
withIccProfile: '',
|
268
|
+
withExif: {},
|
269
|
+
withExifMerge: true,
|
270
|
+
resolveWithObject: false,
|
271
|
+
// output format
|
272
|
+
jpegQuality: 80,
|
273
|
+
jpegProgressive: false,
|
274
|
+
jpegChromaSubsampling: '4:2:0',
|
275
|
+
jpegTrellisQuantisation: false,
|
276
|
+
jpegOvershootDeringing: false,
|
277
|
+
jpegOptimiseScans: false,
|
278
|
+
jpegOptimiseCoding: true,
|
279
|
+
jpegQuantisationTable: 0,
|
280
|
+
pngProgressive: false,
|
281
|
+
pngCompressionLevel: 6,
|
282
|
+
pngAdaptiveFiltering: false,
|
283
|
+
pngPalette: false,
|
284
|
+
pngQuality: 100,
|
285
|
+
pngEffort: 7,
|
286
|
+
pngBitdepth: 8,
|
287
|
+
pngDither: 1,
|
288
|
+
jp2Quality: 80,
|
289
|
+
jp2TileHeight: 512,
|
290
|
+
jp2TileWidth: 512,
|
291
|
+
jp2Lossless: false,
|
292
|
+
jp2ChromaSubsampling: '4:4:4',
|
293
|
+
webpQuality: 80,
|
294
|
+
webpAlphaQuality: 100,
|
295
|
+
webpLossless: false,
|
296
|
+
webpNearLossless: false,
|
297
|
+
webpSmartSubsample: false,
|
298
|
+
webpPreset: 'default',
|
299
|
+
webpEffort: 4,
|
300
|
+
webpMinSize: false,
|
301
|
+
webpMixed: false,
|
302
|
+
gifBitdepth: 8,
|
303
|
+
gifEffort: 7,
|
304
|
+
gifDither: 1,
|
305
|
+
gifInterFrameMaxError: 0,
|
306
|
+
gifInterPaletteMaxError: 3,
|
307
|
+
gifReuse: true,
|
308
|
+
gifProgressive: false,
|
309
|
+
tiffQuality: 80,
|
310
|
+
tiffCompression: 'jpeg',
|
311
|
+
tiffPredictor: 'horizontal',
|
312
|
+
tiffPyramid: false,
|
313
|
+
tiffMiniswhite: false,
|
314
|
+
tiffBitdepth: 8,
|
315
|
+
tiffTile: false,
|
316
|
+
tiffTileHeight: 256,
|
317
|
+
tiffTileWidth: 256,
|
318
|
+
tiffXres: 1.0,
|
319
|
+
tiffYres: 1.0,
|
320
|
+
tiffResolutionUnit: 'inch',
|
321
|
+
heifQuality: 50,
|
322
|
+
heifLossless: false,
|
323
|
+
heifCompression: 'av1',
|
324
|
+
heifEffort: 4,
|
325
|
+
heifChromaSubsampling: '4:4:4',
|
326
|
+
jxlDistance: 1,
|
327
|
+
jxlDecodingTier: 0,
|
328
|
+
jxlEffort: 7,
|
329
|
+
jxlLossless: false,
|
330
|
+
rawDepth: 'uchar',
|
331
|
+
tileSize: 256,
|
332
|
+
tileOverlap: 0,
|
333
|
+
tileContainer: 'fs',
|
334
|
+
tileLayout: 'dz',
|
335
|
+
tileFormat: 'last',
|
336
|
+
tileDepth: 'last',
|
337
|
+
tileAngle: 0,
|
338
|
+
tileSkipBlanks: -1,
|
339
|
+
tileBackground: [255, 255, 255, 255],
|
340
|
+
tileCentre: false,
|
341
|
+
tileId: 'https://example.com/iiif',
|
342
|
+
tileBasename: '',
|
343
|
+
timeoutSeconds: 0,
|
344
|
+
linearA: [],
|
345
|
+
linearB: [],
|
346
|
+
// Function to notify of libvips warnings
|
347
|
+
debuglog: warning => {
|
348
|
+
this.emit('warning', warning);
|
349
|
+
debuglog(warning);
|
350
|
+
},
|
351
|
+
// Function to notify of queue length changes
|
352
|
+
queueListener: function (queueLength) {
|
353
|
+
Sharp.queue.emit('change', queueLength);
|
354
|
+
}
|
355
|
+
};
|
356
|
+
this.options.input = this._createInputDescriptor(input, options, { allowStream: true });
|
357
|
+
return this;
|
358
|
+
};
|
359
|
+
Object.setPrototypeOf(Sharp.prototype, stream.Duplex.prototype);
|
360
|
+
Object.setPrototypeOf(Sharp, stream.Duplex);
|
361
|
+
|
362
|
+
/**
|
363
|
+
* Take a "snapshot" of the Sharp instance, returning a new instance.
|
364
|
+
* Cloned instances inherit the input of their parent instance.
|
365
|
+
* This allows multiple output Streams and therefore multiple processing pipelines to share a single input Stream.
|
366
|
+
*
|
367
|
+
* @example
|
368
|
+
* const pipeline = sharp().rotate();
|
369
|
+
* pipeline.clone().resize(800, 600).pipe(firstWritableStream);
|
370
|
+
* pipeline.clone().extract({ left: 20, top: 20, width: 100, height: 100 }).pipe(secondWritableStream);
|
371
|
+
* readableStream.pipe(pipeline);
|
372
|
+
* // firstWritableStream receives auto-rotated, resized readableStream
|
373
|
+
* // secondWritableStream receives auto-rotated, extracted region of readableStream
|
374
|
+
*
|
375
|
+
* @example
|
376
|
+
* // Create a pipeline that will download an image, resize it and format it to different files
|
377
|
+
* // Using Promises to know when the pipeline is complete
|
378
|
+
* const fs = require("fs");
|
379
|
+
* const got = require("got");
|
380
|
+
* const sharpStream = sharp({ failOn: 'none' });
|
381
|
+
*
|
382
|
+
* const promises = [];
|
383
|
+
*
|
384
|
+
* promises.push(
|
385
|
+
* sharpStream
|
386
|
+
* .clone()
|
387
|
+
* .jpeg({ quality: 100 })
|
388
|
+
* .toFile("originalFile.jpg")
|
389
|
+
* );
|
390
|
+
*
|
391
|
+
* promises.push(
|
392
|
+
* sharpStream
|
393
|
+
* .clone()
|
394
|
+
* .resize({ width: 500 })
|
395
|
+
* .jpeg({ quality: 80 })
|
396
|
+
* .toFile("optimized-500.jpg")
|
397
|
+
* );
|
398
|
+
*
|
399
|
+
* promises.push(
|
400
|
+
* sharpStream
|
401
|
+
* .clone()
|
402
|
+
* .resize({ width: 500 })
|
403
|
+
* .webp({ quality: 80 })
|
404
|
+
* .toFile("optimized-500.webp")
|
405
|
+
* );
|
406
|
+
*
|
407
|
+
* // https://github.com/sindresorhus/got/blob/main/documentation/3-streams.md
|
408
|
+
* got.stream("https://www.example.com/some-file.jpg").pipe(sharpStream);
|
409
|
+
*
|
410
|
+
* Promise.all(promises)
|
411
|
+
* .then(res => { console.log("Done!", res); })
|
412
|
+
* .catch(err => {
|
413
|
+
* console.error("Error processing files, let's clean it up", err);
|
414
|
+
* try {
|
415
|
+
* fs.unlinkSync("originalFile.jpg");
|
416
|
+
* fs.unlinkSync("optimized-500.jpg");
|
417
|
+
* fs.unlinkSync("optimized-500.webp");
|
418
|
+
* } catch (e) {}
|
419
|
+
* });
|
420
|
+
*
|
421
|
+
* @returns {Sharp}
|
422
|
+
*/
|
423
|
+
function clone () {
|
424
|
+
// Clone existing options
|
425
|
+
const clone = this.constructor.call();
|
426
|
+
clone.options = Object.assign({}, this.options);
|
427
|
+
// Pass 'finish' event to clone for Stream-based input
|
428
|
+
if (this._isStreamInput()) {
|
429
|
+
this.on('finish', () => {
|
430
|
+
// Clone inherits input data
|
431
|
+
this._flattenBufferIn();
|
432
|
+
clone.options.bufferIn = this.options.bufferIn;
|
433
|
+
clone.emit('finish');
|
434
|
+
});
|
435
|
+
}
|
436
|
+
return clone;
|
437
|
+
}
|
438
|
+
Object.assign(Sharp.prototype, { clone });
|
439
|
+
|
440
|
+
/**
|
441
|
+
* Export constructor.
|
442
|
+
* @private
|
443
|
+
*/
|
444
|
+
module.exports = Sharp;
|