mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 18:40:16 +02:00
Ensure withMetadata can add RGB16 profiles #3773
This commit is contained in:
parent
e7381e522e
commit
9c217ab580
@ -9,7 +9,10 @@ Requires libvips v8.14.4
|
|||||||
* Ensure composite tile images are fully decoded (regression in 0.32.0).
|
* Ensure composite tile images are fully decoded (regression in 0.32.0).
|
||||||
[#3767](https://github.com/lovell/sharp/issues/3767)
|
[#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)
|
[#3773](https://github.com/lovell/sharp/issues/3773)
|
||||||
|
|
||||||
### v0.32.5 - 15th August 2023
|
### v0.32.5 - 15th August 2023
|
||||||
|
@ -326,7 +326,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
try {
|
try {
|
||||||
image = image.icc_transform(processingProfile, VImage::option()
|
image = image.icc_transform(processingProfile, VImage::option()
|
||||||
->set("embedded", TRUE)
|
->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));
|
->set("intent", VIPS_INTENT_PERCEPTUAL));
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
sharp::VipsWarningCallback(nullptr, G_LOG_LEVEL_WARNING, "Invalid embedded profile", nullptr);
|
sharp::VipsWarningCallback(nullptr, G_LOG_LEVEL_WARNING, "Invalid embedded profile", nullptr);
|
||||||
@ -763,6 +763,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
if (baton->withMetadata && sharp::HasProfile(image) && baton->withMetadataIcc.empty()) {
|
if (baton->withMetadata && sharp::HasProfile(image) && baton->withMetadataIcc.empty()) {
|
||||||
image = image.icc_transform("srgb", VImage::option()
|
image = image.icc_transform("srgb", VImage::option()
|
||||||
->set("embedded", TRUE)
|
->set("embedded", TRUE)
|
||||||
|
->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
|
||||||
->set("intent", VIPS_INTENT_PERCEPTUAL));
|
->set("intent", VIPS_INTENT_PERCEPTUAL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -789,14 +790,13 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
|
|
||||||
// Apply output ICC profile
|
// Apply output ICC profile
|
||||||
if (baton->withMetadata) {
|
if (baton->withMetadata) {
|
||||||
if (image.interpretation() == VIPS_INTERPRETATION_sRGB || !baton->withMetadataIcc.empty()) {
|
image = image.icc_transform(
|
||||||
image = image.icc_transform(
|
baton->withMetadataIcc.empty() ? "srgb" : const_cast<char*>(baton->withMetadataIcc.data()),
|
||||||
baton->withMetadataIcc.empty() ? "srgb" : const_cast<char*>(baton->withMetadataIcc.data()),
|
VImage::option()
|
||||||
VImage::option()
|
->set("input_profile", processingProfile)
|
||||||
->set("input_profile", processingProfile)
|
->set("embedded", TRUE)
|
||||||
->set("embedded", TRUE)
|
->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8)
|
||||||
->set("intent", VIPS_INTENT_PERCEPTUAL));
|
->set("intent", VIPS_INTENT_PERCEPTUAL));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Override EXIF Orientation tag
|
// Override EXIF Orientation tag
|
||||||
if (baton->withMetadata && baton->withMetadataOrientation != -1) {
|
if (baton->withMetadata && baton->withMetadataOrientation != -1) {
|
||||||
|
@ -794,15 +794,40 @@ describe('Image metadata', function () {
|
|||||||
assert.strictEqual(intent, 'Perceptual');
|
assert.strictEqual(intent, 'Perceptual');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('withMetadata does not add default sRGB profile to RGB16', async () => {
|
it('withMetadata adds default sRGB profile to RGB16', async () => {
|
||||||
const data = await sharp(fixtures.inputJpg)
|
const data = await sharp({
|
||||||
.resize(32, 24)
|
create: {
|
||||||
|
width: 8, height: 8, channels: 4, background: 'orange'
|
||||||
|
}
|
||||||
|
})
|
||||||
.toColorspace('rgb16')
|
.toColorspace('rgb16')
|
||||||
|
.png()
|
||||||
.withMetadata()
|
.withMetadata()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
const metadata = await sharp(data).metadata();
|
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) {
|
it('File input with corrupt header fails gracefully', function (done) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user