diff --git a/package.json b/package.json index ad0ec609..214479c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sharp", - "version": "0.11.0", + "version": "0.11.1", "author": "Lovell Fuller ", "contributors": [ "Pierre Inglebert ", @@ -51,7 +51,7 @@ "semver": "^5.0.1" }, "devDependencies": { - "async": "^1.3.0", + "async": "^1.4.2", "coveralls": "^2.11.2", "exif-reader": "1.0.0", "icc": "^0.0.2", diff --git a/src/pipeline.cc b/src/pipeline.cc index e0e2ce08..05567249 100755 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -445,7 +445,7 @@ class PipelineWorker : public NanAsyncWorker { } // Gamma encoding (darken) - if (baton->gamma >= 1 && baton->gamma <= 3) { + if (baton->gamma >= 1 && baton->gamma <= 3 && !HasAlpha(image)) { VipsImage *gammaEncoded; if (vips_gamma(image, &gammaEncoded, "exponent", 1.0 / baton->gamma, NULL)) { return Error(); @@ -493,11 +493,9 @@ class PipelineWorker : public NanAsyncWorker { } bool shouldAffineTransform = xresidual != 0.0 || yresidual != 0.0; - bool shouldBlur = baton->blurSigma != 0.0; - bool shouldSharpen = baton->sharpenRadius != 0; - bool shouldTransform = shouldAffineTransform || shouldBlur || shouldSharpen; + bool willConvolve = baton->blurSigma > 0.0 || baton->sharpenRadius > 0; bool hasOverlay = !baton->overlayPath.empty(); - bool shouldPremultiplyAlpha = HasAlpha(image) && image->Bands == 4 && (shouldTransform || hasOverlay); + bool shouldPremultiplyAlpha = HasAlpha(image) && (shouldAffineTransform || willConvolve || hasOverlay); // Premultiply image alpha channel before all transformations to avoid // dark fringing around bright pixels @@ -681,7 +679,7 @@ class PipelineWorker : public NanAsyncWorker { } // Blur - if (shouldBlur) { + if (baton->blurSigma != 0.0) { VipsImage *blurred; if (Blur(hook, image, &blurred, baton->blurSigma)) { return Error(); @@ -690,7 +688,7 @@ class PipelineWorker : public NanAsyncWorker { } // Sharpen - if (shouldSharpen) { + if (baton->sharpenRadius != 0) { VipsImage *sharpened; if (Sharpen(hook, image, &sharpened, baton->sharpenRadius, baton->sharpenFlat, baton->sharpenJagged)) { return Error(); @@ -698,25 +696,6 @@ class PipelineWorker : public NanAsyncWorker { image = sharpened; } - // Gamma decoding (brighten) - if (baton->gamma >= 1 && baton->gamma <= 3) { - VipsImage *gammaDecoded; - if (vips_gamma(image, &gammaDecoded, "exponent", baton->gamma, NULL)) { - return Error(); - } - vips_object_local(hook, gammaDecoded); - image = gammaDecoded; - } - - // Apply normalization - stretch luminance to cover full dynamic range - if (baton->normalize) { - VipsImage *normalized; - if (Normalize(hook, image, &normalized)) { - return Error(); - } - image = normalized; - } - // Composite with overlay, if present if (hasOverlay) { VipsImage *overlayImage = NULL; @@ -789,6 +768,25 @@ class PipelineWorker : public NanAsyncWorker { image = imageUnpremultiplied; } + // Gamma decoding (brighten) + if (baton->gamma >= 1 && baton->gamma <= 3 && !HasAlpha(image)) { + VipsImage *gammaDecoded; + if (vips_gamma(image, &gammaDecoded, "exponent", baton->gamma, NULL)) { + return Error(); + } + vips_object_local(hook, gammaDecoded); + image = gammaDecoded; + } + + // Apply normalization - stretch luminance to cover full dynamic range + if (baton->normalize) { + VipsImage *normalized; + if (Normalize(hook, image, &normalized)) { + return Error(); + } + image = normalized; + } + // Convert image to sRGB, if not already if (image->Type != VIPS_INTERPRETATION_sRGB) { // Switch interpretation to sRGB diff --git a/test/fixtures/expected/gamma-0.0.jpg b/test/fixtures/expected/gamma-0.0.jpg new file mode 100644 index 00000000..59daf1ac Binary files /dev/null and b/test/fixtures/expected/gamma-0.0.jpg differ diff --git a/test/fixtures/expected/gamma-2.2.jpg b/test/fixtures/expected/gamma-2.2.jpg new file mode 100644 index 00000000..1e876f98 Binary files /dev/null and b/test/fixtures/expected/gamma-2.2.jpg differ diff --git a/test/fixtures/expected/gamma-3.0.jpg b/test/fixtures/expected/gamma-3.0.jpg new file mode 100644 index 00000000..88048ba2 Binary files /dev/null and b/test/fixtures/expected/gamma-3.0.jpg differ diff --git a/test/fixtures/expected/gamma-alpha.jpg b/test/fixtures/expected/gamma-alpha.jpg new file mode 100644 index 00000000..08b54565 Binary files /dev/null and b/test/fixtures/expected/gamma-alpha.jpg differ diff --git a/test/unit/gamma.js b/test/unit/gamma.js index 350a9ef9..b109e28e 100755 --- a/test/unit/gamma.js +++ b/test/unit/gamma.js @@ -12,32 +12,53 @@ describe('Gamma correction', function() { it('value of 0.0 (disabled)', function(done) { sharp(fixtures.inputJpgWithGammaHoliness) .resize(129, 111) - .toFile(fixtures.path('output.gamma-0.0.jpg'), done); + .toBuffer(function(err, data, info) { + assert.strictEqual('jpeg', info.format); + assert.strictEqual(129, info.width); + assert.strictEqual(111, info.height); + fixtures.assertSimilar(fixtures.expected('gamma-0.0.jpg'), data, done); + }); }); it('value of 2.2 (default)', function(done) { sharp(fixtures.inputJpgWithGammaHoliness) .resize(129, 111) .gamma() - .toFile(fixtures.path('output.gamma-2.2.jpg'), done); + .toBuffer(function(err, data, info) { + assert.strictEqual('jpeg', info.format); + assert.strictEqual(129, info.width); + assert.strictEqual(111, info.height); + fixtures.assertSimilar(fixtures.expected('gamma-2.2.jpg'), data, done); + }); }); it('value of 3.0', function(done) { sharp(fixtures.inputJpgWithGammaHoliness) .resize(129, 111) .gamma(3) - .toFile(fixtures.path('output.gamma-3.0.jpg'), done); + .toBuffer(function(err, data, info) { + assert.strictEqual('jpeg', info.format); + assert.strictEqual(129, info.width); + assert.strictEqual(111, info.height); + fixtures.assertSimilar(fixtures.expected('gamma-3.0.jpg'), data, done); + }); }); - it('invalid value', function(done) { - var isValid = true; - try { + it('alpha transparency', function(done) { + sharp(fixtures.inputPngOverlayLayer1) + .resize(320) + .gamma() + .toBuffer(function(err, data, info) { + assert.strictEqual('png', info.format); + assert.strictEqual(320, info.width); + fixtures.assertSimilar(fixtures.expected('gamma-alpha.jpg'), data, done); + }); + }); + + it('invalid value', function() { + assert.throws(function() { sharp(fixtures.inputJpgWithGammaHoliness).gamma(4); - } catch (err) { - isValid = false; - } - assert.strictEqual(false, isValid); - done(); + }); }); });