Ensure ops without multi-page support reject (#3010)

This commit is contained in:
Lovell Fuller 2021-12-12 09:14:26 +00:00 committed by GitHub
parent 5bb6702717
commit 9755629cfd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 1 deletions

View File

@ -98,6 +98,7 @@ class PipelineWorker : public Napi::AsyncWorker {
image = sharp::RemoveExifOrientation(image); image = sharp::RemoveExifOrientation(image);
} }
if (baton->rotationAngle != 0.0) { if (baton->rotationAngle != 0.0) {
MultiPageUnsupported(nPages, "Rotate");
std::vector<double> background; std::vector<double> background;
std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground, FALSE); std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground, FALSE);
image = image.rotate(baton->rotationAngle, VImage::option()->set("background", background)); image = image.rotate(baton->rotationAngle, VImage::option()->set("background", background));
@ -106,6 +107,7 @@ class PipelineWorker : public Napi::AsyncWorker {
// Trim // Trim
if (baton->trimThreshold > 0.0) { if (baton->trimThreshold > 0.0) {
MultiPageUnsupported(nPages, "Trim");
image = sharp::Trim(image, baton->trimThreshold); image = sharp::Trim(image, baton->trimThreshold);
baton->trimOffsetLeft = image.xoffset(); baton->trimOffsetLeft = image.xoffset();
baton->trimOffsetTop = image.yoffset(); baton->trimOffsetTop = image.yoffset();
@ -461,8 +463,9 @@ class PipelineWorker : public Napi::AsyncWorker {
? sharp::CropMultiPage(image, ? sharp::CropMultiPage(image,
left, top, width, height, nPages, &targetPageHeight) left, top, width, height, nPages, &targetPageHeight)
: image.extract_area(left, top, width, height); : image.extract_area(left, top, width, height);
} else if (nPages == 1) { // Skip smart crop for multi-page images } else {
// Attention-based or Entropy-based crop // Attention-based or Entropy-based crop
MultiPageUnsupported(nPages, "Resize strategy");
image = image.tilecache(VImage::option() image = image.tilecache(VImage::option()
->set("access", VIPS_ACCESS_RANDOM) ->set("access", VIPS_ACCESS_RANDOM)
->set("threaded", TRUE)); ->set("threaded", TRUE));
@ -477,6 +480,7 @@ class PipelineWorker : public Napi::AsyncWorker {
// Rotate post-extract non-90 angle // Rotate post-extract non-90 angle
if (!baton->rotateBeforePreExtract && baton->rotationAngle != 0.0) { if (!baton->rotateBeforePreExtract && baton->rotationAngle != 0.0) {
MultiPageUnsupported(nPages, "Rotate");
std::vector<double> background; std::vector<double> background;
std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground, shouldPremultiplyAlpha); std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground, shouldPremultiplyAlpha);
image = image.rotate(baton->rotationAngle, VImage::option()->set("background", background)); image = image.rotate(baton->rotationAngle, VImage::option()->set("background", background));
@ -499,6 +503,7 @@ class PipelineWorker : public Napi::AsyncWorker {
// Affine transform // Affine transform
if (baton->affineMatrix.size() > 0) { if (baton->affineMatrix.size() > 0) {
MultiPageUnsupported(nPages, "Affine");
std::vector<double> background; std::vector<double> background;
std::tie(image, background) = sharp::ApplyAlpha(image, baton->affineBackground, shouldPremultiplyAlpha); std::tie(image, background) = sharp::ApplyAlpha(image, baton->affineBackground, shouldPremultiplyAlpha);
image = image.affine(baton->affineMatrix, VImage::option()->set("background", background) image = image.affine(baton->affineMatrix, VImage::option()->set("background", background)
@ -1224,6 +1229,12 @@ class PipelineWorker : public Napi::AsyncWorker {
Napi::FunctionReference debuglog; Napi::FunctionReference debuglog;
Napi::FunctionReference queueListener; Napi::FunctionReference queueListener;
void MultiPageUnsupported(int const pages, std::string op) {
if (pages > 1) {
throw vips::VError(op + " is not supported for multi-page images");
}
}
/* /*
Calculate the angle of rotation and need-to-flip for the given Exif orientation Calculate the angle of rotation and need-to-flip for the given Exif orientation
By default, returns zero, i.e. no rotation. By default, returns zero, i.e. no rotation.

View File

@ -155,6 +155,15 @@ describe('Affine transform', () => {
fixtures.assertSimilar(fixtures.expected('affine-background-all-offsets-expected.jpg'), data, done); fixtures.assertSimilar(fixtures.expected('affine-background-all-offsets-expected.jpg'), data, done);
}); });
}); });
it('Animated image rejects', () =>
assert.rejects(() => sharp(fixtures.inputGifAnimated, { animated: true })
.affine([1, 1, 1, 1])
.toBuffer(),
/Affine is not supported for multi-page images/
)
);
describe('Interpolations', () => { describe('Interpolations', () => {
const input = fixtures.inputJpg320x240; const input = fixtures.inputJpg320x240;
const inputWidth = 320; const inputWidth = 320;

View File

@ -347,6 +347,18 @@ describe('Resize fit=cover', function () {
fixtures.assertSimilar(fixtures.expected('crop-strategy.png'), data, done); fixtures.assertSimilar(fixtures.expected('crop-strategy.png'), data, done);
}); });
}); });
it('Animated image rejects', () =>
assert.rejects(() => sharp(fixtures.inputGifAnimated, { animated: true })
.resize({
width: 100,
height: 8,
position: sharp.strategy.entropy
})
.toBuffer(),
/Resize strategy is not supported for multi-page images/
)
);
}); });
describe('Attention strategy', function () { describe('Attention strategy', function () {
@ -403,5 +415,17 @@ describe('Resize fit=cover', function () {
fixtures.assertSimilar(fixtures.expected('crop-strategy.png'), data, done); fixtures.assertSimilar(fixtures.expected('crop-strategy.png'), data, done);
}); });
}); });
it('Animated image rejects', () =>
assert.rejects(() => sharp(fixtures.inputGifAnimated, { animated: true })
.resize({
width: 100,
height: 8,
position: sharp.strategy.attention
})
.toBuffer(),
/Resize strategy is not supported for multi-page images/
)
);
}); });
}); });

View File

@ -272,6 +272,34 @@ describe('Rotation', function () {
}); });
}); });
it('Animated image rotate-then-extract rejects', () =>
assert.rejects(() => sharp(fixtures.inputGifAnimated, { animated: true })
.rotate(1)
.extract({
top: 1,
left: 1,
width: 10,
height: 10
})
.toBuffer(),
/Rotate is not supported for multi-page images/
)
);
it('Animated image extract-then-rotate rejects', () =>
assert.rejects(() => sharp(fixtures.inputGifAnimated, { animated: true })
.extract({
top: 1,
left: 1,
width: 10,
height: 10
})
.rotate(1)
.toBuffer(),
/Rotate is not supported for multi-page images/
)
);
it('Flip - vertical', function (done) { it('Flip - vertical', function (done) {
sharp(fixtures.inputJpg) sharp(fixtures.inputJpg)
.resize(320) .resize(320)

View File

@ -120,6 +120,14 @@ describe('Trim borders', function () {
) )
); );
it('Animated image rejects', () =>
assert.rejects(() => sharp(fixtures.inputGifAnimated, { animated: true })
.trim()
.toBuffer(),
/Trim is not supported for multi-page images/
)
);
describe('Invalid thresholds', function () { describe('Invalid thresholds', function () {
[-1, 'fail', {}].forEach(function (threshold) { [-1, 'fail', {}].forEach(function (threshold) {
it(JSON.stringify(threshold), function () { it(JSON.stringify(threshold), function () {