sharp 0.25.1 → 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 +7 -6
- package/binding.gyp +81 -70
- package/install/dll-copy.js +5 -2
- package/install/libvips.js +20 -14
- package/lib/channel.js +7 -10
- package/lib/colour.js +5 -5
- package/lib/composite.js +2 -5
- package/lib/constructor.js +81 -18
- package/lib/input.js +39 -5
- package/lib/is.js +6 -6
- package/lib/libvips.js +2 -8
- package/lib/operation.js +27 -27
- package/lib/output.js +178 -88
- package/lib/platform.js +2 -1
- package/lib/resize.js +15 -15
- package/lib/utility.js +9 -9
- package/package.json +26 -20
- package/src/common.cc +129 -50
- package/src/common.h +23 -2
- package/src/libvips/cplusplus/VImage.cpp +451 -450
- package/src/libvips/cplusplus/vips-operators.cpp +117 -1
- package/src/metadata.cc +21 -0
- package/src/metadata.h +1 -0
- package/src/operations.cc +0 -23
- package/src/operations.h +0 -10
- package/src/pipeline.cc +78 -16
- package/src/pipeline.h +9 -2
- package/src/sharp.cc +7 -1
- package/src/stats.cc +29 -1
- package/src/stats.h +9 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sharp",
|
|
3
3
|
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.26.0",
|
|
5
5
|
"author": "Lovell Fuller <npm@lovell.info>",
|
|
6
6
|
"homepage": "https://github.com/lovell/sharp",
|
|
7
7
|
"contributors": [
|
|
@@ -65,17 +65,21 @@
|
|
|
65
65
|
"Andargor <andargor@yahoo.com>",
|
|
66
66
|
"Paul Neave <paul.neave@gmail.com>",
|
|
67
67
|
"Brendan Kennedy <brenwken@gmail.com>",
|
|
68
|
-
"Brychan Bennett-Odlum <git@brychan.io>"
|
|
68
|
+
"Brychan Bennett-Odlum <git@brychan.io>",
|
|
69
|
+
"Edward Silverton <e.silverton@gmail.com>",
|
|
70
|
+
"Roman Malieiev <aromaleev@gmail.com>",
|
|
71
|
+
"Tomas Szabo <tomas.szabo@deftomat.com>",
|
|
72
|
+
"Robert O'Rourke <robert@o-rourke.org>"
|
|
69
73
|
],
|
|
70
74
|
"scripts": {
|
|
71
|
-
"install": "(node install/libvips && node install/dll-copy && prebuild-install
|
|
75
|
+
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)",
|
|
72
76
|
"clean": "rm -rf node_modules/ build/ vendor/ .nyc_output/ coverage/ test/fixtures/output.*",
|
|
73
|
-
"test": "semistandard && cpplint && npm run test-unit && npm run test-licensing && prebuild-ci",
|
|
77
|
+
"test": "semistandard && cpplint && npm run test-unit && npm run test-licensing && node install/prebuild-ci",
|
|
74
78
|
"test-unit": "nyc --reporter=lcov --branches=99 mocha --slow=5000 --timeout=60000 ./test/unit/*.js",
|
|
75
79
|
"test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;MIT\"",
|
|
76
80
|
"test-coverage": "./test/coverage/report.sh",
|
|
77
81
|
"test-leak": "./test/leak/leak.sh",
|
|
78
|
-
"docs-build": "for m in constructor input resize composite operation colour channel output utility; do documentation build --shallow --format=md --markdown-toc=false lib/$m.js >docs/api-$m.md; done",
|
|
82
|
+
"docs-build": "documentation lint lib && for m in constructor input resize composite operation colour channel output utility; do documentation build --shallow --format=md --markdown-toc=false lib/$m.js >docs/api-$m.md; done && node docs/search-index/build",
|
|
79
83
|
"docs-serve": "cd docs && npx serve",
|
|
80
84
|
"docs-publish": "cd docs && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
|
|
81
85
|
},
|
|
@@ -83,6 +87,7 @@
|
|
|
83
87
|
"files": [
|
|
84
88
|
"binding.gyp",
|
|
85
89
|
"install/**",
|
|
90
|
+
"!install/prebuild-ci.js",
|
|
86
91
|
"lib/**",
|
|
87
92
|
"src/**"
|
|
88
93
|
],
|
|
@@ -109,36 +114,37 @@
|
|
|
109
114
|
"dependencies": {
|
|
110
115
|
"color": "^3.1.2",
|
|
111
116
|
"detect-libc": "^1.0.3",
|
|
112
|
-
"node-addon-api": "^
|
|
117
|
+
"node-addon-api": "^3.0.0",
|
|
113
118
|
"npmlog": "^4.1.2",
|
|
114
|
-
"prebuild-install": "^5.3.
|
|
115
|
-
"semver": "^7.
|
|
116
|
-
"simple-get": "^
|
|
117
|
-
"tar": "^
|
|
119
|
+
"prebuild-install": "^5.3.5",
|
|
120
|
+
"semver": "^7.3.2",
|
|
121
|
+
"simple-get": "^4.0.0",
|
|
122
|
+
"tar-fs": "^2.1.0",
|
|
118
123
|
"tunnel-agent": "^0.6.0"
|
|
119
124
|
},
|
|
120
125
|
"devDependencies": {
|
|
121
126
|
"async": "^3.2.0",
|
|
122
127
|
"cc": "^2.0.1",
|
|
123
128
|
"decompress-zip": "^0.3.2",
|
|
124
|
-
"documentation": "^
|
|
129
|
+
"documentation": "^13.0.2",
|
|
125
130
|
"exif-reader": "^1.0.3",
|
|
126
|
-
"icc": "^
|
|
131
|
+
"icc": "^2.0.0",
|
|
127
132
|
"license-checker": "^25.0.1",
|
|
128
|
-
"mocha": "^
|
|
129
|
-
"mock-fs": "^4.
|
|
130
|
-
"nyc": "^15.
|
|
131
|
-
"prebuild": "^10.0.
|
|
132
|
-
"prebuild-ci": "^3.1.0",
|
|
133
|
+
"mocha": "^8.1.1",
|
|
134
|
+
"mock-fs": "^4.13.0",
|
|
135
|
+
"nyc": "^15.1.0",
|
|
136
|
+
"prebuild": "^10.0.1",
|
|
133
137
|
"rimraf": "^3.0.2",
|
|
134
|
-
"semistandard": "^14.2.
|
|
138
|
+
"semistandard": "^14.2.3"
|
|
135
139
|
},
|
|
136
140
|
"license": "Apache-2.0",
|
|
137
141
|
"config": {
|
|
138
|
-
"libvips": "8.
|
|
142
|
+
"libvips": "8.10.0",
|
|
143
|
+
"runtime": "napi",
|
|
144
|
+
"target": 3
|
|
139
145
|
},
|
|
140
146
|
"engines": {
|
|
141
|
-
"node": ">=10"
|
|
147
|
+
"node": ">=10.16.0"
|
|
142
148
|
},
|
|
143
149
|
"funding": {
|
|
144
150
|
"url": "https://opencollective.com/libvips"
|
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) {
|
|
@@ -88,6 +100,10 @@ namespace sharp {
|
|
|
88
100
|
if (HasAttr(input, "page")) {
|
|
89
101
|
descriptor->page = AttrAsUint32(input, "page");
|
|
90
102
|
}
|
|
103
|
+
// Multi-level input (OpenSlide)
|
|
104
|
+
if (HasAttr(input, "level")) {
|
|
105
|
+
descriptor->level = AttrAsUint32(input, "level");
|
|
106
|
+
}
|
|
91
107
|
// Create new image
|
|
92
108
|
if (HasAttr(input, "createChannels")) {
|
|
93
109
|
descriptor->createChannels = AttrAsUint32(input, "createChannels");
|
|
@@ -121,6 +137,9 @@ namespace sharp {
|
|
|
121
137
|
bool IsWebp(std::string const &str) {
|
|
122
138
|
return EndsWith(str, ".webp") || EndsWith(str, ".WEBP");
|
|
123
139
|
}
|
|
140
|
+
bool IsGif(std::string const &str) {
|
|
141
|
+
return EndsWith(str, ".gif") || EndsWith(str, ".GIF");
|
|
142
|
+
}
|
|
124
143
|
bool IsTiff(std::string const &str) {
|
|
125
144
|
return EndsWith(str, ".tif") || EndsWith(str, ".tiff") || EndsWith(str, ".TIF") || EndsWith(str, ".TIFF");
|
|
126
145
|
}
|
|
@@ -169,32 +188,42 @@ namespace sharp {
|
|
|
169
188
|
return id;
|
|
170
189
|
}
|
|
171
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
|
+
|
|
172
217
|
/*
|
|
173
218
|
Determine image format of a buffer.
|
|
174
219
|
*/
|
|
175
220
|
ImageType DetermineImageType(void *buffer, size_t const length) {
|
|
176
221
|
ImageType imageType = ImageType::UNKNOWN;
|
|
177
222
|
char const *load = vips_foreign_find_load_buffer(buffer, length);
|
|
178
|
-
if (load !=
|
|
179
|
-
|
|
180
|
-
if (
|
|
181
|
-
imageType =
|
|
182
|
-
} else if (EndsWith(loader, "PngBuffer")) {
|
|
183
|
-
imageType = ImageType::PNG;
|
|
184
|
-
} else if (EndsWith(loader, "WebpBuffer")) {
|
|
185
|
-
imageType = ImageType::WEBP;
|
|
186
|
-
} else if (EndsWith(loader, "TiffBuffer")) {
|
|
187
|
-
imageType = ImageType::TIFF;
|
|
188
|
-
} else if (EndsWith(loader, "GifBuffer")) {
|
|
189
|
-
imageType = ImageType::GIF;
|
|
190
|
-
} else if (EndsWith(loader, "SvgBuffer")) {
|
|
191
|
-
imageType = ImageType::SVG;
|
|
192
|
-
} else if (EndsWith(loader, "HeifBuffer")) {
|
|
193
|
-
imageType = ImageType::HEIF;
|
|
194
|
-
} else if (EndsWith(loader, "PdfBuffer")) {
|
|
195
|
-
imageType = ImageType::PDF;
|
|
196
|
-
} else if (EndsWith(loader, "MagickBuffer")) {
|
|
197
|
-
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;
|
|
198
227
|
}
|
|
199
228
|
}
|
|
200
229
|
return imageType;
|
|
@@ -207,36 +236,12 @@ namespace sharp {
|
|
|
207
236
|
ImageType imageType = ImageType::UNKNOWN;
|
|
208
237
|
char const *load = vips_foreign_find_load(file);
|
|
209
238
|
if (load != nullptr) {
|
|
210
|
-
|
|
211
|
-
if (
|
|
212
|
-
imageType =
|
|
213
|
-
} else if (EndsWith(loader, "PngFile")) {
|
|
214
|
-
imageType = ImageType::PNG;
|
|
215
|
-
} else if (EndsWith(loader, "WebpFile")) {
|
|
216
|
-
imageType = ImageType::WEBP;
|
|
217
|
-
} else if (EndsWith(loader, "Openslide")) {
|
|
218
|
-
imageType = ImageType::OPENSLIDE;
|
|
219
|
-
} else if (EndsWith(loader, "TiffFile")) {
|
|
220
|
-
imageType = ImageType::TIFF;
|
|
221
|
-
} else if (EndsWith(loader, "GifFile")) {
|
|
222
|
-
imageType = ImageType::GIF;
|
|
223
|
-
} else if (EndsWith(loader, "SvgFile")) {
|
|
224
|
-
imageType = ImageType::SVG;
|
|
225
|
-
} else if (EndsWith(loader, "HeifFile")) {
|
|
226
|
-
imageType = ImageType::HEIF;
|
|
227
|
-
} else if (EndsWith(loader, "PdfFile")) {
|
|
228
|
-
imageType = ImageType::PDF;
|
|
229
|
-
} else if (EndsWith(loader, "Ppm")) {
|
|
230
|
-
imageType = ImageType::PPM;
|
|
231
|
-
} else if (EndsWith(loader, "Fits")) {
|
|
232
|
-
imageType = ImageType::FITS;
|
|
233
|
-
} else if (EndsWith(loader, "Vips")) {
|
|
234
|
-
imageType = ImageType::VIPS;
|
|
235
|
-
} else if (EndsWith(loader, "Magick") || EndsWith(loader, "MagickFile")) {
|
|
236
|
-
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;
|
|
237
242
|
}
|
|
238
243
|
} else {
|
|
239
|
-
if (EndsWith(vips::VError().what(), " not
|
|
244
|
+
if (EndsWith(vips::VError().what(), " does not exist\n")) {
|
|
240
245
|
imageType = ImageType::MISSING;
|
|
241
246
|
}
|
|
242
247
|
}
|
|
@@ -248,6 +253,8 @@ namespace sharp {
|
|
|
248
253
|
*/
|
|
249
254
|
bool ImageTypeSupportsPage(ImageType imageType) {
|
|
250
255
|
return
|
|
256
|
+
imageType == ImageType::WEBP ||
|
|
257
|
+
imageType == ImageType::MAGICK ||
|
|
251
258
|
imageType == ImageType::GIF ||
|
|
252
259
|
imageType == ImageType::TIFF ||
|
|
253
260
|
imageType == ImageType::HEIF ||
|
|
@@ -279,6 +286,9 @@ namespace sharp {
|
|
|
279
286
|
vips::VOption *option = VImage::option()
|
|
280
287
|
->set("access", descriptor->access)
|
|
281
288
|
->set("fail", descriptor->failOnError);
|
|
289
|
+
if (imageType == ImageType::SVG) {
|
|
290
|
+
option->set("unlimited", TRUE);
|
|
291
|
+
}
|
|
282
292
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF) {
|
|
283
293
|
option->set("dpi", descriptor->density);
|
|
284
294
|
}
|
|
@@ -289,6 +299,9 @@ namespace sharp {
|
|
|
289
299
|
option->set("n", descriptor->pages);
|
|
290
300
|
option->set("page", descriptor->page);
|
|
291
301
|
}
|
|
302
|
+
if (imageType == ImageType::OPENSLIDE) {
|
|
303
|
+
option->set("level", descriptor->level);
|
|
304
|
+
}
|
|
292
305
|
image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);
|
|
293
306
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
|
294
307
|
image = SetDensity(image, descriptor->density);
|
|
@@ -325,6 +338,9 @@ namespace sharp {
|
|
|
325
338
|
vips::VOption *option = VImage::option()
|
|
326
339
|
->set("access", descriptor->access)
|
|
327
340
|
->set("fail", descriptor->failOnError);
|
|
341
|
+
if (imageType == ImageType::SVG) {
|
|
342
|
+
option->set("unlimited", TRUE);
|
|
343
|
+
}
|
|
328
344
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF) {
|
|
329
345
|
option->set("dpi", descriptor->density);
|
|
330
346
|
}
|
|
@@ -335,6 +351,9 @@ namespace sharp {
|
|
|
335
351
|
option->set("n", descriptor->pages);
|
|
336
352
|
option->set("page", descriptor->page);
|
|
337
353
|
}
|
|
354
|
+
if (imageType == ImageType::OPENSLIDE) {
|
|
355
|
+
option->set("level", descriptor->level);
|
|
356
|
+
}
|
|
338
357
|
image = VImage::new_from_file(descriptor->file.data(), option);
|
|
339
358
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
|
340
359
|
image = SetDensity(image, descriptor->density);
|
|
@@ -404,6 +423,38 @@ namespace sharp {
|
|
|
404
423
|
return copy;
|
|
405
424
|
}
|
|
406
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
|
+
|
|
407
458
|
/*
|
|
408
459
|
Does this image have a non-default density?
|
|
409
460
|
*/
|
|
@@ -434,14 +485,21 @@ namespace sharp {
|
|
|
434
485
|
Check the proposed format supports the current dimensions.
|
|
435
486
|
*/
|
|
436
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();
|
|
437
491
|
if (imageType == ImageType::JPEG) {
|
|
438
|
-
if (image.width() > 65535 ||
|
|
492
|
+
if (image.width() > 65535 || height > 65535) {
|
|
439
493
|
throw vips::VError("Processed image is too large for the JPEG format");
|
|
440
494
|
}
|
|
441
495
|
} else if (imageType == ImageType::WEBP) {
|
|
442
|
-
if (image.width() > 16383 ||
|
|
496
|
+
if (image.width() > 16383 || height > 16383) {
|
|
443
497
|
throw vips::VError("Processed image is too large for the WebP format");
|
|
444
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
|
+
}
|
|
445
503
|
}
|
|
446
504
|
}
|
|
447
505
|
|
|
@@ -704,4 +762,25 @@ namespace sharp {
|
|
|
704
762
|
return std::make_tuple(image, alphaColour);
|
|
705
763
|
}
|
|
706
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
|
+
}
|
|
707
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)))
|
|
@@ -57,6 +57,7 @@ namespace sharp {
|
|
|
57
57
|
int rawHeight;
|
|
58
58
|
int pages;
|
|
59
59
|
int page;
|
|
60
|
+
int level;
|
|
60
61
|
int createChannels;
|
|
61
62
|
int createWidth;
|
|
62
63
|
int createHeight;
|
|
@@ -75,6 +76,7 @@ namespace sharp {
|
|
|
75
76
|
rawHeight(0),
|
|
76
77
|
pages(1),
|
|
77
78
|
page(0),
|
|
79
|
+
level(0),
|
|
78
80
|
createChannels(0),
|
|
79
81
|
createWidth(0),
|
|
80
82
|
createHeight(0),
|
|
@@ -86,10 +88,12 @@ namespace sharp {
|
|
|
86
88
|
std::string AttrAsStr(Napi::Object obj, std::string attr);
|
|
87
89
|
uint32_t AttrAsUint32(Napi::Object obj, std::string attr);
|
|
88
90
|
int32_t AttrAsInt32(Napi::Object obj, std::string attr);
|
|
91
|
+
int32_t AttrAsInt32(Napi::Object obj, unsigned int const attr);
|
|
89
92
|
double AttrAsDouble(Napi::Object obj, std::string attr);
|
|
90
93
|
double AttrAsDouble(Napi::Object obj, unsigned int const attr);
|
|
91
94
|
bool AttrAsBool(Napi::Object obj, std::string attr);
|
|
92
95
|
std::vector<double> AttrAsRgba(Napi::Object obj, std::string attr);
|
|
96
|
+
std::vector<int32_t> AttrAsInt32Vector(Napi::Object obj, std::string attr);
|
|
93
97
|
|
|
94
98
|
// Create an InputDescriptor instance from a Napi::Object describing an input image
|
|
95
99
|
InputDescriptor* CreateInputDescriptor(Napi::Object input);
|
|
@@ -123,6 +127,7 @@ namespace sharp {
|
|
|
123
127
|
bool IsJpeg(std::string const &str);
|
|
124
128
|
bool IsPng(std::string const &str);
|
|
125
129
|
bool IsWebp(std::string const &str);
|
|
130
|
+
bool IsGif(std::string const &str);
|
|
126
131
|
bool IsTiff(std::string const &str);
|
|
127
132
|
bool IsHeic(std::string const &str);
|
|
128
133
|
bool IsHeif(std::string const &str);
|
|
@@ -182,6 +187,12 @@ namespace sharp {
|
|
|
182
187
|
*/
|
|
183
188
|
VImage RemoveExifOrientation(VImage image);
|
|
184
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
|
+
|
|
185
196
|
/*
|
|
186
197
|
Does this image have a non-default density?
|
|
187
198
|
*/
|
|
@@ -269,6 +280,16 @@ namespace sharp {
|
|
|
269
280
|
*/
|
|
270
281
|
std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour);
|
|
271
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
|
+
|
|
272
293
|
} // namespace sharp
|
|
273
294
|
|
|
274
295
|
#endif // SRC_COMMON_H_
|