sharp 0.20.8 → 0.21.3
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 +13 -11
- package/binding.gyp +16 -1
- package/docs/api-channel.md +16 -0
- package/docs/api-colour.md +1 -19
- package/docs/api-composite.md +2 -3
- package/docs/api-constructor.md +2 -3
- package/docs/api-input.md +7 -2
- package/docs/api-operation.md +73 -115
- package/docs/api-output.md +9 -0
- package/docs/api-resize.md +160 -108
- package/docs/api-utility.md +4 -7
- package/docs/changelog.md +102 -0
- package/docs/image/sharp-logo.svg +5 -0
- package/docs/index.md +12 -6
- package/docs/install.md +41 -42
- package/docs/performance.md +14 -21
- package/install/libvips.js +28 -24
- package/lib/channel.js +20 -4
- package/lib/colour.js +35 -18
- package/lib/composite.js +2 -3
- package/lib/constructor.js +27 -42
- package/lib/input.js +9 -6
- package/lib/libvips.js +7 -1
- package/lib/operation.js +81 -123
- package/lib/output.js +128 -60
- package/lib/platform.js +4 -1
- package/lib/resize.js +310 -107
- package/lib/utility.js +5 -8
- package/package.json +30 -21
- package/src/common.cc +59 -14
- package/src/common.h +15 -12
- package/src/libvips/cplusplus/VImage.cpp +95 -95
- package/src/libvips/cplusplus/vips-operators.cpp +268 -185
- package/src/metadata.cc +34 -1
- package/src/metadata.h +10 -1
- package/src/operations.cc +47 -49
- package/src/operations.h +13 -2
- package/src/pipeline.cc +101 -95
- package/src/pipeline.h +40 -14
- package/src/sharp.cc +1 -1
- package/src/stats.cc +1 -1
- package/src/stats.h +1 -1
- package/src/utilities.cc +2 -2
- package/src/utilities.h +1 -1
package/src/metadata.cc
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright 2013, 2014, 2015, 2016, 2017 Lovell Fuller and contributors.
|
|
1
|
+
// Copyright 2013, 2014, 2015, 2016, 2017, 2018, 2019 Lovell Fuller and contributors.
|
|
2
2
|
//
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -62,6 +62,21 @@ class MetadataWorker : public Nan::AsyncWorker {
|
|
|
62
62
|
if (sharp::HasDensity(image)) {
|
|
63
63
|
baton->density = sharp::GetDensity(image);
|
|
64
64
|
}
|
|
65
|
+
if (image.get_typeof("jpeg-chroma-subsample") == VIPS_TYPE_REF_STRING) {
|
|
66
|
+
baton->chromaSubsampling = image.get_string("jpeg-chroma-subsample");
|
|
67
|
+
}
|
|
68
|
+
if (image.get_typeof("interlaced") == G_TYPE_INT) {
|
|
69
|
+
baton->isProgressive = image.get_int("interlaced") == 1;
|
|
70
|
+
}
|
|
71
|
+
if (image.get_typeof("palette-bit-depth") == G_TYPE_INT) {
|
|
72
|
+
baton->paletteBitDepth = image.get_int("palette-bit-depth");
|
|
73
|
+
}
|
|
74
|
+
if (image.get_typeof(VIPS_META_N_PAGES) == G_TYPE_INT) {
|
|
75
|
+
baton->pages = image.get_int(VIPS_META_N_PAGES);
|
|
76
|
+
}
|
|
77
|
+
if (image.get_typeof(VIPS_META_PAGE_HEIGHT) == G_TYPE_INT) {
|
|
78
|
+
baton->pageHeight = image.get_int(VIPS_META_PAGE_HEIGHT);
|
|
79
|
+
}
|
|
65
80
|
baton->hasProfile = sharp::HasProfile(image);
|
|
66
81
|
// Derived attributes
|
|
67
82
|
baton->hasAlpha = sharp::HasAlpha(image);
|
|
@@ -117,6 +132,9 @@ class MetadataWorker : public Nan::AsyncWorker {
|
|
|
117
132
|
// Metadata Object
|
|
118
133
|
v8::Local<v8::Object> info = New<v8::Object>();
|
|
119
134
|
Set(info, New("format").ToLocalChecked(), New<v8::String>(baton->format).ToLocalChecked());
|
|
135
|
+
if (baton->input->bufferLength > 0) {
|
|
136
|
+
Set(info, New("size").ToLocalChecked(), New<v8::Uint32>(static_cast<uint32_t>(baton->input->bufferLength)));
|
|
137
|
+
}
|
|
120
138
|
Set(info, New("width").ToLocalChecked(), New<v8::Uint32>(baton->width));
|
|
121
139
|
Set(info, New("height").ToLocalChecked(), New<v8::Uint32>(baton->height));
|
|
122
140
|
Set(info, New("space").ToLocalChecked(), New<v8::String>(baton->space).ToLocalChecked());
|
|
@@ -125,6 +143,21 @@ class MetadataWorker : public Nan::AsyncWorker {
|
|
|
125
143
|
if (baton->density > 0) {
|
|
126
144
|
Set(info, New("density").ToLocalChecked(), New<v8::Uint32>(baton->density));
|
|
127
145
|
}
|
|
146
|
+
if (!baton->chromaSubsampling.empty()) {
|
|
147
|
+
Set(info,
|
|
148
|
+
New("chromaSubsampling").ToLocalChecked(),
|
|
149
|
+
New<v8::String>(baton->chromaSubsampling).ToLocalChecked());
|
|
150
|
+
}
|
|
151
|
+
Set(info, New("isProgressive").ToLocalChecked(), New<v8::Boolean>(baton->isProgressive));
|
|
152
|
+
if (baton->paletteBitDepth > 0) {
|
|
153
|
+
Set(info, New("paletteBitDepth").ToLocalChecked(), New<v8::Uint32>(baton->paletteBitDepth));
|
|
154
|
+
}
|
|
155
|
+
if (baton->pages > 0) {
|
|
156
|
+
Set(info, New("pages").ToLocalChecked(), New<v8::Uint32>(baton->pages));
|
|
157
|
+
}
|
|
158
|
+
if (baton->pageHeight > 0) {
|
|
159
|
+
Set(info, New("pageHeight").ToLocalChecked(), New<v8::Uint32>(baton->pageHeight));
|
|
160
|
+
}
|
|
128
161
|
Set(info, New("hasProfile").ToLocalChecked(), New<v8::Boolean>(baton->hasProfile));
|
|
129
162
|
Set(info, New("hasAlpha").ToLocalChecked(), New<v8::Boolean>(baton->hasAlpha));
|
|
130
163
|
if (baton->orientation > 0) {
|
package/src/metadata.h
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright 2013, 2014, 2015, 2016, 2017 Lovell Fuller and contributors.
|
|
1
|
+
// Copyright 2013, 2014, 2015, 2016, 2017, 2018, 2019 Lovell Fuller and contributors.
|
|
2
2
|
//
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -31,6 +31,11 @@ struct MetadataBaton {
|
|
|
31
31
|
int channels;
|
|
32
32
|
std::string depth;
|
|
33
33
|
int density;
|
|
34
|
+
std::string chromaSubsampling;
|
|
35
|
+
bool isProgressive;
|
|
36
|
+
int paletteBitDepth;
|
|
37
|
+
int pages;
|
|
38
|
+
int pageHeight;
|
|
34
39
|
bool hasProfile;
|
|
35
40
|
bool hasAlpha;
|
|
36
41
|
int orientation;
|
|
@@ -50,6 +55,10 @@ struct MetadataBaton {
|
|
|
50
55
|
height(0),
|
|
51
56
|
channels(0),
|
|
52
57
|
density(0),
|
|
58
|
+
isProgressive(false),
|
|
59
|
+
paletteBitDepth(0),
|
|
60
|
+
pages(0),
|
|
61
|
+
pageHeight(0),
|
|
53
62
|
hasProfile(false),
|
|
54
63
|
hasAlpha(false),
|
|
55
64
|
orientation(0),
|
package/src/operations.cc
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright 2013, 2014, 2015, 2016, 2017 Lovell Fuller and contributors.
|
|
1
|
+
// Copyright 2013, 2014, 2015, 2016, 2017, 2018, 2019 Lovell Fuller and contributors.
|
|
2
2
|
//
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -38,6 +38,18 @@ namespace sharp {
|
|
|
38
38
|
return image;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/*
|
|
42
|
+
Ensures alpha channel, if missing.
|
|
43
|
+
*/
|
|
44
|
+
VImage EnsureAlpha(VImage image) {
|
|
45
|
+
if (!HasAlpha(image)) {
|
|
46
|
+
std::vector<double> alpha;
|
|
47
|
+
alpha.push_back(sharp::MaximumImageAlpha(image.interpretation()));
|
|
48
|
+
image = image.bandjoin_const(alpha);
|
|
49
|
+
}
|
|
50
|
+
return image;
|
|
51
|
+
}
|
|
52
|
+
|
|
41
53
|
/*
|
|
42
54
|
Composite overlayImage over image at given position
|
|
43
55
|
Assumes alpha channels are already premultiplied and will be unpremultiplied after
|
|
@@ -78,7 +90,7 @@ namespace sharp {
|
|
|
78
90
|
//
|
|
79
91
|
// References:
|
|
80
92
|
// - http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
|
|
81
|
-
// - https://github.com/
|
|
93
|
+
// - https://github.com/libvips/ruby-vips/issues/28#issuecomment-9014826
|
|
82
94
|
//
|
|
83
95
|
// out_a = src_a + dst_a * (1 - src_a)
|
|
84
96
|
// ^^^^^^^^^^^
|
|
@@ -278,6 +290,25 @@ namespace sharp {
|
|
|
278
290
|
return image.conv(kernel);
|
|
279
291
|
}
|
|
280
292
|
|
|
293
|
+
/*
|
|
294
|
+
* Recomb with a Matrix of the given bands/channel size.
|
|
295
|
+
* Eg. RGB will be a 3x3 matrix.
|
|
296
|
+
*/
|
|
297
|
+
VImage Recomb(VImage image, std::unique_ptr<double[]> const &matrix) {
|
|
298
|
+
double *m = matrix.get();
|
|
299
|
+
return image
|
|
300
|
+
.colourspace(VIPS_INTERPRETATION_sRGB)
|
|
301
|
+
.recomb(image.bands() == 3
|
|
302
|
+
? VImage::new_from_memory(
|
|
303
|
+
m, 9 * sizeof(double), 3, 3, 1, VIPS_FORMAT_DOUBLE
|
|
304
|
+
)
|
|
305
|
+
: VImage::new_matrixv(4, 4,
|
|
306
|
+
m[0], m[1], m[2], 0.0,
|
|
307
|
+
m[3], m[4], m[5], 0.0,
|
|
308
|
+
m[6], m[7], m[8], 0.0,
|
|
309
|
+
0.0, 0.0, 0.0, 1.0));
|
|
310
|
+
}
|
|
311
|
+
|
|
281
312
|
/*
|
|
282
313
|
* Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen.
|
|
283
314
|
*/
|
|
@@ -324,55 +355,22 @@ namespace sharp {
|
|
|
324
355
|
return image.boolean(imageR, boolean);
|
|
325
356
|
}
|
|
326
357
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
// we need to smooth the image, subtract the background from every pixel, take
|
|
343
|
-
// the absolute value of the difference, then threshold
|
|
344
|
-
VImage mask = (image.median(3) - background).abs() > (max * tolerance / 100);
|
|
345
|
-
|
|
346
|
-
// sum mask rows and columns, then search for the first non-zero sum in each
|
|
347
|
-
// direction
|
|
348
|
-
VImage rows;
|
|
349
|
-
VImage columns = mask.project(&rows);
|
|
350
|
-
|
|
351
|
-
VImage profileLeftV;
|
|
352
|
-
VImage profileLeftH = columns.profile(&profileLeftV);
|
|
353
|
-
|
|
354
|
-
VImage profileRightV;
|
|
355
|
-
VImage profileRightH = columns.fliphor().profile(&profileRightV);
|
|
356
|
-
|
|
357
|
-
VImage profileTopV;
|
|
358
|
-
VImage profileTopH = rows.profile(&profileTopV);
|
|
359
|
-
|
|
360
|
-
VImage profileBottomV;
|
|
361
|
-
VImage profileBottomH = rows.flipver().profile(&profileBottomV);
|
|
362
|
-
|
|
363
|
-
int left = static_cast<int>(floor(profileLeftV.min()));
|
|
364
|
-
int right = columns.width() - static_cast<int>(floor(profileRightV.min()));
|
|
365
|
-
int top = static_cast<int>(floor(profileTopH.min()));
|
|
366
|
-
int bottom = rows.height() - static_cast<int>(floor(profileBottomH.min()));
|
|
367
|
-
|
|
368
|
-
int width = right - left;
|
|
369
|
-
int height = bottom - top;
|
|
370
|
-
|
|
371
|
-
if (width <= 0 || height <= 0) {
|
|
358
|
+
/*
|
|
359
|
+
Trim an image
|
|
360
|
+
*/
|
|
361
|
+
VImage Trim(VImage image, double const threshold) {
|
|
362
|
+
// Top-left pixel provides the background colour
|
|
363
|
+
VImage background = image.extract_area(0, 0, 1, 1);
|
|
364
|
+
if (HasAlpha(background)) {
|
|
365
|
+
background = background.flatten();
|
|
366
|
+
}
|
|
367
|
+
int top, width, height;
|
|
368
|
+
int const left = image.find_trim(&top, &width, &height, VImage::option()
|
|
369
|
+
->set("background", background(0, 0))
|
|
370
|
+
->set("threshold", threshold));
|
|
371
|
+
if (width == 0 || height == 0) {
|
|
372
372
|
throw VError("Unexpected error while trimming. Try to lower the tolerance");
|
|
373
373
|
}
|
|
374
|
-
|
|
375
|
-
// and now crop the original image
|
|
376
374
|
return image.extract_area(left, top, width, height);
|
|
377
375
|
}
|
|
378
376
|
|
package/src/operations.h
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright 2013, 2014, 2015, 2016, 2017 Lovell Fuller and contributors.
|
|
1
|
+
// Copyright 2013, 2014, 2015, 2016, 2017, 2018, 2019 Lovell Fuller and contributors.
|
|
2
2
|
//
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -30,6 +30,11 @@ namespace sharp {
|
|
|
30
30
|
*/
|
|
31
31
|
VImage RemoveAlpha(VImage image);
|
|
32
32
|
|
|
33
|
+
/*
|
|
34
|
+
Ensures alpha channel, if missing.
|
|
35
|
+
*/
|
|
36
|
+
VImage EnsureAlpha(VImage image);
|
|
37
|
+
|
|
33
38
|
/*
|
|
34
39
|
Alpha composite src over dst with given gravity.
|
|
35
40
|
Assumes alpha channels are already premultiplied and will be unpremultiplied after.
|
|
@@ -100,13 +105,19 @@ namespace sharp {
|
|
|
100
105
|
/*
|
|
101
106
|
Trim an image
|
|
102
107
|
*/
|
|
103
|
-
VImage Trim(VImage image,
|
|
108
|
+
VImage Trim(VImage image, double const threshold);
|
|
104
109
|
|
|
105
110
|
/*
|
|
106
111
|
* Linear adjustment (a * in + b)
|
|
107
112
|
*/
|
|
108
113
|
VImage Linear(VImage image, double const a, double const b);
|
|
109
114
|
|
|
115
|
+
/*
|
|
116
|
+
* Recomb with a Matrix of the given bands/channel size.
|
|
117
|
+
* Eg. RGB will be a 3x3 matrix.
|
|
118
|
+
*/
|
|
119
|
+
VImage Recomb(VImage image, std::unique_ptr<double[]> const &matrix);
|
|
120
|
+
|
|
110
121
|
} // namespace sharp
|
|
111
122
|
|
|
112
123
|
#endif // SRC_OPERATIONS_H_
|