Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ rayon = { version = "1.7.0", optional = true }
rgb = { version = "0.8.48", default-features = false, optional = true }
tiff = { version = "0.10.3", optional = true }
zune-core = { version = "0.5.0", default-features = false, optional = true }
zune-jpeg = { version = "0.5.5", optional = true }
zune-jpeg = { version = "0.5.13", optional = true }
jpeg-encoder = { version = "0.7.0", optional = true, features = ["simd"] }
serde = { version = "1.0.214", optional = true, features = ["derive"] }
pic-scale-safe = "0.1.5"
Expand Down
18 changes: 18 additions & 0 deletions src/codecs/jpeg/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,24 @@ impl<R: BufRead + Seek> ImageDecoder for JpegDecoder<R> {
Ok(decoder.xmp().cloned())
}

fn extended_xmp_metadata(&mut self) -> ImageResult<Option<(String, Vec<u8>)>> {
let options = zune_core::options::DecoderOptions::default()
.set_strict_mode(false)
.set_max_width(usize::MAX)
.set_max_height(usize::MAX);
let mut decoder =
zune_jpeg::JpegDecoder::new_with_options(ZCursor::new(&self.input), options);
decoder.decode_headers().map_err(ImageError::from_jpeg)?;

if let Some(info) = decoder.info() {
if let (Some(guid), Some(data)) = (info.extended_xmp_guid, info.extended_xmp) {
let guid_str = String::from_utf8_lossy(&guid).into_owned();
return Ok(Some((guid_str, data)));
}
}
Ok(None)
}

fn iptc_metadata(&mut self) -> ImageResult<Option<Vec<u8>>> {
let options = zune_core::options::DecoderOptions::default()
.set_strict_mode(false)
Expand Down
12 changes: 12 additions & 0 deletions src/io/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ pub trait ImageDecoder {
Ok(None)
}

/// Returns the raw [Extended XMP](https://en.wikipedia.org/wiki/Extensible_Metadata_Platform) metadata, if present.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://en.wikipedia.org/wiki/Extensible_Metadata_Platform contains no mentions of the word "extended", could you clarify where this terminology comes from and where this behavior is specified?

///
/// This is typically used in JPEG files when the XMP data exceeds 64KB.
/// Returns `Ok(Some((guid, data)))` where `guid` is the 128-bit GUID (as a 32-character hex string)
/// and `data` is the concatenated extended XMP data.
fn extended_xmp_metadata(&mut self) -> ImageResult<Option<(String, Vec<u8>)>> {
Ok(None)
}

/// Returns the raw [IPTC](https://en.wikipedia.org/wiki/IPTC_Information_Interchange_Model) chunk, if it is present.
///
/// For formats that don't support embedded profiles this function should always return `Ok(None)`.
Expand Down Expand Up @@ -152,6 +161,9 @@ impl<T: ?Sized + ImageDecoder> ImageDecoder for Box<T> {
fn xmp_metadata(&mut self) -> ImageResult<Option<Vec<u8>>> {
(**self).xmp_metadata()
}
fn extended_xmp_metadata(&mut self) -> ImageResult<Option<(String, Vec<u8>)>> {
(**self).extended_xmp_metadata()
}
fn iptc_metadata(&mut self) -> ImageResult<Option<Vec<u8>>> {
(**self).iptc_metadata()
}
Expand Down
Loading