@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/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
- /* istanbul ignore next */
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
- /* istanbul ignore next */
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
- * The maximum number of images that sharp can process in parallel
139
- * is controlled by libuv's `UV_THREADPOOL_SIZE` environment variable,
140
- * which defaults to 4.
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
- /* istanbul ignore next */
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.1-revizly9",
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 test-lint && npm run test-unit && npm run test-licensing && npm run test-types",
98
- "test-lint": "semistandard && cpplint",
99
- "test-unit": "nyc --reporter=lcov --reporter=text --check-coverage --branches=100 mocha",
100
- "test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;LGPL-3.0-or-later;MIT\"",
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-types": "tsd",
103
- "package-from-local-build": "node npm/from-local-build",
104
- "package-from-github-release": "node npm/from-github-release",
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
- "color": "^4.2.3",
141
- "detect-libc": "^2.0.3",
142
- "semver": "^7.7.1"
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.18",
146
- "@revizly/sharp-libvips-linux-x64": "1.0.18",
147
- "@revizly/sharp-linux-arm64": "0.34.1-revizly7",
148
- "@revizly/sharp-linux-x64": "0.34.1-revizly7"
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
- "@emnapi/runtime": "^1.4.0",
152
- "@revizly/sharp-libvips-dev": "1.0.18",
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
- "cc": "^3.0.1",
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.1",
160
- "license-checker": "^25.0.1",
161
- "mocha": "^11.1.0",
162
- "node-addon-api": "^8.3.1",
163
- "nyc": "^17.1.0",
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.16.1"
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=["emnapiInit", "_vips_shutdown", "_uv_library_shutdown"]',
212
+ '-sEXPORTED_FUNCTIONS=emnapiInit,_vips_shutdown,_uv_library_shutdown',
207
213
  '-sNODERAWFS',
208
- '-sTEXTDECODER=0',
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 <string.h>
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, "level")) {
106
- descriptor->level = AttrAsUint32(input, "level");
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->subifd = AttrAsInt32(input, "subifd");
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 = VImage::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 = VImage::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
- alphaColour.push_back(colour[3] * multiplier);
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.bandjoin(
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
- std::vector<double> alpha;
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 < 16) || \
19
- (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 16 && VIPS_MICRO_VERSION < 1)
20
- #error "libvips version 8.16.1+ is required - please see https://sharp.pixelplumbing.com/install"
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 { // NOLINT(runtime/indentation_namespace)
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
- pdfBackground{ 255.0, 255.0, 255.0, 255.0 } {}
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
- Does this image type support multiple pages?
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
- bool ImageTypeSupportsUnlimited(ImageType imageType);
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
@@ -5,6 +5,7 @@
5
5
  #define SRC_METADATA_H_
6
6
 
7
7
  #include <string>
8
+ #include <vector>
8
9
  #include <napi.h>
9
10
 
10
11
  #include "./common.h"
package/src/operations.cc CHANGED
@@ -8,8 +8,8 @@
8
8
  #include <vector>
9
9
  #include <vips/vips8>
10
10
 
11
- #include "common.h"
12
- #include "operations.h"
11
+ #include "./common.h"
12
+ #include "./operations.h"
13
13
 
14
14
  using vips::VImage;
15
15
  using vips::VError;
package/src/operations.h CHANGED
@@ -8,6 +8,7 @@
8
8
  #include <functional>
9
9
  #include <memory>
10
10
  #include <tuple>
11
+ #include <vector>
11
12
  #include <vips/vips8>
12
13
 
13
14
  using vips::VImage;