sharp 0.29.0 → 0.30.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/lib/utility.js CHANGED
@@ -1,9 +1,12 @@
1
1
  'use strict';
2
2
 
3
+ const fs = require('fs');
4
+ const path = require('path');
3
5
  const events = require('events');
4
6
  const detectLibc = require('detect-libc');
5
7
 
6
8
  const is = require('./is');
9
+ const platformAndArch = require('./platform')();
7
10
  const sharp = require('./sharp');
8
11
 
9
12
  /**
@@ -45,8 +48,23 @@ let versions = {
45
48
  vips: sharp.libvipsVersion()
46
49
  };
47
50
  try {
48
- versions = require(`../vendor/${versions.vips}/versions.json`);
49
- } catch (err) {}
51
+ versions = require(`../vendor/${versions.vips}/${platformAndArch}/versions.json`);
52
+ } catch (_err) { /* ignore */ }
53
+
54
+ /**
55
+ * An Object containing the platform and architecture
56
+ * of the current and installed vendored binaries.
57
+ * @member
58
+ * @example
59
+ * console.log(sharp.vendor);
60
+ */
61
+ const vendor = {
62
+ current: platformAndArch,
63
+ installed: []
64
+ };
65
+ try {
66
+ vendor.installed = fs.readdirSync(path.join(__dirname, `../vendor/${versions.vips}`));
67
+ } catch (_err) { /* ignore */ }
50
68
 
51
69
  /**
52
70
  * Gets or, when options are provided, sets the limits of _libvips'_ operation cache.
@@ -110,7 +128,7 @@ function concurrency (concurrency) {
110
128
  return sharp.concurrency(is.integer(concurrency) ? concurrency : null);
111
129
  }
112
130
  /* istanbul ignore next */
113
- if (detectLibc.family === detectLibc.GLIBC && !sharp._isUsingJemalloc()) {
131
+ if (detectLibc.familySync() === detectLibc.GLIBC && !sharp._isUsingJemalloc()) {
114
132
  // Reduce default concurrency to 1 when using glibc memory allocator
115
133
  sharp.concurrency(1);
116
134
  }
@@ -175,5 +193,6 @@ module.exports = function (Sharp) {
175
193
  Sharp.format = format;
176
194
  Sharp.interpolators = interpolators;
177
195
  Sharp.versions = versions;
196
+ Sharp.vendor = vendor;
178
197
  Sharp.queue = queue;
179
198
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sharp",
3
- "description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images",
4
- "version": "0.29.0",
3
+ "description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
4
+ "version": "0.30.0",
5
5
  "author": "Lovell Fuller <npm@lovell.info>",
6
6
  "homepage": "https://github.com/lovell/sharp",
7
7
  "contributors": [
@@ -78,7 +78,10 @@
78
78
  "Jacob Smith <jacob@frende.me>",
79
79
  "Michael Nutt <michael@nutt.im>",
80
80
  "Brad Parham <baparham@gmail.com>",
81
- "Taneli Vatanen <taneli.vatanen@gmail.com>"
81
+ "Taneli Vatanen <taneli.vatanen@gmail.com>",
82
+ "Joris Dugué <zaruike10@gmail.com>",
83
+ "Chris Banks <christopher.bradley.banks@gmail.com>",
84
+ "Ompal Singh <ompal.hitm09@gmail.com>"
82
85
  ],
83
86
  "scripts": {
84
87
  "install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)",
@@ -112,6 +115,7 @@
112
115
  "tiff",
113
116
  "gif",
114
117
  "svg",
118
+ "jp2",
115
119
  "dzi",
116
120
  "image",
117
121
  "resize",
@@ -122,33 +126,46 @@
122
126
  "vips"
123
127
  ],
124
128
  "dependencies": {
125
- "color": "^4.0.1",
126
- "detect-libc": "^1.0.3",
127
- "node-addon-api": "^4.0.0",
128
- "prebuild-install": "^6.1.4",
129
+ "color": "^4.2.0",
130
+ "detect-libc": "^2.0.0",
131
+ "node-addon-api": "^4.3.0",
132
+ "prebuild-install": "^7.0.1",
129
133
  "semver": "^7.3.5",
130
- "simple-get": "^3.1.0",
134
+ "simple-get": "^4.0.1",
131
135
  "tar-fs": "^2.1.1",
132
136
  "tunnel-agent": "^0.6.0"
133
137
  },
134
138
  "devDependencies": {
135
- "async": "^3.2.1",
139
+ "async": "^3.2.3",
136
140
  "cc": "^3.0.1",
137
141
  "decompress-zip": "^0.3.3",
138
142
  "documentation": "^13.2.5",
139
143
  "exif-reader": "^1.0.3",
140
144
  "icc": "^2.0.0",
141
145
  "license-checker": "^25.0.1",
142
- "mocha": "^9.0.3",
143
- "mock-fs": "^5.0.0",
146
+ "mocha": "^9.2.0",
147
+ "mock-fs": "^5.1.2",
144
148
  "nyc": "^15.1.0",
145
- "prebuild": "^10.0.1",
149
+ "prebuild": "^11.0.2",
146
150
  "rimraf": "^3.0.2",
147
151
  "semistandard": "^16.0.1"
148
152
  },
149
153
  "license": "Apache-2.0",
150
154
  "config": {
151
- "libvips": "8.11.3",
155
+ "libvips": "8.12.2",
156
+ "integrity": {
157
+ "darwin-arm64v8": "sha512-p46s/bbJAjkOXzPISZt9HUpG9GWjwQkYnLLRLKzsBJHLtB3X6C6Y/zXI5Hd0DOojcFkks9a0kTN+uDQ/XJY19g==",
158
+ "darwin-x64": "sha512-6vOHVZnvXwe6EXRsy29jdkUzBE6ElNpXUwd+m8vV7qy32AnXu7B9YemHsZ44vWviIwPZeXF6Nhd9EFLM0wWohw==",
159
+ "linux-arm64v8": "sha512-XwZdS63yhqLtbFtx/0eoLF/Agf5qtTrI11FMnMRpuBJWd4jHB60RAH+uzYUgoChCmKIS+AeXYMLm4d8Ns2QX8w==",
160
+ "linux-armv6": "sha512-Rh0Q0kqwPG2MjXWOkPCuPEyiUKFgKJYWLgS835D4MrXgdKr8Tft/eVrc2iGIxt2re30VpDiZ1h0Rby1aCZt2zw==",
161
+ "linux-armv7": "sha512-heTS/MsmRvu4JljINxP+vDiS9ZZfuGhr3IStb5F7Gc0/QLRhllYAg4rcO8L1eTK9sIIzG5ARvI19+YUZe7WbzA==",
162
+ "linux-x64": "sha512-SSWAwBFi0hx8V/h/v82tTFGKWTFv9FiCK3Timz5OExuI+sX1Ngrd0PVQaWXOThGNdel/fcD3Bz9YjSt4feBR1g==",
163
+ "linuxmusl-arm64v8": "sha512-Rhks+5C7p7aO6AucLT1uvzo8ohlqcqCUPgZmN+LZjsPWob/Iix3MfiDYtv/+gTvdeEfXxbCU6/YuPBwHQ7/crA==",
164
+ "linuxmusl-x64": "sha512-IOyjSQqpWVntqOUpCHVWuQwACwmmjdi15H8Pc+Ma1JkhPogTfVsFQWyL7DuOTD3Yr23EuYGzovUX00duOtfy/g==",
165
+ "win32-arm64v8": "sha512-A+Qe8Ipewtvw9ldvF6nWed2J8kphzrUE04nFeKCtNx6pfGQ/MAlCKMjt/U8VgUKNjB01zJDUW9XE0+FhGZ/UpQ==",
166
+ "win32-ia32": "sha512-cMrAvwFdDeAVnLJt0IPMPRKaIFhyXYGTprsM0DND9VUHE8F7dJMR44tS5YkXsGh1QNDtjKT6YuxAVUglmiXtpA==",
167
+ "win32-x64": "sha512-vLFIfw6aW2zABa8jpgzWDhljnE6glktrddErVyazAIoHl6BFFe/Da+LK1DbXvIYHz7fyOoKhSfCJHCiJG1Vg6w=="
168
+ },
152
169
  "runtime": "napi",
153
170
  "target": 5
154
171
  },
package/src/common.cc CHANGED
@@ -132,6 +132,8 @@ namespace sharp {
132
132
  descriptor->limitInputPixels = AttrAsUint32(input, "limitInputPixels");
133
133
  // Allow switch from random to sequential access
134
134
  descriptor->access = AttrAsBool(input, "sequentialRead") ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM;
135
+ // Remove safety features and allow unlimited SVG/PNG input
136
+ descriptor->unlimited = AttrAsBool(input, "unlimited");
135
137
  return descriptor;
136
138
  }
137
139
 
@@ -157,6 +159,10 @@ namespace sharp {
157
159
  bool IsGif(std::string const &str) {
158
160
  return EndsWith(str, ".gif") || EndsWith(str, ".GIF");
159
161
  }
162
+ bool IsJp2(std::string const &str) {
163
+ return EndsWith(str, ".jp2") || EndsWith(str, ".jpx") || EndsWith(str, ".j2k") || EndsWith(str, ".j2c")
164
+ || EndsWith(str, ".JP2") || EndsWith(str, ".JPX") || EndsWith(str, ".J2K") || EndsWith(str, ".J2C");
165
+ }
160
166
  bool IsTiff(std::string const &str) {
161
167
  return EndsWith(str, ".tif") || EndsWith(str, ".tiff") || EndsWith(str, ".TIF") || EndsWith(str, ".TIFF");
162
168
  }
@@ -190,6 +196,7 @@ namespace sharp {
190
196
  case ImageType::WEBP: id = "webp"; break;
191
197
  case ImageType::TIFF: id = "tiff"; break;
192
198
  case ImageType::GIF: id = "gif"; break;
199
+ case ImageType::JP2: id = "jp2"; break;
193
200
  case ImageType::SVG: id = "svg"; break;
194
201
  case ImageType::HEIF: id = "heif"; break;
195
202
  case ImageType::PDF: id = "pdf"; break;
@@ -226,6 +233,8 @@ namespace sharp {
226
233
  { "VipsForeignLoadGifBuffer", ImageType::GIF },
227
234
  { "VipsForeignLoadNsgifFile", ImageType::GIF },
228
235
  { "VipsForeignLoadNsgifBuffer", ImageType::GIF },
236
+ { "VipsForeignLoadJp2kBuffer", ImageType::JP2 },
237
+ { "VipsForeignLoadJp2kFile", ImageType::JP2 },
229
238
  { "VipsForeignLoadSvgFile", ImageType::SVG },
230
239
  { "VipsForeignLoadSvgBuffer", ImageType::SVG },
231
240
  { "VipsForeignLoadHeifFile", ImageType::HEIF },
@@ -234,6 +243,8 @@ namespace sharp {
234
243
  { "VipsForeignLoadPdfBuffer", ImageType::PDF },
235
244
  { "VipsForeignLoadMagickFile", ImageType::MAGICK },
236
245
  { "VipsForeignLoadMagickBuffer", ImageType::MAGICK },
246
+ { "VipsForeignLoadMagick7File", ImageType::MAGICK },
247
+ { "VipsForeignLoadMagick7Buffer", ImageType::MAGICK },
237
248
  { "VipsForeignLoadOpenslide", ImageType::OPENSLIDE },
238
249
  { "VipsForeignLoadPpmFile", ImageType::PPM },
239
250
  { "VipsForeignLoadFits", ImageType::FITS },
@@ -285,6 +296,7 @@ namespace sharp {
285
296
  imageType == ImageType::WEBP ||
286
297
  imageType == ImageType::MAGICK ||
287
298
  imageType == ImageType::GIF ||
299
+ imageType == ImageType::JP2 ||
288
300
  imageType == ImageType::TIFF ||
289
301
  imageType == ImageType::HEIF ||
290
302
  imageType == ImageType::PDF;
@@ -318,7 +330,7 @@ namespace sharp {
318
330
  vips::VOption *option = VImage::option()
319
331
  ->set("access", descriptor->access)
320
332
  ->set("fail", descriptor->failOnError);
321
- if (imageType == ImageType::SVG) {
333
+ if (descriptor->unlimited && (imageType == ImageType::SVG || imageType == ImageType::PNG)) {
322
334
  option->set("unlimited", TRUE);
323
335
  }
324
336
  if (imageType == ImageType::SVG || imageType == ImageType::PDF) {
@@ -393,7 +405,7 @@ namespace sharp {
393
405
  vips::VOption *option = VImage::option()
394
406
  ->set("access", descriptor->access)
395
407
  ->set("fail", descriptor->failOnError);
396
- if (imageType == ImageType::SVG) {
408
+ if (descriptor->unlimited && (imageType == ImageType::SVG || imageType == ImageType::PNG)) {
397
409
  option->set("unlimited", TRUE);
398
410
  }
399
411
  if (imageType == ImageType::SVG || imageType == ImageType::PDF) {
@@ -478,36 +490,41 @@ namespace sharp {
478
490
 
479
491
  /*
480
492
  Set animation properties if necessary.
481
- Non-provided properties will be loaded from image.
482
493
  */
483
- VImage SetAnimationProperties(VImage image, int pageHeight, std::vector<int> delay, int loop) {
484
- bool hasDelay = delay.size() != 1 || delay.front() != -1;
485
-
486
- if (pageHeight == 0 && image.get_typeof(VIPS_META_PAGE_HEIGHT) == G_TYPE_INT) {
487
- pageHeight = image.get_int(VIPS_META_PAGE_HEIGHT);
488
- }
494
+ VImage SetAnimationProperties(VImage image, int nPages, int pageHeight, std::vector<int> delay, int loop) {
495
+ bool hasDelay = !delay.empty();
489
496
 
490
- if (!hasDelay && image.get_typeof("delay") == VIPS_TYPE_ARRAY_INT) {
491
- delay = image.get_array_int("delay");
492
- hasDelay = true;
493
- }
497
+ // Avoid a copy if none of the animation properties are needed.
498
+ if (nPages == 1 && !hasDelay && loop == -1) return image;
494
499
 
495
- if (loop == -1 && image.get_typeof("loop") == G_TYPE_INT) {
496
- loop = image.get_int("loop");
500
+ if (delay.size() == 1) {
501
+ // We have just one delay, repeat that value for all frames.
502
+ delay.insert(delay.end(), nPages - 1, delay[0]);
497
503
  }
498
504
 
499
- if (pageHeight == 0) return image;
500
-
501
- // It is necessary to create the copy as otherwise, pageHeight will be ignored!
505
+ // Attaching metadata, need to copy the image.
502
506
  VImage copy = image.copy();
503
507
 
504
- copy.set(VIPS_META_PAGE_HEIGHT, pageHeight);
508
+ // Only set page-height if we have more than one page, or this could
509
+ // accidentally turn into an animated image later.
510
+ if (nPages > 1) copy.set(VIPS_META_PAGE_HEIGHT, pageHeight);
505
511
  if (hasDelay) copy.set("delay", delay);
506
512
  if (loop != -1) copy.set("loop", loop);
507
513
 
508
514
  return copy;
509
515
  }
510
516
 
517
+ /*
518
+ Remove animation properties from image.
519
+ */
520
+ VImage RemoveAnimationProperties(VImage image) {
521
+ VImage copy = image.copy();
522
+ copy.remove(VIPS_META_PAGE_HEIGHT);
523
+ copy.remove("delay");
524
+ copy.remove("loop");
525
+ return copy;
526
+ }
527
+
511
528
  /*
512
529
  Does this image have a non-default density?
513
530
  */
@@ -533,6 +550,14 @@ namespace sharp {
533
550
  return copy;
534
551
  }
535
552
 
553
+ /*
554
+ Multi-page images can have a page height. Fetch it, and sanity check it.
555
+ If page-height is not set, it defaults to the image height
556
+ */
557
+ int GetPageHeight(VImage image) {
558
+ return vips_image_get_page_height(image.get_image());
559
+ }
560
+
536
561
  /*
537
562
  Check the proposed format supports the current dimensions.
538
563
  */
@@ -589,6 +614,33 @@ namespace sharp {
589
614
  return warning;
590
615
  }
591
616
 
617
+ /*
618
+ Attach an event listener for progress updates, used to detect timeout
619
+ */
620
+ void SetTimeout(VImage image, int const seconds) {
621
+ if (seconds > 0) {
622
+ VipsImage *im = image.get_image();
623
+ if (im->progress_signal == NULL) {
624
+ int *timeout = VIPS_NEW(im, int);
625
+ *timeout = seconds;
626
+ g_signal_connect(im, "eval", G_CALLBACK(VipsProgressCallBack), timeout);
627
+ vips_image_set_progress(im, TRUE);
628
+ }
629
+ }
630
+ }
631
+
632
+ /*
633
+ Event listener for progress updates, used to detect timeout
634
+ */
635
+ void VipsProgressCallBack(VipsImage *im, VipsProgress *progress, int *timeout) {
636
+ // printf("VipsProgressCallBack progress=%d run=%d timeout=%d\n", progress->percent, progress->run, *timeout);
637
+ if (*timeout > 0 && progress->run >= *timeout) {
638
+ vips_image_set_kill(im, TRUE);
639
+ vips_error("timeout", "%d%% complete", progress->percent);
640
+ *timeout = 0;
641
+ }
642
+ }
643
+
592
644
  /*
593
645
  Calculate the (left, top) coordinates of the output image
594
646
  within the input image, applying the given gravity during an embed.
@@ -757,23 +809,27 @@ namespace sharp {
757
809
  /*
758
810
  Convert RGBA value to another colourspace
759
811
  */
760
- std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba, VipsInterpretation const interpretation) {
812
+ std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba,
813
+ VipsInterpretation const interpretation, bool premultiply) {
761
814
  int const bands = static_cast<int>(rgba.size());
762
- if (bands < 3 || interpretation == VIPS_INTERPRETATION_sRGB || interpretation == VIPS_INTERPRETATION_RGB) {
815
+ if (bands < 3) {
763
816
  return rgba;
764
- } else {
765
- VImage pixel = VImage::new_matrix(1, 1);
766
- pixel.set("bands", bands);
767
- pixel = pixel.new_from_image(rgba);
768
- pixel = pixel.colourspace(interpretation, VImage::option()->set("source_space", VIPS_INTERPRETATION_sRGB));
769
- return pixel(0, 0);
770
817
  }
818
+ VImage pixel = VImage::new_matrix(1, 1);
819
+ pixel.set("bands", bands);
820
+ pixel = pixel
821
+ .new_from_image(rgba)
822
+ .colourspace(interpretation, VImage::option()->set("source_space", VIPS_INTERPRETATION_sRGB));
823
+ if (premultiply) {
824
+ pixel = pixel.premultiply();
825
+ }
826
+ return pixel(0, 0);
771
827
  }
772
828
 
773
829
  /*
774
830
  Apply the alpha channel to a given colour
775
831
  */
776
- std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour) {
832
+ std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour, bool premultiply) {
777
833
  // Scale up 8-bit values to match 16-bit input image
778
834
  double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0;
779
835
  // Create alphaColour colour
@@ -797,7 +853,7 @@ namespace sharp {
797
853
  alphaColour.push_back(colour[3] * multiplier);
798
854
  }
799
855
  // Ensure alphaColour colour uses correct colourspace
800
- alphaColour = sharp::GetRgbaAsColourspace(alphaColour, image.interpretation());
856
+ alphaColour = sharp::GetRgbaAsColourspace(alphaColour, image.interpretation(), premultiply);
801
857
  // Add non-transparent alpha channel, if required
802
858
  if (colour[3] < 255.0 && !HasAlpha(image)) {
803
859
  image = image.bandjoin(
@@ -827,4 +883,75 @@ namespace sharp {
827
883
  }
828
884
  return image;
829
885
  }
886
+
887
+ std::pair<double, double> ResolveShrink(int width, int height, int targetWidth, int targetHeight,
888
+ Canvas canvas, bool swap, bool withoutEnlargement) {
889
+ if (swap) {
890
+ // Swap input width and height when requested.
891
+ std::swap(width, height);
892
+ }
893
+
894
+ double hshrink = 1.0;
895
+ double vshrink = 1.0;
896
+
897
+ if (targetWidth > 0 && targetHeight > 0) {
898
+ // Fixed width and height
899
+ hshrink = static_cast<double>(width) / targetWidth;
900
+ vshrink = static_cast<double>(height) / targetHeight;
901
+
902
+ switch (canvas) {
903
+ case Canvas::CROP:
904
+ case Canvas::MIN:
905
+ if (hshrink < vshrink) {
906
+ vshrink = hshrink;
907
+ } else {
908
+ hshrink = vshrink;
909
+ }
910
+ break;
911
+ case Canvas::EMBED:
912
+ case Canvas::MAX:
913
+ if (hshrink > vshrink) {
914
+ vshrink = hshrink;
915
+ } else {
916
+ hshrink = vshrink;
917
+ }
918
+ break;
919
+ case Canvas::IGNORE_ASPECT:
920
+ if (swap) {
921
+ std::swap(hshrink, vshrink);
922
+ }
923
+ break;
924
+ }
925
+ } else if (targetWidth > 0) {
926
+ // Fixed width
927
+ hshrink = static_cast<double>(width) / targetWidth;
928
+
929
+ if (canvas != Canvas::IGNORE_ASPECT) {
930
+ // Auto height
931
+ vshrink = hshrink;
932
+ }
933
+ } else if (targetHeight > 0) {
934
+ // Fixed height
935
+ vshrink = static_cast<double>(height) / targetHeight;
936
+
937
+ if (canvas != Canvas::IGNORE_ASPECT) {
938
+ // Auto width
939
+ hshrink = vshrink;
940
+ }
941
+ }
942
+
943
+ // We should not enlarge (oversample) the output image,
944
+ // if withoutEnlargement is specified.
945
+ if (withoutEnlargement) {
946
+ hshrink = std::max(1.0, hshrink);
947
+ vshrink = std::max(1.0, vshrink);
948
+ }
949
+
950
+ // We don't want to shrink so much that we send an axis to 0
951
+ hshrink = std::min(hshrink, static_cast<double>(width));
952
+ vshrink = std::min(vshrink, static_cast<double>(height));
953
+
954
+ return std::make_pair(hshrink, vshrink);
955
+ }
956
+
830
957
  } // namespace sharp
package/src/common.h CHANGED
@@ -25,9 +25,9 @@
25
25
  // Verify platform and compiler compatibility
26
26
 
27
27
  #if (VIPS_MAJOR_VERSION < 8) || \
28
- (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 11) || \
29
- (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 11 && VIPS_MICRO_VERSION < 3)
30
- #error "libvips version 8.11.3+ is required - please see https://sharp.pixelplumbing.com/install"
28
+ (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 12) || \
29
+ (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 12 && VIPS_MICRO_VERSION < 2)
30
+ #error "libvips version 8.12.2+ is required - please see https://sharp.pixelplumbing.com/install"
31
31
  #endif
32
32
 
33
33
  #if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
@@ -50,6 +50,7 @@ namespace sharp {
50
50
  char *buffer;
51
51
  bool failOnError;
52
52
  int limitInputPixels;
53
+ bool unlimited;
53
54
  VipsAccess access;
54
55
  size_t bufferLength;
55
56
  bool isBuffer;
@@ -75,6 +76,7 @@ namespace sharp {
75
76
  buffer(nullptr),
76
77
  failOnError(TRUE),
77
78
  limitInputPixels(0x3FFF * 0x3FFF),
79
+ unlimited(FALSE),
78
80
  access(VIPS_ACCESS_RANDOM),
79
81
  bufferLength(0),
80
82
  isBuffer(FALSE),
@@ -116,6 +118,7 @@ namespace sharp {
116
118
  JPEG,
117
119
  PNG,
118
120
  WEBP,
121
+ JP2,
119
122
  TIFF,
120
123
  GIF,
121
124
  SVG,
@@ -132,6 +135,14 @@ namespace sharp {
132
135
  MISSING
133
136
  };
134
137
 
138
+ enum class Canvas {
139
+ CROP,
140
+ EMBED,
141
+ MAX,
142
+ MIN,
143
+ IGNORE_ASPECT
144
+ };
145
+
135
146
  // How many tasks are in the queue?
136
147
  extern volatile int counterQueue;
137
148
 
@@ -142,6 +153,7 @@ namespace sharp {
142
153
  bool IsJpeg(std::string const &str);
143
154
  bool IsPng(std::string const &str);
144
155
  bool IsWebp(std::string const &str);
156
+ bool IsJp2(std::string const &str);
145
157
  bool IsGif(std::string const &str);
146
158
  bool IsTiff(std::string const &str);
147
159
  bool IsHeic(std::string const &str);
@@ -204,9 +216,13 @@ namespace sharp {
204
216
 
205
217
  /*
206
218
  Set animation properties if necessary.
207
- Non-provided properties will be loaded from image.
208
219
  */
209
- VImage SetAnimationProperties(VImage image, int pageHeight, std::vector<int> delay, int loop);
220
+ VImage SetAnimationProperties(VImage image, int nPages, int pageHeight, std::vector<int> delay, int loop);
221
+
222
+ /*
223
+ Remove animation properties from image.
224
+ */
225
+ VImage RemoveAnimationProperties(VImage image);
210
226
 
211
227
  /*
212
228
  Does this image have a non-default density?
@@ -223,6 +239,12 @@ namespace sharp {
223
239
  */
224
240
  VImage SetDensity(VImage image, const double density);
225
241
 
242
+ /*
243
+ Multi-page images can have a page height. Fetch it, and sanity check it.
244
+ If page-height is not set, it defaults to the image height
245
+ */
246
+ int GetPageHeight(VImage image);
247
+
226
248
  /*
227
249
  Check the proposed format supports the current dimensions.
228
250
  */
@@ -243,6 +265,16 @@ namespace sharp {
243
265
  */
244
266
  std::string VipsWarningPop();
245
267
 
268
+ /*
269
+ Attach an event listener for progress updates, used to detect timeout
270
+ */
271
+ void SetTimeout(VImage image, int const timeoutSeconds);
272
+
273
+ /*
274
+ Event listener for progress updates, used to detect timeout
275
+ */
276
+ void VipsProgressCallBack(VipsImage *image, VipsProgress *progress, int *timeoutSeconds);
277
+
246
278
  /*
247
279
  Calculate the (left, top) coordinates of the output image
248
280
  within the input image, applying the given gravity during an embed.
@@ -288,12 +320,13 @@ namespace sharp {
288
320
  /*
289
321
  Convert RGBA value to another colourspace
290
322
  */
291
- std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba, VipsInterpretation const interpretation);
323
+ std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba,
324
+ VipsInterpretation const interpretation, bool premultiply);
292
325
 
293
326
  /*
294
327
  Apply the alpha channel to a given colour
295
328
  */
296
- std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour);
329
+ std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour, bool premultiply);
297
330
 
298
331
  /*
299
332
  Removes alpha channel, if any.
@@ -305,6 +338,15 @@ namespace sharp {
305
338
  */
306
339
  VImage EnsureAlpha(VImage image, double const value);
307
340
 
341
+ /*
342
+ Calculate the shrink factor, taking into account auto-rotate, the canvas
343
+ mode, and so on. The hshrink/vshrink are the amount to shrink the input
344
+ image axes by in order for the output axes (ie. after rotation) to match
345
+ the required thumbnail width/height and canvas mode.
346
+ */
347
+ std::pair<double, double> ResolveShrink(int width, int height, int targetWidth, int targetHeight,
348
+ Canvas canvas, bool swap, bool withoutEnlargement);
349
+
308
350
  } // namespace sharp
309
351
 
310
352
  #endif // SRC_COMMON_H_