@revizly/sharp 0.35.0-revizly45 → 0.35.0-revizly47

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.
@@ -493,7 +493,7 @@ function clone () {
493
493
  clone.options.queueListener = queueListener;
494
494
  // Pass 'finish' event to clone for Stream-based input
495
495
  if (this._isStreamInput()) {
496
- this.on('finish', () => {
496
+ this._whenStreamInFinished(() => {
497
497
  // Clone inherits input data
498
498
  this._flattenBufferIn();
499
499
  clone.options.input.buffer = this.options.input.buffer;
@@ -493,7 +493,7 @@ function clone () {
493
493
  clone.options.queueListener = queueListener;
494
494
  // Pass 'finish' event to clone for Stream-based input
495
495
  if (this._isStreamInput()) {
496
- this.on('finish', () => {
496
+ this._whenStreamInFinished(() => {
497
497
  // Clone inherits input data
498
498
  this._flattenBufferIn();
499
499
  clone.options.input.buffer = this.options.input.buffer;
package/dist/input.cjs CHANGED
@@ -531,11 +531,6 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
531
531
  function _write (chunk, _encoding, callback) {
532
532
  if (Array.isArray(this.options.input.buffer)) {
533
533
  if (is.buffer(chunk)) {
534
- if (this.options.input.buffer.length === 0) {
535
- this.on('finish', () => {
536
- this.streamInFinished = true;
537
- });
538
- }
539
534
  this.options.input.buffer.push(chunk);
540
535
  callback();
541
536
  } else {
@@ -565,6 +560,20 @@ function _isStreamInput () {
565
560
  return Array.isArray(this.options.input.buffer);
566
561
  }
567
562
 
563
+ /**
564
+ * Call fn when the Writable side of Stream-based input has finished,
565
+ * or immediately when it already has, as 'finish' is emitted only once.
566
+ * @private
567
+ * @param {Function} fn
568
+ */
569
+ function _whenStreamInFinished (fn) {
570
+ if (this.writableFinished) {
571
+ fn();
572
+ } else {
573
+ this.once('finish', fn);
574
+ }
575
+ }
576
+
568
577
  /**
569
578
  * Fast access to (uncached) image metadata without decoding any compressed pixel data.
570
579
  *
@@ -642,7 +651,7 @@ function metadata (callback) {
642
651
  const stack = Error();
643
652
  if (is.fn(callback)) {
644
653
  if (this._isStreamInput()) {
645
- this.on('finish', () => {
654
+ this._whenStreamInFinished(() => {
646
655
  this._flattenBufferIn();
647
656
  sharp.metadata(this.options, (err, metadata) => {
648
657
  if (err) {
@@ -665,7 +674,7 @@ function metadata (callback) {
665
674
  } else {
666
675
  if (this._isStreamInput()) {
667
676
  return new Promise((resolve, reject) => {
668
- const finished = () => {
677
+ this._whenStreamInFinished(() => {
669
678
  this._flattenBufferIn();
670
679
  sharp.metadata(this.options, (err, metadata) => {
671
680
  if (err) {
@@ -674,12 +683,7 @@ function metadata (callback) {
674
683
  resolve(metadata);
675
684
  }
676
685
  });
677
- };
678
- if (this.writableFinished) {
679
- finished();
680
- } else {
681
- this.once('finish', finished);
682
- }
686
+ });
683
687
  });
684
688
  } else {
685
689
  return new Promise((resolve, reject) => {
@@ -744,7 +748,7 @@ function stats (callback) {
744
748
  const stack = Error();
745
749
  if (is.fn(callback)) {
746
750
  if (this._isStreamInput()) {
747
- this.on('finish', () => {
751
+ this._whenStreamInFinished(() => {
748
752
  this._flattenBufferIn();
749
753
  sharp.stats(this.options, (err, stats) => {
750
754
  if (err) {
@@ -767,7 +771,7 @@ function stats (callback) {
767
771
  } else {
768
772
  if (this._isStreamInput()) {
769
773
  return new Promise((resolve, reject) => {
770
- this.on('finish', function () {
774
+ this._whenStreamInFinished(() => {
771
775
  this._flattenBufferIn();
772
776
  sharp.stats(this.options, (err, stats) => {
773
777
  if (err) {
@@ -805,6 +809,7 @@ module.exports = (Sharp) => {
805
809
  _write,
806
810
  _flattenBufferIn,
807
811
  _isStreamInput,
812
+ _whenStreamInFinished,
808
813
  // Public
809
814
  metadata,
810
815
  stats
package/dist/input.mjs CHANGED
@@ -531,11 +531,6 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
531
531
  function _write (chunk, _encoding, callback) {
532
532
  if (Array.isArray(this.options.input.buffer)) {
533
533
  if (is.buffer(chunk)) {
534
- if (this.options.input.buffer.length === 0) {
535
- this.on('finish', () => {
536
- this.streamInFinished = true;
537
- });
538
- }
539
534
  this.options.input.buffer.push(chunk);
540
535
  callback();
541
536
  } else {
@@ -565,6 +560,20 @@ function _isStreamInput () {
565
560
  return Array.isArray(this.options.input.buffer);
566
561
  }
567
562
 
563
+ /**
564
+ * Call fn when the Writable side of Stream-based input has finished,
565
+ * or immediately when it already has, as 'finish' is emitted only once.
566
+ * @private
567
+ * @param {Function} fn
568
+ */
569
+ function _whenStreamInFinished (fn) {
570
+ if (this.writableFinished) {
571
+ fn();
572
+ } else {
573
+ this.once('finish', fn);
574
+ }
575
+ }
576
+
568
577
  /**
569
578
  * Fast access to (uncached) image metadata without decoding any compressed pixel data.
570
579
  *
@@ -642,7 +651,7 @@ function metadata (callback) {
642
651
  const stack = Error();
643
652
  if (is.fn(callback)) {
644
653
  if (this._isStreamInput()) {
645
- this.on('finish', () => {
654
+ this._whenStreamInFinished(() => {
646
655
  this._flattenBufferIn();
647
656
  sharp.metadata(this.options, (err, metadata) => {
648
657
  if (err) {
@@ -665,7 +674,7 @@ function metadata (callback) {
665
674
  } else {
666
675
  if (this._isStreamInput()) {
667
676
  return new Promise((resolve, reject) => {
668
- const finished = () => {
677
+ this._whenStreamInFinished(() => {
669
678
  this._flattenBufferIn();
670
679
  sharp.metadata(this.options, (err, metadata) => {
671
680
  if (err) {
@@ -674,12 +683,7 @@ function metadata (callback) {
674
683
  resolve(metadata);
675
684
  }
676
685
  });
677
- };
678
- if (this.writableFinished) {
679
- finished();
680
- } else {
681
- this.once('finish', finished);
682
- }
686
+ });
683
687
  });
684
688
  } else {
685
689
  return new Promise((resolve, reject) => {
@@ -744,7 +748,7 @@ function stats (callback) {
744
748
  const stack = Error();
745
749
  if (is.fn(callback)) {
746
750
  if (this._isStreamInput()) {
747
- this.on('finish', () => {
751
+ this._whenStreamInFinished(() => {
748
752
  this._flattenBufferIn();
749
753
  sharp.stats(this.options, (err, stats) => {
750
754
  if (err) {
@@ -767,7 +771,7 @@ function stats (callback) {
767
771
  } else {
768
772
  if (this._isStreamInput()) {
769
773
  return new Promise((resolve, reject) => {
770
- this.on('finish', function () {
774
+ this._whenStreamInFinished(() => {
771
775
  this._flattenBufferIn();
772
776
  sharp.stats(this.options, (err, stats) => {
773
777
  if (err) {
@@ -805,6 +809,7 @@ export default (Sharp) => {
805
809
  _write,
806
810
  _flattenBufferIn,
807
811
  _isStreamInput,
812
+ _whenStreamInFinished,
808
813
  // Public
809
814
  metadata,
810
815
  stats
@@ -78,6 +78,10 @@ function rotate (angle, options) {
78
78
  * Auto-orient based on the EXIF `Orientation` tag, then remove the tag.
79
79
  * Mirroring is supported and may infer the use of a flip operation.
80
80
  *
81
+ * Only the EXIF `Orientation` tag is considered; orientation carried in other
82
+ * places, such as an XMP `tiff:Orientation` element, is left untouched and
83
+ * remains the responsibility of the consumer.
84
+ *
81
85
  * Previous or subsequent use of `rotate(angle)` and either `flip()` or `flop()`
82
86
  * will logically occur after auto-orientation, regardless of call order.
83
87
  *
@@ -78,6 +78,10 @@ function rotate (angle, options) {
78
78
  * Auto-orient based on the EXIF `Orientation` tag, then remove the tag.
79
79
  * Mirroring is supported and may infer the use of a flip operation.
80
80
  *
81
+ * Only the EXIF `Orientation` tag is considered; orientation carried in other
82
+ * places, such as an XMP `tiff:Orientation` element, is left untouched and
83
+ * remains the responsibility of the consumer.
84
+ *
81
85
  * Previous or subsequent use of `rotate(angle)` and either `flip()` or `flop()`
82
86
  * will logically occur after auto-orientation, regardless of call order.
83
87
  *
package/dist/output.cjs CHANGED
@@ -1656,7 +1656,7 @@ function _pipeline (callback, stack) {
1656
1656
  // output=file/buffer
1657
1657
  if (this._isStreamInput()) {
1658
1658
  // output=file/buffer, input=stream
1659
- this.on('finish', () => {
1659
+ this._whenStreamInFinished(() => {
1660
1660
  this._flattenBufferIn();
1661
1661
  sharp.pipeline(this.options, (err, data, info) => {
1662
1662
  if (err) {
@@ -1681,7 +1681,7 @@ function _pipeline (callback, stack) {
1681
1681
  // output=stream
1682
1682
  if (this._isStreamInput()) {
1683
1683
  // output=stream, input=stream
1684
- this.once('finish', () => {
1684
+ this._whenStreamInFinished(() => {
1685
1685
  this._flattenBufferIn();
1686
1686
  sharp.pipeline(this.options, (err, data, info) => {
1687
1687
  if (err) {
@@ -1694,9 +1694,6 @@ function _pipeline (callback, stack) {
1694
1694
  this.on('end', () => this.emit('close'));
1695
1695
  });
1696
1696
  });
1697
- if (this.streamInFinished) {
1698
- this.emit('finish');
1699
- }
1700
1697
  } else {
1701
1698
  // output=stream, input=file/buffer
1702
1699
  sharp.pipeline(this.options, (err, data, info) => {
@@ -1716,7 +1713,7 @@ function _pipeline (callback, stack) {
1716
1713
  if (this._isStreamInput()) {
1717
1714
  // output=promise, input=stream
1718
1715
  return new Promise((resolve, reject) => {
1719
- this.once('finish', () => {
1716
+ this._whenStreamInFinished(() => {
1720
1717
  this._flattenBufferIn();
1721
1718
  sharp.pipeline(this.options, (err, data, info) => {
1722
1719
  if (err) {
package/dist/output.mjs CHANGED
@@ -1656,7 +1656,7 @@ function _pipeline (callback, stack) {
1656
1656
  // output=file/buffer
1657
1657
  if (this._isStreamInput()) {
1658
1658
  // output=file/buffer, input=stream
1659
- this.on('finish', () => {
1659
+ this._whenStreamInFinished(() => {
1660
1660
  this._flattenBufferIn();
1661
1661
  sharp.pipeline(this.options, (err, data, info) => {
1662
1662
  if (err) {
@@ -1681,7 +1681,7 @@ function _pipeline (callback, stack) {
1681
1681
  // output=stream
1682
1682
  if (this._isStreamInput()) {
1683
1683
  // output=stream, input=stream
1684
- this.once('finish', () => {
1684
+ this._whenStreamInFinished(() => {
1685
1685
  this._flattenBufferIn();
1686
1686
  sharp.pipeline(this.options, (err, data, info) => {
1687
1687
  if (err) {
@@ -1694,9 +1694,6 @@ function _pipeline (callback, stack) {
1694
1694
  this.on('end', () => this.emit('close'));
1695
1695
  });
1696
1696
  });
1697
- if (this.streamInFinished) {
1698
- this.emit('finish');
1699
- }
1700
1697
  } else {
1701
1698
  // output=stream, input=file/buffer
1702
1699
  sharp.pipeline(this.options, (err, data, info) => {
@@ -1716,7 +1713,7 @@ function _pipeline (callback, stack) {
1716
1713
  if (this._isStreamInput()) {
1717
1714
  // output=promise, input=stream
1718
1715
  return new Promise((resolve, reject) => {
1719
- this.once('finish', () => {
1716
+ this._whenStreamInFinished(() => {
1720
1717
  this._flattenBufferIn();
1721
1718
  sharp.pipeline(this.options, (err, data, info) => {
1722
1719
  if (err) {
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-revizly45",
4
+ "version": "0.35.0-revizly47",
5
5
  "author": "Lovell Fuller <npm@lovell.info>",
6
6
  "homepage": "https://sharp.pixelplumbing.com",
7
7
  "contributors": [
@@ -163,10 +163,10 @@
163
163
  "semver": "^7.8.5"
164
164
  },
165
165
  "optionalDependencies": {
166
- "@revizly/sharp-libvips-linux-arm64": "1.0.46",
167
- "@revizly/sharp-libvips-linux-x64": "1.0.46",
168
- "@revizly/sharp-linux-arm64": "0.35.0-revizly45",
169
- "@revizly/sharp-linux-x64": "0.35.0-revizly45"
166
+ "@revizly/sharp-libvips-linux-arm64": "1.0.48",
167
+ "@revizly/sharp-libvips-linux-x64": "1.0.48",
168
+ "@revizly/sharp-linux-arm64": "0.35.0-revizly47",
169
+ "@revizly/sharp-linux-x64": "0.35.0-revizly47"
170
170
  },
171
171
  "peerDependenciesMeta": {
172
172
  "@types/node": {
@@ -177,7 +177,7 @@
177
177
  "@biomejs/biome": "^2.5.5",
178
178
  "@cpplint/cli": "^0.1.0",
179
179
  "@emnapi/runtime": "^1.11.2",
180
- "@revizly/sharp-libvips-dev": "1.0.46",
180
+ "@revizly/sharp-libvips-dev": "1.0.48",
181
181
  "@types/node": "*",
182
182
  "emnapi": "^1.11.2",
183
183
  "exif-reader": "^2.0.3",
package/src/common.cc CHANGED
@@ -711,9 +711,12 @@ namespace sharp {
711
711
  bool hasDelay = !delay.empty();
712
712
  VImage copy = image.copy();
713
713
 
714
- // Only set page-height if we have more than one page, or this could
715
- // accidentally turn into an animated image later.
716
- if (nPages > 1) copy.set(VIPS_META_PAGE_HEIGHT, pageHeight);
714
+ // Only set page-height and n-pages if we have more than one page, or this
715
+ // could accidentally turn into an animated image later.
716
+ if (nPages > 1) {
717
+ copy.set(VIPS_META_PAGE_HEIGHT, pageHeight);
718
+ copy.set(VIPS_META_N_PAGES, nPages);
719
+ }
717
720
  if (hasDelay) {
718
721
  if (delay.size() == 1) {
719
722
  // We have just one delay, repeat that value for all frames.