sharp 0.26.2 → 0.27.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/pipeline.cc CHANGED
@@ -485,6 +485,18 @@ class PipelineWorker : public Napi::AsyncWorker {
485
485
  baton->leftOffsetPost, baton->topOffsetPost, baton->widthPost, baton->heightPost);
486
486
  }
487
487
 
488
+ // Affine transform
489
+ if (baton->affineMatrix.size() > 0) {
490
+ std::vector<double> background;
491
+ std::tie(image, background) = sharp::ApplyAlpha(image, baton->affineBackground);
492
+ image = image.affine(baton->affineMatrix, VImage::option()->set("background", background)
493
+ ->set("idx", baton->affineIdx)
494
+ ->set("idy", baton->affineIdy)
495
+ ->set("odx", baton->affineOdx)
496
+ ->set("ody", baton->affineOdy)
497
+ ->set("interpolate", baton->affineInterpolator));
498
+ }
499
+
488
500
  // Extend edges
489
501
  if (baton->extendTop > 0 || baton->extendBottom > 0 || baton->extendLeft > 0 || baton->extendRight > 0) {
490
502
  std::vector<double> background;
@@ -558,7 +570,7 @@ class PipelineWorker : public Napi::AsyncWorker {
558
570
  int left;
559
571
  int top;
560
572
  compositeImage = compositeImage.replicate(across, down);
561
- if (composite->left >= 0 && composite->top >= 0) {
573
+ if (composite->hasOffset) {
562
574
  std::tie(left, top) = sharp::CalculateCrop(
563
575
  compositeImage.width(), compositeImage.height(), image.width(), image.height(),
564
576
  composite->left, composite->top);
@@ -580,7 +592,7 @@ class PipelineWorker : public Napi::AsyncWorker {
580
592
  // Calculate position
581
593
  int left;
582
594
  int top;
583
- if (composite->left >= 0 && composite->top >= 0) {
595
+ if (composite->hasOffset) {
584
596
  // Composite image at given offsets
585
597
  std::tie(left, top) = sharp::CalculateCrop(image.width(), image.height(),
586
598
  compositeImage.width(), compositeImage.height(), composite->left, composite->top);
@@ -718,7 +730,7 @@ class PipelineWorker : public Napi::AsyncWorker {
718
730
  if (baton->formatOut == "jpeg" || (baton->formatOut == "input" && inputImageType == sharp::ImageType::JPEG)) {
719
731
  // Write JPEG to buffer
720
732
  sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG);
721
- VipsArea *area = VIPS_AREA(image.jpegsave_buffer(VImage::option()
733
+ VipsArea *area = reinterpret_cast<VipsArea*>(image.jpegsave_buffer(VImage::option()
722
734
  ->set("strip", !baton->withMetadata)
723
735
  ->set("Q", baton->jpegQuality)
724
736
  ->set("interlace", baton->jpegProgressive)
@@ -745,7 +757,7 @@ class PipelineWorker : public Napi::AsyncWorker {
745
757
  inputImageType == sharp::ImageType::SVG))) {
746
758
  // Write PNG to buffer
747
759
  sharp::AssertImageTypeDimensions(image, sharp::ImageType::PNG);
748
- VipsArea *area = VIPS_AREA(image.pngsave_buffer(VImage::option()
760
+ VipsArea *area = reinterpret_cast<VipsArea*>(image.pngsave_buffer(VImage::option()
749
761
  ->set("strip", !baton->withMetadata)
750
762
  ->set("interlace", baton->pngProgressive)
751
763
  ->set("compression", baton->pngCompressionLevel)
@@ -763,7 +775,7 @@ class PipelineWorker : public Napi::AsyncWorker {
763
775
  (baton->formatOut == "input" && inputImageType == sharp::ImageType::WEBP)) {
764
776
  // Write WEBP to buffer
765
777
  sharp::AssertImageTypeDimensions(image, sharp::ImageType::WEBP);
766
- VipsArea *area = VIPS_AREA(image.webpsave_buffer(VImage::option()
778
+ VipsArea *area = reinterpret_cast<VipsArea*>(image.webpsave_buffer(VImage::option()
767
779
  ->set("strip", !baton->withMetadata)
768
780
  ->set("Q", baton->webpQuality)
769
781
  ->set("lossless", baton->webpLossless)
@@ -780,7 +792,7 @@ class PipelineWorker : public Napi::AsyncWorker {
780
792
  (baton->formatOut == "input" && inputImageType == sharp::ImageType::GIF && supportsGifOutput)) {
781
793
  // Write GIF to buffer
782
794
  sharp::AssertImageTypeDimensions(image, sharp::ImageType::GIF);
783
- VipsArea *area = VIPS_AREA(image.magicksave_buffer(VImage::option()
795
+ VipsArea *area = reinterpret_cast<VipsArea*>(image.magicksave_buffer(VImage::option()
784
796
  ->set("strip", !baton->withMetadata)
785
797
  ->set("optimize_gif_frames", TRUE)
786
798
  ->set("optimize_gif_transparency", TRUE)
@@ -801,7 +813,7 @@ class PipelineWorker : public Napi::AsyncWorker {
801
813
  if (baton->tiffPredictor == VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT) {
802
814
  image = image.cast(VIPS_FORMAT_FLOAT);
803
815
  }
804
- VipsArea *area = VIPS_AREA(image.tiffsave_buffer(VImage::option()
816
+ VipsArea *area = reinterpret_cast<VipsArea*>(image.tiffsave_buffer(VImage::option()
805
817
  ->set("strip", !baton->withMetadata)
806
818
  ->set("Q", baton->tiffQuality)
807
819
  ->set("bitdepth", baton->tiffBitdepth)
@@ -821,10 +833,15 @@ class PipelineWorker : public Napi::AsyncWorker {
821
833
  } else if (baton->formatOut == "heif" ||
822
834
  (baton->formatOut == "input" && inputImageType == sharp::ImageType::HEIF)) {
823
835
  // Write HEIF to buffer
824
- VipsArea *area = VIPS_AREA(image.heifsave_buffer(VImage::option()
836
+ VipsArea *area = reinterpret_cast<VipsArea*>(image.heifsave_buffer(VImage::option()
825
837
  ->set("strip", !baton->withMetadata)
826
838
  ->set("compression", baton->heifCompression)
827
839
  ->set("Q", baton->heifQuality)
840
+ ->set("speed", baton->heifSpeed)
841
+ #if defined(VIPS_TYPE_FOREIGN_SUBSAMPLE)
842
+ ->set("subsample_mode", baton->heifChromaSubsampling == "4:4:4"
843
+ ? VIPS_FOREIGN_SUBSAMPLE_OFF : VIPS_FOREIGN_SUBSAMPLE_ON)
844
+ #endif
828
845
  ->set("lossless", baton->heifLossless)));
829
846
  baton->bufferOut = static_cast<char*>(area->data);
830
847
  baton->bufferOutLength = area->length;
@@ -873,7 +890,7 @@ class PipelineWorker : public Napi::AsyncWorker {
873
890
  bool const isV = sharp::IsV(baton->fileOut);
874
891
  bool const mightMatchInput = baton->formatOut == "input";
875
892
  bool const willMatchInput = mightMatchInput &&
876
- !(isJpeg || isPng || isWebp || isGif || isTiff || isDz || isDzZip || isV);
893
+ !(isJpeg || isPng || isWebp || isGif || isTiff || isHeif || isDz || isDzZip || isV);
877
894
 
878
895
  if (baton->formatOut == "jpeg" || (mightMatchInput && isJpeg) ||
879
896
  (willMatchInput && inputImageType == sharp::ImageType::JPEG)) {
@@ -938,6 +955,10 @@ class PipelineWorker : public Napi::AsyncWorker {
938
955
  sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG);
939
956
  baton->channels = std::min(baton->channels, 3);
940
957
  }
958
+ // Cast pixel values to float, if required
959
+ if (baton->tiffPredictor == VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT) {
960
+ image = image.cast(VIPS_FORMAT_FLOAT);
961
+ }
941
962
  image.tiffsave(const_cast<char*>(baton->fileOut.data()), VImage::option()
942
963
  ->set("strip", !baton->withMetadata)
943
964
  ->set("Q", baton->tiffQuality)
@@ -954,13 +975,15 @@ class PipelineWorker : public Napi::AsyncWorker {
954
975
  } else if (baton->formatOut == "heif" || (mightMatchInput && isHeif) ||
955
976
  (willMatchInput && inputImageType == sharp::ImageType::HEIF)) {
956
977
  // Write HEIF to file
957
- if (sharp::IsAvif(baton->fileOut)) {
958
- baton->heifCompression = VIPS_FOREIGN_HEIF_COMPRESSION_AV1;
959
- }
960
978
  image.heifsave(const_cast<char*>(baton->fileOut.data()), VImage::option()
961
979
  ->set("strip", !baton->withMetadata)
962
980
  ->set("Q", baton->heifQuality)
963
981
  ->set("compression", baton->heifCompression)
982
+ ->set("speed", baton->heifSpeed)
983
+ #if defined(VIPS_TYPE_FOREIGN_SUBSAMPLE)
984
+ ->set("subsample_mode", baton->heifChromaSubsampling == "4:4:4"
985
+ ? VIPS_FOREIGN_SUBSAMPLE_OFF : VIPS_FOREIGN_SUBSAMPLE_ON)
986
+ #endif
964
987
  ->set("lossless", baton->heifLossless));
965
988
  baton->formatOut = "heif";
966
989
  } else if (baton->formatOut == "dz" || isDz || isDzZip) {
@@ -1242,6 +1265,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1242
1265
  composite->gravity = sharp::AttrAsUint32(compositeObject, "gravity");
1243
1266
  composite->left = sharp::AttrAsInt32(compositeObject, "left");
1244
1267
  composite->top = sharp::AttrAsInt32(compositeObject, "top");
1268
+ composite->hasOffset = sharp::AttrAsBool(compositeObject, "hasOffset");
1245
1269
  composite->tile = sharp::AttrAsBool(compositeObject, "tile");
1246
1270
  composite->premultiplied = sharp::AttrAsBool(compositeObject, "premultiplied");
1247
1271
  baton->composite.push_back(composite);
@@ -1249,7 +1273,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1249
1273
  // Resize options
1250
1274
  baton->withoutEnlargement = sharp::AttrAsBool(options, "withoutEnlargement");
1251
1275
  baton->position = sharp::AttrAsInt32(options, "position");
1252
- baton->resizeBackground = sharp::AttrAsRgba(options, "resizeBackground");
1276
+ baton->resizeBackground = sharp::AttrAsVectorOfDouble(options, "resizeBackground");
1253
1277
  baton->kernel = sharp::AttrAsStr(options, "kernel");
1254
1278
  baton->fastShrinkOnLoad = sharp::AttrAsBool(options, "fastShrinkOnLoad");
1255
1279
  // Join Channel Options
@@ -1262,7 +1286,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1262
1286
  }
1263
1287
  // Operators
1264
1288
  baton->flatten = sharp::AttrAsBool(options, "flatten");
1265
- baton->flattenBackground = sharp::AttrAsRgba(options, "flattenBackground");
1289
+ baton->flattenBackground = sharp::AttrAsVectorOfDouble(options, "flattenBackground");
1266
1290
  baton->negate = sharp::AttrAsBool(options, "negate");
1267
1291
  baton->blurSigma = sharp::AttrAsDouble(options, "blurSigma");
1268
1292
  baton->brightness = sharp::AttrAsDouble(options, "brightness");
@@ -1284,7 +1308,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1284
1308
  baton->useExifOrientation = sharp::AttrAsBool(options, "useExifOrientation");
1285
1309
  baton->angle = sharp::AttrAsInt32(options, "angle");
1286
1310
  baton->rotationAngle = sharp::AttrAsDouble(options, "rotationAngle");
1287
- baton->rotationBackground = sharp::AttrAsRgba(options, "rotationBackground");
1311
+ baton->rotationBackground = sharp::AttrAsVectorOfDouble(options, "rotationBackground");
1288
1312
  baton->rotateBeforePreExtract = sharp::AttrAsBool(options, "rotateBeforePreExtract");
1289
1313
  baton->flip = sharp::AttrAsBool(options, "flip");
1290
1314
  baton->flop = sharp::AttrAsBool(options, "flop");
@@ -1292,8 +1316,15 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1292
1316
  baton->extendBottom = sharp::AttrAsInt32(options, "extendBottom");
1293
1317
  baton->extendLeft = sharp::AttrAsInt32(options, "extendLeft");
1294
1318
  baton->extendRight = sharp::AttrAsInt32(options, "extendRight");
1295
- baton->extendBackground = sharp::AttrAsRgba(options, "extendBackground");
1319
+ baton->extendBackground = sharp::AttrAsVectorOfDouble(options, "extendBackground");
1296
1320
  baton->extractChannel = sharp::AttrAsInt32(options, "extractChannel");
1321
+ baton->affineMatrix = sharp::AttrAsVectorOfDouble(options, "affineMatrix");
1322
+ baton->affineBackground = sharp::AttrAsVectorOfDouble(options, "affineBackground");
1323
+ baton->affineIdx = sharp::AttrAsDouble(options, "affineIdx");
1324
+ baton->affineIdy = sharp::AttrAsDouble(options, "affineIdy");
1325
+ baton->affineOdx = sharp::AttrAsDouble(options, "affineOdx");
1326
+ baton->affineOdy = sharp::AttrAsDouble(options, "affineOdy");
1327
+ baton->affineInterpolator = vips::VInterpolate::new_from_name(sharp::AttrAsStr(options, "affineInterpolator").data());
1297
1328
 
1298
1329
  baton->removeAlpha = sharp::AttrAsBool(options, "removeAlpha");
1299
1330
  baton->ensureAlpha = sharp::AttrAsBool(options, "ensureAlpha");
@@ -1376,6 +1407,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1376
1407
  baton->heifCompression = static_cast<VipsForeignHeifCompression>(
1377
1408
  vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_HEIF_COMPRESSION,
1378
1409
  sharp::AttrAsStr(options, "heifCompression").data()));
1410
+ baton->heifSpeed = sharp::AttrAsUint32(options, "heifSpeed");
1411
+ baton->heifChromaSubsampling = sharp::AttrAsStr(options, "heifChromaSubsampling");
1379
1412
 
1380
1413
  // Animated output
1381
1414
  if (sharp::HasAttr(options, "pageHeight")) {
@@ -1392,7 +1425,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1392
1425
  baton->tileSize = sharp::AttrAsUint32(options, "tileSize");
1393
1426
  baton->tileOverlap = sharp::AttrAsUint32(options, "tileOverlap");
1394
1427
  baton->tileAngle = sharp::AttrAsInt32(options, "tileAngle");
1395
- baton->tileBackground = sharp::AttrAsRgba(options, "tileBackground");
1428
+ baton->tileBackground = sharp::AttrAsVectorOfDouble(options, "tileBackground");
1396
1429
  baton->tileSkipBlanks = sharp::AttrAsInt32(options, "tileSkipBlanks");
1397
1430
  baton->tileContainer = static_cast<VipsForeignDzContainer>(
1398
1431
  vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_DZ_CONTAINER,
package/src/pipeline.h CHANGED
@@ -40,6 +40,7 @@ struct Composite {
40
40
  int gravity;
41
41
  int left;
42
42
  int top;
43
+ bool hasOffset;
43
44
  bool tile;
44
45
  bool premultiplied;
45
46
 
@@ -47,8 +48,9 @@ struct Composite {
47
48
  input(nullptr),
48
49
  mode(VIPS_BLEND_MODE_OVER),
49
50
  gravity(0),
50
- left(-1),
51
- top(-1),
51
+ left(0),
52
+ top(0),
53
+ hasOffset(false),
52
54
  tile(false),
53
55
  premultiplied(false) {}
54
56
  };
@@ -119,6 +121,13 @@ struct PipelineBaton {
119
121
  int extendRight;
120
122
  std::vector<double> extendBackground;
121
123
  bool withoutEnlargement;
124
+ std::vector<double> affineMatrix;
125
+ std::vector<double> affineBackground;
126
+ double affineIdx;
127
+ double affineIdy;
128
+ double affineOdx;
129
+ double affineOdy;
130
+ vips::VInterpolate affineInterpolator;
122
131
  int jpegQuality;
123
132
  bool jpegProgressive;
124
133
  std::string jpegChromaSubsampling;
@@ -152,6 +161,8 @@ struct PipelineBaton {
152
161
  double tiffYres;
153
162
  int heifQuality;
154
163
  VipsForeignHeifCompression heifCompression;
164
+ int heifSpeed;
165
+ std::string heifChromaSubsampling;
155
166
  bool heifLossless;
156
167
  std::string err;
157
168
  bool withMetadata;
@@ -231,6 +242,13 @@ struct PipelineBaton {
231
242
  extendRight(0),
232
243
  extendBackground{ 0.0, 0.0, 0.0, 255.0 },
233
244
  withoutEnlargement(false),
245
+ affineMatrix{ 1.0, 0.0, 0.0, 1.0 },
246
+ affineBackground{ 0.0, 0.0, 0.0, 255.0 },
247
+ affineIdx(0),
248
+ affineIdy(0),
249
+ affineOdx(0),
250
+ affineOdy(0),
251
+ affineInterpolator(vips::VInterpolate::new_from_name("bicubic")),
234
252
  jpegQuality(80),
235
253
  jpegProgressive(false),
236
254
  jpegChromaSubsampling("4:2:0"),
@@ -262,8 +280,10 @@ struct PipelineBaton {
262
280
  tiffTileWidth(256),
263
281
  tiffXres(1.0),
264
282
  tiffYres(1.0),
265
- heifQuality(80),
266
- heifCompression(VIPS_FOREIGN_HEIF_COMPRESSION_HEVC),
283
+ heifQuality(50),
284
+ heifCompression(VIPS_FOREIGN_HEIF_COMPRESSION_AV1),
285
+ heifSpeed(5),
286
+ heifChromaSubsampling("4:2:0"),
267
287
  heifLossless(false),
268
288
  withMetadata(false),
269
289
  withMetadataOrientation(-1),
package/src/sharp.cc CHANGED
@@ -22,6 +22,7 @@
22
22
  #include "stats.h"
23
23
 
24
24
  static void* sharp_vips_init(void*) {
25
+ g_setenv("VIPS_MIN_STACK_SIZE", "2m", FALSE);
25
26
  vips_init("sharp");
26
27
  return nullptr;
27
28
  }