sharp 0.29.1 → 0.29.2

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.
@@ -273,6 +273,7 @@ const Sharp = function (input, options) {
273
273
  tileBackground: [255, 255, 255, 255],
274
274
  tileCentre: false,
275
275
  tileId: 'https://example.com/iiif',
276
+ timeoutSeconds: 0,
276
277
  linearA: 1,
277
278
  linearB: 0,
278
279
  // Function to notify of libvips warnings
@@ -288,7 +289,8 @@ const Sharp = function (input, options) {
288
289
  this.options.input = this._createInputDescriptor(input, options, { allowStream: true });
289
290
  return this;
290
291
  };
291
- util.inherits(Sharp, stream.Duplex);
292
+ Object.setPrototypeOf(Sharp.prototype, stream.Duplex.prototype);
293
+ Object.setPrototypeOf(Sharp, stream.Duplex);
292
294
 
293
295
  /**
294
296
  * Take a "snapshot" of the Sharp instance, returning a new instance.
package/lib/output.js CHANGED
@@ -13,6 +13,7 @@ const formats = new Map([
13
13
  ['png', 'png'],
14
14
  ['raw', 'raw'],
15
15
  ['tiff', 'tiff'],
16
+ ['tif', 'tiff'],
16
17
  ['webp', 'webp'],
17
18
  ['gif', 'gif'],
18
19
  ['jp2', 'jp2'],
@@ -974,6 +975,31 @@ function tile (options) {
974
975
  return this._updateFormatOut('dz');
975
976
  }
976
977
 
978
+ /**
979
+ * Set a timeout for processing, in seconds.
980
+ * Use a value of zero to continue processing indefinitely, the default behaviour.
981
+ *
982
+ * The clock starts when libvips opens an input image for processing.
983
+ * Time spent waiting for a libuv thread to become available is not included.
984
+ *
985
+ * @since 0.29.2
986
+ *
987
+ * @param {Object} options
988
+ * @param {number} options.seconds - Number of seconds after which processing will be stopped
989
+ * @returns {Sharp}
990
+ */
991
+ function timeout (options) {
992
+ if (!is.plainObject(options)) {
993
+ throw is.invalidParameterError('options', 'object', options);
994
+ }
995
+ if (is.integer(options.seconds) && is.inRange(options.seconds, 0, 3600)) {
996
+ this.options.timeoutSeconds = options.seconds;
997
+ } else {
998
+ throw is.invalidParameterError('seconds', 'integer between 0 and 3600', options.seconds);
999
+ }
1000
+ return this;
1001
+ }
1002
+
977
1003
  /**
978
1004
  * Update the output format unless options.force is false,
979
1005
  * in which case revert to input format.
@@ -1128,6 +1154,7 @@ module.exports = function (Sharp) {
1128
1154
  gif,
1129
1155
  raw,
1130
1156
  tile,
1157
+ timeout,
1131
1158
  // Private
1132
1159
  _updateFormatOut,
1133
1160
  _setBooleanOption,
package/lib/sharp.js CHANGED
@@ -19,6 +19,13 @@ try {
19
19
  help.push(
20
20
  '- Consult the installation documentation: https://sharp.pixelplumbing.com/install'
21
21
  );
22
- console.error(help.join('\n'));
23
- process.exit(1);
22
+ // Check loaded
23
+ if (process.platform === 'win32') {
24
+ const loadedModule = Object.keys(require.cache).find((i) => /[\\/]build[\\/]Release[\\/]sharp(.*)\.node$/.test(i));
25
+ if (loadedModule) {
26
+ const [, loadedPackage] = loadedModule.match(/node_modules[\\/]([^\\/]+)[\\/]/);
27
+ help.push(`- Ensure the version of sharp aligns with the ${loadedPackage} package: "npm ls sharp"`);
28
+ }
29
+ }
30
+ throw new Error(help.join('\n'));
24
31
  }
package/lib/utility.js CHANGED
@@ -4,6 +4,7 @@ const events = require('events');
4
4
  const detectLibc = require('detect-libc');
5
5
 
6
6
  const is = require('./is');
7
+ const platformAndArch = require('./platform')();
7
8
  const sharp = require('./sharp');
8
9
 
9
10
  /**
@@ -45,7 +46,7 @@ let versions = {
45
46
  vips: sharp.libvipsVersion()
46
47
  };
47
48
  try {
48
- versions = require(`../vendor/${versions.vips}/versions.json`);
49
+ versions = require(`../vendor/${versions.vips}/${platformAndArch}/versions.json`);
49
50
  } catch (err) {}
50
51
 
51
52
  /**
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, AVIF and TIFF images",
4
- "version": "0.29.1",
4
+ "version": "0.29.2",
5
5
  "author": "Lovell Fuller <npm@lovell.info>",
6
6
  "homepage": "https://github.com/lovell/sharp",
7
7
  "contributors": [
@@ -126,7 +126,7 @@
126
126
  "dependencies": {
127
127
  "color": "^4.0.1",
128
128
  "detect-libc": "^1.0.3",
129
- "node-addon-api": "^4.1.0",
129
+ "node-addon-api": "^4.2.0",
130
130
  "prebuild-install": "^6.1.4",
131
131
  "semver": "^7.3.5",
132
132
  "simple-get": "^3.1.0",
@@ -141,10 +141,10 @@
141
141
  "exif-reader": "^1.0.3",
142
142
  "icc": "^2.0.0",
143
143
  "license-checker": "^25.0.1",
144
- "mocha": "^9.1.1",
145
- "mock-fs": "^5.0.0",
144
+ "mocha": "^9.1.3",
145
+ "mock-fs": "^5.1.1",
146
146
  "nyc": "^15.1.0",
147
- "prebuild": "^10.0.1",
147
+ "prebuild": "^11.0.0",
148
148
  "rimraf": "^3.0.2",
149
149
  "semistandard": "^16.0.1"
150
150
  },
package/src/common.cc CHANGED
@@ -610,6 +610,33 @@ namespace sharp {
610
610
  return warning;
611
611
  }
612
612
 
613
+ /*
614
+ Attach an event listener for progress updates, used to detect timeout
615
+ */
616
+ void SetTimeout(VImage image, int const seconds) {
617
+ if (seconds > 0) {
618
+ VipsImage *im = image.get_image();
619
+ if (im->progress_signal == NULL) {
620
+ int *timeout = VIPS_NEW(im, int);
621
+ *timeout = seconds;
622
+ g_signal_connect(im, "eval", G_CALLBACK(VipsProgressCallBack), timeout);
623
+ vips_image_set_progress(im, TRUE);
624
+ }
625
+ }
626
+ }
627
+
628
+ /*
629
+ Event listener for progress updates, used to detect timeout
630
+ */
631
+ void VipsProgressCallBack(VipsImage *im, VipsProgress *progress, int *timeout) {
632
+ // printf("VipsProgressCallBack progress=%d run=%d timeout=%d\n", progress->percent, progress->run, *timeout);
633
+ if (*timeout > 0 && progress->run >= *timeout) {
634
+ vips_image_set_kill(im, TRUE);
635
+ vips_error("timeout", "%d%% complete", progress->percent);
636
+ *timeout = 0;
637
+ }
638
+ }
639
+
613
640
  /*
614
641
  Calculate the (left, top) coordinates of the output image
615
642
  within the input image, applying the given gravity during an embed.
package/src/common.h CHANGED
@@ -250,6 +250,16 @@ namespace sharp {
250
250
  */
251
251
  std::string VipsWarningPop();
252
252
 
253
+ /*
254
+ Attach an event listener for progress updates, used to detect timeout
255
+ */
256
+ void SetTimeout(VImage image, int const timeoutSeconds);
257
+
258
+ /*
259
+ Event listener for progress updates, used to detect timeout
260
+ */
261
+ void VipsProgressCallBack(VipsImage *image, VipsProgress *progress, int *timeoutSeconds);
262
+
253
263
  /*
254
264
  Calculate the (left, top) coordinates of the output image
255
265
  within the input image, applying the given gravity during an embed.
package/src/pipeline.cc CHANGED
@@ -289,6 +289,10 @@ class PipelineWorker : public Napi::AsyncWorker {
289
289
  yfactor = static_cast<double>(shrunkOnLoadHeight) / static_cast<double>(targetResizeHeight);
290
290
  }
291
291
  }
292
+ // Remove animation properties from single page images
293
+ if (baton->input->pages == 1) {
294
+ image = sharp::RemoveAnimationProperties(image);
295
+ }
292
296
 
293
297
  // Ensure we're using a device-independent colour space
294
298
  char const *processingProfile = image.interpretation() == VIPS_INTERPRETATION_RGB16 ? "p3" : "srgb";
@@ -764,6 +768,7 @@ class PipelineWorker : public Napi::AsyncWorker {
764
768
  baton->loop);
765
769
 
766
770
  // Output
771
+ sharp::SetTimeout(image, baton->timeoutSeconds);
767
772
  if (baton->fileOut.empty()) {
768
773
  // Buffer output
769
774
  if (baton->formatOut == "jpeg" || (baton->formatOut == "input" && inputImageType == sharp::ImageType::JPEG)) {
@@ -1451,6 +1456,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1451
1456
  std::string k = sharp::AttrAsStr(mdStrKeys, i);
1452
1457
  baton->withMetadataStrs.insert(std::make_pair(k, sharp::AttrAsStr(mdStrs, k)));
1453
1458
  }
1459
+ baton->timeoutSeconds = sharp::AttrAsUint32(options, "timeoutSeconds");
1454
1460
  // Format-specific
1455
1461
  baton->jpegQuality = sharp::AttrAsUint32(options, "jpegQuality");
1456
1462
  baton->jpegProgressive = sharp::AttrAsBool(options, "jpegProgressive");
package/src/pipeline.h CHANGED
@@ -182,6 +182,7 @@ struct PipelineBaton {
182
182
  double withMetadataDensity;
183
183
  std::string withMetadataIcc;
184
184
  std::unordered_map<std::string, std::string> withMetadataStrs;
185
+ int timeoutSeconds;
185
186
  std::unique_ptr<double[]> convKernel;
186
187
  int convKernelWidth;
187
188
  int convKernelHeight;
@@ -315,6 +316,7 @@ struct PipelineBaton {
315
316
  withMetadata(false),
316
317
  withMetadataOrientation(-1),
317
318
  withMetadataDensity(0.0),
319
+ timeoutSeconds(0),
318
320
  convKernelWidth(0),
319
321
  convKernelHeight(0),
320
322
  convKernelScale(0.0),