From 8be1df7299b1e5ae15a0afbaa7289bd2352cb176 Mon Sep 17 00:00:00 2001 From: Genny Date: Thu, 24 Nov 2022 18:32:22 -0600 Subject: Rename ColorTable to Palette --- gifed/src/block/colortable.rs | 132 ------------------------------------ gifed/src/block/imagedescriptor.rs | 4 +- gifed/src/block/indexedimage.rs | 9 ++- gifed/src/block/mod.rs | 4 +- gifed/src/block/palette.rs | 117 ++++++++++++++++++++++++++++++++ gifed/src/block/screendescriptor.rs | 4 +- gifed/src/colorimage.rs | 4 +- gifed/src/gif.rs | 11 ++- gifed/src/reader/mod.rs | 10 +-- gifed/src/writer/gifbuilder.rs | 6 +- gifed/src/writer/imagebuilder.rs | 6 +- 11 files changed, 143 insertions(+), 164 deletions(-) delete mode 100644 gifed/src/block/colortable.rs create mode 100644 gifed/src/block/palette.rs diff --git a/gifed/src/block/colortable.rs b/gifed/src/block/colortable.rs deleted file mode 100644 index 0d076c9..0000000 --- a/gifed/src/block/colortable.rs +++ /dev/null @@ -1,132 +0,0 @@ -pub use crate::Color; -use crate::EncodingError; -use std::{ - convert::{TryFrom, TryInto}, - ops::Deref, -}; - -#[derive(Clone, Debug)] -pub struct ColorTable { - table: Vec, -} - -impl ColorTable { - pub fn new() -> Self { - Self { table: vec![] } - } - - /// Returns the number of colors in the color table as used by the packed - /// fields in the Logical Screen Descriptor and Image Descriptor. You can - /// get the actual size with the [`len`](struct.ColorTable.html#method.len) method. - pub fn packed_len(&self) -> u8 { - ((self.table.len() as f32).log2().ceil() - 1f32) as u8 - } - - /// Returns the number of items in the table - pub fn len(&self) -> usize { - self.table.len() - } - - /// Pushes a color on to the end of the table - pub fn push(&mut self, color: Color) { - self.table.push(color); - } - - pub fn get(&self, index: u8) -> Option { - self.table.get(index as usize).map(|v| v.clone()) - } - - pub fn from_color>(&self, color: C) -> Option { - for (i, &c) in self.table.iter().enumerate() { - if c == *color.as_ref() { - return Some(i as u8); - } - } - None - } - - pub fn as_bytes(&self) -> Vec { - let mut bytes = Vec::with_capacity(self.table.len() * 3); - for color in &self.table { - bytes.extend_from_slice(&[color.r, color.g, color.b]); - } - - bytes - } -} - -impl Deref for ColorTable { - type Target = [Color]; - - fn deref(&self) -> &Self::Target { - &self.table - } -} - -impl AsRef for ColorTable { - fn as_ref(&self) -> &ColorTable { - self - } -} - -impl From<&ColorTable> for Box<[u8]> { - fn from(table: &ColorTable) -> Self { - let mut vec = vec![]; - - for color in table.iter() { - vec.extend_from_slice(&[color.r, color.g, color.b]); - } - - let packed_len = 2usize.pow(table.packed_len() as u32 + 1); - let padding = (packed_len as usize - table.len()) * 3; - if padding > 0 { - vec.extend_from_slice(&vec![0; padding]); - } - - vec.into_boxed_slice() - } -} - -//TODO: TryFrom Vec (must be multiple of 3 len) and From Vec -impl TryFrom<&[u8]> for ColorTable { - type Error = (); - - fn try_from(value: &[u8]) -> Result { - if value.len() % 3 != 0 { - return Err(()); - } else { - Ok(Self { - table: value - .chunks(3) - .map(|slice| Color::from(TryInto::<[u8; 3]>::try_into(slice).unwrap())) - .collect::>(), - }) - } - } -} - -impl TryFrom> for ColorTable { - type Error = EncodingError; - - fn try_from(value: Vec) -> Result { - if value.len() > 256 { - Err(EncodingError::TooManyColors) - } else { - Ok(Self { table: value }) - } - } -} - -impl TryFrom> for ColorTable { - type Error = EncodingError; - - fn try_from(value: Vec<(u8, u8, u8)>) -> Result { - if value.len() > 256 { - Err(EncodingError::TooManyColors) - } else { - Ok(Self { - table: value.into_iter().map(|c| c.into()).collect(), - }) - } - } -} diff --git a/gifed/src/block/imagedescriptor.rs b/gifed/src/block/imagedescriptor.rs index 76efe6c..6bc0792 100644 --- a/gifed/src/block/imagedescriptor.rs +++ b/gifed/src/block/imagedescriptor.rs @@ -1,6 +1,6 @@ use std::convert::TryInto; -use super::{packed::ImagePacked, ColorTable}; +use super::{packed::ImagePacked, Palette}; pub struct ImageDescriptor { pub left: u16, @@ -13,7 +13,7 @@ pub struct ImageDescriptor { impl ImageDescriptor { /// This data structure **does not** contain the color table, only a flag to /// indicate if one is present and it's size. - pub fn set_color_table_metadata>(&mut self, table: Option) { + pub fn set_color_table_metadata>(&mut self, table: Option) { if let Some(table) = table { let table = table.as_ref(); self.packed.set_color_table(true); diff --git a/gifed/src/block/indexedimage.rs b/gifed/src/block/indexedimage.rs index 730a02c..4e72ea0 100644 --- a/gifed/src/block/indexedimage.rs +++ b/gifed/src/block/indexedimage.rs @@ -2,12 +2,12 @@ use std::convert::TryFrom; use weezl::encode::Encoder; -use super::{ColorTable, ImageDescriptor}; +use super::{ImageDescriptor, Palette}; use crate::LZW; pub struct IndexedImage { pub image_descriptor: ImageDescriptor, - pub local_color_table: Option, + pub local_color_table: Option, pub indicies: Vec, } @@ -36,8 +36,7 @@ impl IndexedImage { // Get the mcs while we write out the color table let mut mcs = if let Some(lct) = &self.local_color_table { - boxed = lct.into(); - out.extend_from_slice(&*boxed); + out.extend_from_slice(&lct.as_bytes()); lct.packed_len() + 1 } else { @@ -70,7 +69,7 @@ impl IndexedImage { pub struct CompressedImage { pub image_descriptor: ImageDescriptor, - pub local_color_table: Option, + pub local_color_table: Option, pub lzw_minimum_code_size: u8, pub blocks: Vec>, } diff --git a/gifed/src/block/mod.rs b/gifed/src/block/mod.rs index 28f8c86..06f3d9a 100644 --- a/gifed/src/block/mod.rs +++ b/gifed/src/block/mod.rs @@ -1,15 +1,15 @@ -mod colortable; pub mod extension; mod imagedescriptor; mod indexedimage; pub mod packed; +mod palette; mod screendescriptor; mod version; -pub use colortable::ColorTable; pub use imagedescriptor::ImageDescriptor; pub use indexedimage::CompressedImage; pub use indexedimage::IndexedImage; +pub use palette::Palette; pub use screendescriptor::ScreenDescriptor; pub use version::Version; diff --git a/gifed/src/block/palette.rs b/gifed/src/block/palette.rs new file mode 100644 index 0000000..f43a67c --- /dev/null +++ b/gifed/src/block/palette.rs @@ -0,0 +1,117 @@ +pub use crate::Color; +use crate::EncodingError; +use std::{ + convert::{TryFrom, TryInto}, + ops::Deref, +}; + +#[derive(Clone, Debug)] +pub struct Palette { + table: Vec, +} + +impl Palette { + pub fn new() -> Self { + Self { table: vec![] } + } + + /// Returns the number of colors in the color table as used by the packed + /// fields in the Logical Screen Descriptor and Image Descriptor. You can + /// get the actual size with the [`len`](struct.ColorTable.html#method.len) method. + /// + /// This value is equal to `log2([Palette::len]) - 1`. In other words, 2^(n + 1) will + /// give you the same value as [Palette::len]. (where `n` is the value returned) + pub fn packed_len(&self) -> u8 { + ((self.table.len() as f32).log2().ceil() - 1f32) as u8 + } + + /// Returns the number of items in the table + pub fn len(&self) -> usize { + self.table.len() + } + + /// Pushes a color on to the end of the table + pub fn push(&mut self, color: Color) { + self.table.push(color); + } + + pub fn get(&self, index: u8) -> Option { + self.table.get(index as usize).map(|v| v.clone()) + } + + pub fn from_color>(&self, color: C) -> Option { + for (i, &c) in self.table.iter().enumerate() { + if c == *color.as_ref() { + return Some(i as u8); + } + } + None + } + + pub fn as_bytes(&self) -> Vec { + let mut bytes = Vec::with_capacity(self.table.len() * 3); + for color in &self.table { + bytes.extend_from_slice(&[color.r, color.g, color.b]); + } + + bytes + } +} + +impl Deref for Palette { + type Target = [Color]; + + fn deref(&self) -> &Self::Target { + &self.table + } +} + +impl AsRef for Palette { + fn as_ref(&self) -> &Palette { + self + } +} + +//TODO: TryFrom Vec (must be multiple of 3 len) and From Vec +impl TryFrom<&[u8]> for Palette { + type Error = (); + + fn try_from(value: &[u8]) -> Result { + if value.len() % 3 != 0 { + return Err(()); + } else { + Ok(Self { + table: value + .chunks(3) + .map(|slice| Color::from(TryInto::<[u8; 3]>::try_into(slice).unwrap())) + .collect::>(), + }) + } + } +} + +impl TryFrom> for Palette { + type Error = EncodingError; + + fn try_from(value: Vec) -> Result { + if value.len() > 256 { + Err(EncodingError::TooManyColors) + } else { + Ok(Self { table: value }) + } + } +} + +impl TryFrom> for Palette { + type Error = EncodingError; + + fn try_from(value: Vec<(u8, u8, u8)>) -> Result { + if value.len() > 256 { + Err(EncodingError::TooManyColors) + } else { + Ok(Self { + table: value.into_iter().map(|c| c.into()).collect(), + }) + } + } +} diff --git a/gifed/src/block/screendescriptor.rs b/gifed/src/block/screendescriptor.rs index 6b318b5..766ad66 100644 --- a/gifed/src/block/screendescriptor.rs +++ b/gifed/src/block/screendescriptor.rs @@ -1,6 +1,6 @@ use std::convert::TryInto; -use super::{packed::ScreenPacked, ColorTable}; +use super::{packed::ScreenPacked, Palette}; pub struct ScreenDescriptor { pub width: u16, @@ -23,7 +23,7 @@ impl ScreenDescriptor { /// This data structure **does not** contain the color table, only a flag to /// indicate if one is present and it's size. - pub fn set_color_table_metadata>(&mut self, table: Option) { + pub fn set_color_table_metadata>(&mut self, table: Option) { if let Some(table) = table { let table = table.as_ref(); self.packed.set_color_table(true); diff --git a/gifed/src/colorimage.rs b/gifed/src/colorimage.rs index 8b817de..8c42768 100644 --- a/gifed/src/colorimage.rs +++ b/gifed/src/colorimage.rs @@ -3,7 +3,7 @@ use std::{ ops::{Deref, DerefMut, Index}, }; -use crate::{block::ColorTable, color::Rgb, gif::Image, reader::DecodingError, Color}; +use crate::{block::Palette, color::Rgb, gif::Image, reader::DecodingError, Color}; /// An RGBA, full color image pub struct RgbaImage { @@ -21,7 +21,7 @@ impl RgbaImage { top: u16, left: u16, indicies: &[u8], - table: &ColorTable, + table: &Palette, transindex: Option, ) -> Result { let mut data = vec![0; width as usize * height as usize * 4]; diff --git a/gifed/src/gif.rs b/gifed/src/gif.rs index c4fb66c..3fc8e50 100644 --- a/gifed/src/gif.rs +++ b/gifed/src/gif.rs @@ -1,11 +1,11 @@ -use std::{convert::TryInto, fs::File, io::Write, iter::Peekable, path::Path, time::Duration}; +use std::{convert::TryInto, fs::File, io::Write, path::Path, time::Duration}; use crate::{ block::{ encode_block, extension::{DisposalMethod, GraphicControl}, packed::ImagePacked, - Block, ColorTable, ScreenDescriptor, Version, + Block, Palette, ScreenDescriptor, Version, }, colorimage::{RgbImage, RgbaImage}, reader::DecodingError, @@ -15,7 +15,7 @@ use crate::{ pub struct Gif { pub header: Version, pub screen_descriptor: ScreenDescriptor, - pub global_color_table: Option, + pub global_color_table: Option, pub blocks: Vec, // Trailer at the end of this struct is 0x3B // } @@ -35,8 +35,7 @@ impl Gif { // While we output the color table, grab it's length to use when // outputting the image, or 0 if we don't have a GCT let mcs = if let Some(gct) = &self.global_color_table { - boxed = gct.into(); - out.extend_from_slice(&*boxed); + out.extend_from_slice(&gct.as_bytes()); gct.packed_len() } else { @@ -128,7 +127,7 @@ pub struct Image<'a> { pub left_offset: u16, pub top_offset: u16, pub packed: ImagePacked, - pub palette: &'a ColorTable, + pub palette: &'a Palette, pub indicies: &'a [u8], pub blocks: &'a [Block], } diff --git a/gifed/src/reader/mod.rs b/gifed/src/reader/mod.rs index e852d26..bd7d08a 100644 --- a/gifed/src/reader/mod.rs +++ b/gifed/src/reader/mod.rs @@ -11,8 +11,7 @@ use std::{ use crate::{ block::{ extension::{Application, GraphicControl}, - Block, ColorTable, CompressedImage, ImageDescriptor, IndexedImage, ScreenDescriptor, - Version, + Block, CompressedImage, ImageDescriptor, IndexedImage, Palette, ScreenDescriptor, Version, }, color, Gif, }; @@ -65,16 +64,13 @@ impl GifReader { }) } - fn read_color_table( - reader: &mut SmartReader, - size: usize, - ) -> Result { + fn read_color_table(reader: &mut SmartReader, size: usize) -> Result { let buffer = reader .take(size as usize) .ok_or(DecodingError::UnexpectedEof)?; // We get the size from the screen descriptor. This should never return Err - Ok(ColorTable::try_from(&buffer[..]).unwrap()) + Ok(Palette::try_from(&buffer[..]).unwrap()) } fn read_block(reader: &mut SmartReader) -> Result, DecodingError> { diff --git a/gifed/src/writer/gifbuilder.rs b/gifed/src/writer/gifbuilder.rs index 2141fc7..f02862b 100644 --- a/gifed/src/writer/gifbuilder.rs +++ b/gifed/src/writer/gifbuilder.rs @@ -1,7 +1,7 @@ use std::convert::TryInto; use crate::block::packed::ScreenPacked; -use crate::block::{Block, ColorTable, LoopCount, ScreenDescriptor, Version}; +use crate::block::{Block, LoopCount, Palette, ScreenDescriptor, Version}; use crate::writer::ImageBuilder; use crate::{EncodingError, Gif}; @@ -10,7 +10,7 @@ pub struct GifBuilder { width: u16, height: u16, background_color_index: u8, - global_color_table: Option, + global_color_table: Option, blocks: Vec, error: Option, } @@ -28,7 +28,7 @@ impl GifBuilder { } } - pub fn palette(mut self, palette: ColorTable) -> Self { + pub fn palette(mut self, palette: Palette) -> Self { self.global_color_table = Some(palette); self } diff --git a/gifed/src/writer/imagebuilder.rs b/gifed/src/writer/imagebuilder.rs index c2ffd1a..1f1d67c 100644 --- a/gifed/src/writer/imagebuilder.rs +++ b/gifed/src/writer/imagebuilder.rs @@ -2,7 +2,7 @@ use crate::{ block::{ extension::{DisposalMethod, GraphicControl}, packed::ImagePacked, - ColorTable, ImageDescriptor, IndexedImage, Version, + ImageDescriptor, IndexedImage, Palette, Version, }, EncodingError, }; @@ -12,7 +12,7 @@ pub struct ImageBuilder { top_offset: u16, width: u16, height: u16, - color_table: Option, + color_table: Option, delay: u16, disposal_method: DisposalMethod, @@ -42,7 +42,7 @@ impl ImageBuilder { self } - pub fn palette(mut self, table: ColorTable) -> Self { + pub fn palette(mut self, table: Palette) -> Self { self.color_table = Some(table); self } -- cgit 1.4.1-3-g733a5