@revizly/sharp 0.35.0-revizly4 → 0.35.0-revizly41

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.
Files changed (46) hide show
  1. package/README.md +12 -18
  2. package/{lib/channel.js → dist/channel.cjs} +1 -1
  3. package/dist/channel.mjs +177 -0
  4. package/{lib/colour.js → dist/colour.cjs} +11 -7
  5. package/dist/colour.mjs +199 -0
  6. package/{lib/composite.js → dist/composite.cjs} +2 -1
  7. package/dist/composite.mjs +213 -0
  8. package/{lib/constructor.js → dist/constructor.cjs} +42 -29
  9. package/dist/constructor.mjs +512 -0
  10. package/dist/index.cjs +25 -0
  11. package/dist/index.d.cts +2001 -0
  12. package/dist/index.d.mts +2048 -0
  13. package/dist/index.mjs +25 -0
  14. package/{lib/input.js → dist/input.cjs} +26 -21
  15. package/dist/input.mjs +814 -0
  16. package/{lib/is.js → dist/is.cjs} +1 -1
  17. package/dist/is.mjs +143 -0
  18. package/{lib/libvips.js → dist/libvips.cjs} +35 -30
  19. package/dist/libvips.mjs +212 -0
  20. package/{lib/operation.js → dist/operation.cjs} +33 -51
  21. package/dist/operation.mjs +998 -0
  22. package/{lib/output.js → dist/output.cjs} +161 -28
  23. package/dist/output.mjs +1799 -0
  24. package/{lib/resize.js → dist/resize.cjs} +46 -24
  25. package/dist/resize.mjs +617 -0
  26. package/dist/sharp.cjs +125 -0
  27. package/dist/sharp.mjs +125 -0
  28. package/{lib/utility.js → dist/utility.cjs} +18 -8
  29. package/dist/utility.mjs +301 -0
  30. package/install/build.js +3 -3
  31. package/lib/index.d.ts +105 -75
  32. package/package.json +46 -27
  33. package/src/binding.gyp +18 -13
  34. package/src/common.cc +70 -17
  35. package/src/common.h +22 -3
  36. package/src/metadata.cc +66 -8
  37. package/src/metadata.h +6 -1
  38. package/src/operations.cc +25 -8
  39. package/src/operations.h +1 -1
  40. package/src/pipeline.cc +206 -69
  41. package/src/pipeline.h +16 -1
  42. package/src/stats.cc +6 -6
  43. package/src/utilities.cc +7 -6
  44. package/install/check.js +0 -14
  45. package/lib/index.js +0 -16
  46. package/lib/sharp.js +0 -121
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  const path = require('node:path');
7
- const is = require('./is');
8
- const sharp = require('./sharp');
7
+ const is = require('./is.cjs');
8
+ const sharp = require('./sharp.cjs');
9
9
 
10
10
  const formats = new Map([
11
11
  ['heic', 'heif'],
@@ -76,7 +76,7 @@ function toFile (fileOut, callback) {
76
76
  err = new Error('Missing output file path');
77
77
  } else if (is.string(this.options.input.file) && path.resolve(this.options.input.file) === path.resolve(fileOut)) {
78
78
  err = new Error('Cannot use same file for input and output');
79
- } else if (jp2Regex.test(path.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
79
+ } else if (jp2Regex.test(path.extname(fileOut)) && !this.constructor.format.jp2.output.file) {
80
80
  err = errJp2Save();
81
81
  }
82
82
  if (err) {
@@ -164,6 +164,64 @@ function toBuffer (options, callback) {
164
164
  return this._pipeline(is.fn(options) ? options : callback, stack);
165
165
  }
166
166
 
167
+ /**
168
+ * Write output to a `Uint8Array` backed by a transferable `ArrayBuffer`.
169
+ * JPEG, PNG, WebP, AVIF, TIFF, GIF and raw pixel data output are supported.
170
+ *
171
+ * Use {@link #toformat toFormat} or one of the format-specific functions such as {@link #jpeg jpeg}, {@link #png png} etc. to set the output format.
172
+ *
173
+ * If no explicit format is set, the output format will match the input image, except SVG input which becomes PNG output.
174
+ *
175
+ * By default all metadata will be removed, which includes EXIF-based orientation.
176
+ * See {@link #keepexif keepExif} and similar methods for control over this.
177
+ *
178
+ * Resolves with an `Object` containing:
179
+ * - `data` is the output image as a `Uint8Array` backed by a transferable `ArrayBuffer`.
180
+ * - `info` contains properties relating to the output image such as `width` and `height`.
181
+ *
182
+ * @since v0.35.0
183
+ *
184
+ * @example
185
+ * const { data, info } = await sharp(input).toUint8Array();
186
+ *
187
+ * @example
188
+ * const { data } = await sharp(input)
189
+ * .avif()
190
+ * .toUint8Array();
191
+ * const base64String = data.toBase64();
192
+ *
193
+ * @returns {Promise<{ data: Uint8Array, info: Object }>}
194
+ */
195
+ function toUint8Array () {
196
+ this.options.resolveWithObject = true;
197
+ this.options.typedArrayOut = true;
198
+ const stack = Error();
199
+ return this._pipeline(null, stack);
200
+ }
201
+
202
+ /**
203
+ * Set output density (DPI) in EXIF metadata.
204
+ *
205
+ * @since 0.35.0
206
+ *
207
+ * @example
208
+ * const data = await sharp(input)
209
+ * .withDensity(96)
210
+ * .toBuffer();
211
+ *
212
+ * @param {number} density Number of pixels per inch (DPI).
213
+ * @returns {Sharp}
214
+ * @throws {Error} Invalid parameters
215
+ */
216
+ function withDensity (density) {
217
+ if (is.number(density) && density > 0) {
218
+ this.options.withMetadataDensity = density;
219
+ } else {
220
+ throw is.invalidParameterError('density', 'positive number', density);
221
+ }
222
+ return this.keepExif();
223
+ }
224
+
167
225
  /**
168
226
  * Keep all EXIF metadata from the input image in the output image.
169
227
  *
@@ -319,6 +377,60 @@ function withIccProfile (icc, options) {
319
377
  return this;
320
378
  }
321
379
 
380
+ /**
381
+ * If the input contains gain map metadata, attempt to process the image and gain map separately,
382
+ * recombining them into a single output image.
383
+ *
384
+ * This approach is faster and should produce better results than {@link #withgainmap withGainMap},
385
+ * however not all operations are supported.
386
+ *
387
+ * Only JPEG input and output are supported.
388
+ * JPEG output options other than `quality` are ignored.
389
+ *
390
+ * This feature is experimental and the API may change.
391
+ *
392
+ * @since 0.35.0
393
+ *
394
+ * @example
395
+ * const outputWithResizedGainMap = await sharp(inputWithGainMap)
396
+ * .keepGainMap()
397
+ * .resize({ width: 64 })
398
+ * .toBuffer();
399
+ *
400
+ * @returns {Sharp}
401
+ */
402
+ function keepGainMap() {
403
+ this.options.keepGainMap = true;
404
+ this.options.withGainMap = false;
405
+ this.options.keepMetadata |= 0b100000;
406
+ return this;
407
+ }
408
+
409
+ /**
410
+ * If the input contains gain map metadata, use it to convert the main image to HDR (High Dynamic Range) before further processing.
411
+ * The input gain map is discarded.
412
+ *
413
+ * If the output is JPEG, generate and attach a new ISO 21496-1 gain map.
414
+ * JPEG output options other than `quality` are ignored.
415
+ *
416
+ * This feature is experimental and the API may change.
417
+ *
418
+ * @since 0.35.0
419
+ *
420
+ * @example
421
+ * const outputWithRegeneratedGainMap = await sharp(inputWithGainMap)
422
+ * .withGainMap()
423
+ * .toBuffer();
424
+ *
425
+ * @returns {Sharp}
426
+ */
427
+ function withGainMap() {
428
+ this.options.withGainMap = true;
429
+ this.options.keepGainMap = false;
430
+ this.options.colourspace = 'scrgb';
431
+ return this;
432
+ }
433
+
322
434
  /**
323
435
  * Keep XMP metadata from the input image in the output image.
324
436
  *
@@ -388,7 +500,7 @@ function withXmp (xmp) {
388
500
  * @returns {Sharp}
389
501
  */
390
502
  function keepMetadata () {
391
- this.options.keepMetadata = 0b11111;
503
+ this.options.keepMetadata |= 0b11111;
392
504
  return this;
393
505
  }
394
506
 
@@ -690,6 +802,7 @@ function png (options) {
690
802
  * @param {number|number[]} [options.delay] - delay(s) between animation frames (in milliseconds)
691
803
  * @param {boolean} [options.minSize=false] - prevent use of animation key frames to minimise file size (slow)
692
804
  * @param {boolean} [options.mixed=false] - allow mixture of lossy and lossless animation frames (slow)
805
+ * @param {boolean} [options.exact=false] - preserve the colour data in transparent pixels
693
806
  * @param {boolean} [options.force=true] - force WebP output, otherwise attempt to use input format
694
807
  * @returns {Sharp}
695
808
  * @throws {Error} Invalid options
@@ -742,6 +855,9 @@ function webp (options) {
742
855
  if (is.defined(options.mixed)) {
743
856
  this._setBooleanOption('webpMixed', options.mixed);
744
857
  }
858
+ if (is.defined(options.exact)) {
859
+ this._setBooleanOption('webpExact', options.exact);
860
+ }
745
861
  }
746
862
  trySetAnimationOptions(options, this.options);
747
863
  return this._updateFormatOut('webp', options);
@@ -813,7 +929,7 @@ function gif (options) {
813
929
  }
814
930
  }
815
931
  if (is.defined(options.effort)) {
816
- if (is.number(options.effort) && is.inRange(options.effort, 1, 10)) {
932
+ if (is.integer(options.effort) && is.inRange(options.effort, 1, 10)) {
817
933
  this.options.gifEffort = options.effort;
818
934
  } else {
819
935
  throw is.invalidParameterError('effort', 'integer between 1 and 10', options.effort);
@@ -887,7 +1003,7 @@ function gif (options) {
887
1003
  */
888
1004
  function jp2 (options) {
889
1005
  /* node:coverage ignore next 41 */
890
- if (!this.constructor.format.jp2k.output.buffer) {
1006
+ if (!this.constructor.format.jp2.output.buffer) {
891
1007
  throw errJp2Save();
892
1008
  }
893
1009
  if (is.object(options)) {
@@ -987,12 +1103,12 @@ function trySetAnimationOptions (source, target) {
987
1103
  * @param {string} [options.predictor='horizontal'] - compression predictor options: none, horizontal, float
988
1104
  * @param {boolean} [options.pyramid=false] - write an image pyramid
989
1105
  * @param {boolean} [options.tile=false] - write a tiled tiff
990
- * @param {number} [options.tileWidth=256] - horizontal tile size
991
- * @param {number} [options.tileHeight=256] - vertical tile size
992
- * @param {number} [options.xres=1.0] - horizontal resolution in pixels/mm
993
- * @param {number} [options.yres=1.0] - vertical resolution in pixels/mm
1106
+ * @param {number} [options.tileWidth=256] - horizontal tile size, valid values are integers in the range 1-32768
1107
+ * @param {number} [options.tileHeight=256] - vertical tile size, valid values are integers in the range 1-32768
1108
+ * @param {number} [options.xres=1.0] - horizontal resolution in pixels/mm, valid values are numbers in the range 0.001-1000000
1109
+ * @param {number} [options.yres=1.0] - vertical resolution in pixels/mm, valid values are numbers in the range 0.001-1000000
994
1110
  * @param {string} [options.resolutionUnit='inch'] - resolution unit options: inch, cm
995
- * @param {number} [options.bitdepth=8] - reduce bitdepth to 1, 2 or 4 bit
1111
+ * @param {number} [options.bitdepth=0] - reduce bitdepth to 1, 2 or 4 bit
996
1112
  * @param {boolean} [options.miniswhite=false] - write 1-bit images as miniswhite
997
1113
  * @returns {Sharp}
998
1114
  * @throws {Error} Invalid options
@@ -1007,10 +1123,10 @@ function tiff (options) {
1007
1123
  }
1008
1124
  }
1009
1125
  if (is.defined(options.bitdepth)) {
1010
- if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [1, 2, 4, 8])) {
1126
+ if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [1, 2, 4])) {
1011
1127
  this.options.tiffBitdepth = options.bitdepth;
1012
1128
  } else {
1013
- throw is.invalidParameterError('bitdepth', '1, 2, 4 or 8', options.bitdepth);
1129
+ throw is.invalidParameterError('bitdepth', '1, 2 or 4', options.bitdepth);
1014
1130
  }
1015
1131
  }
1016
1132
  // tiling
@@ -1018,17 +1134,17 @@ function tiff (options) {
1018
1134
  this._setBooleanOption('tiffTile', options.tile);
1019
1135
  }
1020
1136
  if (is.defined(options.tileWidth)) {
1021
- if (is.integer(options.tileWidth) && options.tileWidth > 0) {
1137
+ if (is.integer(options.tileWidth) && is.inRange(options.tileWidth, 1, 32768)) {
1022
1138
  this.options.tiffTileWidth = options.tileWidth;
1023
1139
  } else {
1024
- throw is.invalidParameterError('tileWidth', 'integer greater than zero', options.tileWidth);
1140
+ throw is.invalidParameterError('tileWidth', 'integer between 1 and 32768', options.tileWidth);
1025
1141
  }
1026
1142
  }
1027
1143
  if (is.defined(options.tileHeight)) {
1028
- if (is.integer(options.tileHeight) && options.tileHeight > 0) {
1144
+ if (is.integer(options.tileHeight) && is.inRange(options.tileHeight, 1, 32768)) {
1029
1145
  this.options.tiffTileHeight = options.tileHeight;
1030
1146
  } else {
1031
- throw is.invalidParameterError('tileHeight', 'integer greater than zero', options.tileHeight);
1147
+ throw is.invalidParameterError('tileHeight', 'integer between 1 and 32768', options.tileHeight);
1032
1148
  }
1033
1149
  }
1034
1150
  // miniswhite
@@ -1041,17 +1157,17 @@ function tiff (options) {
1041
1157
  }
1042
1158
  // resolution
1043
1159
  if (is.defined(options.xres)) {
1044
- if (is.number(options.xres) && options.xres > 0) {
1160
+ if (is.number(options.xres) && is.inRange(options.xres, 0.001, 1000000)) {
1045
1161
  this.options.tiffXres = options.xres;
1046
1162
  } else {
1047
- throw is.invalidParameterError('xres', 'number greater than zero', options.xres);
1163
+ throw is.invalidParameterError('xres', 'number between 0.001 and 1000000', options.xres);
1048
1164
  }
1049
1165
  }
1050
1166
  if (is.defined(options.yres)) {
1051
- if (is.number(options.yres) && options.yres > 0) {
1167
+ if (is.number(options.yres) && is.inRange(options.yres, 0.001, 1000000)) {
1052
1168
  this.options.tiffYres = options.yres;
1053
1169
  } else {
1054
- throw is.invalidParameterError('yres', 'number greater than zero', options.yres);
1170
+ throw is.invalidParameterError('yres', 'number between 0.001 and 1000000', options.yres);
1055
1171
  }
1056
1172
  }
1057
1173
  // compression
@@ -1090,10 +1206,6 @@ function tiff (options) {
1090
1206
  * Use these AVIF options for output image.
1091
1207
  *
1092
1208
  * AVIF image sequences are not supported.
1093
- * Prebuilt binaries support a bitdepth of 8 only.
1094
- *
1095
- * This feature is experimental on the Windows ARM64 platform
1096
- * and requires a CPU with ARM64v8.4 or later.
1097
1209
  *
1098
1210
  * @example
1099
1211
  * const data = await sharp(input)
@@ -1113,6 +1225,7 @@ function tiff (options) {
1113
1225
  * @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
1114
1226
  * @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
1115
1227
  * @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit
1228
+ * @param {string} [options.tune='auto'] - tune output for a quality metric, one of 'auto' (default), 'iq', 'psnr' or 'ssim'
1116
1229
  * @returns {Sharp}
1117
1230
  * @throws {Error} Invalid options
1118
1231
  */
@@ -1140,6 +1253,7 @@ function avif (options) {
1140
1253
  * @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
1141
1254
  * @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
1142
1255
  * @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit
1256
+ * @param {string} [options.tune='auto'] - tune output for a quality metric, one of 'auto' (default), 'iq', 'psnr' or 'ssim'
1143
1257
  * @returns {Sharp}
1144
1258
  * @throws {Error} Invalid options
1145
1259
  */
@@ -1180,14 +1294,29 @@ function heif (options) {
1180
1294
  }
1181
1295
  if (is.defined(options.bitdepth)) {
1182
1296
  if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [8, 10, 12])) {
1183
- if (options.bitdepth !== 8 && this.constructor.versions.heif) {
1184
- throw is.invalidParameterError('bitdepth when using prebuilt binaries', 8, options.bitdepth);
1185
- }
1186
1297
  this.options.heifBitdepth = options.bitdepth;
1187
1298
  } else {
1188
1299
  throw is.invalidParameterError('bitdepth', '8, 10 or 12', options.bitdepth);
1189
1300
  }
1190
1301
  }
1302
+ if (is.defined(options.tune)) {
1303
+ if (is.string(options.tune) && is.inArray(options.tune, ['auto', 'iq', 'psnr', 'ssim'])) {
1304
+ if (this.options.heifLossless && options.tune === 'iq') {
1305
+ this.options.heifTune = 'ssim';
1306
+ } else {
1307
+ this.options.heifTune = options.tune;
1308
+ }
1309
+ } else {
1310
+ throw is.invalidParameterError('tune', 'one of: auto, iq, psnr, ssim', options.tune);
1311
+ }
1312
+ }
1313
+ if (is.defined(options.encoder)) {
1314
+ if (is.string(options.encoder) && is.inArray(options.encoder, ['auto', 'aom', 'rav1e', 'svt', 'x265'])) {
1315
+ this.options.heifEncoder = options.encoder;
1316
+ } else {
1317
+ throw is.invalidParameterError('encoder', 'one of: auto, aom, rav1e, svt, x265', options.encoder);
1318
+ }
1319
+ }
1191
1320
  } else {
1192
1321
  throw is.invalidParameterError('options', 'Object', options);
1193
1322
  }
@@ -1635,11 +1764,15 @@ module.exports = (Sharp) => {
1635
1764
  // Public
1636
1765
  toFile,
1637
1766
  toBuffer,
1767
+ toUint8Array,
1768
+ withDensity,
1638
1769
  keepExif,
1639
1770
  withExif,
1640
1771
  withExifMerge,
1641
1772
  keepIccProfile,
1642
1773
  withIccProfile,
1774
+ keepGainMap,
1775
+ withGainMap,
1643
1776
  keepXmp,
1644
1777
  withXmp,
1645
1778
  keepMetadata,