From eb5f867f0541bc6ea8f7a64930f488d63313afa0 Mon Sep 17 00:00:00 2001 From: Sam Denty Date: Fri, 23 Dec 2022 23:20:28 +0000 Subject: [PATCH] feat(0.4.0): add support for GIF --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/icon_info.rs | 13 +++++++++++-- src/icon_size/gif.rs | 24 ++++++++++++++++++++++++ src/icon_size/mod.rs | 2 ++ 5 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 src/icon_size/gif.rs diff --git a/Cargo.lock b/Cargo.lock index 82a98e4..d772742 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1525,7 +1525,7 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "site_icons" -version = "0.3.10" +version = "0.4.0" dependencies = [ "byteorder", "clap", diff --git a/Cargo.toml b/Cargo.toml index 28154c2..a51a543 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "site_icons" -version = "0.3.10" +version = "0.4.0" authors = ["Sam Denty "] edition = "2018" license = "GPL-3.0" diff --git a/src/icon_info.rs b/src/icon_info.rs index b1096ba..b08a2ec 100644 --- a/src/icon_info.rs +++ b/src/icon_info.rs @@ -17,6 +17,7 @@ enum IconKind { PNG, JPEG, ICO, + GIF, } #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] @@ -26,6 +27,7 @@ pub enum IconInfo { PNG { size: IconSize }, JPEG { size: IconSize }, ICO { sizes: IconSizes }, + GIF { size: IconSize }, SVG, } @@ -50,6 +52,10 @@ impl IconInfo { let size = get_jpeg_size(reader).await?; Ok(IconInfo::JPEG { size }) } + (Some(IconKind::GIF), _) | (_, &[0x47, 0x49]) => { + let size = get_gif_size(reader).await?; + Ok(IconInfo::GIF { size }) + } _ => Err(format!("unknown icon type ({:?})", header).into()), } } @@ -140,7 +146,7 @@ impl IconInfo { pub fn size(&self) -> Option<&IconSize> { match self { IconInfo::ICO { sizes } => Some(sizes.largest()), - IconInfo::PNG { size } | IconInfo::JPEG { size } => Some(size), + IconInfo::PNG { size } | IconInfo::JPEG { size } | IconInfo::GIF { size } => Some(size), IconInfo::SVG => None, } } @@ -148,7 +154,9 @@ impl IconInfo { pub fn sizes(&self) -> Option { match self { IconInfo::ICO { sizes } => Some((*sizes).clone()), - IconInfo::PNG { size } | IconInfo::JPEG { size } => Some((*size).into()), + IconInfo::PNG { size } | IconInfo::JPEG { size } | IconInfo::GIF { size } => { + Some((*size).into()) + } IconInfo::SVG => None, } } @@ -159,6 +167,7 @@ impl Display for IconInfo { match self { IconInfo::PNG { size } => write!(f, "png {}", size), IconInfo::JPEG { size } => write!(f, "jpeg {}", size), + IconInfo::GIF { size } => write!(f, "gif {}", size), IconInfo::ICO { sizes } => write!(f, "ico {}", sizes), IconInfo::SVG => write!(f, "svg"), } diff --git a/src/icon_size/gif.rs b/src/icon_size/gif.rs new file mode 100644 index 0000000..e75a60f --- /dev/null +++ b/src/icon_size/gif.rs @@ -0,0 +1,24 @@ +use super::IconSize; +use byteorder::{LittleEndian, ReadBytesExt}; +use futures::prelude::*; +use std::{ + error::Error, + io::{Cursor, Seek, SeekFrom}, +}; + +pub async fn get_gif_size( + reader: &mut R, +) -> Result> { + let mut header = [0; 8]; + reader.read_exact(&mut header).await?; + let header = &mut Cursor::new(header); + + assert_slice_eq!(header, 0, b"F8", "bad header"); + + header.seek(SeekFrom::Start(4))?; + + let width = header.read_u16::()? as u32; + let height = header.read_u16::()? as u32; + + Ok(IconSize::new(width, height)) +} diff --git a/src/icon_size/mod.rs b/src/icon_size/mod.rs index 398f172..71ca2ca 100644 --- a/src/icon_size/mod.rs +++ b/src/icon_size/mod.rs @@ -1,8 +1,10 @@ +mod gif; mod ico; mod icon_sizes; mod jpeg; mod png; +pub use gif::*; pub use ico::*; pub use icon_sizes::*; pub use jpeg::*;