jxl_oxide/aux_box/
exif.rs

1use crate::Result;
2
3/// Raw Exif metadata.
4pub struct RawExif<'image> {
5    tiff_header_offset: u32,
6    payload: &'image [u8],
7}
8
9impl std::fmt::Debug for RawExif<'_> {
10    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11        f.debug_struct("RawExif")
12            .field("tiff_header_offset", &self.tiff_header_offset)
13            .finish_non_exhaustive()
14    }
15}
16
17impl<'image> RawExif<'image> {
18    pub(crate) fn new(box_data: &'image [u8]) -> Result<Self> {
19        if box_data.len() < 4 {
20            tracing::error!(len = box_data.len(), "Exif box is too short");
21            return Err(jxl_bitstream::Error::ValidationFailed("Exif box is too short").into());
22        }
23
24        let (tiff, payload) = box_data.split_at(4);
25        let tiff_header_offset = u32::from_be_bytes([tiff[0], tiff[1], tiff[2], tiff[3]]);
26        if tiff_header_offset as usize >= payload.len() {
27            tracing::error!(
28                payload_len = payload.len(),
29                tiff_header_offset,
30                "tiff_header_offset of Exif box is too large"
31            );
32            return Err(jxl_bitstream::Error::ValidationFailed(
33                "tiff_header_offset of Exif box is too large",
34            )
35            .into());
36        }
37
38        Ok(Self {
39            tiff_header_offset,
40            payload,
41        })
42    }
43}
44
45impl<'image> RawExif<'image> {
46    /// Returns the offset of TIFF header within the payload.
47    pub fn tiff_header_offset(&self) -> u32 {
48        self.tiff_header_offset
49    }
50
51    /// Returns the payload.
52    pub fn payload(&self) -> &'image [u8] {
53        self.payload
54    }
55}