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 +1 -1
- package/binding.gyp +53 -66
- package/install/dll-copy.js +3 -1
- package/install/libvips.js +18 -13
- package/lib/constructor.js +7 -1
- package/lib/input.js +10 -1
- package/lib/libvips.js +1 -7
- package/lib/output.js +89 -7
- package/lib/platform.js +2 -1
- package/lib/utility.js +1 -1
- package/package.json +19 -15
- package/src/common.cc +113 -50
- package/src/common.h +21 -2
- package/src/libvips/cplusplus/VImage.cpp +451 -450
- package/src/libvips/cplusplus/vips-operators.cpp +117 -1
- package/src/metadata.cc +1 -1
- package/src/operations.cc +0 -23
- package/src/operations.h +0 -10
- package/src/pipeline.cc +70 -11
- package/src/pipeline.h +9 -2
- package/src/stats.cc +17 -0
- package/src/stats.h +7 -1
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
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
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 -
|
|
74
|
-
'use_global_libvips': '<!(node -
|
|
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
|
-
'
|
|
114
|
-
'
|
|
115
|
-
'
|
|
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
|
-
'
|
|
124
|
-
'
|
|
125
|
-
'
|
|
126
|
-
|
|
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
|
-
'
|
|
131
|
-
'
|
|
132
|
-
'
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
'
|
|
144
|
-
'
|
|
145
|
-
'
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
'
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
'
|
|
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': [
|
package/install/dll-copy.js
CHANGED
|
@@ -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
|
package/install/libvips.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
|
|
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
|
-
|
|
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.
|
|
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}`);
|
package/lib/constructor.js
CHANGED
|
@@ -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
|
-
|
|
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'] -
|
|
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
|
-
*
|
|
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.
|
|
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.
|
|
419
|
-
|
|
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
|
-
|
|
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
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.
|
|
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
|
|
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.
|
|
119
|
+
"prebuild-install": "^5.3.5",
|
|
117
120
|
"semver": "^7.3.2",
|
|
118
121
|
"simple-get": "^4.0.0",
|
|
119
|
-
"tar": "^
|
|
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.
|
|
129
|
+
"documentation": "^13.0.2",
|
|
127
130
|
"exif-reader": "^1.0.3",
|
|
128
|
-
"icc": "^
|
|
131
|
+
"icc": "^2.0.0",
|
|
129
132
|
"license-checker": "^25.0.1",
|
|
130
|
-
"mocha": "^8.
|
|
131
|
-
"mock-fs": "^4.
|
|
133
|
+
"mocha": "^8.1.1",
|
|
134
|
+
"mock-fs": "^4.13.0",
|
|
132
135
|
"nyc": "^15.1.0",
|
|
133
|
-
"prebuild": "^10.0.
|
|
134
|
-
"prebuild-ci": "^3.1.0",
|
|
136
|
+
"prebuild": "^10.0.1",
|
|
135
137
|
"rimraf": "^3.0.2",
|
|
136
|
-
"semistandard": "^14.2.
|
|
138
|
+
"semistandard": "^14.2.3"
|
|
137
139
|
},
|
|
138
140
|
"license": "Apache-2.0",
|
|
139
141
|
"config": {
|
|
140
|
-
"libvips": "8.
|
|
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"
|