@revizly/sharp 0.35.0-revizly40 → 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.
package/dist/colour.cjs CHANGED
@@ -146,12 +146,16 @@ function _getBackgroundColourOption (value) {
146
146
  (is.string(value) && value.length >= 3 && value.length <= 200)
147
147
  ) {
148
148
  const colour = color(value);
149
- return [
150
- colour.red(),
151
- colour.green(),
152
- colour.blue(),
153
- Math.round(colour.alpha() * 255)
154
- ];
149
+ const red = colour.red();
150
+ const green = colour.green();
151
+ const blue = colour.blue();
152
+ const alpha = Math.round(colour.alpha() * 255);
153
+ for (const [channel, component] of [['red', red], ['green', green], ['blue', blue], ['alpha', alpha]]) {
154
+ if (!is.number(component)) {
155
+ throw is.invalidParameterError(`background.${channel}`, 'number', component);
156
+ }
157
+ }
158
+ return [red, green, blue, alpha];
155
159
  } else {
156
160
  throw is.invalidParameterError('background', 'object or string', value);
157
161
  }
package/dist/colour.mjs CHANGED
@@ -146,12 +146,16 @@ function _getBackgroundColourOption (value) {
146
146
  (is.string(value) && value.length >= 3 && value.length <= 200)
147
147
  ) {
148
148
  const colour = color(value);
149
- return [
150
- colour.red(),
151
- colour.green(),
152
- colour.blue(),
153
- Math.round(colour.alpha() * 255)
154
- ];
149
+ const red = colour.red();
150
+ const green = colour.green();
151
+ const blue = colour.blue();
152
+ const alpha = Math.round(colour.alpha() * 255);
153
+ for (const [channel, component] of [['red', red], ['green', green], ['blue', blue], ['alpha', alpha]]) {
154
+ if (!is.number(component)) {
155
+ throw is.invalidParameterError(`background.${channel}`, 'number', component);
156
+ }
157
+ }
158
+ return [red, green, blue, alpha];
155
159
  } else {
156
160
  throw is.invalidParameterError('background', 'object or string', value);
157
161
  }
package/dist/index.d.cts CHANGED
@@ -1602,13 +1602,13 @@ declare namespace sharp {
1602
1602
  }
1603
1603
 
1604
1604
  interface Region {
1605
- /** zero-indexed offset from left edge */
1605
+ /** zero-indexed offset from left edge, an integer between 0 and 100000000 */
1606
1606
  left: number;
1607
- /** zero-indexed offset from top edge */
1607
+ /** zero-indexed offset from top edge, an integer between 0 and 100000000 */
1608
1608
  top: number;
1609
- /** dimension of extracted image */
1609
+ /** dimension of extracted image, an integer between 0 and 100000000 */
1610
1610
  width: number;
1611
- /** dimension of extracted image */
1611
+ /** dimension of extracted image, an integer between 0 and 100000000 */
1612
1612
  height: number;
1613
1613
  }
1614
1614
 
@@ -1787,6 +1787,8 @@ declare namespace sharp {
1787
1787
  channels: Channels;
1788
1788
  /** indicating if premultiplication was used */
1789
1789
  premultiplied: boolean;
1790
+ /** Indicates if the output image has an alpha channel */
1791
+ hasAlpha: boolean;
1790
1792
  /** Only defined when using a crop strategy */
1791
1793
  cropOffsetLeft?: number | undefined;
1792
1794
  /** Only defined when using a crop strategy */
package/dist/index.d.mts CHANGED
@@ -1596,13 +1596,13 @@ export interface ResizeOptions {
1596
1596
  }
1597
1597
 
1598
1598
  export interface Region {
1599
- /** zero-indexed offset from left edge */
1599
+ /** zero-indexed offset from left edge, an integer between 0 and 100000000 */
1600
1600
  left: number;
1601
- /** zero-indexed offset from top edge */
1601
+ /** zero-indexed offset from top edge, an integer between 0 and 100000000 */
1602
1602
  top: number;
1603
- /** dimension of extracted image */
1603
+ /** dimension of extracted image, an integer between 0 and 100000000 */
1604
1604
  width: number;
1605
- /** dimension of extracted image */
1605
+ /** dimension of extracted image, an integer between 0 and 100000000 */
1606
1606
  height: number;
1607
1607
  }
1608
1608
 
@@ -1781,6 +1781,8 @@ export interface OutputInfo {
1781
1781
  channels: Channels;
1782
1782
  /** indicating if premultiplication was used */
1783
1783
  premultiplied: boolean;
1784
+ /** Indicates if the output image has an alpha channel */
1785
+ hasAlpha: boolean;
1784
1786
  /** Only defined when using a crop strategy */
1785
1787
  cropOffsetLeft?: number | undefined;
1786
1788
  /** Only defined when using a crop strategy */
package/dist/input.cjs CHANGED
@@ -181,8 +181,8 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
181
181
  if (is.defined(inputOptions.raw)) {
182
182
  if (
183
183
  is.object(inputOptions.raw) &&
184
- is.integer(inputOptions.raw.width) && inputOptions.raw.width > 0 &&
185
- is.integer(inputOptions.raw.height) && inputOptions.raw.height > 0 &&
184
+ is.integer(inputOptions.raw.width) && is.inRange(inputOptions.raw.width, 1, 100000000) &&
185
+ is.integer(inputOptions.raw.height) && is.inRange(inputOptions.raw.height, 1, 100000000) &&
186
186
  is.integer(inputOptions.raw.channels) && is.inRange(inputOptions.raw.channels, 1, 4)
187
187
  ) {
188
188
  inputDescriptor.rawWidth = inputOptions.raw.width;
@@ -329,8 +329,8 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
329
329
  if (is.defined(inputOptions.create)) {
330
330
  if (
331
331
  is.object(inputOptions.create) &&
332
- is.integer(inputOptions.create.width) && inputOptions.create.width > 0 &&
333
- is.integer(inputOptions.create.height) && inputOptions.create.height > 0 &&
332
+ is.integer(inputOptions.create.width) && is.inRange(inputOptions.create.width, 1, 100000000) &&
333
+ is.integer(inputOptions.create.height) && is.inRange(inputOptions.create.height, 1, 100000000) &&
334
334
  is.integer(inputOptions.create.channels)
335
335
  ) {
336
336
  inputDescriptor.createWidth = inputOptions.create.width;
package/dist/input.mjs CHANGED
@@ -181,8 +181,8 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
181
181
  if (is.defined(inputOptions.raw)) {
182
182
  if (
183
183
  is.object(inputOptions.raw) &&
184
- is.integer(inputOptions.raw.width) && inputOptions.raw.width > 0 &&
185
- is.integer(inputOptions.raw.height) && inputOptions.raw.height > 0 &&
184
+ is.integer(inputOptions.raw.width) && is.inRange(inputOptions.raw.width, 1, 100000000) &&
185
+ is.integer(inputOptions.raw.height) && is.inRange(inputOptions.raw.height, 1, 100000000) &&
186
186
  is.integer(inputOptions.raw.channels) && is.inRange(inputOptions.raw.channels, 1, 4)
187
187
  ) {
188
188
  inputDescriptor.rawWidth = inputOptions.raw.width;
@@ -329,8 +329,8 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
329
329
  if (is.defined(inputOptions.create)) {
330
330
  if (
331
331
  is.object(inputOptions.create) &&
332
- is.integer(inputOptions.create.width) && inputOptions.create.width > 0 &&
333
- is.integer(inputOptions.create.height) && inputOptions.create.height > 0 &&
332
+ is.integer(inputOptions.create.width) && is.inRange(inputOptions.create.width, 1, 100000000) &&
333
+ is.integer(inputOptions.create.height) && is.inRange(inputOptions.create.height, 1, 100000000) &&
334
334
  is.integer(inputOptions.create.channels)
335
335
  ) {
336
336
  inputDescriptor.createWidth = inputOptions.create.width;
@@ -178,7 +178,13 @@ function flop (flop) {
178
178
  * @throws {Error} Invalid parameters
179
179
  */
180
180
  function affine (matrix, options) {
181
- const flatMatrix = Array.isArray(matrix) ? [].concat(...matrix) : [];
181
+ const isValidShape = Array.isArray(matrix) && (
182
+ // 1x4 array of numbers
183
+ (matrix.length === 4 && matrix.every(is.number)) ||
184
+ // 2x2 array of arrays of numbers
185
+ (matrix.length === 2 && matrix.every((row) => Array.isArray(row) && row.length === 2))
186
+ );
187
+ const flatMatrix = isValidShape ? matrix.flat() : [];
182
188
  if (flatMatrix.length === 4 && flatMatrix.every(is.number)) {
183
189
  this.options.affineMatrix = flatMatrix;
184
190
  } else {
@@ -860,13 +866,14 @@ function recomb (inputMatrix) {
860
866
  if (!Array.isArray(inputMatrix)) {
861
867
  throw is.invalidParameterError('inputMatrix', 'array', inputMatrix);
862
868
  }
863
- if (inputMatrix.length !== 3 && inputMatrix.length !== 4) {
864
- throw is.invalidParameterError('inputMatrix', '3x3 or 4x4 array', inputMatrix.length);
869
+ const dimensions = inputMatrix.length;
870
+ if (dimensions !== 3 && dimensions !== 4) {
871
+ throw is.invalidParameterError('inputMatrix', '3x3 or 4x4 array', dimensions);
865
872
  }
866
- const recombMatrix = inputMatrix.flat();
867
- if (recombMatrix.length !== 9 && recombMatrix.length !== 16) {
868
- throw is.invalidParameterError('inputMatrix', 'cardinality of 9 or 16', recombMatrix.length);
873
+ if (!inputMatrix.every((row) => Array.isArray(row) && row.length === dimensions)) {
874
+ throw is.invalidParameterError('inputMatrix', `array of ${dimensions} arrays of length ${dimensions}`, inputMatrix);
869
875
  }
876
+ const recombMatrix = inputMatrix.flat();
870
877
  if (!recombMatrix.every(is.number)) {
871
878
  throw is.invalidParameterError('inputMatrix', 'array of numbers', recombMatrix);
872
879
  }
@@ -178,7 +178,13 @@ function flop (flop) {
178
178
  * @throws {Error} Invalid parameters
179
179
  */
180
180
  function affine (matrix, options) {
181
- const flatMatrix = Array.isArray(matrix) ? [].concat(...matrix) : [];
181
+ const isValidShape = Array.isArray(matrix) && (
182
+ // 1x4 array of numbers
183
+ (matrix.length === 4 && matrix.every(is.number)) ||
184
+ // 2x2 array of arrays of numbers
185
+ (matrix.length === 2 && matrix.every((row) => Array.isArray(row) && row.length === 2))
186
+ );
187
+ const flatMatrix = isValidShape ? matrix.flat() : [];
182
188
  if (flatMatrix.length === 4 && flatMatrix.every(is.number)) {
183
189
  this.options.affineMatrix = flatMatrix;
184
190
  } else {
@@ -860,13 +866,14 @@ function recomb (inputMatrix) {
860
866
  if (!Array.isArray(inputMatrix)) {
861
867
  throw is.invalidParameterError('inputMatrix', 'array', inputMatrix);
862
868
  }
863
- if (inputMatrix.length !== 3 && inputMatrix.length !== 4) {
864
- throw is.invalidParameterError('inputMatrix', '3x3 or 4x4 array', inputMatrix.length);
869
+ const dimensions = inputMatrix.length;
870
+ if (dimensions !== 3 && dimensions !== 4) {
871
+ throw is.invalidParameterError('inputMatrix', '3x3 or 4x4 array', dimensions);
865
872
  }
866
- const recombMatrix = inputMatrix.flat();
867
- if (recombMatrix.length !== 9 && recombMatrix.length !== 16) {
868
- throw is.invalidParameterError('inputMatrix', 'cardinality of 9 or 16', recombMatrix.length);
873
+ if (!inputMatrix.every((row) => Array.isArray(row) && row.length === dimensions)) {
874
+ throw is.invalidParameterError('inputMatrix', `array of ${dimensions} arrays of length ${dimensions}`, inputMatrix);
869
875
  }
876
+ const recombMatrix = inputMatrix.flat();
870
877
  if (!recombMatrix.every(is.number)) {
871
878
  throw is.invalidParameterError('inputMatrix', 'array of numbers', recombMatrix);
872
879
  }
package/dist/resize.cjs CHANGED
@@ -471,10 +471,10 @@ function extend (extend) {
471
471
  * });
472
472
  *
473
473
  * @param {Object} options - describes the region to extract using integral pixel values
474
- * @param {number} options.left - zero-indexed offset from left edge
475
- * @param {number} options.top - zero-indexed offset from top edge
476
- * @param {number} options.width - width of region to extract
477
- * @param {number} options.height - height of region to extract
474
+ * @param {number} options.left - zero-indexed offset from left edge, an integer between 0 and 100000000
475
+ * @param {number} options.top - zero-indexed offset from top edge, an integer between 0 and 100000000
476
+ * @param {number} options.width - width of region to extract, an integer between 0 and 100000000
477
+ * @param {number} options.height - height of region to extract, an integer between 0 and 100000000
478
478
  * @returns {Sharp}
479
479
  * @throws {Error} Invalid parameters
480
480
  */
@@ -485,10 +485,10 @@ function extract (options) {
485
485
  }
486
486
  ['left', 'top', 'width', 'height'].forEach(function (name) {
487
487
  const value = options[name];
488
- if (is.integer(value) && value >= 0) {
488
+ if (is.integer(value) && is.inRange(value, 0, 100000000)) {
489
489
  this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value;
490
490
  } else {
491
- throw is.invalidParameterError(name, 'integer', value);
491
+ throw is.invalidParameterError(name, 'integer between 0 and 100000000', value);
492
492
  }
493
493
  }, this);
494
494
  // Ensure existing rotation occurs before pre-resize extraction
package/dist/resize.mjs CHANGED
@@ -471,10 +471,10 @@ function extend (extend) {
471
471
  * });
472
472
  *
473
473
  * @param {Object} options - describes the region to extract using integral pixel values
474
- * @param {number} options.left - zero-indexed offset from left edge
475
- * @param {number} options.top - zero-indexed offset from top edge
476
- * @param {number} options.width - width of region to extract
477
- * @param {number} options.height - height of region to extract
474
+ * @param {number} options.left - zero-indexed offset from left edge, an integer between 0 and 100000000
475
+ * @param {number} options.top - zero-indexed offset from top edge, an integer between 0 and 100000000
476
+ * @param {number} options.width - width of region to extract, an integer between 0 and 100000000
477
+ * @param {number} options.height - height of region to extract, an integer between 0 and 100000000
478
478
  * @returns {Sharp}
479
479
  * @throws {Error} Invalid parameters
480
480
  */
@@ -485,10 +485,10 @@ function extract (options) {
485
485
  }
486
486
  ['left', 'top', 'width', 'height'].forEach(function (name) {
487
487
  const value = options[name];
488
- if (is.integer(value) && value >= 0) {
488
+ if (is.integer(value) && is.inRange(value, 0, 100000000)) {
489
489
  this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value;
490
490
  } else {
491
- throw is.invalidParameterError(name, 'integer', value);
491
+ throw is.invalidParameterError(name, 'integer between 0 and 100000000', value);
492
492
  }
493
493
  }, this);
494
494
  // Ensure existing rotation occurs before pre-resize extraction
package/dist/sharp.cjs CHANGED
@@ -49,6 +49,12 @@ if (!sharp) {
49
49
  errors.push(err);
50
50
  sharp = null;
51
51
  }
52
+ if (sharp && process.versions.electron && runtimePlatform.startsWith("linux")) {
53
+ process.emitWarning(
54
+ "Binaries provided by Electron for use on Linux may be incompatible with sharp - see https://sharp.pixelplumbing.com/install#electron-and-linux",
55
+ { code: "SharpElectronLinux" }
56
+ );
57
+ }
52
58
  } catch (err) {
53
59
  errors.push(err);
54
60
  }
package/dist/sharp.mjs CHANGED
@@ -49,6 +49,12 @@ if (!sharp) {
49
49
  errors.push(err);
50
50
  sharp = null;
51
51
  }
52
+ if (sharp && process.versions.electron && runtimePlatform.startsWith("linux")) {
53
+ process.emitWarning(
54
+ "Binaries provided by Electron for use on Linux may be incompatible with sharp - see https://sharp.pixelplumbing.com/install#electron-and-linux",
55
+ { code: "SharpElectronLinux" }
56
+ );
57
+ }
52
58
  } catch (err) {
53
59
  errors.push(err);
54
60
  }
package/dist/utility.cjs CHANGED
@@ -114,6 +114,12 @@ function cache (options) {
114
114
  return sharp.cache(0, 0, 0);
115
115
  }
116
116
  } else if (is.object(options)) {
117
+ for (const property of ['memory', 'files', 'items']) {
118
+ const value = options[property];
119
+ if (is.defined(value) && !(is.integer(value) && value >= 0)) {
120
+ throw is.invalidParameterError(property, 'a positive integer', value);
121
+ }
122
+ }
117
123
  return sharp.cache(options.memory, options.files, options.items);
118
124
  } else {
119
125
  return sharp.cache();
@@ -155,7 +161,7 @@ function concurrency (concurrency) {
155
161
  return sharp.concurrency(is.integer(concurrency) ? concurrency : null);
156
162
  }
157
163
  /* node:coverage ignore next 7 */
158
- if (detectLibc.familySync() === detectLibc.GLIBC && !sharp._isUsingJemalloc()) {
164
+ if (!process.env.MALLOC_ARENA_MAX && detectLibc.familySync() === detectLibc.GLIBC && !sharp._isUsingJemalloc()) {
159
165
  // Reduce default concurrency to 1 when using glibc memory allocator
160
166
  sharp.concurrency(1);
161
167
  } else if (detectLibc.familySync() === detectLibc.MUSL && sharp.concurrency() === 1024) {
package/dist/utility.mjs CHANGED
@@ -114,6 +114,12 @@ function cache (options) {
114
114
  return sharp.cache(0, 0, 0);
115
115
  }
116
116
  } else if (is.object(options)) {
117
+ for (const property of ['memory', 'files', 'items']) {
118
+ const value = options[property];
119
+ if (is.defined(value) && !(is.integer(value) && value >= 0)) {
120
+ throw is.invalidParameterError(property, 'a positive integer', value);
121
+ }
122
+ }
117
123
  return sharp.cache(options.memory, options.files, options.items);
118
124
  } else {
119
125
  return sharp.cache();
@@ -155,7 +161,7 @@ function concurrency (concurrency) {
155
161
  return sharp.concurrency(is.integer(concurrency) ? concurrency : null);
156
162
  }
157
163
  /* node:coverage ignore next 7 */
158
- if (detectLibc.familySync() === detectLibc.GLIBC && !sharp._isUsingJemalloc()) {
164
+ if (!process.env.MALLOC_ARENA_MAX && detectLibc.familySync() === detectLibc.GLIBC && !sharp._isUsingJemalloc()) {
159
165
  // Reduce default concurrency to 1 when using glibc memory allocator
160
166
  sharp.concurrency(1);
161
167
  } else if (detectLibc.familySync() === detectLibc.MUSL && sharp.concurrency() === 1024) {
package/lib/index.d.ts CHANGED
@@ -1602,13 +1602,13 @@ declare namespace sharp {
1602
1602
  }
1603
1603
 
1604
1604
  interface Region {
1605
- /** zero-indexed offset from left edge */
1605
+ /** zero-indexed offset from left edge, an integer between 0 and 100000000 */
1606
1606
  left: number;
1607
- /** zero-indexed offset from top edge */
1607
+ /** zero-indexed offset from top edge, an integer between 0 and 100000000 */
1608
1608
  top: number;
1609
- /** dimension of extracted image */
1609
+ /** dimension of extracted image, an integer between 0 and 100000000 */
1610
1610
  width: number;
1611
- /** dimension of extracted image */
1611
+ /** dimension of extracted image, an integer between 0 and 100000000 */
1612
1612
  height: number;
1613
1613
  }
1614
1614
 
@@ -1787,6 +1787,8 @@ declare namespace sharp {
1787
1787
  channels: Channels;
1788
1788
  /** indicating if premultiplication was used */
1789
1789
  premultiplied: boolean;
1790
+ /** Indicates if the output image has an alpha channel */
1791
+ hasAlpha: boolean;
1790
1792
  /** Only defined when using a crop strategy */
1791
1793
  cropOffsetLeft?: number | undefined;
1792
1794
  /** Only defined when using a crop strategy */
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-revizly40",
4
+ "version": "0.35.0-revizly41",
5
5
  "author": "Lovell Fuller <npm@lovell.info>",
6
6
  "homepage": "https://sharp.pixelplumbing.com",
7
7
  "contributors": [
@@ -163,16 +163,16 @@
163
163
  "semver": "^7.8.5"
164
164
  },
165
165
  "optionalDependencies": {
166
- "@revizly/sharp-libvips-linux-arm64": "1.0.41",
167
- "@revizly/sharp-libvips-linux-x64": "1.0.41",
168
- "@revizly/sharp-linux-arm64": "0.35.0-revizly40",
169
- "@revizly/sharp-linux-x64": "0.35.0-revizly40"
166
+ "@revizly/sharp-libvips-linux-arm64": "1.0.42",
167
+ "@revizly/sharp-libvips-linux-x64": "1.0.42",
168
+ "@revizly/sharp-linux-arm64": "0.35.0-revizly41",
169
+ "@revizly/sharp-linux-x64": "0.35.0-revizly41"
170
170
  },
171
171
  "devDependencies": {
172
172
  "@biomejs/biome": "^2.5.1",
173
173
  "@cpplint/cli": "^0.1.0",
174
174
  "@emnapi/runtime": "^1.11.1",
175
- "@revizly/sharp-libvips-dev": "1.0.41",
175
+ "@revizly/sharp-libvips-dev": "1.0.42",
176
176
  "@types/node": "*",
177
177
  "emnapi": "^1.11.1",
178
178
  "exif-reader": "^2.0.3",
package/src/pipeline.cc CHANGED
@@ -944,6 +944,7 @@ class PipelineWorker : public Napi::AsyncWorker {
944
944
  baton->pageHeightOut = image.get_int(VIPS_META_PAGE_HEIGHT);
945
945
  baton->pagesOut = image.get_int(VIPS_META_N_PAGES);
946
946
  }
947
+ baton->hasAlphaOut = image.has_alpha();
947
948
 
948
949
  // Output
949
950
  sharp::SetTimeout(image, baton->timeoutSeconds);
@@ -983,6 +984,7 @@ class PipelineWorker : public Napi::AsyncWorker {
983
984
  } else {
984
985
  baton->channels = std::min(baton->channels, 3);
985
986
  }
987
+ baton->hasAlphaOut = false;
986
988
  } else if (baton->formatOut == "jp2" || (baton->formatOut == "input"
987
989
  && inputImageType == sharp::ImageType::JP2)) {
988
990
  // Write JP2 to Buffer
@@ -1065,6 +1067,7 @@ class PipelineWorker : public Napi::AsyncWorker {
1065
1067
  if (baton->tiffCompression == VIPS_FOREIGN_TIFF_COMPRESSION_JPEG) {
1066
1068
  sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG);
1067
1069
  baton->channels = std::min(baton->channels, 3);
1070
+ baton->hasAlphaOut = false;
1068
1071
  }
1069
1072
  // Cast pixel values to float, if required
1070
1073
  if (baton->tiffPredictor == VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT) {
@@ -1125,6 +1128,9 @@ class PipelineWorker : public Napi::AsyncWorker {
1125
1128
  area->free_fn = nullptr;
1126
1129
  vips_area_unref(area);
1127
1130
  baton->formatOut = "dz";
1131
+ if (baton->tileFormat == "jpeg") {
1132
+ baton->hasAlphaOut = false;
1133
+ }
1128
1134
  } else if (baton->formatOut == "jxl" ||
1129
1135
  (baton->formatOut == "input" && inputImageType == sharp::ImageType::JXL)) {
1130
1136
  // Write JXL to buffer
@@ -1212,6 +1218,7 @@ class PipelineWorker : public Napi::AsyncWorker {
1212
1218
  }
1213
1219
  baton->formatOut = "jpeg";
1214
1220
  baton->channels = std::min(baton->channels, 3);
1221
+ baton->hasAlphaOut = false;
1215
1222
  } else if (baton->formatOut == "jp2" || (mightMatchInput && isJp2) ||
1216
1223
  (willMatchInput && (inputImageType == sharp::ImageType::JP2))) {
1217
1224
  // Write JP2 to file
@@ -1278,6 +1285,7 @@ class PipelineWorker : public Napi::AsyncWorker {
1278
1285
  if (baton->tiffCompression == VIPS_FOREIGN_TIFF_COMPRESSION_JPEG) {
1279
1286
  sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG);
1280
1287
  baton->channels = std::min(baton->channels, 3);
1288
+ baton->hasAlphaOut = false;
1281
1289
  }
1282
1290
  // Cast pixel values to float, if required
1283
1291
  if (baton->tiffPredictor == VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT) {
@@ -1339,6 +1347,9 @@ class PipelineWorker : public Napi::AsyncWorker {
1339
1347
  vips::VOption *options = BuildOptionsDZ(baton);
1340
1348
  image.dzsave(const_cast<char*>(baton->fileOut.data()), options);
1341
1349
  baton->formatOut = "dz";
1350
+ if (baton->tileFormat == "jpeg") {
1351
+ baton->hasAlphaOut = false;
1352
+ }
1342
1353
  } else if (baton->formatOut == "v" || (mightMatchInput && isV) ||
1343
1354
  (willMatchInput && inputImageType == sharp::ImageType::VIPS)) {
1344
1355
  // Write V to file
@@ -1423,6 +1434,7 @@ class PipelineWorker : public Napi::AsyncWorker {
1423
1434
  info.Set("pageHeight", static_cast<int32_t>(baton->pageHeightOut));
1424
1435
  info.Set("pages", static_cast<int32_t>(baton->pagesOut));
1425
1436
  }
1437
+ info.Set("hasAlpha", baton->hasAlphaOut);
1426
1438
 
1427
1439
  if (baton->bufferOutLength > 0) {
1428
1440
  info.Set("size", static_cast<uint32_t>(baton->bufferOutLength));
package/src/pipeline.h CHANGED
@@ -49,6 +49,7 @@ struct PipelineBaton {
49
49
  int pageHeightOut;
50
50
  int pagesOut;
51
51
  bool typedArrayOut;
52
+ bool hasAlphaOut;
52
53
  std::vector<Composite *> composite;
53
54
  std::vector<sharp::InputDescriptor *> joinChannelIn;
54
55
  int topOffsetPre;
@@ -250,6 +251,7 @@ struct PipelineBaton {
250
251
  pageHeightOut(0),
251
252
  pagesOut(0),
252
253
  typedArrayOut(false),
254
+ hasAlphaOut(false),
253
255
  topOffsetPre(-1),
254
256
  topOffsetPost(-1),
255
257
  channels(0),
package/src/utilities.cc CHANGED
@@ -23,15 +23,15 @@ Napi::Value cache(const Napi::CallbackInfo& info) {
23
23
 
24
24
  // Set memory limit
25
25
  if (info[size_t(0)].IsNumber()) {
26
- vips_cache_set_max_mem(info[size_t(0)].As<Napi::Number>().Int32Value() * 1048576);
26
+ vips_cache_set_max_mem(static_cast<size_t>(info[size_t(0)].As<Napi::Number>().Uint32Value()) * 1048576);
27
27
  }
28
28
  // Set file limit
29
29
  if (info[size_t(1)].IsNumber()) {
30
- vips_cache_set_max_files(info[size_t(1)].As<Napi::Number>().Int32Value());
30
+ vips_cache_set_max_files(info[size_t(1)].As<Napi::Number>().Uint32Value());
31
31
  }
32
32
  // Set items limit
33
33
  if (info[size_t(2)].IsNumber()) {
34
- vips_cache_set_max(info[size_t(2)].As<Napi::Number>().Int32Value());
34
+ vips_cache_set_max(info[size_t(2)].As<Napi::Number>().Uint32Value());
35
35
  }
36
36
 
37
37
  // Get memory stats