sharp 0.31.3 → 0.32.1
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 -3
- package/binding.gyp +1 -1
- package/install/can-compile.js +3 -0
- package/install/dll-copy.js +3 -0
- package/install/libvips.js +21 -15
- package/lib/agent.js +4 -1
- package/lib/channel.js +3 -0
- package/lib/colour.js +5 -1
- package/lib/composite.js +3 -0
- package/lib/constructor.js +20 -11
- package/lib/index.d.ts +1621 -0
- package/lib/index.js +3 -0
- package/lib/input.js +32 -6
- package/lib/is.js +12 -0
- package/lib/libvips.js +5 -2
- package/lib/operation.js +104 -37
- package/lib/output.js +31 -15
- package/lib/platform.js +3 -0
- package/lib/resize.js +52 -19
- package/lib/sharp.js +3 -0
- package/lib/utility.js +5 -1
- package/package.json +30 -23
- package/src/common.cc +26 -21
- package/src/common.h +19 -17
- package/src/libvips/cplusplus/vips-operators.cpp +7 -0
- package/src/metadata.cc +18 -22
- package/src/metadata.h +3 -13
- package/src/operations.cc +39 -44
- package/src/operations.h +9 -15
- package/src/pipeline.cc +88 -52
- package/src/pipeline.h +20 -15
- package/src/sharp.cc +2 -13
- package/src/stats.cc +6 -17
- package/src/stats.h +2 -13
- package/src/utilities.cc +16 -27
- package/src/utilities.h +2 -13
package/src/operations.h
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
// Copyright 2013
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
3
|
|
|
15
4
|
#ifndef SRC_OPERATIONS_H_
|
|
16
5
|
#define SRC_OPERATIONS_H_
|
|
@@ -33,7 +22,7 @@ namespace sharp {
|
|
|
33
22
|
/*
|
|
34
23
|
* Stretch luminance to cover full dynamic range.
|
|
35
24
|
*/
|
|
36
|
-
VImage Normalise(VImage image);
|
|
25
|
+
VImage Normalise(VImage image, int const lower, int const upper);
|
|
37
26
|
|
|
38
27
|
/*
|
|
39
28
|
* Contrast limiting adapative histogram equalization (CLAHE)
|
|
@@ -97,6 +86,11 @@ namespace sharp {
|
|
|
97
86
|
*/
|
|
98
87
|
VImage Linear(VImage image, std::vector<double> const a, std::vector<double> const b);
|
|
99
88
|
|
|
89
|
+
/*
|
|
90
|
+
* Unflatten
|
|
91
|
+
*/
|
|
92
|
+
VImage Unflatten(VImage image);
|
|
93
|
+
|
|
100
94
|
/*
|
|
101
95
|
* Recomb with a Matrix of the given bands/channel size.
|
|
102
96
|
* Eg. RGB will be a 3x3 matrix.
|
|
@@ -124,7 +118,7 @@ namespace sharp {
|
|
|
124
118
|
* Split into frames, embed each frame, reassemble, and update pageHeight.
|
|
125
119
|
*/
|
|
126
120
|
VImage EmbedMultiPage(VImage image, int left, int top, int width, int height,
|
|
127
|
-
std::vector<double> background, int nPages, int *pageHeight);
|
|
121
|
+
VipsExtend extendWith, std::vector<double> background, int nPages, int *pageHeight);
|
|
128
122
|
|
|
129
123
|
} // namespace sharp
|
|
130
124
|
|
package/src/pipeline.cc
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
// Copyright 2013
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
3
|
|
|
15
4
|
#include <algorithm>
|
|
16
5
|
#include <cmath>
|
|
@@ -85,6 +74,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
85
74
|
VipsAngle autoRotation = VIPS_ANGLE_D0;
|
|
86
75
|
bool autoFlip = FALSE;
|
|
87
76
|
bool autoFlop = FALSE;
|
|
77
|
+
|
|
88
78
|
if (baton->useExifOrientation) {
|
|
89
79
|
// Rotate and flip image according to Exif orientation
|
|
90
80
|
std::tie(autoRotation, autoFlip, autoFlop) = CalculateExifRotationAndFlip(sharp::ExifOrientation(image));
|
|
@@ -205,7 +195,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
205
195
|
if (jpegShrinkOnLoad > 1 && static_cast<int>(shrink) == jpegShrinkOnLoad) {
|
|
206
196
|
jpegShrinkOnLoad /= 2;
|
|
207
197
|
}
|
|
208
|
-
} else if (inputImageType == sharp::ImageType::WEBP && shrink > 1.0) {
|
|
198
|
+
} else if (inputImageType == sharp::ImageType::WEBP && baton->fastShrinkOnLoad && shrink > 1.0) {
|
|
209
199
|
// Avoid upscaling via webp
|
|
210
200
|
scale = 1.0 / shrink;
|
|
211
201
|
} else if (inputImageType == sharp::ImageType::SVG ||
|
|
@@ -320,7 +310,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
320
310
|
if (
|
|
321
311
|
sharp::HasProfile(image) &&
|
|
322
312
|
image.interpretation() != VIPS_INTERPRETATION_LABS &&
|
|
323
|
-
image.interpretation() != VIPS_INTERPRETATION_GREY16
|
|
313
|
+
image.interpretation() != VIPS_INTERPRETATION_GREY16 &&
|
|
314
|
+
!baton->input->ignoreIcc
|
|
324
315
|
) {
|
|
325
316
|
// Convert to sRGB/P3 using embedded profile
|
|
326
317
|
try {
|
|
@@ -329,9 +320,12 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
329
320
|
->set("depth", image.interpretation() == VIPS_INTERPRETATION_RGB16 ? 16 : 8)
|
|
330
321
|
->set("intent", VIPS_INTENT_PERCEPTUAL));
|
|
331
322
|
} catch(...) {
|
|
332
|
-
|
|
323
|
+
sharp::VipsWarningCallback(nullptr, G_LOG_LEVEL_WARNING, "Invalid embedded profile", nullptr);
|
|
333
324
|
}
|
|
334
|
-
} else if (
|
|
325
|
+
} else if (
|
|
326
|
+
image.interpretation() == VIPS_INTERPRETATION_CMYK &&
|
|
327
|
+
baton->colourspaceInput != VIPS_INTERPRETATION_CMYK
|
|
328
|
+
) {
|
|
335
329
|
image = image.icc_transform(processingProfile, VImage::option()
|
|
336
330
|
->set("input_profile", "cmyk")
|
|
337
331
|
->set("intent", VIPS_INTENT_PERCEPTUAL));
|
|
@@ -367,11 +361,12 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
367
361
|
image = sharp::EnsureAlpha(image, 1);
|
|
368
362
|
}
|
|
369
363
|
|
|
364
|
+
VipsBandFormat premultiplyFormat = image.format();
|
|
370
365
|
bool const shouldPremultiplyAlpha = sharp::HasAlpha(image) &&
|
|
371
366
|
(shouldResize || shouldBlur || shouldConv || shouldSharpen);
|
|
372
367
|
|
|
373
368
|
if (shouldPremultiplyAlpha) {
|
|
374
|
-
image = image.premultiply();
|
|
369
|
+
image = image.premultiply().cast(premultiplyFormat);
|
|
375
370
|
}
|
|
376
371
|
|
|
377
372
|
// Resize
|
|
@@ -399,7 +394,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
399
394
|
}
|
|
400
395
|
|
|
401
396
|
// Join additional color channels to the image
|
|
402
|
-
if (baton->joinChannelIn.
|
|
397
|
+
if (!baton->joinChannelIn.empty()) {
|
|
403
398
|
VImage joinImage;
|
|
404
399
|
sharp::ImageType joinImageType = sharp::ImageType::UNKNOWN;
|
|
405
400
|
|
|
@@ -409,6 +404,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
409
404
|
image = image.bandjoin(joinImage);
|
|
410
405
|
}
|
|
411
406
|
image = image.copy(VImage::option()->set("interpretation", baton->colourspace));
|
|
407
|
+
image = sharp::RemoveGifPalette(image);
|
|
412
408
|
}
|
|
413
409
|
|
|
414
410
|
inputWidth = image.width();
|
|
@@ -438,7 +434,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
438
434
|
|
|
439
435
|
image = nPages > 1
|
|
440
436
|
? sharp::EmbedMultiPage(image,
|
|
441
|
-
left, top, width, height, background, nPages, &targetPageHeight)
|
|
437
|
+
left, top, width, height, VIPS_EXTEND_BACKGROUND, background, nPages, &targetPageHeight)
|
|
442
438
|
: image.embed(left, top, width, height, VImage::option()
|
|
443
439
|
->set("extend", VIPS_EXTEND_BACKGROUND)
|
|
444
440
|
->set("background", background));
|
|
@@ -455,6 +451,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
455
451
|
// Gravity-based crop
|
|
456
452
|
int left;
|
|
457
453
|
int top;
|
|
454
|
+
|
|
458
455
|
std::tie(left, top) = sharp::CalculateCrop(
|
|
459
456
|
inputWidth, inputHeight, baton->width, baton->height, baton->position);
|
|
460
457
|
int width = std::min(inputWidth, baton->width);
|
|
@@ -465,16 +462,26 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
465
462
|
left, top, width, height, nPages, &targetPageHeight)
|
|
466
463
|
: image.extract_area(left, top, width, height);
|
|
467
464
|
} else {
|
|
465
|
+
int attention_x;
|
|
466
|
+
int attention_y;
|
|
467
|
+
|
|
468
468
|
// Attention-based or Entropy-based crop
|
|
469
469
|
MultiPageUnsupported(nPages, "Resize strategy");
|
|
470
470
|
image = image.tilecache(VImage::option()
|
|
471
471
|
->set("access", VIPS_ACCESS_RANDOM)
|
|
472
472
|
->set("threaded", TRUE));
|
|
473
|
+
|
|
473
474
|
image = image.smartcrop(baton->width, baton->height, VImage::option()
|
|
474
|
-
->set("interesting", baton->position == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION)
|
|
475
|
+
->set("interesting", baton->position == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION)
|
|
476
|
+
->set("premultiplied", shouldPremultiplyAlpha)
|
|
477
|
+
->set("attention_x", &attention_x)
|
|
478
|
+
->set("attention_y", &attention_y));
|
|
475
479
|
baton->hasCropOffset = true;
|
|
476
480
|
baton->cropOffsetLeft = static_cast<int>(image.xoffset());
|
|
477
481
|
baton->cropOffsetTop = static_cast<int>(image.yoffset());
|
|
482
|
+
baton->hasAttentionCenter = true;
|
|
483
|
+
baton->attentionX = static_cast<int>(attention_x * jpegShrinkOnLoad / scale);
|
|
484
|
+
baton->attentionY = static_cast<int>(attention_y * jpegShrinkOnLoad / scale);
|
|
478
485
|
}
|
|
479
486
|
}
|
|
480
487
|
}
|
|
@@ -503,7 +510,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
503
510
|
}
|
|
504
511
|
|
|
505
512
|
// Affine transform
|
|
506
|
-
if (baton->affineMatrix.
|
|
513
|
+
if (!baton->affineMatrix.empty()) {
|
|
507
514
|
MultiPageUnsupported(nPages, "Affine");
|
|
508
515
|
std::vector<double> background;
|
|
509
516
|
std::tie(image, background) = sharp::ApplyAlpha(image, baton->affineBackground, shouldPremultiplyAlpha);
|
|
@@ -519,24 +526,37 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
519
526
|
|
|
520
527
|
// Extend edges
|
|
521
528
|
if (baton->extendTop > 0 || baton->extendBottom > 0 || baton->extendLeft > 0 || baton->extendRight > 0) {
|
|
522
|
-
std::vector<double> background;
|
|
523
|
-
std::tie(image, background) = sharp::ApplyAlpha(image, baton->extendBackground, shouldPremultiplyAlpha);
|
|
524
|
-
|
|
525
529
|
// Embed
|
|
526
530
|
baton->width = image.width() + baton->extendLeft + baton->extendRight;
|
|
527
531
|
baton->height = (nPages > 1 ? targetPageHeight : image.height()) + baton->extendTop + baton->extendBottom;
|
|
528
532
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
533
|
+
if (baton->extendWith == VIPS_EXTEND_BACKGROUND) {
|
|
534
|
+
std::vector<double> background;
|
|
535
|
+
std::tie(image, background) = sharp::ApplyAlpha(image, baton->extendBackground, shouldPremultiplyAlpha);
|
|
536
|
+
|
|
537
|
+
image = nPages > 1
|
|
538
|
+
? sharp::EmbedMultiPage(image,
|
|
539
|
+
baton->extendLeft, baton->extendTop, baton->width, baton->height,
|
|
540
|
+
baton->extendWith, background, nPages, &targetPageHeight)
|
|
541
|
+
: image.embed(baton->extendLeft, baton->extendTop, baton->width, baton->height,
|
|
542
|
+
VImage::option()->set("extend", baton->extendWith)->set("background", background));
|
|
543
|
+
} else {
|
|
544
|
+
std::vector<double> ignoredBackground(1);
|
|
545
|
+
image = nPages > 1
|
|
546
|
+
? sharp::EmbedMultiPage(image,
|
|
547
|
+
baton->extendLeft, baton->extendTop, baton->width, baton->height,
|
|
548
|
+
baton->extendWith, ignoredBackground, nPages, &targetPageHeight)
|
|
549
|
+
: image.embed(baton->extendLeft, baton->extendTop, baton->width, baton->height,
|
|
550
|
+
VImage::option()->set("extend", baton->extendWith));
|
|
551
|
+
}
|
|
534
552
|
}
|
|
535
553
|
// Median - must happen before blurring, due to the utility of blurring after thresholding
|
|
536
554
|
if (baton->medianSize > 0) {
|
|
537
555
|
image = image.median(baton->medianSize);
|
|
538
556
|
}
|
|
557
|
+
|
|
539
558
|
// Threshold - must happen before blurring, due to the utility of blurring after thresholding
|
|
559
|
+
// Threshold - must happen before unflatten to enable non-white unflattening
|
|
540
560
|
if (baton->threshold != 0) {
|
|
541
561
|
image = sharp::Threshold(image, baton->threshold, baton->thresholdGrayscale);
|
|
542
562
|
}
|
|
@@ -546,6 +566,11 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
546
566
|
image = sharp::Blur(image, baton->blurSigma);
|
|
547
567
|
}
|
|
548
568
|
|
|
569
|
+
// Unflatten the image
|
|
570
|
+
if (baton->unflatten) {
|
|
571
|
+
image = sharp::Unflatten(image);
|
|
572
|
+
}
|
|
573
|
+
|
|
549
574
|
// Convolve
|
|
550
575
|
if (shouldConv) {
|
|
551
576
|
image = sharp::Convolve(image,
|
|
@@ -572,13 +597,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
572
597
|
|
|
573
598
|
// Reverse premultiplication after all transformations
|
|
574
599
|
if (shouldPremultiplyAlpha) {
|
|
575
|
-
image = image.unpremultiply();
|
|
576
|
-
// Cast pixel values to integer
|
|
577
|
-
if (sharp::Is16Bit(image.interpretation())) {
|
|
578
|
-
image = image.cast(VIPS_FORMAT_USHORT);
|
|
579
|
-
} else {
|
|
580
|
-
image = image.cast(VIPS_FORMAT_UCHAR);
|
|
581
|
-
}
|
|
600
|
+
image = image.unpremultiply().cast(premultiplyFormat);
|
|
582
601
|
}
|
|
583
602
|
baton->premultiplied = shouldPremultiplyAlpha;
|
|
584
603
|
|
|
@@ -660,6 +679,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
660
679
|
ys.push_back(top);
|
|
661
680
|
}
|
|
662
681
|
image = VImage::composite(images, modes, VImage::option()->set("x", xs)->set("y", ys));
|
|
682
|
+
image = sharp::RemoveGifPalette(image);
|
|
663
683
|
}
|
|
664
684
|
|
|
665
685
|
// Gamma decoding (brighten)
|
|
@@ -674,7 +694,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
674
694
|
|
|
675
695
|
// Apply normalisation - stretch luminance to cover full dynamic range
|
|
676
696
|
if (baton->normalise) {
|
|
677
|
-
image = sharp::Normalise(image);
|
|
697
|
+
image = sharp::Normalise(image, baton->normaliseLower, baton->normaliseUpper);
|
|
678
698
|
}
|
|
679
699
|
|
|
680
700
|
// Apply contrast limiting adaptive histogram equalization (CLAHE)
|
|
@@ -689,6 +709,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
689
709
|
std::tie(booleanImage, booleanImageType) = sharp::OpenInput(baton->boolean);
|
|
690
710
|
booleanImage = sharp::EnsureColourspace(booleanImage, baton->colourspaceInput);
|
|
691
711
|
image = sharp::Boolean(image, booleanImage, baton->booleanOp);
|
|
712
|
+
image = sharp::RemoveGifPalette(image);
|
|
692
713
|
}
|
|
693
714
|
|
|
694
715
|
// Apply per-channel Bandbool bitwise operations after all other operations
|
|
@@ -870,7 +891,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
870
891
|
->set("strip", !baton->withMetadata)
|
|
871
892
|
->set("bitdepth", baton->gifBitdepth)
|
|
872
893
|
->set("effort", baton->gifEffort)
|
|
873
|
-
->set("
|
|
894
|
+
->set("reuse", baton->gifReuse)
|
|
895
|
+
->set("interlace", baton->gifProgressive)
|
|
874
896
|
->set("interframe_maxerror", baton->gifInterFrameMaxError)
|
|
875
897
|
->set("interpalette_maxerror", baton->gifInterPaletteMaxError)
|
|
876
898
|
->set("dither", baton->gifDither)));
|
|
@@ -1068,7 +1090,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1068
1090
|
->set("strip", !baton->withMetadata)
|
|
1069
1091
|
->set("bitdepth", baton->gifBitdepth)
|
|
1070
1092
|
->set("effort", baton->gifEffort)
|
|
1071
|
-
->set("
|
|
1093
|
+
->set("reuse", baton->gifReuse)
|
|
1094
|
+
->set("interlace", baton->gifProgressive)
|
|
1072
1095
|
->set("dither", baton->gifDither));
|
|
1073
1096
|
baton->formatOut = "gif";
|
|
1074
1097
|
} else if (baton->formatOut == "tiff" || (mightMatchInput && isTiff) ||
|
|
@@ -1164,7 +1187,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1164
1187
|
// Handle warnings
|
|
1165
1188
|
std::string warning = sharp::VipsWarningPop();
|
|
1166
1189
|
while (!warning.empty()) {
|
|
1167
|
-
debuglog.
|
|
1190
|
+
debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
|
|
1168
1191
|
warning = sharp::VipsWarningPop();
|
|
1169
1192
|
}
|
|
1170
1193
|
|
|
@@ -1193,6 +1216,10 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1193
1216
|
info.Set("cropOffsetLeft", static_cast<int32_t>(baton->cropOffsetLeft));
|
|
1194
1217
|
info.Set("cropOffsetTop", static_cast<int32_t>(baton->cropOffsetTop));
|
|
1195
1218
|
}
|
|
1219
|
+
if (baton->hasAttentionCenter) {
|
|
1220
|
+
info.Set("attentionX", static_cast<int32_t>(baton->attentionX));
|
|
1221
|
+
info.Set("attentionY", static_cast<int32_t>(baton->attentionY));
|
|
1222
|
+
}
|
|
1196
1223
|
if (baton->trimThreshold > 0.0) {
|
|
1197
1224
|
info.Set("trimOffsetLeft", static_cast<int32_t>(baton->trimOffsetLeft));
|
|
1198
1225
|
info.Set("trimOffsetTop", static_cast<int32_t>(baton->trimOffsetTop));
|
|
@@ -1206,8 +1233,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1206
1233
|
// Add buffer size to info
|
|
1207
1234
|
info.Set("size", static_cast<uint32_t>(baton->bufferOutLength));
|
|
1208
1235
|
// Pass ownership of output data to Buffer instance
|
|
1209
|
-
Napi::Buffer<char> data =
|
|
1210
|
-
baton->bufferOutLength);
|
|
1236
|
+
Napi::Buffer<char> data = Napi::Buffer<char>::NewOrCopy(env, static_cast<char*>(baton->bufferOut),
|
|
1237
|
+
baton->bufferOutLength, sharp::FreeCallback);
|
|
1211
1238
|
Callback().MakeCallback(Receiver().Value(), { env.Null(), data, info });
|
|
1212
1239
|
} else {
|
|
1213
1240
|
// Add file size to info
|
|
@@ -1218,7 +1245,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1218
1245
|
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
|
|
1219
1246
|
}
|
|
1220
1247
|
} else {
|
|
1221
|
-
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, baton->err).Value() });
|
|
1248
|
+
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
|
1222
1249
|
}
|
|
1223
1250
|
|
|
1224
1251
|
// Delete baton
|
|
@@ -1236,7 +1263,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1236
1263
|
// Decrement processing task counter
|
|
1237
1264
|
g_atomic_int_dec_and_test(&sharp::counterProcess);
|
|
1238
1265
|
Napi::Number queueLength = Napi::Number::New(env, static_cast<double>(sharp::counterQueue));
|
|
1239
|
-
queueListener.
|
|
1266
|
+
queueListener.MakeCallback(Receiver().Value(), { queueLength });
|
|
1240
1267
|
}
|
|
1241
1268
|
|
|
1242
1269
|
private:
|
|
@@ -1382,7 +1409,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1382
1409
|
Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
1383
1410
|
// V8 objects are converted to non-V8 types held in the baton struct
|
|
1384
1411
|
PipelineBaton *baton = new PipelineBaton;
|
|
1385
|
-
Napi::Object options = info[0].As<Napi::Object>();
|
|
1412
|
+
Napi::Object options = info[size_t(0)].As<Napi::Object>();
|
|
1386
1413
|
|
|
1387
1414
|
// Input
|
|
1388
1415
|
baton->input = sharp::CreateInputDescriptor(options.Get("input").As<Napi::Object>());
|
|
@@ -1444,6 +1471,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1444
1471
|
// Operators
|
|
1445
1472
|
baton->flatten = sharp::AttrAsBool(options, "flatten");
|
|
1446
1473
|
baton->flattenBackground = sharp::AttrAsVectorOfDouble(options, "flattenBackground");
|
|
1474
|
+
baton->unflatten = sharp::AttrAsBool(options, "unflatten");
|
|
1447
1475
|
baton->negate = sharp::AttrAsBool(options, "negate");
|
|
1448
1476
|
baton->negateAlpha = sharp::AttrAsBool(options, "negateAlpha");
|
|
1449
1477
|
baton->blurSigma = sharp::AttrAsDouble(options, "blurSigma");
|
|
@@ -1468,6 +1496,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1468
1496
|
baton->linearB = sharp::AttrAsVectorOfDouble(options, "linearB");
|
|
1469
1497
|
baton->greyscale = sharp::AttrAsBool(options, "greyscale");
|
|
1470
1498
|
baton->normalise = sharp::AttrAsBool(options, "normalise");
|
|
1499
|
+
baton->normaliseLower = sharp::AttrAsUint32(options, "normaliseLower");
|
|
1500
|
+
baton->normaliseUpper = sharp::AttrAsUint32(options, "normaliseUpper");
|
|
1471
1501
|
baton->tintA = sharp::AttrAsDouble(options, "tintA");
|
|
1472
1502
|
baton->tintB = sharp::AttrAsDouble(options, "tintB");
|
|
1473
1503
|
baton->claheWidth = sharp::AttrAsUint32(options, "claheWidth");
|
|
@@ -1485,6 +1515,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1485
1515
|
baton->extendLeft = sharp::AttrAsInt32(options, "extendLeft");
|
|
1486
1516
|
baton->extendRight = sharp::AttrAsInt32(options, "extendRight");
|
|
1487
1517
|
baton->extendBackground = sharp::AttrAsVectorOfDouble(options, "extendBackground");
|
|
1518
|
+
baton->extendWith = sharp::AttrAsEnum<VipsExtend>(options, "extendWith", VIPS_TYPE_EXTEND);
|
|
1488
1519
|
baton->extractChannel = sharp::AttrAsInt32(options, "extractChannel");
|
|
1489
1520
|
baton->affineMatrix = sharp::AttrAsVectorOfDouble(options, "affineMatrix");
|
|
1490
1521
|
baton->affineBackground = sharp::AttrAsVectorOfDouble(options, "affineBackground");
|
|
@@ -1582,7 +1613,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1582
1613
|
baton->gifDither = sharp::AttrAsDouble(options, "gifDither");
|
|
1583
1614
|
baton->gifInterFrameMaxError = sharp::AttrAsDouble(options, "gifInterFrameMaxError");
|
|
1584
1615
|
baton->gifInterPaletteMaxError = sharp::AttrAsDouble(options, "gifInterPaletteMaxError");
|
|
1585
|
-
baton->
|
|
1616
|
+
baton->gifReuse = sharp::AttrAsBool(options, "gifReuse");
|
|
1617
|
+
baton->gifProgressive = sharp::AttrAsBool(options, "gifProgressive");
|
|
1586
1618
|
baton->tiffQuality = sharp::AttrAsUint32(options, "tiffQuality");
|
|
1587
1619
|
baton->tiffPyramid = sharp::AttrAsBool(options, "tiffPyramid");
|
|
1588
1620
|
baton->tiffBitdepth = sharp::AttrAsUint32(options, "tiffBitdepth");
|
|
@@ -1638,9 +1670,13 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1638
1670
|
baton->trimThreshold > 0.0 ||
|
|
1639
1671
|
baton->normalise ||
|
|
1640
1672
|
baton->position == 16 || baton->position == 17 ||
|
|
1641
|
-
baton->angle
|
|
1642
|
-
|
|
1643
|
-
baton->
|
|
1673
|
+
baton->angle != 0 ||
|
|
1674
|
+
baton->rotationAngle != 0.0 ||
|
|
1675
|
+
baton->tileAngle != 0 ||
|
|
1676
|
+
baton->useExifOrientation ||
|
|
1677
|
+
baton->flip ||
|
|
1678
|
+
baton->claheWidth != 0 ||
|
|
1679
|
+
!baton->affineMatrix.empty()
|
|
1644
1680
|
) {
|
|
1645
1681
|
baton->input->access = VIPS_ACCESS_RANDOM;
|
|
1646
1682
|
}
|
|
@@ -1653,7 +1689,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1653
1689
|
Napi::Function queueListener = options.Get("queueListener").As<Napi::Function>();
|
|
1654
1690
|
|
|
1655
1691
|
// Join queue for worker thread
|
|
1656
|
-
Napi::Function callback = info[1].As<Napi::Function>();
|
|
1692
|
+
Napi::Function callback = info[size_t(1)].As<Napi::Function>();
|
|
1657
1693
|
PipelineWorker *worker = new PipelineWorker(callback, baton, debuglog, queueListener);
|
|
1658
1694
|
worker->Receiver().Set("options", options);
|
|
1659
1695
|
worker->Queue();
|
|
@@ -1661,7 +1697,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1661
1697
|
// Increment queued task counter
|
|
1662
1698
|
g_atomic_int_inc(&sharp::counterQueue);
|
|
1663
1699
|
Napi::Number queueLength = Napi::Number::New(info.Env(), static_cast<double>(sharp::counterQueue));
|
|
1664
|
-
queueListener.
|
|
1700
|
+
queueListener.MakeCallback(info.This(), { queueLength });
|
|
1665
1701
|
|
|
1666
1702
|
return info.Env().Undefined();
|
|
1667
1703
|
}
|
package/src/pipeline.h
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
// Copyright 2013
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
3
|
|
|
15
4
|
#ifndef SRC_PIPELINE_H_
|
|
16
5
|
#define SRC_PIPELINE_H_
|
|
@@ -74,6 +63,9 @@ struct PipelineBaton {
|
|
|
74
63
|
bool hasCropOffset;
|
|
75
64
|
int cropOffsetLeft;
|
|
76
65
|
int cropOffsetTop;
|
|
66
|
+
bool hasAttentionCenter;
|
|
67
|
+
int attentionX;
|
|
68
|
+
int attentionY;
|
|
77
69
|
bool premultiplied;
|
|
78
70
|
bool tileCentre;
|
|
79
71
|
bool fastShrinkOnLoad;
|
|
@@ -81,6 +73,7 @@ struct PipelineBaton {
|
|
|
81
73
|
double tintB;
|
|
82
74
|
bool flatten;
|
|
83
75
|
std::vector<double> flattenBackground;
|
|
76
|
+
bool unflatten;
|
|
84
77
|
bool negate;
|
|
85
78
|
bool negateAlpha;
|
|
86
79
|
double blurSigma;
|
|
@@ -107,6 +100,8 @@ struct PipelineBaton {
|
|
|
107
100
|
double gammaOut;
|
|
108
101
|
bool greyscale;
|
|
109
102
|
bool normalise;
|
|
103
|
+
int normaliseLower;
|
|
104
|
+
int normaliseUpper;
|
|
110
105
|
int claheWidth;
|
|
111
106
|
int claheHeight;
|
|
112
107
|
int claheMaxSlope;
|
|
@@ -122,6 +117,7 @@ struct PipelineBaton {
|
|
|
122
117
|
int extendLeft;
|
|
123
118
|
int extendRight;
|
|
124
119
|
std::vector<double> extendBackground;
|
|
120
|
+
VipsExtend extendWith;
|
|
125
121
|
bool withoutEnlargement;
|
|
126
122
|
bool withoutReduction;
|
|
127
123
|
std::vector<double> affineMatrix;
|
|
@@ -165,7 +161,8 @@ struct PipelineBaton {
|
|
|
165
161
|
double gifDither;
|
|
166
162
|
double gifInterFrameMaxError;
|
|
167
163
|
double gifInterPaletteMaxError;
|
|
168
|
-
bool
|
|
164
|
+
bool gifReuse;
|
|
165
|
+
bool gifProgressive;
|
|
169
166
|
int tiffQuality;
|
|
170
167
|
VipsForeignTiffCompression tiffCompression;
|
|
171
168
|
VipsForeignTiffPredictor tiffPredictor;
|
|
@@ -235,11 +232,15 @@ struct PipelineBaton {
|
|
|
235
232
|
hasCropOffset(false),
|
|
236
233
|
cropOffsetLeft(0),
|
|
237
234
|
cropOffsetTop(0),
|
|
235
|
+
hasAttentionCenter(false),
|
|
236
|
+
attentionX(0),
|
|
237
|
+
attentionY(0),
|
|
238
238
|
premultiplied(false),
|
|
239
239
|
tintA(128.0),
|
|
240
240
|
tintB(128.0),
|
|
241
241
|
flatten(false),
|
|
242
242
|
flattenBackground{ 0.0, 0.0, 0.0 },
|
|
243
|
+
unflatten(false),
|
|
243
244
|
negate(false),
|
|
244
245
|
negateAlpha(true),
|
|
245
246
|
blurSigma(0.0),
|
|
@@ -265,6 +266,8 @@ struct PipelineBaton {
|
|
|
265
266
|
gamma(0.0),
|
|
266
267
|
greyscale(false),
|
|
267
268
|
normalise(false),
|
|
269
|
+
normaliseLower(1),
|
|
270
|
+
normaliseUpper(99),
|
|
268
271
|
claheWidth(0),
|
|
269
272
|
claheHeight(0),
|
|
270
273
|
claheMaxSlope(3),
|
|
@@ -279,6 +282,7 @@ struct PipelineBaton {
|
|
|
279
282
|
extendLeft(0),
|
|
280
283
|
extendRight(0),
|
|
281
284
|
extendBackground{ 0.0, 0.0, 0.0, 255.0 },
|
|
285
|
+
extendWith(VIPS_EXTEND_BACKGROUND),
|
|
282
286
|
withoutEnlargement(false),
|
|
283
287
|
withoutReduction(false),
|
|
284
288
|
affineMatrix{ 1.0, 0.0, 0.0, 1.0 },
|
|
@@ -322,7 +326,8 @@ struct PipelineBaton {
|
|
|
322
326
|
gifDither(1.0),
|
|
323
327
|
gifInterFrameMaxError(0.0),
|
|
324
328
|
gifInterPaletteMaxError(3.0),
|
|
325
|
-
|
|
329
|
+
gifReuse(true),
|
|
330
|
+
gifProgressive(false),
|
|
326
331
|
tiffQuality(80),
|
|
327
332
|
tiffCompression(VIPS_FOREIGN_TIFF_COMPRESSION_JPEG),
|
|
328
333
|
tiffPredictor(VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL),
|
package/src/sharp.cc
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
// Copyright 2013
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
3
|
|
|
15
4
|
#include <napi.h>
|
|
16
5
|
#include <vips/vips8>
|
package/src/stats.cc
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
// Copyright 2013
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
3
|
|
|
15
4
|
#include <numeric>
|
|
16
5
|
#include <vector>
|
|
@@ -117,7 +106,7 @@ class StatsWorker : public Napi::AsyncWorker {
|
|
|
117
106
|
// Handle warnings
|
|
118
107
|
std::string warning = sharp::VipsWarningPop();
|
|
119
108
|
while (!warning.empty()) {
|
|
120
|
-
debuglog.
|
|
109
|
+
debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
|
|
121
110
|
warning = sharp::VipsWarningPop();
|
|
122
111
|
}
|
|
123
112
|
|
|
@@ -154,7 +143,7 @@ class StatsWorker : public Napi::AsyncWorker {
|
|
|
154
143
|
info.Set("dominant", dominant);
|
|
155
144
|
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
|
|
156
145
|
} else {
|
|
157
|
-
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, baton->err).Value() });
|
|
146
|
+
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
|
158
147
|
}
|
|
159
148
|
|
|
160
149
|
delete baton->input;
|
|
@@ -172,7 +161,7 @@ class StatsWorker : public Napi::AsyncWorker {
|
|
|
172
161
|
Napi::Value stats(const Napi::CallbackInfo& info) {
|
|
173
162
|
// V8 objects are converted to non-V8 types held in the baton struct
|
|
174
163
|
StatsBaton *baton = new StatsBaton;
|
|
175
|
-
Napi::Object options = info[0].As<Napi::Object>();
|
|
164
|
+
Napi::Object options = info[size_t(0)].As<Napi::Object>();
|
|
176
165
|
|
|
177
166
|
// Input
|
|
178
167
|
baton->input = sharp::CreateInputDescriptor(options.Get("input").As<Napi::Object>());
|
|
@@ -182,7 +171,7 @@ Napi::Value stats(const Napi::CallbackInfo& info) {
|
|
|
182
171
|
Napi::Function debuglog = options.Get("debuglog").As<Napi::Function>();
|
|
183
172
|
|
|
184
173
|
// Join queue for worker thread
|
|
185
|
-
Napi::Function callback = info[1].As<Napi::Function>();
|
|
174
|
+
Napi::Function callback = info[size_t(1)].As<Napi::Function>();
|
|
186
175
|
StatsWorker *worker = new StatsWorker(callback, baton, debuglog);
|
|
187
176
|
worker->Receiver().Set("options", options);
|
|
188
177
|
worker->Queue();
|
package/src/stats.h
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
// Copyright 2013
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
1
|
+
// Copyright 2013 Lovell Fuller and others.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
14
3
|
|
|
15
4
|
#ifndef SRC_STATS_H_
|
|
16
5
|
#define SRC_STATS_H_
|