diff --git a/docs/changelog.md b/docs/changelog.md index ec4ac5a7..59d52d6d 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -9,6 +9,9 @@ Requires libvips v8.14.2 * Ensure use of `flip` operation forces random access read (regression in 0.32.0). [#3600](https://github.com/lovell/sharp/issues/3600) +* Ensure `linear` operation works with 16-bit input (regression in 0.31.3). + [#3605](https://github.com/lovell/sharp/issues/3605) + ### v0.32.0 - 24th March 2023 * Default to using sequential rather than random access read where possible. diff --git a/src/operations.cc b/src/operations.cc index ea8652ec..026a0ffd 100644 --- a/src/operations.cc +++ b/src/operations.cc @@ -332,12 +332,13 @@ namespace sharp { if (a.size() > bands) { throw VError("Band expansion using linear is unsupported"); } + bool const uchar = !Is16Bit(image.interpretation()); if (HasAlpha(image) && a.size() != bands && (a.size() == 1 || a.size() == bands - 1 || bands - 1 == 1)) { // Separate alpha channel VImage alpha = image[bands - 1]; - return RemoveAlpha(image).linear(a, b, VImage::option()->set("uchar", TRUE)).bandjoin(alpha); + return RemoveAlpha(image).linear(a, b, VImage::option()->set("uchar", uchar)).bandjoin(alpha); } else { - return image.linear(a, b, VImage::option()->set("uchar", TRUE)); + return image.linear(a, b, VImage::option()->set("uchar", uchar)); } } diff --git a/test/fixtures/expected/linear-16bit.png b/test/fixtures/expected/linear-16bit.png new file mode 100644 index 00000000..3e7bfc52 Binary files /dev/null and b/test/fixtures/expected/linear-16bit.png differ diff --git a/test/unit/linear.js b/test/unit/linear.js index 05bdad88..d668aabd 100644 --- a/test/unit/linear.js +++ b/test/unit/linear.js @@ -51,6 +51,16 @@ describe('Linear adjustment', function () { }); }); + it('applies linear levels adjustment to 16-bit w alpha ch', function (done) { + sharp(fixtures.inputPngWithTransparency16bit) + .linear(a, b) + .png({ compressionLevel: 0 }) + .toBuffer(function (err, data) { + if (err) throw err; + fixtures.assertSimilar(fixtures.expected('linear-16bit.png'), data, done); + }); + }); + it('applies slope level adjustment w alpha ch', function (done) { sharp(fixtures.inputPngOverlayLayer1) .resize(240)