1From e912074417f5dd3eb9f4bc2dac41f22deae889b9 Mon Sep 17 00:00:00 2001 2From: Lukasz Anforowicz <[email protected]> 3Date: Fri, 1 Nov 2024 11:22:09 -0700 4Subject: [PATCH 302/302] Add support for parsing `cICP` chunks. (#529) 5 6--- 7 src/chunk.rs | 2 ++ 8 src/common.rs | 42 +++++++++++++++++++++++++++++++ 9 src/decoder/stream.rs | 57 ++++++++++++++++++++++++++++++++++++++++++- 10 3 files changed, 100 insertions(+), 1 deletion(-) 11 12diff --git a/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/chunk.rs b/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/chunk.rs 13index 34a088f..b83ce54 100644 14--- a/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/chunk.rs 15+++ b/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/chunk.rs 16@@ -35,6 +35,8 @@ pub const gAMA: ChunkType = ChunkType(*b"gAMA"); 17 pub const sRGB: ChunkType = ChunkType(*b"sRGB"); 18 /// ICC profile chunk 19 pub const iCCP: ChunkType = ChunkType(*b"iCCP"); 20+/// Coding-independent code points for video signal type identification chunk 21+pub const cICP: ChunkType = ChunkType(*b"cICP"); 22 /// Mastering Display Color Volume chunk 23 pub const mDCv: ChunkType = ChunkType(*b"mDCv"); 24 /// Content Light Level Information chunk 25diff --git a/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/common.rs b/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/common.rs 26index 4c06e3b..3d9dc13 100644 27--- a/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/common.rs 28+++ b/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/common.rs 29@@ -470,6 +470,45 @@ impl SrgbRenderingIntent { 30 } 31 } 32 33+/// Coding-independent code points (cICP) specify the color space (primaries), 34+/// transfer function, matrix coefficients and scaling factor of the image using 35+/// the code points specified in [ITU-T-H.273](https://www.itu.int/rec/T-REC-H.273). 36+/// 37+/// See https://www.w3.org/TR/png-3/#cICP-chunk for more details. 38+#[derive(Clone, Copy, Debug, PartialEq, Eq)] 39+pub struct CodingIndependentCodePoints { 40+ /// Id number of the color primaries defined in 41+ /// [ITU-T-H.273](https://www.itu.int/rec/T-REC-H.273) in "Table 2 - 42+ /// Interpretation of colour primaries (ColourPrimaries) value". 43+ pub color_primaries: u8, 44+ 45+ /// Id number of the transfer characteristics defined in 46+ /// [ITU-T-H.273](https://www.itu.int/rec/T-REC-H.273) in "Table 3 - 47+ /// Interpretation of transfer characteristics (TransferCharacteristics) 48+ /// value". 49+ pub transfer_function: u8, 50+ 51+ /// Id number of the matrix coefficients defined in 52+ /// [ITU-T-H.273](https://www.itu.int/rec/T-REC-H.273) in "Table 4 - 53+ /// Interpretation of matrix coefficients (MatrixCoefficients) value". 54+ /// 55+ /// This field is included to faithfully replicate the base 56+ /// [ITU-T-H.273](https://www.itu.int/rec/T-REC-H.273) specification, but matrix coefficients 57+ /// will always be set to 0, because RGB is currently the only supported color mode in PNG. 58+ pub matrix_coefficients: u8, 59+ 60+ /// Whether the image is 61+ /// [a full range image](https://www.w3.org/TR/png-3/#dfn-full-range-image) 62+ /// or 63+ /// [a narrow range image](https://www.w3.org/TR/png-3/#dfn-narrow-range-image). 64+ /// 65+ /// This field is included to faithfully replicate the base 66+ /// [ITU-T-H.273](https://www.itu.int/rec/T-REC-H.273) specification, but it has limited 67+ /// practical application to PNG images, because narrow-range images are [quite 68+ /// rare](https://github.com/w3c/png/issues/312#issuecomment-2327349614) in practice. 69+ pub is_video_full_range_image: bool, 70+} 71+ 72 /// Mastering Display Color Volume (mDCv) used at the point of content creation, 73 /// as specified in [SMPTE-ST-2086](https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=8353899). 74 /// 75@@ -557,6 +596,8 @@ pub struct Info<'a> { 76 pub srgb: Option<SrgbRenderingIntent>, 77 /// The ICC profile for the image. 78 pub icc_profile: Option<Cow<'a, [u8]>>, 79+ /// The coding-independent code points for video signal type identification of the image. 80+ pub coding_independent_code_points: Option<CodingIndependentCodePoints>, 81 /// The mastering display color volume for the image. 82 pub mastering_display_color_volume: Option<MasteringDisplayColorVolume>, 83 /// The content light information for the image. 84@@ -593,6 +634,7 @@ impl Default for Info<'_> { 85 source_chromaticities: None, 86 srgb: None, 87 icc_profile: None, 88+ coding_independent_code_points: None, 89 mastering_display_color_volume: None, 90 content_light_level: None, 91 exif_metadata: None, 92diff --git a/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/decoder/stream.rs b/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/decoder/stream.rs 93index 68de12d..760d5fd 100644 94--- a/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/decoder/stream.rs 95+++ b/third_party/rust/chromium_crates_io/vendor/png-0.17.14/src/decoder/stream.rs 96@@ -15,7 +15,7 @@ use crate::common::{ 97 }; 98 use crate::text_metadata::{ITXtChunk, TEXtChunk, TextDecodingError, ZTXtChunk}; 99 use crate::traits::ReadBytesExt; 100-use crate::Limits; 101+use crate::{CodingIndependentCodePoints, Limits}; 102 103 /// TODO check if these size are reasonable 104 pub const CHUNK_BUFFER_SIZE: usize = 32 * 1024; 105@@ -959,6 +959,7 @@ impl StreamingDecoder { 106 chunk::fcTL => self.parse_fctl(), 107 chunk::cHRM => self.parse_chrm(), 108 chunk::sRGB => self.parse_srgb(), 109+ chunk::cICP => Ok(self.parse_cicp()), 110 chunk::mDCv => Ok(self.parse_mdcv()), 111 chunk::cLLi => Ok(self.parse_clli()), 112 chunk::iCCP if !self.decode_options.ignore_iccp_chunk => self.parse_iccp(), 113@@ -1274,6 +1275,54 @@ impl StreamingDecoder { 114 } 115 } 116 117+ // NOTE: This function cannot return `DecodingError` and handles parsing 118+ // errors or spec violations as-if the chunk was missing. See 119+ // https://github.com/image-rs/image-png/issues/525 for more discussion. 120+ fn parse_cicp(&mut self) -> Decoded { 121+ fn parse(mut buf: &[u8]) -> Result<CodingIndependentCodePoints, std::io::Error> { 122+ let color_primaries: u8 = buf.read_be()?; 123+ let transfer_function: u8 = buf.read_be()?; 124+ let matrix_coefficients: u8 = buf.read_be()?; 125+ let is_video_full_range_image = { 126+ let flag: u8 = buf.read_be()?; 127+ match flag { 128+ 0 => false, 129+ 1 => true, 130+ _ => { 131+ return Err(std::io::ErrorKind::InvalidData.into()); 132+ } 133+ } 134+ }; 135+ 136+ // RGB is currently the only supported color model in PNG, and as 137+ // such Matrix Coefficients shall be set to 0. 138+ if matrix_coefficients != 0 { 139+ return Err(std::io::ErrorKind::InvalidData.into()); 140+ } 141+ 142+ if !buf.is_empty() { 143+ return Err(std::io::ErrorKind::InvalidData.into()); 144+ } 145+ 146+ Ok(CodingIndependentCodePoints { 147+ color_primaries, 148+ transfer_function, 149+ matrix_coefficients, 150+ is_video_full_range_image, 151+ }) 152+ } 153+ 154+ // The spec requires that the cICP chunk MUST come before the PLTE and IDAT chunks. 155+ // Additionally, we ignore a second, duplicated cICP chunk (if any). 156+ let info = self.info.as_mut().unwrap(); 157+ let is_before_plte_and_idat = !self.have_idat && info.palette.is_none(); 158+ if is_before_plte_and_idat && info.coding_independent_code_points.is_none() { 159+ info.coding_independent_code_points = parse(&self.current_chunk.raw_bytes[..]).ok(); 160+ } 161+ 162+ Decoded::Nothing 163+ } 164+ 165 // NOTE: This function cannot return `DecodingError` and handles parsing 166 // errors or spec violations as-if the chunk was missing. See 167 // https://github.com/image-rs/image-png/issues/525 for more discussion. 168-- 1692.47.0.199.ga7371fff76-goog 170 171