From 4a1b982f13b037842b0da70480d1217fc3b2cfc9 Mon Sep 17 00:00:00 2001 From: Kornel Date: Sun, 8 Dec 2024 11:35:03 +0000 Subject: [PATCH] Make gAMA and cHRM fallback optional for sRGB --- src/common.rs | 25 +++++++++++++++++++++---- src/encoder.rs | 18 ++++++++++++++++-- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/common.rs b/src/common.rs index ce694497..36ad78b6 100644 --- a/src/common.rs +++ b/src/common.rs @@ -725,6 +725,17 @@ impl Info<'_> { .raw_row_length_from_width(self.bit_depth, width) } + /// Mark the image data as conforming to the SRGB color space with the specified rendering intent. + /// + /// Any ICC profiles will be ignored. + /// + /// Source gamma and chromaticities will be written only if they're set to fallback + /// values specified in [11.3.2.5](https://www.w3.org/TR/png-3/#sRGB-gAMA-cHRM). + pub(crate) fn set_source_srgb(&mut self, rendering_intent: SrgbRenderingIntent) { + self.srgb = Some(rendering_intent); + self.icc_profile = None; + } + /// Encode this header to the writer. /// /// Note that this does _not_ include the PNG signature, it starts with the IHDR chunk and then @@ -753,11 +764,17 @@ impl Info<'_> { // If specified, the sRGB information overrides the source gamma and chromaticities. if let Some(srgb) = &self.srgb { - let gamma = crate::srgb::substitute_gamma(); - let chromaticities = crate::srgb::substitute_chromaticities(); srgb.encode(&mut w)?; - gamma.encode_gama(&mut w)?; - chromaticities.encode(&mut w)?; + + // gAMA and cHRM are optional, for backwards compatibility + let srgb_gamma = crate::srgb::substitute_gamma(); + if Some(srgb_gamma) == self.source_gamma { + srgb_gamma.encode_gama(&mut w)? + } + let srgb_chromaticities = crate::srgb::substitute_chromaticities(); + if Some(srgb_chromaticities) == self.source_chromaticities { + srgb_chromaticities.encode(&mut w)?; + } } else { if let Some(gma) = self.source_gamma { gma.encode_gama(&mut w)? diff --git a/src/encoder.rs b/src/encoder.rs index 7a71b468..9f275e5e 100644 --- a/src/encoder.rs +++ b/src/encoder.rs @@ -268,9 +268,23 @@ impl<'a, W: Write> Encoder<'a, W> { /// Mark the image data as conforming to the SRGB color space with the specified rendering intent. /// /// Matching source gamma and chromaticities chunks are added automatically. - /// Any manually specified source gamma or chromaticities will be ignored. + /// Any manually specified source gamma, chromaticities, or ICC profiles will be ignored. + #[doc(hidden)] + #[deprecated(note = "use set_source_srgb")] pub fn set_srgb(&mut self, rendering_intent: super::SrgbRenderingIntent) { - self.info.srgb = Some(rendering_intent); + self.info.set_source_srgb(rendering_intent); + self.info.source_gamma = Some(crate::srgb::substitute_gamma()); + self.info.source_chromaticities = Some(crate::srgb::substitute_chromaticities()); + } + + /// Mark the image data as conforming to the SRGB color space with the specified rendering intent. + /// + /// Any ICC profiles will be ignored. + /// + /// Source gamma and chromaticities will be written only if they're set to fallback + /// values specified in [11.3.2.5](https://www.w3.org/TR/png-3/#sRGB-gAMA-cHRM). + pub fn set_source_srgb(&mut self, rendering_intent: super::SrgbRenderingIntent) { + self.info.set_source_srgb(rendering_intent); } /// Start encoding by writing the header data.