@ohos-ports/sharp 0.34.5-beta.9 → 0.35.5-beta.1

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.
Files changed (46) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +112 -0
  3. package/{lib/channel.js → dist/channel.cjs} +1 -1
  4. package/dist/channel.mjs +177 -0
  5. package/{lib/colour.js → dist/colour.cjs} +12 -8
  6. package/dist/colour.mjs +199 -0
  7. package/{lib/composite.js → dist/composite.cjs} +8 -7
  8. package/dist/composite.mjs +213 -0
  9. package/{lib/constructor.js → dist/constructor.cjs} +42 -30
  10. package/dist/constructor.mjs +511 -0
  11. package/dist/index.cjs +25 -0
  12. package/{lib/index.d.ts → dist/index.d.cts} +113 -85
  13. package/dist/index.d.mts +2046 -0
  14. package/dist/index.mjs +25 -0
  15. package/{lib/input.js → dist/input.cjs} +47 -37
  16. package/dist/input.mjs +819 -0
  17. package/{lib/is.js → dist/is.cjs} +9 -3
  18. package/dist/is.mjs +149 -0
  19. package/{lib/libvips.js → dist/libvips.cjs} +35 -30
  20. package/dist/libvips.mjs +213 -0
  21. package/{lib/operation.js → dist/operation.cjs} +39 -53
  22. package/dist/operation.mjs +1002 -0
  23. package/{lib/output.js → dist/output.cjs} +167 -47
  24. package/dist/output.mjs +1786 -0
  25. package/{lib/resize.js → dist/resize.cjs} +54 -32
  26. package/dist/resize.mjs +617 -0
  27. package/dist/sharp.cjs +177 -0
  28. package/dist/sharp.mjs +177 -0
  29. package/{lib/utility.js → dist/utility.cjs} +23 -25
  30. package/dist/utility.mjs +301 -0
  31. package/install/build.js +3 -3
  32. package/package.json +56 -56
  33. package/src/binding.gyp +21 -269
  34. package/src/common.cc +81 -25
  35. package/src/common.h +23 -4
  36. package/src/metadata.cc +66 -8
  37. package/src/metadata.h +6 -1
  38. package/src/operations.cc +25 -8
  39. package/src/operations.h +1 -1
  40. package/src/pipeline.cc +231 -72
  41. package/src/pipeline.h +15 -1
  42. package/src/stats.cc +6 -6
  43. package/src/utilities.cc +8 -7
  44. package/install/check.js +0 -73
  45. package/lib/index.js +0 -16
  46. package/lib/sharp.js +0 -154
package/src/binding.gyp CHANGED
@@ -1,87 +1,11 @@
1
1
  # Copyright 2013 Lovell Fuller and others.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
-
3
+ # HarmonyOS (openharmony) migration: minimal binding.gyp linking against the
4
+ # HarmonyOS-built libvips-cpp 8.18.7 (vips-full prefix, all formats) instead of
5
+ # the glibc prebuilt package / Round-1 cmd-pkgs 8.18.3.
4
6
  {
5
- 'variables': {
6
- 'vips_version': '<!(node -p "require(\'../lib/libvips\').minimumLibvipsVersion")',
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)\']")',
9
- 'sharp_libvips_yarn_locator': '<!(node -p "require(\'../lib/libvips\').yarnLocator()")',
10
- 'sharp_libvips_include_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsIncludeDir()")',
11
- 'sharp_libvips_cplusplus_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsCPlusPlusDir()")',
12
- 'sharp_libvips_lib_dir': '<!(node -p "require(\'../lib/libvips\').buildSharpLibvipsLibDir()")'
13
- },
14
7
  'targets': [{
15
- 'target_name': 'libvips-cpp-<(vips_version)',
16
- 'conditions': [
17
- ['OS == "win"', {
18
- # Build libvips C++ binding for Windows due to MSVC std library ABI changes
19
- 'type': 'shared_library',
20
- 'defines': [
21
- '_VIPS_PUBLIC=__declspec(dllexport)',
22
- '_ALLOW_KEYWORD_MACROS',
23
- 'G_DISABLE_ASSERT',
24
- 'G_DISABLE_CAST_CHECKS',
25
- 'G_DISABLE_CHECKS'
26
- ],
27
- 'sources': [
28
- '<(sharp_libvips_cplusplus_dir)/VConnection.cpp',
29
- '<(sharp_libvips_cplusplus_dir)/VError.cpp',
30
- '<(sharp_libvips_cplusplus_dir)/VImage.cpp',
31
- '<(sharp_libvips_cplusplus_dir)/VInterpolate.cpp',
32
- '<(sharp_libvips_cplusplus_dir)/VRegion.cpp'
33
- ],
34
- 'include_dirs': [
35
- '<(sharp_libvips_include_dir)',
36
- '<(sharp_libvips_include_dir)/glib-2.0',
37
- '<(sharp_libvips_lib_dir)/glib-2.0/include'
38
- ],
39
- 'link_settings': {
40
- 'library_dirs': [
41
- '<(sharp_libvips_lib_dir)'
42
- ],
43
- 'libraries': [
44
- 'libvips.lib'
45
- ],
46
- },
47
- 'configurations': {
48
- 'Release': {
49
- 'msvs_settings': {
50
- 'VCCLCompilerTool': {
51
- "AdditionalOptions": [
52
- "/std:c++17"
53
- ],
54
- 'ExceptionHandling': 1,
55
- 'Optimization': 1,
56
- 'WholeProgramOptimization': 'true'
57
- },
58
- 'VCLibrarianTool': {
59
- 'AdditionalOptions': [
60
- '/LTCG:INCREMENTAL'
61
- ]
62
- },
63
- 'VCLinkerTool': {
64
- 'ImageHasSafeExceptionHandlers': 'false',
65
- 'OptimizeReferences': 2,
66
- 'EnableCOMDATFolding': 2,
67
- 'LinkIncremental': 1,
68
- 'AdditionalOptions': [
69
- '/LTCG:INCREMENTAL'
70
- ]
71
- }
72
- },
73
- 'msvs_disabled_warnings': [
74
- 4275
75
- ]
76
- }
77
- }
78
- }, {
79
- # Ignore this target for non-Windows
80
- 'type': 'none'
81
- }]
82
- ]
83
- }, {
84
- 'target_name': 'sharp-<(platform_and_arch)',
8
+ 'target_name': 'sharp-linux-arm64-0.35.5',
85
9
  'defines': [
86
10
  'G_DISABLE_ASSERT',
87
11
  'G_DISABLE_CAST_CHECKS',
@@ -91,208 +15,36 @@
91
15
  'NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS'
92
16
  ],
93
17
  'dependencies': [
94
- '<!(node -p "require(\'node-addon-api\').gyp")',
95
- 'libvips-cpp-<(vips_version)'
18
+ '<!(node -p "require(\'node-addon-api\').gyp")'
19
+ ],
20
+ 'include_dirs': [
21
+ '<!(node -p "require(\'node-addon-api\').include_dir")',
22
+ '/storage/Users/currentUser/workspace/node_result/packages/@img+sharp-linux-arm64@0.35.5/vips-full/prefix/include',
23
+ '/storage/Users/currentUser/.harmonybrew/include/glib-2.0',
24
+ '/storage/Users/currentUser/.harmonybrew/lib/glib-2.0/include',
25
+ '/storage/Users/currentUser/usr/local/include'
96
26
  ],
97
- 'variables': {
98
- 'conditions': [
99
- ['OS != "win"', {
100
- 'pkg_config_path': '<!(node -p "require(\'../lib/libvips\').pkgConfigPath()")',
101
- 'use_global_libvips': '<!(node -p "Boolean(require(\'../lib/libvips\').useGlobalLibvips()).toString()")'
102
- }, {
103
- 'pkg_config_path': '',
104
- 'use_global_libvips': ''
105
- }]
106
- ]
107
- },
108
27
  'sources': [
109
28
  'common.cc',
110
29
  'metadata.cc',
111
- 'stats.cc',
112
30
  'operations.cc',
113
31
  'pipeline.cc',
114
- 'utilities.cc',
115
- 'sharp.cc'
116
- ],
117
- 'include_dirs': [
118
- '<!(node -p "require(\'node-addon-api\').include_dir")',
119
- ],
120
- 'conditions': [
121
- ['use_global_libvips == "true"', {
122
- # Use pkg-config for include and lib
123
- 'include_dirs': ['<!@(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --cflags-only-I vips-cpp vips glib-2.0 | sed s\/-I//g)'],
124
- 'libraries': ['<!@(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --libs vips-cpp)'],
125
- 'defines': [
126
- 'SHARP_USE_GLOBAL_LIBVIPS'
127
- ],
128
- 'conditions': [
129
- ['OS == "linux"', {
130
- 'defines': [
131
- # Inspect libvips-cpp.so to determine which C++11 ABI version was used and set _GLIBCXX_USE_CXX11_ABI accordingly. This is quite horrible.
132
- '_GLIBCXX_USE_CXX11_ABI=<!(if readelf -Ws "$(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --variable libdir vips-cpp)/libvips-cpp.so" | c++filt | grep -qF __cxx11;then echo "1";else echo "0";fi)'
133
- ]
134
- }]
135
- ]
136
- }, {
137
- # Use pre-built libvips stored locally within node_modules
138
- 'include_dirs': [
139
- '<(sharp_libvips_include_dir)',
140
- '<(sharp_libvips_include_dir)/glib-2.0',
141
- '<(sharp_libvips_lib_dir)/glib-2.0/include'
142
- ],
143
- 'library_dirs': [
144
- '<(sharp_libvips_lib_dir)'
145
- ],
146
- 'conditions': [
147
- ['OS == "win"', {
148
- 'defines': [
149
- '_ALLOW_KEYWORD_MACROS',
150
- '_FILE_OFFSET_BITS=64'
151
- ],
152
- 'link_settings': {
153
- 'libraries': [
154
- 'libvips.lib'
155
- ]
156
- }
157
- }],
158
- ['OS == "mac"', {
159
- 'link_settings': {
160
- 'libraries': [
161
- 'libvips-cpp.<(vips_version).dylib'
162
- ]
163
- },
164
- 'xcode_settings': {
165
- 'OTHER_LDFLAGS': [
166
- '-Wl,-s',
167
- '-Wl,-dead_strip',
168
- # Ensure runtime linking is relative to sharp.node
169
- '-Wl,-rpath,\'@loader_path/../../sharp-libvips-<(platform_and_arch)/lib\'',
170
- '-Wl,-rpath,\'@loader_path/../../../sharp-libvips-<(platform_and_arch)/<(sharp_libvips_version)/lib\'',
171
- '-Wl,-rpath,\'@loader_path/../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
172
- '-Wl,-rpath,\'@loader_path/../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
173
- '-Wl,-rpath,\'@loader_path/../../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
174
- '-Wl,-rpath,\'@loader_path/../../../../../@img-sharp-libvips-<(platform_and_arch)-npm-<(sharp_libvips_version)-<(sharp_libvips_yarn_locator)/node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\''
175
- ]
176
- }
177
- }],
178
- ['OS == "linux"', {
179
- 'defines': [
180
- '_GLIBCXX_USE_CXX11_ABI=1'
181
- ],
182
- 'cflags_cc': [
183
- '<!(node -p "require(\'detect-libc\').isNonGlibcLinuxSync() ? \'\' : \'-flto=auto\'")'
184
- ],
185
- 'link_settings': {
186
- 'libraries': [
187
- '-l:libvips-cpp.so.<(vips_version)'
188
- ],
189
- 'ldflags': [
190
- '-lstdc++fs',
191
- '-Wl,-s',
192
- '-Wl,--disable-new-dtags',
193
- '-Wl,-z,nodelete',
194
- '-Wl,-Bsymbolic-functions',
195
- '-Wl,-rpath=\'$$ORIGIN/../../sharp-libvips-<(platform_and_arch)/lib\'',
196
- '-Wl,-rpath=\'$$ORIGIN/../../../sharp-libvips-<(platform_and_arch)/<(sharp_libvips_version)/lib\'',
197
- '-Wl,-rpath=\'$$ORIGIN/../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
198
- '-Wl,-rpath=\'$$ORIGIN/../../../node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\'',
199
- '-Wl,-rpath,\'$$ORIGIN/../../../../../@img-sharp-libvips-<(platform_and_arch)-npm-<(sharp_libvips_version)-<(sharp_libvips_yarn_locator)/node_modules/@img/sharp-libvips-<(platform_and_arch)/lib\''
200
- ]
201
- }
202
- }],
203
- ['OS == "emscripten"', {
204
- 'product_extension': 'node.js',
205
- 'link_settings': {
206
- 'ldflags': [
207
- '-fexceptions',
208
- '--pre-js=<!(node -p "require.resolve(\'./emscripten/pre.js\')")',
209
- '-Oz',
210
- '-sALLOW_MEMORY_GROWTH',
211
- '-sENVIRONMENT=node',
212
- '-sEXPORTED_FUNCTIONS=emnapiInit,_vips_shutdown,_uv_library_shutdown',
213
- '-sNODERAWFS',
214
- '-sWASM_ASYNC_COMPILATION=0'
215
- ],
216
- 'libraries': [
217
- '<!@(PKG_CONFIG_PATH="<!(node -p "require(\'@img/sharp-libvips-dev-wasm32/lib\')")/pkgconfig" pkg-config --static --libs vips-cpp)'
218
- ],
219
- }
220
- }]
221
- ]
222
- }]
32
+ 'sharp.cc',
33
+ 'stats.cc',
34
+ 'utilities.cc'
223
35
  ],
224
36
  'cflags_cc': [
225
37
  '-std=c++17',
226
38
  '-fexceptions',
227
- '-Wall',
228
39
  '-Os'
229
40
  ],
230
- 'xcode_settings': {
231
- 'CLANG_CXX_LANGUAGE_STANDARD': 'c++17',
232
- 'MACOSX_DEPLOYMENT_TARGET': '10.15',
233
- 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
234
- 'GCC_ENABLE_CPP_RTTI': 'YES',
235
- 'OTHER_CPLUSPLUSFLAGS': [
236
- '-fexceptions',
237
- '-Wall',
238
- '-Oz'
239
- ]
240
- },
241
- 'configurations': {
242
- 'Release': {
243
- 'conditions': [
244
- ['target_arch == "arm"', {
245
- 'cflags_cc': [
246
- '-Wno-psabi'
247
- ]
248
- }],
249
- ['OS == "win"', {
250
- 'msvs_settings': {
251
- 'VCCLCompilerTool': {
252
- "AdditionalOptions": [
253
- "/std:c++17"
254
- ],
255
- 'ExceptionHandling': 1,
256
- 'Optimization': 1,
257
- 'WholeProgramOptimization': 'true'
258
- },
259
- 'VCLibrarianTool': {
260
- 'AdditionalOptions': [
261
- '/LTCG:INCREMENTAL'
262
- ]
263
- },
264
- 'VCLinkerTool': {
265
- 'ImageHasSafeExceptionHandlers': 'false',
266
- 'OptimizeReferences': 2,
267
- 'EnableCOMDATFolding': 2,
268
- 'LinkIncremental': 1,
269
- 'AdditionalOptions': [
270
- '/LTCG:INCREMENTAL'
271
- ]
272
- }
273
- },
274
- 'msvs_disabled_warnings': [
275
- 4275
276
- ]
277
- }]
278
- ]
279
- }
280
- },
281
- }, {
282
- 'target_name': 'copy-dll',
283
- 'type': 'none',
284
- 'dependencies': [
285
- 'sharp-<(platform_and_arch)'
41
+ 'ldflags': [
42
+ '-Wl,-rpath=$$ORIGIN'
286
43
  ],
287
- 'conditions': [
288
- ['OS == "win"', {
289
- 'copies': [{
290
- 'destination': 'build/Release',
291
- 'files': [
292
- '<(sharp_libvips_lib_dir)/libvips-42.dll'
293
- ]
294
- }]
295
- }]
44
+ 'libraries': [
45
+ '-L/storage/Users/currentUser/workspace/node_result/packages/@img+sharp-linux-arm64@0.35.5/vips-full/prefix/lib',
46
+ '-L/storage/Users/currentUser/.harmonybrew/lib',
47
+ '-lvips-cpp'
296
48
  ]
297
49
  }]
298
50
  }
package/src/common.cc CHANGED
@@ -118,7 +118,7 @@ namespace sharp {
118
118
  descriptor->openSlideLevel = AttrAsUint32(input, "openSlideLevel");
119
119
  }
120
120
  // subIFD (OME-TIFF)
121
- if (HasAttr(input, "subifd")) {
121
+ if (HasAttr(input, "tiffSubifd")) {
122
122
  descriptor->tiffSubifd = AttrAsInt32(input, "tiffSubifd");
123
123
  }
124
124
  // // PDF background color
@@ -196,8 +196,8 @@ namespace sharp {
196
196
  if (HasAttr(input, "joinValign")) {
197
197
  descriptor->joinValign = AttrAsEnum<VipsAlign>(input, "joinValign", VIPS_TYPE_ALIGN);
198
198
  }
199
- // Limit input images to a given number of pixels, where pixels = width * height
200
199
  descriptor->limitInputPixels = static_cast<uint64_t>(AttrAsInt64(input, "limitInputPixels"));
200
+ descriptor->limitInputChannels = static_cast<uint64_t>(AttrAsInt64(input, "limitInputChannels"));
201
201
  if (HasAttr(input, "access")) {
202
202
  descriptor->access = AttrAsBool(input, "sequentialRead") ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM;
203
203
  }
@@ -289,6 +289,7 @@ namespace sharp {
289
289
  case ImageType::JXL: id = "jxl"; break;
290
290
  case ImageType::RAD: id = "rad"; break;
291
291
  case ImageType::DCRAW: id = "dcraw"; break;
292
+ case ImageType::UHDR: id = "uhdr"; break;
292
293
  case ImageType::VIPS: id = "vips"; break;
293
294
  case ImageType::RAW: id = "raw"; break;
294
295
  case ImageType::UNKNOWN: id = "unknown"; break;
@@ -339,6 +340,9 @@ namespace sharp {
339
340
  { "VipsForeignLoadRadBuffer", ImageType::RAD },
340
341
  { "VipsForeignLoadDcRawFile", ImageType::DCRAW },
341
342
  { "VipsForeignLoadDcRawBuffer", ImageType::DCRAW },
343
+ { "VipsForeignLoadUhdr", ImageType::UHDR },
344
+ { "VipsForeignLoadUhdrFile", ImageType::UHDR },
345
+ { "VipsForeignLoadUhdrBuffer", ImageType::UHDR },
342
346
  { "VipsForeignLoadVips", ImageType::VIPS },
343
347
  { "VipsForeignLoadVipsFile", ImageType::VIPS },
344
348
  { "VipsForeignLoadRaw", ImageType::RAW }
@@ -356,6 +360,9 @@ namespace sharp {
356
360
  imageType = it->second;
357
361
  }
358
362
  }
363
+ if (imageType == ImageType::UHDR) {
364
+ imageType = ImageType::JPEG;
365
+ }
359
366
  return imageType;
360
367
  }
361
368
 
@@ -375,6 +382,9 @@ namespace sharp {
375
382
  imageType = ImageType::MISSING;
376
383
  }
377
384
  }
385
+ if (imageType == ImageType::UHDR) {
386
+ imageType = ImageType::JPEG;
387
+ }
378
388
  return imageType;
379
389
  }
380
390
 
@@ -416,7 +426,7 @@ namespace sharp {
416
426
  }
417
427
  if (ImageTypeSupportsPage(imageType)) {
418
428
  option->set("n", descriptor->pages);
419
- option->set("page", descriptor->page);
429
+ option->set("page", std::max(0, descriptor->page));
420
430
  }
421
431
  switch (imageType) {
422
432
  case ImageType::SVG:
@@ -446,6 +456,22 @@ namespace sharp {
446
456
  return option;
447
457
  }
448
458
 
459
+ /*
460
+ Should HEIF image be re-opened using the primary item?
461
+ */
462
+ static bool HeifPrimaryPageReopen(VImage image, InputDescriptor *descriptor) {
463
+ if (image.get_typeof(VIPS_META_N_PAGES) == G_TYPE_INT && image.get_typeof("heif-primary") == G_TYPE_INT) {
464
+ if (image.get_int(VIPS_META_N_PAGES) > 1 && descriptor->pages == 1 && descriptor->page == -1) {
465
+ int const pagePrimary = image.get_int("heif-primary");
466
+ if (pagePrimary != 0) {
467
+ descriptor->page = pagePrimary;
468
+ return true;
469
+ }
470
+ }
471
+ }
472
+ return false;
473
+ }
474
+
449
475
  /*
450
476
  Open an image from the given InputDescriptor (filesystem, compressed buffer, raw pixel data)
451
477
  */
@@ -480,12 +506,15 @@ namespace sharp {
480
506
  image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);
481
507
  if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
482
508
  image = SetDensity(image, descriptor->density);
509
+ } else if (imageType == ImageType::HEIF && HeifPrimaryPageReopen(image, descriptor)) {
510
+ option = GetOptionsForImageType(imageType, descriptor);
511
+ image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);
483
512
  }
484
- } catch (vips::VError const &err) {
485
- throw vips::VError(std::string("Input buffer has corrupt header: ") + err.what());
513
+ } catch (std::runtime_error const &err) {
514
+ throw std::runtime_error(std::string("Input buffer has corrupt header: ") + err.what());
486
515
  }
487
516
  } else {
488
- throw vips::VError("Input buffer contains unsupported image format");
517
+ throw std::runtime_error("Input buffer contains unsupported image format");
489
518
  }
490
519
  }
491
520
  } else {
@@ -511,10 +540,10 @@ namespace sharp {
511
540
  if (channels == 4) {
512
541
  background.push_back(descriptor->createBackground[3]);
513
542
  }
514
- image = VImage::new_matrix(descriptor->createWidth, descriptor->createHeight)
515
- .copy(VImage::option()->set("interpretation",
516
- channels < 3 ? VIPS_INTERPRETATION_B_W : VIPS_INTERPRETATION_sRGB))
517
- .new_from_image(background);
543
+ image = VImage::black(descriptor->createWidth, descriptor->createHeight,
544
+ VImage::option()->set("bands", channels))
545
+ .copy(VImage::option()->set("interpretation", VIPS_INTERPRETATION_sRGB))
546
+ .linear(std::vector<double>(channels, 0.0), background, VImage::option()->set("uchar", true));
518
547
  }
519
548
  if (descriptor->createPageHeight > 0) {
520
549
  image.set(VIPS_META_PAGE_HEIGHT, descriptor->createPageHeight);
@@ -556,10 +585,10 @@ namespace sharp {
556
585
  imageType = DetermineImageType(descriptor->file.data());
557
586
  if (imageType == ImageType::MISSING) {
558
587
  if (descriptor->file.find("<svg") != std::string::npos) {
559
- throw vips::VError("Input file is missing, did you mean "
588
+ throw std::runtime_error("Input file is missing, did you mean "
560
589
  "sharp(Buffer.from('" + descriptor->file.substr(0, 8) + "...')?");
561
590
  }
562
- throw vips::VError("Input file is missing: " + descriptor->file);
591
+ throw std::runtime_error("Input file is missing: " + descriptor->file);
563
592
  }
564
593
  if (imageType != ImageType::UNKNOWN) {
565
594
  try {
@@ -567,12 +596,15 @@ namespace sharp {
567
596
  image = VImage::new_from_file(descriptor->file.data(), option);
568
597
  if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
569
598
  image = SetDensity(image, descriptor->density);
599
+ } else if (imageType == ImageType::HEIF && HeifPrimaryPageReopen(image, descriptor)) {
600
+ option = GetOptionsForImageType(imageType, descriptor);
601
+ image = VImage::new_from_file(descriptor->file.data(), option);
570
602
  }
571
- } catch (vips::VError const &err) {
572
- throw vips::VError(std::string("Input file has corrupt header: ") + err.what());
603
+ } catch (std::runtime_error const &err) {
604
+ throw std::runtime_error(std::string("Input file has corrupt header: ") + err.what());
573
605
  }
574
606
  } else {
575
- throw vips::VError("Input file contains unsupported image format");
607
+ throw std::runtime_error("Input file contains unsupported image format");
576
608
  }
577
609
  }
578
610
  }
@@ -580,7 +612,10 @@ namespace sharp {
580
612
  // Limit input images to a given number of pixels, where pixels = width * height
581
613
  if (descriptor->limitInputPixels > 0 &&
582
614
  static_cast<uint64_t>(image.width()) * image.height() > descriptor->limitInputPixels) {
583
- throw vips::VError("Input image exceeds pixel limit");
615
+ throw std::runtime_error("Input image exceeds pixel limit");
616
+ }
617
+ if (descriptor->limitInputChannels > 0 && static_cast<uint64_t>(image.bands()) > descriptor->limitInputChannels) {
618
+ throw std::runtime_error("Input image exceeds channel limit");
584
619
  }
585
620
  return std::make_tuple(image, imageType);
586
621
  }
@@ -600,7 +635,7 @@ namespace sharp {
600
635
  if (HasProfile(image)) {
601
636
  size_t length;
602
637
  const void *data = image.get_blob(VIPS_META_ICC_NAME, &length);
603
- icc.first = static_cast<char*>(g_malloc(length));
638
+ icc.first = static_cast<char*>(vips_malloc(reinterpret_cast<VipsObject*>(image.get_image()), length));
604
639
  icc.second = length;
605
640
  memcpy(icc.first, data, length);
606
641
  }
@@ -613,7 +648,7 @@ namespace sharp {
613
648
  VImage SetProfile(VImage image, std::pair<char*, size_t> icc) {
614
649
  if (icc.first != nullptr) {
615
650
  image = image.copy();
616
- image.set(VIPS_META_ICC_NAME, reinterpret_cast<VipsCallbackFn>(vips_area_free_cb), icc.first, icc.second);
651
+ image.set(VIPS_META_ICC_NAME, nullptr, icc.first, icc.second);
617
652
  }
618
653
  return image;
619
654
  }
@@ -676,9 +711,12 @@ namespace sharp {
676
711
  bool hasDelay = !delay.empty();
677
712
  VImage copy = image.copy();
678
713
 
679
- // Only set page-height if we have more than one page, or this could
680
- // accidentally turn into an animated image later.
681
- if (nPages > 1) copy.set(VIPS_META_PAGE_HEIGHT, pageHeight);
714
+ // Only set page-height and n-pages if we have more than one page, or this
715
+ // could accidentally turn into an animated image later.
716
+ if (nPages > 1) {
717
+ copy.set(VIPS_META_PAGE_HEIGHT, pageHeight);
718
+ copy.set(VIPS_META_N_PAGES, nPages);
719
+ }
682
720
  if (hasDelay) {
683
721
  if (delay.size() == 1) {
684
722
  // We have just one delay, repeat that value for all frames.
@@ -756,19 +794,19 @@ namespace sharp {
756
794
  : image.height();
757
795
  if (imageType == ImageType::JPEG) {
758
796
  if (image.width() > 65535 || height > 65535) {
759
- throw vips::VError("Processed image is too large for the JPEG format");
797
+ throw std::runtime_error("Processed image is too large for the JPEG format");
760
798
  }
761
799
  } else if (imageType == ImageType::WEBP) {
762
800
  if (image.width() > 16383 || height > 16383) {
763
- throw vips::VError("Processed image is too large for the WebP format");
801
+ throw std::runtime_error("Processed image is too large for the WebP format");
764
802
  }
765
803
  } else if (imageType == ImageType::GIF) {
766
804
  if (image.width() > 65535 || height > 65535) {
767
- throw vips::VError("Processed image is too large for the GIF format");
805
+ throw std::runtime_error("Processed image is too large for the GIF format");
768
806
  }
769
807
  } else if (imageType == ImageType::HEIF) {
770
808
  if (image.width() > 16384 || height > 16384) {
771
- throw vips::VError("Processed image is too large for the HEIF format");
809
+ throw std::runtime_error("Processed image is too large for the HEIF format");
772
810
  }
773
811
  }
774
812
  }
@@ -1127,4 +1165,22 @@ namespace sharp {
1127
1165
  }
1128
1166
  return image;
1129
1167
  }
1168
+
1169
+ /*
1170
+ Does this image have a gain map?
1171
+ */
1172
+ bool HasGainMap(VImage image) {
1173
+ return image.get_typeof("gainmap") == VIPS_TYPE_BLOB ||
1174
+ image.get_typeof("gainmap-data") == VIPS_TYPE_BLOB;
1175
+ }
1176
+
1177
+ /*
1178
+ Removes gain map, if any.
1179
+ */
1180
+ VImage RemoveGainMap(VImage image) {
1181
+ VImage copy = image.copy();
1182
+ copy.remove("gainmap");
1183
+ copy.remove("gainmap-data");
1184
+ return copy;
1185
+ }
1130
1186
  } // namespace sharp
package/src/common.h CHANGED
@@ -18,9 +18,9 @@
18
18
  // Verify platform and compiler compatibility
19
19
 
20
20
  #if (VIPS_MAJOR_VERSION < 8) || \
21
- (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 17) || \
22
- (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 17 && VIPS_MICRO_VERSION < 3)
23
- #error "libvips version 8.17.3+ is required - please see https://sharp.pixelplumbing.com/install"
21
+ (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 18) || \
22
+ (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 18 && VIPS_MICRO_VERSION < 7)
23
+ #error "libvips version 8.18.7+ is required - please see https://sharp.pixelplumbing.com/install"
24
24
  #endif
25
25
 
26
26
  #if defined(__has_include)
@@ -29,6 +29,12 @@
29
29
  #endif
30
30
  #endif
31
31
 
32
+ #ifdef __EMSCRIPTEN__
33
+ #define SHARP_CALLBACK_FN_NAME Call
34
+ #else
35
+ #define SHARP_CALLBACK_FN_NAME MakeCallback
36
+ #endif
37
+
32
38
  using vips::VImage;
33
39
 
34
40
  namespace sharp {
@@ -40,6 +46,7 @@ namespace sharp {
40
46
  char *buffer;
41
47
  VipsFailOn failOn;
42
48
  uint64_t limitInputPixels;
49
+ uint64_t limitInputChannels;
43
50
  bool unlimited;
44
51
  VipsAccess access;
45
52
  size_t bufferLength;
@@ -92,6 +99,7 @@ namespace sharp {
92
99
  buffer(nullptr),
93
100
  failOn(VIPS_FAIL_ON_WARNING),
94
101
  limitInputPixels(0x3FFF * 0x3FFF),
102
+ limitInputChannels(5),
95
103
  unlimited(false),
96
104
  access(VIPS_ACCESS_SEQUENTIAL),
97
105
  bufferLength(0),
@@ -105,7 +113,7 @@ namespace sharp {
105
113
  rawPremultiplied(false),
106
114
  rawPageHeight(0),
107
115
  pages(1),
108
- page(0),
116
+ page(-1),
109
117
  createChannels(0),
110
118
  createWidth(0),
111
119
  createHeight(0),
@@ -173,6 +181,7 @@ namespace sharp {
173
181
  JXL,
174
182
  RAD,
175
183
  DCRAW,
184
+ UHDR,
176
185
  VIPS,
177
186
  RAW,
178
187
  UNKNOWN,
@@ -397,6 +406,16 @@ namespace sharp {
397
406
  */
398
407
  VImage StaySequential(VImage image, bool condition = true);
399
408
 
409
+ /*
410
+ Does this image have a gain map?
411
+ */
412
+ bool HasGainMap(VImage image);
413
+
414
+ /*
415
+ Removes gain map, if any.
416
+ */
417
+ VImage RemoveGainMap(VImage image);
418
+
400
419
  } // namespace sharp
401
420
 
402
421
  #endif // SRC_COMMON_H_