sharp 0.32.5 → 0.33.0-alpha.10
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 +6 -2
- package/install/check.js +36 -0
- package/lib/constructor.js +6 -5
- package/lib/index.d.ts +59 -16
- package/lib/input.js +34 -8
- package/lib/is.js +28 -14
- package/lib/libvips.js +70 -57
- package/lib/operation.js +1 -5
- package/lib/output.js +44 -26
- package/lib/resize.js +46 -46
- package/lib/sharp.js +58 -27
- package/lib/utility.js +19 -25
- package/package.json +46 -41
- package/{binding.gyp → src/binding.gyp} +68 -42
- package/src/common.cc +5 -4
- package/src/common.h +6 -5
- package/src/metadata.cc +5 -5
- package/src/operations.cc +5 -2
- package/src/operations.h +1 -1
- package/src/pipeline.cc +23 -21
- package/src/pipeline.h +5 -1
- package/src/sharp.cc +6 -7
- package/src/stats.cc +5 -5
- package/src/utilities.cc +15 -5
- package/install/can-compile.js +0 -14
- package/install/dll-copy.js +0 -40
- package/install/libvips.js +0 -222
- package/lib/agent.js +0 -44
- package/lib/platform.js +0 -30
- package/src/libvips/cplusplus/VConnection.cpp +0 -151
- package/src/libvips/cplusplus/VError.cpp +0 -49
- package/src/libvips/cplusplus/VImage.cpp +0 -1548
- package/src/libvips/cplusplus/VInterpolate.cpp +0 -62
- package/src/libvips/cplusplus/VRegion.cpp +0 -27
- package/src/libvips/cplusplus/vips-operators.cpp +0 -3760
package/README.md
CHANGED
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
|
|
4
4
|
|
|
5
|
-
The typical use case for this high speed Node
|
|
5
|
+
The typical use case for this high speed Node-API module
|
|
6
6
|
is to convert large images in common formats to
|
|
7
7
|
smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions.
|
|
8
8
|
|
|
9
|
+
It can be used with all JavaScript runtimes
|
|
10
|
+
that provide support for Node-API v9, including
|
|
11
|
+
Node.js >= 18.17.0, Deno and Bun.
|
|
12
|
+
|
|
9
13
|
Resizing an image is typically 4x-5x faster than using the
|
|
10
14
|
quickest ImageMagick and GraphicsMagick settings
|
|
11
15
|
due to its use of [libvips](https://github.com/libvips/libvips).
|
|
@@ -16,7 +20,7 @@ Lanczos resampling ensures quality is not sacrificed for speed.
|
|
|
16
20
|
As well as image resizing, operations such as
|
|
17
21
|
rotation, extraction, compositing and gamma correction are available.
|
|
18
22
|
|
|
19
|
-
Most modern macOS, Windows and Linux systems
|
|
23
|
+
Most modern macOS, Windows and Linux systems
|
|
20
24
|
do not require any additional install or runtime dependencies.
|
|
21
25
|
|
|
22
26
|
## Documentation
|
package/install/check.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
'use strict';
|
|
5
|
+
|
|
6
|
+
const { useGlobalLibvips, globalLibvipsVersion, log, spawnRebuild } = require('../lib/libvips');
|
|
7
|
+
|
|
8
|
+
const buildFromSource = (msg) => {
|
|
9
|
+
log(msg);
|
|
10
|
+
log('Attempting to build from source via node-gyp');
|
|
11
|
+
try {
|
|
12
|
+
require('node-addon-api');
|
|
13
|
+
log('Found node-addon-api');
|
|
14
|
+
} catch (err) {
|
|
15
|
+
log('Please add node-addon-api to your dependencies');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const gyp = require('node-gyp');
|
|
20
|
+
log(`Found node-gyp version ${gyp().version}`);
|
|
21
|
+
} catch (err) {
|
|
22
|
+
log('Please add node-gyp to your dependencies');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
log('See https://sharp.pixelplumbing.com/install#building-from-source');
|
|
26
|
+
const status = spawnRebuild();
|
|
27
|
+
if (status !== 0) {
|
|
28
|
+
process.exit(status);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
if (useGlobalLibvips()) {
|
|
33
|
+
buildFromSource(`Detected globally-installed libvips v${globalLibvipsVersion()}`);
|
|
34
|
+
} else if (process.env.npm_config_build_from_source) {
|
|
35
|
+
buildFromSource('Detected --build-from-source flag');
|
|
36
|
+
}
|
package/lib/constructor.js
CHANGED
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
const util = require('util');
|
|
7
|
-
const stream = require('stream');
|
|
6
|
+
const util = require('node:util');
|
|
7
|
+
const stream = require('node:stream');
|
|
8
8
|
const is = require('./is');
|
|
9
9
|
|
|
10
|
-
require('./libvips').hasVendoredLibvips();
|
|
11
10
|
require('./sharp');
|
|
12
11
|
|
|
13
12
|
// Use NODE_DEBUG=sharp to enable libvips warnings
|
|
@@ -122,7 +121,7 @@ const debuglog = util.debuglog('sharp');
|
|
|
122
121
|
* a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file.
|
|
123
122
|
* JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
|
|
124
123
|
* @param {Object} [options] - if present, is an Object with optional attributes.
|
|
125
|
-
* @param {string} [options.failOn='warning'] -
|
|
124
|
+
* @param {string} [options.failOn='warning'] - When to abort processing of invalid pixel data, one of (in order of sensitivity, least to most): 'none', 'truncated', 'error', 'warning'. Higher levels imply lower levels. Invalid metadata will always abort.
|
|
126
125
|
* @param {number|boolean} [options.limitInputPixels=268402689] - Do not process input images where the number of pixels
|
|
127
126
|
* (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted.
|
|
128
127
|
* An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF).
|
|
@@ -231,7 +230,8 @@ const Sharp = function (input, options) {
|
|
|
231
230
|
threshold: 0,
|
|
232
231
|
thresholdGrayscale: true,
|
|
233
232
|
trimBackground: [],
|
|
234
|
-
trimThreshold:
|
|
233
|
+
trimThreshold: -1,
|
|
234
|
+
trimLineArt: false,
|
|
235
235
|
gamma: 0,
|
|
236
236
|
gammaOut: 0,
|
|
237
237
|
greyscale: false,
|
|
@@ -306,6 +306,7 @@ const Sharp = function (input, options) {
|
|
|
306
306
|
tiffCompression: 'jpeg',
|
|
307
307
|
tiffPredictor: 'horizontal',
|
|
308
308
|
tiffPyramid: false,
|
|
309
|
+
tiffMiniswhite: false,
|
|
309
310
|
tiffBitdepth: 8,
|
|
310
311
|
tiffTile: false,
|
|
311
312
|
tiffTileHeight: 256,
|
package/lib/index.d.ts
CHANGED
|
@@ -91,12 +91,6 @@ declare namespace sharp {
|
|
|
91
91
|
zlib?: string | undefined;
|
|
92
92
|
};
|
|
93
93
|
|
|
94
|
-
/** An Object containing the platform and architecture of the current and installed vendored binaries. */
|
|
95
|
-
const vendor: {
|
|
96
|
-
current: string;
|
|
97
|
-
installed: string[];
|
|
98
|
-
};
|
|
99
|
-
|
|
100
94
|
/** An Object containing the available interpolators and their proper values */
|
|
101
95
|
const interpolators: Interpolators;
|
|
102
96
|
|
|
@@ -139,6 +133,52 @@ declare namespace sharp {
|
|
|
139
133
|
*/
|
|
140
134
|
function simd(enable?: boolean): boolean;
|
|
141
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Block libvips operations at runtime.
|
|
138
|
+
*
|
|
139
|
+
* This is in addition to the `VIPS_BLOCK_UNTRUSTED` environment variable,
|
|
140
|
+
* which when set will block all "untrusted" operations.
|
|
141
|
+
*
|
|
142
|
+
* @since 0.32.4
|
|
143
|
+
*
|
|
144
|
+
* @example <caption>Block all TIFF input.</caption>
|
|
145
|
+
* sharp.block({
|
|
146
|
+
* operation: ['VipsForeignLoadTiff']
|
|
147
|
+
* });
|
|
148
|
+
*
|
|
149
|
+
* @param {Object} options
|
|
150
|
+
* @param {Array<string>} options.operation - List of libvips low-level operation names to block.
|
|
151
|
+
*/
|
|
152
|
+
function block(options: { operation: string[] }): void;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Unblock libvips operations at runtime.
|
|
156
|
+
*
|
|
157
|
+
* This is useful for defining a list of allowed operations.
|
|
158
|
+
*
|
|
159
|
+
* @since 0.32.4
|
|
160
|
+
*
|
|
161
|
+
* @example <caption>Block all input except WebP from the filesystem.</caption>
|
|
162
|
+
* sharp.block({
|
|
163
|
+
* operation: ['VipsForeignLoad']
|
|
164
|
+
* });
|
|
165
|
+
* sharp.unblock({
|
|
166
|
+
* operation: ['VipsForeignLoadWebpFile']
|
|
167
|
+
* });
|
|
168
|
+
*
|
|
169
|
+
* @example <caption>Block all input except JPEG and PNG from a Buffer or Stream.</caption>
|
|
170
|
+
* sharp.block({
|
|
171
|
+
* operation: ['VipsForeignLoad']
|
|
172
|
+
* });
|
|
173
|
+
* sharp.unblock({
|
|
174
|
+
* operation: ['VipsForeignLoadJpegBuffer', 'VipsForeignLoadPngBuffer']
|
|
175
|
+
* });
|
|
176
|
+
*
|
|
177
|
+
* @param {Object} options
|
|
178
|
+
* @param {Array<string>} options.operation - List of libvips low-level operation names to unblock.
|
|
179
|
+
*/
|
|
180
|
+
function unblock(options: { operation: string[] }): void;
|
|
181
|
+
|
|
142
182
|
//#endregion
|
|
143
183
|
|
|
144
184
|
const gravity: GravityEnum;
|
|
@@ -600,7 +640,7 @@ declare namespace sharp {
|
|
|
600
640
|
* @param withMetadata
|
|
601
641
|
* @throws {Error} Invalid parameters.
|
|
602
642
|
*/
|
|
603
|
-
withMetadata(withMetadata?: WriteableMetadata): Sharp;
|
|
643
|
+
withMetadata(withMetadata?: boolean | WriteableMetadata): Sharp;
|
|
604
644
|
|
|
605
645
|
/**
|
|
606
646
|
* Use these JPEG options for output image.
|
|
@@ -659,7 +699,6 @@ declare namespace sharp {
|
|
|
659
699
|
|
|
660
700
|
/**
|
|
661
701
|
* Use these AVIF options for output image.
|
|
662
|
-
* Whilst it is possible to create AVIF images smaller than 16x16 pixels, most web browsers do not display these properly.
|
|
663
702
|
* @param options Output options.
|
|
664
703
|
* @throws {Error} Invalid options
|
|
665
704
|
* @returns A sharp instance that can be used to chain operations
|
|
@@ -808,11 +847,11 @@ declare namespace sharp {
|
|
|
808
847
|
* Trim pixels from all edges that contain values similar to the given background colour, which defaults to that of the top-left pixel.
|
|
809
848
|
* Images with an alpha channel will use the combined bounding box of alpha and non-alpha channels.
|
|
810
849
|
* The info response Object will contain trimOffsetLeft and trimOffsetTop properties.
|
|
811
|
-
* @param
|
|
850
|
+
* @param options trim options
|
|
812
851
|
* @throws {Error} Invalid parameters
|
|
813
852
|
* @returns A sharp instance that can be used to chain operations
|
|
814
853
|
*/
|
|
815
|
-
trim(
|
|
854
|
+
trim(options?: TrimOptions): Sharp;
|
|
816
855
|
|
|
817
856
|
//#endregion
|
|
818
857
|
}
|
|
@@ -1195,6 +1234,8 @@ declare namespace sharp {
|
|
|
1195
1234
|
yres?: number | undefined;
|
|
1196
1235
|
/** Reduce bitdepth to 1, 2 or 4 bit (optional, default 8) */
|
|
1197
1236
|
bitdepth?: 1 | 2 | 4 | 8 | undefined;
|
|
1237
|
+
/** Write 1-bit images as miniswhite (optional, default false) */
|
|
1238
|
+
miniswhite?: boolean | undefined;
|
|
1198
1239
|
/** Resolution unit options: inch, cm (optional, default 'inch') */
|
|
1199
1240
|
resolutionUnit?: 'inch' | 'cm' | undefined;
|
|
1200
1241
|
}
|
|
@@ -1236,10 +1277,10 @@ declare namespace sharp {
|
|
|
1236
1277
|
}
|
|
1237
1278
|
|
|
1238
1279
|
interface NormaliseOptions {
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1280
|
+
/** Percentile below which luminance values will be underexposed. */
|
|
1281
|
+
lower?: number | undefined;
|
|
1282
|
+
/** Percentile above which luminance values will be overexposed. */
|
|
1283
|
+
upper?: number | undefined;
|
|
1243
1284
|
}
|
|
1244
1285
|
|
|
1245
1286
|
interface ResizeOptions {
|
|
@@ -1301,10 +1342,12 @@ declare namespace sharp {
|
|
|
1301
1342
|
}
|
|
1302
1343
|
|
|
1303
1344
|
interface TrimOptions {
|
|
1304
|
-
/**
|
|
1345
|
+
/** Background colour, parsed by the color module, defaults to that of the top-left pixel. (optional) */
|
|
1305
1346
|
background?: Color | undefined;
|
|
1306
|
-
/**
|
|
1347
|
+
/** Allowed difference from the above colour, a positive number. (optional, default 10) */
|
|
1307
1348
|
threshold?: number | undefined;
|
|
1349
|
+
/** Does the input more closely resemble line art (e.g. vector) rather than being photographic? (optional, default false) */
|
|
1350
|
+
lineArt?: boolean | undefined;
|
|
1308
1351
|
}
|
|
1309
1352
|
|
|
1310
1353
|
interface RawOptions {
|
package/lib/input.js
CHANGED
|
@@ -483,14 +483,27 @@ function _isStreamInput () {
|
|
|
483
483
|
* @returns {Promise<Object>|Sharp}
|
|
484
484
|
*/
|
|
485
485
|
function metadata (callback) {
|
|
486
|
+
const stack = Error();
|
|
486
487
|
if (is.fn(callback)) {
|
|
487
488
|
if (this._isStreamInput()) {
|
|
488
489
|
this.on('finish', () => {
|
|
489
490
|
this._flattenBufferIn();
|
|
490
|
-
sharp.metadata(this.options,
|
|
491
|
+
sharp.metadata(this.options, (err, metadata) => {
|
|
492
|
+
if (err) {
|
|
493
|
+
callback(is.nativeError(err, stack));
|
|
494
|
+
} else {
|
|
495
|
+
callback(null, metadata);
|
|
496
|
+
}
|
|
497
|
+
});
|
|
491
498
|
});
|
|
492
499
|
} else {
|
|
493
|
-
sharp.metadata(this.options,
|
|
500
|
+
sharp.metadata(this.options, (err, metadata) => {
|
|
501
|
+
if (err) {
|
|
502
|
+
callback(is.nativeError(err, stack));
|
|
503
|
+
} else {
|
|
504
|
+
callback(null, metadata);
|
|
505
|
+
}
|
|
506
|
+
});
|
|
494
507
|
}
|
|
495
508
|
return this;
|
|
496
509
|
} else {
|
|
@@ -500,7 +513,7 @@ function metadata (callback) {
|
|
|
500
513
|
this._flattenBufferIn();
|
|
501
514
|
sharp.metadata(this.options, (err, metadata) => {
|
|
502
515
|
if (err) {
|
|
503
|
-
reject(err);
|
|
516
|
+
reject(is.nativeError(err, stack));
|
|
504
517
|
} else {
|
|
505
518
|
resolve(metadata);
|
|
506
519
|
}
|
|
@@ -516,7 +529,7 @@ function metadata (callback) {
|
|
|
516
529
|
return new Promise((resolve, reject) => {
|
|
517
530
|
sharp.metadata(this.options, (err, metadata) => {
|
|
518
531
|
if (err) {
|
|
519
|
-
reject(err);
|
|
532
|
+
reject(is.nativeError(err, stack));
|
|
520
533
|
} else {
|
|
521
534
|
resolve(metadata);
|
|
522
535
|
}
|
|
@@ -572,14 +585,27 @@ function metadata (callback) {
|
|
|
572
585
|
* @returns {Promise<Object>}
|
|
573
586
|
*/
|
|
574
587
|
function stats (callback) {
|
|
588
|
+
const stack = Error();
|
|
575
589
|
if (is.fn(callback)) {
|
|
576
590
|
if (this._isStreamInput()) {
|
|
577
591
|
this.on('finish', () => {
|
|
578
592
|
this._flattenBufferIn();
|
|
579
|
-
sharp.stats(this.options,
|
|
593
|
+
sharp.stats(this.options, (err, stats) => {
|
|
594
|
+
if (err) {
|
|
595
|
+
callback(is.nativeError(err, stack));
|
|
596
|
+
} else {
|
|
597
|
+
callback(null, stats);
|
|
598
|
+
}
|
|
599
|
+
});
|
|
580
600
|
});
|
|
581
601
|
} else {
|
|
582
|
-
sharp.stats(this.options,
|
|
602
|
+
sharp.stats(this.options, (err, stats) => {
|
|
603
|
+
if (err) {
|
|
604
|
+
callback(is.nativeError(err, stack));
|
|
605
|
+
} else {
|
|
606
|
+
callback(null, stats);
|
|
607
|
+
}
|
|
608
|
+
});
|
|
583
609
|
}
|
|
584
610
|
return this;
|
|
585
611
|
} else {
|
|
@@ -589,7 +615,7 @@ function stats (callback) {
|
|
|
589
615
|
this._flattenBufferIn();
|
|
590
616
|
sharp.stats(this.options, (err, stats) => {
|
|
591
617
|
if (err) {
|
|
592
|
-
reject(err);
|
|
618
|
+
reject(is.nativeError(err, stack));
|
|
593
619
|
} else {
|
|
594
620
|
resolve(stats);
|
|
595
621
|
}
|
|
@@ -600,7 +626,7 @@ function stats (callback) {
|
|
|
600
626
|
return new Promise((resolve, reject) => {
|
|
601
627
|
sharp.stats(this.options, (err, stats) => {
|
|
602
628
|
if (err) {
|
|
603
|
-
reject(err);
|
|
629
|
+
reject(is.nativeError(err, stack));
|
|
604
630
|
} else {
|
|
605
631
|
resolve(stats);
|
|
606
632
|
}
|
package/lib/is.js
CHANGED
|
@@ -137,19 +137,33 @@ const invalidParameterError = function (name, expected, actual) {
|
|
|
137
137
|
);
|
|
138
138
|
};
|
|
139
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Ensures an Error from C++ contains a JS stack.
|
|
142
|
+
*
|
|
143
|
+
* @param {Error} native - Error with message from C++.
|
|
144
|
+
* @param {Error} context - Error with stack from JS.
|
|
145
|
+
* @returns {Error} Error with message and stack.
|
|
146
|
+
* @private
|
|
147
|
+
*/
|
|
148
|
+
const nativeError = function (native, context) {
|
|
149
|
+
context.message = native.message;
|
|
150
|
+
return context;
|
|
151
|
+
};
|
|
152
|
+
|
|
140
153
|
module.exports = {
|
|
141
|
-
defined
|
|
142
|
-
object
|
|
143
|
-
plainObject
|
|
144
|
-
fn
|
|
145
|
-
bool
|
|
146
|
-
buffer
|
|
147
|
-
typedArray
|
|
148
|
-
arrayBuffer
|
|
149
|
-
string
|
|
150
|
-
number
|
|
151
|
-
integer
|
|
152
|
-
inRange
|
|
153
|
-
inArray
|
|
154
|
-
invalidParameterError
|
|
154
|
+
defined,
|
|
155
|
+
object,
|
|
156
|
+
plainObject,
|
|
157
|
+
fn,
|
|
158
|
+
bool,
|
|
159
|
+
buffer,
|
|
160
|
+
typedArray,
|
|
161
|
+
arrayBuffer,
|
|
162
|
+
string,
|
|
163
|
+
number,
|
|
164
|
+
integer,
|
|
165
|
+
inRange,
|
|
166
|
+
inArray,
|
|
167
|
+
invalidParameterError,
|
|
168
|
+
nativeError
|
|
155
169
|
};
|
package/lib/libvips.js
CHANGED
|
@@ -3,61 +3,74 @@
|
|
|
3
3
|
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
const os = require('os');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const spawnSync = require('child_process').spawnSync;
|
|
6
|
+
const { spawnSync } = require('node:child_process');
|
|
10
7
|
const semverCoerce = require('semver/functions/coerce');
|
|
11
8
|
const semverGreaterThanOrEqualTo = require('semver/functions/gte');
|
|
9
|
+
const detectLibc = require('detect-libc');
|
|
12
10
|
|
|
13
|
-
const
|
|
14
|
-
const { config } = require('../package.json');
|
|
11
|
+
const { engines } = require('../package.json');
|
|
15
12
|
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
config.libvips;
|
|
13
|
+
const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || /* istanbul ignore next */
|
|
14
|
+
engines.libvips;
|
|
19
15
|
const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).version;
|
|
20
16
|
|
|
17
|
+
const prebuiltPlatforms = [
|
|
18
|
+
'darwin-arm64', 'darwin-x64',
|
|
19
|
+
'linux-arm', 'linux-arm64', 'linux-x64',
|
|
20
|
+
'linuxmusl-arm64', 'linuxmusl-x64',
|
|
21
|
+
'win32-ia32', 'win32-x64'
|
|
22
|
+
];
|
|
23
|
+
|
|
21
24
|
const spawnSyncOptions = {
|
|
22
25
|
encoding: 'utf8',
|
|
23
26
|
shell: true
|
|
24
27
|
};
|
|
25
28
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} catch (err) {
|
|
32
|
-
/* istanbul ignore next */
|
|
33
|
-
if (err.code !== 'EEXIST') {
|
|
34
|
-
throw err;
|
|
35
|
-
}
|
|
29
|
+
const log = (item) => {
|
|
30
|
+
if (item instanceof Error) {
|
|
31
|
+
console.error(`sharp: Installation error: ${item.message}`);
|
|
32
|
+
} else {
|
|
33
|
+
console.log(`sharp: ${item}`);
|
|
36
34
|
}
|
|
37
35
|
};
|
|
38
36
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
/* istanbul ignore next */
|
|
38
|
+
const runtimeLibc = () => detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '';
|
|
39
|
+
|
|
40
|
+
const runtimePlatformArch = () => `${process.platform}${runtimeLibc()}-${process.arch}`;
|
|
41
|
+
|
|
42
|
+
/* istanbul ignore next */
|
|
43
|
+
const buildPlatformArch = () => {
|
|
44
|
+
/* eslint camelcase: ["error", { allow: ["^npm_config_"] }] */
|
|
45
|
+
const { npm_config_arch, npm_config_platform, npm_config_libc } = process.env;
|
|
46
|
+
return `${npm_config_platform || process.platform}${npm_config_libc || runtimeLibc()}-${npm_config_arch || process.arch}`;
|
|
46
47
|
};
|
|
47
48
|
|
|
48
|
-
const
|
|
49
|
-
|
|
49
|
+
const buildSharpLibvipsIncludeDir = () => {
|
|
50
|
+
try {
|
|
51
|
+
return require('@img/sharp-libvips-dev/include');
|
|
52
|
+
} catch {}
|
|
53
|
+
/* istanbul ignore next */
|
|
54
|
+
return '';
|
|
50
55
|
};
|
|
51
56
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
const buildSharpLibvipsCPlusPlusDir = () => {
|
|
58
|
+
try {
|
|
59
|
+
return require('@img/sharp-libvips-dev/cplusplus');
|
|
60
|
+
} catch {}
|
|
61
|
+
/* istanbul ignore next */
|
|
62
|
+
return '';
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const buildSharpLibvipsLibDir = () => {
|
|
66
|
+
try {
|
|
67
|
+
return require(`@img/sharp-libvips-${buildPlatformArch()}/lib`);
|
|
68
|
+
} catch {}
|
|
69
|
+
/* istanbul ignore next */
|
|
70
|
+
return '';
|
|
58
71
|
};
|
|
59
72
|
|
|
60
|
-
const isRosetta =
|
|
73
|
+
const isRosetta = () => {
|
|
61
74
|
/* istanbul ignore next */
|
|
62
75
|
if (process.platform === 'darwin' && process.arch === 'x64') {
|
|
63
76
|
const translated = spawnSync('sysctl sysctl.proc_translated', spawnSyncOptions).stdout;
|
|
@@ -66,12 +79,19 @@ const isRosetta = function () {
|
|
|
66
79
|
return false;
|
|
67
80
|
};
|
|
68
81
|
|
|
69
|
-
|
|
82
|
+
/* istanbul ignore next */
|
|
83
|
+
const spawnRebuild = () =>
|
|
84
|
+
spawnSync('node-gyp rebuild --directory=src', {
|
|
85
|
+
...spawnSyncOptions,
|
|
86
|
+
stdio: 'inherit'
|
|
87
|
+
}).status;
|
|
88
|
+
|
|
89
|
+
const globalLibvipsVersion = () => {
|
|
70
90
|
if (process.platform !== 'win32') {
|
|
71
91
|
const globalLibvipsVersion = spawnSync('pkg-config --modversion vips-cpp', {
|
|
72
92
|
...spawnSyncOptions,
|
|
73
93
|
env: {
|
|
74
|
-
...env,
|
|
94
|
+
...process.env,
|
|
75
95
|
PKG_CONFIG_PATH: pkgConfigPath()
|
|
76
96
|
}
|
|
77
97
|
}).stdout;
|
|
@@ -82,17 +102,8 @@ const globalLibvipsVersion = function () {
|
|
|
82
102
|
}
|
|
83
103
|
};
|
|
84
104
|
|
|
85
|
-
const hasVendoredLibvips = function () {
|
|
86
|
-
return fs.existsSync(vendorPath);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
/* istanbul ignore next */
|
|
90
|
-
const removeVendoredLibvips = function () {
|
|
91
|
-
fs.rmSync(vendorPath, { recursive: true, maxRetries: 3, force: true });
|
|
92
|
-
};
|
|
93
|
-
|
|
94
105
|
/* istanbul ignore next */
|
|
95
|
-
const pkgConfigPath =
|
|
106
|
+
const pkgConfigPath = () => {
|
|
96
107
|
if (process.platform !== 'win32') {
|
|
97
108
|
const brewPkgConfigPath = spawnSync(
|
|
98
109
|
'which brew >/dev/null 2>&1 && brew environment --plain | grep PKG_CONFIG_LIBDIR | cut -d" " -f2',
|
|
@@ -100,7 +111,7 @@ const pkgConfigPath = function () {
|
|
|
100
111
|
).stdout || '';
|
|
101
112
|
return [
|
|
102
113
|
brewPkgConfigPath.trim(),
|
|
103
|
-
env.PKG_CONFIG_PATH,
|
|
114
|
+
process.env.PKG_CONFIG_PATH,
|
|
104
115
|
'/usr/local/lib/pkgconfig',
|
|
105
116
|
'/usr/lib/pkgconfig',
|
|
106
117
|
'/usr/local/libdata/pkgconfig',
|
|
@@ -111,8 +122,9 @@ const pkgConfigPath = function () {
|
|
|
111
122
|
}
|
|
112
123
|
};
|
|
113
124
|
|
|
114
|
-
const useGlobalLibvips =
|
|
115
|
-
if (Boolean(env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
|
125
|
+
const useGlobalLibvips = () => {
|
|
126
|
+
if (Boolean(process.env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
|
127
|
+
log('Detected SHARP_IGNORE_GLOBAL_LIBVIPS, skipping search for globally-installed libvips');
|
|
116
128
|
return false;
|
|
117
129
|
}
|
|
118
130
|
/* istanbul ignore next */
|
|
@@ -127,14 +139,15 @@ const useGlobalLibvips = function () {
|
|
|
127
139
|
|
|
128
140
|
module.exports = {
|
|
129
141
|
minimumLibvipsVersion,
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
142
|
+
prebuiltPlatforms,
|
|
143
|
+
buildPlatformArch,
|
|
144
|
+
buildSharpLibvipsIncludeDir,
|
|
145
|
+
buildSharpLibvipsCPlusPlusDir,
|
|
146
|
+
buildSharpLibvipsLibDir,
|
|
147
|
+
runtimePlatformArch,
|
|
133
148
|
log,
|
|
149
|
+
spawnRebuild,
|
|
134
150
|
globalLibvipsVersion,
|
|
135
|
-
hasVendoredLibvips,
|
|
136
|
-
removeVendoredLibvips,
|
|
137
151
|
pkgConfigPath,
|
|
138
|
-
useGlobalLibvips
|
|
139
|
-
mkdirSync
|
|
152
|
+
useGlobalLibvips
|
|
140
153
|
};
|
package/lib/operation.js
CHANGED
|
@@ -19,7 +19,7 @@ const is = require('./is');
|
|
|
19
19
|
* If no angle is provided, it is determined from the EXIF data.
|
|
20
20
|
* Mirroring is supported and may infer the use of a flip operation.
|
|
21
21
|
*
|
|
22
|
-
* The use of `rotate`
|
|
22
|
+
* The use of `rotate` without an angle will remove the EXIF `Orientation` tag, if any.
|
|
23
23
|
*
|
|
24
24
|
* Only one rotation can occur per pipeline.
|
|
25
25
|
* Previous calls to `rotate` in the same pipeline will be ignored.
|
|
@@ -83,8 +83,6 @@ function rotate (angle, options) {
|
|
|
83
83
|
* Mirror the image vertically (up-down) about the x-axis.
|
|
84
84
|
* This always occurs before rotation, if any.
|
|
85
85
|
*
|
|
86
|
-
* The use of `flip` implies the removal of the EXIF `Orientation` tag, if any.
|
|
87
|
-
*
|
|
88
86
|
* This operation does not work correctly with multi-page images.
|
|
89
87
|
*
|
|
90
88
|
* @example
|
|
@@ -102,8 +100,6 @@ function flip (flip) {
|
|
|
102
100
|
* Mirror the image horizontally (left-right) about the y-axis.
|
|
103
101
|
* This always occurs before rotation, if any.
|
|
104
102
|
*
|
|
105
|
-
* The use of `flop` implies the removal of the EXIF `Orientation` tag, if any.
|
|
106
|
-
*
|
|
107
103
|
* @example
|
|
108
104
|
* const output = await sharp(input).flop().toBuffer();
|
|
109
105
|
*
|