sharp 0.31.3 → 0.32.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 +1 -1
- package/binding.gyp +1 -1
- package/install/can-compile.js +3 -0
- package/install/dll-copy.js +3 -0
- package/install/libvips.js +3 -4
- package/lib/agent.js +3 -0
- package/lib/channel.js +3 -0
- package/lib/colour.js +3 -0
- package/lib/composite.js +3 -0
- package/lib/constructor.js +16 -8
- package/lib/index.d.ts +1614 -0
- package/lib/index.js +3 -0
- package/lib/input.js +32 -6
- package/lib/is.js +12 -0
- package/lib/libvips.js +4 -0
- package/lib/operation.js +75 -35
- package/lib/output.js +17 -8
- 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 +28 -21
- package/src/common.cc +29 -14
- package/src/common.h +19 -16
- package/src/libvips/cplusplus/vips-operators.cpp +7 -0
- package/src/metadata.cc +12 -17
- package/src/metadata.h +3 -13
- package/src/operations.cc +11 -21
- package/src/operations.h +4 -15
- package/src/pipeline.cc +72 -49
- package/src/pipeline.h +18 -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/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,7 +320,7 @@ 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
325
|
} else if (image.interpretation() == VIPS_INTERPRETATION_CMYK) {
|
|
335
326
|
image = image.icc_transform(processingProfile, VImage::option()
|
|
@@ -367,11 +358,12 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
367
358
|
image = sharp::EnsureAlpha(image, 1);
|
|
368
359
|
}
|
|
369
360
|
|
|
361
|
+
VipsBandFormat premultiplyFormat = image.format();
|
|
370
362
|
bool const shouldPremultiplyAlpha = sharp::HasAlpha(image) &&
|
|
371
363
|
(shouldResize || shouldBlur || shouldConv || shouldSharpen);
|
|
372
364
|
|
|
373
365
|
if (shouldPremultiplyAlpha) {
|
|
374
|
-
image = image.premultiply();
|
|
366
|
+
image = image.premultiply().cast(premultiplyFormat);
|
|
375
367
|
}
|
|
376
368
|
|
|
377
369
|
// Resize
|
|
@@ -399,7 +391,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
399
391
|
}
|
|
400
392
|
|
|
401
393
|
// Join additional color channels to the image
|
|
402
|
-
if (baton->joinChannelIn.
|
|
394
|
+
if (!baton->joinChannelIn.empty()) {
|
|
403
395
|
VImage joinImage;
|
|
404
396
|
sharp::ImageType joinImageType = sharp::ImageType::UNKNOWN;
|
|
405
397
|
|
|
@@ -409,6 +401,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
409
401
|
image = image.bandjoin(joinImage);
|
|
410
402
|
}
|
|
411
403
|
image = image.copy(VImage::option()->set("interpretation", baton->colourspace));
|
|
404
|
+
image = sharp::RemoveGifPalette(image);
|
|
412
405
|
}
|
|
413
406
|
|
|
414
407
|
inputWidth = image.width();
|
|
@@ -438,7 +431,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
438
431
|
|
|
439
432
|
image = nPages > 1
|
|
440
433
|
? sharp::EmbedMultiPage(image,
|
|
441
|
-
left, top, width, height, background, nPages, &targetPageHeight)
|
|
434
|
+
left, top, width, height, VIPS_EXTEND_BACKGROUND, background, nPages, &targetPageHeight)
|
|
442
435
|
: image.embed(left, top, width, height, VImage::option()
|
|
443
436
|
->set("extend", VIPS_EXTEND_BACKGROUND)
|
|
444
437
|
->set("background", background));
|
|
@@ -455,6 +448,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
455
448
|
// Gravity-based crop
|
|
456
449
|
int left;
|
|
457
450
|
int top;
|
|
451
|
+
|
|
458
452
|
std::tie(left, top) = sharp::CalculateCrop(
|
|
459
453
|
inputWidth, inputHeight, baton->width, baton->height, baton->position);
|
|
460
454
|
int width = std::min(inputWidth, baton->width);
|
|
@@ -465,16 +459,25 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
465
459
|
left, top, width, height, nPages, &targetPageHeight)
|
|
466
460
|
: image.extract_area(left, top, width, height);
|
|
467
461
|
} else {
|
|
462
|
+
int attention_x;
|
|
463
|
+
int attention_y;
|
|
464
|
+
|
|
468
465
|
// Attention-based or Entropy-based crop
|
|
469
466
|
MultiPageUnsupported(nPages, "Resize strategy");
|
|
470
467
|
image = image.tilecache(VImage::option()
|
|
471
468
|
->set("access", VIPS_ACCESS_RANDOM)
|
|
472
469
|
->set("threaded", TRUE));
|
|
470
|
+
|
|
473
471
|
image = image.smartcrop(baton->width, baton->height, VImage::option()
|
|
474
|
-
->set("interesting", baton->position == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION)
|
|
472
|
+
->set("interesting", baton->position == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION)
|
|
473
|
+
->set("attention_x", &attention_x)
|
|
474
|
+
->set("attention_y", &attention_y));
|
|
475
475
|
baton->hasCropOffset = true;
|
|
476
476
|
baton->cropOffsetLeft = static_cast<int>(image.xoffset());
|
|
477
477
|
baton->cropOffsetTop = static_cast<int>(image.yoffset());
|
|
478
|
+
baton->hasAttentionCenter = true;
|
|
479
|
+
baton->attentionX = static_cast<int>(attention_x * jpegShrinkOnLoad / scale);
|
|
480
|
+
baton->attentionY = static_cast<int>(attention_y * jpegShrinkOnLoad / scale);
|
|
478
481
|
}
|
|
479
482
|
}
|
|
480
483
|
}
|
|
@@ -503,7 +506,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
503
506
|
}
|
|
504
507
|
|
|
505
508
|
// Affine transform
|
|
506
|
-
if (baton->affineMatrix.
|
|
509
|
+
if (!baton->affineMatrix.empty()) {
|
|
507
510
|
MultiPageUnsupported(nPages, "Affine");
|
|
508
511
|
std::vector<double> background;
|
|
509
512
|
std::tie(image, background) = sharp::ApplyAlpha(image, baton->affineBackground, shouldPremultiplyAlpha);
|
|
@@ -519,18 +522,29 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
519
522
|
|
|
520
523
|
// Extend edges
|
|
521
524
|
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
525
|
// Embed
|
|
526
526
|
baton->width = image.width() + baton->extendLeft + baton->extendRight;
|
|
527
527
|
baton->height = (nPages > 1 ? targetPageHeight : image.height()) + baton->extendTop + baton->extendBottom;
|
|
528
528
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
529
|
+
if (baton->extendWith == VIPS_EXTEND_BACKGROUND) {
|
|
530
|
+
std::vector<double> background;
|
|
531
|
+
std::tie(image, background) = sharp::ApplyAlpha(image, baton->extendBackground, shouldPremultiplyAlpha);
|
|
532
|
+
|
|
533
|
+
image = nPages > 1
|
|
534
|
+
? sharp::EmbedMultiPage(image,
|
|
535
|
+
baton->extendLeft, baton->extendTop, baton->width, baton->height,
|
|
536
|
+
baton->extendWith, background, nPages, &targetPageHeight)
|
|
537
|
+
: image.embed(baton->extendLeft, baton->extendTop, baton->width, baton->height,
|
|
538
|
+
VImage::option()->set("extend", baton->extendWith)->set("background", background));
|
|
539
|
+
} else {
|
|
540
|
+
std::vector<double> ignoredBackground(1);
|
|
541
|
+
image = nPages > 1
|
|
542
|
+
? sharp::EmbedMultiPage(image,
|
|
543
|
+
baton->extendLeft, baton->extendTop, baton->width, baton->height,
|
|
544
|
+
baton->extendWith, ignoredBackground, nPages, &targetPageHeight)
|
|
545
|
+
: image.embed(baton->extendLeft, baton->extendTop, baton->width, baton->height,
|
|
546
|
+
VImage::option()->set("extend", baton->extendWith));
|
|
547
|
+
}
|
|
534
548
|
}
|
|
535
549
|
// Median - must happen before blurring, due to the utility of blurring after thresholding
|
|
536
550
|
if (baton->medianSize > 0) {
|
|
@@ -572,13 +586,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
572
586
|
|
|
573
587
|
// Reverse premultiplication after all transformations
|
|
574
588
|
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
|
-
}
|
|
589
|
+
image = image.unpremultiply().cast(premultiplyFormat);
|
|
582
590
|
}
|
|
583
591
|
baton->premultiplied = shouldPremultiplyAlpha;
|
|
584
592
|
|
|
@@ -660,6 +668,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
660
668
|
ys.push_back(top);
|
|
661
669
|
}
|
|
662
670
|
image = VImage::composite(images, modes, VImage::option()->set("x", xs)->set("y", ys));
|
|
671
|
+
image = sharp::RemoveGifPalette(image);
|
|
663
672
|
}
|
|
664
673
|
|
|
665
674
|
// Gamma decoding (brighten)
|
|
@@ -674,7 +683,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
674
683
|
|
|
675
684
|
// Apply normalisation - stretch luminance to cover full dynamic range
|
|
676
685
|
if (baton->normalise) {
|
|
677
|
-
image = sharp::Normalise(image);
|
|
686
|
+
image = sharp::Normalise(image, baton->normaliseLower, baton->normaliseUpper);
|
|
678
687
|
}
|
|
679
688
|
|
|
680
689
|
// Apply contrast limiting adaptive histogram equalization (CLAHE)
|
|
@@ -689,6 +698,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
689
698
|
std::tie(booleanImage, booleanImageType) = sharp::OpenInput(baton->boolean);
|
|
690
699
|
booleanImage = sharp::EnsureColourspace(booleanImage, baton->colourspaceInput);
|
|
691
700
|
image = sharp::Boolean(image, booleanImage, baton->booleanOp);
|
|
701
|
+
image = sharp::RemoveGifPalette(image);
|
|
692
702
|
}
|
|
693
703
|
|
|
694
704
|
// Apply per-channel Bandbool bitwise operations after all other operations
|
|
@@ -870,7 +880,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
870
880
|
->set("strip", !baton->withMetadata)
|
|
871
881
|
->set("bitdepth", baton->gifBitdepth)
|
|
872
882
|
->set("effort", baton->gifEffort)
|
|
873
|
-
->set("
|
|
883
|
+
->set("reuse", baton->gifReuse)
|
|
884
|
+
->set("interlace", baton->gifProgressive)
|
|
874
885
|
->set("interframe_maxerror", baton->gifInterFrameMaxError)
|
|
875
886
|
->set("interpalette_maxerror", baton->gifInterPaletteMaxError)
|
|
876
887
|
->set("dither", baton->gifDither)));
|
|
@@ -1068,7 +1079,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1068
1079
|
->set("strip", !baton->withMetadata)
|
|
1069
1080
|
->set("bitdepth", baton->gifBitdepth)
|
|
1070
1081
|
->set("effort", baton->gifEffort)
|
|
1071
|
-
->set("
|
|
1082
|
+
->set("reuse", baton->gifReuse)
|
|
1083
|
+
->set("interlace", baton->gifProgressive)
|
|
1072
1084
|
->set("dither", baton->gifDither));
|
|
1073
1085
|
baton->formatOut = "gif";
|
|
1074
1086
|
} else if (baton->formatOut == "tiff" || (mightMatchInput && isTiff) ||
|
|
@@ -1164,7 +1176,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1164
1176
|
// Handle warnings
|
|
1165
1177
|
std::string warning = sharp::VipsWarningPop();
|
|
1166
1178
|
while (!warning.empty()) {
|
|
1167
|
-
debuglog.
|
|
1179
|
+
debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
|
|
1168
1180
|
warning = sharp::VipsWarningPop();
|
|
1169
1181
|
}
|
|
1170
1182
|
|
|
@@ -1193,6 +1205,10 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1193
1205
|
info.Set("cropOffsetLeft", static_cast<int32_t>(baton->cropOffsetLeft));
|
|
1194
1206
|
info.Set("cropOffsetTop", static_cast<int32_t>(baton->cropOffsetTop));
|
|
1195
1207
|
}
|
|
1208
|
+
if (baton->hasAttentionCenter) {
|
|
1209
|
+
info.Set("attentionX", static_cast<int32_t>(baton->attentionX));
|
|
1210
|
+
info.Set("attentionY", static_cast<int32_t>(baton->attentionY));
|
|
1211
|
+
}
|
|
1196
1212
|
if (baton->trimThreshold > 0.0) {
|
|
1197
1213
|
info.Set("trimOffsetLeft", static_cast<int32_t>(baton->trimOffsetLeft));
|
|
1198
1214
|
info.Set("trimOffsetTop", static_cast<int32_t>(baton->trimOffsetTop));
|
|
@@ -1218,7 +1234,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1218
1234
|
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
|
|
1219
1235
|
}
|
|
1220
1236
|
} else {
|
|
1221
|
-
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, baton->err).Value() });
|
|
1237
|
+
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
|
|
1222
1238
|
}
|
|
1223
1239
|
|
|
1224
1240
|
// Delete baton
|
|
@@ -1236,7 +1252,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1236
1252
|
// Decrement processing task counter
|
|
1237
1253
|
g_atomic_int_dec_and_test(&sharp::counterProcess);
|
|
1238
1254
|
Napi::Number queueLength = Napi::Number::New(env, static_cast<double>(sharp::counterQueue));
|
|
1239
|
-
queueListener.
|
|
1255
|
+
queueListener.MakeCallback(Receiver().Value(), { queueLength });
|
|
1240
1256
|
}
|
|
1241
1257
|
|
|
1242
1258
|
private:
|
|
@@ -1382,7 +1398,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1382
1398
|
Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
1383
1399
|
// V8 objects are converted to non-V8 types held in the baton struct
|
|
1384
1400
|
PipelineBaton *baton = new PipelineBaton;
|
|
1385
|
-
Napi::Object options = info[0].As<Napi::Object>();
|
|
1401
|
+
Napi::Object options = info[size_t(0)].As<Napi::Object>();
|
|
1386
1402
|
|
|
1387
1403
|
// Input
|
|
1388
1404
|
baton->input = sharp::CreateInputDescriptor(options.Get("input").As<Napi::Object>());
|
|
@@ -1468,6 +1484,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1468
1484
|
baton->linearB = sharp::AttrAsVectorOfDouble(options, "linearB");
|
|
1469
1485
|
baton->greyscale = sharp::AttrAsBool(options, "greyscale");
|
|
1470
1486
|
baton->normalise = sharp::AttrAsBool(options, "normalise");
|
|
1487
|
+
baton->normaliseLower = sharp::AttrAsUint32(options, "normaliseLower");
|
|
1488
|
+
baton->normaliseUpper = sharp::AttrAsUint32(options, "normaliseUpper");
|
|
1471
1489
|
baton->tintA = sharp::AttrAsDouble(options, "tintA");
|
|
1472
1490
|
baton->tintB = sharp::AttrAsDouble(options, "tintB");
|
|
1473
1491
|
baton->claheWidth = sharp::AttrAsUint32(options, "claheWidth");
|
|
@@ -1485,6 +1503,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1485
1503
|
baton->extendLeft = sharp::AttrAsInt32(options, "extendLeft");
|
|
1486
1504
|
baton->extendRight = sharp::AttrAsInt32(options, "extendRight");
|
|
1487
1505
|
baton->extendBackground = sharp::AttrAsVectorOfDouble(options, "extendBackground");
|
|
1506
|
+
baton->extendWith = sharp::AttrAsEnum<VipsExtend>(options, "extendWith", VIPS_TYPE_EXTEND);
|
|
1488
1507
|
baton->extractChannel = sharp::AttrAsInt32(options, "extractChannel");
|
|
1489
1508
|
baton->affineMatrix = sharp::AttrAsVectorOfDouble(options, "affineMatrix");
|
|
1490
1509
|
baton->affineBackground = sharp::AttrAsVectorOfDouble(options, "affineBackground");
|
|
@@ -1582,7 +1601,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1582
1601
|
baton->gifDither = sharp::AttrAsDouble(options, "gifDither");
|
|
1583
1602
|
baton->gifInterFrameMaxError = sharp::AttrAsDouble(options, "gifInterFrameMaxError");
|
|
1584
1603
|
baton->gifInterPaletteMaxError = sharp::AttrAsDouble(options, "gifInterPaletteMaxError");
|
|
1585
|
-
baton->
|
|
1604
|
+
baton->gifReuse = sharp::AttrAsBool(options, "gifReuse");
|
|
1605
|
+
baton->gifProgressive = sharp::AttrAsBool(options, "gifProgressive");
|
|
1586
1606
|
baton->tiffQuality = sharp::AttrAsUint32(options, "tiffQuality");
|
|
1587
1607
|
baton->tiffPyramid = sharp::AttrAsBool(options, "tiffPyramid");
|
|
1588
1608
|
baton->tiffBitdepth = sharp::AttrAsUint32(options, "tiffBitdepth");
|
|
@@ -1638,9 +1658,12 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1638
1658
|
baton->trimThreshold > 0.0 ||
|
|
1639
1659
|
baton->normalise ||
|
|
1640
1660
|
baton->position == 16 || baton->position == 17 ||
|
|
1641
|
-
baton->angle
|
|
1642
|
-
|
|
1643
|
-
baton->
|
|
1661
|
+
baton->angle != 0 ||
|
|
1662
|
+
baton->rotationAngle != 0.0 ||
|
|
1663
|
+
baton->tileAngle != 0 ||
|
|
1664
|
+
baton->useExifOrientation ||
|
|
1665
|
+
baton->claheWidth != 0 ||
|
|
1666
|
+
!baton->affineMatrix.empty()
|
|
1644
1667
|
) {
|
|
1645
1668
|
baton->input->access = VIPS_ACCESS_RANDOM;
|
|
1646
1669
|
}
|
|
@@ -1653,7 +1676,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1653
1676
|
Napi::Function queueListener = options.Get("queueListener").As<Napi::Function>();
|
|
1654
1677
|
|
|
1655
1678
|
// Join queue for worker thread
|
|
1656
|
-
Napi::Function callback = info[1].As<Napi::Function>();
|
|
1679
|
+
Napi::Function callback = info[size_t(1)].As<Napi::Function>();
|
|
1657
1680
|
PipelineWorker *worker = new PipelineWorker(callback, baton, debuglog, queueListener);
|
|
1658
1681
|
worker->Receiver().Set("options", options);
|
|
1659
1682
|
worker->Queue();
|
|
@@ -1661,7 +1684,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1661
1684
|
// Increment queued task counter
|
|
1662
1685
|
g_atomic_int_inc(&sharp::counterQueue);
|
|
1663
1686
|
Napi::Number queueLength = Napi::Number::New(info.Env(), static_cast<double>(sharp::counterQueue));
|
|
1664
|
-
queueListener.
|
|
1687
|
+
queueListener.MakeCallback(info.This(), { queueLength });
|
|
1665
1688
|
|
|
1666
1689
|
return info.Env().Undefined();
|
|
1667
1690
|
}
|
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;
|
|
@@ -107,6 +99,8 @@ struct PipelineBaton {
|
|
|
107
99
|
double gammaOut;
|
|
108
100
|
bool greyscale;
|
|
109
101
|
bool normalise;
|
|
102
|
+
int normaliseLower;
|
|
103
|
+
int normaliseUpper;
|
|
110
104
|
int claheWidth;
|
|
111
105
|
int claheHeight;
|
|
112
106
|
int claheMaxSlope;
|
|
@@ -122,6 +116,7 @@ struct PipelineBaton {
|
|
|
122
116
|
int extendLeft;
|
|
123
117
|
int extendRight;
|
|
124
118
|
std::vector<double> extendBackground;
|
|
119
|
+
VipsExtend extendWith;
|
|
125
120
|
bool withoutEnlargement;
|
|
126
121
|
bool withoutReduction;
|
|
127
122
|
std::vector<double> affineMatrix;
|
|
@@ -165,7 +160,8 @@ struct PipelineBaton {
|
|
|
165
160
|
double gifDither;
|
|
166
161
|
double gifInterFrameMaxError;
|
|
167
162
|
double gifInterPaletteMaxError;
|
|
168
|
-
bool
|
|
163
|
+
bool gifReuse;
|
|
164
|
+
bool gifProgressive;
|
|
169
165
|
int tiffQuality;
|
|
170
166
|
VipsForeignTiffCompression tiffCompression;
|
|
171
167
|
VipsForeignTiffPredictor tiffPredictor;
|
|
@@ -235,6 +231,9 @@ struct PipelineBaton {
|
|
|
235
231
|
hasCropOffset(false),
|
|
236
232
|
cropOffsetLeft(0),
|
|
237
233
|
cropOffsetTop(0),
|
|
234
|
+
hasAttentionCenter(false),
|
|
235
|
+
attentionX(0),
|
|
236
|
+
attentionY(0),
|
|
238
237
|
premultiplied(false),
|
|
239
238
|
tintA(128.0),
|
|
240
239
|
tintB(128.0),
|
|
@@ -265,6 +264,8 @@ struct PipelineBaton {
|
|
|
265
264
|
gamma(0.0),
|
|
266
265
|
greyscale(false),
|
|
267
266
|
normalise(false),
|
|
267
|
+
normaliseLower(1),
|
|
268
|
+
normaliseUpper(99),
|
|
268
269
|
claheWidth(0),
|
|
269
270
|
claheHeight(0),
|
|
270
271
|
claheMaxSlope(3),
|
|
@@ -279,6 +280,7 @@ struct PipelineBaton {
|
|
|
279
280
|
extendLeft(0),
|
|
280
281
|
extendRight(0),
|
|
281
282
|
extendBackground{ 0.0, 0.0, 0.0, 255.0 },
|
|
283
|
+
extendWith(VIPS_EXTEND_BACKGROUND),
|
|
282
284
|
withoutEnlargement(false),
|
|
283
285
|
withoutReduction(false),
|
|
284
286
|
affineMatrix{ 1.0, 0.0, 0.0, 1.0 },
|
|
@@ -322,7 +324,8 @@ struct PipelineBaton {
|
|
|
322
324
|
gifDither(1.0),
|
|
323
325
|
gifInterFrameMaxError(0.0),
|
|
324
326
|
gifInterPaletteMaxError(3.0),
|
|
325
|
-
|
|
327
|
+
gifReuse(true),
|
|
328
|
+
gifProgressive(false),
|
|
326
329
|
tiffQuality(80),
|
|
327
330
|
tiffCompression(VIPS_FOREIGN_TIFF_COMPRESSION_JPEG),
|
|
328
331
|
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_
|
package/src/utilities.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 <cmath>
|
|
16
5
|
#include <string>
|
|
@@ -30,16 +19,16 @@ Napi::Value cache(const Napi::CallbackInfo& info) {
|
|
|
30
19
|
Napi::Env env = info.Env();
|
|
31
20
|
|
|
32
21
|
// Set memory limit
|
|
33
|
-
if (info[0].IsNumber()) {
|
|
34
|
-
vips_cache_set_max_mem(info[0].As<Napi::Number>().Int32Value() * 1048576);
|
|
22
|
+
if (info[size_t(0)].IsNumber()) {
|
|
23
|
+
vips_cache_set_max_mem(info[size_t(0)].As<Napi::Number>().Int32Value() * 1048576);
|
|
35
24
|
}
|
|
36
25
|
// Set file limit
|
|
37
|
-
if (info[1].IsNumber()) {
|
|
38
|
-
vips_cache_set_max_files(info[1].As<Napi::Number>().Int32Value());
|
|
26
|
+
if (info[size_t(1)].IsNumber()) {
|
|
27
|
+
vips_cache_set_max_files(info[size_t(1)].As<Napi::Number>().Int32Value());
|
|
39
28
|
}
|
|
40
29
|
// Set items limit
|
|
41
|
-
if (info[2].IsNumber()) {
|
|
42
|
-
vips_cache_set_max(info[2].As<Napi::Number>().Int32Value());
|
|
30
|
+
if (info[size_t(2)].IsNumber()) {
|
|
31
|
+
vips_cache_set_max(info[size_t(2)].As<Napi::Number>().Int32Value());
|
|
43
32
|
}
|
|
44
33
|
|
|
45
34
|
// Get memory stats
|
|
@@ -69,8 +58,8 @@ Napi::Value cache(const Napi::CallbackInfo& info) {
|
|
|
69
58
|
*/
|
|
70
59
|
Napi::Value concurrency(const Napi::CallbackInfo& info) {
|
|
71
60
|
// Set concurrency
|
|
72
|
-
if (info[0].IsNumber()) {
|
|
73
|
-
vips_concurrency_set(info[0].As<Napi::Number>().Int32Value());
|
|
61
|
+
if (info[size_t(0)].IsNumber()) {
|
|
62
|
+
vips_concurrency_set(info[size_t(0)].As<Napi::Number>().Int32Value());
|
|
74
63
|
}
|
|
75
64
|
// Get concurrency
|
|
76
65
|
return Napi::Number::New(info.Env(), vips_concurrency_get());
|
|
@@ -91,8 +80,8 @@ Napi::Value counters(const Napi::CallbackInfo& info) {
|
|
|
91
80
|
*/
|
|
92
81
|
Napi::Value simd(const Napi::CallbackInfo& info) {
|
|
93
82
|
// Set state
|
|
94
|
-
if (info[0].IsBoolean()) {
|
|
95
|
-
vips_vector_set_enabled(info[0].As<Napi::Boolean>().Value());
|
|
83
|
+
if (info[size_t(0)].IsBoolean()) {
|
|
84
|
+
vips_vector_set_enabled(info[size_t(0)].As<Napi::Boolean>().Value());
|
|
96
85
|
}
|
|
97
86
|
// Get state
|
|
98
87
|
return Napi::Boolean::New(info.Env(), vips_vector_isenabled());
|
|
@@ -185,10 +174,10 @@ Napi::Value _maxColourDistance(const Napi::CallbackInfo& info) {
|
|
|
185
174
|
|
|
186
175
|
// Open input files
|
|
187
176
|
VImage image1;
|
|
188
|
-
sharp::ImageType imageType1 = sharp::DetermineImageType(info[0].As<Napi::String>().Utf8Value().data());
|
|
177
|
+
sharp::ImageType imageType1 = sharp::DetermineImageType(info[size_t(0)].As<Napi::String>().Utf8Value().data());
|
|
189
178
|
if (imageType1 != sharp::ImageType::UNKNOWN) {
|
|
190
179
|
try {
|
|
191
|
-
image1 = VImage::new_from_file(info[0].As<Napi::String>().Utf8Value().c_str());
|
|
180
|
+
image1 = VImage::new_from_file(info[size_t(0)].As<Napi::String>().Utf8Value().c_str());
|
|
192
181
|
} catch (...) {
|
|
193
182
|
throw Napi::Error::New(env, "Input file 1 has corrupt header");
|
|
194
183
|
}
|
|
@@ -196,10 +185,10 @@ Napi::Value _maxColourDistance(const Napi::CallbackInfo& info) {
|
|
|
196
185
|
throw Napi::Error::New(env, "Input file 1 is of an unsupported image format");
|
|
197
186
|
}
|
|
198
187
|
VImage image2;
|
|
199
|
-
sharp::ImageType imageType2 = sharp::DetermineImageType(info[1].As<Napi::String>().Utf8Value().data());
|
|
188
|
+
sharp::ImageType imageType2 = sharp::DetermineImageType(info[size_t(1)].As<Napi::String>().Utf8Value().data());
|
|
200
189
|
if (imageType2 != sharp::ImageType::UNKNOWN) {
|
|
201
190
|
try {
|
|
202
|
-
image2 = VImage::new_from_file(info[1].As<Napi::String>().Utf8Value().c_str());
|
|
191
|
+
image2 = VImage::new_from_file(info[size_t(1)].As<Napi::String>().Utf8Value().c_str());
|
|
203
192
|
} catch (...) {
|
|
204
193
|
throw Napi::Error::New(env, "Input file 2 has corrupt header");
|
|
205
194
|
}
|
package/src/utilities.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_UTILITIES_H_
|
|
16
5
|
#define SRC_UTILITIES_H_
|