sharp 0.25.1 → 0.26.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/lib/input.js CHANGED
@@ -4,6 +4,17 @@ const color = require('color');
4
4
  const is = require('./is');
5
5
  const sharp = require('../build/Release/sharp.node');
6
6
 
7
+ /**
8
+ * Extract input options, if any, from an object.
9
+ * @private
10
+ */
11
+ function _inputOptionsFromObject (obj) {
12
+ const { raw, density, limitInputPixels, sequentialRead, failOnError } = obj;
13
+ return [raw, density, limitInputPixels, sequentialRead, failOnError].some(is.defined)
14
+ ? { raw, density, limitInputPixels, sequentialRead, failOnError }
15
+ : undefined;
16
+ }
17
+
7
18
  /**
8
19
  * Create Object containing input and input-related options.
9
20
  * @private
@@ -23,12 +34,12 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
23
34
  } else if (is.plainObject(input) && !is.defined(inputOptions)) {
24
35
  // Plain Object descriptor, e.g. create
25
36
  inputOptions = input;
26
- if (is.plainObject(inputOptions.raw) || is.bool(inputOptions.failOnError)) {
27
- // Raw Stream
37
+ if (_inputOptionsFromObject(inputOptions)) {
38
+ // Stream with options
28
39
  inputDescriptor.buffer = [];
29
40
  }
30
41
  } else if (!is.defined(input) && !is.defined(inputOptions) && is.object(containerOptions) && containerOptions.allowStream) {
31
- // Stream
42
+ // Stream without options
32
43
  inputDescriptor.buffer = [];
33
44
  } else {
34
45
  throw new Error(`Unsupported input '${input}' of type ${typeof input}${
@@ -88,6 +99,13 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
88
99
  }
89
100
  }
90
101
  // Multi-page input (GIF, TIFF, PDF)
102
+ if (is.defined(inputOptions.animated)) {
103
+ if (is.bool(inputOptions.animated)) {
104
+ inputDescriptor.pages = inputOptions.animated ? -1 : 1;
105
+ } else {
106
+ throw is.invalidParameterError('animated', 'boolean', inputOptions.animated);
107
+ }
108
+ }
91
109
  if (is.defined(inputOptions.pages)) {
92
110
  if (is.integer(inputOptions.pages) && is.inRange(inputOptions.pages, -1, 100000)) {
93
111
  inputDescriptor.pages = inputOptions.pages;
@@ -102,6 +120,14 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
102
120
  throw is.invalidParameterError('page', 'integer between 0 and 100000', inputOptions.page);
103
121
  }
104
122
  }
123
+ // Multi-level input (OpenSlide)
124
+ if (is.defined(inputOptions.level)) {
125
+ if (is.integer(inputOptions.level) && is.inRange(inputOptions.level, 0, 256)) {
126
+ inputDescriptor.level = inputOptions.level;
127
+ } else {
128
+ throw is.invalidParameterError('level', 'integer between 0 and 256', inputOptions.level);
129
+ }
130
+ }
105
131
  // Create new image
106
132
  if (is.defined(inputOptions.create)) {
107
133
  if (
@@ -136,7 +162,7 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
136
162
  * Handle incoming Buffer chunk on Writable Stream.
137
163
  * @private
138
164
  * @param {Buffer} chunk
139
- * @param {String} encoding - unused
165
+ * @param {string} encoding - unused
140
166
  * @param {Function} callback
141
167
  */
142
168
  function _write (chunk, encoding, callback) {
@@ -172,7 +198,7 @@ function _flattenBufferIn () {
172
198
  /**
173
199
  * Are we expecting Stream-based input?
174
200
  * @private
175
- * @returns {Boolean}
201
+ * @returns {boolean}
176
202
  */
177
203
  function _isStreamInput () {
178
204
  return Array.isArray(this.options.input.buffer);
@@ -197,6 +223,7 @@ function _isStreamInput () {
197
223
  * - `loop`: Number of times to loop an animated image, zero refers to a continuous loop.
198
224
  * - `delay`: Delay in ms between each page in an animated image, provided as an array of integers.
199
225
  * - `pagePrimary`: Number of the primary page in a HEIF image
226
+ * - `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide
200
227
  * - `hasProfile`: Boolean indicating the presence of an embedded ICC profile
201
228
  * - `hasAlpha`: Boolean indicating the presence of an alpha transparency channel
202
229
  * - `orientation`: Number value of the EXIF Orientation header, if present
@@ -279,6 +306,8 @@ function metadata (callback) {
279
306
  * - `maxY` (y-coordinate of one of the pixel where the maximum lies)
280
307
  * - `isOpaque`: Is the image fully opaque? Will be `true` if the image has no alpha channel or if every pixel is fully opaque.
281
308
  * - `entropy`: Histogram-based estimation of greyscale entropy, discarding alpha channel if any (experimental)
309
+ * - `sharpness`: Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any (experimental)
310
+ * - `dominant`: Object containing most dominant sRGB colour based on a 4096-bin 3D histogram (experimental)
282
311
  *
283
312
  * @example
284
313
  * const image = sharp(inputJpg);
@@ -288,6 +317,10 @@ function metadata (callback) {
288
317
  * // stats contains the channel-wise statistics array and the isOpaque value
289
318
  * });
290
319
  *
320
+ * @example
321
+ * const { entropy, sharpness, dominant } = await sharp(input).stats();
322
+ * const { r, g, b } = dominant;
323
+ *
291
324
  * @param {Function} [callback] - called with the arguments `(err, stats)`
292
325
  * @returns {Promise<Object>}
293
326
  */
@@ -337,6 +370,7 @@ function stats (callback) {
337
370
  module.exports = function (Sharp) {
338
371
  Object.assign(Sharp.prototype, {
339
372
  // Private
373
+ _inputOptionsFromObject,
340
374
  _createInputDescriptor,
341
375
  _write,
342
376
  _flattenBufferIn,
package/lib/is.js CHANGED
@@ -21,7 +21,7 @@ const object = function (val) {
21
21
  * @private
22
22
  */
23
23
  const plainObject = function (val) {
24
- return object(val) && Object.prototype.toString.call(val) === '[object Object]';
24
+ return Object.prototype.toString.call(val) === '[object Object]';
25
25
  };
26
26
 
27
27
  /**
@@ -45,7 +45,7 @@ const bool = function (val) {
45
45
  * @private
46
46
  */
47
47
  const buffer = function (val) {
48
- return object(val) && val instanceof Buffer;
48
+ return val instanceof Buffer;
49
49
  };
50
50
 
51
51
  /**
@@ -69,7 +69,7 @@ const number = function (val) {
69
69
  * @private
70
70
  */
71
71
  const integer = function (val) {
72
- return number(val) && val % 1 === 0;
72
+ return Number.isInteger(val);
73
73
  };
74
74
 
75
75
  /**
@@ -85,14 +85,14 @@ const inRange = function (val, min, max) {
85
85
  * @private
86
86
  */
87
87
  const inArray = function (val, list) {
88
- return list.indexOf(val) !== -1;
88
+ return list.includes(val);
89
89
  };
90
90
 
91
91
  /**
92
92
  * Create an Error with a message relating to an invalid parameter.
93
93
  *
94
- * @param {String} name - parameter name.
95
- * @param {String} expected - description of the type/value/range expected.
94
+ * @param {string} name - parameter name.
95
+ * @param {string} expected - description of the type/value/range expected.
96
96
  * @param {*} actual - the value received.
97
97
  * @returns {Error} Containing the formatted message.
98
98
  * @private
package/lib/libvips.js CHANGED
@@ -48,24 +48,18 @@ const globalLibvipsVersion = function () {
48
48
 
49
49
  const hasVendoredLibvips = function () {
50
50
  const currentPlatformId = platform();
51
- const vendorPath = path.join(__dirname, '..', 'vendor');
52
- let vendorVersionId;
51
+ const vendorPath = path.join(__dirname, '..', 'vendor', minimumLibvipsVersion);
53
52
  let vendorPlatformId;
54
53
  try {
55
- vendorVersionId = require(path.join(vendorPath, 'versions.json')).vips;
56
54
  vendorPlatformId = require(path.join(vendorPath, 'platform.json'));
57
55
  } catch (err) {}
58
- /* istanbul ignore if */
59
- if (vendorVersionId && vendorVersionId !== minimumLibvipsVersion) {
60
- throw new Error(`Found vendored libvips v${vendorVersionId} but require v${minimumLibvipsVersion}. Please remove the 'node_modules/sharp/vendor' directory and run 'npm install'.`);
61
- }
62
56
  /* istanbul ignore else */
63
57
  if (vendorPlatformId) {
64
58
  /* istanbul ignore else */
65
59
  if (currentPlatformId === vendorPlatformId) {
66
60
  return true;
67
61
  } else {
68
- throw new Error(`'${vendorPlatformId}' binaries cannot be used on the '${currentPlatformId}' platform. Please remove the 'node_modules/sharp/vendor' directory and run 'npm install'.`);
62
+ throw new Error(`'${vendorPlatformId}' binaries cannot be used on the '${currentPlatformId}' platform. Please remove the 'node_modules/sharp' directory and run 'npm install' on the '${currentPlatformId}' platform.`);
69
63
  }
70
64
  } else {
71
65
  return false;
package/lib/operation.js CHANGED
@@ -32,9 +32,9 @@ const is = require('./is');
32
32
  * });
33
33
  * readableStream.pipe(pipeline);
34
34
  *
35
- * @param {Number} [angle=auto] angle of rotation.
35
+ * @param {number} [angle=auto] angle of rotation.
36
36
  * @param {Object} [options] - if present, is an Object with optional attributes.
37
- * @param {String|Object} [options.background="#000000"] parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
37
+ * @param {string|Object} [options.background="#000000"] parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
38
38
  * @returns {Sharp}
39
39
  * @throws {Error} Invalid parameters
40
40
  */
@@ -88,9 +88,9 @@ function flop (flop) {
88
88
  * When a `sigma` is provided, performs a slower, more accurate sharpen of the L channel in the LAB colour space.
89
89
  * Separate control over the level of sharpening in "flat" and "jagged" areas is available.
90
90
  *
91
- * @param {Number} [sigma] - the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
92
- * @param {Number} [flat=1.0] - the level of sharpening to apply to "flat" areas.
93
- * @param {Number} [jagged=2.0] - the level of sharpening to apply to "jagged" areas.
91
+ * @param {number} [sigma] - the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
92
+ * @param {number} [flat=1.0] - the level of sharpening to apply to "flat" areas.
93
+ * @param {number} [jagged=2.0] - the level of sharpening to apply to "jagged" areas.
94
94
  * @returns {Sharp}
95
95
  * @throws {Error} Invalid parameters
96
96
  */
@@ -129,7 +129,7 @@ function sharpen (sigma, flat, jagged) {
129
129
  /**
130
130
  * Apply median filter.
131
131
  * When used without parameters the default window is 3x3.
132
- * @param {Number} [size=3] square mask size: size x size
132
+ * @param {number} [size=3] square mask size: size x size
133
133
  * @returns {Sharp}
134
134
  * @throws {Error} Invalid parameters
135
135
  */
@@ -150,7 +150,7 @@ function median (size) {
150
150
  * Blur the image.
151
151
  * When used without parameters, performs a fast, mild blur of the output image.
152
152
  * When a `sigma` is provided, performs a slower, more accurate Gaussian blur.
153
- * @param {Number} [sigma] a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
153
+ * @param {number} [sigma] a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
154
154
  * @returns {Sharp}
155
155
  * @throws {Error} Invalid parameters
156
156
  */
@@ -173,7 +173,7 @@ function blur (sigma) {
173
173
  /**
174
174
  * Merge alpha transparency channel, if any, with a background.
175
175
  * @param {Object} [options]
176
- * @param {String|Object} [options.background={r: 0, g: 0, b: 0}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black.
176
+ * @param {string|Object} [options.background={r: 0, g: 0, b: 0}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black.
177
177
  * @returns {Sharp}
178
178
  */
179
179
  function flatten (options) {
@@ -193,8 +193,8 @@ function flatten (options) {
193
193
  *
194
194
  * Supply a second argument to use a different output gamma value, otherwise the first value is used in both cases.
195
195
  *
196
- * @param {Number} [gamma=2.2] value between 1.0 and 3.0.
197
- * @param {Number} [gammaOut] value between 1.0 and 3.0. (optional, defaults to same as `gamma`)
196
+ * @param {number} [gamma=2.2] value between 1.0 and 3.0.
197
+ * @param {number} [gammaOut] value between 1.0 and 3.0. (optional, defaults to same as `gamma`)
198
198
  * @returns {Sharp}
199
199
  * @throws {Error} Invalid parameters
200
200
  */
@@ -264,11 +264,11 @@ function normalize (normalize) {
264
264
  * });
265
265
  *
266
266
  * @param {Object} kernel
267
- * @param {Number} kernel.width - width of the kernel in pixels.
268
- * @param {Number} kernel.height - width of the kernel in pixels.
269
- * @param {Array<Number>} kernel.kernel - Array of length `width*height` containing the kernel values.
270
- * @param {Number} [kernel.scale=sum] - the scale of the kernel in pixels.
271
- * @param {Number} [kernel.offset=0] - the offset of the kernel in pixels.
267
+ * @param {number} kernel.width - width of the kernel in pixels.
268
+ * @param {number} kernel.height - width of the kernel in pixels.
269
+ * @param {Array<number>} kernel.kernel - Array of length `width*height` containing the kernel values.
270
+ * @param {number} [kernel.scale=sum] - the scale of the kernel in pixels.
271
+ * @param {number} [kernel.offset=0] - the offset of the kernel in pixels.
272
272
  * @returns {Sharp}
273
273
  * @throws {Error} Invalid parameters
274
274
  */
@@ -300,7 +300,7 @@ function convolve (kernel) {
300
300
 
301
301
  /**
302
302
  * Any pixel value greather than or equal to the threshold value will be set to 255, otherwise it will be set to 0.
303
- * @param {Number} [threshold=128] - a value in the range 0-255 representing the level at which the threshold will be applied.
303
+ * @param {number} [threshold=128] - a value in the range 0-255 representing the level at which the threshold will be applied.
304
304
  * @param {Object} [options]
305
305
  * @param {Boolean} [options.greyscale=true] - convert to single channel greyscale.
306
306
  * @param {Boolean} [options.grayscale=true] - alternative spelling for greyscale.
@@ -331,13 +331,13 @@ function threshold (threshold, options) {
331
331
  * This operation creates an output image where each pixel is the result of
332
332
  * the selected bitwise boolean `operation` between the corresponding pixels of the input images.
333
333
  *
334
- * @param {Buffer|String} operand - Buffer containing image data or String containing the path to an image file.
335
- * @param {String} operator - one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively.
334
+ * @param {Buffer|string} operand - Buffer containing image data or string containing the path to an image file.
335
+ * @param {string} operator - one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively.
336
336
  * @param {Object} [options]
337
337
  * @param {Object} [options.raw] - describes operand when using raw pixel data.
338
- * @param {Number} [options.raw.width]
339
- * @param {Number} [options.raw.height]
340
- * @param {Number} [options.raw.channels]
338
+ * @param {number} [options.raw.width]
339
+ * @param {number} [options.raw.height]
340
+ * @param {number} [options.raw.channels]
341
341
  * @returns {Sharp}
342
342
  * @throws {Error} Invalid parameters
343
343
  */
@@ -353,8 +353,8 @@ function boolean (operand, operator, options) {
353
353
 
354
354
  /**
355
355
  * Apply the linear formula a * input + b to the image (levels adjustment)
356
- * @param {Number} [a=1.0] multiplier
357
- * @param {Number} [b=0.0] offset
356
+ * @param {number} [a=1.0] multiplier
357
+ * @param {number} [b=0.0] offset
358
358
  * @returns {Sharp}
359
359
  * @throws {Error} Invalid parameters
360
360
  */
@@ -394,7 +394,7 @@ function linear (a, b) {
394
394
  * // With this example input, a sepia filter has been applied
395
395
  * });
396
396
  *
397
- * @param {Array<Array<Number>>} 3x3 Recombination matrix
397
+ * @param {Array<Array<number>>} inputMatrix - 3x3 Recombination matrix
398
398
  * @returns {Sharp}
399
399
  * @throws {Error} Invalid parameters
400
400
  */
@@ -440,9 +440,9 @@ function recomb (inputMatrix) {
440
440
  * });
441
441
  *
442
442
  * @param {Object} [options]
443
- * @param {Number} [options.brightness] Brightness multiplier
444
- * @param {Number} [options.saturation] Saturation multiplier
445
- * @param {Number} [options.hue] Degrees for hue rotation
443
+ * @param {number} [options.brightness] Brightness multiplier
444
+ * @param {number} [options.saturation] Saturation multiplier
445
+ * @param {number} [options.hue] Degrees for hue rotation
446
446
  * @returns {Sharp}
447
447
  */
448
448
  function modulate (options) {