From b369c4bb8a52db0072b46cffd974d4964ff12860 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Thu, 17 Sep 2020 11:08:52 +0100 Subject: [PATCH] Ensure stats can be calculated for 1x1 input #2372 --- docs/changelog.md | 3 +++ src/stats.cc | 14 ++++++++------ test/unit/stats.js | 13 +++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index b0c2dd14..1364a70f 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -18,6 +18,9 @@ Requires libvips v8.10.0 [#2369](https://github.com/lovell/sharp/pull/2369) [@AcrylicShrimp](https://github.com/AcrylicShrimp) +* Ensure `stats` can be calculated for 1x1 input. + [#2372](https://github.com/lovell/sharp/issues/2372) + ### v0.26.0 - 25th August 2020 * Prebuilt libvips binaries are now statically-linked and Brotli-compressed, requiring Node.js 10.16.0+. diff --git a/src/stats.cc b/src/stats.cc index bc5ee13e..1d7942b1 100644 --- a/src/stats.cc +++ b/src/stats.cc @@ -80,12 +80,14 @@ class StatsWorker : public Napi::AsyncWorker { // Estimate entropy via histogram of greyscale value frequency baton->entropy = std::abs(greyscale.hist_find().hist_entropy()); // Estimate sharpness via standard deviation of greyscale laplacian - VImage laplacian = VImage::new_matrixv(3, 3, - 0.0, 1.0, 0.0, - 1.0, -4.0, 1.0, - 0.0, 1.0, 0.0); - laplacian.set("scale", 9.0); - baton->sharpness = greyscale.conv(laplacian).deviate(); + if (image.width() > 1 || image.height() > 1) { + VImage laplacian = VImage::new_matrixv(3, 3, + 0.0, 1.0, 0.0, + 1.0, -4.0, 1.0, + 0.0, 1.0, 0.0); + laplacian.set("scale", 9.0); + baton->sharpness = greyscale.conv(laplacian).deviate(); + } // Most dominant sRGB colour via 4096-bin 3D histogram vips::VImage hist = sharp::RemoveAlpha(image) .colourspace(VIPS_INTERPRETATION_sRGB) diff --git a/test/unit/stats.js b/test/unit/stats.js index b456ca9c..6b1d8ee5 100644 --- a/test/unit/stats.js +++ b/test/unit/stats.js @@ -462,6 +462,19 @@ describe('Image Stats', function () { }) ); + it('Entropy and sharpness of 1x1 input are zero', async () => { + const { entropy, sharpness } = await sharp({ + create: { + width: 1, + height: 1, + channels: 3, + background: 'red' + } + }).stats(); + assert.strictEqual(entropy, 0); + assert.strictEqual(sharpness, 0); + }); + it('Stream in, Callback out', function (done) { const readable = fs.createReadStream(fixtures.inputJpg); const pipeline = sharp().stats(function (err, stats) {