From 2deced0fb93f51667d75250457f08d3d62f5207d Mon Sep 17 00:00:00 2001 From: Max Gordon Date: Sun, 31 Oct 2021 22:22:35 +0100 Subject: [PATCH] Ensure 16-bit PNG output uses correct bitdepth #2958 --- src/pipeline.cc | 4 ++-- test/unit/png.js | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/pipeline.cc b/src/pipeline.cc index 270c7424..0cb161f5 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -824,7 +824,7 @@ class PipelineWorker : public Napi::AsyncWorker { ->set("filter", baton->pngAdaptiveFiltering ? VIPS_FOREIGN_PNG_FILTER_ALL : VIPS_FOREIGN_PNG_FILTER_NONE) ->set("palette", baton->pngPalette) ->set("Q", baton->pngQuality) - ->set("bitdepth", baton->pngBitdepth) + ->set("bitdepth", sharp::Is16Bit(image.interpretation()) ? 16 : baton->pngBitdepth) ->set("dither", baton->pngDither))); baton->bufferOut = static_cast(area->data); baton->bufferOutLength = area->length; @@ -993,7 +993,7 @@ class PipelineWorker : public Napi::AsyncWorker { ->set("filter", baton->pngAdaptiveFiltering ? VIPS_FOREIGN_PNG_FILTER_ALL : VIPS_FOREIGN_PNG_FILTER_NONE) ->set("palette", baton->pngPalette) ->set("Q", baton->pngQuality) - ->set("bitdepth", baton->pngBitdepth) + ->set("bitdepth", sharp::Is16Bit(image.interpretation()) ? 16 : baton->pngBitdepth) ->set("dither", baton->pngDither)); baton->formatOut = "png"; } else if (baton->formatOut == "webp" || (mightMatchInput && isWebp) || diff --git a/test/unit/png.js b/test/unit/png.js index 99694133..19d9c1f2 100644 --- a/test/unit/png.js +++ b/test/unit/png.js @@ -112,6 +112,18 @@ describe('PNG', function () { }); }); + it('16-bit grey+alpha PNG roundtrip', async () => { + const after = await sharp(fixtures.inputPng16BitGreyAlpha) + .toColourspace('grey16') + .toBuffer(); + + const [statsBefore, statsAfter] = await Promise.all([ + sharp(fixtures.inputPng16BitGreyAlpha).stats(), + sharp(after).stats() + ]); + assert.deepStrictEqual(statsAfter.channels[1], statsBefore.channels[1]); + }); + it('Valid PNG libimagequant palette value does not throw error', function () { assert.doesNotThrow(function () { sharp().png({ palette: false });