sharp 0.30.3 → 0.30.4

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/composite.js CHANGED
@@ -105,7 +105,7 @@ const blend = {
105
105
  * @param {Number} [images[].raw.height]
106
106
  * @param {Number} [images[].raw.channels]
107
107
  * @param {boolean} [images[].animated=false] - Set to `true` to read all frames/pages of an animated image.
108
- * @param {boolean} [images[].failOnError=true] - @see {@link /api-constructor#parameters|constructor parameters}
108
+ * @param {string} [images[].failOn='warning'] - @see {@link /api-constructor#parameters|constructor parameters}
109
109
  * @param {number|boolean} [images[].limitInputPixels=268402689] - @see {@link /api-constructor#parameters|constructor parameters}
110
110
  * @returns {Sharp}
111
111
  * @throws {Error} Invalid parameters
@@ -98,8 +98,7 @@ const debuglog = util.debuglog('sharp');
98
98
  * a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file.
99
99
  * JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
100
100
  * @param {Object} [options] - if present, is an Object with optional attributes.
101
- * @param {boolean} [options.failOnError=true] - by default halt processing and raise an error when loading invalid images.
102
- * Set this flag to `false` if you'd rather apply a "best effort" to decode images, even if the data is corrupt or invalid.
101
+ * @param {string} [options.failOn='warning'] - level of sensitivity to invalid images, one of (in order of sensitivity): 'none' (least), 'truncated', 'error' or 'warning' (most), highers level imply lower levels.
103
102
  * @param {number|boolean} [options.limitInputPixels=268402689] - Do not process input images where the number of pixels
104
103
  * (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted.
105
104
  * An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF).
@@ -320,9 +319,7 @@ Object.setPrototypeOf(Sharp, stream.Duplex);
320
319
  * // Using Promises to know when the pipeline is complete
321
320
  * const fs = require("fs");
322
321
  * const got = require("got");
323
- * const sharpStream = sharp({
324
- * failOnError: false
325
- * });
322
+ * const sharpStream = sharp({ failOn: 'none' });
326
323
  *
327
324
  * const promises = [];
328
325
  *
package/lib/input.js CHANGED
@@ -9,9 +9,9 @@ const sharp = require('./sharp');
9
9
  * @private
10
10
  */
11
11
  function _inputOptionsFromObject (obj) {
12
- const { raw, density, limitInputPixels, unlimited, sequentialRead, failOnError, animated, page, pages, subifd } = obj;
13
- return [raw, density, limitInputPixels, unlimited, sequentialRead, failOnError, animated, page, pages, subifd].some(is.defined)
14
- ? { raw, density, limitInputPixels, unlimited, sequentialRead, failOnError, animated, page, pages, subifd }
12
+ const { raw, density, limitInputPixels, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd } = obj;
13
+ return [raw, density, limitInputPixels, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd].some(is.defined)
14
+ ? { raw, density, limitInputPixels, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd }
15
15
  : undefined;
16
16
  }
17
17
 
@@ -21,7 +21,7 @@ function _inputOptionsFromObject (obj) {
21
21
  */
22
22
  function _createInputDescriptor (input, inputOptions, containerOptions) {
23
23
  const inputDescriptor = {
24
- failOnError: true,
24
+ failOn: 'warning',
25
25
  limitInputPixels: Math.pow(0x3FFF, 2),
26
26
  unlimited: false,
27
27
  sequentialRead: false
@@ -39,7 +39,7 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
39
39
  if (input.length === 0) {
40
40
  throw Error('Input Bit Array is empty');
41
41
  }
42
- inputDescriptor.buffer = Buffer.from(input.buffer);
42
+ inputDescriptor.buffer = Buffer.from(input.buffer, input.byteOffset, input.byteLength);
43
43
  } else if (is.plainObject(input) && !is.defined(inputOptions)) {
44
44
  // Plain Object descriptor, e.g. create
45
45
  inputOptions = input;
@@ -56,14 +56,22 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
56
56
  }`);
57
57
  }
58
58
  if (is.object(inputOptions)) {
59
- // Fail on error
59
+ // Deprecated: failOnError
60
60
  if (is.defined(inputOptions.failOnError)) {
61
61
  if (is.bool(inputOptions.failOnError)) {
62
- inputDescriptor.failOnError = inputOptions.failOnError;
62
+ inputDescriptor.failOn = inputOptions.failOnError ? 'warning' : 'none';
63
63
  } else {
64
64
  throw is.invalidParameterError('failOnError', 'boolean', inputOptions.failOnError);
65
65
  }
66
66
  }
67
+ // failOn
68
+ if (is.defined(inputOptions.failOn)) {
69
+ if (is.string(inputOptions.failOn) && is.inArray(inputOptions.failOn, ['none', 'truncated', 'error', 'warning'])) {
70
+ inputDescriptor.failOn = inputOptions.failOn;
71
+ } else {
72
+ throw is.invalidParameterError('failOn', 'one of: none, truncated, error, warning', inputOptions.failOn);
73
+ }
74
+ }
67
75
  // Density
68
76
  if (is.defined(inputOptions.density)) {
69
77
  if (is.inRange(inputOptions.density, 1, 100000)) {
package/lib/operation.js CHANGED
@@ -420,6 +420,17 @@ function gamma (gamma, gammaOut) {
420
420
 
421
421
  /**
422
422
  * Produce the "negative" of the image.
423
+ *
424
+ * @example
425
+ * const output = await sharp(input)
426
+ * .negate()
427
+ * .toBuffer();
428
+ *
429
+ * @example
430
+ * const output = await sharp(input)
431
+ * .negate({ alpha: false })
432
+ * .toBuffer();
433
+ *
423
434
  * @param {Object} [options]
424
435
  * @param {Boolean} [options.alpha=true] Whether or not to negate any alpha channel
425
436
  * @returns {Sharp}
package/lib/output.js CHANGED
@@ -151,6 +151,8 @@ function toBuffer (options, callback) {
151
151
  * The default behaviour, when `withMetadata` is not used, is to convert to the device-independent
152
152
  * sRGB colour space and strip all metadata, including the removal of any ICC profile.
153
153
  *
154
+ * EXIF metadata is unsupported for TIFF output.
155
+ *
154
156
  * @example
155
157
  * sharp('input.jpg')
156
158
  * .withMetadata()
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sharp",
3
3
  "description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
4
- "version": "0.30.3",
4
+ "version": "0.30.4",
5
5
  "author": "Lovell Fuller <npm@lovell.info>",
6
6
  "homepage": "https://github.com/lovell/sharp",
7
7
  "contributors": [
@@ -81,7 +81,8 @@
81
81
  "Taneli Vatanen <taneli.vatanen@gmail.com>",
82
82
  "Joris Dugué <zaruike10@gmail.com>",
83
83
  "Chris Banks <christopher.bradley.banks@gmail.com>",
84
- "Ompal Singh <ompal.hitm09@gmail.com>"
84
+ "Ompal Singh <ompal.hitm09@gmail.com>",
85
+ "Brodan <christopher.hranj@gmail.com"
85
86
  ],
86
87
  "scripts": {
87
88
  "install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)",
@@ -126,11 +127,11 @@
126
127
  "vips"
127
128
  ],
128
129
  "dependencies": {
129
- "color": "^4.2.1",
130
+ "color": "^4.2.3",
130
131
  "detect-libc": "^2.0.1",
131
132
  "node-addon-api": "^4.3.0",
132
133
  "prebuild-install": "^7.0.1",
133
- "semver": "^7.3.5",
134
+ "semver": "^7.3.7",
134
135
  "simple-get": "^4.0.1",
135
136
  "tar-fs": "^2.1.1",
136
137
  "tunnel-agent": "^0.6.0"
package/src/common.cc CHANGED
@@ -85,7 +85,9 @@ namespace sharp {
85
85
  descriptor->buffer = buffer.Data();
86
86
  descriptor->isBuffer = TRUE;
87
87
  }
88
- descriptor->failOnError = AttrAsBool(input, "failOnError");
88
+ descriptor->failOn = static_cast<VipsFailOn>(
89
+ vips_enum_from_nick(nullptr, VIPS_TYPE_FAIL_ON,
90
+ AttrAsStr(input, "failOn").data()));
89
91
  // Density for vector-based input
90
92
  if (HasAttr(input, "density")) {
91
93
  descriptor->density = AttrAsDouble(input, "density");
@@ -329,7 +331,7 @@ namespace sharp {
329
331
  try {
330
332
  vips::VOption *option = VImage::option()
331
333
  ->set("access", descriptor->access)
332
- ->set("fail", descriptor->failOnError);
334
+ ->set("fail_on", descriptor->failOn);
333
335
  if (descriptor->unlimited && (imageType == ImageType::SVG || imageType == ImageType::PNG)) {
334
336
  option->set("unlimited", TRUE);
335
337
  }
@@ -375,12 +377,6 @@ namespace sharp {
375
377
  VImage::option()->set("mean", descriptor->createNoiseMean)->set("sigma", descriptor->createNoiseSigma)));
376
378
  }
377
379
  image = image.bandjoin(bands);
378
- image = image.cast(VipsBandFormat::VIPS_FORMAT_UCHAR);
379
- if (channels < 3) {
380
- image = image.colourspace(VIPS_INTERPRETATION_B_W);
381
- } else {
382
- image = image.colourspace(VIPS_INTERPRETATION_sRGB);
383
- }
384
380
  } else {
385
381
  std::vector<double> background = {
386
382
  descriptor->createBackground[0],
@@ -392,7 +388,8 @@ namespace sharp {
392
388
  }
393
389
  image = VImage::new_matrix(descriptor->createWidth, descriptor->createHeight).new_from_image(background);
394
390
  }
395
- image.get_image()->Type = VIPS_INTERPRETATION_sRGB;
391
+ image.get_image()->Type = image.guess_interpretation();
392
+ image = image.cast(VIPS_FORMAT_UCHAR);
396
393
  imageType = ImageType::RAW;
397
394
  } else {
398
395
  // From filesystem
@@ -402,13 +399,13 @@ namespace sharp {
402
399
  throw vips::VError("Input file is missing, did you mean "
403
400
  "sharp(Buffer.from('" + descriptor->file.substr(0, 8) + "...')?");
404
401
  }
405
- throw vips::VError("Input file is missing");
402
+ throw vips::VError("Input file is missing: " + descriptor->file);
406
403
  }
407
404
  if (imageType != ImageType::UNKNOWN) {
408
405
  try {
409
406
  vips::VOption *option = VImage::option()
410
407
  ->set("access", descriptor->access)
411
- ->set("fail", descriptor->failOnError);
408
+ ->set("fail_on", descriptor->failOn);
412
409
  if (descriptor->unlimited && (imageType == ImageType::SVG || imageType == ImageType::PNG)) {
413
410
  option->set("unlimited", TRUE);
414
411
  }
package/src/common.h CHANGED
@@ -48,7 +48,7 @@ namespace sharp {
48
48
  std::string name;
49
49
  std::string file;
50
50
  char *buffer;
51
- bool failOnError;
51
+ VipsFailOn failOn;
52
52
  int limitInputPixels;
53
53
  bool unlimited;
54
54
  VipsAccess access;
@@ -74,7 +74,7 @@ namespace sharp {
74
74
 
75
75
  InputDescriptor():
76
76
  buffer(nullptr),
77
- failOnError(TRUE),
77
+ failOn(VIPS_FAIL_ON_WARNING),
78
78
  limitInputPixels(0x3FFF * 0x3FFF),
79
79
  unlimited(FALSE),
80
80
  access(VIPS_ACCESS_RANDOM),
package/src/pipeline.cc CHANGED
@@ -200,7 +200,7 @@ class PipelineWorker : public Napi::AsyncWorker {
200
200
  vips::VOption *option = VImage::option()
201
201
  ->set("access", baton->input->access)
202
202
  ->set("shrink", jpegShrinkOnLoad)
203
- ->set("fail", baton->input->failOnError);
203
+ ->set("fail_on", baton->input->failOn);
204
204
  if (baton->input->buffer != nullptr) {
205
205
  // Reload JPEG buffer
206
206
  VipsBlob *blob = vips_blob_new(nullptr, baton->input->buffer, baton->input->bufferLength);
@@ -214,7 +214,7 @@ class PipelineWorker : public Napi::AsyncWorker {
214
214
  vips::VOption *option = VImage::option()
215
215
  ->set("access", baton->input->access)
216
216
  ->set("scale", scale)
217
- ->set("fail", baton->input->failOnError);
217
+ ->set("fail_on", baton->input->failOn);
218
218
  if (inputImageType == sharp::ImageType::WEBP) {
219
219
  option->set("n", baton->input->pages);
220
220
  option->set("page", baton->input->page);
@@ -241,8 +241,10 @@ class PipelineWorker : public Napi::AsyncWorker {
241
241
  // Reload SVG file
242
242
  image = VImage::svgload(const_cast<char*>(baton->input->file.data()), option);
243
243
  }
244
-
245
244
  sharp::SetDensity(image, baton->input->density);
245
+ if (image.width() > 32767 || image.height() > 32767) {
246
+ throw vips::VError("Input SVG image will exceed 32767x32767 pixel limit when scaled");
247
+ }
246
248
  } else if (inputImageType == sharp::ImageType::PDF) {
247
249
  option->set("n", baton->input->pages);
248
250
  option->set("page", baton->input->page);
@@ -260,6 +262,10 @@ class PipelineWorker : public Napi::AsyncWorker {
260
262
 
261
263
  sharp::SetDensity(image, baton->input->density);
262
264
  }
265
+ } else {
266
+ if (inputImageType == sharp::ImageType::SVG && (image.width() > 32767 || image.height() > 32767)) {
267
+ throw vips::VError("Input SVG image exceeds 32767x32767 pixel limit");
268
+ }
263
269
  }
264
270
 
265
271
  // Any pre-shrinking may already have been done