sharp 0.35.0-rc.0 → 0.35.0-rc.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/README.md +6 -16
- package/lib/constructor.js +3 -2
- package/lib/index.d.ts +25 -23
- package/lib/input.js +1 -0
- package/lib/libvips.js +27 -19
- package/lib/output.js +65 -6
- package/lib/sharp.js +60 -20
- package/package.json +41 -39
- package/src/binding.gyp +7 -3
- package/src/common.cc +39 -15
- package/src/common.h +9 -3
- package/src/metadata.cc +52 -4
- package/src/metadata.h +1 -0
- package/src/operations.cc +2 -3
- package/src/pipeline.cc +159 -51
- package/src/pipeline.h +3 -1
- package/src/stats.cc +6 -6
- package/src/utilities.cc +1 -1
package/README.md
CHANGED
|
@@ -41,28 +41,20 @@ npm install sharp
|
|
|
41
41
|
const sharp = require('sharp');
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
### Callback
|
|
45
|
-
|
|
46
44
|
```javascript
|
|
47
|
-
sharp(inputBuffer)
|
|
48
|
-
.resize(320, 240)
|
|
45
|
+
await sharp(inputBuffer)
|
|
46
|
+
.resize({ width: 320, height: 240 })
|
|
49
47
|
.toFile('output.webp', (err, info) => { ... });
|
|
50
48
|
```
|
|
51
49
|
|
|
52
|
-
### Promise
|
|
53
|
-
|
|
54
50
|
```javascript
|
|
55
|
-
sharp('input.jpg')
|
|
56
|
-
.
|
|
57
|
-
.resize(200)
|
|
51
|
+
const output = await sharp('input.jpg')
|
|
52
|
+
.autoOrient()
|
|
53
|
+
.resize({ width: 200 })
|
|
58
54
|
.jpeg({ mozjpeg: true })
|
|
59
|
-
.toBuffer()
|
|
60
|
-
.then( data => { ... })
|
|
61
|
-
.catch( err => { ... });
|
|
55
|
+
.toBuffer();
|
|
62
56
|
```
|
|
63
57
|
|
|
64
|
-
### Async/await
|
|
65
|
-
|
|
66
58
|
```javascript
|
|
67
59
|
const semiTransparentRedPng = await sharp({
|
|
68
60
|
create: {
|
|
@@ -76,8 +68,6 @@ const semiTransparentRedPng = await sharp({
|
|
|
76
68
|
.toBuffer();
|
|
77
69
|
```
|
|
78
70
|
|
|
79
|
-
### Stream
|
|
80
|
-
|
|
81
71
|
```javascript
|
|
82
72
|
const roundedCorners = Buffer.from(
|
|
83
73
|
'<svg><rect x="0" y="0" width="200" height="200" rx="50" ry="50"/></svg>'
|
package/lib/constructor.js
CHANGED
|
@@ -153,7 +153,7 @@ const queueListener = (queueLength) => {
|
|
|
153
153
|
* @param {boolean} [options.unlimited=false] - Set this to `true` to remove safety features that help prevent memory exhaustion (JPEG, PNG, SVG, HEIF).
|
|
154
154
|
* @param {boolean} [options.autoOrient=false] - Set this to `true` to rotate/flip the image to match EXIF `Orientation`, if any.
|
|
155
155
|
* @param {boolean} [options.sequentialRead=true] - Set this to `false` to use random access rather than sequential read. Some operations will do this automatically.
|
|
156
|
-
* @param {number} [options.density=72] -
|
|
156
|
+
* @param {number} [options.density=72] - The DPI at which to render SVG and PDF images, in the range 1 to 100000.
|
|
157
157
|
* @param {number} [options.ignoreIcc=false] - should the embedded ICC profile, if any, be ignored.
|
|
158
158
|
* @param {number} [options.pages=1] - Number of pages to extract for multi-page input (GIF, WebP, TIFF), use -1 for all pages.
|
|
159
159
|
* @param {number} [options.page=0] - Page number to start extracting from for multi-page input (GIF, WebP, TIFF), zero based.
|
|
@@ -315,6 +315,7 @@ const Sharp = function (input, options) {
|
|
|
315
315
|
withExif: {},
|
|
316
316
|
withExifMerge: true,
|
|
317
317
|
withXmp: '',
|
|
318
|
+
keepGainMap: false,
|
|
318
319
|
withGainMap: false,
|
|
319
320
|
resolveWithObject: false,
|
|
320
321
|
loop: -1,
|
|
@@ -366,7 +367,7 @@ const Sharp = function (input, options) {
|
|
|
366
367
|
tiffPredictor: 'horizontal',
|
|
367
368
|
tiffPyramid: false,
|
|
368
369
|
tiffMiniswhite: false,
|
|
369
|
-
tiffBitdepth:
|
|
370
|
+
tiffBitdepth: 0,
|
|
370
371
|
tiffTile: false,
|
|
371
372
|
tiffTileHeight: 256,
|
|
372
373
|
tiffTileWidth: 256,
|
package/lib/index.d.ts
CHANGED
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
/// <reference types="node" />
|
|
29
29
|
|
|
30
30
|
import type { Duplex } from 'node:stream';
|
|
31
|
+
import { ColorLike } from '@img/colour';
|
|
31
32
|
|
|
32
33
|
//#region Constructor functions
|
|
33
34
|
|
|
@@ -234,7 +235,7 @@ declare namespace sharp {
|
|
|
234
235
|
* @param tint Parsed by the color module.
|
|
235
236
|
* @returns A sharp instance that can be used to chain operations
|
|
236
237
|
*/
|
|
237
|
-
tint(tint:
|
|
238
|
+
tint(tint: ColorLike): Sharp;
|
|
238
239
|
|
|
239
240
|
/**
|
|
240
241
|
* Convert to 8-bit greyscale; 256 shades of grey.
|
|
@@ -684,6 +685,14 @@ declare namespace sharp {
|
|
|
684
685
|
*/
|
|
685
686
|
toUint8Array(): Promise<{ data: Uint8Array; info: OutputInfo }>;
|
|
686
687
|
|
|
688
|
+
/**
|
|
689
|
+
* Set output density (DPI) in EXIF metadata.
|
|
690
|
+
* @param density Density in dots per inch (DPI).
|
|
691
|
+
* @returns A sharp instance that can be used to chain operations
|
|
692
|
+
* @throws {Error} Invalid parameters
|
|
693
|
+
*/
|
|
694
|
+
withDensity(density: number): Sharp;
|
|
695
|
+
|
|
687
696
|
/**
|
|
688
697
|
* Keep all EXIF metadata from the input image in the output image.
|
|
689
698
|
* EXIF metadata is unsupported for TIFF output.
|
|
@@ -993,7 +1002,7 @@ declare namespace sharp {
|
|
|
993
1002
|
unlimited?: boolean | undefined;
|
|
994
1003
|
/** Set this to false to use random access rather than sequential read. Some operations will do this automatically. */
|
|
995
1004
|
sequentialRead?: boolean | undefined;
|
|
996
|
-
/**
|
|
1005
|
+
/** The DPI at which to render SVG and PDF images, in the range 1 to 100000. (optional, default 72) */
|
|
997
1006
|
density?: number | undefined;
|
|
998
1007
|
/** Should the embedded ICC profile, if any, be ignored. */
|
|
999
1008
|
ignoreIcc?: boolean | undefined;
|
|
@@ -1014,7 +1023,7 @@ declare namespace sharp {
|
|
|
1014
1023
|
/** @deprecated Use {@link SharpOptions.tiff} instead */
|
|
1015
1024
|
subifd?: number | undefined;
|
|
1016
1025
|
/** @deprecated Use {@link SharpOptions.pdf} instead */
|
|
1017
|
-
pdfBackground?:
|
|
1026
|
+
pdfBackground?: ColorLike | undefined;
|
|
1018
1027
|
/** @deprecated Use {@link SharpOptions.openSlide} instead */
|
|
1019
1028
|
level?: number | undefined;
|
|
1020
1029
|
/** Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`). (optional, default false) */
|
|
@@ -1073,7 +1082,7 @@ declare namespace sharp {
|
|
|
1073
1082
|
/** Number of bands, 3 for RGB, 4 for RGBA */
|
|
1074
1083
|
channels: CreateChannels;
|
|
1075
1084
|
/** Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. */
|
|
1076
|
-
background:
|
|
1085
|
+
background: ColorLike;
|
|
1077
1086
|
/** Describes a noise to be created. */
|
|
1078
1087
|
noise?: Noise | undefined;
|
|
1079
1088
|
/** The height of each page/frame for animated images, must be an integral factor of the overall image height. */
|
|
@@ -1120,7 +1129,7 @@ declare namespace sharp {
|
|
|
1120
1129
|
/** Space between images, in pixels. */
|
|
1121
1130
|
shim?: number | undefined;
|
|
1122
1131
|
/** Background colour. */
|
|
1123
|
-
background?:
|
|
1132
|
+
background?: ColorLike | undefined;
|
|
1124
1133
|
/** Horizontal alignment. */
|
|
1125
1134
|
halign?: HorizontalAlignment | undefined;
|
|
1126
1135
|
/** Vertical alignment. */
|
|
@@ -1141,7 +1150,7 @@ declare namespace sharp {
|
|
|
1141
1150
|
|
|
1142
1151
|
interface PdfInputOptions {
|
|
1143
1152
|
/** Background colour to use when PDF is partially transparent. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick. */
|
|
1144
|
-
background?:
|
|
1153
|
+
background?: ColorLike | undefined;
|
|
1145
1154
|
}
|
|
1146
1155
|
|
|
1147
1156
|
interface OpenSlideInputOptions {
|
|
@@ -1479,8 +1488,8 @@ declare namespace sharp {
|
|
|
1479
1488
|
xres?: number | undefined;
|
|
1480
1489
|
/** Vertical resolution in pixels/mm (optional, default 1.0) */
|
|
1481
1490
|
yres?: number | undefined;
|
|
1482
|
-
/** Reduce bitdepth to 1, 2 or 4 bit (optional
|
|
1483
|
-
bitdepth?: 1 | 2 | 4 |
|
|
1491
|
+
/** Reduce bitdepth to 1, 2 or 4 bit (optional) */
|
|
1492
|
+
bitdepth?: 1 | 2 | 4 | undefined;
|
|
1484
1493
|
/** Write 1-bit images as miniswhite (optional, default false) */
|
|
1485
1494
|
miniswhite?: boolean | undefined;
|
|
1486
1495
|
/** Resolution unit options: inch, cm (optional, default 'inch') */
|
|
@@ -1510,7 +1519,7 @@ declare namespace sharp {
|
|
|
1510
1519
|
|
|
1511
1520
|
interface RotateOptions {
|
|
1512
1521
|
/** parsed by the color module to extract values for red, green, blue and alpha. (optional, default "#000000") */
|
|
1513
|
-
background?:
|
|
1522
|
+
background?: ColorLike | undefined;
|
|
1514
1523
|
}
|
|
1515
1524
|
|
|
1516
1525
|
type Precision = 'integer' | 'float' | 'approximate';
|
|
@@ -1526,7 +1535,7 @@ declare namespace sharp {
|
|
|
1526
1535
|
|
|
1527
1536
|
interface FlattenOptions {
|
|
1528
1537
|
/** background colour, parsed by the color module, defaults to black. (optional, default {r:0,g:0,b:0}) */
|
|
1529
|
-
background?:
|
|
1538
|
+
background?: ColorLike | undefined;
|
|
1530
1539
|
}
|
|
1531
1540
|
|
|
1532
1541
|
interface NegateOptions {
|
|
@@ -1551,7 +1560,7 @@ declare namespace sharp {
|
|
|
1551
1560
|
/** Position, gravity or strategy to use when fit is cover or contain. (optional, default 'centre') */
|
|
1552
1561
|
position?: number | string | undefined;
|
|
1553
1562
|
/** Background colour when using a fit of contain, parsed by the color module, defaults to black without transparency. (optional, default {r:0,g:0,b:0,alpha:1}) */
|
|
1554
|
-
background?:
|
|
1563
|
+
background?: ColorLike | undefined;
|
|
1555
1564
|
/** The kernel to use for image reduction. (optional, default 'lanczos3') */
|
|
1556
1565
|
kernel?: keyof KernelEnum | undefined;
|
|
1557
1566
|
/** Do not enlarge if the width or height are already less than the specified dimensions, equivalent to GraphicsMagick's > geometry option. (optional, default false) */
|
|
@@ -1594,14 +1603,14 @@ declare namespace sharp {
|
|
|
1594
1603
|
/** single pixel count to right edge (optional, default 0) */
|
|
1595
1604
|
right?: number | undefined;
|
|
1596
1605
|
/** background colour, parsed by the color module, defaults to black without transparency. (optional, default {r:0,g:0,b:0,alpha:1}) */
|
|
1597
|
-
background?:
|
|
1606
|
+
background?: ColorLike | undefined;
|
|
1598
1607
|
/** how the extension is done, one of: "background", "copy", "repeat", "mirror" (optional, default `'background'`) */
|
|
1599
1608
|
extendWith?: ExtendWith | undefined;
|
|
1600
1609
|
}
|
|
1601
1610
|
|
|
1602
1611
|
interface TrimOptions {
|
|
1603
1612
|
/** Background colour, parsed by the color module, defaults to that of the top-left pixel. (optional) */
|
|
1604
|
-
background?:
|
|
1613
|
+
background?: ColorLike | undefined;
|
|
1605
1614
|
/** Allowed difference from the above colour, a positive number. (optional, default 10) */
|
|
1606
1615
|
threshold?: number | undefined;
|
|
1607
1616
|
/** Does the input more closely resemble line art (e.g. vector) rather than being photographic? (optional, default false) */
|
|
@@ -1617,15 +1626,8 @@ declare namespace sharp {
|
|
|
1617
1626
|
/** 1 for grayscale, 2 for grayscale + alpha, 3 for sRGB, 4 for CMYK or RGBA */
|
|
1618
1627
|
type Channels = 1 | 2 | 3 | 4;
|
|
1619
1628
|
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
g?: number | undefined;
|
|
1623
|
-
b?: number | undefined;
|
|
1624
|
-
alpha?: number | undefined;
|
|
1625
|
-
}
|
|
1626
|
-
|
|
1627
|
-
type Colour = string | RGBA;
|
|
1628
|
-
type Color = Colour;
|
|
1629
|
+
type Colour = ColorLike;
|
|
1630
|
+
type Color = ColorLike;
|
|
1629
1631
|
|
|
1630
1632
|
interface Kernel {
|
|
1631
1633
|
/** width of the kernel in pixels. */
|
|
@@ -1691,7 +1693,7 @@ declare namespace sharp {
|
|
|
1691
1693
|
/** Tile angle of rotation, must be a multiple of 90. (optional, default 0) */
|
|
1692
1694
|
angle?: number | undefined;
|
|
1693
1695
|
/** background colour, parsed by the color module, defaults to white without transparency. (optional, default {r:255,g:255,b:255,alpha:1}) */
|
|
1694
|
-
background?:
|
|
1696
|
+
background?: ColorLike | undefined;
|
|
1695
1697
|
/** How deep to make the pyramid, possible values are "onepixel", "onetile" or "one" (default based on layout) */
|
|
1696
1698
|
depth?: string | undefined;
|
|
1697
1699
|
/** Threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images */
|
package/lib/input.js
CHANGED
|
@@ -567,6 +567,7 @@ function _isStreamInput () {
|
|
|
567
567
|
* A `Promise` is returned when `callback` is not provided.
|
|
568
568
|
*
|
|
569
569
|
* - `format`: Name of decoder used to parse image e.g. `jpeg`, `png`, `webp`, `gif`, `svg`, `heif`, `tiff`
|
|
570
|
+
* - `mediaType`: Media Type (MIME Type) e.g. `image/jpeg`, `image/png`, `image/svg+xml`, `image/avif`
|
|
570
571
|
* - `size`: Total size of image in bytes, for Stream and Buffer input only
|
|
571
572
|
* - `width`: Number of pixels wide (EXIF orientation is not taken into consideration, see example below)
|
|
572
573
|
* - `height`: Number of pixels high (EXIF orientation is not taken into consideration, see example below)
|
package/lib/libvips.js
CHANGED
|
@@ -18,7 +18,8 @@ const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).versio
|
|
|
18
18
|
|
|
19
19
|
const prebuiltPlatforms = [
|
|
20
20
|
'darwin-arm64', 'darwin-x64',
|
|
21
|
-
'
|
|
21
|
+
'freebsd-arm64', 'freebsd-x64',
|
|
22
|
+
'linux-arm', 'linux-arm64', 'linux-ppc64', 'linux-riscv64', 'linux-s390x', 'linux-wasm32', 'linux-x64',
|
|
22
23
|
'linuxmusl-arm64', 'linuxmusl-x64',
|
|
23
24
|
'win32-arm64', 'win32-ia32', 'win32-x64'
|
|
24
25
|
];
|
|
@@ -36,13 +37,13 @@ const log = (item) => {
|
|
|
36
37
|
}
|
|
37
38
|
};
|
|
38
39
|
|
|
39
|
-
/* node:coverage
|
|
40
|
+
/* node:coverage disable */
|
|
41
|
+
|
|
40
42
|
const runtimeLibc = () => detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '';
|
|
41
43
|
|
|
42
44
|
const runtimePlatformArch = () => `${process.platform}${runtimeLibc()}-${process.arch}`;
|
|
43
45
|
|
|
44
46
|
const buildPlatformArch = () => {
|
|
45
|
-
/* node:coverage ignore next 3 */
|
|
46
47
|
if (isEmscripten()) {
|
|
47
48
|
return 'wasm32';
|
|
48
49
|
}
|
|
@@ -55,7 +56,6 @@ const buildSharpLibvipsIncludeDir = () => {
|
|
|
55
56
|
try {
|
|
56
57
|
return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/include`);
|
|
57
58
|
} catch {
|
|
58
|
-
/* node:coverage ignore next 5 */
|
|
59
59
|
try {
|
|
60
60
|
return require('@img/sharp-libvips-dev/include');
|
|
61
61
|
} catch {}
|
|
@@ -64,7 +64,6 @@ const buildSharpLibvipsIncludeDir = () => {
|
|
|
64
64
|
};
|
|
65
65
|
|
|
66
66
|
const buildSharpLibvipsCPlusPlusDir = () => {
|
|
67
|
-
/* node:coverage ignore next 4 */
|
|
68
67
|
try {
|
|
69
68
|
return require('@img/sharp-libvips-dev/cplusplus');
|
|
70
69
|
} catch {}
|
|
@@ -75,7 +74,6 @@ const buildSharpLibvipsLibDir = () => {
|
|
|
75
74
|
try {
|
|
76
75
|
return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/lib`);
|
|
77
76
|
} catch {
|
|
78
|
-
/* node:coverage ignore next 5 */
|
|
79
77
|
try {
|
|
80
78
|
return require(`@img/sharp-libvips-${buildPlatformArch()}/lib`);
|
|
81
79
|
} catch {}
|
|
@@ -83,8 +81,6 @@ const buildSharpLibvipsLibDir = () => {
|
|
|
83
81
|
return '';
|
|
84
82
|
};
|
|
85
83
|
|
|
86
|
-
/* node:coverage disable */
|
|
87
|
-
|
|
88
84
|
const isUnsupportedNodeRuntime = () => {
|
|
89
85
|
if (process.release?.name === 'node' && process.versions) {
|
|
90
86
|
if (!semverSatisfies(process.versions.node, engines.node)) {
|
|
@@ -144,22 +140,34 @@ const globalLibvipsVersion = () => {
|
|
|
144
140
|
}
|
|
145
141
|
};
|
|
146
142
|
|
|
143
|
+
const getBrewPkgConfigPath = () => {
|
|
144
|
+
try {
|
|
145
|
+
const brewPrefix = (spawnSync('brew', ['--prefix'], { encoding: 'utf8' }).stdout || '').trim();
|
|
146
|
+
if (brewPrefix) {
|
|
147
|
+
return `${brewPrefix}/lib/pkgconfig`;
|
|
148
|
+
}
|
|
149
|
+
} catch (_err) {}
|
|
150
|
+
return undefined;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const getPkgConfigPath = () => {
|
|
154
|
+
try {
|
|
155
|
+
const pkgConfigPath = (spawnSync('pkg-config', ['--variable', 'pc_path', 'pkg-config'], { encoding: 'utf8' }).stdout || '').trim();
|
|
156
|
+
if (pkgConfigPath) {
|
|
157
|
+
return pkgConfigPath;
|
|
158
|
+
}
|
|
159
|
+
} catch (_err) {}
|
|
160
|
+
return undefined;
|
|
161
|
+
};
|
|
162
|
+
|
|
147
163
|
/* node:coverage enable */
|
|
148
164
|
|
|
149
165
|
const pkgConfigPath = () => {
|
|
150
166
|
if (process.platform !== 'win32') {
|
|
151
|
-
/* node:coverage ignore next 4 */
|
|
152
|
-
const brewPkgConfigPath = spawnSync(
|
|
153
|
-
'which brew >/dev/null 2>&1 && brew environment --plain | grep PKG_CONFIG_LIBDIR | cut -d" " -f2',
|
|
154
|
-
spawnSyncOptions
|
|
155
|
-
).stdout || '';
|
|
156
167
|
return [
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
'/usr/lib/pkgconfig',
|
|
161
|
-
'/usr/local/libdata/pkgconfig',
|
|
162
|
-
'/usr/libdata/pkgconfig'
|
|
168
|
+
getBrewPkgConfigPath(),
|
|
169
|
+
getPkgConfigPath(),
|
|
170
|
+
process.env.PKG_CONFIG_PATH
|
|
163
171
|
].filter(Boolean).join(':');
|
|
164
172
|
} else {
|
|
165
173
|
return '';
|
package/lib/output.js
CHANGED
|
@@ -199,6 +199,29 @@ function toUint8Array () {
|
|
|
199
199
|
return this._pipeline(null, stack);
|
|
200
200
|
}
|
|
201
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
|
+
|
|
202
225
|
/**
|
|
203
226
|
* Keep all EXIF metadata from the input image in the output image.
|
|
204
227
|
*
|
|
@@ -354,6 +377,35 @@ function withIccProfile (icc, options) {
|
|
|
354
377
|
return this;
|
|
355
378
|
}
|
|
356
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
|
+
|
|
357
409
|
/**
|
|
358
410
|
* If the input contains gain map metadata, use it to convert the main image to HDR (High Dynamic Range) before further processing.
|
|
359
411
|
* The input gain map is discarded.
|
|
@@ -366,7 +418,7 @@ function withIccProfile (icc, options) {
|
|
|
366
418
|
* @since 0.35.0
|
|
367
419
|
*
|
|
368
420
|
* @example
|
|
369
|
-
* const
|
|
421
|
+
* const outputWithRegeneratedGainMap = await sharp(inputWithGainMap)
|
|
370
422
|
* .withGainMap()
|
|
371
423
|
* .toBuffer();
|
|
372
424
|
*
|
|
@@ -374,6 +426,7 @@ function withIccProfile (icc, options) {
|
|
|
374
426
|
*/
|
|
375
427
|
function withGainMap() {
|
|
376
428
|
this.options.withGainMap = true;
|
|
429
|
+
this.options.keepGainMap = false;
|
|
377
430
|
this.options.colourspace = 'scrgb';
|
|
378
431
|
return this;
|
|
379
432
|
}
|
|
@@ -1055,7 +1108,7 @@ function trySetAnimationOptions (source, target) {
|
|
|
1055
1108
|
* @param {number} [options.xres=1.0] - horizontal resolution in pixels/mm
|
|
1056
1109
|
* @param {number} [options.yres=1.0] - vertical resolution in pixels/mm
|
|
1057
1110
|
* @param {string} [options.resolutionUnit='inch'] - resolution unit options: inch, cm
|
|
1058
|
-
* @param {number} [options.bitdepth=
|
|
1111
|
+
* @param {number} [options.bitdepth=0] - reduce bitdepth to 1, 2 or 4 bit
|
|
1059
1112
|
* @param {boolean} [options.miniswhite=false] - write 1-bit images as miniswhite
|
|
1060
1113
|
* @returns {Sharp}
|
|
1061
1114
|
* @throws {Error} Invalid options
|
|
@@ -1070,10 +1123,10 @@ function tiff (options) {
|
|
|
1070
1123
|
}
|
|
1071
1124
|
}
|
|
1072
1125
|
if (is.defined(options.bitdepth)) {
|
|
1073
|
-
if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [1, 2, 4
|
|
1126
|
+
if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [1, 2, 4])) {
|
|
1074
1127
|
this.options.tiffBitdepth = options.bitdepth;
|
|
1075
1128
|
} else {
|
|
1076
|
-
throw is.invalidParameterError('bitdepth', '1, 2
|
|
1129
|
+
throw is.invalidParameterError('bitdepth', '1, 2 or 4', options.bitdepth);
|
|
1077
1130
|
}
|
|
1078
1131
|
}
|
|
1079
1132
|
// tiling
|
|
@@ -1175,7 +1228,7 @@ function tiff (options) {
|
|
|
1175
1228
|
* @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
|
|
1176
1229
|
* @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
|
|
1177
1230
|
* @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit
|
|
1178
|
-
* @param {string} [options.tune='iq'] - tune output for a quality metric, one of 'iq' (default), 'ssim' or 'psnr'
|
|
1231
|
+
* @param {string} [options.tune='iq'] - tune output for a quality metric, one of 'iq' (default), 'ssim' (default when lossless) or 'psnr'
|
|
1179
1232
|
* @returns {Sharp}
|
|
1180
1233
|
* @throws {Error} Invalid options
|
|
1181
1234
|
*/
|
|
@@ -1255,7 +1308,11 @@ function heif (options) {
|
|
|
1255
1308
|
}
|
|
1256
1309
|
if (is.defined(options.tune)) {
|
|
1257
1310
|
if (is.string(options.tune) && is.inArray(options.tune, ['iq', 'ssim', 'psnr'])) {
|
|
1258
|
-
this.options.
|
|
1311
|
+
if (this.options.heifLossless && options.tune === 'iq') {
|
|
1312
|
+
this.options.heifTune = 'ssim';
|
|
1313
|
+
} else {
|
|
1314
|
+
this.options.heifTune = options.tune;
|
|
1315
|
+
}
|
|
1259
1316
|
} else {
|
|
1260
1317
|
throw is.invalidParameterError('tune', 'one of: psnr, ssim, iq', options.tune);
|
|
1261
1318
|
}
|
|
@@ -1708,11 +1765,13 @@ module.exports = (Sharp) => {
|
|
|
1708
1765
|
toFile,
|
|
1709
1766
|
toBuffer,
|
|
1710
1767
|
toUint8Array,
|
|
1768
|
+
withDensity,
|
|
1711
1769
|
keepExif,
|
|
1712
1770
|
withExif,
|
|
1713
1771
|
withExifMerge,
|
|
1714
1772
|
keepIccProfile,
|
|
1715
1773
|
withIccProfile,
|
|
1774
|
+
keepGainMap,
|
|
1716
1775
|
withGainMap,
|
|
1717
1776
|
keepXmp,
|
|
1718
1777
|
withXmp,
|
package/lib/sharp.js
CHANGED
|
@@ -11,31 +11,72 @@ const { version } = require('../package.json');
|
|
|
11
11
|
const { runtimePlatformArch, isUnsupportedNodeRuntime, prebuiltPlatforms, minimumLibvipsVersion } = require('./libvips');
|
|
12
12
|
const runtimePlatform = runtimePlatformArch();
|
|
13
13
|
|
|
14
|
-
const paths = [
|
|
15
|
-
`../src/build/Release/sharp-${runtimePlatform}-${version}.node`,
|
|
16
|
-
`../src/build/Release/sharp-wasm32-${version}.node`,
|
|
17
|
-
`@img/sharp-${runtimePlatform}/sharp.node`,
|
|
18
|
-
'@img/sharp-wasm32/sharp.node'
|
|
19
|
-
];
|
|
20
|
-
|
|
21
14
|
/* node:coverage disable */
|
|
22
15
|
|
|
23
|
-
|
|
16
|
+
const prebuiltBinaryForRuntime = () => {
|
|
17
|
+
switch (runtimePlatform) {
|
|
18
|
+
case 'darwin-arm64':
|
|
19
|
+
return require('@img/sharp-darwin-arm64/sharp.node');
|
|
20
|
+
case 'darwin-x64':
|
|
21
|
+
return require('@img/sharp-darwin-x64/sharp.node');
|
|
22
|
+
case 'linux-arm':
|
|
23
|
+
return require('@img/sharp-linux-arm/sharp.node');
|
|
24
|
+
case 'linux-arm64':
|
|
25
|
+
return require('@img/sharp-linux-arm64/sharp.node');
|
|
26
|
+
case 'linux-ppc64':
|
|
27
|
+
return require('@img/sharp-linux-ppc64/sharp.node');
|
|
28
|
+
case 'linux-riscv64':
|
|
29
|
+
return require('@img/sharp-linux-riscv64/sharp.node');
|
|
30
|
+
case 'linux-s390x':
|
|
31
|
+
return require('@img/sharp-linux-s390x/sharp.node');
|
|
32
|
+
case 'linux-x64':
|
|
33
|
+
return require('@img/sharp-linux-x64/sharp.node');
|
|
34
|
+
case 'linuxmusl-arm64':
|
|
35
|
+
return require('@img/sharp-linuxmusl-arm64/sharp.node') ;
|
|
36
|
+
case 'linuxmusl-x64':
|
|
37
|
+
return require('@img/sharp-linuxmusl-x64/sharp.node');
|
|
38
|
+
case 'win32-arm64':
|
|
39
|
+
return require('@img/sharp-win32-arm64/sharp.node');
|
|
40
|
+
case 'win32-ia32':
|
|
41
|
+
return require('@img/sharp-win32-ia32/sharp.node');
|
|
42
|
+
case 'win32-x64':
|
|
43
|
+
return require('@img/sharp-win32-x64/sharp.node');
|
|
44
|
+
case 'freebsd-arm64':
|
|
45
|
+
case 'freebsd-x64':
|
|
46
|
+
return require('@img/sharp-freebsd-wasm32/sharp.node');
|
|
47
|
+
case 'linux-wasm32':
|
|
48
|
+
return require('@img/sharp-webcontainers-wasm32/sharp.node');
|
|
49
|
+
default:
|
|
50
|
+
return require('@img/sharp-wasm32/sharp.node');
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
let sharp;
|
|
24
55
|
const errors = [];
|
|
25
|
-
|
|
56
|
+
try {
|
|
57
|
+
sharp = require(`../src/build/Release/sharp-${runtimePlatform}-${version}.node`);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
errors.push(err);
|
|
60
|
+
}
|
|
61
|
+
if (!sharp) {
|
|
26
62
|
try {
|
|
27
|
-
sharp = require(
|
|
28
|
-
break;
|
|
63
|
+
sharp = require(`../src/build/Release/sharp-wasm32-${version}.node`);
|
|
29
64
|
} catch (err) {
|
|
30
65
|
errors.push(err);
|
|
31
66
|
}
|
|
32
67
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
68
|
+
if (!sharp) {
|
|
69
|
+
try {
|
|
70
|
+
sharp = prebuiltBinaryForRuntime();
|
|
71
|
+
if (['linux-x64', 'linuxmusl-x64'].includes(runtimePlatform) && !sharp._isUsingX64V2()) {
|
|
72
|
+
const err = new Error('Prebuilt binaries for Linux x64 require v2 microarchitecture');
|
|
73
|
+
err.code = 'Unsupported CPU';
|
|
74
|
+
errors.push(err);
|
|
75
|
+
sharp = null;
|
|
76
|
+
}
|
|
77
|
+
} catch (err) {
|
|
78
|
+
errors.push(err);
|
|
79
|
+
}
|
|
39
80
|
}
|
|
40
81
|
|
|
41
82
|
if (sharp) {
|
|
@@ -74,9 +115,8 @@ if (sharp) {
|
|
|
74
115
|
help.push(
|
|
75
116
|
`- Manually install libvips >= ${minimumLibvipsVersion}`,
|
|
76
117
|
' See https://sharp.pixelplumbing.com/install#building-from-source',
|
|
77
|
-
'- Add
|
|
78
|
-
' npm install
|
|
79
|
-
' npm install @img/sharp-wasm32'
|
|
118
|
+
'- Add WebAssembly-based dependencies:',
|
|
119
|
+
' npm install sharp @img/sharp-wasm32'
|
|
80
120
|
);
|
|
81
121
|
}
|
|
82
122
|
if (isLinux && /(symbol not found|CXXABI_)/i.test(messages)) {
|