sharp 0.27.1 → 0.30.5
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 +19 -18
- package/binding.gyp +15 -14
- package/install/can-compile.js +11 -0
- package/install/dll-copy.js +10 -10
- package/install/libvips.js +128 -47
- package/lib/agent.js +1 -1
- package/lib/channel.js +38 -14
- package/lib/colour.js +51 -1
- package/lib/composite.js +19 -2
- package/lib/constructor.js +47 -46
- package/lib/input.js +112 -18
- package/lib/is.js +19 -5
- package/lib/libvips.js +64 -29
- package/lib/operation.js +239 -35
- package/lib/output.js +398 -116
- package/lib/platform.js +5 -3
- package/lib/resize.js +61 -15
- package/lib/sharp.js +32 -0
- package/lib/utility.js +58 -19
- package/package.json +46 -24
- package/src/common.cc +202 -52
- package/src/common.h +59 -10
- package/src/libvips/cplusplus/VConnection.cpp +0 -26
- package/src/libvips/cplusplus/VImage.cpp +88 -32
- package/src/libvips/cplusplus/VInterpolate.cpp +0 -13
- package/src/libvips/cplusplus/vips-operators.cpp +213 -1
- package/src/metadata.cc +26 -0
- package/src/metadata.h +4 -0
- package/src/operations.cc +141 -7
- package/src/operations.h +32 -3
- package/src/pipeline.cc +454 -306
- package/src/pipeline.h +64 -29
- package/src/sharp.cc +1 -0
- package/src/utilities.cc +17 -1
- package/src/utilities.h +1 -0
package/src/operations.cc
CHANGED
|
@@ -92,6 +92,13 @@ namespace sharp {
|
|
|
92
92
|
return image;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/*
|
|
96
|
+
* Contrast limiting adapative histogram equalization (CLAHE)
|
|
97
|
+
*/
|
|
98
|
+
VImage Clahe(VImage image, int const width, int const height, int const maxSlope) {
|
|
99
|
+
return image.hist_local(width, height, VImage::option()->set("max_slope", maxSlope));
|
|
100
|
+
}
|
|
101
|
+
|
|
95
102
|
/*
|
|
96
103
|
* Gamma encoding/decoding
|
|
97
104
|
*/
|
|
@@ -105,6 +112,19 @@ namespace sharp {
|
|
|
105
112
|
}
|
|
106
113
|
}
|
|
107
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Produce the "negative" of the image.
|
|
117
|
+
*/
|
|
118
|
+
VImage Negate(VImage image, bool const negateAlpha) {
|
|
119
|
+
if (HasAlpha(image) && !negateAlpha) {
|
|
120
|
+
// Separate alpha channel
|
|
121
|
+
VImage alpha = image[image.bands() - 1];
|
|
122
|
+
return RemoveAlpha(image).invert().bandjoin(alpha);
|
|
123
|
+
} else {
|
|
124
|
+
return image.invert();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
108
128
|
/*
|
|
109
129
|
* Gaussian blur. Use sigma of -1.0 for fast blur.
|
|
110
130
|
*/
|
|
@@ -149,8 +169,8 @@ namespace sharp {
|
|
|
149
169
|
*/
|
|
150
170
|
VImage Recomb(VImage image, std::unique_ptr<double[]> const &matrix) {
|
|
151
171
|
double *m = matrix.get();
|
|
172
|
+
image = image.colourspace(VIPS_INTERPRETATION_sRGB);
|
|
152
173
|
return image
|
|
153
|
-
.colourspace(VIPS_INTERPRETATION_sRGB)
|
|
154
174
|
.recomb(image.bands() == 3
|
|
155
175
|
? VImage::new_from_memory(
|
|
156
176
|
m, 9 * sizeof(double), 3, 3, 1, VIPS_FORMAT_DOUBLE
|
|
@@ -162,7 +182,8 @@ namespace sharp {
|
|
|
162
182
|
0.0, 0.0, 0.0, 1.0));
|
|
163
183
|
}
|
|
164
184
|
|
|
165
|
-
VImage Modulate(VImage image, double const brightness, double const saturation,
|
|
185
|
+
VImage Modulate(VImage image, double const brightness, double const saturation,
|
|
186
|
+
int const hue, double const lightness) {
|
|
166
187
|
if (HasAlpha(image)) {
|
|
167
188
|
// Separate alpha channel
|
|
168
189
|
VImage alpha = image[image.bands() - 1];
|
|
@@ -170,7 +191,7 @@ namespace sharp {
|
|
|
170
191
|
.colourspace(VIPS_INTERPRETATION_LCH)
|
|
171
192
|
.linear(
|
|
172
193
|
{ brightness, saturation, 1},
|
|
173
|
-
{
|
|
194
|
+
{ lightness, 0.0, static_cast<double>(hue) }
|
|
174
195
|
)
|
|
175
196
|
.colourspace(VIPS_INTERPRETATION_sRGB)
|
|
176
197
|
.bandjoin(alpha);
|
|
@@ -179,7 +200,7 @@ namespace sharp {
|
|
|
179
200
|
.colourspace(VIPS_INTERPRETATION_LCH)
|
|
180
201
|
.linear(
|
|
181
202
|
{ brightness, saturation, 1 },
|
|
182
|
-
{
|
|
203
|
+
{ lightness, 0.0, static_cast<double>(hue) }
|
|
183
204
|
)
|
|
184
205
|
.colourspace(VIPS_INTERPRETATION_sRGB);
|
|
185
206
|
}
|
|
@@ -188,7 +209,8 @@ namespace sharp {
|
|
|
188
209
|
/*
|
|
189
210
|
* Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen.
|
|
190
211
|
*/
|
|
191
|
-
VImage Sharpen(VImage image, double const sigma, double const
|
|
212
|
+
VImage Sharpen(VImage image, double const sigma, double const m1, double const m2,
|
|
213
|
+
double const x1, double const y2, double const y3) {
|
|
192
214
|
if (sigma == -1.0) {
|
|
193
215
|
// Fast, mild sharpen
|
|
194
216
|
VImage sharpen = VImage::new_matrixv(3, 3,
|
|
@@ -203,8 +225,14 @@ namespace sharp {
|
|
|
203
225
|
if (colourspaceBeforeSharpen == VIPS_INTERPRETATION_RGB) {
|
|
204
226
|
colourspaceBeforeSharpen = VIPS_INTERPRETATION_sRGB;
|
|
205
227
|
}
|
|
206
|
-
return image
|
|
207
|
-
VImage::option()
|
|
228
|
+
return image
|
|
229
|
+
.sharpen(VImage::option()
|
|
230
|
+
->set("sigma", sigma)
|
|
231
|
+
->set("m1", m1)
|
|
232
|
+
->set("m2", m2)
|
|
233
|
+
->set("x1", x1)
|
|
234
|
+
->set("y2", y2)
|
|
235
|
+
->set("y3", y3))
|
|
208
236
|
.colourspace(colourspaceBeforeSharpen);
|
|
209
237
|
}
|
|
210
238
|
}
|
|
@@ -275,4 +303,110 @@ namespace sharp {
|
|
|
275
303
|
return image.linear(a, b);
|
|
276
304
|
}
|
|
277
305
|
}
|
|
306
|
+
|
|
307
|
+
/*
|
|
308
|
+
* Ensure the image is in a given colourspace
|
|
309
|
+
*/
|
|
310
|
+
VImage EnsureColourspace(VImage image, VipsInterpretation colourspace) {
|
|
311
|
+
if (colourspace != VIPS_INTERPRETATION_LAST && image.interpretation() != colourspace) {
|
|
312
|
+
image = image.colourspace(colourspace,
|
|
313
|
+
VImage::option()->set("source_space", image.interpretation()));
|
|
314
|
+
}
|
|
315
|
+
return image;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/*
|
|
319
|
+
* Split and crop each frame, reassemble, and update pageHeight.
|
|
320
|
+
*/
|
|
321
|
+
VImage CropMultiPage(VImage image, int left, int top, int width, int height,
|
|
322
|
+
int nPages, int *pageHeight) {
|
|
323
|
+
if (top == 0 && height == *pageHeight) {
|
|
324
|
+
// Fast path; no need to adjust the height of the multi-page image
|
|
325
|
+
return image.extract_area(left, 0, width, image.height());
|
|
326
|
+
} else {
|
|
327
|
+
std::vector<VImage> pages;
|
|
328
|
+
pages.reserve(nPages);
|
|
329
|
+
|
|
330
|
+
// Split the image into cropped frames
|
|
331
|
+
for (int i = 0; i < nPages; i++) {
|
|
332
|
+
pages.push_back(
|
|
333
|
+
image.extract_area(left, *pageHeight * i + top, width, height));
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Reassemble the frames into a tall, thin image
|
|
337
|
+
VImage assembled = VImage::arrayjoin(pages,
|
|
338
|
+
VImage::option()->set("across", 1));
|
|
339
|
+
|
|
340
|
+
// Update the page height
|
|
341
|
+
*pageHeight = height;
|
|
342
|
+
|
|
343
|
+
return assembled;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/*
|
|
348
|
+
* Split into frames, embed each frame, reassemble, and update pageHeight.
|
|
349
|
+
*/
|
|
350
|
+
VImage EmbedMultiPage(VImage image, int left, int top, int width, int height,
|
|
351
|
+
std::vector<double> background, int nPages, int *pageHeight) {
|
|
352
|
+
if (top == 0 && height == *pageHeight) {
|
|
353
|
+
// Fast path; no need to adjust the height of the multi-page image
|
|
354
|
+
return image.embed(left, 0, width, image.height(), VImage::option()
|
|
355
|
+
->set("extend", VIPS_EXTEND_BACKGROUND)
|
|
356
|
+
->set("background", background));
|
|
357
|
+
} else if (left == 0 && width == image.width()) {
|
|
358
|
+
// Fast path; no need to adjust the width of the multi-page image
|
|
359
|
+
std::vector<VImage> pages;
|
|
360
|
+
pages.reserve(nPages);
|
|
361
|
+
|
|
362
|
+
// Rearrange the tall image into a vertical grid
|
|
363
|
+
image = image.grid(*pageHeight, nPages, 1);
|
|
364
|
+
|
|
365
|
+
// Do the embed on the wide image
|
|
366
|
+
image = image.embed(0, top, image.width(), height, VImage::option()
|
|
367
|
+
->set("extend", VIPS_EXTEND_BACKGROUND)
|
|
368
|
+
->set("background", background));
|
|
369
|
+
|
|
370
|
+
// Split the wide image into frames
|
|
371
|
+
for (int i = 0; i < nPages; i++) {
|
|
372
|
+
pages.push_back(
|
|
373
|
+
image.extract_area(width * i, 0, width, height));
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Reassemble the frames into a tall, thin image
|
|
377
|
+
VImage assembled = VImage::arrayjoin(pages,
|
|
378
|
+
VImage::option()->set("across", 1));
|
|
379
|
+
|
|
380
|
+
// Update the page height
|
|
381
|
+
*pageHeight = height;
|
|
382
|
+
|
|
383
|
+
return assembled;
|
|
384
|
+
} else {
|
|
385
|
+
std::vector<VImage> pages;
|
|
386
|
+
pages.reserve(nPages);
|
|
387
|
+
|
|
388
|
+
// Split the image into frames
|
|
389
|
+
for (int i = 0; i < nPages; i++) {
|
|
390
|
+
pages.push_back(
|
|
391
|
+
image.extract_area(0, *pageHeight * i, image.width(), *pageHeight));
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Embed each frame in the target size
|
|
395
|
+
for (int i = 0; i < nPages; i++) {
|
|
396
|
+
pages[i] = pages[i].embed(left, top, width, height, VImage::option()
|
|
397
|
+
->set("extend", VIPS_EXTEND_BACKGROUND)
|
|
398
|
+
->set("background", background));
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Reassemble the frames into a tall, thin image
|
|
402
|
+
VImage assembled = VImage::arrayjoin(pages,
|
|
403
|
+
VImage::option()->set("across", 1));
|
|
404
|
+
|
|
405
|
+
// Update the page height
|
|
406
|
+
*pageHeight = height;
|
|
407
|
+
|
|
408
|
+
return assembled;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
278
412
|
} // namespace sharp
|
package/src/operations.h
CHANGED
|
@@ -35,11 +35,21 @@ namespace sharp {
|
|
|
35
35
|
*/
|
|
36
36
|
VImage Normalise(VImage image);
|
|
37
37
|
|
|
38
|
+
/*
|
|
39
|
+
* Contrast limiting adapative histogram equalization (CLAHE)
|
|
40
|
+
*/
|
|
41
|
+
VImage Clahe(VImage image, int const width, int const height, int const maxSlope);
|
|
42
|
+
|
|
38
43
|
/*
|
|
39
44
|
* Gamma encoding/decoding
|
|
40
45
|
*/
|
|
41
46
|
VImage Gamma(VImage image, double const exponent);
|
|
42
47
|
|
|
48
|
+
/*
|
|
49
|
+
* Produce the "negative" of the image.
|
|
50
|
+
*/
|
|
51
|
+
VImage Negate(VImage image, bool const negateAlpha);
|
|
52
|
+
|
|
43
53
|
/*
|
|
44
54
|
* Gaussian blur. Use sigma of -1.0 for fast blur.
|
|
45
55
|
*/
|
|
@@ -54,7 +64,8 @@ namespace sharp {
|
|
|
54
64
|
/*
|
|
55
65
|
* Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen.
|
|
56
66
|
*/
|
|
57
|
-
VImage Sharpen(VImage image, double const sigma, double const
|
|
67
|
+
VImage Sharpen(VImage image, double const sigma, double const m1, double const m2,
|
|
68
|
+
double const x1, double const y2, double const y3);
|
|
58
69
|
|
|
59
70
|
/*
|
|
60
71
|
Threshold an image
|
|
@@ -88,9 +99,27 @@ namespace sharp {
|
|
|
88
99
|
VImage Recomb(VImage image, std::unique_ptr<double[]> const &matrix);
|
|
89
100
|
|
|
90
101
|
/*
|
|
91
|
-
* Modulate brightness, saturation and
|
|
102
|
+
* Modulate brightness, saturation, hue and lightness
|
|
103
|
+
*/
|
|
104
|
+
VImage Modulate(VImage image, double const brightness, double const saturation,
|
|
105
|
+
int const hue, double const lightness);
|
|
106
|
+
|
|
107
|
+
/*
|
|
108
|
+
* Ensure the image is in a given colourspace
|
|
109
|
+
*/
|
|
110
|
+
VImage EnsureColourspace(VImage image, VipsInterpretation colourspace);
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
* Split and crop each frame, reassemble, and update pageHeight.
|
|
114
|
+
*/
|
|
115
|
+
VImage CropMultiPage(VImage image, int left, int top, int width, int height,
|
|
116
|
+
int nPages, int *pageHeight);
|
|
117
|
+
|
|
118
|
+
/*
|
|
119
|
+
* Split into frames, embed each frame, reassemble, and update pageHeight.
|
|
92
120
|
*/
|
|
93
|
-
VImage
|
|
121
|
+
VImage EmbedMultiPage(VImage image, int left, int top, int width, int height,
|
|
122
|
+
std::vector<double> background, int nPages, int *pageHeight);
|
|
94
123
|
|
|
95
124
|
} // namespace sharp
|
|
96
125
|
|