From 2eb03b004915688d3fc8e41a9429494a01b57acf Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sun, 11 Aug 2024 09:44:53 +0100 Subject: [PATCH] Ensure keepIccProfile avoids ICC transform #4186 --- docs/changelog.md | 3 +++ src/pipeline.cc | 1 + test/fixtures/index.js | 1 + test/fixtures/prophoto.png | Bin 0 -> 556 bytes test/unit/metadata.js | 11 +++++++++++ 5 files changed, 16 insertions(+) create mode 100644 test/fixtures/prophoto.png diff --git a/docs/changelog.md b/docs/changelog.md index aa78725ab..b198fab7c 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -29,6 +29,9 @@ Requires libvips v8.15.2 [#4172](https://github.com/lovell/sharp/pull/4172) [@marcosc90](https://github.com/marcosc90) +* Ensure `keepIccProfile` avoids colour transformation where possible. + [#4186](https://github.com/lovell/sharp/issues/4186) + ### v0.33.4 - 16th May 2024 * Remove experimental status from `pipelineColourspace`. diff --git a/src/pipeline.cc b/src/pipeline.cc index fafd695ca..ac5ead01e 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -325,6 +325,7 @@ class PipelineWorker : public Napi::AsyncWorker { if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) && baton->withIccProfile.empty()) { // Cache input profile for use with output inputProfile = sharp::GetProfile(image); + baton->input->ignoreIcc = true; } char const *processingProfile = image.interpretation() == VIPS_INTERPRETATION_RGB16 ? "p3" : "srgb"; if ( diff --git a/test/fixtures/index.js b/test/fixtures/index.js index a791ac7e8..e4b8e266e 100644 --- a/test/fixtures/index.js +++ b/test/fixtures/index.js @@ -99,6 +99,7 @@ module.exports = { inputPngTrimSpecificColour16bit: getPath('Flag_of_the_Netherlands-16bit.png'), // convert Flag_of_the_Netherlands.png -depth 16 Flag_of_the_Netherlands-16bit.png inputPngTrimSpecificColourIncludeAlpha: getPath('Flag_of_the_Netherlands-alpha.png'), // convert Flag_of_the_Netherlands.png -alpha set -background none -channel A -evaluate multiply 0.5 +channel Flag_of_the_Netherlands-alpha.png inputPngUint32Limit: getPath('65536-uint32-limit.png'), // https://alexandre.alapetite.fr/doc-alex/large-image/ + inputPngWithProPhotoProfile: getPath('prophoto.png'), inputWebP: getPath('4.webp'), // http://www.gstatic.com/webp/gallery/4.webp inputWebPWithTransparency: getPath('5_webp_a.webp'), // http://www.gstatic.com/webp/gallery3/5_webp_a.webp diff --git a/test/fixtures/prophoto.png b/test/fixtures/prophoto.png new file mode 100644 index 0000000000000000000000000000000000000000..e01fcb02a05ac9a422cf97d89ce52b37ee6b0123 GIT binary patch literal 556 zcmV+{0@MA8P)WK@`S+lSt~KmLe5g4sJ{^3WA#`h)r6fTrM}xwYL1 z`WX5KF1m8(8~6t)xb`8$Wg?TLm{hum-(u#QIp3Lc&YT0~4_?dPDy>42S`)ULa%Xo> zE`4Pg!F3*TBZ>#Pzx8w*zza6k!@&2M!|xvmx1Zf{b{4~OoEr;b4S1&XAO`UQc=O8U z?*1pRX12o?h+n`;cZToJaI>?!2c;`c-<|NAj_*%+-Eozq3QA9aR3*ysQ{a1&WD3e} zfvVNV)+N@;@)OhV_N=VNHMtoLY!ao?%T)AIwz4FT(v!Np-)J=IGCDkzW9dK|J<#Sz zt9wjp8RJ^VWSw4SGa0s<=Y_8fM|3b`bm);`$&iG!X)b& z^8D z!sdmQzE=Grk-oO3A6MO&*5ou}s18SjXb#XAG$}C}NkD-mAFmQ0jiOIMGCf%gePXJF z1o-&Wkc^*QFoVl5nZ5BJt-|}V5JH@Od-VFE@DHZhnW)0u0JZ=C010qNS#tmYB { + const [r, g, b] = await sharp(fixtures.inputPngWithProPhotoProfile) + .keepIccProfile() + .raw() + .toBuffer(); + + assert.strictEqual(r, 131); + assert.strictEqual(g, 141); + assert.strictEqual(b, 192); + }); + it('keep existing CMYK ICC profile', async () => { const data = await sharp(fixtures.inputJpgWithCmykProfile) .pipelineColourspace('cmyk')