@revizly/sharp 0.34.1-revizly9 → 0.34.4-revizly10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/install/check.js +2 -4
- package/lib/channel.js +2 -2
- package/lib/colour.js +1 -3
- package/lib/composite.js +0 -2
- package/lib/constructor.js +20 -9
- package/lib/index.d.ts +116 -21
- package/lib/index.js +0 -2
- package/lib/input.js +117 -31
- package/lib/is.js +0 -2
- package/lib/libvips.js +22 -22
- package/lib/operation.js +0 -2
- package/lib/output.js +67 -4
- package/lib/resize.js +10 -7
- package/lib/sharp.js +3 -6
- package/lib/utility.js +6 -14
- package/package.json +28 -48
- package/src/binding.gyp +8 -4
- package/src/common.cc +84 -73
- package/src/common.h +23 -23
- package/src/metadata.cc +9 -3
- package/src/metadata.h +1 -0
- package/src/operations.cc +2 -2
- package/src/operations.h +1 -0
- package/src/pipeline.cc +64 -73
- package/src/pipeline.h +6 -2
- package/src/sharp.cc +6 -6
- package/src/stats.cc +5 -4
- package/src/stats.h +2 -1
- package/src/utilities.cc +5 -5
package/lib/utility.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Copyright 2013 Lovell Fuller and others.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
'use strict';
|
|
5
|
-
|
|
6
4
|
const events = require('node:events');
|
|
7
5
|
const detectLibc = require('detect-libc');
|
|
8
6
|
|
|
@@ -57,7 +55,7 @@ const interpolators = {
|
|
|
57
55
|
let versions = {
|
|
58
56
|
vips: libvipsVersion.semver
|
|
59
57
|
};
|
|
60
|
-
/*
|
|
58
|
+
/* node:coverage ignore next 15 */
|
|
61
59
|
if (!libvipsVersion.isGlobal) {
|
|
62
60
|
if (!libvipsVersion.isWasm) {
|
|
63
61
|
try {
|
|
@@ -75,7 +73,7 @@ if (!libvipsVersion.isGlobal) {
|
|
|
75
73
|
}
|
|
76
74
|
versions.sharp = require('../package.json').version;
|
|
77
75
|
|
|
78
|
-
/*
|
|
76
|
+
/* node:coverage ignore next 5 */
|
|
79
77
|
if (versions.heif && format.heif) {
|
|
80
78
|
// Prebuilt binaries provide AV1
|
|
81
79
|
format.heif.input.fileSuffix = ['.avif'];
|
|
@@ -135,15 +133,9 @@ cache(true);
|
|
|
135
133
|
* e.g. libaom manages its own 4 threads when encoding AVIF images,
|
|
136
134
|
* and these are independent of the value set here.
|
|
137
135
|
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* https://nodejs.org/api/cli.html#uv_threadpool_sizesize
|
|
143
|
-
*
|
|
144
|
-
* For example, by default, a machine with 8 CPU cores will process
|
|
145
|
-
* 4 images in parallel and use up to 8 threads per image,
|
|
146
|
-
* so there will be up to 32 concurrent threads.
|
|
136
|
+
* :::note
|
|
137
|
+
* Further {@link /performance|control over performance} is available.
|
|
138
|
+
* :::
|
|
147
139
|
*
|
|
148
140
|
* @example
|
|
149
141
|
* const threads = sharp.concurrency(); // 4
|
|
@@ -156,7 +148,7 @@ cache(true);
|
|
|
156
148
|
function concurrency (concurrency) {
|
|
157
149
|
return sharp.concurrency(is.integer(concurrency) ? concurrency : null);
|
|
158
150
|
}
|
|
159
|
-
/*
|
|
151
|
+
/* node:coverage ignore next 7 */
|
|
160
152
|
if (detectLibc.familySync() === detectLibc.GLIBC && !sharp._isUsingJemalloc()) {
|
|
161
153
|
// Reduce default concurrency to 1 when using glibc memory allocator
|
|
162
154
|
sharp.concurrency(1);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revizly/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.34.
|
|
4
|
+
"version": "0.34.4-revizly10",
|
|
5
5
|
"author": "Lovell Fuller <npm@lovell.info>",
|
|
6
6
|
"homepage": "https://sharp.pixelplumbing.com",
|
|
7
7
|
"contributors": [
|
|
@@ -92,16 +92,17 @@
|
|
|
92
92
|
"Don Denton <don@happycollision.com>"
|
|
93
93
|
],
|
|
94
94
|
"scripts": {
|
|
95
|
-
"install": "node install/check",
|
|
95
|
+
"install": "node install/check.js",
|
|
96
96
|
"clean": "rm -rf src/build/ .nyc_output/ coverage/ test/fixtures/output.*",
|
|
97
|
-
"test": "npm run
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
"
|
|
97
|
+
"test": "npm run lint && npm run test-unit",
|
|
98
|
+
"lint": "npm run lint-cpp && npm run lint-js && npm run lint-types",
|
|
99
|
+
"lint-cpp": "cpplint --quiet src/*.h src/*.cc",
|
|
100
|
+
"lint-js": "biome lint",
|
|
101
|
+
"lint-types": "tsd --files ./test/types/sharp.test-d.ts",
|
|
101
102
|
"test-leak": "./test/leak/leak.sh",
|
|
102
|
-
"test-
|
|
103
|
-
"package-from-local-build": "node npm/from-local-build",
|
|
104
|
-
"package-
|
|
103
|
+
"test-unit": "node --experimental-test-coverage test/unit.mjs",
|
|
104
|
+
"package-from-local-build": "node npm/from-local-build.js",
|
|
105
|
+
"package-release-notes": "node npm/release-notes.js",
|
|
105
106
|
"docs-build": "node docs/build.mjs",
|
|
106
107
|
"docs-serve": "cd docs && npm start",
|
|
107
108
|
"docs-publish": "cd docs && npm run build && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
|
|
@@ -137,67 +138,46 @@
|
|
|
137
138
|
"vips"
|
|
138
139
|
],
|
|
139
140
|
"dependencies": {
|
|
140
|
-
"
|
|
141
|
-
"detect-libc": "^2.0
|
|
142
|
-
"semver": "^7.7.
|
|
141
|
+
"@img/colour": "^1.0.0",
|
|
142
|
+
"detect-libc": "^2.1.0",
|
|
143
|
+
"semver": "^7.7.2"
|
|
143
144
|
},
|
|
144
145
|
"optionalDependencies": {
|
|
145
|
-
"@revizly/sharp-libvips-linux-arm64": "1.0.
|
|
146
|
-
"@revizly/sharp-libvips-linux-x64": "1.0.
|
|
147
|
-
"@revizly/sharp-linux-arm64": "0.34.
|
|
148
|
-
"@revizly/sharp-linux-x64": "0.34.
|
|
146
|
+
"@revizly/sharp-libvips-linux-arm64": "1.0.23",
|
|
147
|
+
"@revizly/sharp-libvips-linux-x64": "1.0.23",
|
|
148
|
+
"@revizly/sharp-linux-arm64": "0.34.4-revizly8",
|
|
149
|
+
"@revizly/sharp-linux-x64": "0.34.4-revizly8"
|
|
149
150
|
},
|
|
150
151
|
"devDependencies": {
|
|
151
|
-
"@
|
|
152
|
-
"@
|
|
152
|
+
"@biomejs/biome": "^2.2.4",
|
|
153
|
+
"@cpplint/cli": "^0.1.0",
|
|
154
|
+
"@emnapi/runtime": "^1.5.0",
|
|
155
|
+
"@revizly/sharp-libvips-dev": "1.0.23",
|
|
153
156
|
"@types/node": "*",
|
|
154
|
-
"
|
|
155
|
-
"emnapi": "^1.4.0",
|
|
157
|
+
"emnapi": "^1.5.0",
|
|
156
158
|
"exif-reader": "^2.0.2",
|
|
157
159
|
"extract-zip": "^2.0.1",
|
|
158
160
|
"icc": "^3.0.0",
|
|
159
|
-
"jsdoc-to-markdown": "^9.1.
|
|
160
|
-
"
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"prebuild": "^13.0.1",
|
|
165
|
-
"semistandard": "^17.0.0",
|
|
166
|
-
"tar-fs": "^3.0.8",
|
|
167
|
-
"tsd": "^0.31.2"
|
|
161
|
+
"jsdoc-to-markdown": "^9.1.2",
|
|
162
|
+
"node-addon-api": "^8.5.0",
|
|
163
|
+
"node-gyp": "^11.4.2",
|
|
164
|
+
"tar-fs": "^3.1.1",
|
|
165
|
+
"tsd": "^0.33.0"
|
|
168
166
|
},
|
|
169
167
|
"license": "Apache-2.0",
|
|
170
168
|
"engines": {
|
|
171
169
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
|
172
170
|
},
|
|
173
171
|
"config": {
|
|
174
|
-
"libvips": ">=8.
|
|
172
|
+
"libvips": ">=8.17.2"
|
|
175
173
|
},
|
|
176
174
|
"funding": {
|
|
177
175
|
"url": "https://opencollective.com/libvips"
|
|
178
176
|
},
|
|
179
|
-
"binary": {
|
|
180
|
-
"napi_versions": [
|
|
181
|
-
9
|
|
182
|
-
]
|
|
183
|
-
},
|
|
184
|
-
"semistandard": {
|
|
185
|
-
"env": [
|
|
186
|
-
"mocha"
|
|
187
|
-
]
|
|
188
|
-
},
|
|
189
177
|
"cc": {
|
|
190
178
|
"linelength": "120",
|
|
191
179
|
"filter": [
|
|
192
180
|
"build/include"
|
|
193
181
|
]
|
|
194
|
-
},
|
|
195
|
-
"nyc": {
|
|
196
|
-
"include": [
|
|
197
|
-
"lib"
|
|
198
|
-
]
|
|
199
|
-
},
|
|
200
|
-
"tsd": {
|
|
201
|
-
"directory": "test/types/"
|
|
202
182
|
}
|
|
203
183
|
}
|
package/src/binding.gyp
CHANGED
|
@@ -163,9 +163,12 @@
|
|
|
163
163
|
},
|
|
164
164
|
'xcode_settings': {
|
|
165
165
|
'OTHER_LDFLAGS': [
|
|
166
|
+
'-Wl,-s',
|
|
167
|
+
'-Wl,-dead_strip',
|
|
166
168
|
# Ensure runtime linking is relative to sharp.node
|
|
167
169
|
'-Wl,-rpath,\'@loader_path/../../sharp-libvips-<(platform_and_arch)/lib\'',
|
|
168
170
|
'-Wl,-rpath,\'@loader_path/../../../sharp-libvips-<(platform_and_arch)/<(sharp_libvips_version)/lib\'',
|
|
171
|
+
'-Wl,-rpath,\'@loader_path/../node_modules/@revizly/sharp-libvips-<(platform_and_arch)/lib\'',
|
|
169
172
|
'-Wl,-rpath,\'@loader_path/../../node_modules/@revizly/sharp-libvips-<(platform_and_arch)/lib\'',
|
|
170
173
|
'-Wl,-rpath,\'@loader_path/../../../node_modules/@revizly/sharp-libvips-<(platform_and_arch)/lib\'',
|
|
171
174
|
'-Wl,-rpath,\'@loader_path/../../../../../@revizly-sharp-libvips-<(platform_and_arch)-npm-<(sharp_libvips_version)-<(sharp_libvips_yarn_locator)/node_modules/@revizly/sharp-libvips-<(platform_and_arch)/lib\''
|
|
@@ -176,6 +179,9 @@
|
|
|
176
179
|
'defines': [
|
|
177
180
|
'_GLIBCXX_USE_CXX11_ABI=1'
|
|
178
181
|
],
|
|
182
|
+
'cflags_cc': [
|
|
183
|
+
'<!(node -p "require(\'detect-libc\').isNonGlibcLinuxSync() ? \'\' : \'-flto=auto\'")'
|
|
184
|
+
],
|
|
179
185
|
'link_settings': {
|
|
180
186
|
'libraries': [
|
|
181
187
|
'-l:libvips-cpp.so.<(vips_version)'
|
|
@@ -203,11 +209,9 @@
|
|
|
203
209
|
'-Oz',
|
|
204
210
|
'-sALLOW_MEMORY_GROWTH',
|
|
205
211
|
'-sENVIRONMENT=node',
|
|
206
|
-
'-sEXPORTED_FUNCTIONS=
|
|
212
|
+
'-sEXPORTED_FUNCTIONS=emnapiInit,_vips_shutdown,_uv_library_shutdown',
|
|
207
213
|
'-sNODERAWFS',
|
|
208
|
-
'-
|
|
209
|
-
'-sWASM_ASYNC_COMPILATION=0',
|
|
210
|
-
'-sWASM_BIGINT'
|
|
214
|
+
'-sWASM_ASYNC_COMPILATION=0'
|
|
211
215
|
],
|
|
212
216
|
'libraries': [
|
|
213
217
|
'<!@(PKG_CONFIG_PATH="<!(node -p "require(\'@revizly/sharp-libvips-dev-wasm32/lib\')")/pkgconfig" pkg-config --static --libs vips-cpp)'
|
package/src/common.cc
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
// Copyright 2013 Lovell Fuller and others.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
#include <algorithm>
|
|
4
5
|
#include <cstdlib>
|
|
6
|
+
#include <map>
|
|
7
|
+
#include <mutex>
|
|
8
|
+
#include <queue>
|
|
5
9
|
#include <string>
|
|
6
|
-
#include <
|
|
10
|
+
#include <tuple>
|
|
11
|
+
#include <utility>
|
|
7
12
|
#include <vector>
|
|
8
|
-
#include <queue>
|
|
9
|
-
#include <map>
|
|
10
|
-
#include <mutex> // NOLINT(build/c++11)
|
|
11
13
|
|
|
12
14
|
#include <napi.h>
|
|
13
15
|
#include <vips/vips8>
|
|
14
16
|
|
|
15
|
-
#include "common.h"
|
|
17
|
+
#include "./common.h"
|
|
16
18
|
|
|
17
19
|
using vips::VImage;
|
|
18
20
|
|
|
@@ -93,6 +95,7 @@ namespace sharp {
|
|
|
93
95
|
descriptor->rawWidth = AttrAsUint32(input, "rawWidth");
|
|
94
96
|
descriptor->rawHeight = AttrAsUint32(input, "rawHeight");
|
|
95
97
|
descriptor->rawPremultiplied = AttrAsBool(input, "rawPremultiplied");
|
|
98
|
+
descriptor->rawPageHeight = AttrAsUint32(input, "rawPageHeight");
|
|
96
99
|
}
|
|
97
100
|
// Multi-page input (GIF, TIFF, PDF)
|
|
98
101
|
if (HasAttr(input, "pages")) {
|
|
@@ -101,23 +104,35 @@ namespace sharp {
|
|
|
101
104
|
if (HasAttr(input, "page")) {
|
|
102
105
|
descriptor->page = AttrAsUint32(input, "page");
|
|
103
106
|
}
|
|
107
|
+
// SVG
|
|
108
|
+
if (HasAttr(input, "svgStylesheet")) {
|
|
109
|
+
descriptor->svgStylesheet = AttrAsStr(input, "svgStylesheet");
|
|
110
|
+
}
|
|
111
|
+
if (HasAttr(input, "svgHighBitdepth")) {
|
|
112
|
+
descriptor->svgHighBitdepth = AttrAsBool(input, "svgHighBitdepth");
|
|
113
|
+
}
|
|
104
114
|
// Multi-level input (OpenSlide)
|
|
105
|
-
if (HasAttr(input, "
|
|
106
|
-
descriptor->
|
|
115
|
+
if (HasAttr(input, "openSlideLevel")) {
|
|
116
|
+
descriptor->openSlideLevel = AttrAsUint32(input, "openSlideLevel");
|
|
107
117
|
}
|
|
108
118
|
// subIFD (OME-TIFF)
|
|
109
119
|
if (HasAttr(input, "subifd")) {
|
|
110
|
-
descriptor->
|
|
120
|
+
descriptor->tiffSubifd = AttrAsInt32(input, "tiffSubifd");
|
|
111
121
|
}
|
|
112
122
|
// // PDF background color
|
|
113
123
|
if (HasAttr(input, "pdfBackground")) {
|
|
114
124
|
descriptor->pdfBackground = AttrAsVectorOfDouble(input, "pdfBackground");
|
|
115
125
|
}
|
|
126
|
+
// Use JPEG 2000 oneshot mode?
|
|
127
|
+
if (HasAttr(input, "jp2Oneshot")) {
|
|
128
|
+
descriptor->jp2Oneshot = AttrAsBool(input, "jp2Oneshot");
|
|
129
|
+
}
|
|
116
130
|
// Create new image
|
|
117
131
|
if (HasAttr(input, "createChannels")) {
|
|
118
132
|
descriptor->createChannels = AttrAsUint32(input, "createChannels");
|
|
119
133
|
descriptor->createWidth = AttrAsUint32(input, "createWidth");
|
|
120
134
|
descriptor->createHeight = AttrAsUint32(input, "createHeight");
|
|
135
|
+
descriptor->createPageHeight = AttrAsUint32(input, "createPageHeight");
|
|
121
136
|
if (HasAttr(input, "createNoiseType")) {
|
|
122
137
|
descriptor->createNoiseType = AttrAsStr(input, "createNoiseType");
|
|
123
138
|
descriptor->createNoiseMean = AttrAsDouble(input, "createNoiseMean");
|
|
@@ -271,6 +286,7 @@ namespace sharp {
|
|
|
271
286
|
case ImageType::EXR: id = "exr"; break;
|
|
272
287
|
case ImageType::JXL: id = "jxl"; break;
|
|
273
288
|
case ImageType::RAD: id = "rad"; break;
|
|
289
|
+
case ImageType::DCRAW: id = "dcraw"; break;
|
|
274
290
|
case ImageType::VIPS: id = "vips"; break;
|
|
275
291
|
case ImageType::RAW: id = "raw"; break;
|
|
276
292
|
case ImageType::UNKNOWN: id = "unknown"; break;
|
|
@@ -319,6 +335,8 @@ namespace sharp {
|
|
|
319
335
|
{ "VipsForeignLoadJxlBuffer", ImageType::JXL },
|
|
320
336
|
{ "VipsForeignLoadRadFile", ImageType::RAD },
|
|
321
337
|
{ "VipsForeignLoadRadBuffer", ImageType::RAD },
|
|
338
|
+
{ "VipsForeignLoadDcRawFile", ImageType::DCRAW },
|
|
339
|
+
{ "VipsForeignLoadDcRawBuffer", ImageType::DCRAW },
|
|
322
340
|
{ "VipsForeignLoadVips", ImageType::VIPS },
|
|
323
341
|
{ "VipsForeignLoadVipsFile", ImageType::VIPS },
|
|
324
342
|
{ "VipsForeignLoadRaw", ImageType::RAW }
|
|
@@ -380,9 +398,52 @@ namespace sharp {
|
|
|
380
398
|
imageType == ImageType::JPEG ||
|
|
381
399
|
imageType == ImageType::PNG ||
|
|
382
400
|
imageType == ImageType::SVG ||
|
|
401
|
+
imageType == ImageType::TIFF ||
|
|
383
402
|
imageType == ImageType::HEIF;
|
|
384
403
|
}
|
|
385
404
|
|
|
405
|
+
/*
|
|
406
|
+
Format-specific options builder
|
|
407
|
+
*/
|
|
408
|
+
vips::VOption* GetOptionsForImageType(ImageType imageType, InputDescriptor *descriptor) {
|
|
409
|
+
vips::VOption *option = VImage::option()
|
|
410
|
+
->set("access", descriptor->access)
|
|
411
|
+
->set("fail_on", descriptor->failOn);
|
|
412
|
+
if (descriptor->unlimited && ImageTypeSupportsUnlimited(imageType)) {
|
|
413
|
+
option->set("unlimited", true);
|
|
414
|
+
}
|
|
415
|
+
if (ImageTypeSupportsPage(imageType)) {
|
|
416
|
+
option->set("n", descriptor->pages);
|
|
417
|
+
option->set("page", descriptor->page);
|
|
418
|
+
}
|
|
419
|
+
switch (imageType) {
|
|
420
|
+
case ImageType::SVG:
|
|
421
|
+
option->set("dpi", descriptor->density)
|
|
422
|
+
->set("stylesheet", descriptor->svgStylesheet.data())
|
|
423
|
+
->set("high_bitdepth", descriptor->svgHighBitdepth);
|
|
424
|
+
break;
|
|
425
|
+
case ImageType::TIFF:
|
|
426
|
+
option->set("subifd", descriptor->tiffSubifd);
|
|
427
|
+
break;
|
|
428
|
+
case ImageType::PDF:
|
|
429
|
+
option->set("dpi", descriptor->density)
|
|
430
|
+
->set("background", descriptor->pdfBackground);
|
|
431
|
+
break;
|
|
432
|
+
case ImageType::OPENSLIDE:
|
|
433
|
+
option->set("level", descriptor->openSlideLevel);
|
|
434
|
+
break;
|
|
435
|
+
case ImageType::JP2:
|
|
436
|
+
option->set("oneshot", descriptor->jp2Oneshot);
|
|
437
|
+
break;
|
|
438
|
+
case ImageType::MAGICK:
|
|
439
|
+
option->set("density", std::to_string(descriptor->density).data());
|
|
440
|
+
break;
|
|
441
|
+
default:
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
return option;
|
|
445
|
+
}
|
|
446
|
+
|
|
386
447
|
/*
|
|
387
448
|
Open an image from the given InputDescriptor (filesystem, compressed buffer, raw pixel data)
|
|
388
449
|
*/
|
|
@@ -400,6 +461,10 @@ namespace sharp {
|
|
|
400
461
|
} else {
|
|
401
462
|
image.get_image()->Type = is8bit ? VIPS_INTERPRETATION_sRGB : VIPS_INTERPRETATION_RGB16;
|
|
402
463
|
}
|
|
464
|
+
if (descriptor->rawPageHeight > 0) {
|
|
465
|
+
image.set(VIPS_META_PAGE_HEIGHT, descriptor->rawPageHeight);
|
|
466
|
+
image.set(VIPS_META_N_PAGES, static_cast<int>(descriptor->rawHeight / descriptor->rawPageHeight));
|
|
467
|
+
}
|
|
403
468
|
if (descriptor->rawPremultiplied) {
|
|
404
469
|
image = image.unpremultiply();
|
|
405
470
|
}
|
|
@@ -409,31 +474,7 @@ namespace sharp {
|
|
|
409
474
|
imageType = DetermineImageType(descriptor->buffer, descriptor->bufferLength);
|
|
410
475
|
if (imageType != ImageType::UNKNOWN) {
|
|
411
476
|
try {
|
|
412
|
-
vips::VOption *option =
|
|
413
|
-
->set("access", descriptor->access)
|
|
414
|
-
->set("fail_on", descriptor->failOn);
|
|
415
|
-
if (descriptor->unlimited && ImageTypeSupportsUnlimited(imageType)) {
|
|
416
|
-
option->set("unlimited", true);
|
|
417
|
-
}
|
|
418
|
-
if (imageType == ImageType::SVG || imageType == ImageType::PDF) {
|
|
419
|
-
option->set("dpi", descriptor->density);
|
|
420
|
-
}
|
|
421
|
-
if (imageType == ImageType::MAGICK) {
|
|
422
|
-
option->set("density", std::to_string(descriptor->density).data());
|
|
423
|
-
}
|
|
424
|
-
if (ImageTypeSupportsPage(imageType)) {
|
|
425
|
-
option->set("n", descriptor->pages);
|
|
426
|
-
option->set("page", descriptor->page);
|
|
427
|
-
}
|
|
428
|
-
if (imageType == ImageType::OPENSLIDE) {
|
|
429
|
-
option->set("level", descriptor->level);
|
|
430
|
-
}
|
|
431
|
-
if (imageType == ImageType::TIFF) {
|
|
432
|
-
option->set("subifd", descriptor->subifd);
|
|
433
|
-
}
|
|
434
|
-
if (imageType == ImageType::PDF) {
|
|
435
|
-
option->set("background", descriptor->pdfBackground);
|
|
436
|
-
}
|
|
477
|
+
vips::VOption *option = GetOptionsForImageType(imageType, descriptor);
|
|
437
478
|
image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);
|
|
438
479
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
|
439
480
|
image = SetDensity(image, descriptor->density);
|
|
@@ -473,6 +514,10 @@ namespace sharp {
|
|
|
473
514
|
channels < 3 ? VIPS_INTERPRETATION_B_W : VIPS_INTERPRETATION_sRGB))
|
|
474
515
|
.new_from_image(background);
|
|
475
516
|
}
|
|
517
|
+
if (descriptor->createPageHeight > 0) {
|
|
518
|
+
image.set(VIPS_META_PAGE_HEIGHT, descriptor->createPageHeight);
|
|
519
|
+
image.set(VIPS_META_N_PAGES, static_cast<int>(descriptor->createHeight / descriptor->createPageHeight));
|
|
520
|
+
}
|
|
476
521
|
image = image.cast(VIPS_FORMAT_UCHAR);
|
|
477
522
|
imageType = ImageType::RAW;
|
|
478
523
|
} else if (descriptor->textValue.length() > 0) {
|
|
@@ -516,31 +561,7 @@ namespace sharp {
|
|
|
516
561
|
}
|
|
517
562
|
if (imageType != ImageType::UNKNOWN) {
|
|
518
563
|
try {
|
|
519
|
-
vips::VOption *option =
|
|
520
|
-
->set("access", descriptor->access)
|
|
521
|
-
->set("fail_on", descriptor->failOn);
|
|
522
|
-
if (descriptor->unlimited && ImageTypeSupportsUnlimited(imageType)) {
|
|
523
|
-
option->set("unlimited", true);
|
|
524
|
-
}
|
|
525
|
-
if (imageType == ImageType::SVG || imageType == ImageType::PDF) {
|
|
526
|
-
option->set("dpi", descriptor->density);
|
|
527
|
-
}
|
|
528
|
-
if (imageType == ImageType::MAGICK) {
|
|
529
|
-
option->set("density", std::to_string(descriptor->density).data());
|
|
530
|
-
}
|
|
531
|
-
if (ImageTypeSupportsPage(imageType)) {
|
|
532
|
-
option->set("n", descriptor->pages);
|
|
533
|
-
option->set("page", descriptor->page);
|
|
534
|
-
}
|
|
535
|
-
if (imageType == ImageType::OPENSLIDE) {
|
|
536
|
-
option->set("level", descriptor->level);
|
|
537
|
-
}
|
|
538
|
-
if (imageType == ImageType::TIFF) {
|
|
539
|
-
option->set("subifd", descriptor->subifd);
|
|
540
|
-
}
|
|
541
|
-
if (imageType == ImageType::PDF) {
|
|
542
|
-
option->set("background", descriptor->pdfBackground);
|
|
543
|
-
}
|
|
564
|
+
vips::VOption *option = GetOptionsForImageType(imageType, descriptor);
|
|
544
565
|
image = VImage::new_from_file(descriptor->file.data(), option);
|
|
545
566
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
|
546
567
|
image = SetDensity(image, descriptor->density);
|
|
@@ -951,14 +972,6 @@ namespace sharp {
|
|
|
951
972
|
return interpretation == VIPS_INTERPRETATION_RGB16 || interpretation == VIPS_INTERPRETATION_GREY16;
|
|
952
973
|
}
|
|
953
974
|
|
|
954
|
-
/*
|
|
955
|
-
Return the image alpha maximum. Useful for combining alpha bands. scRGB
|
|
956
|
-
images are 0 - 1 for image data, but the alpha is 0 - 255.
|
|
957
|
-
*/
|
|
958
|
-
double MaximumImageAlpha(VipsInterpretation const interpretation) {
|
|
959
|
-
return Is16Bit(interpretation) ? 65535.0 : 255.0;
|
|
960
|
-
}
|
|
961
|
-
|
|
962
975
|
/*
|
|
963
976
|
Convert RGBA value to another colourspace
|
|
964
977
|
*/
|
|
@@ -1001,16 +1014,16 @@ namespace sharp {
|
|
|
1001
1014
|
0.0722 * colour[2])
|
|
1002
1015
|
};
|
|
1003
1016
|
}
|
|
1004
|
-
// Add alpha channel to alphaColour colour
|
|
1017
|
+
// Add alpha channel(s) to alphaColour colour
|
|
1005
1018
|
if (colour[3] < 255.0 || image.has_alpha()) {
|
|
1006
|
-
|
|
1019
|
+
int extraBands = image.bands() > 4 ? image.bands() - 3 : 1;
|
|
1020
|
+
alphaColour.insert(alphaColour.end(), extraBands, colour[3] * multiplier);
|
|
1007
1021
|
}
|
|
1008
1022
|
// Ensure alphaColour colour uses correct colourspace
|
|
1009
1023
|
alphaColour = sharp::GetRgbaAsColourspace(alphaColour, image.interpretation(), premultiply);
|
|
1010
1024
|
// Add non-transparent alpha channel, if required
|
|
1011
1025
|
if (colour[3] < 255.0 && !image.has_alpha()) {
|
|
1012
|
-
image = image.
|
|
1013
|
-
VImage::new_matrix(image.width(), image.height()).new_from_image(255 * multiplier).cast(image.format()));
|
|
1026
|
+
image = image.bandjoin_const({ 255 * multiplier });
|
|
1014
1027
|
}
|
|
1015
1028
|
return std::make_tuple(image, alphaColour);
|
|
1016
1029
|
}
|
|
@@ -1030,9 +1043,7 @@ namespace sharp {
|
|
|
1030
1043
|
*/
|
|
1031
1044
|
VImage EnsureAlpha(VImage image, double const value) {
|
|
1032
1045
|
if (!image.has_alpha()) {
|
|
1033
|
-
|
|
1034
|
-
alpha.push_back(value * sharp::MaximumImageAlpha(image.interpretation()));
|
|
1035
|
-
image = image.bandjoin_const(alpha);
|
|
1046
|
+
image = image.bandjoin_const({ value * vips_interpretation_max_alpha(image.interpretation()) });
|
|
1036
1047
|
}
|
|
1037
1048
|
return image;
|
|
1038
1049
|
}
|
package/src/common.h
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
#ifndef SRC_COMMON_H_
|
|
5
5
|
#define SRC_COMMON_H_
|
|
6
6
|
|
|
7
|
+
#include <atomic>
|
|
7
8
|
#include <string>
|
|
8
9
|
#include <tuple>
|
|
10
|
+
#include <utility>
|
|
9
11
|
#include <vector>
|
|
10
|
-
#include <atomic>
|
|
11
12
|
|
|
12
13
|
#include <napi.h>
|
|
13
14
|
#include <vips/vips8>
|
|
@@ -15,9 +16,9 @@
|
|
|
15
16
|
// Verify platform and compiler compatibility
|
|
16
17
|
|
|
17
18
|
#if (VIPS_MAJOR_VERSION < 8) || \
|
|
18
|
-
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION <
|
|
19
|
-
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION ==
|
|
20
|
-
#error "libvips version 8.
|
|
19
|
+
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 17) || \
|
|
20
|
+
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 17 && VIPS_MICRO_VERSION < 2)
|
|
21
|
+
#error "libvips version 8.17.2+ is required - please see https://sharp.pixelplumbing.com/install"
|
|
21
22
|
#endif
|
|
22
23
|
|
|
23
24
|
#if defined(__has_include)
|
|
@@ -30,7 +31,7 @@ using vips::VImage;
|
|
|
30
31
|
|
|
31
32
|
namespace sharp {
|
|
32
33
|
|
|
33
|
-
struct InputDescriptor {
|
|
34
|
+
struct InputDescriptor {
|
|
34
35
|
std::string name;
|
|
35
36
|
std::string file;
|
|
36
37
|
bool autoOrient;
|
|
@@ -48,13 +49,13 @@ namespace sharp {
|
|
|
48
49
|
int rawWidth;
|
|
49
50
|
int rawHeight;
|
|
50
51
|
bool rawPremultiplied;
|
|
52
|
+
int rawPageHeight;
|
|
51
53
|
int pages;
|
|
52
54
|
int page;
|
|
53
|
-
int level;
|
|
54
|
-
int subifd;
|
|
55
55
|
int createChannels;
|
|
56
56
|
int createWidth;
|
|
57
57
|
int createHeight;
|
|
58
|
+
int createPageHeight;
|
|
58
59
|
std::vector<double> createBackground;
|
|
59
60
|
std::string createNoiseType;
|
|
60
61
|
double createNoiseMean;
|
|
@@ -77,7 +78,12 @@ namespace sharp {
|
|
|
77
78
|
std::vector<double> joinBackground;
|
|
78
79
|
VipsAlign joinHalign;
|
|
79
80
|
VipsAlign joinValign;
|
|
81
|
+
std::string svgStylesheet;
|
|
82
|
+
bool svgHighBitdepth;
|
|
83
|
+
int tiffSubifd;
|
|
84
|
+
int openSlideLevel;
|
|
80
85
|
std::vector<double> pdfBackground;
|
|
86
|
+
bool jp2Oneshot;
|
|
81
87
|
|
|
82
88
|
InputDescriptor():
|
|
83
89
|
autoOrient(false),
|
|
@@ -95,13 +101,13 @@ namespace sharp {
|
|
|
95
101
|
rawWidth(0),
|
|
96
102
|
rawHeight(0),
|
|
97
103
|
rawPremultiplied(false),
|
|
104
|
+
rawPageHeight(0),
|
|
98
105
|
pages(1),
|
|
99
106
|
page(0),
|
|
100
|
-
level(0),
|
|
101
|
-
subifd(-1),
|
|
102
107
|
createChannels(0),
|
|
103
108
|
createWidth(0),
|
|
104
109
|
createHeight(0),
|
|
110
|
+
createPageHeight(0),
|
|
105
111
|
createBackground{ 0.0, 0.0, 0.0, 255.0 },
|
|
106
112
|
createNoiseMean(0.0),
|
|
107
113
|
createNoiseSigma(0.0),
|
|
@@ -120,7 +126,11 @@ namespace sharp {
|
|
|
120
126
|
joinBackground{ 0.0, 0.0, 0.0, 255.0 },
|
|
121
127
|
joinHalign(VIPS_ALIGN_LOW),
|
|
122
128
|
joinValign(VIPS_ALIGN_LOW),
|
|
123
|
-
|
|
129
|
+
svgHighBitdepth(false),
|
|
130
|
+
tiffSubifd(-1),
|
|
131
|
+
openSlideLevel(0),
|
|
132
|
+
pdfBackground{ 255.0, 255.0, 255.0, 255.0 },
|
|
133
|
+
jp2Oneshot(false) {}
|
|
124
134
|
};
|
|
125
135
|
|
|
126
136
|
// Convenience methods to access the attributes of a Napi::Object
|
|
@@ -160,6 +170,7 @@ namespace sharp {
|
|
|
160
170
|
EXR,
|
|
161
171
|
JXL,
|
|
162
172
|
RAD,
|
|
173
|
+
DCRAW,
|
|
163
174
|
VIPS,
|
|
164
175
|
RAW,
|
|
165
176
|
UNKNOWN,
|
|
@@ -216,14 +227,9 @@ namespace sharp {
|
|
|
216
227
|
ImageType DetermineImageType(char const *file);
|
|
217
228
|
|
|
218
229
|
/*
|
|
219
|
-
|
|
220
|
-
*/
|
|
221
|
-
bool ImageTypeSupportsPage(ImageType imageType);
|
|
222
|
-
|
|
223
|
-
/*
|
|
224
|
-
Does this image type support removal of safety limits?
|
|
230
|
+
Format-specific options builder
|
|
225
231
|
*/
|
|
226
|
-
|
|
232
|
+
vips::VOption* GetOptionsForImageType(ImageType imageType, InputDescriptor *descriptor);
|
|
227
233
|
|
|
228
234
|
/*
|
|
229
235
|
Open an image from the given InputDescriptor (filesystem, compressed buffer, raw pixel data)
|
|
@@ -357,12 +363,6 @@ namespace sharp {
|
|
|
357
363
|
*/
|
|
358
364
|
bool Is16Bit(VipsInterpretation const interpretation);
|
|
359
365
|
|
|
360
|
-
/*
|
|
361
|
-
Return the image alpha maximum. Useful for combining alpha bands. scRGB
|
|
362
|
-
images are 0 - 1 for image data, but the alpha is 0 - 255.
|
|
363
|
-
*/
|
|
364
|
-
double MaximumImageAlpha(VipsInterpretation const interpretation);
|
|
365
|
-
|
|
366
366
|
/*
|
|
367
367
|
Convert RGBA value to another colourspace
|
|
368
368
|
*/
|
package/src/metadata.cc
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
// Copyright 2013 Lovell Fuller and others.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
#include <cmath>
|
|
4
5
|
#include <numeric>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <utility>
|
|
5
8
|
#include <vector>
|
|
6
|
-
#include <cmath>
|
|
7
9
|
|
|
8
10
|
#include <napi.h>
|
|
9
11
|
#include <vips/vips8>
|
|
10
12
|
|
|
11
|
-
#include "common.h"
|
|
12
|
-
#include "metadata.h"
|
|
13
|
+
#include "./common.h"
|
|
14
|
+
#include "./metadata.h"
|
|
13
15
|
|
|
14
16
|
static void* readPNGComment(VipsImage *image, const char *field, GValue *value, void *p);
|
|
15
17
|
|
|
@@ -261,6 +263,10 @@ class MetadataWorker : public Napi::AsyncWorker {
|
|
|
261
263
|
info.Set("iptc", Napi::Buffer<char>::NewOrCopy(env, baton->iptc, baton->iptcLength, sharp::FreeCallback));
|
|
262
264
|
}
|
|
263
265
|
if (baton->xmpLength > 0) {
|
|
266
|
+
if (g_utf8_validate(static_cast<char const *>(baton->xmp), baton->xmpLength, nullptr)) {
|
|
267
|
+
info.Set("xmpAsString",
|
|
268
|
+
Napi::String::New(env, static_cast<char const *>(baton->xmp), baton->xmpLength));
|
|
269
|
+
}
|
|
264
270
|
info.Set("xmp", Napi::Buffer<char>::NewOrCopy(env, baton->xmp, baton->xmpLength, sharp::FreeCallback));
|
|
265
271
|
}
|
|
266
272
|
if (baton->tifftagPhotoshopLength > 0) {
|
package/src/metadata.h
CHANGED
package/src/operations.cc
CHANGED