Skip to content

Commit cbf68c1

Browse files
committed
Improve error for unsupported multi-page rotation #3940
1 parent 45e8071 commit cbf68c1

File tree

5 files changed

+34
-0
lines changed

5 files changed

+34
-0
lines changed

docs/api-operation.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ The use of `rotate` without an angle will remove the EXIF `Orientation` tag, if
1818
Only one rotation can occur per pipeline.
1919
Previous calls to `rotate` in the same pipeline will be ignored.
2020

21+
Multi-page images can only be rotated by 180 degrees.
22+
2123
Method order is important when rotating, resizing and/or extracting regions,
2224
for example `.rotate(x).extract(y)` will produce a different result to `.extract(y).rotate(x)`.
2325

docs/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Requires libvips v8.15.0
1313
* Ensure `extend` operation stays sequential when copying (regression in 0.32.0).
1414
[#3928](https://github.com/lovell/sharp/issues/3928)
1515

16+
* Improve error handling for unsupported multi-page rotation.
17+
[#3940](https://github.com/lovell/sharp/issues/3940)
18+
1619
### v0.33.1 - 17th December 2023
1720

1821
* Add support for Yarn Plug'n'Play filesystem layout.

lib/operation.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const is = require('./is');
2424
* Only one rotation can occur per pipeline.
2525
* Previous calls to `rotate` in the same pipeline will be ignored.
2626
*
27+
* Multi-page images can only be rotated by 180 degrees.
28+
*
2729
* Method order is important when rotating, resizing and/or extracting regions,
2830
* for example `.rotate(x).extract(y)` will produce a different result to `.extract(y).rotate(x)`.
2931
*

src/pipeline.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ class PipelineWorker : public Napi::AsyncWorker {
9696
baton->rotationAngle != 0.0);
9797

9898
if (autoRotation != VIPS_ANGLE_D0) {
99+
if (autoRotation != VIPS_ANGLE_D180) {
100+
MultiPageUnsupported(nPages, "Rotate");
101+
}
99102
image = image.rot(autoRotation);
100103
autoRotation = VIPS_ANGLE_D0;
101104
}
@@ -114,6 +117,9 @@ class PipelineWorker : public Napi::AsyncWorker {
114117
baton->flop = FALSE;
115118
}
116119
if (rotation != VIPS_ANGLE_D0) {
120+
if (rotation != VIPS_ANGLE_D180) {
121+
MultiPageUnsupported(nPages, "Rotate");
122+
}
117123
image = image.rot(rotation);
118124
rotation = VIPS_ANGLE_D0;
119125
}
@@ -397,6 +403,9 @@ class PipelineWorker : public Napi::AsyncWorker {
397403
rotation != VIPS_ANGLE_D0);
398404
// Auto-rotate post-extract
399405
if (autoRotation != VIPS_ANGLE_D0) {
406+
if (autoRotation != VIPS_ANGLE_D180) {
407+
MultiPageUnsupported(nPages, "Rotate");
408+
}
400409
image = image.rot(autoRotation);
401410
}
402411
// Mirror vertically (up-down) about the x-axis
@@ -409,6 +418,9 @@ class PipelineWorker : public Napi::AsyncWorker {
409418
}
410419
// Rotate post-extract 90-angle
411420
if (rotation != VIPS_ANGLE_D0) {
421+
if (rotation != VIPS_ANGLE_D180) {
422+
MultiPageUnsupported(nPages, "Rotate");
423+
}
412424
image = image.rot(rotation);
413425
}
414426

test/unit/rotate.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,21 @@ describe('Rotation', function () {
353353
)
354354
);
355355

356+
it('Animated image rotate 180', () =>
357+
assert.doesNotReject(() => sharp(fixtures.inputGifAnimated, { animated: true })
358+
.rotate(180)
359+
.toBuffer()
360+
)
361+
);
362+
363+
it('Animated image rotate non-180 rejects', () =>
364+
assert.rejects(() => sharp(fixtures.inputGifAnimated, { animated: true })
365+
.rotate(90)
366+
.toBuffer(),
367+
/Rotate is not supported for multi-page images/
368+
)
369+
);
370+
356371
it('Multiple rotate emits warning', () => {
357372
let warningMessage = '';
358373
const s = sharp();

0 commit comments

Comments
 (0)