sharp 0.33.2 → 0.33.3-rc.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/colour.js CHANGED
@@ -90,7 +90,7 @@ function pipelineColourspace (colourspace) {
90
90
  if (!is.string(colourspace)) {
91
91
  throw is.invalidParameterError('colourspace', 'string', colourspace);
92
92
  }
93
- this.options.colourspaceInput = colourspace;
93
+ this.options.colourspacePipeline = colourspace;
94
94
  return this;
95
95
  }
96
96
 
@@ -40,14 +40,16 @@ const debuglog = util.debuglog('sharp');
40
40
  * });
41
41
  *
42
42
  * @example
43
- * // Read image data from readableStream,
43
+ * // Read image data from remote URL,
44
44
  * // resize to 300 pixels wide,
45
45
  * // emit an 'info' event with calculated dimensions
46
46
  * // and finally write image data to writableStream
47
- * var transformer = sharp()
47
+ * const { body } = fetch('https://...');
48
+ * const readableStream = Readable.fromWeb(body);
49
+ * const transformer = sharp()
48
50
  * .resize(300)
49
- * .on('info', function(info) {
50
- * console.log('Image height is ' + info.height);
51
+ * .on('info', ({ height }) => {
52
+ * console.log(`Image height is ${height}`);
51
53
  * });
52
54
  * readableStream.pipe(transformer).pipe(writableStream);
53
55
  *
@@ -164,7 +166,7 @@ const debuglog = util.debuglog('sharp');
164
166
  * @param {number} [options.text.dpi=72] - the resolution (size) at which to render the text. Does not take effect if `height` is specified.
165
167
  * @param {boolean} [options.text.rgba=false] - set this to true to enable RGBA output. This is useful for colour emoji rendering, or support for pango markup features like `<span foreground="red">Red!</span>`.
166
168
  * @param {number} [options.text.spacing=0] - text line height in points. Will use the font line height if none is specified.
167
- * @param {string} [options.text.wrap='word'] - word wrapping style when width is provided, one of: 'word', 'char', 'charWord' (prefer char, fallback to word) or 'none'.
169
+ * @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'.
168
170
  * @returns {Sharp}
169
171
  * @throws {Error} Invalid parameters
170
172
  */
@@ -255,7 +257,7 @@ const Sharp = function (input, options) {
255
257
  removeAlpha: false,
256
258
  ensureAlpha: -1,
257
259
  colourspace: 'srgb',
258
- colourspaceInput: 'last',
260
+ colourspacePipeline: 'last',
259
261
  composite: [],
260
262
  // output
261
263
  fileOut: '',
@@ -323,6 +325,7 @@ const Sharp = function (input, options) {
323
325
  heifCompression: 'av1',
324
326
  heifEffort: 4,
325
327
  heifChromaSubsampling: '4:4:4',
328
+ heifBitdepth: 8,
326
329
  jxlDistance: 1,
327
330
  jxlDecodingTier: 0,
328
331
  jxlEffort: 7,
@@ -423,13 +426,16 @@ Object.setPrototypeOf(Sharp, stream.Duplex);
423
426
  function clone () {
424
427
  // Clone existing options
425
428
  const clone = this.constructor.call();
426
- clone.options = Object.assign({}, this.options);
429
+ const { debuglog, queueListener, ...options } = this.options;
430
+ clone.options = structuredClone(options);
431
+ clone.options.debuglog = debuglog;
432
+ clone.options.queueListener = queueListener;
427
433
  // Pass 'finish' event to clone for Stream-based input
428
434
  if (this._isStreamInput()) {
429
435
  this.on('finish', () => {
430
436
  // Clone inherits input data
431
437
  this._flattenBufferIn();
432
- clone.options.bufferIn = this.options.bufferIn;
438
+ clone.options.input.buffer = this.options.input.buffer;
433
439
  clone.emit('finish');
434
440
  });
435
441
  }
package/lib/index.d.ts CHANGED
@@ -1017,7 +1017,7 @@ declare namespace sharp {
1017
1017
  rgba?: boolean;
1018
1018
  /** Text line height in points. Will use the font line height if none is specified. (optional, default `0`) */
1019
1019
  spacing?: number;
1020
- /** Word wrapping style when width is provided, one of: 'word', 'char', 'charWord' (prefer char, fallback to word) or 'none' */
1020
+ /** Word wrapping style when width is provided, one of: 'word', 'char', 'word-char' (prefer word, fallback to char) or 'none' */
1021
1021
  wrap?: TextWrap;
1022
1022
  }
1023
1023
 
@@ -1244,6 +1244,8 @@ declare namespace sharp {
1244
1244
  effort?: number | undefined;
1245
1245
  /** set to '4:2:0' to use chroma subsampling, requires libvips v8.11.0 (optional, default '4:4:4') */
1246
1246
  chromaSubsampling?: string | undefined;
1247
+ /** Set bitdepth to 8, 10 or 12 bit (optional, default 8) */
1248
+ bitdepth?: 8 | 10 | 12 | undefined;
1247
1249
  }
1248
1250
 
1249
1251
  interface HeifOptions extends OutputOptions {
@@ -1257,6 +1259,8 @@ declare namespace sharp {
1257
1259
  effort?: number | undefined;
1258
1260
  /** set to '4:2:0' to use chroma subsampling (optional, default '4:4:4') */
1259
1261
  chromaSubsampling?: string | undefined;
1262
+ /** Set bitdepth to 8, 10 or 12 bit (optional, default 8) */
1263
+ bitdepth?: 8 | 10 | 12 | undefined;
1260
1264
  }
1261
1265
 
1262
1266
  interface GifOptions extends OutputOptions, AnimationOptions {
@@ -1613,7 +1617,7 @@ declare namespace sharp {
1613
1617
 
1614
1618
  type TextAlign = 'left' | 'centre' | 'center' | 'right';
1615
1619
 
1616
- type TextWrap = 'word' | 'char' | 'charWord' | 'none';
1620
+ type TextWrap = 'word' | 'char' | 'word-char' | 'none';
1617
1621
 
1618
1622
  type TileContainer = 'fs' | 'zip';
1619
1623
 
package/lib/input.js CHANGED
@@ -345,10 +345,10 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
345
345
  }
346
346
  }
347
347
  if (is.defined(inputOptions.text.wrap)) {
348
- if (is.string(inputOptions.text.wrap) && is.inArray(inputOptions.text.wrap, ['word', 'char', 'wordChar', 'none'])) {
348
+ if (is.string(inputOptions.text.wrap) && is.inArray(inputOptions.text.wrap, ['word', 'char', 'word-char', 'none'])) {
349
349
  inputDescriptor.textWrap = inputOptions.text.wrap;
350
350
  } else {
351
- throw is.invalidParameterError('text.wrap', 'one of: word, char, wordChar, none', inputOptions.text.wrap);
351
+ throw is.invalidParameterError('text.wrap', 'one of: word, char, word-char, none', inputOptions.text.wrap);
352
352
  }
353
353
  }
354
354
  delete inputDescriptor.buffer;
package/lib/output.js CHANGED
@@ -504,10 +504,14 @@ function jpeg (options) {
504
504
  /**
505
505
  * Use these PNG options for output image.
506
506
  *
507
- * By default, PNG output is full colour at 8 or 16 bits per pixel.
507
+ * By default, PNG output is full colour at 8 bits per pixel.
508
+ *
508
509
  * Indexed PNG input at 1, 2 or 4 bits per pixel is converted to 8 bits per pixel.
509
510
  * Set `palette` to `true` for slower, indexed PNG output.
510
511
  *
512
+ * For 16 bits per pixel output, convert to `rgb16` via
513
+ * {@link /api-colour#tocolourspace|toColourspace}.
514
+ *
511
515
  * @example
512
516
  * // Convert any input to full colour PNG output
513
517
  * const data = await sharp(input)
@@ -520,6 +524,13 @@ function jpeg (options) {
520
524
  * .png({ palette: true })
521
525
  * .toBuffer();
522
526
  *
527
+ * @example
528
+ * // Output 16 bits per pixel RGB(A)
529
+ * const data = await sharp(input)
530
+ * .toColourspace('rgb16')
531
+ * .png()
532
+ * .toBuffer();
533
+ *
523
534
  * @param {Object} [options]
524
535
  * @param {boolean} [options.progressive=false] - use progressive (interlace) scan
525
536
  * @param {number} [options.compressionLevel=6] - zlib compression level, 0 (fastest, largest) to 9 (slowest, smallest)
@@ -1000,6 +1011,7 @@ function tiff (options) {
1000
1011
  * Use these AVIF options for output image.
1001
1012
  *
1002
1013
  * AVIF image sequences are not supported.
1014
+ * Prebuilt binaries support a bitdepth of 8 only.
1003
1015
  *
1004
1016
  * @example
1005
1017
  * const data = await sharp(input)
@@ -1018,6 +1030,7 @@ function tiff (options) {
1018
1030
  * @param {boolean} [options.lossless=false] - use lossless compression
1019
1031
  * @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
1020
1032
  * @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
1033
+ * @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit
1021
1034
  * @returns {Sharp}
1022
1035
  * @throws {Error} Invalid options
1023
1036
  */
@@ -1044,6 +1057,7 @@ function avif (options) {
1044
1057
  * @param {boolean} [options.lossless=false] - use lossless compression
1045
1058
  * @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
1046
1059
  * @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
1060
+ * @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit
1047
1061
  * @returns {Sharp}
1048
1062
  * @throws {Error} Invalid options
1049
1063
  */
@@ -1082,6 +1096,16 @@ function heif (options) {
1082
1096
  throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling);
1083
1097
  }
1084
1098
  }
1099
+ if (is.defined(options.bitdepth)) {
1100
+ if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [8, 10, 12])) {
1101
+ if (options.bitdepth !== 8 && this.constructor.versions.heif) {
1102
+ throw is.invalidParameterError('bitdepth when using prebuilt binaries', 8, options.bitdepth);
1103
+ }
1104
+ this.options.heifBitdepth = options.bitdepth;
1105
+ } else {
1106
+ throw is.invalidParameterError('bitdepth', '8, 10 or 12', options.bitdepth);
1107
+ }
1108
+ }
1085
1109
  } else {
1086
1110
  throw is.invalidParameterError('options', 'Object', options);
1087
1111
  }
@@ -1233,7 +1257,7 @@ function raw (options) {
1233
1257
  * @param {number} [options.angle=0] tile angle of rotation, must be a multiple of 90.
1234
1258
  * @param {string|Object} [options.background={r: 255, g: 255, b: 255, alpha: 1}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to white without transparency.
1235
1259
  * @param {string} [options.depth] how deep to make the pyramid, possible values are `onepixel`, `onetile` or `one`, default based on layout.
1236
- * @param {number} [options.skipBlanks=-1] threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images
1260
+ * @param {number} [options.skipBlanks=-1] Threshold to skip tile generation. Range is 0-255 for 8-bit images, 0-65535 for 16-bit images. Default is 5 for `google` layout, -1 (no skip) otherwise.
1237
1261
  * @param {string} [options.container='fs'] tile container, with value `fs` (filesystem) or `zip` (compressed file).
1238
1262
  * @param {string} [options.layout='dz'] filesystem layout, possible values are `dz`, `iiif`, `iiif3`, `zoomify` or `google`.
1239
1263
  * @param {boolean} [options.centre=false] centre image in tile.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "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.33.2",
4
+ "version": "0.33.3-rc.0",
5
5
  "author": "Lovell Fuller <npm@lovell.info>",
6
6
  "homepage": "https://sharp.pixelplumbing.com",
7
7
  "contributors": [
@@ -137,57 +137,57 @@
137
137
  ],
138
138
  "dependencies": {
139
139
  "color": "^4.2.3",
140
- "detect-libc": "^2.0.2",
141
- "semver": "^7.5.4"
140
+ "detect-libc": "^2.0.3",
141
+ "semver": "^7.6.0"
142
142
  },
143
143
  "optionalDependencies": {
144
- "@img/sharp-darwin-arm64": "0.33.2",
145
- "@img/sharp-darwin-x64": "0.33.2",
146
- "@img/sharp-libvips-darwin-arm64": "1.0.1",
147
- "@img/sharp-libvips-darwin-x64": "1.0.1",
148
- "@img/sharp-libvips-linux-arm": "1.0.1",
149
- "@img/sharp-libvips-linux-arm64": "1.0.1",
150
- "@img/sharp-libvips-linux-s390x": "1.0.1",
151
- "@img/sharp-libvips-linux-x64": "1.0.1",
152
- "@img/sharp-libvips-linuxmusl-arm64": "1.0.1",
153
- "@img/sharp-libvips-linuxmusl-x64": "1.0.1",
154
- "@img/sharp-linux-arm": "0.33.2",
155
- "@img/sharp-linux-arm64": "0.33.2",
156
- "@img/sharp-linux-s390x": "0.33.2",
157
- "@img/sharp-linux-x64": "0.33.2",
158
- "@img/sharp-linuxmusl-arm64": "0.33.2",
159
- "@img/sharp-linuxmusl-x64": "0.33.2",
160
- "@img/sharp-wasm32": "0.33.2",
161
- "@img/sharp-win32-ia32": "0.33.2",
162
- "@img/sharp-win32-x64": "0.33.2"
144
+ "@img/sharp-darwin-arm64": "0.33.3-rc.0",
145
+ "@img/sharp-darwin-x64": "0.33.3-rc.0",
146
+ "@img/sharp-libvips-darwin-arm64": "1.0.2",
147
+ "@img/sharp-libvips-darwin-x64": "1.0.2",
148
+ "@img/sharp-libvips-linux-arm": "1.0.2",
149
+ "@img/sharp-libvips-linux-arm64": "1.0.2",
150
+ "@img/sharp-libvips-linux-s390x": "1.0.2",
151
+ "@img/sharp-libvips-linux-x64": "1.0.2",
152
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.2",
153
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.2",
154
+ "@img/sharp-linux-arm": "0.33.3-rc.0",
155
+ "@img/sharp-linux-arm64": "0.33.3-rc.0",
156
+ "@img/sharp-linux-s390x": "0.33.3-rc.0",
157
+ "@img/sharp-linux-x64": "0.33.3-rc.0",
158
+ "@img/sharp-linuxmusl-arm64": "0.33.3-rc.0",
159
+ "@img/sharp-linuxmusl-x64": "0.33.3-rc.0",
160
+ "@img/sharp-wasm32": "0.33.3-rc.0",
161
+ "@img/sharp-win32-ia32": "0.33.3-rc.0",
162
+ "@img/sharp-win32-x64": "0.33.3-rc.0"
163
163
  },
164
164
  "devDependencies": {
165
- "@emnapi/runtime": "^0.45.0",
166
- "@img/sharp-libvips-dev": "1.0.1",
167
- "@img/sharp-libvips-dev-wasm32": "1.0.1",
168
- "@img/sharp-libvips-win32-ia32": "1.0.1",
169
- "@img/sharp-libvips-win32-x64": "1.0.1",
165
+ "@emnapi/runtime": "^1.1.0",
166
+ "@img/sharp-libvips-dev": "1.0.2",
167
+ "@img/sharp-libvips-dev-wasm32": "1.0.3",
168
+ "@img/sharp-libvips-win32-ia32": "1.0.2",
169
+ "@img/sharp-libvips-win32-x64": "1.0.2",
170
170
  "@types/node": "*",
171
171
  "async": "^3.2.5",
172
172
  "cc": "^3.0.1",
173
- "emnapi": "^0.45.0",
174
- "exif-reader": "^2.0.0",
173
+ "emnapi": "^1.1.0",
174
+ "exif-reader": "^2.0.1",
175
175
  "extract-zip": "^2.0.1",
176
176
  "icc": "^3.0.0",
177
- "jsdoc-to-markdown": "^8.0.0",
177
+ "jsdoc-to-markdown": "^8.0.1",
178
178
  "license-checker": "^25.0.1",
179
- "mocha": "^10.2.0",
180
- "node-addon-api": "^7.0.0",
179
+ "mocha": "^10.3.0",
180
+ "node-addon-api": "^8.0.0",
181
181
  "nyc": "^15.1.0",
182
- "prebuild": "^12.1.0",
182
+ "prebuild": "^13.0.0",
183
183
  "semistandard": "^17.0.0",
184
- "tar-fs": "^3.0.4",
185
- "tsd": "^0.30.3"
184
+ "tar-fs": "^3.0.5",
185
+ "tsd": "^0.30.7"
186
186
  },
187
187
  "license": "Apache-2.0",
188
188
  "engines": {
189
189
  "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
190
- "libvips": ">=8.15.1"
190
+ "libvips": ">=8.15.2"
191
191
  },
192
192
  "funding": {
193
193
  "url": "https://opencollective.com/libvips"
package/src/common.h CHANGED
@@ -16,8 +16,8 @@
16
16
 
17
17
  #if (VIPS_MAJOR_VERSION < 8) || \
18
18
  (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 15) || \
19
- (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 15 && VIPS_MICRO_VERSION < 1)
20
- #error "libvips version 8.15.1+ is required - please see https://sharp.pixelplumbing.com/install"
19
+ (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 15 && VIPS_MICRO_VERSION < 2)
20
+ #error "libvips version 8.15.2+ is required - please see https://sharp.pixelplumbing.com/install"
21
21
  #endif
22
22
 
23
23
  #if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
package/src/pipeline.cc CHANGED
@@ -54,7 +54,7 @@ class PipelineWorker : public Napi::AsyncWorker {
54
54
  sharp::ImageType inputImageType;
55
55
  std::tie(image, inputImageType) = sharp::OpenInput(baton->input);
56
56
  VipsAccess access = baton->input->access;
57
- image = sharp::EnsureColourspace(image, baton->colourspaceInput);
57
+ image = sharp::EnsureColourspace(image, baton->colourspacePipeline);
58
58
 
59
59
  int nPages = baton->input->pages;
60
60
  if (nPages == -1) {
@@ -189,7 +189,7 @@ class PipelineWorker : public Napi::AsyncWorker {
189
189
  // - input colourspace is not specified;
190
190
  bool const shouldPreShrink = (targetResizeWidth > 0 || targetResizeHeight > 0) &&
191
191
  baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold < 0.0 &&
192
- baton->colourspaceInput == VIPS_INTERPRETATION_LAST && !shouldRotateBefore;
192
+ baton->colourspacePipeline == VIPS_INTERPRETATION_LAST && !shouldRotateBefore;
193
193
 
194
194
  if (shouldPreShrink) {
195
195
  // The common part of the shrink: the bit by which both axes must be shrunk
@@ -331,6 +331,7 @@ class PipelineWorker : public Napi::AsyncWorker {
331
331
  sharp::HasProfile(image) &&
332
332
  image.interpretation() != VIPS_INTERPRETATION_LABS &&
333
333
  image.interpretation() != VIPS_INTERPRETATION_GREY16 &&
334
+ baton->colourspacePipeline != VIPS_INTERPRETATION_CMYK &&
334
335
  !baton->input->ignoreIcc
335
336
  ) {
336
337
  // Convert to sRGB/P3 using embedded profile
@@ -344,7 +345,7 @@ class PipelineWorker : public Napi::AsyncWorker {
344
345
  }
345
346
  } else if (
346
347
  image.interpretation() == VIPS_INTERPRETATION_CMYK &&
347
- baton->colourspaceInput != VIPS_INTERPRETATION_CMYK
348
+ baton->colourspacePipeline != VIPS_INTERPRETATION_CMYK
348
349
  ) {
349
350
  image = image.icc_transform(processingProfile, VImage::option()
350
351
  ->set("input_profile", "cmyk")
@@ -432,7 +433,7 @@ class PipelineWorker : public Napi::AsyncWorker {
432
433
  for (unsigned int i = 0; i < baton->joinChannelIn.size(); i++) {
433
434
  baton->joinChannelIn[i]->access = access;
434
435
  std::tie(joinImage, joinImageType) = sharp::OpenInput(baton->joinChannelIn[i]);
435
- joinImage = sharp::EnsureColourspace(joinImage, baton->colourspaceInput);
436
+ joinImage = sharp::EnsureColourspace(joinImage, baton->colourspacePipeline);
436
437
  image = image.bandjoin(joinImage);
437
438
  }
438
439
  image = image.copy(VImage::option()->set("interpretation", baton->colourspace));
@@ -642,7 +643,7 @@ class PipelineWorker : public Napi::AsyncWorker {
642
643
  sharp::ImageType compositeImageType = sharp::ImageType::UNKNOWN;
643
644
  composite->input->access = access;
644
645
  std::tie(compositeImage, compositeImageType) = sharp::OpenInput(composite->input);
645
- compositeImage = sharp::EnsureColourspace(compositeImage, baton->colourspaceInput);
646
+ compositeImage = sharp::EnsureColourspace(compositeImage, baton->colourspacePipeline);
646
647
  // Verify within current dimensions
647
648
  if (compositeImage.width() > image.width() || compositeImage.height() > image.height()) {
648
649
  throw vips::VError("Image to composite must have same dimensions or smaller");
@@ -743,7 +744,7 @@ class PipelineWorker : public Napi::AsyncWorker {
743
744
  sharp::ImageType booleanImageType = sharp::ImageType::UNKNOWN;
744
745
  baton->boolean->access = access;
745
746
  std::tie(booleanImage, booleanImageType) = sharp::OpenInput(baton->boolean);
746
- booleanImage = sharp::EnsureColourspace(booleanImage, baton->colourspaceInput);
747
+ booleanImage = sharp::EnsureColourspace(booleanImage, baton->colourspacePipeline);
747
748
  image = sharp::Boolean(image, booleanImage, baton->booleanOp);
748
749
  image = sharp::RemoveGifPalette(image);
749
750
  }
@@ -776,9 +777,9 @@ class PipelineWorker : public Napi::AsyncWorker {
776
777
  // Convert colourspace, pass the current known interpretation so libvips doesn't have to guess
777
778
  image = image.colourspace(baton->colourspace, VImage::option()->set("source_space", image.interpretation()));
778
779
  // Transform colours from embedded profile to output profile
779
- if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) &&
780
+ if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) && baton->colourspacePipeline != VIPS_INTERPRETATION_CMYK &&
780
781
  baton->withIccProfile.empty() && sharp::HasProfile(image)) {
781
- image = image.icc_transform("srgb", VImage::option()
782
+ image = image.icc_transform(processingProfile, VImage::option()
782
783
  ->set("embedded", TRUE)
783
784
  ->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
784
785
  ->set("intent", VIPS_INTENT_PERCEPTUAL));
@@ -988,7 +989,7 @@ class PipelineWorker : public Napi::AsyncWorker {
988
989
  ->set("Q", baton->heifQuality)
989
990
  ->set("compression", baton->heifCompression)
990
991
  ->set("effort", baton->heifEffort)
991
- ->set("bitdepth", 8)
992
+ ->set("bitdepth", baton->heifBitdepth)
992
993
  ->set("subsample_mode", baton->heifChromaSubsampling == "4:4:4"
993
994
  ? VIPS_FOREIGN_SUBSAMPLE_OFF : VIPS_FOREIGN_SUBSAMPLE_ON)
994
995
  ->set("lossless", baton->heifLossless)));
@@ -1181,7 +1182,7 @@ class PipelineWorker : public Napi::AsyncWorker {
1181
1182
  ->set("Q", baton->heifQuality)
1182
1183
  ->set("compression", baton->heifCompression)
1183
1184
  ->set("effort", baton->heifEffort)
1184
- ->set("bitdepth", 8)
1185
+ ->set("bitdepth", baton->heifBitdepth)
1185
1186
  ->set("subsample_mode", baton->heifChromaSubsampling == "4:4:4"
1186
1187
  ? VIPS_FOREIGN_SUBSAMPLE_OFF : VIPS_FOREIGN_SUBSAMPLE_ON)
1187
1188
  ->set("lossless", baton->heifLossless));
@@ -1607,10 +1608,10 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1607
1608
  baton->recombMatrix[i] = sharp::AttrAsDouble(recombMatrix, i);
1608
1609
  }
1609
1610
  }
1610
- baton->colourspaceInput = sharp::AttrAsEnum<VipsInterpretation>(
1611
- options, "colourspaceInput", VIPS_TYPE_INTERPRETATION);
1612
- if (baton->colourspaceInput == VIPS_INTERPRETATION_ERROR) {
1613
- baton->colourspaceInput = VIPS_INTERPRETATION_LAST;
1611
+ baton->colourspacePipeline = sharp::AttrAsEnum<VipsInterpretation>(
1612
+ options, "colourspacePipeline", VIPS_TYPE_INTERPRETATION);
1613
+ if (baton->colourspacePipeline == VIPS_INTERPRETATION_ERROR) {
1614
+ baton->colourspacePipeline = VIPS_INTERPRETATION_LAST;
1614
1615
  }
1615
1616
  baton->colourspace = sharp::AttrAsEnum<VipsInterpretation>(options, "colourspace", VIPS_TYPE_INTERPRETATION);
1616
1617
  if (baton->colourspace == VIPS_INTERPRETATION_ERROR) {
@@ -1695,6 +1696,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1695
1696
  options, "heifCompression", VIPS_TYPE_FOREIGN_HEIF_COMPRESSION);
1696
1697
  baton->heifEffort = sharp::AttrAsUint32(options, "heifEffort");
1697
1698
  baton->heifChromaSubsampling = sharp::AttrAsStr(options, "heifChromaSubsampling");
1699
+ baton->heifBitdepth = sharp::AttrAsUint32(options, "heifBitdepth");
1698
1700
  baton->jxlDistance = sharp::AttrAsDouble(options, "jxlDistance");
1699
1701
  baton->jxlDecodingTier = sharp::AttrAsUint32(options, "jxlDecodingTier");
1700
1702
  baton->jxlEffort = sharp::AttrAsUint32(options, "jxlEffort");
package/src/pipeline.h CHANGED
@@ -181,6 +181,7 @@ struct PipelineBaton {
181
181
  int heifEffort;
182
182
  std::string heifChromaSubsampling;
183
183
  bool heifLossless;
184
+ int heifBitdepth;
184
185
  double jxlDistance;
185
186
  int jxlDecodingTier;
186
187
  int jxlEffort;
@@ -205,7 +206,7 @@ struct PipelineBaton {
205
206
  int extractChannel;
206
207
  bool removeAlpha;
207
208
  double ensureAlpha;
208
- VipsInterpretation colourspaceInput;
209
+ VipsInterpretation colourspacePipeline;
209
210
  VipsInterpretation colourspace;
210
211
  std::vector<int> delay;
211
212
  int loop;
@@ -349,6 +350,7 @@ struct PipelineBaton {
349
350
  heifEffort(4),
350
351
  heifChromaSubsampling("4:4:4"),
351
352
  heifLossless(false),
353
+ heifBitdepth(8),
352
354
  jxlDistance(1.0),
353
355
  jxlDecodingTier(0),
354
356
  jxlEffort(7),
@@ -369,7 +371,7 @@ struct PipelineBaton {
369
371
  extractChannel(-1),
370
372
  removeAlpha(false),
371
373
  ensureAlpha(-1.0),
372
- colourspaceInput(VIPS_INTERPRETATION_LAST),
374
+ colourspacePipeline(VIPS_INTERPRETATION_LAST),
373
375
  colourspace(VIPS_INTERPRETATION_LAST),
374
376
  loop(-1),
375
377
  tileSize(256),