diff --git a/docs/changelog.md b/docs/changelog.md index a49df805a..735fc3665 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -6,6 +6,9 @@ Requires libvips v8.14.4 ### v0.32.6 - TBD +* Ensure composite tile images are fully decoded (regression in 0.32.0). + [#3767](https://github.com/lovell/sharp/issues/3767) + * Ensure `withMetadata` does not add default sRGB profile to RGB16 (regression in 0.32.5). [#3773](https://github.com/lovell/sharp/issues/3773) diff --git a/src/pipeline.cc b/src/pipeline.cc index f8b0d60eb..692870808 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -653,7 +653,7 @@ class PipelineWorker : public Napi::AsyncWorker { if (across != 0 || down != 0) { int left; int top; - compositeImage = compositeImage.replicate(across, down); + compositeImage = compositeImage.copy_memory().replicate(across, down); if (composite->hasOffset) { std::tie(left, top) = sharp::CalculateCrop( compositeImage.width(), compositeImage.height(), image.width(), image.height(), diff --git a/test/unit/composite.js b/test/unit/composite.js index e7811c755..27ac22ad0 100644 --- a/test/unit/composite.js +++ b/test/unit/composite.js @@ -472,4 +472,28 @@ describe('composite', () => { assert.strictEqual(b, 19); assert.strictEqual(a, 128); }); + + it('Ensure tiled overlay is fully decoded', async () => { + const tile = await sharp({ + create: { + width: 8, height: 513, channels: 3, background: 'red' + } + }) + .png({ compressionLevel: 0 }) + .toBuffer(); + + const { info } = await sharp({ + create: { + width: 8, height: 514, channels: 3, background: 'green' + } + }) + .composite([{ + input: tile, + tile: true + }]) + .toBuffer({ resolveWithObject: true }); + + assert.strictEqual(info.width, 8); + assert.strictEqual(info.height, 514); + }); });