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()