sharp 0.20.8 → 0.21.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.
@@ -3,19 +3,17 @@
3
3
  ### Test environment
4
4
 
5
5
  * AWS EC2 eu-west-1 [c5.large](https://aws.amazon.com/ec2/instance-types/c5/) (2x Xeon Platinum 8124M CPU @ 3.00GHz)
6
- * Ubuntu 17.10 (hvm:ebs-ssd, 20180102, ami-0741d47e)
7
- * Node.js v8.9.4
6
+ * Ubuntu 18.04 (hvm-ssd/ubuntu-bionic-18.04-amd64-server-20180912 ami-00035f41c82244dab)
7
+ * Node.js v10.11.0
8
8
 
9
9
  ### The contenders
10
10
 
11
- * [jimp](https://www.npmjs.com/package/jimp) v0.2.28 - Image processing in pure JavaScript. Bilinear interpolation only.
12
- * [pajk-lwip](https://www.npmjs.com/package/pajk-lwip) v0.2.0 (fork) - Wrapper around CImg that compiles dependencies from source.
13
- * [mapnik](https://www.npmjs.org/package/mapnik) v3.6.2 - Whilst primarily a map renderer, Mapnik contains bitmap image utilities.
11
+ * [jimp](https://www.npmjs.com/package/jimp) v0.5.3 - Image processing in pure JavaScript. Provides bicubic interpolation.
12
+ * [mapnik](https://www.npmjs.org/package/mapnik) v4.0.1 - Whilst primarily a map renderer, Mapnik contains bitmap image utilities.
14
13
  * [imagemagick-native](https://www.npmjs.com/package/imagemagick-native) v1.9.3 - Wrapper around libmagick++, supports Buffers only.
15
14
  * [imagemagick](https://www.npmjs.com/package/imagemagick) v0.1.3 - Supports filesystem only and "*has been unmaintained for a long time*".
16
15
  * [gm](https://www.npmjs.com/package/gm) v1.23.1 - Fully featured wrapper around GraphicsMagick's `gm` command line utility.
17
- * [images](https://www.npmjs.com/package/images) v3.0.1 - Compiles dependencies from source. Provides bicubic interpolation.
18
- * sharp v0.19.0 / libvips v8.6.1 - Caching within libvips disabled to ensure a fair comparison.
16
+ * sharp v0.21.0 / libvips v8.7.0 - Caching within libvips disabled to ensure a fair comparison.
19
17
 
20
18
  ### The task
21
19
 
@@ -27,19 +25,14 @@ then compress to JPEG at a "quality" setting of 80.
27
25
 
28
26
  | Module | Input | Output | Ops/sec | Speed-up |
29
27
  | :----------------- | :----- | :----- | ------: | -------: |
30
- | jimp (bilinear) | buffer | buffer | 1.14 | 1.0 |
31
- | lwip | buffer | buffer | 1.86 | 1.6 |
32
- | mapnik | buffer | buffer | 3.34 | 2.9 |
33
- | imagemagick-native | buffer | buffer | 4.13 | 3.6 |
34
- | gm | buffer | buffer | 4.21 | 3.7 |
35
- | gm | file | file | 4.27 | 3.7 |
36
- | imagemagick | file | file | 4.67 | 4.1 |
37
- | images (bicubic) | file | file | 6.22 | 5.5 |
38
- | sharp | stream | stream | 24.43 | 21.4 |
39
- | sharp | file | file | 25.97 | 22.7 |
40
- | sharp | file | buffer | 26.00 | 22.8 |
41
- | sharp | buffer | file | 26.33 | 23.0 |
42
- | sharp | buffer | buffer | 26.43 | 23.1 |
28
+ | jimp | buffer | buffer | 0.71 | 1.0 |
29
+ | mapnik | buffer | buffer | 3.32 | 4.7 |
30
+ | gm | buffer | buffer | 3.97 | 5.6 |
31
+ | imagemagick-native | buffer | buffer | 4.06 | 5.7 |
32
+ | imagemagick | file | file | 4.24 | 6.0 |
33
+ | sharp | stream | stream | 25.30 | 35.6 |
34
+ | sharp | file | file | 26.17 | 36.9 |
35
+ | sharp | buffer | buffer | 26.45 | 37.3 |
43
36
 
44
37
  Greater libvips performance can be expected with caching enabled (default)
45
38
  and using 8+ core machines, especially those with larger L1/L2 CPU caches.
@@ -57,7 +50,7 @@ brew install mapnik
57
50
  ```
58
51
 
59
52
  ```sh
60
- sudo apt-get install imagemagick libmagick++-dev graphicsmagick mapnik-dev
53
+ sudo apt-get install imagemagick libmagick++-dev graphicsmagick libmapnik-dev
61
54
  ```
62
55
 
63
56
  ```sh
@@ -18,6 +18,12 @@ const platform = require('../lib/platform');
18
18
  const minimumLibvipsVersion = libvips.minimumLibvipsVersion;
19
19
  const distBaseUrl = process.env.SHARP_DIST_BASE_URL || `https://github.com/lovell/sharp-libvips/releases/download/v${minimumLibvipsVersion}/`;
20
20
 
21
+ const fail = function (err) {
22
+ npmLog.error('sharp', err.message);
23
+ npmLog.error('sharp', 'Please see http://sharp.pixelplumbing.com/page/install');
24
+ process.exit(1);
25
+ };
26
+
21
27
  const extractTarball = function (tarPath) {
22
28
  const vendorPath = path.join(__dirname, '..', 'vendor');
23
29
  libvips.mkdirSync(vendorPath);
@@ -27,9 +33,7 @@ const extractTarball = function (tarPath) {
27
33
  cwd: vendorPath,
28
34
  strict: true
29
35
  })
30
- .catch(function (err) {
31
- throw err;
32
- });
36
+ .catch(fail);
33
37
  };
34
38
 
35
39
  try {
@@ -54,9 +58,6 @@ try {
54
58
  if (platformAndArch === 'freebsd-x64') {
55
59
  throw new Error(`FreeBSD systems require manual installation of libvips >= ${minimumLibvipsVersion}`);
56
60
  }
57
- if (detectLibc.isNonGlibcLinux) {
58
- throw new Error(`Use with ${detectLibc.family} libc requires manual installation of libvips >= ${minimumLibvipsVersion}`);
59
- }
60
61
  if (detectLibc.family === detectLibc.GLIBC && detectLibc.version && semver.lt(`${detectLibc.version}.0`, '2.13.0')) {
61
62
  throw new Error(`Use with glibc version ${detectLibc.version} requires manual installation of libvips >= ${minimumLibvipsVersion}`);
62
63
  }
@@ -80,21 +81,21 @@ try {
80
81
  }
81
82
  response.pipe(tmpFile);
82
83
  });
83
- tmpFile.on('close', function () {
84
- try {
85
- // Attempt to rename
86
- fs.renameSync(tarPathTemp, tarPathCache);
87
- } catch (err) {
88
- // Fall back to copy and unlink
89
- copyFileSync(tarPathTemp, tarPathCache);
90
- fs.unlinkSync(tarPathTemp);
91
- }
92
- extractTarball(tarPathCache);
93
- });
84
+ tmpFile
85
+ .on('error', fail)
86
+ .on('close', function () {
87
+ try {
88
+ // Attempt to rename
89
+ fs.renameSync(tarPathTemp, tarPathCache);
90
+ } catch (err) {
91
+ // Fall back to copy and unlink
92
+ copyFileSync(tarPathTemp, tarPathCache);
93
+ fs.unlinkSync(tarPathTemp);
94
+ }
95
+ extractTarball(tarPathCache);
96
+ });
94
97
  }
95
98
  }
96
99
  } catch (err) {
97
- npmLog.error('sharp', err.message);
98
- npmLog.error('sharp', 'Please see http://sharp.pixelplumbing.com/page/install');
99
- process.exit(1);
100
+ fail(err);
100
101
  }
package/lib/colour.js CHANGED
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ const deprecate = require('util').deprecate;
4
+
3
5
  const color = require('color');
4
6
  const is = require('./is');
5
7
 
@@ -16,25 +18,20 @@ const colourspace = {
16
18
  };
17
19
 
18
20
  /**
19
- * Set the background for the `embed`, `flatten` and `extend` operations.
20
- * The default background is `{r: 0, g: 0, b: 0, alpha: 1}`, black without transparency.
21
- *
22
- * Delegates to the _color_ module, which can throw an Error
23
- * but is liberal in what it accepts, clipping values to sensible min/max.
24
- * The alpha value is a float between `0` (transparent) and `1` (opaque).
25
- *
26
- * @param {String|Object} rgba - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
27
- * @returns {Sharp}
28
- * @throws {Error} Invalid parameter
21
+ * @deprecated
22
+ * @private
29
23
  */
30
24
  function background (rgba) {
31
25
  const colour = color(rgba);
32
- this.options.background = [
26
+ const background = [
33
27
  colour.red(),
34
28
  colour.green(),
35
29
  colour.blue(),
36
30
  Math.round(colour.alpha() * 255)
37
31
  ];
32
+ this.options.resizeBackground = background;
33
+ this.options.extendBackground = background;
34
+ this.options.flattenBackground = background.slice(0, 3);
38
35
  return this;
39
36
  }
40
37
 
@@ -80,7 +77,7 @@ function grayscale (grayscale) {
80
77
  /**
81
78
  * Set the output colourspace.
82
79
  * By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.
83
- * @param {String} [colourspace] - output colourspace e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://github.com/jcupitt/libvips/blob/master/libvips/iofuncs/enumtypes.c#L568)
80
+ * @param {String} [colourspace] - output colourspace e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://github.com/libvips/libvips/blob/master/libvips/iofuncs/enumtypes.c#L568)
84
81
  * @returns {Sharp}
85
82
  * @throws {Error} Invalid parameters
86
83
  */
@@ -102,23 +99,45 @@ function toColorspace (colorspace) {
102
99
  return this.toColourspace(colorspace);
103
100
  }
104
101
 
102
+ /**
103
+ * Update a colour attribute of the this.options Object.
104
+ * @private
105
+ * @param {String} key
106
+ * @param {String|Object} val
107
+ * @throws {Error} Invalid key
108
+ */
109
+ function _setColourOption (key, val) {
110
+ if (is.object(val) || is.string(val)) {
111
+ const colour = color(val);
112
+ this.options[key] = [
113
+ colour.red(),
114
+ colour.green(),
115
+ colour.blue(),
116
+ Math.round(colour.alpha() * 255)
117
+ ];
118
+ }
119
+ }
120
+
105
121
  /**
106
122
  * Decorate the Sharp prototype with colour-related functions.
107
123
  * @private
108
124
  */
109
125
  module.exports = function (Sharp) {
110
- // Public instance functions
111
126
  [
112
- background,
127
+ // Public
113
128
  tint,
114
129
  greyscale,
115
130
  grayscale,
116
131
  toColourspace,
117
- toColorspace
132
+ toColorspace,
133
+ // Private
134
+ _setColourOption
118
135
  ].forEach(function (f) {
119
136
  Sharp.prototype[f.name] = f;
120
137
  });
121
138
  // Class attributes
122
139
  Sharp.colourspace = colourspace;
123
140
  Sharp.colorspace = colourspace;
141
+ // Deprecated
142
+ Sharp.prototype.background = deprecate(background, 'background(background) is deprecated, use resize({ background }), extend({ background }) or flatten({ background }) instead');
124
143
  };
@@ -4,42 +4,10 @@ const path = require('path');
4
4
  const util = require('util');
5
5
  const stream = require('stream');
6
6
  const events = require('events');
7
- const semver = require('semver');
8
7
  const is = require('./is');
9
- const platform = require('./platform');
10
- const sharp = require('../build/Release/sharp.node');
11
8
 
12
- // Vendor platform
13
- (function () {
14
- let vendorPlatformId;
15
- try {
16
- vendorPlatformId = require('../vendor/platform.json');
17
- } catch (err) {
18
- return;
19
- }
20
- const currentPlatformId = platform();
21
- /* istanbul ignore if */
22
- if (currentPlatformId !== vendorPlatformId) {
23
- throw new Error(`'${vendorPlatformId}' binaries cannot be used on the '${currentPlatformId}' platform. Please remove the 'node_modules/sharp/vendor' directory and run 'npm rebuild'.`);
24
- }
25
- })();
26
-
27
- // Versioning
28
- let versions = {
29
- vips: sharp.libvipsVersion()
30
- };
31
- (function () {
32
- // Does libvips meet minimum requirement?
33
- const libvipsVersionMin = require('../package.json').config.libvips;
34
- /* istanbul ignore if */
35
- if (semver.lt(versions.vips, libvipsVersionMin)) {
36
- throw new Error('Found libvips ' + versions.vips + ' but require at least ' + libvipsVersionMin);
37
- }
38
- // Include versions of dependencies, if present
39
- try {
40
- versions = require('../vendor/versions.json');
41
- } catch (err) {}
42
- })();
9
+ require('./libvips').hasVendoredLibvips();
10
+ const sharp = require('../build/Release/sharp.node');
43
11
 
44
12
  // Use NODE_DEBUG=sharp to enable libvips warnings
45
13
  const debuglog = util.debuglog('sharp');
@@ -136,10 +104,12 @@ const Sharp = function (input, options) {
136
104
  width: -1,
137
105
  height: -1,
138
106
  canvas: 'crop',
139
- crop: 0,
140
- embed: 0,
107
+ position: 0,
108
+ resizeBackground: [0, 0, 0, 255],
141
109
  useExifOrientation: false,
142
110
  angle: 0,
111
+ rotationAngle: 0,
112
+ rotationBackground: [0, 0, 0, 255],
143
113
  rotateBeforePreExtract: false,
144
114
  flip: false,
145
115
  flop: false,
@@ -147,14 +117,15 @@ const Sharp = function (input, options) {
147
117
  extendBottom: 0,
148
118
  extendLeft: 0,
149
119
  extendRight: 0,
120
+ extendBackground: [0, 0, 0, 255],
150
121
  withoutEnlargement: false,
151
122
  kernel: 'lanczos3',
152
123
  fastShrinkOnLoad: true,
153
124
  // operations
154
- background: [0, 0, 0, 255],
155
125
  tintA: 128,
156
126
  tintB: 128,
157
127
  flatten: false,
128
+ flattenBackground: [0, 0, 0],
158
129
  negate: false,
159
130
  medianSize: 0,
160
131
  blurSigma: 0,
@@ -163,7 +134,7 @@ const Sharp = function (input, options) {
163
134
  sharpenJagged: 2,
164
135
  threshold: 0,
165
136
  thresholdGrayscale: true,
166
- trimTolerance: 0,
137
+ trimThreshold: 0,
167
138
  gamma: 0,
168
139
  greyscale: false,
169
140
  normalise: 0,
@@ -251,7 +222,12 @@ Sharp.format = sharp.format();
251
222
  * @example
252
223
  * console.log(sharp.versions);
253
224
  */
254
- Sharp.versions = versions;
225
+ Sharp.versions = {
226
+ vips: sharp.libvipsVersion()
227
+ };
228
+ try {
229
+ Sharp.versions = require('../vendor/versions.json');
230
+ } catch (err) {}
255
231
 
256
232
  /**
257
233
  * Export constructor.
package/lib/input.js CHANGED
@@ -177,12 +177,15 @@ function clone () {
177
177
  * A Promises/A+ promise is returned when `callback` is not provided.
178
178
  *
179
179
  * - `format`: Name of decoder used to decompress image data e.g. `jpeg`, `png`, `webp`, `gif`, `svg`
180
+ * - `size`: Total size of image in bytes, for Stream and Buffer input only
180
181
  * - `width`: Number of pixels wide (EXIF orientation is not taken into consideration)
181
182
  * - `height`: Number of pixels high (EXIF orientation is not taken into consideration)
182
- * - `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://github.com/jcupitt/libvips/blob/master/libvips/iofuncs/enumtypes.c#L636)
183
+ * - `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://github.com/libvips/libvips/blob/master/libvips/iofuncs/enumtypes.c#L636)
183
184
  * - `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
184
- * - `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://github.com/jcupitt/libvips/blob/master/libvips/iofuncs/enumtypes.c#L672)
185
+ * - `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://github.com/libvips/libvips/blob/master/libvips/iofuncs/enumtypes.c#L672)
185
186
  * - `density`: Number of pixels per inch (DPI), if present
187
+ * - `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
188
+ * - `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
186
189
  * - `hasProfile`: Boolean indicating the presence of an embedded ICC profile
187
190
  * - `hasAlpha`: Boolean indicating the presence of an alpha transparency channel
188
191
  * - `orientation`: Number value of the EXIF Orientation header, if present
package/lib/libvips.js CHANGED
@@ -44,10 +44,16 @@ const globalLibvipsVersion = function () {
44
44
 
45
45
  const hasVendoredLibvips = function () {
46
46
  const currentPlatformId = platform();
47
+ const vendorPath = path.join(__dirname, '..', 'vendor');
48
+ let vendorVersionId;
47
49
  let vendorPlatformId;
48
50
  try {
49
- vendorPlatformId = require(path.join(__dirname, '..', 'vendor', 'platform.json'));
51
+ vendorVersionId = require(path.join(vendorPath, 'versions.json')).vips;
52
+ vendorPlatformId = require(path.join(vendorPath, 'platform.json'));
50
53
  } catch (err) {}
54
+ if (vendorVersionId && vendorVersionId !== minimumLibvipsVersion) {
55
+ throw new Error(`Found vendored libvips v${vendorVersionId} but require v${minimumLibvipsVersion}. Please remove the 'node_modules/sharp/vendor' directory and run 'npm install'.`);
56
+ }
51
57
  if (vendorPlatformId) {
52
58
  if (currentPlatformId === vendorPlatformId) {
53
59
  return true;
package/lib/operation.js CHANGED
@@ -1,14 +1,18 @@
1
1
  'use strict';
2
2
 
3
+ const color = require('color');
3
4
  const is = require('./is');
4
5
 
5
6
  /**
6
7
  * Rotate the output image by either an explicit angle
7
8
  * or auto-orient based on the EXIF `Orientation` tag.
8
9
  *
9
- * If an angle is provided, it is converted to a valid 90/180/270deg rotation.
10
+ * If an angle is provided, it is converted to a valid positive degree rotation.
10
11
  * For example, `-450` will produce a 270deg rotation.
11
12
  *
13
+ * When rotating by an angle other than a multiple of 90,
14
+ * the background colour can be provided with the `background` option.
15
+ *
12
16
  * If no angle is provided, it is determined from the EXIF data.
13
17
  * Mirroring is supported and may infer the use of a flip operation.
14
18
  *
@@ -28,64 +32,30 @@ const is = require('./is');
28
32
  * });
29
33
  * readableStream.pipe(pipeline);
30
34
  *
31
- * @param {Number} [angle=auto] angle of rotation, must be a multiple of 90.
35
+ * @param {Number} [angle=auto] angle of rotation.
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.
32
38
  * @returns {Sharp}
33
39
  * @throws {Error} Invalid parameters
34
40
  */
35
- function rotate (angle) {
41
+ function rotate (angle, options) {
36
42
  if (!is.defined(angle)) {
37
43
  this.options.useExifOrientation = true;
38
44
  } else if (is.integer(angle) && !(angle % 90)) {
39
45
  this.options.angle = angle;
40
- } else {
41
- throw new Error('Unsupported angle: angle must be a positive/negative multiple of 90 ' + angle);
42
- }
43
- return this;
44
- }
45
-
46
- /**
47
- * Extract a region of the image.
48
- *
49
- * - Use `extract` before `resize` for pre-resize extraction.
50
- * - Use `extract` after `resize` for post-resize extraction.
51
- * - Use `extract` before and after for both.
52
- *
53
- * @example
54
- * sharp(input)
55
- * .extract({ left: left, top: top, width: width, height: height })
56
- * .toFile(output, function(err) {
57
- * // Extract a region of the input image, saving in the same format.
58
- * });
59
- * @example
60
- * sharp(input)
61
- * .extract({ left: leftOffsetPre, top: topOffsetPre, width: widthPre, height: heightPre })
62
- * .resize(width, height)
63
- * .extract({ left: leftOffsetPost, top: topOffsetPost, width: widthPost, height: heightPost })
64
- * .toFile(output, function(err) {
65
- * // Extract a region, resize, then extract from the resized image
66
- * });
67
- *
68
- * @param {Object} options
69
- * @param {Number} options.left - zero-indexed offset from left edge
70
- * @param {Number} options.top - zero-indexed offset from top edge
71
- * @param {Number} options.width - dimension of extracted image
72
- * @param {Number} options.height - dimension of extracted image
73
- * @returns {Sharp}
74
- * @throws {Error} Invalid parameters
75
- */
76
- function extract (options) {
77
- const suffix = this.options.width === -1 && this.options.height === -1 ? 'Pre' : 'Post';
78
- ['left', 'top', 'width', 'height'].forEach(function (name) {
79
- const value = options[name];
80
- if (is.integer(value) && value >= 0) {
81
- this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value;
82
- } else {
83
- throw new Error('Non-integer value for ' + name + ' of ' + value);
46
+ } else if (is.number(angle)) {
47
+ this.options.rotationAngle = angle;
48
+ if (is.object(options) && options.background) {
49
+ const backgroundColour = color(options.background);
50
+ this.options.rotationBackground = [
51
+ backgroundColour.red(),
52
+ backgroundColour.green(),
53
+ backgroundColour.blue(),
54
+ Math.round(backgroundColour.alpha() * 255)
55
+ ];
84
56
  }
85
- }, this);
86
- // Ensure existing rotation occurs before pre-resize extraction
87
- if (suffix === 'Pre' && ((this.options.angle % 360) !== 0 || this.options.useExifOrientation === true)) {
88
- this.options.rotateBeforePreExtract = true;
57
+ } else {
58
+ throw new Error('Unsupported angle: must be a number.');
89
59
  }
90
60
  return this;
91
61
  }
@@ -201,72 +171,14 @@ function blur (sigma) {
201
171
  }
202
172
 
203
173
  /**
204
- * Extends/pads the edges of the image with the colour provided to the `background` method.
205
- * This operation will always occur after resizing and extraction, if any.
206
- *
207
- * @example
208
- * // Resize to 140 pixels wide, then add 10 transparent pixels
209
- * // to the top, left and right edges and 20 to the bottom edge
210
- * sharp(input)
211
- * .resize(140)
212
- * .background({r: 0, g: 0, b: 0, alpha: 0})
213
- * .extend({top: 10, bottom: 20, left: 10, right: 10})
214
- * ...
215
- *
216
- * @param {(Number|Object)} extend - single pixel count to add to all edges or an Object with per-edge counts
217
- * @param {Number} [extend.top]
218
- * @param {Number} [extend.left]
219
- * @param {Number} [extend.bottom]
220
- * @param {Number} [extend.right]
221
- * @returns {Sharp}
222
- * @throws {Error} Invalid parameters
223
- */
224
- function extend (extend) {
225
- if (is.integer(extend) && extend > 0) {
226
- this.options.extendTop = extend;
227
- this.options.extendBottom = extend;
228
- this.options.extendLeft = extend;
229
- this.options.extendRight = extend;
230
- } else if (
231
- is.object(extend) &&
232
- is.integer(extend.top) && extend.top >= 0 &&
233
- is.integer(extend.bottom) && extend.bottom >= 0 &&
234
- is.integer(extend.left) && extend.left >= 0 &&
235
- is.integer(extend.right) && extend.right >= 0
236
- ) {
237
- this.options.extendTop = extend.top;
238
- this.options.extendBottom = extend.bottom;
239
- this.options.extendLeft = extend.left;
240
- this.options.extendRight = extend.right;
241
- } else {
242
- throw new Error('Invalid edge extension ' + extend);
243
- }
244
- return this;
245
- }
246
-
247
- /**
248
- * Merge alpha transparency channel, if any, with `background`.
249
- * @param {Boolean} [flatten=true]
250
- * @returns {Sharp}
251
- */
252
- function flatten (flatten) {
253
- this.options.flatten = is.bool(flatten) ? flatten : true;
254
- return this;
255
- }
256
-
257
- /**
258
- * Trim "boring" pixels from all edges that contain values within a percentage similarity of the top-left pixel.
259
- * @param {Number} [tolerance=10] value between 1 and 99 representing the percentage similarity.
174
+ * Merge alpha transparency channel, if any, with a background.
175
+ * @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.
260
176
  * @returns {Sharp}
261
- * @throws {Error} Invalid parameters
262
177
  */
263
- function trim (tolerance) {
264
- if (!is.defined(tolerance)) {
265
- this.options.trimTolerance = 10;
266
- } else if (is.integer(tolerance) && is.inRange(tolerance, 1, 99)) {
267
- this.options.trimTolerance = tolerance;
268
- } else {
269
- throw new Error('Invalid trim tolerance (1 to 99) ' + tolerance);
178
+ function flatten (options) {
179
+ this.options.flatten = is.bool(options) ? options : true;
180
+ if (is.object(options)) {
181
+ this._setColourOption('flattenBackground', options.background);
270
182
  }
271
183
  return this;
272
184
  }
@@ -460,15 +372,12 @@ function linear (a, b) {
460
372
  module.exports = function (Sharp) {
461
373
  [
462
374
  rotate,
463
- extract,
464
375
  flip,
465
376
  flop,
466
377
  sharpen,
467
378
  median,
468
379
  blur,
469
- extend,
470
380
  flatten,
471
- trim,
472
381
  gamma,
473
382
  negate,
474
383
  normalise,
package/lib/platform.js CHANGED
@@ -1,10 +1,13 @@
1
1
  'use strict';
2
2
 
3
+ const detectLibc = require('detect-libc');
4
+
3
5
  module.exports = function () {
4
6
  const arch = process.env.npm_config_arch || process.arch;
5
7
  const platform = process.env.npm_config_platform || process.platform;
8
+ const libc = (platform === 'linux' && detectLibc.isNonGlibcLinux) ? detectLibc.family : '';
6
9
 
7
- const platformId = [platform];
10
+ const platformId = [`${platform}${libc}`];
8
11
  if (arch === 'arm' || arch === 'armhf' || arch === 'arm64') {
9
12
  const armVersion = (arch === 'arm64') ? '8' : process.env.npm_config_armv || process.config.variables.arm_version || '6';
10
13
  platformId.push(`armv${armVersion}`);