Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EXIF and ICC encoding and fix chunk order #526

Merged
merged 1 commit into from
Oct 21, 2024
Merged
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: 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
Loading