diff --git a/src/decoder/stream.rs b/src/decoder/stream.rs index 1b00968b..904d3beb 100644 --- a/src/decoder/stream.rs +++ b/src/decoder/stream.rs @@ -989,6 +989,7 @@ impl StreamingDecoder { chunk::cICP => Ok(self.parse_cicp()), chunk::mDCV => Ok(self.parse_mdcv()), chunk::cLLI => Ok(self.parse_clli()), + chunk::eXIf => Ok(self.parse_exif()), chunk::bKGD => Ok(self.parse_bkgd()), chunk::iCCP if !self.decode_options.ignore_iccp_chunk => self.parse_iccp(), chunk::tEXt if !self.decode_options.ignore_text_chunk => self.parse_text(), @@ -1487,6 +1488,16 @@ impl StreamingDecoder { Decoded::Nothing } + fn parse_exif(&mut self) -> Decoded { + // We ignore a second, duplicated eXIf chunk (if any). + let info = self.info.as_mut().unwrap(); + if info.exif_metadata.is_none() { + info.exif_metadata = Some(self.current_chunk.raw_bytes.clone().into()); + } + + Decoded::Nothing + } + fn parse_iccp(&mut self) -> Result { if self.have_idat { Err(DecodingError::Format( @@ -2125,7 +2136,7 @@ mod tests { assert!(decoder.read_info().is_ok()); } - /// Test handling of `mDCV` and `cLLI` chunks.` + /// Test handling of `mDCV` and `cLLI` chunks. #[test] fn test_mdcv_and_clli_chunks() { let decoder = crate::Decoder::new(File::open("tests/bugfixes/cicp_pq.png").unwrap()); @@ -2155,6 +2166,17 @@ mod tests { assert_relative_eq!(clli.max_frame_average_light_level as f32 / 10_000.0, 2627.0); } + /// Test handling of `eXIf` chunk. + #[test] + fn test_exif_chunk() { + let decoder = + crate::Decoder::new(File::open("tests/bugfixes/F-exif-chunk-early.png").unwrap()); + let reader = decoder.read_info().unwrap(); + let info = reader.info(); + let exif = info.exif_metadata.as_ref().unwrap().as_ref(); + assert_eq!(exif.len(), 90); + } + /// Tests what happens then [`Reader.finish`] is called twice. #[test] fn test_finishing_twice() { diff --git a/tests/bugfixes/F-exif-chunk-early.png b/tests/bugfixes/F-exif-chunk-early.png new file mode 100644 index 00000000..24bd924e Binary files /dev/null and b/tests/bugfixes/F-exif-chunk-early.png differ diff --git a/tests/results.txt b/tests/results.txt index 3a65313d..c192bb12 100644 --- a/tests/results.txt +++ b/tests/results.txt @@ -178,6 +178,7 @@ tests/pngsuite-extra/basi3p02_2.png: 419215269 tests/bugfixes/invalid_palette_index.png: 3040120786 tests/bugfixes/acid2.png: 2380843583 tests/bugfixes/cicp_pq.png: 3306910117 +tests/bugfixes/F-exif-chunk-early.png: 4079196849 tests/bugfixes/gama-srgb-order-issue#304.png: 275287206 tests/bugfixes/issue#1825.png: 3386502267 tests/bugfixes/issue#430.png: 574381763 diff --git a/tests/results_alpha.txt b/tests/results_alpha.txt index a9648aca..ced4aa2d 100644 --- a/tests/results_alpha.txt +++ b/tests/results_alpha.txt @@ -177,6 +177,7 @@ tests/pngsuite-extra/basi3p01_2.png: 4023530527 tests/pngsuite-extra/basi3p02_2.png: 313298351 tests/bugfixes/acid2.png: 2380843583 tests/bugfixes/cicp_pq.png: 2316063598 +tests/bugfixes/F-exif-chunk-early.png: 3035932940 tests/bugfixes/gama-srgb-order-issue#304.png: 275287206 tests/bugfixes/invalid_palette_index.png: 4178597885 tests/bugfixes/issue#202.png: 29900969 diff --git a/tests/results_identity.txt b/tests/results_identity.txt index ed332b98..82e3c21c 100644 --- a/tests/results_identity.txt +++ b/tests/results_identity.txt @@ -177,6 +177,7 @@ tests/pngsuite-extra/basi3p01_2.png: 3071936103 tests/pngsuite-extra/basi3p02_2.png: 1136045771 tests/bugfixes/acid2.png: 2051796287 tests/bugfixes/cicp_pq.png: 3306910117 +tests/bugfixes/F-exif-chunk-early.png: 4079196849 tests/bugfixes/invalid_palette_index.png: 64128641 tests/bugfixes/gama-srgb-order-issue#304.png: 275287206 tests/bugfixes/issue#1825.png: 3386502267