diff --git a/docs/changelog.md b/docs/changelog.md index 5bcdd147..93eb1904 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,12 @@ ### v0.12 - "*look*" +#### v0.12.2 - TBD + +* Ensure 16-bit input images work with embed option. + [#325](https://github.com/lovell/sharp/issues/325) + [@janaz](https://github.com/janaz) + #### v0.12.1 - 12th December 2015 * Allow use of SIMD vector instructions (via liborc) to be toggled on/off. diff --git a/package.json b/package.json index dab15784..a26863d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sharp", - "version": "0.12.1", + "version": "0.12.2", "author": "Lovell Fuller ", "contributors": [ "Pierre Inglebert ", diff --git a/src/pipeline.cc b/src/pipeline.cc index 1558b425..91a62662 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -627,16 +627,6 @@ class PipelineWorker : public AsyncWorker { // Crop/embed if (image->Xsize != baton->width || image->Ysize != baton->height) { if (baton->canvas == Canvas::EMBED) { - // Match background colour space, namely sRGB - if (image->Type != VIPS_INTERPRETATION_sRGB) { - // Convert to sRGB colour space - VipsImage *colourspaced; - if (vips_colourspace(image, &colourspaced, VIPS_INTERPRETATION_sRGB, nullptr)) { - return Error(); - } - vips_object_local(hook, colourspaced); - image = colourspaced; - } // Add non-transparent alpha channel, if required if (baton->background[3] < 255.0 && !HasAlpha(image)) { // Create single-channel transparency @@ -661,13 +651,22 @@ class PipelineWorker : public AsyncWorker { } // Create background VipsArrayDouble *background; + // Scale up 8-bit values to match 16-bit input image + double multiplier = (image->Type == VIPS_INTERPRETATION_RGB16) ? 256.0 : 1.0; if (baton->background[3] < 255.0 || HasAlpha(image)) { - background = vips_array_double_newv( - 4, baton->background[0], baton->background[1], baton->background[2], baton->background[3] + // RGBA + background = vips_array_double_newv(4, + baton->background[0] * multiplier, + baton->background[1] * multiplier, + baton->background[2] * multiplier, + baton->background[3] * multiplier ); } else { - background = vips_array_double_newv( - 3, baton->background[0], baton->background[1], baton->background[2] + // RGB + background = vips_array_double_newv(3, + baton->background[0] * multiplier, + baton->background[1] * multiplier, + baton->background[2] * multiplier ); } // Embed diff --git a/test/fixtures/expected/embed-16bit.png b/test/fixtures/expected/embed-16bit.png new file mode 100644 index 00000000..9b49e8cb Binary files /dev/null and b/test/fixtures/expected/embed-16bit.png differ diff --git a/test/unit/embed.js b/test/unit/embed.js index e92b121e..3dd29d9f 100644 --- a/test/unit/embed.js +++ b/test/unit/embed.js @@ -68,6 +68,20 @@ describe('Embed', function() { }); }); + it('16-bit PNG with alpha channel', function(done) { + sharp(fixtures.inputPngWithTransparency16bit) + .resize(32, 16) + .embed() + .toBuffer(function(err, data, info) { + if (err) throw err; + assert.strictEqual(true, data.length > 0); + assert.strictEqual('png', info.format); + assert.strictEqual(32, info.width); + assert.strictEqual(16, info.height); + fixtures.assertSimilar(fixtures.expected('embed-16bit.png'), data, done); + }); + }); + it('Enlarge and embed', function(done) { sharp(fixtures.inputPngWithOneColor) .embed()