From f60f7dab12c53a88faed7f4f4604d6924196fa90 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Tue, 13 Mar 2018 19:42:10 +0000 Subject: [PATCH] Prevent error when cumulative rounding below target #1154 --- docs/changelog.md | 6 ++++++ src/pipeline.cc | 6 ++++++ test/unit/crop.js | 21 ++++++++++++++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 5aec9033..eae332ac 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -4,6 +4,12 @@ Requires libvips v8.6.1. +#### v0.20.1 - TBD + +* Prevent smartcrop error when cumulative rounding is below target size. + [#1154](https://github.com/lovell/sharp/issues/1154) + [@ralrom](https://github.com/ralrom) + #### v0.20.0 - 5th March 2018 * Add support for prebuilt sharp binaries on common platforms. diff --git a/src/pipeline.cc b/src/pipeline.cc index fb6ae8b4..3a631836 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -482,6 +482,12 @@ class PipelineWorker : public Nan::AsyncWorker { image = image.extract_area(left, top, width, height); } else { // Attention-based or Entropy-based crop + if (baton->width > image.width()) { + baton->width = image.width(); + } + if (baton->height > image.height()) { + baton->height = image.height(); + } image = image.tilecache(VImage::option() ->set("access", baton->accessMethod) ->set("threaded", TRUE)); diff --git a/test/unit/crop.js b/test/unit/crop.js index 0f9f5a61..5073a3c5 100644 --- a/test/unit/crop.js +++ b/test/unit/crop.js @@ -159,7 +159,7 @@ describe('Crop', function () { }); }); - it('Skip crop when post-resize dimensions are at or below target dimensions', function () { + it('Skip crop when post-resize dimensions are at target', function () { return sharp(fixtures.inputJpg) .resize(1600, 1200) .toBuffer() @@ -177,6 +177,25 @@ describe('Crop', function () { }); }); + it('Clamp before crop when one post-resize dimension is below target', function () { + return sharp(fixtures.inputJpg) + .resize(1024, 1034) + .toBuffer() + .then(function (input) { + return sharp(input) + .rotate(270) + .resize(256) + .crop(sharp.strategy.entropy) + .toBuffer({ resolveWithObject: true }) + .then(function (result) { + assert.strictEqual(256, result.info.width); + assert.strictEqual(253, result.info.height); + assert.strictEqual(0, result.info.cropOffsetLeft); + assert.strictEqual(0, result.info.cropOffsetTop); + }); + }); + }); + describe('Entropy-based strategy', function () { it('JPEG', function (done) { sharp(fixtures.inputJpg)