sharp 0.33.5 → 0.35.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 +12 -18
- package/dist/channel.cjs +177 -0
- package/{lib/channel.js → dist/channel.mjs} +11 -8
- package/dist/colour.cjs +195 -0
- package/{lib/colour.js → dist/colour.mjs} +38 -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.mjs +25 -0
- package/dist/input.cjs +814 -0
- package/{lib/input.js → dist/input.mjs} +224 -68
- 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 +987 -0
- package/{lib/operation.js → dist/operation.mjs} +108 -79
- package/{lib/output.js → dist/output.cjs} +243 -36
- package/dist/output.mjs +1794 -0
- package/dist/resize.cjs +613 -0
- package/{lib/resize.js → dist/resize.mjs} +38 -12
- package/dist/sharp.cjs +164 -0
- package/dist/sharp.mjs +164 -0
- package/{lib/utility.js → dist/utility.cjs} +23 -24
- package/dist/utility.mjs +295 -0
- package/install/build.js +38 -0
- package/lib/index.d.ts +347 -125
- package/package.json +75 -84
- 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 +374 -183
- package/src/pipeline.h +34 -7
- package/src/sharp.cc +11 -8
- package/src/stats.cc +16 -13
- package/src/stats.h +6 -3
- package/src/utilities.cc +32 -12
- 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,32 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/*!
|
|
2
|
+
Copyright 2013 Lovell Fuller and others.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const color = require('color');
|
|
7
|
-
const is = require('./is');
|
|
8
|
-
const sharp = require('./sharp');
|
|
6
|
+
import is from './is.mjs';
|
|
7
|
+
import sharp from './sharp.mjs';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
|
-
*
|
|
10
|
+
* Justification alignment
|
|
12
11
|
* @member
|
|
13
12
|
* @private
|
|
14
13
|
*/
|
|
15
14
|
const align = {
|
|
16
15
|
left: 'low',
|
|
16
|
+
top: 'low',
|
|
17
|
+
low: 'low',
|
|
17
18
|
center: 'centre',
|
|
18
19
|
centre: 'centre',
|
|
19
|
-
right: 'high'
|
|
20
|
+
right: 'high',
|
|
21
|
+
bottom: 'high',
|
|
22
|
+
high: 'high'
|
|
20
23
|
};
|
|
21
24
|
|
|
25
|
+
const inputStreamParameters = [
|
|
26
|
+
// Limits and error handling
|
|
27
|
+
'failOn', 'limitInputPixels', 'limitInputChannels', 'unlimited',
|
|
28
|
+
// Format-generic
|
|
29
|
+
'animated', 'autoOrient', 'density', 'ignoreIcc', 'page', 'pages', 'sequentialRead',
|
|
30
|
+
// Format-specific
|
|
31
|
+
'jp2', 'openSlide', 'pdf', 'raw', 'svg', 'tiff',
|
|
32
|
+
// Deprecated
|
|
33
|
+
'openSlideLevel', 'pdfBackground', 'tiffSubifd'
|
|
34
|
+
];
|
|
35
|
+
|
|
22
36
|
/**
|
|
23
37
|
* Extract input options, if any, from an object.
|
|
24
38
|
* @private
|
|
25
39
|
*/
|
|
26
40
|
function _inputOptionsFromObject (obj) {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
41
|
+
const params = inputStreamParameters
|
|
42
|
+
.filter(p => is.defined(obj[p]))
|
|
43
|
+
.map(p => ([p, obj[p]]));
|
|
44
|
+
return params.length
|
|
45
|
+
? Object.fromEntries(params)
|
|
30
46
|
: undefined;
|
|
31
47
|
}
|
|
32
48
|
|
|
@@ -36,8 +52,10 @@ function _inputOptionsFromObject (obj) {
|
|
|
36
52
|
*/
|
|
37
53
|
function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
38
54
|
const inputDescriptor = {
|
|
55
|
+
autoOrient: false,
|
|
39
56
|
failOn: 'warning',
|
|
40
|
-
limitInputPixels:
|
|
57
|
+
limitInputPixels: 0x3FFF ** 2,
|
|
58
|
+
limitInputChannels: 5,
|
|
41
59
|
ignoreIcc: false,
|
|
42
60
|
unlimited: false,
|
|
43
61
|
sequentialRead: true
|
|
@@ -71,20 +89,24 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
71
89
|
} else if (!is.defined(input) && !is.defined(inputOptions) && is.object(containerOptions) && containerOptions.allowStream) {
|
|
72
90
|
// Stream without options
|
|
73
91
|
inputDescriptor.buffer = [];
|
|
92
|
+
} else if (Array.isArray(input)) {
|
|
93
|
+
if (input.length > 1) {
|
|
94
|
+
// Join images together
|
|
95
|
+
if (!this.options.joining) {
|
|
96
|
+
this.options.joining = true;
|
|
97
|
+
this.options.join = input.map(i => this._createInputDescriptor(i));
|
|
98
|
+
} else {
|
|
99
|
+
throw new Error('Recursive join is unsupported');
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
throw new Error('Expected at least two images to join');
|
|
103
|
+
}
|
|
74
104
|
} else {
|
|
75
105
|
throw new Error(`Unsupported input '${input}' of type ${typeof input}${
|
|
76
106
|
is.defined(inputOptions) ? ` when also providing options of type ${typeof inputOptions}` : ''
|
|
77
107
|
}`);
|
|
78
108
|
}
|
|
79
109
|
if (is.object(inputOptions)) {
|
|
80
|
-
// Deprecated: failOnError
|
|
81
|
-
if (is.defined(inputOptions.failOnError)) {
|
|
82
|
-
if (is.bool(inputOptions.failOnError)) {
|
|
83
|
-
inputDescriptor.failOn = inputOptions.failOnError ? 'warning' : 'none';
|
|
84
|
-
} else {
|
|
85
|
-
throw is.invalidParameterError('failOnError', 'boolean', inputOptions.failOnError);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
110
|
// failOn
|
|
89
111
|
if (is.defined(inputOptions.failOn)) {
|
|
90
112
|
if (is.string(inputOptions.failOn) && is.inArray(inputOptions.failOn, ['none', 'truncated', 'error', 'warning'])) {
|
|
@@ -93,9 +115,17 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
93
115
|
throw is.invalidParameterError('failOn', 'one of: none, truncated, error, warning', inputOptions.failOn);
|
|
94
116
|
}
|
|
95
117
|
}
|
|
118
|
+
// autoOrient
|
|
119
|
+
if (is.defined(inputOptions.autoOrient)) {
|
|
120
|
+
if (is.bool(inputOptions.autoOrient)) {
|
|
121
|
+
inputDescriptor.autoOrient = inputOptions.autoOrient;
|
|
122
|
+
} else {
|
|
123
|
+
throw is.invalidParameterError('autoOrient', 'boolean', inputOptions.autoOrient);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
96
126
|
// Density
|
|
97
127
|
if (is.defined(inputOptions.density)) {
|
|
98
|
-
if (is.inRange(inputOptions.density, 1, 100000)) {
|
|
128
|
+
if (is.number(inputOptions.density) && is.inRange(inputOptions.density, 1, 100000)) {
|
|
99
129
|
inputDescriptor.density = inputOptions.density;
|
|
100
130
|
} else {
|
|
101
131
|
throw is.invalidParameterError('density', 'number between 1 and 100000', inputOptions.density);
|
|
@@ -113,7 +143,7 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
113
143
|
if (is.defined(inputOptions.limitInputPixels)) {
|
|
114
144
|
if (is.bool(inputOptions.limitInputPixels)) {
|
|
115
145
|
inputDescriptor.limitInputPixels = inputOptions.limitInputPixels
|
|
116
|
-
?
|
|
146
|
+
? 0x3FFF ** 2
|
|
117
147
|
: 0;
|
|
118
148
|
} else if (is.integer(inputOptions.limitInputPixels) && is.inRange(inputOptions.limitInputPixels, 0, Number.MAX_SAFE_INTEGER)) {
|
|
119
149
|
inputDescriptor.limitInputPixels = inputOptions.limitInputPixels;
|
|
@@ -121,6 +151,16 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
121
151
|
throw is.invalidParameterError('limitInputPixels', 'positive integer', inputOptions.limitInputPixels);
|
|
122
152
|
}
|
|
123
153
|
}
|
|
154
|
+
// limitInputChannels
|
|
155
|
+
if (is.defined(inputOptions.limitInputChannels)) {
|
|
156
|
+
if (is.bool(inputOptions.limitInputChannels)) {
|
|
157
|
+
inputDescriptor.limitInputChannels = inputOptions.limitInputChannels ? 5 : 0;
|
|
158
|
+
} else if (is.integer(inputOptions.limitInputChannels) && is.inRange(inputOptions.limitInputChannels, 0, Number.MAX_SAFE_INTEGER)) {
|
|
159
|
+
inputDescriptor.limitInputChannels = inputOptions.limitInputChannels;
|
|
160
|
+
} else {
|
|
161
|
+
throw is.invalidParameterError('limitInputChannels', 'positive integer', inputOptions.limitInputChannels);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
124
164
|
// unlimited
|
|
125
165
|
if (is.defined(inputOptions.unlimited)) {
|
|
126
166
|
if (is.bool(inputOptions.unlimited)) {
|
|
@@ -148,8 +188,6 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
148
188
|
inputDescriptor.rawWidth = inputOptions.raw.width;
|
|
149
189
|
inputDescriptor.rawHeight = inputOptions.raw.height;
|
|
150
190
|
inputDescriptor.rawChannels = inputOptions.raw.channels;
|
|
151
|
-
inputDescriptor.rawPremultiplied = !!inputOptions.raw.premultiplied;
|
|
152
|
-
|
|
153
191
|
switch (input.constructor) {
|
|
154
192
|
case Uint8Array:
|
|
155
193
|
case Uint8ClampedArray:
|
|
@@ -183,6 +221,25 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
183
221
|
} else {
|
|
184
222
|
throw new Error('Expected width, height and channels for raw pixel input');
|
|
185
223
|
}
|
|
224
|
+
inputDescriptor.rawPremultiplied = false;
|
|
225
|
+
if (is.defined(inputOptions.raw.premultiplied)) {
|
|
226
|
+
if (is.bool(inputOptions.raw.premultiplied)) {
|
|
227
|
+
inputDescriptor.rawPremultiplied = inputOptions.raw.premultiplied;
|
|
228
|
+
} else {
|
|
229
|
+
throw is.invalidParameterError('raw.premultiplied', 'boolean', inputOptions.raw.premultiplied);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
inputDescriptor.rawPageHeight = 0;
|
|
233
|
+
if (is.defined(inputOptions.raw.pageHeight)) {
|
|
234
|
+
if (is.integer(inputOptions.raw.pageHeight) && inputOptions.raw.pageHeight > 0 && inputOptions.raw.pageHeight <= inputOptions.raw.height) {
|
|
235
|
+
if (inputOptions.raw.height % inputOptions.raw.pageHeight !== 0) {
|
|
236
|
+
throw new Error(`Expected raw.height ${inputOptions.raw.height} to be a multiple of raw.pageHeight ${inputOptions.raw.pageHeight}`);
|
|
237
|
+
}
|
|
238
|
+
inputDescriptor.rawPageHeight = inputOptions.raw.pageHeight;
|
|
239
|
+
} else {
|
|
240
|
+
throw is.invalidParameterError('raw.pageHeight', 'positive integer', inputOptions.raw.pageHeight);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
186
243
|
}
|
|
187
244
|
// Multi-page input (GIF, TIFF, PDF)
|
|
188
245
|
if (is.defined(inputOptions.animated)) {
|
|
@@ -206,22 +263,68 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
206
263
|
throw is.invalidParameterError('page', 'integer between 0 and 100000', inputOptions.page);
|
|
207
264
|
}
|
|
208
265
|
}
|
|
209
|
-
//
|
|
210
|
-
if (is.defined(inputOptions.level)) {
|
|
266
|
+
// OpenSlide specific options
|
|
267
|
+
if (is.object(inputOptions.openSlide) && is.defined(inputOptions.openSlide.level)) {
|
|
268
|
+
if (is.integer(inputOptions.openSlide.level) && is.inRange(inputOptions.openSlide.level, 0, 256)) {
|
|
269
|
+
inputDescriptor.openSlideLevel = inputOptions.openSlide.level;
|
|
270
|
+
} else {
|
|
271
|
+
throw is.invalidParameterError('openSlide.level', 'integer between 0 and 256', inputOptions.openSlide.level);
|
|
272
|
+
}
|
|
273
|
+
} else if (is.defined(inputOptions.level)) {
|
|
274
|
+
// Deprecated
|
|
211
275
|
if (is.integer(inputOptions.level) && is.inRange(inputOptions.level, 0, 256)) {
|
|
212
|
-
inputDescriptor.
|
|
276
|
+
inputDescriptor.openSlideLevel = inputOptions.level;
|
|
213
277
|
} else {
|
|
214
278
|
throw is.invalidParameterError('level', 'integer between 0 and 256', inputOptions.level);
|
|
215
279
|
}
|
|
216
280
|
}
|
|
217
|
-
//
|
|
218
|
-
if (is.defined(inputOptions.subifd)) {
|
|
281
|
+
// TIFF specific options
|
|
282
|
+
if (is.object(inputOptions.tiff) && is.defined(inputOptions.tiff.subifd)) {
|
|
283
|
+
if (is.integer(inputOptions.tiff.subifd) && is.inRange(inputOptions.tiff.subifd, -1, 100000)) {
|
|
284
|
+
inputDescriptor.tiffSubifd = inputOptions.tiff.subifd;
|
|
285
|
+
} else {
|
|
286
|
+
throw is.invalidParameterError('tiff.subifd', 'integer between -1 and 100000', inputOptions.tiff.subifd);
|
|
287
|
+
}
|
|
288
|
+
} else if (is.defined(inputOptions.subifd)) {
|
|
289
|
+
// Deprecated
|
|
219
290
|
if (is.integer(inputOptions.subifd) && is.inRange(inputOptions.subifd, -1, 100000)) {
|
|
220
|
-
inputDescriptor.
|
|
291
|
+
inputDescriptor.tiffSubifd = inputOptions.subifd;
|
|
221
292
|
} else {
|
|
222
293
|
throw is.invalidParameterError('subifd', 'integer between -1 and 100000', inputOptions.subifd);
|
|
223
294
|
}
|
|
224
295
|
}
|
|
296
|
+
// SVG specific options
|
|
297
|
+
if (is.object(inputOptions.svg)) {
|
|
298
|
+
if (is.defined(inputOptions.svg.stylesheet)) {
|
|
299
|
+
if (is.string(inputOptions.svg.stylesheet)) {
|
|
300
|
+
inputDescriptor.svgStylesheet = inputOptions.svg.stylesheet;
|
|
301
|
+
} else {
|
|
302
|
+
throw is.invalidParameterError('svg.stylesheet', 'string', inputOptions.svg.stylesheet);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (is.defined(inputOptions.svg.highBitdepth)) {
|
|
306
|
+
if (is.bool(inputOptions.svg.highBitdepth)) {
|
|
307
|
+
inputDescriptor.svgHighBitdepth = inputOptions.svg.highBitdepth;
|
|
308
|
+
} else {
|
|
309
|
+
throw is.invalidParameterError('svg.highBitdepth', 'boolean', inputOptions.svg.highBitdepth);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// PDF specific options
|
|
314
|
+
if (is.object(inputOptions.pdf) && is.defined(inputOptions.pdf.background)) {
|
|
315
|
+
inputDescriptor.pdfBackground = this._getBackgroundColourOption(inputOptions.pdf.background);
|
|
316
|
+
} else if (is.defined(inputOptions.pdfBackground)) {
|
|
317
|
+
// Deprecated
|
|
318
|
+
inputDescriptor.pdfBackground = this._getBackgroundColourOption(inputOptions.pdfBackground);
|
|
319
|
+
}
|
|
320
|
+
// JPEG 2000 specific options
|
|
321
|
+
if (is.object(inputOptions.jp2) && is.defined(inputOptions.jp2.oneshot)) {
|
|
322
|
+
if (is.bool(inputOptions.jp2.oneshot)) {
|
|
323
|
+
inputDescriptor.jp2Oneshot = inputOptions.jp2.oneshot;
|
|
324
|
+
} else {
|
|
325
|
+
throw is.invalidParameterError('jp2.oneshot', 'boolean', inputOptions.jp2.oneshot);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
225
328
|
// Create new image
|
|
226
329
|
if (is.defined(inputOptions.create)) {
|
|
227
330
|
if (
|
|
@@ -233,39 +336,50 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
233
336
|
inputDescriptor.createWidth = inputOptions.create.width;
|
|
234
337
|
inputDescriptor.createHeight = inputOptions.create.height;
|
|
235
338
|
inputDescriptor.createChannels = inputOptions.create.channels;
|
|
339
|
+
inputDescriptor.createPageHeight = 0;
|
|
340
|
+
if (is.defined(inputOptions.create.pageHeight)) {
|
|
341
|
+
if (is.integer(inputOptions.create.pageHeight) && inputOptions.create.pageHeight > 0 && inputOptions.create.pageHeight <= inputOptions.create.height) {
|
|
342
|
+
if (inputOptions.create.height % inputOptions.create.pageHeight !== 0) {
|
|
343
|
+
throw new Error(`Expected create.height ${inputOptions.create.height} to be a multiple of create.pageHeight ${inputOptions.create.pageHeight}`);
|
|
344
|
+
}
|
|
345
|
+
inputDescriptor.createPageHeight = inputOptions.create.pageHeight;
|
|
346
|
+
} else {
|
|
347
|
+
throw is.invalidParameterError('create.pageHeight', 'positive integer', inputOptions.create.pageHeight);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
236
350
|
// Noise
|
|
237
351
|
if (is.defined(inputOptions.create.noise)) {
|
|
238
352
|
if (!is.object(inputOptions.create.noise)) {
|
|
239
353
|
throw new Error('Expected noise to be an object');
|
|
240
354
|
}
|
|
241
|
-
if (
|
|
355
|
+
if (inputOptions.create.noise.type !== 'gaussian') {
|
|
242
356
|
throw new Error('Only gaussian noise is supported at the moment');
|
|
243
357
|
}
|
|
358
|
+
inputDescriptor.createNoiseType = inputOptions.create.noise.type;
|
|
244
359
|
if (!is.inRange(inputOptions.create.channels, 1, 4)) {
|
|
245
360
|
throw is.invalidParameterError('create.channels', 'number between 1 and 4', inputOptions.create.channels);
|
|
246
361
|
}
|
|
247
|
-
inputDescriptor.
|
|
248
|
-
if (is.
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
362
|
+
inputDescriptor.createNoiseMean = 128;
|
|
363
|
+
if (is.defined(inputOptions.create.noise.mean)) {
|
|
364
|
+
if (is.number(inputOptions.create.noise.mean) && is.inRange(inputOptions.create.noise.mean, 0, 10000)) {
|
|
365
|
+
inputDescriptor.createNoiseMean = inputOptions.create.noise.mean;
|
|
366
|
+
} else {
|
|
367
|
+
throw is.invalidParameterError('create.noise.mean', 'number between 0 and 10000', inputOptions.create.noise.mean);
|
|
368
|
+
}
|
|
252
369
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
370
|
+
inputDescriptor.createNoiseSigma = 30;
|
|
371
|
+
if (is.defined(inputOptions.create.noise.sigma)) {
|
|
372
|
+
if (is.number(inputOptions.create.noise.sigma) && is.inRange(inputOptions.create.noise.sigma, 0, 10000)) {
|
|
373
|
+
inputDescriptor.createNoiseSigma = inputOptions.create.noise.sigma;
|
|
374
|
+
} else {
|
|
375
|
+
throw is.invalidParameterError('create.noise.sigma', 'number between 0 and 10000', inputOptions.create.noise.sigma);
|
|
376
|
+
}
|
|
257
377
|
}
|
|
258
378
|
} else if (is.defined(inputOptions.create.background)) {
|
|
259
379
|
if (!is.inRange(inputOptions.create.channels, 3, 4)) {
|
|
260
380
|
throw is.invalidParameterError('create.channels', 'number between 3 and 4', inputOptions.create.channels);
|
|
261
381
|
}
|
|
262
|
-
|
|
263
|
-
inputDescriptor.createBackground = [
|
|
264
|
-
background.red(),
|
|
265
|
-
background.green(),
|
|
266
|
-
background.blue(),
|
|
267
|
-
Math.round(background.alpha() * 255)
|
|
268
|
-
];
|
|
382
|
+
inputDescriptor.createBackground = this._getBackgroundColourOption(inputOptions.create.background);
|
|
269
383
|
} else {
|
|
270
384
|
throw new Error('Expected valid noise or background to create a new input image');
|
|
271
385
|
}
|
|
@@ -356,8 +470,53 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
356
470
|
throw new Error('Expected a valid string to create an image with text.');
|
|
357
471
|
}
|
|
358
472
|
}
|
|
473
|
+
// Join images together
|
|
474
|
+
if (is.defined(inputOptions.join)) {
|
|
475
|
+
if (is.defined(this.options.join)) {
|
|
476
|
+
if (is.defined(inputOptions.join.animated)) {
|
|
477
|
+
if (is.bool(inputOptions.join.animated)) {
|
|
478
|
+
inputDescriptor.joinAnimated = inputOptions.join.animated;
|
|
479
|
+
} else {
|
|
480
|
+
throw is.invalidParameterError('join.animated', 'boolean', inputOptions.join.animated);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (is.defined(inputOptions.join.across)) {
|
|
484
|
+
if (is.integer(inputOptions.join.across) && is.inRange(inputOptions.join.across, 1, 1000000)) {
|
|
485
|
+
inputDescriptor.joinAcross = inputOptions.join.across;
|
|
486
|
+
} else {
|
|
487
|
+
throw is.invalidParameterError('join.across', 'integer between 1 and 100000', inputOptions.join.across);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (is.defined(inputOptions.join.shim)) {
|
|
491
|
+
if (is.integer(inputOptions.join.shim) && is.inRange(inputOptions.join.shim, 0, 1000000)) {
|
|
492
|
+
inputDescriptor.joinShim = inputOptions.join.shim;
|
|
493
|
+
} else {
|
|
494
|
+
throw is.invalidParameterError('join.shim', 'integer between 0 and 100000', inputOptions.join.shim);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
if (is.defined(inputOptions.join.background)) {
|
|
498
|
+
inputDescriptor.joinBackground = this._getBackgroundColourOption(inputOptions.join.background);
|
|
499
|
+
}
|
|
500
|
+
if (is.defined(inputOptions.join.halign)) {
|
|
501
|
+
if (is.string(inputOptions.join.halign) && is.string(this.constructor.align[inputOptions.join.halign])) {
|
|
502
|
+
inputDescriptor.joinHalign = this.constructor.align[inputOptions.join.halign];
|
|
503
|
+
} else {
|
|
504
|
+
throw is.invalidParameterError('join.halign', 'valid alignment', inputOptions.join.halign);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
if (is.defined(inputOptions.join.valign)) {
|
|
508
|
+
if (is.string(inputOptions.join.valign) && is.string(this.constructor.align[inputOptions.join.valign])) {
|
|
509
|
+
inputDescriptor.joinValign = this.constructor.align[inputOptions.join.valign];
|
|
510
|
+
} else {
|
|
511
|
+
throw is.invalidParameterError('join.valign', 'valid alignment', inputOptions.join.valign);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
} else {
|
|
515
|
+
throw new Error('Expected input to be an array of images to join');
|
|
516
|
+
}
|
|
517
|
+
}
|
|
359
518
|
} else if (is.defined(inputOptions)) {
|
|
360
|
-
throw new Error(
|
|
519
|
+
throw new Error(`Invalid input options ${inputOptions}`);
|
|
361
520
|
}
|
|
362
521
|
return inputDescriptor;
|
|
363
522
|
}
|
|
@@ -369,10 +528,8 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
369
528
|
* @param {string} encoding - unused
|
|
370
529
|
* @param {Function} callback
|
|
371
530
|
*/
|
|
372
|
-
function _write (chunk,
|
|
373
|
-
/* istanbul ignore else */
|
|
531
|
+
function _write (chunk, _encoding, callback) {
|
|
374
532
|
if (Array.isArray(this.options.input.buffer)) {
|
|
375
|
-
/* istanbul ignore else */
|
|
376
533
|
if (is.buffer(chunk)) {
|
|
377
534
|
if (this.options.input.buffer.length === 0) {
|
|
378
535
|
this.on('finish', () => {
|
|
@@ -416,29 +573,31 @@ function _isStreamInput () {
|
|
|
416
573
|
* such as resize or rotate.
|
|
417
574
|
*
|
|
418
575
|
* Dimensions in the response will respect the `page` and `pages` properties of the
|
|
419
|
-
* {@link /api-constructor
|
|
576
|
+
* {@link /api-constructor/ constructor parameters}.
|
|
420
577
|
*
|
|
421
578
|
* A `Promise` is returned when `callback` is not provided.
|
|
422
579
|
*
|
|
423
|
-
* - `format`: Name of decoder used to
|
|
580
|
+
* - `format`: Name of decoder used to parse image e.g. `jpeg`, `png`, `webp`, `gif`, `svg`, `heif`, `tiff`
|
|
581
|
+
* - `mediaType`: Media Type (MIME Type) e.g. `image/jpeg`, `image/png`, `image/svg+xml`, `image/avif`
|
|
424
582
|
* - `size`: Total size of image in bytes, for Stream and Buffer input only
|
|
425
583
|
* - `width`: Number of pixels wide (EXIF orientation is not taken into consideration, see example below)
|
|
426
584
|
* - `height`: Number of pixels high (EXIF orientation is not taken into consideration, see example below)
|
|
427
|
-
* - `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://www.libvips.org/API/current/
|
|
585
|
+
* - `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://www.libvips.org/API/current/enum.Interpretation.html)
|
|
428
586
|
* - `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
|
|
429
|
-
* - `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://www.libvips.org/API/current/
|
|
587
|
+
* - `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://www.libvips.org/API/current/enum.BandFormat.html)
|
|
430
588
|
* - `density`: Number of pixels per inch (DPI), if present
|
|
431
589
|
* - `chromaSubsampling`: String containing JPEG chroma subsampling, `4:2:0` or `4:4:4` for RGB, `4:2:0:4` or `4:4:4:4` for CMYK
|
|
432
590
|
* - `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
|
|
591
|
+
* - `isPalette`: Boolean indicating whether the image is palette-based (GIF, PNG).
|
|
592
|
+
* - `bitsPerSample`: Number of bits per sample for each channel (GIF, PNG, HEIF).
|
|
433
593
|
* - `pages`: Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP
|
|
434
594
|
* - `pageHeight`: Number of pixels high each page in a multi-page image will be.
|
|
435
|
-
* - `paletteBitDepth`: Bit depth of palette-based image (GIF, PNG).
|
|
436
595
|
* - `loop`: Number of times to loop an animated image, zero refers to a continuous loop.
|
|
437
596
|
* - `delay`: Delay in ms between each page in an animated image, provided as an array of integers.
|
|
438
597
|
* - `pagePrimary`: Number of the primary page in a HEIF image
|
|
439
598
|
* - `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide
|
|
440
599
|
* - `subifds`: Number of Sub Image File Directories in an OME-TIFF image
|
|
441
|
-
* - `background`: Default background colour, if present, for PNG (bKGD) and GIF images
|
|
600
|
+
* - `background`: Default background colour, if present, for PNG (bKGD) and GIF images
|
|
442
601
|
* - `compression`: The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC)
|
|
443
602
|
* - `resolutionUnit`: The unit of resolution (density), either `inch` or `cm`, if present
|
|
444
603
|
* - `hasProfile`: Boolean indicating the presence of an embedded ICC profile
|
|
@@ -448,9 +607,11 @@ function _isStreamInput () {
|
|
|
448
607
|
* - `icc`: Buffer containing raw [ICC](https://www.npmjs.com/package/icc) profile data, if present
|
|
449
608
|
* - `iptc`: Buffer containing raw IPTC data, if present
|
|
450
609
|
* - `xmp`: Buffer containing raw XMP data, if present
|
|
610
|
+
* - `xmpAsString`: String containing XMP data, if valid UTF-8.
|
|
451
611
|
* - `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
|
|
452
612
|
* - `formatMagick`: String containing format for images loaded via *magick
|
|
453
613
|
* - `comments`: Array of keyword/text pairs representing PNG text blocks, if present.
|
|
614
|
+
* - `gainMap.image`: HDR gain map, if present, as compressed JPEG image.
|
|
454
615
|
*
|
|
455
616
|
* @example
|
|
456
617
|
* const metadata = await sharp(input).metadata();
|
|
@@ -470,15 +631,9 @@ function _isStreamInput () {
|
|
|
470
631
|
* });
|
|
471
632
|
*
|
|
472
633
|
* @example
|
|
473
|
-
* //
|
|
474
|
-
*
|
|
475
|
-
* const
|
|
476
|
-
*
|
|
477
|
-
* function getNormalSize({ width, height, orientation }) {
|
|
478
|
-
* return (orientation || 0) >= 5
|
|
479
|
-
* ? { width: height, height: width }
|
|
480
|
-
* : { width, height };
|
|
481
|
-
* }
|
|
634
|
+
* // Get dimensions taking EXIF Orientation into account.
|
|
635
|
+
* const { autoOrient } = await sharp(input).metadata();
|
|
636
|
+
* const { width, height } = autoOrient;
|
|
482
637
|
*
|
|
483
638
|
* @param {Function} [callback] - called with the arguments `(err, metadata)`
|
|
484
639
|
* @returns {Promise<Object>|Sharp}
|
|
@@ -639,9 +794,10 @@ function stats (callback) {
|
|
|
639
794
|
|
|
640
795
|
/**
|
|
641
796
|
* Decorate the Sharp prototype with input-related functions.
|
|
797
|
+
* @module Sharp
|
|
642
798
|
* @private
|
|
643
799
|
*/
|
|
644
|
-
|
|
800
|
+
export default (Sharp) => {
|
|
645
801
|
Object.assign(Sharp.prototype, {
|
|
646
802
|
// Private
|
|
647
803
|
_inputOptionsFromObject,
|
|
@@ -1,61 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/*!
|
|
2
|
+
Copyright 2013 Lovell Fuller and others.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Is this value defined and not null?
|
|
8
8
|
* @private
|
|
9
9
|
*/
|
|
10
|
-
const defined =
|
|
11
|
-
return typeof val !== 'undefined' && val !== null;
|
|
12
|
-
};
|
|
10
|
+
const defined = (val) => typeof val !== 'undefined' && val !== null;
|
|
13
11
|
|
|
14
12
|
/**
|
|
15
13
|
* Is this value an object?
|
|
16
14
|
* @private
|
|
17
15
|
*/
|
|
18
|
-
const object =
|
|
19
|
-
return typeof val === 'object';
|
|
20
|
-
};
|
|
16
|
+
const object = (val) => typeof val === 'object';
|
|
21
17
|
|
|
22
18
|
/**
|
|
23
19
|
* Is this value a plain object?
|
|
24
20
|
* @private
|
|
25
21
|
*/
|
|
26
|
-
const plainObject =
|
|
27
|
-
return Object.prototype.toString.call(val) === '[object Object]';
|
|
28
|
-
};
|
|
22
|
+
const plainObject = (val) => Object.prototype.toString.call(val) === '[object Object]';
|
|
29
23
|
|
|
30
24
|
/**
|
|
31
25
|
* Is this value a function?
|
|
32
26
|
* @private
|
|
33
27
|
*/
|
|
34
|
-
const fn =
|
|
35
|
-
return typeof val === 'function';
|
|
36
|
-
};
|
|
28
|
+
const fn = (val) => typeof val === 'function';
|
|
37
29
|
|
|
38
30
|
/**
|
|
39
31
|
* Is this value a boolean?
|
|
40
32
|
* @private
|
|
41
33
|
*/
|
|
42
|
-
const bool =
|
|
43
|
-
return typeof val === 'boolean';
|
|
44
|
-
};
|
|
34
|
+
const bool = (val) => typeof val === 'boolean';
|
|
45
35
|
|
|
46
36
|
/**
|
|
47
37
|
* Is this value a Buffer object?
|
|
48
38
|
* @private
|
|
49
39
|
*/
|
|
50
|
-
const buffer =
|
|
51
|
-
return val instanceof Buffer;
|
|
52
|
-
};
|
|
40
|
+
const buffer = (val) => val instanceof Buffer;
|
|
53
41
|
|
|
54
42
|
/**
|
|
55
43
|
* Is this value a typed array object?. E.g. Uint8Array or Uint8ClampedArray?
|
|
56
44
|
* @private
|
|
57
45
|
*/
|
|
58
|
-
const typedArray =
|
|
46
|
+
const typedArray = (val) => {
|
|
59
47
|
if (defined(val)) {
|
|
60
48
|
switch (val.constructor) {
|
|
61
49
|
case Uint8Array:
|
|
@@ -78,49 +66,37 @@ const typedArray = function (val) {
|
|
|
78
66
|
* Is this value an ArrayBuffer object?
|
|
79
67
|
* @private
|
|
80
68
|
*/
|
|
81
|
-
const arrayBuffer =
|
|
82
|
-
return val instanceof ArrayBuffer;
|
|
83
|
-
};
|
|
69
|
+
const arrayBuffer = (val) => val instanceof ArrayBuffer;
|
|
84
70
|
|
|
85
71
|
/**
|
|
86
72
|
* Is this value a non-empty string?
|
|
87
73
|
* @private
|
|
88
74
|
*/
|
|
89
|
-
const string =
|
|
90
|
-
return typeof val === 'string' && val.length > 0;
|
|
91
|
-
};
|
|
75
|
+
const string = (val) => typeof val === 'string' && val.length > 0;
|
|
92
76
|
|
|
93
77
|
/**
|
|
94
78
|
* Is this value a real number?
|
|
95
79
|
* @private
|
|
96
80
|
*/
|
|
97
|
-
const number =
|
|
98
|
-
return typeof val === 'number' && !Number.isNaN(val);
|
|
99
|
-
};
|
|
81
|
+
const number = (val) => typeof val === 'number' && !Number.isNaN(val);
|
|
100
82
|
|
|
101
83
|
/**
|
|
102
84
|
* Is this value an integer?
|
|
103
85
|
* @private
|
|
104
86
|
*/
|
|
105
|
-
const integer =
|
|
106
|
-
return Number.isInteger(val);
|
|
107
|
-
};
|
|
87
|
+
const integer = (val) => Number.isInteger(val);
|
|
108
88
|
|
|
109
89
|
/**
|
|
110
90
|
* Is this value within an inclusive given range?
|
|
111
91
|
* @private
|
|
112
92
|
*/
|
|
113
|
-
const inRange =
|
|
114
|
-
return val >= min && val <= max;
|
|
115
|
-
};
|
|
93
|
+
const inRange = (val, min, max) => val >= min && val <= max;
|
|
116
94
|
|
|
117
95
|
/**
|
|
118
96
|
* Is this value within the elements of an array?
|
|
119
97
|
* @private
|
|
120
98
|
*/
|
|
121
|
-
const inArray =
|
|
122
|
-
return list.includes(val);
|
|
123
|
-
};
|
|
99
|
+
const inArray = (val, list) => list.includes(val);
|
|
124
100
|
|
|
125
101
|
/**
|
|
126
102
|
* Create an Error with a message relating to an invalid parameter.
|
|
@@ -131,11 +107,9 @@ const inArray = function (val, list) {
|
|
|
131
107
|
* @returns {Error} Containing the formatted message.
|
|
132
108
|
* @private
|
|
133
109
|
*/
|
|
134
|
-
const invalidParameterError =
|
|
135
|
-
return new Error(
|
|
110
|
+
const invalidParameterError = (name, expected, actual) => new Error(
|
|
136
111
|
`Expected ${expected} for ${name} but received ${actual} of type ${typeof actual}`
|
|
137
112
|
);
|
|
138
|
-
};
|
|
139
113
|
|
|
140
114
|
/**
|
|
141
115
|
* Ensures an Error from C++ contains a JS stack.
|
|
@@ -145,7 +119,7 @@ const invalidParameterError = function (name, expected, actual) {
|
|
|
145
119
|
* @returns {Error} Error with message and stack.
|
|
146
120
|
* @private
|
|
147
121
|
*/
|
|
148
|
-
const nativeError =
|
|
122
|
+
const nativeError = (native, context) => {
|
|
149
123
|
context.message = native.message;
|
|
150
124
|
return context;
|
|
151
125
|
};
|