sharp 0.28.2 → 0.28.3

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.
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ const libvips = require('../lib/libvips');
4
+
5
+ try {
6
+ if (!(libvips.useGlobalLibvips() || libvips.hasVendoredLibvips())) {
7
+ process.exitCode = 1;
8
+ }
9
+ } catch (err) {
10
+ process.exitCode = 1;
11
+ }
@@ -43,7 +43,6 @@ const fail = function (err) {
43
43
  if (err.code === 'EACCES') {
44
44
  libvips.log('Are you trying to install as a root or sudo user? Try again with the --unsafe-perm flag');
45
45
  }
46
- libvips.log('Attempting to build from source via node-gyp but this may fail due to the above error');
47
46
  libvips.log('Please see https://sharp.pixelplumbing.com/install for required dependencies');
48
47
  process.exit(1);
49
48
  };
package/lib/channel.js CHANGED
@@ -15,6 +15,8 @@ const bool = {
15
15
  /**
16
16
  * Remove alpha channel, if any. This is a no-op if the image does not have an alpha channel.
17
17
  *
18
+ * See also {@link /api-operation#flatten|flatten}.
19
+ *
18
20
  * @example
19
21
  * sharp('rgba.png')
20
22
  * .removeAlpha()
package/lib/composite.js CHANGED
@@ -89,6 +89,8 @@ const blend = {
89
89
  * @param {Number} [images[].raw.width]
90
90
  * @param {Number} [images[].raw.height]
91
91
  * @param {Number} [images[].raw.channels]
92
+ * @param {boolean} [images[].failOnError=true] - @see {@link /api-constructor#parameters|constructor parameters}
93
+ * @param {number|boolean} [images[].limitInputPixels=268402689] - @see {@link /api-constructor#parameters|constructor parameters}
92
94
  * @returns {Sharp}
93
95
  * @throws {Error} Invalid parameters
94
96
  */
@@ -216,6 +216,9 @@ const Sharp = function (input, options) {
216
216
  gammaOut: 0,
217
217
  greyscale: false,
218
218
  normalise: false,
219
+ claheWidth: 0,
220
+ claheHeight: 0,
221
+ claheMaxSlope: 3,
219
222
  brightness: 1,
220
223
  saturation: 1,
221
224
  hue: 0,
package/lib/operation.js CHANGED
@@ -270,9 +270,11 @@ function blur (sigma) {
270
270
  /**
271
271
  * Merge alpha transparency channel, if any, with a background, then remove the alpha channel.
272
272
  *
273
+ * See also {@link /api-channel#removealpha|removeAlpha}.
274
+ *
273
275
  * @example
274
276
  * await sharp(rgbaInput)
275
- * .flatten({background: '#F0A703' })
277
+ * .flatten({ background: '#F0A703' })
276
278
  * .toBuffer();
277
279
  *
278
280
  * @param {Object} [options]
@@ -350,6 +352,47 @@ function normalize (normalize) {
350
352
  return this.normalise(normalize);
351
353
  }
352
354
 
355
+ /**
356
+ * Perform contrast limiting adaptive histogram equalization
357
+ * {@link https://en.wikipedia.org/wiki/Adaptive_histogram_equalization#Contrast_Limited_AHE|CLAHE}.
358
+ *
359
+ * This will, in general, enhance the clarity of the image by bringing out darker details.
360
+ *
361
+ * @since 0.28.3
362
+ *
363
+ * @param {Object} options
364
+ * @param {number} options.width - integer width of the region in pixels.
365
+ * @param {number} options.height - integer height of the region in pixels.
366
+ * @param {number} [options.maxSlope=3] - maximum value for the slope of the
367
+ * cumulative histogram. A value of 0 disables contrast limiting. Valid values
368
+ * are integers in the range 0-100 (inclusive)
369
+ * @returns {Sharp}
370
+ * @throws {Error} Invalid parameters
371
+ */
372
+ function clahe (options) {
373
+ if (!is.plainObject(options)) {
374
+ throw is.invalidParameterError('options', 'plain object', options);
375
+ }
376
+ if (!('width' in options) || !is.integer(options.width) || options.width <= 0) {
377
+ throw is.invalidParameterError('width', 'integer above zero', options.width);
378
+ } else {
379
+ this.options.claheWidth = options.width;
380
+ }
381
+ if (!('height' in options) || !is.integer(options.height) || options.height <= 0) {
382
+ throw is.invalidParameterError('height', 'integer above zero', options.height);
383
+ } else {
384
+ this.options.claheHeight = options.height;
385
+ }
386
+ if (!is.defined(options.maxSlope)) {
387
+ this.options.claheMaxSlope = 3;
388
+ } else if (!is.integer(options.maxSlope) || options.maxSlope < 0 || options.maxSlope > 100) {
389
+ throw is.invalidParameterError('maxSlope', 'integer 0-100', options.maxSlope);
390
+ } else {
391
+ this.options.claheMaxSlope = options.maxSlope;
392
+ }
393
+ return this;
394
+ }
395
+
353
396
  /**
354
397
  * Convolve the image with the specified kernel.
355
398
  *
@@ -368,7 +411,7 @@ function normalize (normalize) {
368
411
  *
369
412
  * @param {Object} kernel
370
413
  * @param {number} kernel.width - width of the kernel in pixels.
371
- * @param {number} kernel.height - width of the kernel in pixels.
414
+ * @param {number} kernel.height - height of the kernel in pixels.
372
415
  * @param {Array<number>} kernel.kernel - Array of length `width*height` containing the kernel values.
373
416
  * @param {number} [kernel.scale=sum] - the scale of the kernel in pixels.
374
417
  * @param {number} [kernel.offset=0] - the offset of the kernel in pixels.
@@ -594,6 +637,7 @@ module.exports = function (Sharp) {
594
637
  negate,
595
638
  normalise,
596
639
  normalize,
640
+ clahe,
597
641
  convolve,
598
642
  threshold,
599
643
  boolean,
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.28.2",
4
+ "version": "0.28.3",
5
5
  "author": "Lovell Fuller <npm@lovell.info>",
6
6
  "homepage": "https://github.com/lovell/sharp",
7
7
  "contributors": [
@@ -76,10 +76,11 @@
76
76
  "Leon Radley <leon@radley.se>",
77
77
  "alza54 <alza54@thiocod.in>",
78
78
  "Jacob Smith <jacob@frende.me>",
79
- "Michael Nutt <michael@nutt.im>"
79
+ "Michael Nutt <michael@nutt.im>",
80
+ "Brad Parham <baparham@gmail.com>"
80
81
  ],
81
82
  "scripts": {
82
- "install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)",
83
+ "install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)",
83
84
  "clean": "rm -rf node_modules/ build/ vendor/ .nyc_output/ coverage/ test/fixtures/output.*",
84
85
  "test": "npm run test-lint && npm run test-unit && npm run test-licensing",
85
86
  "test-lint": "semistandard && cpplint",
@@ -122,7 +123,7 @@
122
123
  "dependencies": {
123
124
  "color": "^3.1.3",
124
125
  "detect-libc": "^1.0.3",
125
- "node-addon-api": "^3.1.0",
126
+ "node-addon-api": "^3.2.0",
126
127
  "prebuild-install": "^6.1.2",
127
128
  "semver": "^7.3.5",
128
129
  "simple-get": "^3.1.0",
package/src/operations.cc CHANGED
@@ -92,6 +92,13 @@ namespace sharp {
92
92
  return image;
93
93
  }
94
94
 
95
+ /*
96
+ * Contrast limiting adapative histogram equalization (CLAHE)
97
+ */
98
+ VImage Clahe(VImage image, int const width, int const height, int const maxSlope) {
99
+ return image.hist_local(width, height, VImage::option()->set("max_slope", maxSlope));
100
+ }
101
+
95
102
  /*
96
103
  * Gamma encoding/decoding
97
104
  */
package/src/operations.h CHANGED
@@ -35,6 +35,11 @@ namespace sharp {
35
35
  */
36
36
  VImage Normalise(VImage image);
37
37
 
38
+ /*
39
+ * Contrast limiting adapative histogram equalization (CLAHE)
40
+ */
41
+ VImage Clahe(VImage image, int const width, int const height, int const maxSlope);
42
+
38
43
  /*
39
44
  * Gamma encoding/decoding
40
45
  */
package/src/pipeline.cc CHANGED
@@ -227,7 +227,7 @@ class PipelineWorker : public Napi::AsyncWorker {
227
227
  xshrink == yshrink && xshrink >= 2 * shrink_on_load_factor &&
228
228
  (inputImageType == sharp::ImageType::JPEG || inputImageType == sharp::ImageType::WEBP) &&
229
229
  baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold == 0.0 &&
230
- image.width() > 3 && image.height() > 3
230
+ image.width() > 3 && image.height() > 3 && baton->input->pages == 1
231
231
  ) {
232
232
  if (xshrink >= 8 * shrink_on_load_factor) {
233
233
  xfactor = xfactor / 8;
@@ -345,6 +345,7 @@ class PipelineWorker : public Napi::AsyncWorker {
345
345
  bool const shouldApplyMedian = baton->medianSize > 0;
346
346
  bool const shouldComposite = !baton->composite.empty();
347
347
  bool const shouldModulate = baton->brightness != 1.0 || baton->saturation != 1.0 || baton->hue != 0.0;
348
+ bool const shouldApplyClahe = baton->claheWidth != 0 && baton->claheHeight != 0;
348
349
 
349
350
  if (shouldComposite && !sharp::HasAlpha(image)) {
350
351
  image = sharp::EnsureAlpha(image, 1);
@@ -650,6 +651,11 @@ class PipelineWorker : public Napi::AsyncWorker {
650
651
  image = sharp::Normalise(image);
651
652
  }
652
653
 
654
+ // Apply contrast limiting adaptive histogram equalization (CLAHE)
655
+ if (shouldApplyClahe) {
656
+ image = sharp::Clahe(image, baton->claheWidth, baton->claheHeight, baton->claheMaxSlope);
657
+ }
658
+
653
659
  // Apply bitwise boolean operation between images
654
660
  if (baton->boolean != nullptr) {
655
661
  VImage booleanImage;
@@ -1330,6 +1336,9 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1330
1336
  baton->linearB = sharp::AttrAsDouble(options, "linearB");
1331
1337
  baton->greyscale = sharp::AttrAsBool(options, "greyscale");
1332
1338
  baton->normalise = sharp::AttrAsBool(options, "normalise");
1339
+ baton->claheWidth = sharp::AttrAsUint32(options, "claheWidth");
1340
+ baton->claheHeight = sharp::AttrAsUint32(options, "claheHeight");
1341
+ baton->claheMaxSlope = sharp::AttrAsUint32(options, "claheMaxSlope");
1333
1342
  baton->useExifOrientation = sharp::AttrAsBool(options, "useExifOrientation");
1334
1343
  baton->angle = sharp::AttrAsInt32(options, "angle");
1335
1344
  baton->rotationAngle = sharp::AttrAsDouble(options, "rotationAngle");
package/src/pipeline.h CHANGED
@@ -109,6 +109,9 @@ struct PipelineBaton {
109
109
  double gammaOut;
110
110
  bool greyscale;
111
111
  bool normalise;
112
+ int claheWidth;
113
+ int claheHeight;
114
+ int claheMaxSlope;
112
115
  bool useExifOrientation;
113
116
  int angle;
114
117
  double rotationAngle;
@@ -234,6 +237,9 @@ struct PipelineBaton {
234
237
  gamma(0.0),
235
238
  greyscale(false),
236
239
  normalise(false),
240
+ claheWidth(0),
241
+ claheHeight(0),
242
+ claheMaxSlope(3),
237
243
  useExifOrientation(false),
238
244
  angle(0),
239
245
  rotationAngle(0.0),