sharp 0.25.4 → 0.26.0
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/binding.gyp +53 -66
- package/install/dll-copy.js +3 -1
- package/install/libvips.js +18 -13
- package/lib/constructor.js +7 -1
- package/lib/input.js +10 -1
- package/lib/libvips.js +1 -7
- package/lib/output.js +89 -7
- package/lib/platform.js +2 -1
- package/lib/utility.js +1 -1
- package/package.json +19 -15
- package/src/common.cc +113 -50
- package/src/common.h +21 -2
- package/src/libvips/cplusplus/VImage.cpp +451 -450
- package/src/libvips/cplusplus/vips-operators.cpp +117 -1
- package/src/metadata.cc +1 -1
- package/src/operations.cc +0 -23
- package/src/operations.h +0 -10
- package/src/pipeline.cc +70 -11
- package/src/pipeline.h +9 -2
- package/src/stats.cc +17 -0
- package/src/stats.h +7 -1
package/src/common.cc
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
#include <string.h>
|
|
18
18
|
#include <vector>
|
|
19
19
|
#include <queue>
|
|
20
|
+
#include <map>
|
|
20
21
|
#include <mutex> // NOLINT(build/c++11)
|
|
21
22
|
|
|
22
23
|
#include <napi.h>
|
|
@@ -41,6 +42,9 @@ namespace sharp {
|
|
|
41
42
|
int32_t AttrAsInt32(Napi::Object obj, std::string attr) {
|
|
42
43
|
return obj.Get(attr).As<Napi::Number>().Int32Value();
|
|
43
44
|
}
|
|
45
|
+
int32_t AttrAsInt32(Napi::Object obj, unsigned int const attr) {
|
|
46
|
+
return obj.Get(attr).As<Napi::Number>().Int32Value();
|
|
47
|
+
}
|
|
44
48
|
double AttrAsDouble(Napi::Object obj, std::string attr) {
|
|
45
49
|
return obj.Get(attr).As<Napi::Number>().DoubleValue();
|
|
46
50
|
}
|
|
@@ -58,6 +62,14 @@ namespace sharp {
|
|
|
58
62
|
}
|
|
59
63
|
return rgba;
|
|
60
64
|
}
|
|
65
|
+
std::vector<int32_t> AttrAsInt32Vector(Napi::Object obj, std::string attr) {
|
|
66
|
+
Napi::Array array = obj.Get(attr).As<Napi::Array>();
|
|
67
|
+
std::vector<int32_t> vector(array.Length());
|
|
68
|
+
for (unsigned int i = 0; i < array.Length(); i++) {
|
|
69
|
+
vector[i] = AttrAsInt32(array, i);
|
|
70
|
+
}
|
|
71
|
+
return vector;
|
|
72
|
+
}
|
|
61
73
|
|
|
62
74
|
// Create an InputDescriptor instance from a Napi::Object describing an input image
|
|
63
75
|
InputDescriptor* CreateInputDescriptor(Napi::Object input) {
|
|
@@ -125,6 +137,9 @@ namespace sharp {
|
|
|
125
137
|
bool IsWebp(std::string const &str) {
|
|
126
138
|
return EndsWith(str, ".webp") || EndsWith(str, ".WEBP");
|
|
127
139
|
}
|
|
140
|
+
bool IsGif(std::string const &str) {
|
|
141
|
+
return EndsWith(str, ".gif") || EndsWith(str, ".GIF");
|
|
142
|
+
}
|
|
128
143
|
bool IsTiff(std::string const &str) {
|
|
129
144
|
return EndsWith(str, ".tif") || EndsWith(str, ".tiff") || EndsWith(str, ".TIF") || EndsWith(str, ".TIFF");
|
|
130
145
|
}
|
|
@@ -173,32 +188,42 @@ namespace sharp {
|
|
|
173
188
|
return id;
|
|
174
189
|
}
|
|
175
190
|
|
|
191
|
+
std::map<std::string, ImageType> loaderToType = {
|
|
192
|
+
{ "jpegload", ImageType::JPEG },
|
|
193
|
+
{ "jpegload_buffer", ImageType::JPEG },
|
|
194
|
+
{ "pngload", ImageType::PNG },
|
|
195
|
+
{ "pngload_buffer", ImageType::PNG },
|
|
196
|
+
{ "webpload", ImageType::WEBP },
|
|
197
|
+
{ "webpload_buffer", ImageType::WEBP },
|
|
198
|
+
{ "tiffload", ImageType::TIFF },
|
|
199
|
+
{ "tiffload_buffer", ImageType::TIFF },
|
|
200
|
+
{ "gifload", ImageType::GIF },
|
|
201
|
+
{ "gifload_buffer", ImageType::GIF },
|
|
202
|
+
{ "svgload", ImageType::SVG },
|
|
203
|
+
{ "svgload_buffer", ImageType::SVG },
|
|
204
|
+
{ "heifload", ImageType::HEIF },
|
|
205
|
+
{ "heifload_buffer", ImageType::HEIF },
|
|
206
|
+
{ "pdfload", ImageType::PDF },
|
|
207
|
+
{ "pdfload_buffer", ImageType::PDF },
|
|
208
|
+
{ "magickload", ImageType::MAGICK },
|
|
209
|
+
{ "magickload_buffer", ImageType::MAGICK },
|
|
210
|
+
{ "openslideload", ImageType::OPENSLIDE },
|
|
211
|
+
{ "ppmload", ImageType::PPM },
|
|
212
|
+
{ "fitsload", ImageType::FITS },
|
|
213
|
+
{ "vipsload", ImageType::VIPS },
|
|
214
|
+
{ "rawload", ImageType::RAW }
|
|
215
|
+
};
|
|
216
|
+
|
|
176
217
|
/*
|
|
177
218
|
Determine image format of a buffer.
|
|
178
219
|
*/
|
|
179
220
|
ImageType DetermineImageType(void *buffer, size_t const length) {
|
|
180
221
|
ImageType imageType = ImageType::UNKNOWN;
|
|
181
222
|
char const *load = vips_foreign_find_load_buffer(buffer, length);
|
|
182
|
-
if (load !=
|
|
183
|
-
|
|
184
|
-
if (
|
|
185
|
-
imageType =
|
|
186
|
-
} else if (EndsWith(loader, "PngBuffer")) {
|
|
187
|
-
imageType = ImageType::PNG;
|
|
188
|
-
} else if (EndsWith(loader, "WebpBuffer")) {
|
|
189
|
-
imageType = ImageType::WEBP;
|
|
190
|
-
} else if (EndsWith(loader, "TiffBuffer")) {
|
|
191
|
-
imageType = ImageType::TIFF;
|
|
192
|
-
} else if (EndsWith(loader, "GifBuffer")) {
|
|
193
|
-
imageType = ImageType::GIF;
|
|
194
|
-
} else if (EndsWith(loader, "SvgBuffer")) {
|
|
195
|
-
imageType = ImageType::SVG;
|
|
196
|
-
} else if (EndsWith(loader, "HeifBuffer")) {
|
|
197
|
-
imageType = ImageType::HEIF;
|
|
198
|
-
} else if (EndsWith(loader, "PdfBuffer")) {
|
|
199
|
-
imageType = ImageType::PDF;
|
|
200
|
-
} else if (EndsWith(loader, "MagickBuffer")) {
|
|
201
|
-
imageType = ImageType::MAGICK;
|
|
223
|
+
if (load != nullptr) {
|
|
224
|
+
auto it = loaderToType.find(vips_nickname_find(g_type_from_name(load)));
|
|
225
|
+
if (it != loaderToType.end()) {
|
|
226
|
+
imageType = it->second;
|
|
202
227
|
}
|
|
203
228
|
}
|
|
204
229
|
return imageType;
|
|
@@ -211,36 +236,12 @@ namespace sharp {
|
|
|
211
236
|
ImageType imageType = ImageType::UNKNOWN;
|
|
212
237
|
char const *load = vips_foreign_find_load(file);
|
|
213
238
|
if (load != nullptr) {
|
|
214
|
-
|
|
215
|
-
if (
|
|
216
|
-
imageType =
|
|
217
|
-
} else if (EndsWith(loader, "PngFile")) {
|
|
218
|
-
imageType = ImageType::PNG;
|
|
219
|
-
} else if (EndsWith(loader, "WebpFile")) {
|
|
220
|
-
imageType = ImageType::WEBP;
|
|
221
|
-
} else if (EndsWith(loader, "Openslide")) {
|
|
222
|
-
imageType = ImageType::OPENSLIDE;
|
|
223
|
-
} else if (EndsWith(loader, "TiffFile")) {
|
|
224
|
-
imageType = ImageType::TIFF;
|
|
225
|
-
} else if (EndsWith(loader, "GifFile")) {
|
|
226
|
-
imageType = ImageType::GIF;
|
|
227
|
-
} else if (EndsWith(loader, "SvgFile")) {
|
|
228
|
-
imageType = ImageType::SVG;
|
|
229
|
-
} else if (EndsWith(loader, "HeifFile")) {
|
|
230
|
-
imageType = ImageType::HEIF;
|
|
231
|
-
} else if (EndsWith(loader, "PdfFile")) {
|
|
232
|
-
imageType = ImageType::PDF;
|
|
233
|
-
} else if (EndsWith(loader, "Ppm")) {
|
|
234
|
-
imageType = ImageType::PPM;
|
|
235
|
-
} else if (EndsWith(loader, "Fits")) {
|
|
236
|
-
imageType = ImageType::FITS;
|
|
237
|
-
} else if (EndsWith(loader, "Vips")) {
|
|
238
|
-
imageType = ImageType::VIPS;
|
|
239
|
-
} else if (EndsWith(loader, "Magick") || EndsWith(loader, "MagickFile")) {
|
|
240
|
-
imageType = ImageType::MAGICK;
|
|
239
|
+
auto it = loaderToType.find(vips_nickname_find(g_type_from_name(load)));
|
|
240
|
+
if (it != loaderToType.end()) {
|
|
241
|
+
imageType = it->second;
|
|
241
242
|
}
|
|
242
243
|
} else {
|
|
243
|
-
if (EndsWith(vips::VError().what(), " not
|
|
244
|
+
if (EndsWith(vips::VError().what(), " does not exist\n")) {
|
|
244
245
|
imageType = ImageType::MISSING;
|
|
245
246
|
}
|
|
246
247
|
}
|
|
@@ -252,6 +253,8 @@ namespace sharp {
|
|
|
252
253
|
*/
|
|
253
254
|
bool ImageTypeSupportsPage(ImageType imageType) {
|
|
254
255
|
return
|
|
256
|
+
imageType == ImageType::WEBP ||
|
|
257
|
+
imageType == ImageType::MAGICK ||
|
|
255
258
|
imageType == ImageType::GIF ||
|
|
256
259
|
imageType == ImageType::TIFF ||
|
|
257
260
|
imageType == ImageType::HEIF ||
|
|
@@ -420,6 +423,38 @@ namespace sharp {
|
|
|
420
423
|
return copy;
|
|
421
424
|
}
|
|
422
425
|
|
|
426
|
+
/*
|
|
427
|
+
Set animation properties if necessary.
|
|
428
|
+
Non-provided properties will be loaded from image.
|
|
429
|
+
*/
|
|
430
|
+
VImage SetAnimationProperties(VImage image, int pageHeight, std::vector<int> delay, int loop) {
|
|
431
|
+
bool hasDelay = delay.size() != 1 || delay.front() != -1;
|
|
432
|
+
|
|
433
|
+
if (pageHeight == 0 && image.get_typeof(VIPS_META_PAGE_HEIGHT) == G_TYPE_INT) {
|
|
434
|
+
pageHeight = image.get_int(VIPS_META_PAGE_HEIGHT);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (!hasDelay && image.get_typeof("delay") == VIPS_TYPE_ARRAY_INT) {
|
|
438
|
+
delay = image.get_array_int("delay");
|
|
439
|
+
hasDelay = true;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (loop == -1 && image.get_typeof("loop") == G_TYPE_INT) {
|
|
443
|
+
loop = image.get_int("loop");
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
if (pageHeight == 0) return image;
|
|
447
|
+
|
|
448
|
+
// It is necessary to create the copy as otherwise, pageHeight will be ignored!
|
|
449
|
+
VImage copy = image.copy();
|
|
450
|
+
|
|
451
|
+
copy.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
|
452
|
+
if (hasDelay) copy.set("delay", delay);
|
|
453
|
+
if (loop != -1) copy.set("loop", loop);
|
|
454
|
+
|
|
455
|
+
return copy;
|
|
456
|
+
}
|
|
457
|
+
|
|
423
458
|
/*
|
|
424
459
|
Does this image have a non-default density?
|
|
425
460
|
*/
|
|
@@ -450,14 +485,21 @@ namespace sharp {
|
|
|
450
485
|
Check the proposed format supports the current dimensions.
|
|
451
486
|
*/
|
|
452
487
|
void AssertImageTypeDimensions(VImage image, ImageType const imageType) {
|
|
488
|
+
const int height = image.get_typeof("pageHeight") == G_TYPE_INT
|
|
489
|
+
? image.get_int("pageHeight")
|
|
490
|
+
: image.height();
|
|
453
491
|
if (imageType == ImageType::JPEG) {
|
|
454
|
-
if (image.width() > 65535 ||
|
|
492
|
+
if (image.width() > 65535 || height > 65535) {
|
|
455
493
|
throw vips::VError("Processed image is too large for the JPEG format");
|
|
456
494
|
}
|
|
457
495
|
} else if (imageType == ImageType::WEBP) {
|
|
458
|
-
if (image.width() > 16383 ||
|
|
496
|
+
if (image.width() > 16383 || height > 16383) {
|
|
459
497
|
throw vips::VError("Processed image is too large for the WebP format");
|
|
460
498
|
}
|
|
499
|
+
} else if (imageType == ImageType::GIF) {
|
|
500
|
+
if (image.width() > 65535 || height > 65535) {
|
|
501
|
+
throw vips::VError("Processed image is too large for the GIF format");
|
|
502
|
+
}
|
|
461
503
|
}
|
|
462
504
|
}
|
|
463
505
|
|
|
@@ -720,4 +762,25 @@ namespace sharp {
|
|
|
720
762
|
return std::make_tuple(image, alphaColour);
|
|
721
763
|
}
|
|
722
764
|
|
|
765
|
+
/*
|
|
766
|
+
Removes alpha channel, if any.
|
|
767
|
+
*/
|
|
768
|
+
VImage RemoveAlpha(VImage image) {
|
|
769
|
+
if (HasAlpha(image)) {
|
|
770
|
+
image = image.extract_band(0, VImage::option()->set("n", image.bands() - 1));
|
|
771
|
+
}
|
|
772
|
+
return image;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/*
|
|
776
|
+
Ensures alpha channel, if missing.
|
|
777
|
+
*/
|
|
778
|
+
VImage EnsureAlpha(VImage image) {
|
|
779
|
+
if (!HasAlpha(image)) {
|
|
780
|
+
std::vector<double> alpha;
|
|
781
|
+
alpha.push_back(sharp::MaximumImageAlpha(image.interpretation()));
|
|
782
|
+
image = image.bandjoin_const(alpha);
|
|
783
|
+
}
|
|
784
|
+
return image;
|
|
785
|
+
}
|
|
723
786
|
} // namespace sharp
|
package/src/common.h
CHANGED
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
|
|
25
25
|
// Verify platform and compiler compatibility
|
|
26
26
|
|
|
27
|
-
#if (VIPS_MAJOR_VERSION < 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION <
|
|
28
|
-
#error "libvips version 8.
|
|
27
|
+
#if (VIPS_MAJOR_VERSION < 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 10))
|
|
28
|
+
#error "libvips version 8.10.0+ is required - please see https://sharp.pixelplumbing.com/install"
|
|
29
29
|
#endif
|
|
30
30
|
|
|
31
31
|
#if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
|
|
@@ -88,10 +88,12 @@ namespace sharp {
|
|
|
88
88
|
std::string AttrAsStr(Napi::Object obj, std::string attr);
|
|
89
89
|
uint32_t AttrAsUint32(Napi::Object obj, std::string attr);
|
|
90
90
|
int32_t AttrAsInt32(Napi::Object obj, std::string attr);
|
|
91
|
+
int32_t AttrAsInt32(Napi::Object obj, unsigned int const attr);
|
|
91
92
|
double AttrAsDouble(Napi::Object obj, std::string attr);
|
|
92
93
|
double AttrAsDouble(Napi::Object obj, unsigned int const attr);
|
|
93
94
|
bool AttrAsBool(Napi::Object obj, std::string attr);
|
|
94
95
|
std::vector<double> AttrAsRgba(Napi::Object obj, std::string attr);
|
|
96
|
+
std::vector<int32_t> AttrAsInt32Vector(Napi::Object obj, std::string attr);
|
|
95
97
|
|
|
96
98
|
// Create an InputDescriptor instance from a Napi::Object describing an input image
|
|
97
99
|
InputDescriptor* CreateInputDescriptor(Napi::Object input);
|
|
@@ -125,6 +127,7 @@ namespace sharp {
|
|
|
125
127
|
bool IsJpeg(std::string const &str);
|
|
126
128
|
bool IsPng(std::string const &str);
|
|
127
129
|
bool IsWebp(std::string const &str);
|
|
130
|
+
bool IsGif(std::string const &str);
|
|
128
131
|
bool IsTiff(std::string const &str);
|
|
129
132
|
bool IsHeic(std::string const &str);
|
|
130
133
|
bool IsHeif(std::string const &str);
|
|
@@ -184,6 +187,12 @@ namespace sharp {
|
|
|
184
187
|
*/
|
|
185
188
|
VImage RemoveExifOrientation(VImage image);
|
|
186
189
|
|
|
190
|
+
/*
|
|
191
|
+
Set animation properties if necessary.
|
|
192
|
+
Non-provided properties will be loaded from image.
|
|
193
|
+
*/
|
|
194
|
+
VImage SetAnimationProperties(VImage image, int pageHeight, std::vector<int> delay, int loop);
|
|
195
|
+
|
|
187
196
|
/*
|
|
188
197
|
Does this image have a non-default density?
|
|
189
198
|
*/
|
|
@@ -271,6 +280,16 @@ namespace sharp {
|
|
|
271
280
|
*/
|
|
272
281
|
std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour);
|
|
273
282
|
|
|
283
|
+
/*
|
|
284
|
+
Removes alpha channel, if any.
|
|
285
|
+
*/
|
|
286
|
+
VImage RemoveAlpha(VImage image);
|
|
287
|
+
|
|
288
|
+
/*
|
|
289
|
+
Ensures alpha channel, if missing.
|
|
290
|
+
*/
|
|
291
|
+
VImage EnsureAlpha(VImage image);
|
|
292
|
+
|
|
274
293
|
} // namespace sharp
|
|
275
294
|
|
|
276
295
|
#endif // SRC_COMMON_H_
|