Skip to content

Commit

Permalink
Add EXIF and ICC encoding and fix chunk order
Browse files Browse the repository at this point in the history
  • Loading branch information
fintelia authored and kornelski committed Oct 21, 2024
1 parent ffed4de commit 6bbdb50
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 8 deletions.
2 changes: 2 additions & 0 deletions src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ pub const gAMA: ChunkType = ChunkType(*b"gAMA");
pub const sRGB: ChunkType = ChunkType(*b"sRGB");
/// ICC profile chunk
pub const iCCP: ChunkType = ChunkType(*b"iCCP");
/// EXIF metadata chunk
pub const eXIf: ChunkType = ChunkType(*b"eXIf");
/// Latin-1 uncompressed textual data
pub const tEXt: ChunkType = ChunkType(*b"tEXt");
/// Latin-1 compressed textual data
Expand Down
30 changes: 22 additions & 8 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,8 @@ pub struct Info<'a> {
pub srgb: Option<SrgbRenderingIntent>,
/// The ICC profile for the image.
pub icc_profile: Option<Cow<'a, [u8]>>,
/// The EXIF metadata for the image.
pub exif_metadata: Option<Cow<'a, [u8]>>,
/// tEXt field
pub uncompressed_latin1_text: Vec<TEXtChunk>,
/// zTXt field
Expand Down Expand Up @@ -537,6 +539,7 @@ impl Default for Info<'_> {
source_chromaticities: None,
srgb: None,
icc_profile: None,
exif_metadata: None,
uncompressed_latin1_text: Vec::new(),
compressed_latin1_text: Vec::new(),
utf8_text: Vec::new(),
Expand Down Expand Up @@ -631,6 +634,7 @@ impl Info<'_> {
data[9] = self.color_type as u8;
data[12] = self.interlaced as u8;
encoder::write_chunk(&mut w, chunk::IHDR, &data)?;

// Encode the pHYs chunk
if let Some(pd) = self.pixel_dims {
let mut phys_data = [0; 9];
Expand All @@ -643,14 +647,6 @@ impl Info<'_> {
encoder::write_chunk(&mut w, chunk::pHYs, &phys_data)?;
}

if let Some(p) = &self.palette {
encoder::write_chunk(&mut w, chunk::PLTE, p)?;
};

if let Some(t) = &self.trns {
encoder::write_chunk(&mut w, chunk::tRNS, t)?;
}

// If specified, the sRGB information overrides the source gamma and chromaticities.
if let Some(srgb) = &self.srgb {
let gamma = crate::srgb::substitute_gamma();
Expand All @@ -665,11 +661,29 @@ impl Info<'_> {
if let Some(chrms) = self.source_chromaticities {
chrms.encode(&mut w)?;
}
if let Some(iccp) = &self.icc_profile {
encoder::write_chunk(&mut w, chunk::iCCP, iccp)?;
}
}

if let Some(exif) = &self.exif_metadata {
encoder::write_chunk(&mut w, chunk::eXIf, exif)?;
}

if let Some(actl) = self.animation_control {
actl.encode(&mut w)?;
}

// The position of the PLTE chunk is important, it must come before the tRNS chunk and after
// many of the other metadata chunks.
if let Some(p) = &self.palette {
encoder::write_chunk(&mut w, chunk::PLTE, p)?;
};

if let Some(t) = &self.trns {
encoder::write_chunk(&mut w, chunk::tRNS, t)?;
}

for text_chunk in &self.uncompressed_latin1_text {
text_chunk.encode(&mut w)?;
}
Expand Down

0 comments on commit 6bbdb50

Please sign in to comment.