@depup/sharp 0.34.5-depup.0 → 0.35.4-depup.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 +16 -109
- package/changes.json +5 -0
- package/{lib/channel.js → dist/channel.cjs} +1 -1
- package/dist/channel.mjs +177 -0
- package/{lib/colour.js → dist/colour.cjs} +11 -7
- package/dist/colour.mjs +199 -0
- package/{lib/composite.js → dist/composite.cjs} +8 -7
- package/dist/composite.mjs +213 -0
- package/{lib/constructor.js → dist/constructor.cjs} +42 -30
- package/dist/constructor.mjs +511 -0
- package/dist/index.cjs +25 -0
- package/dist/index.d.cts +1999 -0
- package/dist/index.d.mts +2046 -0
- package/dist/index.mjs +25 -0
- package/{lib/input.js → dist/input.cjs} +47 -37
- package/dist/input.mjs +819 -0
- package/{lib/is.js → dist/is.cjs} +1 -1
- package/dist/is.mjs +143 -0
- package/{lib/libvips.js → dist/libvips.cjs} +35 -30
- package/dist/libvips.mjs +212 -0
- package/{lib/operation.js → dist/operation.cjs} +37 -51
- package/dist/operation.mjs +1002 -0
- package/{lib/output.js → dist/output.cjs} +166 -47
- package/dist/output.mjs +1785 -0
- package/{lib/resize.js → dist/resize.cjs} +54 -32
- package/dist/resize.mjs +617 -0
- package/dist/sharp.cjs +174 -0
- package/dist/sharp.mjs +174 -0
- package/{lib/utility.js → dist/utility.cjs} +18 -8
- package/dist/utility.mjs +301 -0
- package/install/build.js +3 -3
- package/lib/index.d.ts +111 -83
- package/package.json +95 -54
- package/src/binding.gyp +19 -14
- package/src/common.cc +77 -21
- package/src/common.h +23 -4
- package/src/metadata.cc +66 -8
- package/src/metadata.h +6 -1
- package/src/operations.cc +25 -8
- package/src/operations.h +1 -1
- package/src/pipeline.cc +203 -69
- package/src/pipeline.h +15 -1
- package/src/stats.cc +6 -6
- package/src/utilities.cc +7 -6
- package/install/check.js +0 -14
- package/lib/index.js +0 -16
- package/lib/sharp.js +0 -121
|
@@ -78,7 +78,7 @@ const string = (val) => typeof val === 'string' && val.length > 0;
|
|
|
78
78
|
* Is this value a real number?
|
|
79
79
|
* @private
|
|
80
80
|
*/
|
|
81
|
-
const number = (val) => typeof val === 'number' &&
|
|
81
|
+
const number = (val) => typeof val === 'number' && Number.isFinite(val);
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Is this value an integer?
|
package/dist/is.mjs
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
Copyright 2013 Lovell Fuller and others.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Is this value defined and not null?
|
|
8
|
+
* @private
|
|
9
|
+
*/
|
|
10
|
+
const defined = (val) => typeof val !== 'undefined' && val !== null;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Is this value an object?
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
const object = (val) => typeof val === 'object';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Is this value a plain object?
|
|
20
|
+
* @private
|
|
21
|
+
*/
|
|
22
|
+
const plainObject = (val) => Object.prototype.toString.call(val) === '[object Object]';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Is this value a function?
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
const fn = (val) => typeof val === 'function';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Is this value a boolean?
|
|
32
|
+
* @private
|
|
33
|
+
*/
|
|
34
|
+
const bool = (val) => typeof val === 'boolean';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Is this value a Buffer object?
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
const buffer = (val) => val instanceof Buffer;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Is this value a typed array object?. E.g. Uint8Array or Uint8ClampedArray?
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
const typedArray = (val) => {
|
|
47
|
+
if (defined(val)) {
|
|
48
|
+
switch (val.constructor) {
|
|
49
|
+
case Uint8Array:
|
|
50
|
+
case Uint8ClampedArray:
|
|
51
|
+
case Int8Array:
|
|
52
|
+
case Uint16Array:
|
|
53
|
+
case Int16Array:
|
|
54
|
+
case Uint32Array:
|
|
55
|
+
case Int32Array:
|
|
56
|
+
case Float32Array:
|
|
57
|
+
case Float64Array:
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return false;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Is this value an ArrayBuffer object?
|
|
67
|
+
* @private
|
|
68
|
+
*/
|
|
69
|
+
const arrayBuffer = (val) => val instanceof ArrayBuffer;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Is this value a non-empty string?
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
const string = (val) => typeof val === 'string' && val.length > 0;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Is this value a real number?
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
const number = (val) => typeof val === 'number' && Number.isFinite(val);
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Is this value an integer?
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
const integer = (val) => Number.isInteger(val);
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Is this value within an inclusive given range?
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
const inRange = (val, min, max) => val >= min && val <= max;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Is this value within the elements of an array?
|
|
97
|
+
* @private
|
|
98
|
+
*/
|
|
99
|
+
const inArray = (val, list) => list.includes(val);
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Create an Error with a message relating to an invalid parameter.
|
|
103
|
+
*
|
|
104
|
+
* @param {string} name - parameter name.
|
|
105
|
+
* @param {string} expected - description of the type/value/range expected.
|
|
106
|
+
* @param {*} actual - the value received.
|
|
107
|
+
* @returns {Error} Containing the formatted message.
|
|
108
|
+
* @private
|
|
109
|
+
*/
|
|
110
|
+
const invalidParameterError = (name, expected, actual) => new Error(
|
|
111
|
+
`Expected ${expected} for ${name} but received ${actual} of type ${typeof actual}`
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Ensures an Error from C++ contains a JS stack.
|
|
116
|
+
*
|
|
117
|
+
* @param {Error} native - Error with message from C++.
|
|
118
|
+
* @param {Error} context - Error with stack from JS.
|
|
119
|
+
* @returns {Error} Error with message and stack.
|
|
120
|
+
* @private
|
|
121
|
+
*/
|
|
122
|
+
const nativeError = (native, context) => {
|
|
123
|
+
context.message = native.message;
|
|
124
|
+
return context;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export default {
|
|
128
|
+
defined,
|
|
129
|
+
object,
|
|
130
|
+
plainObject,
|
|
131
|
+
fn,
|
|
132
|
+
bool,
|
|
133
|
+
buffer,
|
|
134
|
+
typedArray,
|
|
135
|
+
arrayBuffer,
|
|
136
|
+
string,
|
|
137
|
+
number,
|
|
138
|
+
integer,
|
|
139
|
+
inRange,
|
|
140
|
+
inArray,
|
|
141
|
+
invalidParameterError,
|
|
142
|
+
nativeError
|
|
143
|
+
};
|
|
@@ -5,20 +5,18 @@
|
|
|
5
5
|
|
|
6
6
|
const { spawnSync } = require('node:child_process');
|
|
7
7
|
const { createHash } = require('node:crypto');
|
|
8
|
-
const
|
|
9
|
-
const semverGreaterThanOrEqualTo = require('semver/functions/gte');
|
|
10
|
-
const semverSatisfies = require('semver/functions/satisfies');
|
|
8
|
+
const semver = require('semver');
|
|
11
9
|
const detectLibc = require('detect-libc');
|
|
12
|
-
|
|
13
|
-
const { config, engines, optionalDependencies } = require('../package.json');
|
|
10
|
+
const pkg = require('../package.json');
|
|
14
11
|
|
|
15
12
|
/* node:coverage ignore next */
|
|
16
|
-
const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || config.libvips;
|
|
17
|
-
const minimumLibvipsVersion =
|
|
13
|
+
const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || pkg.config.libvips;
|
|
14
|
+
const minimumLibvipsVersion = semver.coerce(minimumLibvipsVersionLabelled).version;
|
|
18
15
|
|
|
19
16
|
const prebuiltPlatforms = [
|
|
20
17
|
'darwin-arm64', 'darwin-x64',
|
|
21
|
-
'
|
|
18
|
+
'freebsd-arm64', 'freebsd-x64',
|
|
19
|
+
'linux-arm', 'linux-arm64', 'linux-ppc64', 'linux-riscv64', 'linux-s390x', 'linux-wasm32', 'linux-x64',
|
|
22
20
|
'linuxmusl-arm64', 'linuxmusl-x64',
|
|
23
21
|
'win32-arm64', 'win32-ia32', 'win32-x64'
|
|
24
22
|
];
|
|
@@ -36,13 +34,13 @@ const log = (item) => {
|
|
|
36
34
|
}
|
|
37
35
|
};
|
|
38
36
|
|
|
39
|
-
/* node:coverage
|
|
37
|
+
/* node:coverage disable */
|
|
38
|
+
|
|
40
39
|
const runtimeLibc = () => detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '';
|
|
41
40
|
|
|
42
41
|
const runtimePlatformArch = () => `${process.platform}${runtimeLibc()}-${process.arch}`;
|
|
43
42
|
|
|
44
43
|
const buildPlatformArch = () => {
|
|
45
|
-
/* node:coverage ignore next 3 */
|
|
46
44
|
if (isEmscripten()) {
|
|
47
45
|
return 'wasm32';
|
|
48
46
|
}
|
|
@@ -55,7 +53,6 @@ const buildSharpLibvipsIncludeDir = () => {
|
|
|
55
53
|
try {
|
|
56
54
|
return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/include`);
|
|
57
55
|
} catch {
|
|
58
|
-
/* node:coverage ignore next 5 */
|
|
59
56
|
try {
|
|
60
57
|
return require('@img/sharp-libvips-dev/include');
|
|
61
58
|
} catch {}
|
|
@@ -64,7 +61,6 @@ const buildSharpLibvipsIncludeDir = () => {
|
|
|
64
61
|
};
|
|
65
62
|
|
|
66
63
|
const buildSharpLibvipsCPlusPlusDir = () => {
|
|
67
|
-
/* node:coverage ignore next 4 */
|
|
68
64
|
try {
|
|
69
65
|
return require('@img/sharp-libvips-dev/cplusplus');
|
|
70
66
|
} catch {}
|
|
@@ -75,7 +71,6 @@ const buildSharpLibvipsLibDir = () => {
|
|
|
75
71
|
try {
|
|
76
72
|
return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/lib`);
|
|
77
73
|
} catch {
|
|
78
|
-
/* node:coverage ignore next 5 */
|
|
79
74
|
try {
|
|
80
75
|
return require(`@img/sharp-libvips-${buildPlatformArch()}/lib`);
|
|
81
76
|
} catch {}
|
|
@@ -83,12 +78,10 @@ const buildSharpLibvipsLibDir = () => {
|
|
|
83
78
|
return '';
|
|
84
79
|
};
|
|
85
80
|
|
|
86
|
-
/* node:coverage disable */
|
|
87
|
-
|
|
88
81
|
const isUnsupportedNodeRuntime = () => {
|
|
89
82
|
if (process.release?.name === 'node' && process.versions) {
|
|
90
|
-
if (!
|
|
91
|
-
return { found: process.versions.node, expected: engines.node };
|
|
83
|
+
if (!semver.satisfies(process.versions.node, pkg.engines.node)) {
|
|
84
|
+
return { found: process.versions.node, expected: pkg.engines.node };
|
|
92
85
|
}
|
|
93
86
|
}
|
|
94
87
|
};
|
|
@@ -113,7 +106,7 @@ const sha512 = (s) => createHash('sha512').update(s).digest('hex');
|
|
|
113
106
|
const yarnLocator = () => {
|
|
114
107
|
try {
|
|
115
108
|
const identHash = sha512(`imgsharp-libvips-${buildPlatformArch()}`);
|
|
116
|
-
const npmVersion =
|
|
109
|
+
const npmVersion = semver.coerce(pkg.optionalDependencies[`@img/sharp-libvips-${buildPlatformArch()}`], {
|
|
117
110
|
includePrerelease: true
|
|
118
111
|
}).version;
|
|
119
112
|
return sha512(`${identHash}npm:${npmVersion}`).slice(0, 10);
|
|
@@ -144,22 +137,34 @@ const globalLibvipsVersion = () => {
|
|
|
144
137
|
}
|
|
145
138
|
};
|
|
146
139
|
|
|
140
|
+
const getBrewPkgConfigPath = () => {
|
|
141
|
+
try {
|
|
142
|
+
const brewPrefix = (spawnSync('brew', ['--prefix'], { encoding: 'utf8' }).stdout || '').trim();
|
|
143
|
+
if (brewPrefix) {
|
|
144
|
+
return `${brewPrefix}/lib/pkgconfig`;
|
|
145
|
+
}
|
|
146
|
+
} catch (_err) {}
|
|
147
|
+
return undefined;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const getPkgConfigPath = () => {
|
|
151
|
+
try {
|
|
152
|
+
const pkgConfigPath = (spawnSync('pkg-config', ['--variable', 'pc_path', 'pkg-config'], { encoding: 'utf8' }).stdout || '').trim();
|
|
153
|
+
if (pkgConfigPath) {
|
|
154
|
+
return pkgConfigPath;
|
|
155
|
+
}
|
|
156
|
+
} catch (_err) {}
|
|
157
|
+
return undefined;
|
|
158
|
+
};
|
|
159
|
+
|
|
147
160
|
/* node:coverage enable */
|
|
148
161
|
|
|
149
162
|
const pkgConfigPath = () => {
|
|
150
163
|
if (process.platform !== 'win32') {
|
|
151
|
-
/* node:coverage ignore next 4 */
|
|
152
|
-
const brewPkgConfigPath = spawnSync(
|
|
153
|
-
'which brew >/dev/null 2>&1 && brew environment --plain | grep PKG_CONFIG_LIBDIR | cut -d" " -f2',
|
|
154
|
-
spawnSyncOptions
|
|
155
|
-
).stdout || '';
|
|
156
164
|
return [
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
'/usr/lib/pkgconfig',
|
|
161
|
-
'/usr/local/libdata/pkgconfig',
|
|
162
|
-
'/usr/libdata/pkgconfig'
|
|
165
|
+
getBrewPkgConfigPath(),
|
|
166
|
+
getPkgConfigPath(),
|
|
167
|
+
process.env.PKG_CONFIG_PATH
|
|
163
168
|
].filter(Boolean).join(':');
|
|
164
169
|
} else {
|
|
165
170
|
return '';
|
|
@@ -186,7 +191,7 @@ const useGlobalLibvips = (logger) => {
|
|
|
186
191
|
}
|
|
187
192
|
const globalVipsVersion = globalLibvipsVersion();
|
|
188
193
|
/* node:coverage ignore next */
|
|
189
|
-
return !!globalVipsVersion &&
|
|
194
|
+
return !!globalVipsVersion && semver.gte(globalVipsVersion, minimumLibvipsVersion);
|
|
190
195
|
};
|
|
191
196
|
|
|
192
197
|
module.exports = {
|
package/dist/libvips.mjs
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
Copyright 2013 Lovell Fuller and others.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { spawnSync } from 'node:child_process';
|
|
7
|
+
import { createHash } from 'node:crypto';
|
|
8
|
+
import semver from 'semver';
|
|
9
|
+
import detectLibc from 'detect-libc';
|
|
10
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
11
|
+
|
|
12
|
+
/* node:coverage ignore next */
|
|
13
|
+
const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || pkg.config.libvips;
|
|
14
|
+
const minimumLibvipsVersion = semver.coerce(minimumLibvipsVersionLabelled).version;
|
|
15
|
+
|
|
16
|
+
const prebuiltPlatforms = [
|
|
17
|
+
'darwin-arm64', 'darwin-x64',
|
|
18
|
+
'freebsd-arm64', 'freebsd-x64',
|
|
19
|
+
'linux-arm', 'linux-arm64', 'linux-ppc64', 'linux-riscv64', 'linux-s390x', 'linux-wasm32', 'linux-x64',
|
|
20
|
+
'linuxmusl-arm64', 'linuxmusl-x64',
|
|
21
|
+
'win32-arm64', 'win32-ia32', 'win32-x64'
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const spawnSyncOptions = {
|
|
25
|
+
encoding: 'utf8',
|
|
26
|
+
shell: true
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const log = (item) => {
|
|
30
|
+
if (item instanceof Error) {
|
|
31
|
+
console.error(`sharp: Installation error: ${item.message}`);
|
|
32
|
+
} else {
|
|
33
|
+
console.log(`sharp: ${item}`);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/* node:coverage disable */
|
|
38
|
+
|
|
39
|
+
const runtimeLibc = () => detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '';
|
|
40
|
+
|
|
41
|
+
const runtimePlatformArch = () => `${process.platform}${runtimeLibc()}-${process.arch}`;
|
|
42
|
+
|
|
43
|
+
const buildPlatformArch = () => {
|
|
44
|
+
if (isEmscripten()) {
|
|
45
|
+
return 'wasm32';
|
|
46
|
+
}
|
|
47
|
+
const { npm_config_arch, npm_config_platform, npm_config_libc } = process.env;
|
|
48
|
+
const libc = typeof npm_config_libc === 'string' ? npm_config_libc : runtimeLibc();
|
|
49
|
+
return `${npm_config_platform || process.platform}${libc}-${npm_config_arch || process.arch}`;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const buildSharpLibvipsIncludeDir = () => {
|
|
53
|
+
try {
|
|
54
|
+
return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/include`);
|
|
55
|
+
} catch {
|
|
56
|
+
try {
|
|
57
|
+
return require('@img/sharp-libvips-dev/include');
|
|
58
|
+
} catch {}
|
|
59
|
+
}
|
|
60
|
+
return '';
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const buildSharpLibvipsCPlusPlusDir = () => {
|
|
64
|
+
try {
|
|
65
|
+
return require('@img/sharp-libvips-dev/cplusplus');
|
|
66
|
+
} catch {}
|
|
67
|
+
return '';
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const buildSharpLibvipsLibDir = () => {
|
|
71
|
+
try {
|
|
72
|
+
return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/lib`);
|
|
73
|
+
} catch {
|
|
74
|
+
try {
|
|
75
|
+
return require(`@img/sharp-libvips-${buildPlatformArch()}/lib`);
|
|
76
|
+
} catch {}
|
|
77
|
+
}
|
|
78
|
+
return '';
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const isUnsupportedNodeRuntime = () => {
|
|
82
|
+
if (process.release?.name === 'node' && process.versions) {
|
|
83
|
+
if (!semver.satisfies(process.versions.node, pkg.engines.node)) {
|
|
84
|
+
return { found: process.versions.node, expected: pkg.engines.node };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const isEmscripten = () => {
|
|
90
|
+
const { CC } = process.env;
|
|
91
|
+
return Boolean(CC?.endsWith('/emcc'));
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const isRosetta = () => {
|
|
95
|
+
if (process.platform === 'darwin' && process.arch === 'x64') {
|
|
96
|
+
const translated = spawnSync('sysctl sysctl.proc_translated', spawnSyncOptions).stdout;
|
|
97
|
+
return (translated || '').trim() === 'sysctl.proc_translated: 1';
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/* node:coverage enable */
|
|
103
|
+
|
|
104
|
+
const sha512 = (s) => createHash('sha512').update(s).digest('hex');
|
|
105
|
+
|
|
106
|
+
const yarnLocator = () => {
|
|
107
|
+
try {
|
|
108
|
+
const identHash = sha512(`imgsharp-libvips-${buildPlatformArch()}`);
|
|
109
|
+
const npmVersion = semver.coerce(pkg.optionalDependencies[`@img/sharp-libvips-${buildPlatformArch()}`], {
|
|
110
|
+
includePrerelease: true
|
|
111
|
+
}).version;
|
|
112
|
+
return sha512(`${identHash}npm:${npmVersion}`).slice(0, 10);
|
|
113
|
+
} catch {}
|
|
114
|
+
return '';
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/* node:coverage disable */
|
|
118
|
+
|
|
119
|
+
const spawnRebuild = () =>
|
|
120
|
+
spawnSync(`node-gyp rebuild --directory=src ${isEmscripten() ? '--nodedir=emscripten' : ''}`, {
|
|
121
|
+
...spawnSyncOptions,
|
|
122
|
+
stdio: 'inherit'
|
|
123
|
+
}).status;
|
|
124
|
+
|
|
125
|
+
const globalLibvipsVersion = () => {
|
|
126
|
+
if (process.platform !== 'win32') {
|
|
127
|
+
const globalLibvipsVersion = spawnSync('pkg-config --modversion vips-cpp', {
|
|
128
|
+
...spawnSyncOptions,
|
|
129
|
+
env: {
|
|
130
|
+
...process.env,
|
|
131
|
+
PKG_CONFIG_PATH: pkgConfigPath()
|
|
132
|
+
}
|
|
133
|
+
}).stdout;
|
|
134
|
+
return (globalLibvipsVersion || '').trim();
|
|
135
|
+
} else {
|
|
136
|
+
return '';
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const getBrewPkgConfigPath = () => {
|
|
141
|
+
try {
|
|
142
|
+
const brewPrefix = (spawnSync('brew', ['--prefix'], { encoding: 'utf8' }).stdout || '').trim();
|
|
143
|
+
if (brewPrefix) {
|
|
144
|
+
return `${brewPrefix}/lib/pkgconfig`;
|
|
145
|
+
}
|
|
146
|
+
} catch (_err) {}
|
|
147
|
+
return undefined;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const getPkgConfigPath = () => {
|
|
151
|
+
try {
|
|
152
|
+
const pkgConfigPath = (spawnSync('pkg-config', ['--variable', 'pc_path', 'pkg-config'], { encoding: 'utf8' }).stdout || '').trim();
|
|
153
|
+
if (pkgConfigPath) {
|
|
154
|
+
return pkgConfigPath;
|
|
155
|
+
}
|
|
156
|
+
} catch (_err) {}
|
|
157
|
+
return undefined;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/* node:coverage enable */
|
|
161
|
+
|
|
162
|
+
const pkgConfigPath = () => {
|
|
163
|
+
if (process.platform !== 'win32') {
|
|
164
|
+
return [
|
|
165
|
+
getBrewPkgConfigPath(),
|
|
166
|
+
getPkgConfigPath(),
|
|
167
|
+
process.env.PKG_CONFIG_PATH
|
|
168
|
+
].filter(Boolean).join(':');
|
|
169
|
+
} else {
|
|
170
|
+
return '';
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const skipSearch = (status, reason, logger) => {
|
|
175
|
+
if (logger) {
|
|
176
|
+
logger(`Detected ${reason}, skipping search for globally-installed libvips`);
|
|
177
|
+
}
|
|
178
|
+
return status;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const useGlobalLibvips = (logger) => {
|
|
182
|
+
if (Boolean(process.env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
|
183
|
+
return skipSearch(false, 'SHARP_IGNORE_GLOBAL_LIBVIPS', logger);
|
|
184
|
+
}
|
|
185
|
+
if (Boolean(process.env.SHARP_FORCE_GLOBAL_LIBVIPS) === true) {
|
|
186
|
+
return skipSearch(true, 'SHARP_FORCE_GLOBAL_LIBVIPS', logger);
|
|
187
|
+
}
|
|
188
|
+
/* node:coverage ignore next 3 */
|
|
189
|
+
if (isRosetta()) {
|
|
190
|
+
return skipSearch(false, 'Rosetta', logger);
|
|
191
|
+
}
|
|
192
|
+
const globalVipsVersion = globalLibvipsVersion();
|
|
193
|
+
/* node:coverage ignore next */
|
|
194
|
+
return !!globalVipsVersion && semver.gte(globalVipsVersion, minimumLibvipsVersion);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export default {
|
|
198
|
+
minimumLibvipsVersion,
|
|
199
|
+
prebuiltPlatforms,
|
|
200
|
+
buildPlatformArch,
|
|
201
|
+
buildSharpLibvipsIncludeDir,
|
|
202
|
+
buildSharpLibvipsCPlusPlusDir,
|
|
203
|
+
buildSharpLibvipsLibDir,
|
|
204
|
+
isUnsupportedNodeRuntime,
|
|
205
|
+
runtimePlatformArch,
|
|
206
|
+
log,
|
|
207
|
+
yarnLocator,
|
|
208
|
+
spawnRebuild,
|
|
209
|
+
globalLibvipsVersion,
|
|
210
|
+
pkgConfigPath,
|
|
211
|
+
useGlobalLibvips
|
|
212
|
+
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const is = require('./is');
|
|
6
|
+
const is = require('./is.cjs');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* How accurate an operation should be.
|
|
@@ -78,6 +78,10 @@ function rotate (angle, options) {
|
|
|
78
78
|
* Auto-orient based on the EXIF `Orientation` tag, then remove the tag.
|
|
79
79
|
* Mirroring is supported and may infer the use of a flip operation.
|
|
80
80
|
*
|
|
81
|
+
* Only the EXIF `Orientation` tag is considered; orientation carried in other
|
|
82
|
+
* places, such as an XMP `tiff:Orientation` element, is left untouched and
|
|
83
|
+
* remains the responsibility of the consumer.
|
|
84
|
+
*
|
|
81
85
|
* Previous or subsequent use of `rotate(angle)` and either `flip()` or `flop()`
|
|
82
86
|
* will logically occur after auto-orientation, regardless of call order.
|
|
83
87
|
*
|
|
@@ -178,7 +182,13 @@ function flop (flop) {
|
|
|
178
182
|
* @throws {Error} Invalid parameters
|
|
179
183
|
*/
|
|
180
184
|
function affine (matrix, options) {
|
|
181
|
-
const
|
|
185
|
+
const isValidShape = Array.isArray(matrix) && (
|
|
186
|
+
// 1x4 array of numbers
|
|
187
|
+
(matrix.length === 4 && matrix.every(is.number)) ||
|
|
188
|
+
// 2x2 array of arrays of numbers
|
|
189
|
+
(matrix.length === 2 && matrix.every((row) => Array.isArray(row) && row.length === 2))
|
|
190
|
+
);
|
|
191
|
+
const flatMatrix = isValidShape ? matrix.flat() : [];
|
|
182
192
|
if (flatMatrix.length === 4 && flatMatrix.every(is.number)) {
|
|
183
193
|
this.options.affineMatrix = flatMatrix;
|
|
184
194
|
} else {
|
|
@@ -259,45 +269,18 @@ function affine (matrix, options) {
|
|
|
259
269
|
* })
|
|
260
270
|
* .toBuffer();
|
|
261
271
|
*
|
|
262
|
-
* @param {Object
|
|
272
|
+
* @param {Object} [options] - if present, is an Object with attributes
|
|
263
273
|
* @param {number} [options.sigma] - the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`, between 0.000001 and 10
|
|
264
274
|
* @param {number} [options.m1=1.0] - the level of sharpening to apply to "flat" areas, between 0 and 1000000
|
|
265
275
|
* @param {number} [options.m2=2.0] - the level of sharpening to apply to "jagged" areas, between 0 and 1000000
|
|
266
276
|
* @param {number} [options.x1=2.0] - threshold between "flat" and "jagged", between 0 and 1000000
|
|
267
277
|
* @param {number} [options.y2=10.0] - maximum amount of brightening, between 0 and 1000000
|
|
268
278
|
* @param {number} [options.y3=20.0] - maximum amount of darkening, between 0 and 1000000
|
|
269
|
-
* @param {number} [flat] - (deprecated) see `options.m1`.
|
|
270
|
-
* @param {number} [jagged] - (deprecated) see `options.m2`.
|
|
271
279
|
* @returns {Sharp}
|
|
272
280
|
* @throws {Error} Invalid parameters
|
|
273
281
|
*/
|
|
274
|
-
function sharpen (options
|
|
275
|
-
if (
|
|
276
|
-
// No arguments: default to mild sharpen
|
|
277
|
-
this.options.sharpenSigma = -1;
|
|
278
|
-
} else if (is.bool(options)) {
|
|
279
|
-
// Deprecated boolean argument: apply mild sharpen?
|
|
280
|
-
this.options.sharpenSigma = options ? -1 : 0;
|
|
281
|
-
} else if (is.number(options) && is.inRange(options, 0.01, 10000)) {
|
|
282
|
-
// Deprecated numeric argument: specific sigma
|
|
283
|
-
this.options.sharpenSigma = options;
|
|
284
|
-
// Deprecated control over flat areas
|
|
285
|
-
if (is.defined(flat)) {
|
|
286
|
-
if (is.number(flat) && is.inRange(flat, 0, 10000)) {
|
|
287
|
-
this.options.sharpenM1 = flat;
|
|
288
|
-
} else {
|
|
289
|
-
throw is.invalidParameterError('flat', 'number between 0 and 10000', flat);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
// Deprecated control over jagged areas
|
|
293
|
-
if (is.defined(jagged)) {
|
|
294
|
-
if (is.number(jagged) && is.inRange(jagged, 0, 10000)) {
|
|
295
|
-
this.options.sharpenM2 = jagged;
|
|
296
|
-
} else {
|
|
297
|
-
throw is.invalidParameterError('jagged', 'number between 0 and 10000', jagged);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
} else if (is.plainObject(options)) {
|
|
282
|
+
function sharpen (options) {
|
|
283
|
+
if (is.plainObject(options)) {
|
|
301
284
|
if (is.number(options.sigma) && is.inRange(options.sigma, 0.000001, 10)) {
|
|
302
285
|
this.options.sharpenSigma = options.sigma;
|
|
303
286
|
} else {
|
|
@@ -339,7 +322,7 @@ function sharpen (options, flat, jagged) {
|
|
|
339
322
|
}
|
|
340
323
|
}
|
|
341
324
|
} else {
|
|
342
|
-
|
|
325
|
+
this.options.sharpenSigma = -1;
|
|
343
326
|
}
|
|
344
327
|
return this;
|
|
345
328
|
}
|
|
@@ -451,10 +434,10 @@ function blur (options) {
|
|
|
451
434
|
function dilate (width) {
|
|
452
435
|
if (!is.defined(width)) {
|
|
453
436
|
this.options.dilateWidth = 1;
|
|
454
|
-
} else if (is.integer(width) && width
|
|
437
|
+
} else if (is.integer(width) && is.inRange(width, 1, 65536)) {
|
|
455
438
|
this.options.dilateWidth = width;
|
|
456
439
|
} else {
|
|
457
|
-
throw is.invalidParameterError('
|
|
440
|
+
throw is.invalidParameterError('width', 'integer between 1 and 65536', width);
|
|
458
441
|
}
|
|
459
442
|
return this;
|
|
460
443
|
}
|
|
@@ -474,10 +457,10 @@ function dilate (width) {
|
|
|
474
457
|
function erode (width) {
|
|
475
458
|
if (!is.defined(width)) {
|
|
476
459
|
this.options.erodeWidth = 1;
|
|
477
|
-
} else if (is.integer(width) && width
|
|
460
|
+
} else if (is.integer(width) && is.inRange(width, 1, 65536)) {
|
|
478
461
|
this.options.erodeWidth = width;
|
|
479
462
|
} else {
|
|
480
|
-
throw is.invalidParameterError('
|
|
463
|
+
throw is.invalidParameterError('width', 'integer between 1 and 65536', width);
|
|
481
464
|
}
|
|
482
465
|
return this;
|
|
483
466
|
}
|
|
@@ -510,8 +493,6 @@ function flatten (options) {
|
|
|
510
493
|
*
|
|
511
494
|
* Existing alpha channel values for non-white pixels remain unchanged.
|
|
512
495
|
*
|
|
513
|
-
* This feature is experimental and the API may change.
|
|
514
|
-
*
|
|
515
496
|
* @since 0.32.1
|
|
516
497
|
*
|
|
517
498
|
* @example
|
|
@@ -675,23 +656,23 @@ function normalize (options) {
|
|
|
675
656
|
* .toBuffer();
|
|
676
657
|
*
|
|
677
658
|
* @param {Object} options
|
|
678
|
-
* @param {number} options.width - Integral width of the search window, in pixels.
|
|
679
|
-
* @param {number} options.height - Integral height of the search window, in pixels.
|
|
659
|
+
* @param {number} options.width - Integral width of the search window, in pixels, between 1 and 65536.
|
|
660
|
+
* @param {number} options.height - Integral height of the search window, in pixels, between 1 and 65536.
|
|
680
661
|
* @param {number} [options.maxSlope=3] - Integral level of brightening, between 0 and 100, where 0 disables contrast limiting.
|
|
681
662
|
* @returns {Sharp}
|
|
682
663
|
* @throws {Error} Invalid parameters
|
|
683
664
|
*/
|
|
684
665
|
function clahe (options) {
|
|
685
666
|
if (is.plainObject(options)) {
|
|
686
|
-
if (is.integer(options.width) && options.width
|
|
667
|
+
if (is.integer(options.width) && is.inRange(options.width, 1, 65536)) {
|
|
687
668
|
this.options.claheWidth = options.width;
|
|
688
669
|
} else {
|
|
689
|
-
throw is.invalidParameterError('width', 'integer
|
|
670
|
+
throw is.invalidParameterError('width', 'integer between 1 and 65536', options.width);
|
|
690
671
|
}
|
|
691
|
-
if (is.integer(options.height) && options.height
|
|
672
|
+
if (is.integer(options.height) && is.inRange(options.height, 1, 65536)) {
|
|
692
673
|
this.options.claheHeight = options.height;
|
|
693
674
|
} else {
|
|
694
|
-
throw is.invalidParameterError('height', 'integer
|
|
675
|
+
throw is.invalidParameterError('height', 'integer between 1 and 65536', options.height);
|
|
695
676
|
}
|
|
696
677
|
if (is.defined(options.maxSlope)) {
|
|
697
678
|
if (is.integer(options.maxSlope) && is.inRange(options.maxSlope, 0, 100)) {
|
|
@@ -735,7 +716,8 @@ function convolve (kernel) {
|
|
|
735
716
|
if (!is.object(kernel) || !Array.isArray(kernel.kernel) ||
|
|
736
717
|
!is.integer(kernel.width) || !is.integer(kernel.height) ||
|
|
737
718
|
!is.inRange(kernel.width, 3, 1001) || !is.inRange(kernel.height, 3, 1001) ||
|
|
738
|
-
kernel.height * kernel.width !== kernel.kernel.length
|
|
719
|
+
kernel.height * kernel.width !== kernel.kernel.length ||
|
|
720
|
+
!kernel.kernel.every(is.number)
|
|
739
721
|
) {
|
|
740
722
|
// must pass in a kernel
|
|
741
723
|
throw new Error('Invalid convolution kernel');
|
|
@@ -888,12 +870,16 @@ function recomb (inputMatrix) {
|
|
|
888
870
|
if (!Array.isArray(inputMatrix)) {
|
|
889
871
|
throw is.invalidParameterError('inputMatrix', 'array', inputMatrix);
|
|
890
872
|
}
|
|
891
|
-
|
|
892
|
-
|
|
873
|
+
const dimensions = inputMatrix.length;
|
|
874
|
+
if (dimensions !== 3 && dimensions !== 4) {
|
|
875
|
+
throw is.invalidParameterError('inputMatrix', '3x3 or 4x4 array', dimensions);
|
|
876
|
+
}
|
|
877
|
+
if (!inputMatrix.every((row) => Array.isArray(row) && row.length === dimensions)) {
|
|
878
|
+
throw is.invalidParameterError('inputMatrix', `array of ${dimensions} arrays of length ${dimensions}`, inputMatrix);
|
|
893
879
|
}
|
|
894
|
-
const recombMatrix = inputMatrix.flat()
|
|
895
|
-
if (recombMatrix.
|
|
896
|
-
throw is.invalidParameterError('inputMatrix', '
|
|
880
|
+
const recombMatrix = inputMatrix.flat();
|
|
881
|
+
if (!recombMatrix.every(is.number)) {
|
|
882
|
+
throw is.invalidParameterError('inputMatrix', 'array of numbers', recombMatrix);
|
|
897
883
|
}
|
|
898
884
|
this.options.recombMatrix = recombMatrix;
|
|
899
885
|
return this;
|