sharp 0.33.0-alpha.9 → 0.33.0-rc.2

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/lib/resize.js CHANGED
@@ -494,70 +494,67 @@ function extract (options) {
494
494
  *
495
495
  * If the result of this operation would trim an image to nothing then no change is made.
496
496
  *
497
- * The `info` response Object, obtained from callback of `.toFile()` or `.toBuffer()`,
498
- * will contain `trimOffsetLeft` and `trimOffsetTop` properties.
497
+ * The `info` response Object will contain `trimOffsetLeft` and `trimOffsetTop` properties.
499
498
  *
500
499
  * @example
501
500
  * // Trim pixels with a colour similar to that of the top-left pixel.
502
- * sharp(input)
501
+ * await sharp(input)
503
502
  * .trim()
504
- * .toFile(output, function(err, info) {
505
- * ...
506
- * });
503
+ * .toFile(output);
504
+ *
507
505
  * @example
508
506
  * // Trim pixels with the exact same colour as that of the top-left pixel.
509
- * sharp(input)
510
- * .trim(0)
511
- * .toFile(output, function(err, info) {
512
- * ...
513
- * });
507
+ * await sharp(input)
508
+ * .trim({
509
+ * threshold: 0
510
+ * })
511
+ * .toFile(output);
512
+ *
514
513
  * @example
515
- * // Trim only pixels with a similar colour to red.
516
- * sharp(input)
517
- * .trim("#FF0000")
518
- * .toFile(output, function(err, info) {
519
- * ...
520
- * });
514
+ * // Assume input is line art and trim only pixels with a similar colour to red.
515
+ * const output = await sharp(input)
516
+ * .trim({
517
+ * background: "#FF0000",
518
+ * lineArt: true
519
+ * })
520
+ * .toBuffer();
521
+ *
521
522
  * @example
522
523
  * // Trim all "yellow-ish" pixels, being more lenient with the higher threshold.
523
- * sharp(input)
524
+ * const output = await sharp(input)
524
525
  * .trim({
525
526
  * background: "yellow",
526
527
  * threshold: 42,
527
528
  * })
528
- * .toFile(output, function(err, info) {
529
- * ...
530
- * });
529
+ * .toBuffer();
531
530
  *
532
- * @param {string|number|Object} trim - the specific background colour to trim, the threshold for doing so or an Object with both.
533
- * @param {string|Object} [trim.background='top-left pixel'] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel.
534
- * @param {number} [trim.threshold=10] - the allowed difference from the above colour, a positive number.
531
+ * @param {Object} [options]
532
+ * @param {string|Object} [options.background='top-left pixel'] - Background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel.
533
+ * @param {number} [options.threshold=10] - Allowed difference from the above colour, a positive number.
534
+ * @param {boolean} [options.lineArt=false] - Does the input more closely resemble line art (e.g. vector) rather than being photographic?
535
535
  * @returns {Sharp}
536
536
  * @throws {Error} Invalid parameters
537
537
  */
538
- function trim (trim) {
539
- if (!is.defined(trim)) {
540
- this.options.trimThreshold = 10;
541
- } else if (is.string(trim)) {
542
- this._setBackgroundColourOption('trimBackground', trim);
543
- this.options.trimThreshold = 10;
544
- } else if (is.number(trim)) {
545
- if (trim >= 0) {
546
- this.options.trimThreshold = trim;
547
- } else {
548
- throw is.invalidParameterError('threshold', 'positive number', trim);
549
- }
550
- } else if (is.object(trim)) {
551
- this._setBackgroundColourOption('trimBackground', trim.background);
552
- if (!is.defined(trim.threshold)) {
553
- this.options.trimThreshold = 10;
554
- } else if (is.number(trim.threshold) && trim.threshold >= 0) {
555
- this.options.trimThreshold = trim.threshold;
538
+ function trim (options) {
539
+ this.options.trimThreshold = 10;
540
+ if (is.defined(options)) {
541
+ if (is.object(options)) {
542
+ if (is.defined(options.background)) {
543
+ this._setBackgroundColourOption('trimBackground', options.background);
544
+ }
545
+ if (is.defined(options.threshold)) {
546
+ if (is.number(options.threshold) && options.threshold >= 0) {
547
+ this.options.trimThreshold = options.threshold;
548
+ } else {
549
+ throw is.invalidParameterError('threshold', 'positive number', options.threshold);
550
+ }
551
+ }
552
+ if (is.defined(options.lineArt)) {
553
+ this._setBooleanOption('trimLineArt', options.lineArt);
554
+ }
556
555
  } else {
557
- throw is.invalidParameterError('threshold', 'positive number', trim);
556
+ throw is.invalidParameterError('trim', 'object', options);
558
557
  }
559
- } else {
560
- throw is.invalidParameterError('trim', 'string, number or object', trim);
561
558
  }
562
559
  if (isRotationExpected(this.options)) {
563
560
  this.options.rotateBeforePreExtract = true;
package/lib/sharp.js CHANGED
@@ -9,61 +9,78 @@ const { familySync, versionSync } = require('detect-libc');
9
9
 
10
10
  const { runtimePlatformArch, prebuiltPlatforms, minimumLibvipsVersion } = require('./libvips');
11
11
  const runtimePlatform = runtimePlatformArch();
12
- const [isLinux, isMacOs, isWindows] = ['linux', 'darwin', 'win32'].map(os => runtimePlatform.startsWith(os));
13
12
 
14
- /* istanbul ignore next */
15
- try {
16
- // Check for local build
17
- module.exports = require(`../src/build/Release/sharp-${runtimePlatform}.node`);
18
- } catch (errLocal) {
13
+ const paths = [
14
+ `../src/build/Release/sharp-${runtimePlatform}.node`,
15
+ '../src/build/Release/sharp-wasm32.node',
16
+ `@img/sharp-${runtimePlatform}/sharp.node`,
17
+ '@img/sharp-wasm32/sharp.node'
18
+ ];
19
+
20
+ let sharp;
21
+ const errors = [];
22
+ for (const path of paths) {
19
23
  try {
20
- // Check for runtime package
21
- module.exports = require(`@img/sharp-${runtimePlatform}/sharp.node`);
22
- } catch (errPackage) {
23
- const help = ['Could not load the "sharp" module at runtime'];
24
- if (errLocal.code !== 'MODULE_NOT_FOUND') {
25
- help.push(`${errLocal.code}: ${errLocal.message}`);
26
- }
27
- if (errPackage.code !== 'MODULE_NOT_FOUND') {
28
- help.push(`${errPackage.code}: ${errPackage.message}`);
29
- }
30
- help.push('Possible solutions:');
31
- // Common error messages
32
- if (prebuiltPlatforms.includes(runtimePlatform)) {
33
- help.push('- Add an explicit dependency for the runtime platform:');
34
- help.push(` npm install --force @img/sharp-${runtimePlatform}`);
35
- } else {
36
- help.push(`- The ${runtimePlatform} platform requires manual installation of libvips >= ${minimumLibvipsVersion}`);
37
- }
38
- if (isLinux && /symbol not found/i.test(errPackage)) {
39
- try {
40
- const { engines } = require(`@img/sharp-libvips-${runtimePlatform}/package`);
41
- const libcFound = `${familySync()} ${versionSync()}`;
42
- const libcRequires = `${engines.musl ? 'musl' : 'glibc'} ${engines.musl || engines.glibc}`;
43
- help.push('- Update your OS:');
44
- help.push(` Found ${libcFound}`);
45
- help.push(` Requires ${libcRequires}`);
46
- } catch (errEngines) {}
47
- }
48
- if (isMacOs && /Incompatible library version/.test(errLocal.message)) {
49
- help.push('- Update Homebrew:');
50
- help.push(' brew update && brew upgrade vips');
51
- }
52
- if (errPackage.code === 'ERR_DLOPEN_DISABLED') {
53
- help.push('- Run Node.js without using the --no-addons flag');
54
- }
55
- if (process.versions.pnp) {
56
- help.push('- Use a supported yarn linker, either pnpm or node-modules:');
57
- help.push(' yarn config set nodeLinker node-modules');
58
- }
59
- // Link to installation docs
60
- if (isLinux && /Module did not self-register/.test(errLocal.message + errPackage.message)) {
61
- help.push('- Using worker threads on Linux? See https://sharp.pixelplumbing.com/install#worker-threads');
62
- } else if (isWindows && /The specified procedure could not be found/.test(errPackage.message)) {
63
- help.push('- Using the canvas package on Windows? See https://sharp.pixelplumbing.com/install#canvas-and-windows');
64
- } else {
65
- help.push('- Consult the installation documentation: https://sharp.pixelplumbing.com/install');
24
+ sharp = require(path);
25
+ break;
26
+ } catch (err) {
27
+ /* istanbul ignore next */
28
+ errors.push(err);
29
+ }
30
+ }
31
+
32
+ /* istanbul ignore next */
33
+ if (sharp) {
34
+ module.exports = sharp;
35
+ } else {
36
+ const [isLinux, isMacOs, isWindows] = ['linux', 'darwin', 'win32'].map(os => runtimePlatform.startsWith(os));
37
+
38
+ const help = [`Could not load the "sharp" module using the ${runtimePlatform} runtime`];
39
+ errors.forEach(err => {
40
+ if (err.code !== 'MODULE_NOT_FOUND') {
41
+ help.push(`${err.code}: ${err.message}`);
66
42
  }
67
- throw new Error(help.join('\n'));
43
+ });
44
+ const messages = errors.map(err => err.message).join(' ');
45
+ help.push('Possible solutions:');
46
+ // Common error messages
47
+ if (prebuiltPlatforms.includes(runtimePlatform)) {
48
+ const [os, cpu] = runtimePlatform.split('-');
49
+ help.push('- Add platform-specific dependencies:');
50
+ help.push(` npm install --os=${os} --cpu=${cpu} sharp`);
51
+ help.push(' or');
52
+ help.push(` npm install --force @img/sharp-${runtimePlatform}`);
53
+ } else {
54
+ help.push(`- Manually install libvips >= ${minimumLibvipsVersion}`);
55
+ help.push('- Add experimental WebAssembly-based dependencies:');
56
+ help.push(' npm install --cpu=wasm32 sharp');
57
+ }
58
+ if (isLinux && /symbol not found/i.test(messages)) {
59
+ try {
60
+ const { engines } = require(`@img/sharp-libvips-${runtimePlatform}/package`);
61
+ const libcFound = `${familySync()} ${versionSync()}`;
62
+ const libcRequires = `${engines.musl ? 'musl' : 'glibc'} ${engines.musl || engines.glibc}`;
63
+ help.push('- Update your OS:');
64
+ help.push(` Found ${libcFound}`);
65
+ help.push(` Requires ${libcRequires}`);
66
+ } catch (errEngines) {}
67
+ }
68
+ if (isMacOs && /Incompatible library version/.test(messages)) {
69
+ help.push('- Update Homebrew:');
70
+ help.push(' brew update && brew upgrade vips');
71
+ }
72
+ if (errors.some(err => err.code === 'ERR_DLOPEN_DISABLED')) {
73
+ help.push('- Run Node.js without using the --no-addons flag');
74
+ }
75
+ if (process.versions.pnp) {
76
+ help.push('- Use a supported yarn linker, either pnpm or node-modules:');
77
+ help.push(' yarn config set nodeLinker node-modules');
78
+ }
79
+ // Link to installation docs
80
+ if (isWindows && /The specified procedure could not be found/.test(messages)) {
81
+ help.push('- Using the canvas package on Windows? See https://sharp.pixelplumbing.com/install#canvas-and-windows');
82
+ } else {
83
+ help.push('- Consult the installation documentation: https://sharp.pixelplumbing.com/install');
68
84
  }
85
+ throw new Error(help.join('\n'));
69
86
  }
package/lib/utility.js CHANGED
@@ -59,11 +59,17 @@ let versions = {
59
59
  };
60
60
  /* istanbul ignore next */
61
61
  if (!libvipsVersion.isGlobal) {
62
- try {
63
- versions = require(`@img/sharp-${runtimePlatform}/versions`);
64
- } catch (_) {
62
+ if (!libvipsVersion.isWasm) {
65
63
  try {
66
- versions = require(`@img/sharp-libvips-${runtimePlatform}/versions`);
64
+ versions = require(`@img/sharp-${runtimePlatform}/versions`);
65
+ } catch (_) {
66
+ try {
67
+ versions = require(`@img/sharp-libvips-${runtimePlatform}/versions`);
68
+ } catch (_) {}
69
+ }
70
+ } else {
71
+ try {
72
+ versions = require('@img/sharp-wasm32/versions');
67
73
  } catch (_) {}
68
74
  }
69
75
  }
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, GIF, AVIF and TIFF images",
4
- "version": "0.33.0-alpha.9",
4
+ "version": "0.33.0-rc.2",
5
5
  "author": "Lovell Fuller <npm@lovell.info>",
6
6
  "homepage": "https://github.com/lovell/sharp",
7
7
  "contributors": [
@@ -86,7 +86,9 @@
86
86
  "Ankur Parihar <ankur.github@gmail.com>",
87
87
  "Brahim Ait elhaj <brahima@gmail.com>",
88
88
  "Mart Jansink <m.jansink@gmail.com>",
89
- "Lachlan Newman <lachnewman007@gmail.com>"
89
+ "Lachlan Newman <lachnewman007@gmail.com>",
90
+ "Dennis Beatty <dennis@dcbeatty.com>",
91
+ "Ingvar Stepanyan <me@rreverser.com>"
90
92
  ],
91
93
  "scripts": {
92
94
  "install": "node install/check",
@@ -139,30 +141,36 @@
139
141
  "semver": "^7.5.4"
140
142
  },
141
143
  "optionalDependencies": {
142
- "@img/sharp-darwin-arm64": "0.33.0-alpha.9",
143
- "@img/sharp-darwin-x64": "0.33.0-alpha.9",
144
- "@img/sharp-libvips-darwin-arm64": "0.0.1",
145
- "@img/sharp-libvips-darwin-x64": "0.0.1",
146
- "@img/sharp-libvips-linux-arm": "0.0.1",
147
- "@img/sharp-libvips-linux-arm64": "0.0.1",
148
- "@img/sharp-libvips-linux-x64": "0.0.1",
149
- "@img/sharp-libvips-linuxmusl-arm64": "0.0.1",
150
- "@img/sharp-libvips-linuxmusl-x64": "0.0.1",
151
- "@img/sharp-linux-arm": "0.33.0-alpha.9",
152
- "@img/sharp-linux-arm64": "0.33.0-alpha.9",
153
- "@img/sharp-linux-x64": "0.33.0-alpha.9",
154
- "@img/sharp-linuxmusl-arm64": "0.33.0-alpha.9",
155
- "@img/sharp-linuxmusl-x64": "0.33.0-alpha.9",
156
- "@img/sharp-win32-ia32": "0.33.0-alpha.9",
157
- "@img/sharp-win32-x64": "0.33.0-alpha.9"
144
+ "@img/sharp-darwin-arm64": "0.33.0-rc.2",
145
+ "@img/sharp-darwin-x64": "0.33.0-rc.2",
146
+ "@img/sharp-libvips-darwin-arm64": "1.0.0",
147
+ "@img/sharp-libvips-darwin-x64": "1.0.0",
148
+ "@img/sharp-libvips-linux-arm": "1.0.0",
149
+ "@img/sharp-libvips-linux-arm64": "1.0.0",
150
+ "@img/sharp-libvips-linux-s390x": "1.0.0",
151
+ "@img/sharp-libvips-linux-x64": "1.0.0",
152
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.0",
153
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.0",
154
+ "@img/sharp-linux-arm": "0.33.0-rc.2",
155
+ "@img/sharp-linux-arm64": "0.33.0-rc.2",
156
+ "@img/sharp-linux-s390x": "0.33.0-rc.2",
157
+ "@img/sharp-linux-x64": "0.33.0-rc.2",
158
+ "@img/sharp-linuxmusl-arm64": "0.33.0-rc.2",
159
+ "@img/sharp-linuxmusl-x64": "0.33.0-rc.2",
160
+ "@img/sharp-wasm32": "0.33.0-rc.2",
161
+ "@img/sharp-win32-ia32": "0.33.0-rc.2",
162
+ "@img/sharp-win32-x64": "0.33.0-rc.2"
158
163
  },
159
164
  "devDependencies": {
160
- "@img/sharp-libvips-dev": "0.0.1",
161
- "@img/sharp-libvips-win32-ia32": "0.0.1",
162
- "@img/sharp-libvips-win32-x64": "0.0.1",
165
+ "@emnapi/runtime": "^0.44.0",
166
+ "@img/sharp-libvips-dev": "1.0.0",
167
+ "@img/sharp-libvips-dev-wasm32": "1.0.0",
168
+ "@img/sharp-libvips-win32-ia32": "1.0.0",
169
+ "@img/sharp-libvips-win32-x64": "1.0.0",
163
170
  "@types/node": "*",
164
- "async": "^3.2.4",
171
+ "async": "^3.2.5",
165
172
  "cc": "^3.0.1",
173
+ "emnapi": "^0.44.0",
166
174
  "exif-reader": "^2.0.0",
167
175
  "extract-zip": "^2.0.1",
168
176
  "icc": "^3.0.0",
@@ -179,7 +187,7 @@
179
187
  "license": "Apache-2.0",
180
188
  "engines": {
181
189
  "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
182
- "libvips": ">=8.14.5"
190
+ "libvips": ">=8.15.0"
183
191
  },
184
192
  "funding": {
185
193
  "url": "https://opencollective.com/libvips"
@@ -200,6 +208,11 @@
200
208
  "build/include"
201
209
  ]
202
210
  },
211
+ "nyc": {
212
+ "include": [
213
+ "lib"
214
+ ]
215
+ },
203
216
  "tsd": {
204
217
  "directory": "test/types/"
205
218
  }
package/src/binding.gyp CHANGED
@@ -5,6 +5,7 @@
5
5
  'variables': {
6
6
  'vips_version': '<!(node -p "require(\'../lib/libvips\').minimumLibvipsVersion")',
7
7
  'platform_and_arch': '<!(node -p "require(\'../lib/libvips\').buildPlatformArch()")',
8
+ 'sharp_libvips_version': '<!(node -p "require(\'../package.json\').optionalDependencies[\'@img/sharp-libvips-<(platform_and_arch)\']")',
8
9
  'sharp_libvips_include_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsIncludeDir()")',
9
10
  'sharp_libvips_cplusplus_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsCPlusPlusDir()")',
10
11
  'sharp_libvips_lib_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsLibDir()")'
@@ -32,11 +33,11 @@
32
33
  '<(sharp_libvips_lib_dir)/glib-2.0/include'
33
34
  ],
34
35
  'link_settings': {
35
- 'library_dirs': ['<(sharp_libvips_lib_dir)'],
36
+ 'library_dirs': [
37
+ '<(sharp_libvips_lib_dir)'
38
+ ],
36
39
  'libraries': [
37
- 'libvips.lib',
38
- 'libglib-2.0.lib',
39
- 'libgobject-2.0.lib'
40
+ 'libvips.lib'
40
41
  ],
41
42
  },
42
43
  'configurations': {
@@ -129,6 +130,9 @@
129
130
  '<(sharp_libvips_include_dir)/glib-2.0',
130
131
  '<(sharp_libvips_lib_dir)/glib-2.0/include'
131
132
  ],
133
+ 'library_dirs': [
134
+ '<(sharp_libvips_lib_dir)'
135
+ ],
132
136
  'conditions': [
133
137
  ['OS == "win"', {
134
138
  'defines': [
@@ -136,19 +140,13 @@
136
140
  '_FILE_OFFSET_BITS=64'
137
141
  ],
138
142
  'link_settings': {
139
- 'library_dirs': ['<(sharp_libvips_lib_dir)'],
140
143
  'libraries': [
141
- 'libvips.lib',
142
- 'libglib-2.0.lib',
143
- 'libgobject-2.0.lib'
144
+ 'libvips.lib'
144
145
  ]
145
146
  }
146
147
  }],
147
148
  ['OS == "mac"', {
148
149
  'link_settings': {
149
- 'library_dirs': [
150
- '<(sharp_libvips_lib_dir)'
151
- ],
152
150
  'libraries': [
153
151
  'libvips-cpp.42.dylib'
154
152
  ]
@@ -157,6 +155,7 @@
157
155
  'OTHER_LDFLAGS': [
158
156
  # Ensure runtime linking is relative to sharp.node
159
157
  '-Wl,-rpath,\'@loader_path/../../sharp-libvips-<(platform_and_arch)/lib\'',
158
+ '-Wl,-rpath,\'@loader_path/../../../sharp-libvips-<(platform_and_arch)/<(sharp_libvips_version)/lib\'',
160
159
  '-Wl,-rpath,\'@loader_path/../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
161
160
  '-Wl,-rpath,\'@loader_path/../../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\''
162
161
  ]
@@ -167,21 +166,39 @@
167
166
  '_GLIBCXX_USE_CXX11_ABI=1'
168
167
  ],
169
168
  'link_settings': {
170
- 'library_dirs': [
171
- '<(sharp_libvips_lib_dir)'
172
- ],
173
169
  'libraries': [
174
170
  '-l:libvips-cpp.so.42'
175
171
  ],
176
172
  'ldflags': [
177
- # Ensure runtime linking is relative to sharp.node
178
173
  '-Wl,-s',
179
174
  '-Wl,--disable-new-dtags',
175
+ '-Wl,-z,nodelete',
180
176
  '-Wl,-rpath=\'$$ORIGIN/../../sharp-libvips-<(platform_and_arch)/lib\'',
177
+ '-Wl,-rpath=\'$$ORIGIN/../../../sharp-libvips-<(platform_and_arch)/<(sharp_libvips_version)/lib\'',
181
178
  '-Wl,-rpath=\'$$ORIGIN/../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
182
179
  '-Wl,-rpath=\'$$ORIGIN/../../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\''
183
180
  ]
184
181
  }
182
+ }],
183
+ ['OS == "emscripten"', {
184
+ 'product_extension': 'node.js',
185
+ 'link_settings': {
186
+ 'ldflags': [
187
+ '-fexceptions',
188
+ '--pre-js=<!(node -p "require.resolve(\'./emscripten/pre.js\')")',
189
+ '-Oz',
190
+ '-sALLOW_MEMORY_GROWTH',
191
+ '-sENVIRONMENT=node',
192
+ '-sEXPORTED_FUNCTIONS=["_vips_shutdown", "_uv_library_shutdown"]',
193
+ '-sNODERAWFS',
194
+ '-sTEXTDECODER=0',
195
+ '-sWASM_ASYNC_COMPILATION=0',
196
+ '-sWASM_BIGINT'
197
+ ],
198
+ 'libraries': [
199
+ '<!@(PKG_CONFIG_PATH="<!(node -p "require(\'@img/sharp-libvips-dev-wasm32/lib\')")/pkgconfig" pkg-config --static --libs vips-cpp)'
200
+ ],
201
+ }
185
202
  }]
186
203
  ]
187
204
  }]
@@ -206,11 +223,6 @@
206
223
  'configurations': {
207
224
  'Release': {
208
225
  'conditions': [
209
- ['OS == "linux"', {
210
- 'cflags_cc': [
211
- '-Wno-cast-function-type'
212
- ]
213
- }],
214
226
  ['target_arch == "arm"', {
215
227
  'cflags_cc': [
216
228
  '-Wno-psabi'
@@ -256,9 +268,7 @@
256
268
  'copies': [{
257
269
  'destination': 'build/Release',
258
270
  'files': [
259
- '<(sharp_libvips_lib_dir)/libvips-42.dll',
260
- '<(sharp_libvips_lib_dir)/libglib-2.0-0.dll',
261
- '<(sharp_libvips_lib_dir)/libgobject-2.0-0.dll'
271
+ '<(sharp_libvips_lib_dir)/libvips-42.dll'
262
272
  ]
263
273
  }]
264
274
  }]
package/src/common.cc CHANGED
@@ -531,7 +531,33 @@ namespace sharp {
531
531
  Does this image have an embedded profile?
532
532
  */
533
533
  bool HasProfile(VImage image) {
534
- return (image.get_typeof(VIPS_META_ICC_NAME) != 0) ? TRUE : FALSE;
534
+ return image.get_typeof(VIPS_META_ICC_NAME) == VIPS_TYPE_BLOB;
535
+ }
536
+
537
+ /*
538
+ Get copy of embedded profile.
539
+ */
540
+ std::pair<char*, size_t> GetProfile(VImage image) {
541
+ std::pair<char*, size_t> icc(nullptr, 0);
542
+ if (HasProfile(image)) {
543
+ size_t length;
544
+ const void *data = image.get_blob(VIPS_META_ICC_NAME, &length);
545
+ icc.first = static_cast<char*>(g_malloc(length));
546
+ icc.second = length;
547
+ memcpy(icc.first, data, length);
548
+ }
549
+ return icc;
550
+ }
551
+
552
+ /*
553
+ Set embedded profile.
554
+ */
555
+ VImage SetProfile(VImage image, std::pair<char*, size_t> icc) {
556
+ if (icc.first != nullptr) {
557
+ image = image.copy();
558
+ image.set(VIPS_META_ICC_NAME, reinterpret_cast<VipsCallbackFn>(vips_area_free_cb), icc.first, icc.second);
559
+ }
560
+ return image;
535
561
  }
536
562
 
537
563
  /*
@@ -542,6 +568,27 @@ namespace sharp {
542
568
  return image.has_alpha();
543
569
  }
544
570
 
571
+ static void* RemoveExifCallback(VipsImage *image, char const *field, GValue *value, void *data) {
572
+ std::vector<std::string> *fieldNames = static_cast<std::vector<std::string> *>(data);
573
+ std::string fieldName(field);
574
+ if (fieldName.substr(0, 8) == ("exif-ifd")) {
575
+ fieldNames->push_back(fieldName);
576
+ }
577
+ return nullptr;
578
+ }
579
+
580
+ /*
581
+ Remove all EXIF-related image fields.
582
+ */
583
+ VImage RemoveExif(VImage image) {
584
+ std::vector<std::string> fieldNames;
585
+ vips_image_map(image.get_image(), static_cast<VipsImageMapFn>(RemoveExifCallback), &fieldNames);
586
+ for (const auto& f : fieldNames) {
587
+ image.remove(f.data());
588
+ }
589
+ return image;
590
+ }
591
+
545
592
  /*
546
593
  Get EXIF Orientation of image, if any.
547
594
  */
package/src/common.h CHANGED
@@ -15,9 +15,9 @@
15
15
  // Verify platform and compiler compatibility
16
16
 
17
17
  #if (VIPS_MAJOR_VERSION < 8) || \
18
- (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 14) || \
19
- (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 14 && VIPS_MICRO_VERSION < 5)
20
- #error "libvips version 8.14.5+ is required - please see https://sharp.pixelplumbing.com/install"
18
+ (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 15) || \
19
+ (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 15 && VIPS_MICRO_VERSION < 0)
20
+ #error "libvips version 8.15.0+ is required - please see https://sharp.pixelplumbing.com/install"
21
21
  #endif
22
22
 
23
23
  #if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
@@ -222,12 +222,27 @@ namespace sharp {
222
222
  */
223
223
  bool HasProfile(VImage image);
224
224
 
225
+ /*
226
+ Get copy of embedded profile.
227
+ */
228
+ std::pair<char*, size_t> GetProfile(VImage image);
229
+
230
+ /*
231
+ Set embedded profile.
232
+ */
233
+ VImage SetProfile(VImage image, std::pair<char*, size_t> icc);
234
+
225
235
  /*
226
236
  Does this image have an alpha channel?
227
237
  Uses colour space interpretation with number of channels to guess this.
228
238
  */
229
239
  bool HasAlpha(VImage image);
230
240
 
241
+ /*
242
+ Remove all EXIF-related image fields.
243
+ */
244
+ VImage RemoveExif(VImage image);
245
+
231
246
  /*
232
247
  Get EXIF Orientation of image, if any.
233
248
  */
package/src/metadata.cc CHANGED
@@ -145,7 +145,7 @@ class MetadataWorker : public Napi::AsyncWorker {
145
145
  // Handle warnings
146
146
  std::string warning = sharp::VipsWarningPop();
147
147
  while (!warning.empty()) {
148
- debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
148
+ debuglog.Call(Receiver().Value(), { Napi::String::New(env, warning) });
149
149
  warning = sharp::VipsWarningPop();
150
150
  }
151
151
 
@@ -246,9 +246,9 @@ class MetadataWorker : public Napi::AsyncWorker {
246
246
  Napi::Buffer<char>::NewOrCopy(env, baton->tifftagPhotoshop,
247
247
  baton->tifftagPhotoshopLength, sharp::FreeCallback));
248
248
  }
249
- Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
249
+ Callback().Call(Receiver().Value(), { env.Null(), info });
250
250
  } else {
251
- Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
251
+ Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
252
252
  }
253
253
 
254
254
  delete baton->input;