From f19b6c48cae8da3e670b06f3c5ee2352183b2357 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Wed, 20 May 2015 20:07:32 +0100 Subject: [PATCH] Skip normalise operation for images with one colour It didn't play nicely with premultiplication --- src/composite.c | 17 ----------------- src/resize.cc | 41 ++++++++++++++++++----------------------- test/unit/normalize.js | 30 +++++++----------------------- 3 files changed, 25 insertions(+), 63 deletions(-) diff --git a/src/composite.c b/src/composite.c index f35c97ba..b712f103 100644 --- a/src/composite.c +++ b/src/composite.c @@ -128,11 +128,6 @@ int Composite(VipsObject *context, VipsImage *srcPremultiplied, VipsImage *dstPr int Premultiply(VipsObject *context, VipsImage *image, VipsImage **out) { VipsImage *imagePremultiplied; - // Trivial case: Copy images without alpha channel: - if (!HasAlpha(image)) { - return vips_image_write(image, *out); - } - #if (VIPS_MAJOR_VERSION >= 9 || (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 1)) if (vips_premultiply(image, &imagePremultiplied, NULL)) @@ -140,9 +135,6 @@ int Premultiply(VipsObject *context, VipsImage *image, VipsImage **out) { #else - if (image->Bands != 4) - return -1; - VipsImage *imageRGB; if (vips_extract_band(image, &imageRGB, 0, "n", NUM_COLOR_BANDS, NULL)) return -1; @@ -181,11 +173,6 @@ int Premultiply(VipsObject *context, VipsImage *image, VipsImage **out) { int Unpremultiply(VipsObject *context, VipsImage *image, VipsImage **out) { VipsImage *imageUnpremultiplied; - // Trivial case: Copy images without alpha channel: - if (!HasAlpha(image)) { - return vips_image_write(image, *out); - } - #if (VIPS_MAJOR_VERSION >= 9 || (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 1)) if (vips_unpremultiply(image, &imageUnpremultiplied, NULL)) @@ -193,9 +180,6 @@ int Unpremultiply(VipsObject *context, VipsImage *image, VipsImage **out) { #else - if (image->Bands != 4) - return -1; - VipsImage *imageRGBPremultipliedTransformed; if (vips_extract_band(image, &imageRGBPremultipliedTransformed, 0, "n", NUM_COLOR_BANDS, NULL)) return -1; @@ -219,7 +203,6 @@ int Unpremultiply(VipsObject *context, VipsImage *image, VipsImage **out) { if (vips_bandjoin2(imageRGBUnpremultipliedTransformed, imageAlphaTransformed, &imageUnpremultiplied, NULL)) return -1; - #endif // Return a reference to the unpremultiplied output image: diff --git a/src/resize.cc b/src/resize.cc index 3f329729..608f26b8 100755 --- a/src/resize.cc +++ b/src/resize.cc @@ -763,17 +763,10 @@ class ResizeWorker : public NanAsyncWorker { return Error(); } vips_object_local(hook, stats); + double min = *VIPS_MATRIX(stats, 0, 0); double max = *VIPS_MATRIX(stats, 1, 0); - - VipsImage *normalized; - if (min == max) { - // Range of zero: create black image - if (vips_black(&normalized, image->Xsize, image->Ysize, "bands", 1, NULL )) { - return Error(); - } - vips_object_local(hook, normalized); - } else { + if (min != max) { double f = 100.0 / (max - min); double a = -(min * f); @@ -788,27 +781,29 @@ class ResizeWorker : public NanAsyncWorker { return Error(); } vips_object_local(hook, normalizedLab); + + VipsImage *normalized; if (vips_colourspace(normalizedLab, &normalized, typeBeforeNormalize, NULL)) { return Error(); } vips_object_local(hook, normalized); - } - if (HasAlpha(image)) { - VipsImage *alpha; - if (vips_extract_band(image, &alpha, image->Bands - 1, "n", 1, NULL)) { - return Error(); - } - vips_object_local(hook, alpha); + if (HasAlpha(image)) { + VipsImage *alpha; + if (vips_extract_band(image, &alpha, image->Bands - 1, "n", 1, NULL)) { + return Error(); + } + vips_object_local(hook, alpha); - VipsImage *normalizedAlpha; - if (vips_bandjoin2(normalized, alpha, &normalizedAlpha, NULL)) { - return Error(); + VipsImage *normalizedAlpha; + if (vips_bandjoin2(normalized, alpha, &normalizedAlpha, NULL)) { + return Error(); + } + vips_object_local(hook, normalizedAlpha); + image = normalizedAlpha; + } else { + image = normalized; } - vips_object_local(hook, normalizedAlpha); - image = normalizedAlpha; - } else { - image = normalized; } } #endif diff --git a/test/unit/normalize.js b/test/unit/normalize.js index 2f144a68..deda0851 100755 --- a/test/unit/normalize.js +++ b/test/unit/normalize.js @@ -98,31 +98,15 @@ describe('Normalization', function () { }); }); - it('returns a black image for images with only one color', function (done) { + it('does not alter images with only one color', function (done) { + var output = fixtures.path('output.unmodified-png-with-one-color.png'); sharp(fixtures.inputPngWithOneColor) .normalize() - .toBuffer() - .bind({}) - .then(function (imageData) { - this.imageData = imageData; - return sharp(imageData) - .metadata(); - }) - .then(function (metadata) { - assert.strictEqual(false, metadata.hasAlpha); - assert.strictEqual(3, metadata.channels); - assert.strictEqual('srgb', metadata.space); - }) - .then(function () { - return sharp(this.imageData) - .raw() - .toBuffer(); - }) - .then(function (rawData) { - var blackBuffer = new Buffer([0,0,0, 0,0,0, 0,0,0, 0,0,0]); - assert.strictEqual(blackBuffer.toString(), rawData.toString()); - }) - .finally(done); + .toFile(output, function(err, info) { + if (err) done(err); + fixtures.assertMaxColourDistance(output, fixtures.inputPngWithOneColor, 0); + done(); + }); }); }