@revizly/sharp 0.35.0-revizly4 → 0.35.0-revizly40
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 +12 -18
- package/{lib/channel.js → dist/channel.cjs} +1 -1
- package/dist/channel.mjs +177 -0
- package/{lib/colour.js → dist/colour.cjs} +1 -1
- package/dist/colour.mjs +195 -0
- package/{lib/composite.js → dist/composite.cjs} +2 -1
- package/dist/composite.mjs +213 -0
- package/{lib/constructor.js → dist/constructor.cjs} +42 -29
- package/dist/constructor.mjs +512 -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} +22 -17
- package/dist/input.mjs +814 -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} +22 -47
- package/dist/operation.mjs +991 -0
- package/{lib/output.js → dist/output.cjs} +161 -28
- package/dist/output.mjs +1799 -0
- package/{lib/resize.js → dist/resize.cjs} +40 -18
- package/dist/resize.mjs +617 -0
- package/dist/sharp.cjs +119 -0
- package/dist/sharp.mjs +119 -0
- package/{lib/utility.js → dist/utility.cjs} +11 -7
- package/dist/utility.mjs +295 -0
- package/install/build.js +3 -3
- package/lib/index.d.ts +99 -71
- package/package.json +46 -27
- package/src/binding.gyp +18 -13
- package/src/common.cc +70 -17
- package/src/common.h +22 -3
- 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 +194 -69
- package/src/pipeline.h +14 -1
- package/src/stats.cc +6 -6
- package/src/utilities.cc +4 -3
- 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(`@revizly/sharp-libvips-dev-${buildPlatformArch()}/include`);
|
|
57
55
|
} catch {
|
|
58
|
-
/* node:coverage ignore next 5 */
|
|
59
56
|
try {
|
|
60
57
|
return require('@revizly/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('@revizly/sharp-libvips-dev/cplusplus');
|
|
70
66
|
} catch {}
|
|
@@ -75,7 +71,6 @@ const buildSharpLibvipsLibDir = () => {
|
|
|
75
71
|
try {
|
|
76
72
|
return require(`@revizly/sharp-libvips-dev-${buildPlatformArch()}/lib`);
|
|
77
73
|
} catch {
|
|
78
|
-
/* node:coverage ignore next 5 */
|
|
79
74
|
try {
|
|
80
75
|
return require(`@revizly/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[`@revizly/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(`@revizly/sharp-libvips-dev-${buildPlatformArch()}/include`);
|
|
55
|
+
} catch {
|
|
56
|
+
try {
|
|
57
|
+
return require('@revizly/sharp-libvips-dev/include');
|
|
58
|
+
} catch {}
|
|
59
|
+
}
|
|
60
|
+
return '';
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const buildSharpLibvipsCPlusPlusDir = () => {
|
|
64
|
+
try {
|
|
65
|
+
return require('@revizly/sharp-libvips-dev/cplusplus');
|
|
66
|
+
} catch {}
|
|
67
|
+
return '';
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const buildSharpLibvipsLibDir = () => {
|
|
71
|
+
try {
|
|
72
|
+
return require(`@revizly/sharp-libvips-dev-${buildPlatformArch()}/lib`);
|
|
73
|
+
} catch {
|
|
74
|
+
try {
|
|
75
|
+
return require(`@revizly/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[`@revizly/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.
|
|
@@ -178,7 +178,7 @@ function flop (flop) {
|
|
|
178
178
|
* @throws {Error} Invalid parameters
|
|
179
179
|
*/
|
|
180
180
|
function affine (matrix, options) {
|
|
181
|
-
const flatMatrix = [].concat(...matrix);
|
|
181
|
+
const flatMatrix = Array.isArray(matrix) ? [].concat(...matrix) : [];
|
|
182
182
|
if (flatMatrix.length === 4 && flatMatrix.every(is.number)) {
|
|
183
183
|
this.options.affineMatrix = flatMatrix;
|
|
184
184
|
} else {
|
|
@@ -259,45 +259,18 @@ function affine (matrix, options) {
|
|
|
259
259
|
* })
|
|
260
260
|
* .toBuffer();
|
|
261
261
|
*
|
|
262
|
-
* @param {Object
|
|
262
|
+
* @param {Object} [options] - if present, is an Object with attributes
|
|
263
263
|
* @param {number} [options.sigma] - the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`, between 0.000001 and 10
|
|
264
264
|
* @param {number} [options.m1=1.0] - the level of sharpening to apply to "flat" areas, between 0 and 1000000
|
|
265
265
|
* @param {number} [options.m2=2.0] - the level of sharpening to apply to "jagged" areas, between 0 and 1000000
|
|
266
266
|
* @param {number} [options.x1=2.0] - threshold between "flat" and "jagged", between 0 and 1000000
|
|
267
267
|
* @param {number} [options.y2=10.0] - maximum amount of brightening, between 0 and 1000000
|
|
268
268
|
* @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
269
|
* @returns {Sharp}
|
|
272
270
|
* @throws {Error} Invalid parameters
|
|
273
271
|
*/
|
|
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)) {
|
|
272
|
+
function sharpen (options) {
|
|
273
|
+
if (is.plainObject(options)) {
|
|
301
274
|
if (is.number(options.sigma) && is.inRange(options.sigma, 0.000001, 10)) {
|
|
302
275
|
this.options.sharpenSigma = options.sigma;
|
|
303
276
|
} else {
|
|
@@ -339,7 +312,7 @@ function sharpen (options, flat, jagged) {
|
|
|
339
312
|
}
|
|
340
313
|
}
|
|
341
314
|
} else {
|
|
342
|
-
|
|
315
|
+
this.options.sharpenSigma = -1;
|
|
343
316
|
}
|
|
344
317
|
return this;
|
|
345
318
|
}
|
|
@@ -451,10 +424,10 @@ function blur (options) {
|
|
|
451
424
|
function dilate (width) {
|
|
452
425
|
if (!is.defined(width)) {
|
|
453
426
|
this.options.dilateWidth = 1;
|
|
454
|
-
} else if (is.integer(width) && width
|
|
427
|
+
} else if (is.integer(width) && is.inRange(width, 1, 65536)) {
|
|
455
428
|
this.options.dilateWidth = width;
|
|
456
429
|
} else {
|
|
457
|
-
throw is.invalidParameterError('
|
|
430
|
+
throw is.invalidParameterError('width', 'integer between 1 and 65536', width);
|
|
458
431
|
}
|
|
459
432
|
return this;
|
|
460
433
|
}
|
|
@@ -474,10 +447,10 @@ function dilate (width) {
|
|
|
474
447
|
function erode (width) {
|
|
475
448
|
if (!is.defined(width)) {
|
|
476
449
|
this.options.erodeWidth = 1;
|
|
477
|
-
} else if (is.integer(width) && width
|
|
450
|
+
} else if (is.integer(width) && is.inRange(width, 1, 65536)) {
|
|
478
451
|
this.options.erodeWidth = width;
|
|
479
452
|
} else {
|
|
480
|
-
throw is.invalidParameterError('
|
|
453
|
+
throw is.invalidParameterError('width', 'integer between 1 and 65536', width);
|
|
481
454
|
}
|
|
482
455
|
return this;
|
|
483
456
|
}
|
|
@@ -510,8 +483,6 @@ function flatten (options) {
|
|
|
510
483
|
*
|
|
511
484
|
* Existing alpha channel values for non-white pixels remain unchanged.
|
|
512
485
|
*
|
|
513
|
-
* This feature is experimental and the API may change.
|
|
514
|
-
*
|
|
515
486
|
* @since 0.32.1
|
|
516
487
|
*
|
|
517
488
|
* @example
|
|
@@ -675,23 +646,23 @@ function normalize (options) {
|
|
|
675
646
|
* .toBuffer();
|
|
676
647
|
*
|
|
677
648
|
* @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.
|
|
649
|
+
* @param {number} options.width - Integral width of the search window, in pixels, between 1 and 65536.
|
|
650
|
+
* @param {number} options.height - Integral height of the search window, in pixels, between 1 and 65536.
|
|
680
651
|
* @param {number} [options.maxSlope=3] - Integral level of brightening, between 0 and 100, where 0 disables contrast limiting.
|
|
681
652
|
* @returns {Sharp}
|
|
682
653
|
* @throws {Error} Invalid parameters
|
|
683
654
|
*/
|
|
684
655
|
function clahe (options) {
|
|
685
656
|
if (is.plainObject(options)) {
|
|
686
|
-
if (is.integer(options.width) && options.width
|
|
657
|
+
if (is.integer(options.width) && is.inRange(options.width, 1, 65536)) {
|
|
687
658
|
this.options.claheWidth = options.width;
|
|
688
659
|
} else {
|
|
689
|
-
throw is.invalidParameterError('width', 'integer
|
|
660
|
+
throw is.invalidParameterError('width', 'integer between 1 and 65536', options.width);
|
|
690
661
|
}
|
|
691
|
-
if (is.integer(options.height) && options.height
|
|
662
|
+
if (is.integer(options.height) && is.inRange(options.height, 1, 65536)) {
|
|
692
663
|
this.options.claheHeight = options.height;
|
|
693
664
|
} else {
|
|
694
|
-
throw is.invalidParameterError('height', 'integer
|
|
665
|
+
throw is.invalidParameterError('height', 'integer between 1 and 65536', options.height);
|
|
695
666
|
}
|
|
696
667
|
if (is.defined(options.maxSlope)) {
|
|
697
668
|
if (is.integer(options.maxSlope) && is.inRange(options.maxSlope, 0, 100)) {
|
|
@@ -735,7 +706,8 @@ function convolve (kernel) {
|
|
|
735
706
|
if (!is.object(kernel) || !Array.isArray(kernel.kernel) ||
|
|
736
707
|
!is.integer(kernel.width) || !is.integer(kernel.height) ||
|
|
737
708
|
!is.inRange(kernel.width, 3, 1001) || !is.inRange(kernel.height, 3, 1001) ||
|
|
738
|
-
kernel.height * kernel.width !== kernel.kernel.length
|
|
709
|
+
kernel.height * kernel.width !== kernel.kernel.length ||
|
|
710
|
+
!kernel.kernel.every(is.number)
|
|
739
711
|
) {
|
|
740
712
|
// must pass in a kernel
|
|
741
713
|
throw new Error('Invalid convolution kernel');
|
|
@@ -891,10 +863,13 @@ function recomb (inputMatrix) {
|
|
|
891
863
|
if (inputMatrix.length !== 3 && inputMatrix.length !== 4) {
|
|
892
864
|
throw is.invalidParameterError('inputMatrix', '3x3 or 4x4 array', inputMatrix.length);
|
|
893
865
|
}
|
|
894
|
-
const recombMatrix = inputMatrix.flat()
|
|
866
|
+
const recombMatrix = inputMatrix.flat();
|
|
895
867
|
if (recombMatrix.length !== 9 && recombMatrix.length !== 16) {
|
|
896
868
|
throw is.invalidParameterError('inputMatrix', 'cardinality of 9 or 16', recombMatrix.length);
|
|
897
869
|
}
|
|
870
|
+
if (!recombMatrix.every(is.number)) {
|
|
871
|
+
throw is.invalidParameterError('inputMatrix', 'array of numbers', recombMatrix);
|
|
872
|
+
}
|
|
898
873
|
this.options.recombMatrix = recombMatrix;
|
|
899
874
|
return this;
|
|
900
875
|
}
|