diff --git a/docs/changelog.md b/docs/changelog.md index cb682b0c6..8f80eddc8 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -4,6 +4,11 @@ Requires libvips v8.15.1 +### v0.33.3 - TBD + +* Ensure `keepIccProfile` retains CMYK input profiles. + [#3906](https://github.com/lovell/sharp/issues/3906) + ### v0.33.2 - 12th January 2024 * Upgrade to libvips v8.15.1 for upstream bug fixes. diff --git a/src/pipeline.cc b/src/pipeline.cc index 791f208bc..b4d587b02 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -776,7 +776,7 @@ class PipelineWorker : public Napi::AsyncWorker { // Convert colourspace, pass the current known interpretation so libvips doesn't have to guess image = image.colourspace(baton->colourspace, VImage::option()->set("source_space", image.interpretation())); // Transform colours from embedded profile to output profile - if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) && + if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) && baton->colourspaceInput != VIPS_INTERPRETATION_CMYK && baton->withIccProfile.empty() && sharp::HasProfile(image)) { image = image.icc_transform("srgb", VImage::option() ->set("embedded", TRUE) diff --git a/test/unit/metadata.js b/test/unit/metadata.js index 820868dde..09de787cf 100644 --- a/test/unit/metadata.js +++ b/test/unit/metadata.js @@ -576,6 +576,19 @@ describe('Image metadata', function () { assert.strictEqual(description, 'Generic RGB Profile'); }); + it('keep existing CMYK ICC profile', async () => { + const data = await sharp(fixtures.inputJpgWithCmykProfile) + .pipelineColourspace('cmyk') + .toColourspace('cmyk') + .keepIccProfile() + .toBuffer(); + + const metadata = await sharp(data).metadata(); + assert.strictEqual(metadata.channels, 4); + const { description } = icc.parse(metadata.icc); + assert.strictEqual(description, 'U.S. Web Coated (SWOP) v2'); + }); + it('transform to ICC profile and attach', async () => { const data = await sharp({ create }) .png()