@revizly/sharp 0.35.0-revizly54 → 0.35.0-revizly56
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/dist/constructor.cjs +1 -1
- package/dist/constructor.mjs +1 -1
- package/dist/index.d.cts +8 -6
- package/dist/index.d.mts +8 -6
- package/dist/input.cjs +3 -0
- package/dist/input.mjs +3 -0
- package/dist/is.cjs +1 -1
- package/dist/is.mjs +1 -1
- package/dist/operation.cjs +1 -1
- package/dist/operation.mjs +1 -1
- package/dist/output.cjs +26 -13
- package/dist/output.mjs +26 -13
- package/dist/resize.cjs +1 -1
- package/dist/resize.mjs +1 -1
- package/lib/index.d.ts +8 -6
- package/package.json +11 -9
- package/src/common.cc +1 -1
- package/src/operations.cc +1 -1
- package/src/operations.h +1 -1
- package/src/pipeline.cc +37 -19
- package/src/stats.cc +1 -1
package/dist/constructor.cjs
CHANGED
|
@@ -202,7 +202,7 @@ const queueListener = (queueLength) => {
|
|
|
202
202
|
* @param {string} [options.text.wrap='word'] - word wrapping style when width is provided, one of: 'word', 'char', 'word-char' (prefer word, fallback to char) or 'none'.
|
|
203
203
|
* @param {Object} [options.join] - describes how an array of input images should be joined.
|
|
204
204
|
* @param {number} [options.join.across=1] - number of images to join horizontally.
|
|
205
|
-
* @param {boolean} [options.join.animated=false] - set this to `true` to join the images as an animated image
|
|
205
|
+
* @param {boolean} [options.join.animated=false] - set this to `true` to join the images as an animated image, cannot be used with `across` or `shim`.
|
|
206
206
|
* @param {number} [options.join.shim=0] - number of pixels to insert between joined images.
|
|
207
207
|
* @param {string|Object} [options.join.background] - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
|
|
208
208
|
* @param {string} [options.join.halign='left'] - horizontal alignment style for images joined horizontally (`'left'`, `'centre'`, `'center'`, `'right'`).
|
package/dist/constructor.mjs
CHANGED
|
@@ -202,7 +202,7 @@ const queueListener = (queueLength) => {
|
|
|
202
202
|
* @param {string} [options.text.wrap='word'] - word wrapping style when width is provided, one of: 'word', 'char', 'word-char' (prefer word, fallback to char) or 'none'.
|
|
203
203
|
* @param {Object} [options.join] - describes how an array of input images should be joined.
|
|
204
204
|
* @param {number} [options.join.across=1] - number of images to join horizontally.
|
|
205
|
-
* @param {boolean} [options.join.animated=false] - set this to `true` to join the images as an animated image
|
|
205
|
+
* @param {boolean} [options.join.animated=false] - set this to `true` to join the images as an animated image, cannot be used with `across` or `shim`.
|
|
206
206
|
* @param {number} [options.join.shim=0] - number of pixels to insert between joined images.
|
|
207
207
|
* @param {string|Object} [options.join.background] - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
|
|
208
208
|
* @param {string} [options.join.halign='left'] - horizontal alignment style for images joined horizontally (`'left'`, `'centre'`, `'center'`, `'right'`).
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* cspell:disable */
|
|
1
2
|
/**
|
|
2
3
|
* Copyright 2017 François Nguyen and others.
|
|
3
4
|
*
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
23
24
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
24
25
|
*/
|
|
26
|
+
/* cspell:enable */
|
|
25
27
|
|
|
26
28
|
// SPDX-License-Identifier: MIT
|
|
27
29
|
|
|
@@ -408,7 +410,7 @@ declare namespace sharp {
|
|
|
408
410
|
|
|
409
411
|
/**
|
|
410
412
|
* Alias for calling `rotate()` with no arguments, which orients the image based
|
|
411
|
-
* on EXIF
|
|
413
|
+
* on EXIF orientation.
|
|
412
414
|
*
|
|
413
415
|
* This operation is aliased to emphasize its purpose, helping to remove any
|
|
414
416
|
* confusion between rotation and orientation.
|
|
@@ -580,7 +582,7 @@ declare namespace sharp {
|
|
|
580
582
|
convolve(kernel: Kernel): Sharp;
|
|
581
583
|
|
|
582
584
|
/**
|
|
583
|
-
* Any pixel value
|
|
585
|
+
* Any pixel value greater than or equal to the threshold value will be set to 255, otherwise it will be set to 0.
|
|
584
586
|
* @param threshold a value in the range 0-255 representing the level at which the threshold will be applied. (optional, default 128)
|
|
585
587
|
* @param options threshold options
|
|
586
588
|
* @throws {Error} Invalid parameters
|
|
@@ -1462,8 +1464,8 @@ declare namespace sharp {
|
|
|
1462
1464
|
interface HeifOptions extends OutputOptions {
|
|
1463
1465
|
/** quality, integer 1-100 (optional, default 50) */
|
|
1464
1466
|
quality?: number | undefined;
|
|
1465
|
-
/** compression format: av1, hevc
|
|
1466
|
-
compression
|
|
1467
|
+
/** compression format: av1, hevc */
|
|
1468
|
+
compression: HeifCompression;
|
|
1467
1469
|
/** use lossless compression (optional, default false) */
|
|
1468
1470
|
lossless?: boolean | undefined;
|
|
1469
1471
|
/** Level of CPU effort to reduce file size, between 0 (fastest) and 9 (slowest) (optional, default 4) */
|
|
@@ -1472,7 +1474,7 @@ declare namespace sharp {
|
|
|
1472
1474
|
chromaSubsampling?: string | undefined;
|
|
1473
1475
|
/** Set bitdepth to 8, 10 or 12 bit (optional, default 8) */
|
|
1474
1476
|
bitdepth?: 8 | 10 | 12 | undefined;
|
|
1475
|
-
/** Tune output for a quality metric, one of 'auto', 'iq', 'psnr' or 'ssim' (
|
|
1477
|
+
/** Tune output for a quality metric, one of 'auto' (av1 default), 'iq' (av1 only), 'psnr' or 'ssim' (hevc default) */
|
|
1476
1478
|
tune?: HeifTune | undefined;
|
|
1477
1479
|
/** Which encoder libheif uses (must be compiled in) (optional, default 'auto') */
|
|
1478
1480
|
encoder?: 'auto' | 'aom' | 'rav1e' | 'svt' | 'x265' | undefined;
|
|
@@ -1703,7 +1705,7 @@ declare namespace sharp {
|
|
|
1703
1705
|
left?: number | undefined;
|
|
1704
1706
|
/** set to true to repeat the overlay image across the entire image with the given gravity. (optional, default false) */
|
|
1705
1707
|
tile?: boolean | undefined;
|
|
1706
|
-
/** Set to true to avoid
|
|
1708
|
+
/** Set to true to avoid premultiplying the image below. Equivalent to the --premultiplied vips option. */
|
|
1707
1709
|
premultiplied?: boolean | undefined;
|
|
1708
1710
|
/** number representing the DPI for vector overlay image. (optional, default 72)*/
|
|
1709
1711
|
density?: number | undefined;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* cspell:disable */
|
|
1
2
|
/**
|
|
2
3
|
* Copyright 2017 François Nguyen and others.
|
|
3
4
|
*
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
23
24
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
24
25
|
*/
|
|
26
|
+
/* cspell:enable */
|
|
25
27
|
|
|
26
28
|
// SPDX-License-Identifier: MIT
|
|
27
29
|
|
|
@@ -402,7 +404,7 @@ export interface Sharp extends Duplex {
|
|
|
402
404
|
|
|
403
405
|
/**
|
|
404
406
|
* Alias for calling `rotate()` with no arguments, which orients the image based
|
|
405
|
-
* on EXIF
|
|
407
|
+
* on EXIF orientation.
|
|
406
408
|
*
|
|
407
409
|
* This operation is aliased to emphasize its purpose, helping to remove any
|
|
408
410
|
* confusion between rotation and orientation.
|
|
@@ -574,7 +576,7 @@ export interface Sharp extends Duplex {
|
|
|
574
576
|
convolve(kernel: Kernel): Sharp;
|
|
575
577
|
|
|
576
578
|
/**
|
|
577
|
-
* Any pixel value
|
|
579
|
+
* Any pixel value greater than or equal to the threshold value will be set to 255, otherwise it will be set to 0.
|
|
578
580
|
* @param threshold a value in the range 0-255 representing the level at which the threshold will be applied. (optional, default 128)
|
|
579
581
|
* @param options threshold options
|
|
580
582
|
* @throws {Error} Invalid parameters
|
|
@@ -1456,8 +1458,8 @@ export interface AvifOptions extends OutputOptions {
|
|
|
1456
1458
|
export interface HeifOptions extends OutputOptions {
|
|
1457
1459
|
/** quality, integer 1-100 (optional, default 50) */
|
|
1458
1460
|
quality?: number | undefined;
|
|
1459
|
-
/** compression format: av1, hevc
|
|
1460
|
-
compression
|
|
1461
|
+
/** compression format: av1, hevc */
|
|
1462
|
+
compression: HeifCompression;
|
|
1461
1463
|
/** use lossless compression (optional, default false) */
|
|
1462
1464
|
lossless?: boolean | undefined;
|
|
1463
1465
|
/** Level of CPU effort to reduce file size, between 0 (fastest) and 9 (slowest) (optional, default 4) */
|
|
@@ -1466,7 +1468,7 @@ export interface HeifOptions extends OutputOptions {
|
|
|
1466
1468
|
chromaSubsampling?: string | undefined;
|
|
1467
1469
|
/** Set bitdepth to 8, 10 or 12 bit (optional, default 8) */
|
|
1468
1470
|
bitdepth?: 8 | 10 | 12 | undefined;
|
|
1469
|
-
/** Tune output for a quality metric, one of 'auto', 'iq', 'psnr' or 'ssim' (
|
|
1471
|
+
/** Tune output for a quality metric, one of 'auto' (av1 default), 'iq' (av1 only), 'psnr' or 'ssim' (hevc default) */
|
|
1470
1472
|
tune?: HeifTune | undefined;
|
|
1471
1473
|
/** Which encoder libheif uses (must be compiled in) (optional, default 'auto') */
|
|
1472
1474
|
encoder?: 'auto' | 'aom' | 'rav1e' | 'svt' | 'x265' | undefined;
|
|
@@ -1697,7 +1699,7 @@ export interface OverlayOptions extends SharpOptions {
|
|
|
1697
1699
|
left?: number | undefined;
|
|
1698
1700
|
/** set to true to repeat the overlay image across the entire image with the given gravity. (optional, default false) */
|
|
1699
1701
|
tile?: boolean | undefined;
|
|
1700
|
-
/** Set to true to avoid
|
|
1702
|
+
/** Set to true to avoid premultiplying the image below. Equivalent to the --premultiplied vips option. */
|
|
1701
1703
|
premultiplied?: boolean | undefined;
|
|
1702
1704
|
/** number representing the DPI for vector overlay image. (optional, default 72)*/
|
|
1703
1705
|
density?: number | undefined;
|
package/dist/input.cjs
CHANGED
|
@@ -511,6 +511,9 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
511
511
|
throw is.invalidParameterError('join.valign', 'valid alignment', inputOptions.join.valign);
|
|
512
512
|
}
|
|
513
513
|
}
|
|
514
|
+
if (inputDescriptor.joinAnimated && (inputDescriptor.joinAcross > 1 || inputDescriptor.joinShim > 0)) {
|
|
515
|
+
throw new Error('Expected neither join.across nor join.shim when join.animated is set');
|
|
516
|
+
}
|
|
514
517
|
} else {
|
|
515
518
|
throw new Error('Expected input to be an array of images to join');
|
|
516
519
|
}
|
package/dist/input.mjs
CHANGED
|
@@ -511,6 +511,9 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|
|
511
511
|
throw is.invalidParameterError('join.valign', 'valid alignment', inputOptions.join.valign);
|
|
512
512
|
}
|
|
513
513
|
}
|
|
514
|
+
if (inputDescriptor.joinAnimated && (inputDescriptor.joinAcross > 1 || inputDescriptor.joinShim > 0)) {
|
|
515
|
+
throw new Error('Expected neither join.across nor join.shim when join.animated is set');
|
|
516
|
+
}
|
|
514
517
|
} else {
|
|
515
518
|
throw new Error('Expected input to be an array of images to join');
|
|
516
519
|
}
|
package/dist/is.cjs
CHANGED
|
@@ -13,7 +13,7 @@ const defined = (val) => typeof val !== 'undefined' && val !== null;
|
|
|
13
13
|
* Is this value an object?
|
|
14
14
|
* @private
|
|
15
15
|
*/
|
|
16
|
-
const object = (val) => typeof val === 'object';
|
|
16
|
+
const object = (val) => typeof val === 'object' && val !== null;
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Is this value a plain object?
|
package/dist/is.mjs
CHANGED
|
@@ -13,7 +13,7 @@ const defined = (val) => typeof val !== 'undefined' && val !== null;
|
|
|
13
13
|
* Is this value an object?
|
|
14
14
|
* @private
|
|
15
15
|
*/
|
|
16
|
-
const object = (val) => typeof val === 'object';
|
|
16
|
+
const object = (val) => typeof val === 'object' && val !== null;
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Is this value a plain object?
|
package/dist/operation.cjs
CHANGED
|
@@ -62,7 +62,7 @@ function rotate (angle, options) {
|
|
|
62
62
|
this.options.rotationAngle = 0;
|
|
63
63
|
}
|
|
64
64
|
if (is.integer(angle) && !(angle % 90)) {
|
|
65
|
-
this.options.angle = angle;
|
|
65
|
+
this.options.angle = angle % 360;
|
|
66
66
|
} else if (is.number(angle)) {
|
|
67
67
|
this.options.rotationAngle = angle;
|
|
68
68
|
if (is.object(options) && options.background) {
|
package/dist/operation.mjs
CHANGED
|
@@ -62,7 +62,7 @@ function rotate (angle, options) {
|
|
|
62
62
|
this.options.rotationAngle = 0;
|
|
63
63
|
}
|
|
64
64
|
if (is.integer(angle) && !(angle % 90)) {
|
|
65
|
-
this.options.angle = angle;
|
|
65
|
+
this.options.angle = angle % 360;
|
|
66
66
|
} else if (is.number(angle)) {
|
|
67
67
|
this.options.rotationAngle = angle;
|
|
68
68
|
if (is.object(options) && options.background) {
|
package/dist/output.cjs
CHANGED
|
@@ -205,15 +205,15 @@ function toUint8Array () {
|
|
|
205
205
|
* .withDensity(96)
|
|
206
206
|
* .toBuffer();
|
|
207
207
|
*
|
|
208
|
-
* @param {number} density Number of pixels per inch (DPI).
|
|
208
|
+
* @param {number} density Number of pixels per inch (DPI), between 1 and 100000.
|
|
209
209
|
* @returns {Sharp}
|
|
210
210
|
* @throws {Error} Invalid parameters
|
|
211
211
|
*/
|
|
212
212
|
function withDensity (density) {
|
|
213
|
-
if (is.number(density) && density
|
|
213
|
+
if (is.number(density) && is.inRange(density, 1, 100000)) {
|
|
214
214
|
this.options.withMetadataDensity = density;
|
|
215
215
|
} else {
|
|
216
|
-
throw is.invalidParameterError('density', '
|
|
216
|
+
throw is.invalidParameterError('density', 'number between 1 and 100000', density);
|
|
217
217
|
}
|
|
218
218
|
return this.keepExif();
|
|
219
219
|
}
|
|
@@ -520,7 +520,7 @@ function keepMetadata () {
|
|
|
520
520
|
*
|
|
521
521
|
* @param {Object} [options]
|
|
522
522
|
* @param {number} [options.orientation] Used to update the EXIF `Orientation` tag, integer between 1 and 8.
|
|
523
|
-
* @param {number} [options.density] Number of pixels per inch (DPI).
|
|
523
|
+
* @param {number} [options.density] Number of pixels per inch (DPI), between 1 and 100000.
|
|
524
524
|
* @returns {Sharp}
|
|
525
525
|
* @throws {Error} Invalid parameters
|
|
526
526
|
*/
|
|
@@ -536,10 +536,10 @@ function withMetadata (options) {
|
|
|
536
536
|
}
|
|
537
537
|
}
|
|
538
538
|
if (is.defined(options.density)) {
|
|
539
|
-
if (is.number(options.density) && options.density
|
|
539
|
+
if (is.number(options.density) && is.inRange(options.density, 1, 100000)) {
|
|
540
540
|
this.options.withMetadataDensity = options.density;
|
|
541
541
|
} else {
|
|
542
|
-
throw is.invalidParameterError('density', '
|
|
542
|
+
throw is.invalidParameterError('density', 'number between 1 and 100000', options.density);
|
|
543
543
|
}
|
|
544
544
|
}
|
|
545
545
|
if (is.defined(options.icc)) {
|
|
@@ -1250,7 +1250,7 @@ function avif (options) {
|
|
|
1250
1250
|
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
|
|
1251
1251
|
* @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
|
|
1252
1252
|
* @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit
|
|
1253
|
-
* @param {string} [options.tune='auto'] - tune output for a quality metric, one of 'auto' (default), 'iq', 'psnr' or 'ssim'
|
|
1253
|
+
* @param {string} [options.tune='auto'] - tune output for a quality metric, one of 'auto' (av1 default), 'iq' (av1 only), 'psnr' or 'ssim' (hevc default)
|
|
1254
1254
|
* @returns {Sharp}
|
|
1255
1255
|
* @throws {Error} Invalid options
|
|
1256
1256
|
*/
|
|
@@ -1258,6 +1258,9 @@ function heif (options) {
|
|
|
1258
1258
|
if (is.object(options)) {
|
|
1259
1259
|
if (is.string(options.compression) && is.inArray(options.compression, ['av1', 'hevc'])) {
|
|
1260
1260
|
this.options.heifCompression = options.compression;
|
|
1261
|
+
if (options.compression === 'hevc' && this.options.heifTune === 'auto') {
|
|
1262
|
+
this.options.heifTune = 'ssim';
|
|
1263
|
+
}
|
|
1261
1264
|
} else {
|
|
1262
1265
|
throw is.invalidParameterError('compression', 'one of: av1, hevc', options.compression);
|
|
1263
1266
|
}
|
|
@@ -1297,14 +1300,24 @@ function heif (options) {
|
|
|
1297
1300
|
}
|
|
1298
1301
|
}
|
|
1299
1302
|
if (is.defined(options.tune)) {
|
|
1300
|
-
if (is.string(options.tune)
|
|
1301
|
-
if (this.options.
|
|
1302
|
-
|
|
1303
|
-
|
|
1303
|
+
if (is.string(options.tune)) {
|
|
1304
|
+
if (this.options.heifCompression === 'av1') {
|
|
1305
|
+
if (is.inArray(options.tune, ['auto', 'iq', 'psnr', 'ssim'])) {
|
|
1306
|
+
if (this.options.heifLossless && options.tune === 'iq') {
|
|
1307
|
+
this.options.heifTune = 'ssim';
|
|
1308
|
+
} else {
|
|
1309
|
+
this.options.heifTune = options.tune;
|
|
1310
|
+
}
|
|
1311
|
+
} else {
|
|
1312
|
+
throw is.invalidParameterError('tune', 'one of: auto, iq, psnr, ssim', options.tune);
|
|
1313
|
+
}
|
|
1314
|
+
} else if (is.inArray(options.tune, ['psnr', 'ssim'])) {
|
|
1304
1315
|
this.options.heifTune = options.tune;
|
|
1316
|
+
} else {
|
|
1317
|
+
throw is.invalidParameterError('tune', 'one of: psnr, ssim', options.tune);
|
|
1305
1318
|
}
|
|
1306
1319
|
} else {
|
|
1307
|
-
throw is.invalidParameterError('tune', '
|
|
1320
|
+
throw is.invalidParameterError('tune', 'string', options.tune);
|
|
1308
1321
|
}
|
|
1309
1322
|
}
|
|
1310
1323
|
if (is.defined(options.encoder)) {
|
|
@@ -1511,7 +1524,7 @@ function tile (options) {
|
|
|
1511
1524
|
// Angle of rotation,
|
|
1512
1525
|
if (is.defined(options.angle)) {
|
|
1513
1526
|
if (is.integer(options.angle) && !(options.angle % 90)) {
|
|
1514
|
-
this.options.tileAngle = options.angle;
|
|
1527
|
+
this.options.tileAngle = options.angle % 360;
|
|
1515
1528
|
} else {
|
|
1516
1529
|
throw is.invalidParameterError('angle', 'positive/negative multiple of 90', options.angle);
|
|
1517
1530
|
}
|
package/dist/output.mjs
CHANGED
|
@@ -205,15 +205,15 @@ function toUint8Array () {
|
|
|
205
205
|
* .withDensity(96)
|
|
206
206
|
* .toBuffer();
|
|
207
207
|
*
|
|
208
|
-
* @param {number} density Number of pixels per inch (DPI).
|
|
208
|
+
* @param {number} density Number of pixels per inch (DPI), between 1 and 100000.
|
|
209
209
|
* @returns {Sharp}
|
|
210
210
|
* @throws {Error} Invalid parameters
|
|
211
211
|
*/
|
|
212
212
|
function withDensity (density) {
|
|
213
|
-
if (is.number(density) && density
|
|
213
|
+
if (is.number(density) && is.inRange(density, 1, 100000)) {
|
|
214
214
|
this.options.withMetadataDensity = density;
|
|
215
215
|
} else {
|
|
216
|
-
throw is.invalidParameterError('density', '
|
|
216
|
+
throw is.invalidParameterError('density', 'number between 1 and 100000', density);
|
|
217
217
|
}
|
|
218
218
|
return this.keepExif();
|
|
219
219
|
}
|
|
@@ -520,7 +520,7 @@ function keepMetadata () {
|
|
|
520
520
|
*
|
|
521
521
|
* @param {Object} [options]
|
|
522
522
|
* @param {number} [options.orientation] Used to update the EXIF `Orientation` tag, integer between 1 and 8.
|
|
523
|
-
* @param {number} [options.density] Number of pixels per inch (DPI).
|
|
523
|
+
* @param {number} [options.density] Number of pixels per inch (DPI), between 1 and 100000.
|
|
524
524
|
* @returns {Sharp}
|
|
525
525
|
* @throws {Error} Invalid parameters
|
|
526
526
|
*/
|
|
@@ -536,10 +536,10 @@ function withMetadata (options) {
|
|
|
536
536
|
}
|
|
537
537
|
}
|
|
538
538
|
if (is.defined(options.density)) {
|
|
539
|
-
if (is.number(options.density) && options.density
|
|
539
|
+
if (is.number(options.density) && is.inRange(options.density, 1, 100000)) {
|
|
540
540
|
this.options.withMetadataDensity = options.density;
|
|
541
541
|
} else {
|
|
542
|
-
throw is.invalidParameterError('density', '
|
|
542
|
+
throw is.invalidParameterError('density', 'number between 1 and 100000', options.density);
|
|
543
543
|
}
|
|
544
544
|
}
|
|
545
545
|
if (is.defined(options.icc)) {
|
|
@@ -1250,7 +1250,7 @@ function avif (options) {
|
|
|
1250
1250
|
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
|
|
1251
1251
|
* @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
|
|
1252
1252
|
* @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit
|
|
1253
|
-
* @param {string} [options.tune='auto'] - tune output for a quality metric, one of 'auto' (default), 'iq', 'psnr' or 'ssim'
|
|
1253
|
+
* @param {string} [options.tune='auto'] - tune output for a quality metric, one of 'auto' (av1 default), 'iq' (av1 only), 'psnr' or 'ssim' (hevc default)
|
|
1254
1254
|
* @returns {Sharp}
|
|
1255
1255
|
* @throws {Error} Invalid options
|
|
1256
1256
|
*/
|
|
@@ -1258,6 +1258,9 @@ function heif (options) {
|
|
|
1258
1258
|
if (is.object(options)) {
|
|
1259
1259
|
if (is.string(options.compression) && is.inArray(options.compression, ['av1', 'hevc'])) {
|
|
1260
1260
|
this.options.heifCompression = options.compression;
|
|
1261
|
+
if (options.compression === 'hevc' && this.options.heifTune === 'auto') {
|
|
1262
|
+
this.options.heifTune = 'ssim';
|
|
1263
|
+
}
|
|
1261
1264
|
} else {
|
|
1262
1265
|
throw is.invalidParameterError('compression', 'one of: av1, hevc', options.compression);
|
|
1263
1266
|
}
|
|
@@ -1297,14 +1300,24 @@ function heif (options) {
|
|
|
1297
1300
|
}
|
|
1298
1301
|
}
|
|
1299
1302
|
if (is.defined(options.tune)) {
|
|
1300
|
-
if (is.string(options.tune)
|
|
1301
|
-
if (this.options.
|
|
1302
|
-
|
|
1303
|
-
|
|
1303
|
+
if (is.string(options.tune)) {
|
|
1304
|
+
if (this.options.heifCompression === 'av1') {
|
|
1305
|
+
if (is.inArray(options.tune, ['auto', 'iq', 'psnr', 'ssim'])) {
|
|
1306
|
+
if (this.options.heifLossless && options.tune === 'iq') {
|
|
1307
|
+
this.options.heifTune = 'ssim';
|
|
1308
|
+
} else {
|
|
1309
|
+
this.options.heifTune = options.tune;
|
|
1310
|
+
}
|
|
1311
|
+
} else {
|
|
1312
|
+
throw is.invalidParameterError('tune', 'one of: auto, iq, psnr, ssim', options.tune);
|
|
1313
|
+
}
|
|
1314
|
+
} else if (is.inArray(options.tune, ['psnr', 'ssim'])) {
|
|
1304
1315
|
this.options.heifTune = options.tune;
|
|
1316
|
+
} else {
|
|
1317
|
+
throw is.invalidParameterError('tune', 'one of: psnr, ssim', options.tune);
|
|
1305
1318
|
}
|
|
1306
1319
|
} else {
|
|
1307
|
-
throw is.invalidParameterError('tune', '
|
|
1320
|
+
throw is.invalidParameterError('tune', 'string', options.tune);
|
|
1308
1321
|
}
|
|
1309
1322
|
}
|
|
1310
1323
|
if (is.defined(options.encoder)) {
|
|
@@ -1511,7 +1524,7 @@ function tile (options) {
|
|
|
1511
1524
|
// Angle of rotation,
|
|
1512
1525
|
if (is.defined(options.angle)) {
|
|
1513
1526
|
if (is.integer(options.angle) && !(options.angle % 90)) {
|
|
1514
|
-
this.options.tileAngle = options.angle;
|
|
1527
|
+
this.options.tileAngle = options.angle % 360;
|
|
1515
1528
|
} else {
|
|
1516
1529
|
throw is.invalidParameterError('angle', 'positive/negative multiple of 90', options.angle);
|
|
1517
1530
|
}
|
package/dist/resize.cjs
CHANGED
package/dist/resize.mjs
CHANGED
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* cspell:disable */
|
|
1
2
|
/**
|
|
2
3
|
* Copyright 2017 François Nguyen and others.
|
|
3
4
|
*
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
23
24
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
24
25
|
*/
|
|
26
|
+
/* cspell:enable */
|
|
25
27
|
|
|
26
28
|
// SPDX-License-Identifier: MIT
|
|
27
29
|
|
|
@@ -408,7 +410,7 @@ declare namespace sharp {
|
|
|
408
410
|
|
|
409
411
|
/**
|
|
410
412
|
* Alias for calling `rotate()` with no arguments, which orients the image based
|
|
411
|
-
* on EXIF
|
|
413
|
+
* on EXIF orientation.
|
|
412
414
|
*
|
|
413
415
|
* This operation is aliased to emphasize its purpose, helping to remove any
|
|
414
416
|
* confusion between rotation and orientation.
|
|
@@ -580,7 +582,7 @@ declare namespace sharp {
|
|
|
580
582
|
convolve(kernel: Kernel): Sharp;
|
|
581
583
|
|
|
582
584
|
/**
|
|
583
|
-
* Any pixel value
|
|
585
|
+
* Any pixel value greater than or equal to the threshold value will be set to 255, otherwise it will be set to 0.
|
|
584
586
|
* @param threshold a value in the range 0-255 representing the level at which the threshold will be applied. (optional, default 128)
|
|
585
587
|
* @param options threshold options
|
|
586
588
|
* @throws {Error} Invalid parameters
|
|
@@ -1462,8 +1464,8 @@ declare namespace sharp {
|
|
|
1462
1464
|
interface HeifOptions extends OutputOptions {
|
|
1463
1465
|
/** quality, integer 1-100 (optional, default 50) */
|
|
1464
1466
|
quality?: number | undefined;
|
|
1465
|
-
/** compression format: av1, hevc
|
|
1466
|
-
compression
|
|
1467
|
+
/** compression format: av1, hevc */
|
|
1468
|
+
compression: HeifCompression;
|
|
1467
1469
|
/** use lossless compression (optional, default false) */
|
|
1468
1470
|
lossless?: boolean | undefined;
|
|
1469
1471
|
/** Level of CPU effort to reduce file size, between 0 (fastest) and 9 (slowest) (optional, default 4) */
|
|
@@ -1472,7 +1474,7 @@ declare namespace sharp {
|
|
|
1472
1474
|
chromaSubsampling?: string | undefined;
|
|
1473
1475
|
/** Set bitdepth to 8, 10 or 12 bit (optional, default 8) */
|
|
1474
1476
|
bitdepth?: 8 | 10 | 12 | undefined;
|
|
1475
|
-
/** Tune output for a quality metric, one of 'auto', 'iq', 'psnr' or 'ssim' (
|
|
1477
|
+
/** Tune output for a quality metric, one of 'auto' (av1 default), 'iq' (av1 only), 'psnr' or 'ssim' (hevc default) */
|
|
1476
1478
|
tune?: HeifTune | undefined;
|
|
1477
1479
|
/** Which encoder libheif uses (must be compiled in) (optional, default 'auto') */
|
|
1478
1480
|
encoder?: 'auto' | 'aom' | 'rav1e' | 'svt' | 'x265' | undefined;
|
|
@@ -1703,7 +1705,7 @@ declare namespace sharp {
|
|
|
1703
1705
|
left?: number | undefined;
|
|
1704
1706
|
/** set to true to repeat the overlay image across the entire image with the given gravity. (optional, default false) */
|
|
1705
1707
|
tile?: boolean | undefined;
|
|
1706
|
-
/** Set to true to avoid
|
|
1708
|
+
/** Set to true to avoid premultiplying the image below. Equivalent to the --premultiplied vips option. */
|
|
1707
1709
|
premultiplied?: boolean | undefined;
|
|
1708
1710
|
/** number representing the DPI for vector overlay image. (optional, default 72)*/
|
|
1709
1711
|
density?: number | undefined;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revizly/sharp",
|
|
3
3
|
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
|
|
4
|
-
"version": "0.35.0-
|
|
4
|
+
"version": "0.35.0-revizly56",
|
|
5
5
|
"author": "Lovell Fuller <npm@lovell.info>",
|
|
6
6
|
"homepage": "https://sharp.pixelplumbing.com",
|
|
7
7
|
"contributors": [
|
|
@@ -98,10 +98,11 @@
|
|
|
98
98
|
"build:dist": "node scripts/build.mjs",
|
|
99
99
|
"clean": "rm -rf src/build/ test/fixtures/output.*",
|
|
100
100
|
"test": "npm run lint && npm run test-unit",
|
|
101
|
-
"lint": "npm run lint-cpp && npm run lint-js && npm run lint-types && npm run lint-publish",
|
|
101
|
+
"lint": "npm run lint-cpp && npm run lint-js && npm run lint-types && npm run lint-spell && npm run lint-publish",
|
|
102
102
|
"lint-cpp": "cpplint --quiet src/*.h src/*.cc",
|
|
103
103
|
"lint-js": "biome lint",
|
|
104
104
|
"lint-publish": "publint --strict",
|
|
105
|
+
"lint-spell": "cspell --config ./test/spell/cspell.jsonc --no-progress .",
|
|
105
106
|
"lint-types": "tsd --files ./test/types/sharp.test-d.{cts,mts}",
|
|
106
107
|
"test-leak": "./test/leak/leak.sh",
|
|
107
108
|
"test-unit": "node --experimental-test-coverage test/unit.mjs",
|
|
@@ -163,10 +164,10 @@
|
|
|
163
164
|
"semver": "^7.8.5"
|
|
164
165
|
},
|
|
165
166
|
"optionalDependencies": {
|
|
166
|
-
"@revizly/sharp-libvips-linux-arm64": "1.0.
|
|
167
|
-
"@revizly/sharp-libvips-linux-x64": "1.0.
|
|
168
|
-
"@revizly/sharp-linux-arm64": "0.35.0-
|
|
169
|
-
"@revizly/sharp-linux-x64": "0.35.0-
|
|
167
|
+
"@revizly/sharp-libvips-linux-arm64": "1.0.56",
|
|
168
|
+
"@revizly/sharp-libvips-linux-x64": "1.0.56",
|
|
169
|
+
"@revizly/sharp-linux-arm64": "0.35.0-revizly56",
|
|
170
|
+
"@revizly/sharp-linux-x64": "0.35.0-revizly56"
|
|
170
171
|
},
|
|
171
172
|
"peerDependenciesMeta": {
|
|
172
173
|
"@types/node": {
|
|
@@ -174,17 +175,18 @@
|
|
|
174
175
|
}
|
|
175
176
|
},
|
|
176
177
|
"devDependencies": {
|
|
177
|
-
"@biomejs/biome": "^2.5.
|
|
178
|
+
"@biomejs/biome": "^2.5.15",
|
|
178
179
|
"@cpplint/cli": "^0.1.0",
|
|
179
180
|
"@emnapi/runtime": "^1.11.3",
|
|
180
|
-
"@revizly/sharp-libvips-dev": "1.0.
|
|
181
|
+
"@revizly/sharp-libvips-dev": "1.0.56",
|
|
181
182
|
"@types/node": "*",
|
|
183
|
+
"cspell": "^10.4.0",
|
|
182
184
|
"emnapi": "^1.11.3",
|
|
183
185
|
"exif-reader": "^2.0.3",
|
|
184
186
|
"icc": "^4.0.0",
|
|
185
187
|
"node-addon-api": "^8.9.2",
|
|
186
188
|
"node-gyp": "^12.4.0",
|
|
187
|
-
"publint": "^0.3.
|
|
189
|
+
"publint": "^0.3.25",
|
|
188
190
|
"tar-fs": "^3.1.3",
|
|
189
191
|
"tsd": "^0.33.0",
|
|
190
192
|
"yauzl": "^3.4.0"
|
package/src/common.cc
CHANGED
|
@@ -198,7 +198,7 @@ namespace sharp {
|
|
|
198
198
|
}
|
|
199
199
|
descriptor->limitInputPixels = static_cast<uint64_t>(AttrAsInt64(input, "limitInputPixels"));
|
|
200
200
|
descriptor->limitInputChannels = static_cast<uint64_t>(AttrAsInt64(input, "limitInputChannels"));
|
|
201
|
-
if (HasAttr(input, "
|
|
201
|
+
if (HasAttr(input, "sequentialRead")) {
|
|
202
202
|
descriptor->access = AttrAsBool(input, "sequentialRead") ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM;
|
|
203
203
|
}
|
|
204
204
|
// Remove safety features and allow unlimited input
|
package/src/operations.cc
CHANGED
|
@@ -97,7 +97,7 @@ namespace sharp {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/*
|
|
100
|
-
* Contrast limiting
|
|
100
|
+
* Contrast limiting adaptive histogram equalization (CLAHE)
|
|
101
101
|
*/
|
|
102
102
|
VImage Clahe(VImage image, int const width, int const height, int const maxSlope) {
|
|
103
103
|
return image.hist_local(width, height, VImage::option()->set("max_slope", maxSlope));
|
package/src/operations.h
CHANGED
|
@@ -28,7 +28,7 @@ namespace sharp {
|
|
|
28
28
|
VImage Normalise(VImage image, int const lower, int const upper);
|
|
29
29
|
|
|
30
30
|
/*
|
|
31
|
-
* Contrast limiting
|
|
31
|
+
* Contrast limiting adaptive histogram equalization (CLAHE)
|
|
32
32
|
*/
|
|
33
33
|
VImage Clahe(VImage image, int const width, int const height, int const maxSlope);
|
|
34
34
|
|
package/src/pipeline.cc
CHANGED
|
@@ -40,6 +40,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
40
40
|
// Increment processing task counter
|
|
41
41
|
sharp::counterProcess++;
|
|
42
42
|
|
|
43
|
+
std::pair<char*, size_t> inputProfile(nullptr, 0);
|
|
43
44
|
try {
|
|
44
45
|
// Open input
|
|
45
46
|
vips::VImage image;
|
|
@@ -269,7 +270,12 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
269
270
|
if (baton->input->buffer != nullptr) {
|
|
270
271
|
// Reload JPEG buffer
|
|
271
272
|
VipsBlob *blob = vips_blob_new(nullptr, baton->input->buffer, baton->input->bufferLength);
|
|
272
|
-
|
|
273
|
+
try {
|
|
274
|
+
image = VImage::jpegload_buffer(blob, option);
|
|
275
|
+
} catch (...) {
|
|
276
|
+
vips_area_unref(reinterpret_cast<VipsArea*>(blob));
|
|
277
|
+
throw;
|
|
278
|
+
}
|
|
273
279
|
vips_area_unref(reinterpret_cast<VipsArea*>(blob));
|
|
274
280
|
} else {
|
|
275
281
|
// Reload JPEG file
|
|
@@ -281,7 +287,12 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
281
287
|
if (baton->input->buffer != nullptr) {
|
|
282
288
|
// Reload WebP buffer
|
|
283
289
|
VipsBlob *blob = vips_blob_new(nullptr, baton->input->buffer, baton->input->bufferLength);
|
|
284
|
-
|
|
290
|
+
try {
|
|
291
|
+
image = VImage::webpload_buffer(blob, option);
|
|
292
|
+
} catch (...) {
|
|
293
|
+
vips_area_unref(reinterpret_cast<VipsArea*>(blob));
|
|
294
|
+
throw;
|
|
295
|
+
}
|
|
285
296
|
vips_area_unref(reinterpret_cast<VipsArea*>(blob));
|
|
286
297
|
} else {
|
|
287
298
|
// Reload WebP file
|
|
@@ -291,7 +302,12 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
291
302
|
if (baton->input->buffer != nullptr) {
|
|
292
303
|
// Reload SVG buffer
|
|
293
304
|
VipsBlob *blob = vips_blob_new(nullptr, baton->input->buffer, baton->input->bufferLength);
|
|
294
|
-
|
|
305
|
+
try {
|
|
306
|
+
image = VImage::svgload_buffer(blob, option);
|
|
307
|
+
} catch (...) {
|
|
308
|
+
vips_area_unref(reinterpret_cast<VipsArea*>(blob));
|
|
309
|
+
throw;
|
|
310
|
+
}
|
|
295
311
|
vips_area_unref(reinterpret_cast<VipsArea*>(blob));
|
|
296
312
|
} else {
|
|
297
313
|
// Reload SVG file
|
|
@@ -305,7 +321,12 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
305
321
|
if (baton->input->buffer != nullptr) {
|
|
306
322
|
// Reload PDF buffer
|
|
307
323
|
VipsBlob *blob = vips_blob_new(nullptr, baton->input->buffer, baton->input->bufferLength);
|
|
308
|
-
|
|
324
|
+
try {
|
|
325
|
+
image = VImage::pdfload_buffer(blob, option);
|
|
326
|
+
} catch (...) {
|
|
327
|
+
vips_area_unref(reinterpret_cast<VipsArea*>(blob));
|
|
328
|
+
throw;
|
|
329
|
+
}
|
|
309
330
|
vips_area_unref(reinterpret_cast<VipsArea*>(blob));
|
|
310
331
|
} else {
|
|
311
332
|
// Reload PDF file
|
|
@@ -325,7 +346,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
325
346
|
int gainMapScaleFactor = 1;
|
|
326
347
|
if (sharp::HasGainMap(image)) {
|
|
327
348
|
if (baton->keepGainMap) {
|
|
328
|
-
gainMap = image.gainmap();
|
|
349
|
+
gainMap = image.gainmap().copy_memory();
|
|
329
350
|
if (image.get_typeof("gainmap-scale-factor") == G_TYPE_INT) {
|
|
330
351
|
gainMapScaleFactor = image.get_int("gainmap-scale-factor");
|
|
331
352
|
}
|
|
@@ -378,7 +399,6 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
378
399
|
}
|
|
379
400
|
|
|
380
401
|
// Ensure we're using a device-independent colour space
|
|
381
|
-
std::pair<char*, size_t> inputProfile(nullptr, 0);
|
|
382
402
|
if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) && baton->withIccProfile.empty()) {
|
|
383
403
|
// Cache input profile for use with output
|
|
384
404
|
inputProfile = sharp::GetProfile(image);
|
|
@@ -481,14 +501,14 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
481
501
|
}
|
|
482
502
|
image = image.rot(autoRotation);
|
|
483
503
|
if (baton->keepGainMap) {
|
|
484
|
-
gainMap =
|
|
504
|
+
gainMap = gainMap.rot(autoRotation);
|
|
485
505
|
}
|
|
486
506
|
}
|
|
487
507
|
// Mirror vertically (up-down) about the x-axis
|
|
488
508
|
if (baton->flip) {
|
|
489
509
|
image = image.flip(VIPS_DIRECTION_VERTICAL);
|
|
490
510
|
if (baton->keepGainMap) {
|
|
491
|
-
gainMap =
|
|
511
|
+
gainMap = gainMap.flip(VIPS_DIRECTION_VERTICAL);
|
|
492
512
|
}
|
|
493
513
|
}
|
|
494
514
|
// Mirror horizontally (left-right) about the y-axis
|
|
@@ -505,7 +525,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
505
525
|
}
|
|
506
526
|
image = image.rot(rotation);
|
|
507
527
|
if (baton->keepGainMap) {
|
|
508
|
-
gainMap =
|
|
528
|
+
gainMap = gainMap.rot(rotation);
|
|
509
529
|
}
|
|
510
530
|
}
|
|
511
531
|
|
|
@@ -931,11 +951,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
931
951
|
image = image.colourspace(baton->colourspace, VImage::option()->set("source_space", image.interpretation()));
|
|
932
952
|
if (inputProfile.first != nullptr && baton->withIccProfile.empty()) {
|
|
933
953
|
image = sharp::SetProfile(image, inputProfile);
|
|
934
|
-
|
|
935
|
-
g_free(inputProfile.first);
|
|
954
|
+
inputProfile.first = nullptr;
|
|
936
955
|
}
|
|
937
|
-
} else {
|
|
938
|
-
g_free(inputProfile.first);
|
|
939
956
|
}
|
|
940
957
|
|
|
941
958
|
// Extract channel
|
|
@@ -945,10 +962,9 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
945
962
|
if (baton->extractChannel == 3 && image.has_alpha()) {
|
|
946
963
|
baton->extractChannel = image.bands() - 1;
|
|
947
964
|
} else {
|
|
948
|
-
(
|
|
949
|
-
|
|
950
|
-
.append(" from image with channels 0-").append(std::to_string(image.bands() - 1));
|
|
951
|
-
return Error();
|
|
965
|
+
throw std::runtime_error(
|
|
966
|
+
std::string("Cannot extract channel ").append(std::to_string(baton->extractChannel))
|
|
967
|
+
.append(" from image with channels 0-").append(std::to_string(image.bands() - 1)));
|
|
952
968
|
}
|
|
953
969
|
}
|
|
954
970
|
VipsInterpretation colourspace = sharp::Is16Bit(image.interpretation())
|
|
@@ -1444,6 +1460,8 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|
|
1444
1460
|
}
|
|
1445
1461
|
}
|
|
1446
1462
|
}
|
|
1463
|
+
g_free(inputProfile.first);
|
|
1464
|
+
|
|
1447
1465
|
// Clean up libvips' per-request data and threads
|
|
1448
1466
|
vips_error_clear();
|
|
1449
1467
|
vips_thread_shutdown();
|
|
@@ -1869,9 +1887,9 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
|
|
1869
1887
|
baton->convKernelOffset = sharp::AttrAsDouble(kernel, "offset");
|
|
1870
1888
|
size_t const kernelSize = static_cast<size_t>(baton->convKernelWidth * baton->convKernelHeight);
|
|
1871
1889
|
baton->convKernel.resize(kernelSize);
|
|
1872
|
-
Napi::Array
|
|
1890
|
+
Napi::Array kernelData = kernel.Get("kernel").As<Napi::Array>();
|
|
1873
1891
|
for (unsigned int i = 0; i < kernelSize; i++) {
|
|
1874
|
-
baton->convKernel[i] = sharp::AttrAsDouble(
|
|
1892
|
+
baton->convKernel[i] = sharp::AttrAsDouble(kernelData, i);
|
|
1875
1893
|
}
|
|
1876
1894
|
}
|
|
1877
1895
|
if (options.Has("recombMatrix")) {
|
package/src/stats.cc
CHANGED
|
@@ -60,7 +60,7 @@ class StatsWorker : public Napi::AsyncWorker {
|
|
|
60
60
|
static_cast<int>(stats.getpoint(STAT_MAXY_INDEX, b).front()));
|
|
61
61
|
baton->channelStats.push_back(cStats);
|
|
62
62
|
}
|
|
63
|
-
// Image is not opaque when alpha layer is present and contains a non-
|
|
63
|
+
// Image is not opaque when alpha layer is present and contains a non-maxima value
|
|
64
64
|
if (image.has_alpha()) {
|
|
65
65
|
double const minAlpha = static_cast<double>(stats.getpoint(STAT_MIN_INDEX, bands).front());
|
|
66
66
|
if (minAlpha != vips_interpretation_max_alpha(image.interpretation())) {
|