sharp 0.17.2 → 0.18.2
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/CONTRIBUTING.md +1 -7
- package/binding.gyp +1 -1
- package/binding.js +14 -14
- package/docs/api-colour.md +2 -2
- package/docs/api-composite.md +11 -3
- package/docs/api-constructor.md +25 -5
- package/docs/api-input.md +4 -3
- package/docs/api-operation.md +20 -17
- package/docs/api-output.md +39 -30
- package/docs/api-resize.md +9 -8
- package/docs/api-utility.md +4 -4
- package/docs/changelog.md +103 -0
- package/docs/index.md +4 -1
- package/docs/install.md +44 -14
- package/lib/channel.js +6 -6
- package/lib/colour.js +10 -10
- package/lib/composite.js +11 -6
- package/lib/constructor.js +41 -18
- package/lib/input.js +52 -24
- package/lib/is.js +9 -0
- package/lib/operation.js +41 -38
- package/lib/output.js +103 -112
- package/lib/resize.js +25 -20
- package/lib/utility.js +8 -8
- package/package.json +22 -18
- package/src/common.cc +94 -20
- package/src/common.h +30 -3
- package/src/libvips/cplusplus/VImage.cpp +110 -104
- package/src/libvips/cplusplus/vips-operators.cpp +108 -44
- package/src/metadata.cc +19 -4
- package/src/metadata.h +1 -0
- package/src/operations.cc +18 -165
- package/src/operations.h +4 -26
- package/src/pipeline.cc +201 -97
- package/src/pipeline.h +14 -0
- package/src/sharp.cc +3 -0
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.18.2",
|
|
5
5
|
"author": "Lovell Fuller <npm@lovell.info>",
|
|
6
6
|
"homepage": "https://github.com/lovell/sharp",
|
|
7
7
|
"contributors": [
|
|
@@ -32,11 +32,16 @@
|
|
|
32
32
|
"Matthias Thoemmes <thoemmes@gmail.com>",
|
|
33
33
|
"Patrick Paskaris <patrick@paskaris.gr>",
|
|
34
34
|
"Jérémy Lal <kapouer@melix.org>",
|
|
35
|
-
"Rahul Nanwani <r.nanwani@gmail.com>"
|
|
35
|
+
"Rahul Nanwani <r.nanwani@gmail.com>",
|
|
36
|
+
"Alice Monday <alice0meta@gmail.com>",
|
|
37
|
+
"Kristo Jorgenson <kristo.jorgenson@gmail.com>",
|
|
38
|
+
"YvesBos <yves_bos@outlook.com>",
|
|
39
|
+
"Guy Maliar <guy@tailorbrands.com>",
|
|
40
|
+
"Nicolas Coden <nicolas@ncoden.fr>"
|
|
36
41
|
],
|
|
37
42
|
"scripts": {
|
|
38
43
|
"clean": "rm -rf node_modules/ build/ vendor/ coverage/ test/fixtures/output.*",
|
|
39
|
-
"test": "semistandard && cc &&
|
|
44
|
+
"test": "semistandard && cc && nyc --reporter=lcov --branches=99 mocha --slow=5000 --timeout=60000 ./test/unit/*.js",
|
|
40
45
|
"test-leak": "./test/leak/leak.sh",
|
|
41
46
|
"test-packaging": "./packaging/test-linux-x64.sh",
|
|
42
47
|
"docs": "for m in constructor input resize composite operation colour channel output utility; do documentation build --shallow --format=md lib/$m.js >docs/api-$m.md; done"
|
|
@@ -63,32 +68,30 @@
|
|
|
63
68
|
],
|
|
64
69
|
"dependencies": {
|
|
65
70
|
"caw": "^2.0.0",
|
|
66
|
-
"color": "^
|
|
67
|
-
"got": "^
|
|
68
|
-
"nan": "^2.
|
|
71
|
+
"color": "^2.0.0",
|
|
72
|
+
"got": "^7.1.0",
|
|
73
|
+
"nan": "^2.6.2",
|
|
69
74
|
"semver": "^5.3.0",
|
|
70
|
-
"tar": "^
|
|
75
|
+
"tar": "^3.1.5"
|
|
71
76
|
},
|
|
72
77
|
"devDependencies": {
|
|
73
|
-
"async": "^2.
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"cross-env": "^3.1.4",
|
|
77
|
-
"documentation": "^4.0.0-beta.18",
|
|
78
|
+
"async": "^2.5.0",
|
|
79
|
+
"cc": "^1.0.1",
|
|
80
|
+
"documentation": "^4.0.0-rc.1",
|
|
78
81
|
"exif-reader": "^1.0.2",
|
|
79
82
|
"icc": "^1.0.0",
|
|
80
|
-
"mocha": "^3.2
|
|
81
|
-
"nyc": "^
|
|
82
|
-
"rimraf": "^2.
|
|
83
|
-
"semistandard": "^
|
|
83
|
+
"mocha": "^3.4.2",
|
|
84
|
+
"nyc": "^11.0.3",
|
|
85
|
+
"rimraf": "^2.6.1",
|
|
86
|
+
"semistandard": "^11.0.0",
|
|
84
87
|
"unzip": "^0.1.11"
|
|
85
88
|
},
|
|
86
89
|
"license": "Apache-2.0",
|
|
87
90
|
"config": {
|
|
88
|
-
"libvips": "8.
|
|
91
|
+
"libvips": "8.5.5"
|
|
89
92
|
},
|
|
90
93
|
"engines": {
|
|
91
|
-
"node": ">=4"
|
|
94
|
+
"node": ">=4.5.0"
|
|
92
95
|
},
|
|
93
96
|
"semistandard": {
|
|
94
97
|
"env": [
|
|
@@ -98,6 +101,7 @@
|
|
|
98
101
|
"cc": {
|
|
99
102
|
"linelength": "120",
|
|
100
103
|
"filter": [
|
|
104
|
+
"build/c++11",
|
|
101
105
|
"build/include",
|
|
102
106
|
"runtime/indentation_namespace"
|
|
103
107
|
]
|
package/src/common.cc
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
#include <string>
|
|
17
17
|
#include <string.h>
|
|
18
18
|
#include <vector>
|
|
19
|
+
#include <queue>
|
|
20
|
+
#include <mutex>
|
|
19
21
|
|
|
20
22
|
#include <node.h>
|
|
21
23
|
#include <node_buffer.h>
|
|
@@ -44,7 +46,7 @@ namespace sharp {
|
|
|
44
46
|
InputDescriptor *descriptor = new InputDescriptor;
|
|
45
47
|
if (HasAttr(input, "file")) {
|
|
46
48
|
descriptor->file = AttrAsStr(input, "file");
|
|
47
|
-
} else {
|
|
49
|
+
} else if (HasAttr(input, "buffer")) {
|
|
48
50
|
v8::Local<v8::Object> buffer = AttrAs<v8::Object>(input, "buffer");
|
|
49
51
|
descriptor->bufferLength = node::Buffer::Length(buffer);
|
|
50
52
|
descriptor->buffer = node::Buffer::Data(buffer);
|
|
@@ -60,6 +62,16 @@ namespace sharp {
|
|
|
60
62
|
descriptor->rawWidth = AttrTo<uint32_t>(input, "rawWidth");
|
|
61
63
|
descriptor->rawHeight = AttrTo<uint32_t>(input, "rawHeight");
|
|
62
64
|
}
|
|
65
|
+
// Create new image
|
|
66
|
+
if (HasAttr(input, "createChannels")) {
|
|
67
|
+
descriptor->createChannels = AttrTo<uint32_t>(input, "createChannels");
|
|
68
|
+
descriptor->createWidth = AttrTo<uint32_t>(input, "createWidth");
|
|
69
|
+
descriptor->createHeight = AttrTo<uint32_t>(input, "createHeight");
|
|
70
|
+
v8::Local<v8::Object> createBackground = AttrAs<v8::Object>(input, "createBackground");
|
|
71
|
+
for (unsigned int i = 0; i < 4; i++) {
|
|
72
|
+
descriptor->createBackground[i] = AttrTo<double>(createBackground, i);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
63
75
|
return descriptor;
|
|
64
76
|
}
|
|
65
77
|
|
|
@@ -192,7 +204,6 @@ namespace sharp {
|
|
|
192
204
|
VImage image;
|
|
193
205
|
ImageType imageType;
|
|
194
206
|
if (descriptor->buffer != nullptr) {
|
|
195
|
-
// From buffer
|
|
196
207
|
if (descriptor->rawChannels > 0) {
|
|
197
208
|
// Raw, uncompressed pixel data
|
|
198
209
|
image = VImage::new_from_memory(descriptor->buffer, descriptor->bufferLength,
|
|
@@ -227,26 +238,41 @@ namespace sharp {
|
|
|
227
238
|
}
|
|
228
239
|
}
|
|
229
240
|
} else {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
option->set("density", std::to_string(descriptor->density).data());
|
|
240
|
-
}
|
|
241
|
-
image = VImage::new_from_file(descriptor->file.data(), option);
|
|
242
|
-
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
|
243
|
-
SetDensity(image, descriptor->density);
|
|
244
|
-
}
|
|
245
|
-
} catch (...) {
|
|
246
|
-
throw vips::VError("Input file has corrupt header");
|
|
241
|
+
if (descriptor->createChannels > 0) {
|
|
242
|
+
// Create new image
|
|
243
|
+
std::vector<double> background = {
|
|
244
|
+
descriptor->createBackground[0],
|
|
245
|
+
descriptor->createBackground[1],
|
|
246
|
+
descriptor->createBackground[2]
|
|
247
|
+
};
|
|
248
|
+
if (descriptor->createChannels == 4) {
|
|
249
|
+
background.push_back(descriptor->createBackground[3]);
|
|
247
250
|
}
|
|
251
|
+
image = VImage::new_matrix(descriptor->createWidth, descriptor->createHeight).new_from_image(background);
|
|
252
|
+
image.get_image()->Type = VIPS_INTERPRETATION_sRGB;
|
|
253
|
+
imageType = ImageType::RAW;
|
|
248
254
|
} else {
|
|
249
|
-
|
|
255
|
+
// From filesystem
|
|
256
|
+
imageType = DetermineImageType(descriptor->file.data());
|
|
257
|
+
if (imageType != ImageType::UNKNOWN) {
|
|
258
|
+
try {
|
|
259
|
+
vips::VOption *option = VImage::option()->set("access", accessMethod);
|
|
260
|
+
if (imageType == ImageType::SVG || imageType == ImageType::PDF) {
|
|
261
|
+
option->set("dpi", static_cast<double>(descriptor->density));
|
|
262
|
+
}
|
|
263
|
+
if (imageType == ImageType::MAGICK) {
|
|
264
|
+
option->set("density", std::to_string(descriptor->density).data());
|
|
265
|
+
}
|
|
266
|
+
image = VImage::new_from_file(descriptor->file.data(), option);
|
|
267
|
+
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
|
268
|
+
SetDensity(image, descriptor->density);
|
|
269
|
+
}
|
|
270
|
+
} catch (...) {
|
|
271
|
+
throw vips::VError("Input file has corrupt header");
|
|
272
|
+
}
|
|
273
|
+
} else {
|
|
274
|
+
throw vips::VError("Input file is missing or of an unsupported image format");
|
|
275
|
+
}
|
|
250
276
|
}
|
|
251
277
|
}
|
|
252
278
|
return std::make_tuple(image, imageType);
|
|
@@ -321,6 +347,25 @@ namespace sharp {
|
|
|
321
347
|
image.set(VIPS_META_RESOLUTION_UNIT, "in");
|
|
322
348
|
}
|
|
323
349
|
|
|
350
|
+
/*
|
|
351
|
+
Check the proposed format supports the current dimensions.
|
|
352
|
+
*/
|
|
353
|
+
void AssertImageTypeDimensions(VImage image, ImageType const imageType) {
|
|
354
|
+
if (imageType == ImageType::JPEG) {
|
|
355
|
+
if (image.width() > 65535 || image.height() > 65535) {
|
|
356
|
+
throw vips::VError("Processed image is too large for the JPEG format");
|
|
357
|
+
}
|
|
358
|
+
} else if (imageType == ImageType::PNG) {
|
|
359
|
+
if (image.width() > 2147483647 || image.height() > 2147483647) {
|
|
360
|
+
throw vips::VError("Processed image is too large for the PNG format");
|
|
361
|
+
}
|
|
362
|
+
} else if (imageType == ImageType::WEBP) {
|
|
363
|
+
if (image.width() > 16383 || image.height() > 16383) {
|
|
364
|
+
throw vips::VError("Processed image is too large for the WebP format");
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
324
369
|
/*
|
|
325
370
|
Called when a Buffer undergoes GC, required to support mixed runtime libraries in Windows
|
|
326
371
|
*/
|
|
@@ -330,6 +375,33 @@ namespace sharp {
|
|
|
330
375
|
}
|
|
331
376
|
}
|
|
332
377
|
|
|
378
|
+
/*
|
|
379
|
+
Temporary buffer of warnings
|
|
380
|
+
*/
|
|
381
|
+
std::queue<std::string> vipsWarnings;
|
|
382
|
+
std::mutex vipsWarningsMutex;
|
|
383
|
+
|
|
384
|
+
/*
|
|
385
|
+
Called with warnings from the glib-registered "VIPS" domain
|
|
386
|
+
*/
|
|
387
|
+
void VipsWarningCallback(char const* log_domain, GLogLevelFlags log_level, char const* message, void* ignore) {
|
|
388
|
+
std::lock_guard<std::mutex> lock(vipsWarningsMutex);
|
|
389
|
+
vipsWarnings.emplace(message);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/*
|
|
393
|
+
Pop the oldest warning message from the queue
|
|
394
|
+
*/
|
|
395
|
+
std::string VipsWarningPop() {
|
|
396
|
+
std::string warning;
|
|
397
|
+
std::lock_guard<std::mutex> lock(vipsWarningsMutex);
|
|
398
|
+
if (!vipsWarnings.empty()) {
|
|
399
|
+
warning = vipsWarnings.front();
|
|
400
|
+
vipsWarnings.pop();
|
|
401
|
+
}
|
|
402
|
+
return warning;
|
|
403
|
+
}
|
|
404
|
+
|
|
333
405
|
/*
|
|
334
406
|
Calculate the (left, top) coordinates of the output image
|
|
335
407
|
within the input image, applying the given gravity.
|
|
@@ -366,9 +438,11 @@ namespace sharp {
|
|
|
366
438
|
// Southeast
|
|
367
439
|
left = inWidth - outWidth;
|
|
368
440
|
top = inHeight - outHeight;
|
|
441
|
+
break;
|
|
369
442
|
case 7:
|
|
370
443
|
// Southwest
|
|
371
444
|
top = inHeight - outHeight;
|
|
445
|
+
break;
|
|
372
446
|
case 8:
|
|
373
447
|
// Northwest
|
|
374
448
|
break;
|
package/src/common.h
CHANGED
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
|
|
26
26
|
// Verify platform and compiler compatibility
|
|
27
27
|
|
|
28
|
-
#if (VIPS_MAJOR_VERSION < 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION <
|
|
29
|
-
#error libvips version 8.
|
|
28
|
+
#if (VIPS_MAJOR_VERSION < 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 5))
|
|
29
|
+
#error libvips version 8.5.x required - see sharp.dimens.io/page/install
|
|
30
30
|
#endif
|
|
31
31
|
|
|
32
32
|
#if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
|
|
@@ -52,6 +52,10 @@ namespace sharp {
|
|
|
52
52
|
int rawChannels;
|
|
53
53
|
int rawWidth;
|
|
54
54
|
int rawHeight;
|
|
55
|
+
int createChannels;
|
|
56
|
+
int createWidth;
|
|
57
|
+
int createHeight;
|
|
58
|
+
double createBackground[4];
|
|
55
59
|
|
|
56
60
|
InputDescriptor():
|
|
57
61
|
buffer(nullptr),
|
|
@@ -59,7 +63,15 @@ namespace sharp {
|
|
|
59
63
|
density(72),
|
|
60
64
|
rawChannels(0),
|
|
61
65
|
rawWidth(0),
|
|
62
|
-
rawHeight(0)
|
|
66
|
+
rawHeight(0),
|
|
67
|
+
createChannels(0),
|
|
68
|
+
createWidth(0),
|
|
69
|
+
createHeight(0) {
|
|
70
|
+
createBackground[0] = 0.0;
|
|
71
|
+
createBackground[1] = 0.0;
|
|
72
|
+
createBackground[2] = 0.0;
|
|
73
|
+
createBackground[3] = 255.0;
|
|
74
|
+
}
|
|
63
75
|
};
|
|
64
76
|
|
|
65
77
|
// Convenience methods to access the attributes of a v8::Object
|
|
@@ -172,11 +184,26 @@ namespace sharp {
|
|
|
172
184
|
*/
|
|
173
185
|
void SetDensity(VImage image, const int density);
|
|
174
186
|
|
|
187
|
+
/*
|
|
188
|
+
Check the proposed format supports the current dimensions.
|
|
189
|
+
*/
|
|
190
|
+
void AssertImageTypeDimensions(VImage image, ImageType const imageType);
|
|
191
|
+
|
|
175
192
|
/*
|
|
176
193
|
Called when a Buffer undergoes GC, required to support mixed runtime libraries in Windows
|
|
177
194
|
*/
|
|
178
195
|
void FreeCallback(char* data, void* hint);
|
|
179
196
|
|
|
197
|
+
/*
|
|
198
|
+
Called with warnings from the glib-registered "VIPS" domain
|
|
199
|
+
*/
|
|
200
|
+
void VipsWarningCallback(char const* log_domain, GLogLevelFlags log_level, char const* message, void* ignore);
|
|
201
|
+
|
|
202
|
+
/*
|
|
203
|
+
Pop the oldest warning message from the queue
|
|
204
|
+
*/
|
|
205
|
+
std::string VipsWarningPop();
|
|
206
|
+
|
|
180
207
|
/*
|
|
181
208
|
Calculate the (left, top) coordinates of the output image
|
|
182
209
|
within the input image, applying the given gravity.
|