Skip to content

Commit

Permalink
Ensure withMetadata can add RGB16 profiles #3773
Browse files Browse the repository at this point in the history
  • Loading branch information
lovell committed Aug 31, 2023
1 parent e7381e5 commit 9c217ab
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 14 deletions.
5 changes: 4 additions & 1 deletion docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ Requires libvips v8.14.4
* 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).
* Ensure `withMetadata` can add ICC profiles to RGB16 output.
[#3773](https://github.com/lovell/sharp/issues/3773)

* Ensure `withMetadata` does not reduce 16-bit images to 8-bit (regression in 0.32.5).
[#3773](https://github.com/lovell/sharp/issues/3773)

### v0.32.5 - 15th August 2023
Expand Down
18 changes: 9 additions & 9 deletions src/pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ class PipelineWorker : public Napi::AsyncWorker {
try {
image = image.icc_transform(processingProfile, VImage::option()
->set("embedded", TRUE)
->set("depth", image.interpretation() == VIPS_INTERPRETATION_RGB16 ? 16 : 8)
->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
->set("intent", VIPS_INTENT_PERCEPTUAL));
} catch(...) {
sharp::VipsWarningCallback(nullptr, G_LOG_LEVEL_WARNING, "Invalid embedded profile", nullptr);
Expand Down Expand Up @@ -763,6 +763,7 @@ class PipelineWorker : public Napi::AsyncWorker {
if (baton->withMetadata && sharp::HasProfile(image) && baton->withMetadataIcc.empty()) {
image = image.icc_transform("srgb", VImage::option()
->set("embedded", TRUE)
->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
->set("intent", VIPS_INTENT_PERCEPTUAL));
}
}
Expand All @@ -789,14 +790,13 @@ class PipelineWorker : public Napi::AsyncWorker {

// Apply output ICC profile
if (baton->withMetadata) {
if (image.interpretation() == VIPS_INTERPRETATION_sRGB || !baton->withMetadataIcc.empty()) {
image = image.icc_transform(
baton->withMetadataIcc.empty() ? "srgb" : const_cast<char*>(baton->withMetadataIcc.data()),
VImage::option()
->set("input_profile", processingProfile)
->set("embedded", TRUE)
->set("intent", VIPS_INTENT_PERCEPTUAL));
}
image = image.icc_transform(
baton->withMetadataIcc.empty() ? "srgb" : const_cast<char*>(baton->withMetadataIcc.data()),
VImage::option()
->set("input_profile", processingProfile)
->set("embedded", TRUE)
->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
->set("intent", VIPS_INTENT_PERCEPTUAL));
}
// Override EXIF Orientation tag
if (baton->withMetadata && baton->withMetadataOrientation != -1) {
Expand Down
33 changes: 29 additions & 4 deletions test/unit/metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -794,15 +794,40 @@ describe('Image metadata', function () {
assert.strictEqual(intent, 'Perceptual');
});

it('withMetadata does not add default sRGB profile to RGB16', async () => {
const data = await sharp(fixtures.inputJpg)
.resize(32, 24)
it('withMetadata adds default sRGB profile to RGB16', async () => {
const data = await sharp({
create: {
width: 8, height: 8, channels: 4, background: 'orange'
}
})
.toColorspace('rgb16')
.png()
.withMetadata()
.toBuffer();

const metadata = await sharp(data).metadata();
assert.strictEqual(undefined, metadata.icc);
assert.strictEqual(metadata.depth, 'ushort');

const { description } = icc.parse(metadata.icc);
assert.strictEqual(description, 'sRGB');
});

it('withMetadata adds P3 profile to 16-bit PNG', async () => {
const data = await sharp({
create: {
width: 8, height: 8, channels: 4, background: 'orange'
}
})
.toColorspace('rgb16')
.png()
.withMetadata({ icc: 'p3' })
.toBuffer();

const metadata = await sharp(data).metadata();
assert.strictEqual(metadata.depth, 'ushort');

const { description } = icc.parse(metadata.icc);
assert.strictEqual(description, 'sP3C');
});

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

0 comments on commit 9c217ab

Please sign in to comment.