Skip to content

Commit 9c217ab

Browse files
committed
Ensure withMetadata can add RGB16 profiles #3773
1 parent e7381e5 commit 9c217ab

File tree

3 files changed

+42
-14
lines changed

3 files changed

+42
-14
lines changed

docs/changelog.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ Requires libvips v8.14.4
99
* Ensure composite tile images are fully decoded (regression in 0.32.0).
1010
[#3767](https://github.com/lovell/sharp/issues/3767)
1111

12-
* Ensure `withMetadata` does not add default sRGB profile to RGB16 (regression in 0.32.5).
12+
* Ensure `withMetadata` can add ICC profiles to RGB16 output.
13+
[#3773](https://github.com/lovell/sharp/issues/3773)
14+
15+
* Ensure `withMetadata` does not reduce 16-bit images to 8-bit (regression in 0.32.5).
1316
[#3773](https://github.com/lovell/sharp/issues/3773)
1417

1518
### v0.32.5 - 15th August 2023

src/pipeline.cc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ class PipelineWorker : public Napi::AsyncWorker {
326326
try {
327327
image = image.icc_transform(processingProfile, VImage::option()
328328
->set("embedded", TRUE)
329-
->set("depth", image.interpretation() == VIPS_INTERPRETATION_RGB16 ? 16 : 8)
329+
->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
330330
->set("intent", VIPS_INTENT_PERCEPTUAL));
331331
} catch(...) {
332332
sharp::VipsWarningCallback(nullptr, G_LOG_LEVEL_WARNING, "Invalid embedded profile", nullptr);
@@ -763,6 +763,7 @@ class PipelineWorker : public Napi::AsyncWorker {
763763
if (baton->withMetadata && sharp::HasProfile(image) && baton->withMetadataIcc.empty()) {
764764
image = image.icc_transform("srgb", VImage::option()
765765
->set("embedded", TRUE)
766+
->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
766767
->set("intent", VIPS_INTENT_PERCEPTUAL));
767768
}
768769
}
@@ -789,14 +790,13 @@ class PipelineWorker : public Napi::AsyncWorker {
789790

790791
// Apply output ICC profile
791792
if (baton->withMetadata) {
792-
if (image.interpretation() == VIPS_INTERPRETATION_sRGB || !baton->withMetadataIcc.empty()) {
793-
image = image.icc_transform(
794-
baton->withMetadataIcc.empty() ? "srgb" : const_cast<char*>(baton->withMetadataIcc.data()),
795-
VImage::option()
796-
->set("input_profile", processingProfile)
797-
->set("embedded", TRUE)
798-
->set("intent", VIPS_INTENT_PERCEPTUAL));
799-
}
793+
image = image.icc_transform(
794+
baton->withMetadataIcc.empty() ? "srgb" : const_cast<char*>(baton->withMetadataIcc.data()),
795+
VImage::option()
796+
->set("input_profile", processingProfile)
797+
->set("embedded", TRUE)
798+
->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
799+
->set("intent", VIPS_INTENT_PERCEPTUAL));
800800
}
801801
// Override EXIF Orientation tag
802802
if (baton->withMetadata && baton->withMetadataOrientation != -1) {

test/unit/metadata.js

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -794,15 +794,40 @@ describe('Image metadata', function () {
794794
assert.strictEqual(intent, 'Perceptual');
795795
});
796796

797-
it('withMetadata does not add default sRGB profile to RGB16', async () => {
798-
const data = await sharp(fixtures.inputJpg)
799-
.resize(32, 24)
797+
it('withMetadata adds default sRGB profile to RGB16', async () => {
798+
const data = await sharp({
799+
create: {
800+
width: 8, height: 8, channels: 4, background: 'orange'
801+
}
802+
})
800803
.toColorspace('rgb16')
804+
.png()
801805
.withMetadata()
802806
.toBuffer();
803807

804808
const metadata = await sharp(data).metadata();
805-
assert.strictEqual(undefined, metadata.icc);
809+
assert.strictEqual(metadata.depth, 'ushort');
810+
811+
const { description } = icc.parse(metadata.icc);
812+
assert.strictEqual(description, 'sRGB');
813+
});
814+
815+
it('withMetadata adds P3 profile to 16-bit PNG', async () => {
816+
const data = await sharp({
817+
create: {
818+
width: 8, height: 8, channels: 4, background: 'orange'
819+
}
820+
})
821+
.toColorspace('rgb16')
822+
.png()
823+
.withMetadata({ icc: 'p3' })
824+
.toBuffer();
825+
826+
const metadata = await sharp(data).metadata();
827+
assert.strictEqual(metadata.depth, 'ushort');
828+
829+
const { description } = icc.parse(metadata.icc);
830+
assert.strictEqual(description, 'sP3C');
806831
});
807832

808833
it('File input with corrupt header fails gracefully', function (done) {

0 commit comments

Comments
 (0)