sharp 0.25.4 → 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/README.md CHANGED
@@ -16,7 +16,7 @@ Lanczos resampling ensures quality is not sacrificed for speed.
16
16
  As well as image resizing, operations such as
17
17
  rotation, extraction, compositing and gamma correction are available.
18
18
 
19
- Most modern macOS, Windows and Linux systems running Node.js v10+
19
+ Most modern macOS, Windows and Linux systems running Node.js v10.16.0+
20
20
  do not require any additional install or runtime dependencies.
21
21
 
22
22
  ## Examples
package/binding.gyp CHANGED
@@ -1,4 +1,8 @@
1
1
  {
2
+ 'variables': {
3
+ 'vips_version': '<!(node -p "require(\'./lib/libvips\').minimumLibvipsVersion")',
4
+ 'sharp_vendor_dir': '<(module_root_dir)/vendor/<(vips_version)'
5
+ },
2
6
  'targets': [{
3
7
  'target_name': 'libvips-cpp',
4
8
  'conditions': [
@@ -16,15 +20,18 @@
16
20
  'src/libvips/cplusplus/VImage.cpp'
17
21
  ],
18
22
  'include_dirs': [
19
- 'vendor/include',
20
- 'vendor/include/glib-2.0',
21
- 'vendor/lib/glib-2.0/include'
22
- ],
23
- 'libraries': [
24
- '../vendor/lib/libvips.lib',
25
- '../vendor/lib/libglib-2.0.lib',
26
- '../vendor/lib/libgobject-2.0.lib'
23
+ '<(sharp_vendor_dir)/include',
24
+ '<(sharp_vendor_dir)/include/glib-2.0',
25
+ '<(sharp_vendor_dir)/lib/glib-2.0/include'
27
26
  ],
27
+ 'link_settings': {
28
+ 'library_dirs': ['<(sharp_vendor_dir)/lib'],
29
+ 'libraries': [
30
+ 'libvips.lib',
31
+ 'libglib-2.0.lib',
32
+ 'libgobject-2.0.lib'
33
+ ],
34
+ },
28
35
  'configurations': {
29
36
  'Release': {
30
37
  'msvs_settings': {
@@ -70,8 +77,8 @@
70
77
  'runtime_link%': 'shared',
71
78
  'conditions': [
72
79
  ['OS != "win"', {
73
- 'pkg_config_path': '<!(node -e "console.log(require(\'./lib/libvips\').pkgConfigPath())")',
74
- 'use_global_libvips': '<!(node -e "console.log(Boolean(require(\'./lib/libvips\').useGlobalLibvips()).toString())")'
80
+ 'pkg_config_path': '<!(node -p "require(\'./lib/libvips\').pkgConfigPath()")',
81
+ 'use_global_libvips': '<!(node -p "Boolean(require(\'./lib/libvips\').useGlobalLibvips()).toString()")'
75
82
  }, {
76
83
  'pkg_config_path': '',
77
84
  'use_global_libvips': ''
@@ -110,9 +117,9 @@
110
117
  }, {
111
118
  # Use pre-built libvips stored locally within node_modules
112
119
  'include_dirs': [
113
- 'vendor/include',
114
- 'vendor/include/glib-2.0',
115
- 'vendor/lib/glib-2.0/include'
120
+ '<(sharp_vendor_dir)/include',
121
+ '<(sharp_vendor_dir)/include/glib-2.0',
122
+ '<(sharp_vendor_dir)/lib/glib-2.0/include'
116
123
  ],
117
124
  'conditions': [
118
125
  ['OS == "win"', {
@@ -120,64 +127,45 @@
120
127
  '_ALLOW_KEYWORD_MACROS',
121
128
  '_FILE_OFFSET_BITS=64'
122
129
  ],
123
- 'libraries': [
124
- '../vendor/lib/libvips.lib',
125
- '../vendor/lib/libglib-2.0.lib',
126
- '../vendor/lib/libgobject-2.0.lib'
127
- ]
130
+ 'link_settings': {
131
+ 'library_dirs': ['<(sharp_vendor_dir)/lib'],
132
+ 'libraries': [
133
+ 'libvips.lib',
134
+ 'libglib-2.0.lib',
135
+ 'libgobject-2.0.lib'
136
+ ]
137
+ }
128
138
  }],
129
139
  ['OS == "mac"', {
130
- 'libraries': [
131
- '../vendor/lib/libvips-cpp.42.dylib',
132
- '../vendor/lib/libvips.42.dylib',
133
- '../vendor/lib/libglib-2.0.0.dylib',
134
- '../vendor/lib/libgobject-2.0.0.dylib',
135
- # Ensure runtime linking is relative to sharp.node
136
- '-Wl,-s -rpath \'@loader_path/../../vendor/lib\''
137
- ]
140
+ 'link_settings': {
141
+ 'library_dirs': ['<(sharp_vendor_dir)/lib'],
142
+ 'libraries': [
143
+ 'libvips-cpp.42.dylib',
144
+ 'libvips.42.dylib'
145
+ ]
146
+ },
147
+ 'xcode_settings': {
148
+ 'OTHER_LDFLAGS': [
149
+ # Ensure runtime linking is relative to sharp.node
150
+ '-Wl,-rpath,\'@loader_path/../../vendor/<(vips_version)/lib\''
151
+ ]
152
+ }
138
153
  }],
139
154
  ['OS == "linux"', {
140
155
  'defines': [
141
156
  '_GLIBCXX_USE_CXX11_ABI=0'
142
157
  ],
143
- 'libraries': [
144
- '../vendor/lib/libvips-cpp.so',
145
- '../vendor/lib/libvips.so',
146
- '../vendor/lib/libglib-2.0.so',
147
- '../vendor/lib/libgobject-2.0.so',
148
- # Dependencies of dependencies, included for openSUSE support
149
- '../vendor/lib/libcairo.so',
150
- '../vendor/lib/libexif.so',
151
- '../vendor/lib/libexpat.so',
152
- '../vendor/lib/libffi.so',
153
- '../vendor/lib/libfontconfig.so',
154
- '../vendor/lib/libfreetype.so',
155
- '../vendor/lib/libfribidi.so',
156
- '../vendor/lib/libgdk_pixbuf-2.0.so',
157
- '../vendor/lib/libgif.so',
158
- '../vendor/lib/libgio-2.0.so',
159
- '../vendor/lib/libgmodule-2.0.so',
160
- '../vendor/lib/libgsf-1.so',
161
- '../vendor/lib/libgthread-2.0.so',
162
- '../vendor/lib/libharfbuzz.so',
163
- '../vendor/lib/libjpeg.so',
164
- '../vendor/lib/liblcms2.so',
165
- '../vendor/lib/liborc-0.4.so',
166
- '../vendor/lib/libpango-1.0.so',
167
- '../vendor/lib/libpangocairo-1.0.so',
168
- '../vendor/lib/libpangoft2-1.0.so',
169
- '../vendor/lib/libpixman-1.so',
170
- '../vendor/lib/libpng.so',
171
- '../vendor/lib/librsvg-2.so',
172
- '../vendor/lib/libtiff.so',
173
- '../vendor/lib/libwebp.so',
174
- '../vendor/lib/libwebpdemux.so',
175
- '../vendor/lib/libwebpmux.so',
176
- '../vendor/lib/libxml2.so',
177
- '../vendor/lib/libz.so',
178
- # Ensure runtime linking is relative to sharp.node
179
- '-Wl,-s -Wl,--disable-new-dtags -Wl,-rpath=\'$${ORIGIN}/../../vendor/lib\''
180
- ]
158
+ 'link_settings': {
159
+ 'library_dirs': ['<(sharp_vendor_dir)/lib'],
160
+ 'libraries': [
161
+ '-l:libvips-cpp.so.42',
162
+ '-l:libvips.so.42'
163
+ ],
164
+ 'ldflags': [
165
+ # Ensure runtime linking is relative to sharp.node
166
+ '-Wl,-s -Wl,--disable-new-dtags -Wl,-rpath=\'$$ORIGIN/../../vendor/<(vips_version)/lib\''
167
+ ]
168
+ }
181
169
  }]
182
170
  ]
183
171
  }]
@@ -190,8 +178,7 @@
190
178
  ],
191
179
  'xcode_settings': {
192
180
  'CLANG_CXX_LANGUAGE_STANDARD': 'c++11',
193
- 'CLANG_CXX_LIBRARY': 'libc++',
194
- 'MACOSX_DEPLOYMENT_TARGET': '10.7',
181
+ 'MACOSX_DEPLOYMENT_TARGET': '10.9',
195
182
  'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
196
183
  'GCC_ENABLE_CPP_RTTI': 'YES',
197
184
  'OTHER_CPLUSPLUSFLAGS': [
@@ -6,6 +6,8 @@ const path = require('path');
6
6
  const libvips = require('../lib/libvips');
7
7
  const npmLog = require('npmlog');
8
8
 
9
+ const minimumLibvipsVersion = libvips.minimumLibvipsVersion;
10
+
9
11
  const platform = process.env.npm_config_platform || process.platform;
10
12
  if (platform === 'win32') {
11
13
  const buildDir = path.join(__dirname, '..', 'build');
@@ -15,7 +17,7 @@ if (platform === 'win32') {
15
17
  libvips.mkdirSync(buildDir);
16
18
  libvips.mkdirSync(buildReleaseDir);
17
19
  } catch (err) {}
18
- const vendorLibDir = path.join(__dirname, '..', 'vendor', 'lib');
20
+ const vendorLibDir = path.join(__dirname, '..', 'vendor', minimumLibvipsVersion, 'lib');
19
21
  npmLog.info('sharp', `Copying DLLs from ${vendorLibDir} to ${buildReleaseDir}`);
20
22
  try {
21
23
  fs
@@ -3,12 +3,14 @@
3
3
  const fs = require('fs');
4
4
  const os = require('os');
5
5
  const path = require('path');
6
+ const stream = require('stream');
7
+ const zlib = require('zlib');
6
8
 
7
9
  const detectLibc = require('detect-libc');
8
10
  const npmLog = require('npmlog');
9
11
  const semver = require('semver');
10
12
  const simpleGet = require('simple-get');
11
- const tar = require('tar');
13
+ const tarFs = require('tar-fs');
12
14
 
13
15
  const agent = require('../lib/agent');
14
16
  const libvips = require('../lib/libvips');
@@ -37,18 +39,21 @@ const fail = function (err) {
37
39
  const extractTarball = function (tarPath) {
38
40
  const vendorPath = path.join(__dirname, '..', 'vendor');
39
41
  libvips.mkdirSync(vendorPath);
40
- tar
41
- .extract({
42
- file: tarPath,
43
- cwd: vendorPath,
44
- strict: true
45
- })
46
- .catch(function (err) {
47
- if (/unexpected end of file/.test(err.message)) {
48
- npmLog.error('sharp', `Please delete ${tarPath} as it is not a valid tarball`);
42
+ const versionedVendorPath = path.join(vendorPath, minimumLibvipsVersion);
43
+ libvips.mkdirSync(versionedVendorPath);
44
+ stream.pipeline(
45
+ fs.createReadStream(tarPath),
46
+ new zlib.BrotliDecompress(),
47
+ tarFs.extract(versionedVendorPath),
48
+ function (err) {
49
+ if (err) {
50
+ if (/unexpected end of file/.test(err.message)) {
51
+ npmLog.error('sharp', `Please delete ${tarPath} as it is not a valid tarball`);
52
+ }
53
+ fail(err);
49
54
  }
50
- fail(err);
51
- });
55
+ }
56
+ );
52
57
  };
53
58
 
54
59
  try {
@@ -76,7 +81,7 @@ try {
76
81
  }
77
82
  }
78
83
  // Download to per-process temporary file
79
- const tarFilename = ['libvips', minimumLibvipsVersion, platformAndArch].join('-') + '.tar.gz';
84
+ const tarFilename = ['libvips', minimumLibvipsVersion, platformAndArch].join('-') + '.tar.br';
80
85
  const tarPathCache = path.join(libvips.cachePath(), tarFilename);
81
86
  if (fs.existsSync(tarPathCache)) {
82
87
  npmLog.info('sharp', `Using cached ${tarPathCache}`);
@@ -86,6 +86,10 @@ const debuglog = util.debuglog('sharp');
86
86
  * .toBuffer()
87
87
  * .then( ... );
88
88
  *
89
+ * @example
90
+ * // Convert an animated GIF to an animated WebP
91
+ * await sharp('in.gif', { animated: true }).toFile('out.webp');
92
+ *
89
93
  * @param {(Buffer|string)} [input] - if present, can be
90
94
  * a Buffer containing JPEG, PNG, WebP, GIF, SVG, TIFF or raw pixel image data, or
91
95
  * a String containing the filesystem path to an JPEG, PNG, WebP, GIF, SVG or TIFF image file.
@@ -102,6 +106,7 @@ const debuglog = util.debuglog('sharp');
102
106
  * @param {number} [options.pages=1] - number of pages to extract for multi-page input (GIF, TIFF, PDF), use -1 for all pages.
103
107
  * @param {number} [options.page=0] - page number to start extracting from for multi-page input (GIF, TIFF, PDF), zero based.
104
108
  * @param {number} [options.level=0] - level to extract from a multi-level input (OpenSlide), zero based.
109
+ * @param {boolean} [options.animated=false] - Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`).
105
110
  * @param {Object} [options.raw] - describes raw pixel input image data. See `raw()` for pixel ordering.
106
111
  * @param {number} [options.raw.width]
107
112
  * @param {number} [options.raw.height]
@@ -187,6 +192,7 @@ const Sharp = function (input, options) {
187
192
  streamOut: false,
188
193
  withMetadata: false,
189
194
  withMetadataOrientation: -1,
195
+ withMetadataIcc: '',
190
196
  resolveWithObject: false,
191
197
  // output format
192
198
  jpegQuality: 80,
@@ -214,7 +220,7 @@ const Sharp = function (input, options) {
214
220
  tiffCompression: 'jpeg',
215
221
  tiffPredictor: 'horizontal',
216
222
  tiffPyramid: false,
217
- tiffSquash: false,
223
+ tiffBitdepth: 8,
218
224
  tiffTile: false,
219
225
  tiffTileHeight: 256,
220
226
  tiffTileWidth: 256,
package/lib/input.js CHANGED
@@ -99,6 +99,13 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
99
99
  }
100
100
  }
101
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
+ }
102
109
  if (is.defined(inputOptions.pages)) {
103
110
  if (is.integer(inputOptions.pages) && is.inRange(inputOptions.pages, -1, 100000)) {
104
111
  inputDescriptor.pages = inputOptions.pages;
@@ -300,6 +307,7 @@ function metadata (callback) {
300
307
  * - `isOpaque`: Is the image fully opaque? Will be `true` if the image has no alpha channel or if every pixel is fully opaque.
301
308
  * - `entropy`: Histogram-based estimation of greyscale entropy, discarding alpha channel if any (experimental)
302
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)
303
311
  *
304
312
  * @example
305
313
  * const image = sharp(inputJpg);
@@ -310,7 +318,8 @@ function metadata (callback) {
310
318
  * });
311
319
  *
312
320
  * @example
313
- * const { entropy, sharpness } = await sharp(input).stats();
321
+ * const { entropy, sharpness, dominant } = await sharp(input).stats();
322
+ * const { r, g, b } = dominant;
314
323
  *
315
324
  * @param {Function} [callback] - called with the arguments `(err, stats)`
316
325
  * @returns {Promise<Object>}
package/lib/libvips.js CHANGED
@@ -48,17 +48,11 @@ 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 */
package/lib/output.js CHANGED
@@ -11,7 +11,8 @@ const formats = new Map([
11
11
  ['png', 'png'],
12
12
  ['raw', 'raw'],
13
13
  ['tiff', 'tiff'],
14
- ['webp', 'webp']
14
+ ['webp', 'webp'],
15
+ ['gif', 'gif']
15
16
  ]);
16
17
 
17
18
  /**
@@ -118,7 +119,8 @@ function toBuffer (options, callback) {
118
119
 
119
120
  /**
120
121
  * Include all metadata (EXIF, XMP, IPTC) from the input image in the output image.
121
- * This will also convert to and add a web-friendly sRGB ICC profile.
122
+ * This will also convert to and add a web-friendly sRGB ICC profile unless a custom
123
+ * output profile is provided.
122
124
  *
123
125
  * The default behaviour, when `withMetadata` is not used, is to convert to the device-independent
124
126
  * sRGB colour space and strip all metadata, including the removal of any ICC profile.
@@ -131,6 +133,7 @@ function toBuffer (options, callback) {
131
133
  *
132
134
  * @param {Object} [options]
133
135
  * @param {number} [options.orientation] value between 1 and 8, used to update the EXIF `Orientation` tag.
136
+ * @param {string} [options.icc] filesystem path to output ICC profile, defaults to sRGB.
134
137
  * @returns {Sharp}
135
138
  * @throws {Error} Invalid parameters
136
139
  */
@@ -144,6 +147,13 @@ function withMetadata (options) {
144
147
  throw is.invalidParameterError('orientation', 'integer between 1 and 8', options.orientation);
145
148
  }
146
149
  }
150
+ if (is.defined(options.icc)) {
151
+ if (is.string(options.icc)) {
152
+ this.options.withMetadataIcc = options.icc;
153
+ } else {
154
+ throw is.invalidParameterError('icc', 'string filesystem path to ICC profile', options.icc);
155
+ }
156
+ }
147
157
  }
148
158
  return this;
149
159
  }
@@ -187,7 +197,7 @@ function toFormat (format, options) {
187
197
  * @param {Object} [options] - output options
188
198
  * @param {number} [options.quality=80] - quality, integer 1-100
189
199
  * @param {boolean} [options.progressive=false] - use progressive (interlace) scan
190
- * @param {string} [options.chromaSubsampling='4:2:0'] - for quality < 90, set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' (use chroma subsampling); for quality >= 90 chroma is never subsampled
200
+ * @param {string} [options.chromaSubsampling='4:2:0'] - set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' chroma subsampling
191
201
  * @param {boolean} [options.optimiseCoding=true] - optimise Huffman coding tables
192
202
  * @param {boolean} [options.optimizeCoding=true] - alternative spelling of optimiseCoding
193
203
  * @param {boolean} [options.trellisQuantisation=false] - apply trellis quantisation, requires libvips compiled with support for mozjpeg
@@ -340,6 +350,9 @@ function png (options) {
340
350
  * @param {boolean} [options.nearLossless=false] - use near_lossless compression mode
341
351
  * @param {boolean} [options.smartSubsample=false] - use high quality chroma subsampling
342
352
  * @param {number} [options.reductionEffort=4] - level of CPU effort to reduce file size, integer 0-6
353
+ * @param {number} [options.pageHeight] - page height for animated output
354
+ * @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation
355
+ * @param {number[]} [options.delay] - list of delays between animation frames (in milliseconds)
343
356
  * @param {boolean} [options.force=true] - force WebP output, otherwise attempt to use input format
344
357
  * @returns {Sharp}
345
358
  * @throws {Error} Invalid options
@@ -375,9 +388,73 @@ function webp (options) {
375
388
  throw is.invalidParameterError('reductionEffort', 'integer between 0 and 6', options.reductionEffort);
376
389
  }
377
390
  }
391
+
392
+ trySetAnimationOptions(options, this.options);
378
393
  return this._updateFormatOut('webp', options);
379
394
  }
380
395
 
396
+ /**
397
+ * Use these GIF options for output image.
398
+ *
399
+ * Requires libvips compiled with support for ImageMagick or GraphicsMagick.
400
+ * The prebuilt binaries do not include this - see
401
+ * {@link https://sharp.pixelplumbing.com/install#custom-libvips installing a custom libvips}.
402
+ *
403
+ * @param {Object} [options] - output options
404
+ * @param {number} [options.pageHeight] - page height for animated output
405
+ * @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation
406
+ * @param {number[]} [options.delay] - list of delays between animation frames (in milliseconds)
407
+ * @param {boolean} [options.force=true] - force GIF output, otherwise attempt to use input format
408
+ * @returns {Sharp}
409
+ * @throws {Error} Invalid options
410
+ */
411
+ /* istanbul ignore next */
412
+ function gif (options) {
413
+ if (!this.constructor.format.magick.output.buffer) {
414
+ throw new Error('The gif operation requires libvips to have been installed with support for ImageMagick');
415
+ }
416
+ trySetAnimationOptions(options, this.options);
417
+ return this._updateFormatOut('gif', options);
418
+ }
419
+
420
+ /**
421
+ * Set animation options if available.
422
+ * @private
423
+ *
424
+ * @param {Object} [source] - output options
425
+ * @param {number} [source.pageHeight] - page height for animated output
426
+ * @param {number} [source.loop=0] - number of animation iterations, use 0 for infinite animation
427
+ * @param {number[]} [source.delay] - list of delays between animation frames (in milliseconds)
428
+ * @param {Object} [target] - target object for valid options
429
+ * @throws {Error} Invalid options
430
+ */
431
+ function trySetAnimationOptions (source, target) {
432
+ if (is.object(source) && is.defined(source.pageHeight)) {
433
+ if (is.integer(source.pageHeight) && source.pageHeight > 0) {
434
+ target.pageHeight = source.pageHeight;
435
+ } else {
436
+ throw is.invalidParameterError('pageHeight', 'integer larger than 0', source.pageHeight);
437
+ }
438
+ }
439
+ if (is.object(source) && is.defined(source.loop)) {
440
+ if (is.integer(source.loop) && is.inRange(source.loop, 0, 65535)) {
441
+ target.loop = source.loop;
442
+ } else {
443
+ throw is.invalidParameterError('loop', 'integer between 0 and 65535', source.loop);
444
+ }
445
+ }
446
+ if (is.object(source) && is.defined(source.delay)) {
447
+ if (
448
+ Array.isArray(source.delay) &&
449
+ source.delay.every(is.integer) &&
450
+ source.delay.every(v => is.inRange(v, 0, 65535))) {
451
+ target.delay = source.delay;
452
+ } else {
453
+ throw is.invalidParameterError('delay', 'array of integers between 0 and 65535', source.delay);
454
+ }
455
+ }
456
+ }
457
+
381
458
  /**
382
459
  * Use these TIFF options for output image.
383
460
  *
@@ -386,7 +463,7 @@ function webp (options) {
386
463
  * sharp('input.svg')
387
464
  * .tiff({
388
465
  * compression: 'lzw',
389
- * squash: true
466
+ * bitdepth: 1
390
467
  * })
391
468
  * .toFile('1-bpp-output.tiff')
392
469
  * .then(info => { ... });
@@ -402,7 +479,7 @@ function webp (options) {
402
479
  * @param {boolean} [options.tileHeight=256] - vertical tile size
403
480
  * @param {number} [options.xres=1.0] - horizontal resolution in pixels/mm
404
481
  * @param {number} [options.yres=1.0] - vertical resolution in pixels/mm
405
- * @param {boolean} [options.squash=false] - squash 8-bit images down to 1 bit
482
+ * @param {boolean} [options.bitdepth=8] - reduce bitdepth to 1, 2 or 4 bit
406
483
  * @returns {Sharp}
407
484
  * @throws {Error} Invalid options
408
485
  */
@@ -415,8 +492,12 @@ function tiff (options) {
415
492
  throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality);
416
493
  }
417
494
  }
418
- if (is.defined(options.squash)) {
419
- this._setBooleanOption('tiffSquash', options.squash);
495
+ if (is.defined(options.bitdepth)) {
496
+ if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [1, 2, 4, 8])) {
497
+ this.options.tiffBitdepth = options.bitdepth;
498
+ } else {
499
+ throw is.invalidParameterError('bitdepth', '1, 2, 4 or 8', options.bitdepth);
500
+ }
420
501
  }
421
502
  // tiling
422
503
  if (is.defined(options.tile)) {
@@ -804,6 +885,7 @@ module.exports = function (Sharp) {
804
885
  webp,
805
886
  tiff,
806
887
  heif,
888
+ gif,
807
889
  raw,
808
890
  tile,
809
891
  // Private
package/lib/platform.js CHANGED
@@ -13,7 +13,8 @@ module.exports = function () {
13
13
  const platformId = [`${platform}${libc}`];
14
14
 
15
15
  if (arch === 'arm') {
16
- platformId.push(`armv${env.npm_config_arm_version || process.config.variables.arm_version || '6'}`);
16
+ const fallback = process.versions.electron ? '7' : '6';
17
+ platformId.push(`armv${env.npm_config_arm_version || process.config.variables.arm_version || fallback}`);
17
18
  } else if (arch === 'arm64') {
18
19
  platformId.push(`arm64v${env.npm_config_arm_version || '8'}`);
19
20
  } else {
package/lib/utility.js CHANGED
@@ -23,7 +23,7 @@ let versions = {
23
23
  vips: sharp.libvipsVersion()
24
24
  };
25
25
  try {
26
- versions = require('../vendor/versions.json');
26
+ versions = require(`../vendor/${versions.vips}/versions.json`);
27
27
  } catch (err) {}
28
28
 
29
29
  /**
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 and TIFF images",
4
- "version": "0.25.4",
4
+ "version": "0.26.0",
5
5
  "author": "Lovell Fuller <npm@lovell.info>",
6
6
  "homepage": "https://github.com/lovell/sharp",
7
7
  "contributors": [
@@ -67,12 +67,14 @@
67
67
  "Brendan Kennedy <brenwken@gmail.com>",
68
68
  "Brychan Bennett-Odlum <git@brychan.io>",
69
69
  "Edward Silverton <e.silverton@gmail.com>",
70
- "Roman Malieiev <aromaleev@gmail.com>"
70
+ "Roman Malieiev <aromaleev@gmail.com>",
71
+ "Tomas Szabo <tomas.szabo@deftomat.com>",
72
+ "Robert O'Rourke <robert@o-rourke.org>"
71
73
  ],
72
74
  "scripts": {
73
- "install": "(node install/libvips && node install/dll-copy && prebuild-install --runtime=napi) || (node-gyp rebuild && node install/dll-copy)",
75
+ "install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)",
74
76
  "clean": "rm -rf node_modules/ build/ vendor/ .nyc_output/ coverage/ test/fixtures/output.*",
75
- "test": "semistandard && cpplint && npm run test-unit && npm run test-licensing && prebuild-ci",
77
+ "test": "semistandard && cpplint && npm run test-unit && npm run test-licensing && node install/prebuild-ci",
76
78
  "test-unit": "nyc --reporter=lcov --branches=99 mocha --slow=5000 --timeout=60000 ./test/unit/*.js",
77
79
  "test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;MIT\"",
78
80
  "test-coverage": "./test/coverage/report.sh",
@@ -85,6 +87,7 @@
85
87
  "files": [
86
88
  "binding.gyp",
87
89
  "install/**",
90
+ "!install/prebuild-ci.js",
88
91
  "lib/**",
89
92
  "src/**"
90
93
  ],
@@ -113,34 +116,35 @@
113
116
  "detect-libc": "^1.0.3",
114
117
  "node-addon-api": "^3.0.0",
115
118
  "npmlog": "^4.1.2",
116
- "prebuild-install": "^5.3.4",
119
+ "prebuild-install": "^5.3.5",
117
120
  "semver": "^7.3.2",
118
121
  "simple-get": "^4.0.0",
119
- "tar": "^6.0.2",
122
+ "tar-fs": "^2.1.0",
120
123
  "tunnel-agent": "^0.6.0"
121
124
  },
122
125
  "devDependencies": {
123
126
  "async": "^3.2.0",
124
127
  "cc": "^2.0.1",
125
128
  "decompress-zip": "^0.3.2",
126
- "documentation": "^13.0.1",
129
+ "documentation": "^13.0.2",
127
130
  "exif-reader": "^1.0.3",
128
- "icc": "^1.0.0",
131
+ "icc": "^2.0.0",
129
132
  "license-checker": "^25.0.1",
130
- "mocha": "^8.0.1",
131
- "mock-fs": "^4.12.0",
133
+ "mocha": "^8.1.1",
134
+ "mock-fs": "^4.13.0",
132
135
  "nyc": "^15.1.0",
133
- "prebuild": "^10.0.0",
134
- "prebuild-ci": "^3.1.0",
136
+ "prebuild": "^10.0.1",
135
137
  "rimraf": "^3.0.2",
136
- "semistandard": "^14.2.0"
138
+ "semistandard": "^14.2.3"
137
139
  },
138
140
  "license": "Apache-2.0",
139
141
  "config": {
140
- "libvips": "8.9.1"
142
+ "libvips": "8.10.0",
143
+ "runtime": "napi",
144
+ "target": 3
141
145
  },
142
146
  "engines": {
143
- "node": ">=10"
147
+ "node": ">=10.16.0"
144
148
  },
145
149
  "funding": {
146
150
  "url": "https://opencollective.com/libvips"