Skip to content

Commit 4cdedb2

Browse files
committed
Implement retrieving XMP metadata for Webp
1 parent 63a59f0 commit 4cdedb2

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

src/codecs/webp/decoder.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ impl<R: BufRead + Seek> ImageDecoder for WebPDecoder<R> {
8484
Ok(exif)
8585
}
8686

87+
fn xmp_metadata(&mut self) -> ImageResult<Option<Vec<u8>>> {
88+
self.inner
89+
.xmp_metadata()
90+
.map_err(ImageError::from_webp_decode)
91+
}
92+
8793
fn orientation(&mut self) -> ImageResult<Orientation> {
8894
// `exif_metadata` caches the orientation, so call it if `orientation` hasn't been set yet.
8995
if self.orientation.is_none() {
Binary file not shown.

tests/metadata.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@ use std::fs;
22
use std::path::PathBuf;
33
use std::str::FromStr;
44

5-
use image::{codecs::png::PngDecoder, ImageDecoder};
5+
use image::{
6+
codecs::{png::PngDecoder, webp::WebPDecoder},
7+
ImageDecoder,
8+
};
69

710
extern crate glob;
811
extern crate image;
912

1013
const XMP_PNG_PATH: &str = "tests/images/png/transparency/tp1n3p08_xmp.png";
11-
const EXPECTED_METADATA: &str = "<?xpacket begin='\u{feff}' id='W5M0MpCehiHzreSzNTczkc9d'?>\n<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 13.25'>\n<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>\n\n <rdf:Description rdf:about=''\n xmlns:dc='http://purl.org/dc/elements/1.1/'>\n <dc:subject>\n <rdf:Bag>\n <rdf:li>sunset, mountains, nature</rdf:li>\n </rdf:Bag>\n </dc:subject>\n </rdf:Description>\n</rdf:RDF>\n</x:xmpmeta>\n<?xpacket end='r'?>";
14+
const EXPECTED_PNG_METADATA: &str = "<?xpacket begin='\u{feff}' id='W5M0MpCehiHzreSzNTczkc9d'?>\n<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 13.25'>\n<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>\n\n <rdf:Description rdf:about=''\n xmlns:dc='http://purl.org/dc/elements/1.1/'>\n <dc:subject>\n <rdf:Bag>\n <rdf:li>sunset, mountains, nature</rdf:li>\n </rdf:Bag>\n </dc:subject>\n </rdf:Description>\n</rdf:RDF>\n</x:xmpmeta>\n<?xpacket end='r'?>";
15+
16+
const XMP_WEBP_PATH: &str = "tests/images/webp/lossless_images/simple_xmp.webp";
17+
const EXPECTED_WEBP_METADATA: &str = "<?xpacket begin='\u{feff}' id='W5M0MpCehiHzreSzNTczkc9d'?>\n<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 13.25'>\n<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>\n\n <rdf:Description rdf:about=''\n xmlns:dc='http://purl.org/dc/elements/1.1/'>\n <dc:subject>\n <rdf:Bag>\n <rdf:li>sunset, mountains, nature</rdf:li>\n </rdf:Bag>\n </dc:subject>\n </rdf:Description>\n</rdf:RDF>\n</x:xmpmeta>\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n<?xpacket end='w'?>";
1218

1319
#[test]
1420
fn test_read_xmp_png() -> Result<(), image::ImageError> {
@@ -18,7 +24,21 @@ fn test_read_xmp_png() -> Result<(), image::ImageError> {
1824
let mut png_decoder = PngDecoder::new(std::io::Cursor::new(data))?;
1925
let metadata = png_decoder.xmp_metadata()?;
2026
assert!(metadata.is_some());
21-
assert_eq!(EXPECTED_METADATA.as_bytes(), metadata.unwrap());
27+
assert_eq!(EXPECTED_PNG_METADATA.as_bytes(), metadata.unwrap());
28+
29+
Ok(())
30+
}
31+
32+
#[test]
33+
fn test_read_xmp_webp() -> Result<(), image::ImageError> {
34+
let img_path = PathBuf::from_str(XMP_WEBP_PATH).unwrap();
35+
36+
let data = fs::read(img_path)?;
37+
let mut webp_decoder = WebPDecoder::new(std::io::Cursor::new(data))?;
38+
let metadata = webp_decoder.xmp_metadata()?;
39+
40+
assert!(metadata.is_some());
41+
assert_eq!(EXPECTED_WEBP_METADATA.as_bytes(), metadata.unwrap());
2242

2343
Ok(())
2444
}

0 commit comments

Comments
 (0)