diff options
Diffstat (limited to 'src/block')
-rw-r--r-- | src/block/colortable.rs | 47 | ||||
-rw-r--r-- | src/block/extension/graphiccontrol.rs | 38 | ||||
-rw-r--r-- | src/block/extension/mod.rs | 7 | ||||
-rw-r--r-- | src/block/indexedimage.rs | 18 | ||||
-rw-r--r-- | src/block/mod.rs | 10 | ||||
-rw-r--r-- | src/block/screendescriptor.rs | 10 | ||||
-rw-r--r-- | src/block/version.rs | 1 |
7 files changed, 117 insertions, 14 deletions
diff --git a/src/block/colortable.rs b/src/block/colortable.rs index da9458c..d8241f7 100644 --- a/src/block/colortable.rs +++ b/src/block/colortable.rs @@ -1,9 +1,11 @@ pub use crate::Color; +use crate::EncodingError; use std::{ convert::{TryFrom, TryInto}, ops::Deref, }; +#[derive(Clone, Debug)] pub struct ColorTable { table: Vec<Color>, } @@ -29,6 +31,19 @@ impl ColorTable { pub fn push(&mut self, color: Color) { self.table.push(color); } + + pub fn get(&self, index: u8) -> Option<Color> { + self.table.get(index as usize).map(|v| v.clone()) + } + + pub fn from_color(&self, color: Color) -> Option<u8> { + for (i, &c) in self.table.iter().enumerate() { + if c == color { + return Some(i as u8); + } + } + None + } } impl Deref for ColorTable { @@ -39,12 +54,6 @@ impl Deref for ColorTable { } } -impl From<Vec<Color>> for ColorTable { - fn from(table: Vec<Color>) -> Self { - ColorTable { table } - } -} - impl From<&ColorTable> for Box<[u8]> { fn from(table: &ColorTable) -> Self { let mut vec = vec![]; @@ -80,3 +89,29 @@ impl TryFrom<&[u8]> for ColorTable { } } } + +impl TryFrom<Vec<Color>> for ColorTable { + type Error = EncodingError; + + fn try_from(value: Vec<Color>) -> Result<Self, Self::Error> { + if value.len() > 256 { + Err(EncodingError::TooManyColors) + } else { + Ok(Self { table: value }) + } + } +} + +impl TryFrom<Vec<(u8, u8, u8)>> for ColorTable { + type Error = EncodingError; + + fn try_from(value: Vec<(u8, u8, u8)>) -> Result<Self, Self::Error> { + if value.len() > 256 { + Err(EncodingError::TooManyColors) + } else { + Ok(Self { + table: value.into_iter().map(|c| c.into()).collect(), + }) + } + } +} diff --git a/src/block/extension/graphiccontrol.rs b/src/block/extension/graphiccontrol.rs index 0d4edd1..830dff4 100644 --- a/src/block/extension/graphiccontrol.rs +++ b/src/block/extension/graphiccontrol.rs @@ -1,4 +1,4 @@ -use std::convert::TryInto; +use std::{convert::TryInto, fmt}; #[derive(Clone, Debug)] pub struct GraphicControl { @@ -21,22 +21,36 @@ impl GraphicControl { transparency_index, }; - ret.disposal_method(disposal_method); + ret.set_disposal_method(disposal_method); ret.user_input(user_input_flag); ret.transparency(transparency_flag); ret } - pub fn disposal_method(&mut self, method: DisposalMethod) { + pub fn disposal_method(&self) -> Option<DisposalMethod> { + match self.packed & 0b000_111_00 { + 0b000_000_00 => Some(DisposalMethod::NoAction), + 0b000_100_00 => Some(DisposalMethod::DoNotDispose), + 0b000_010_00 => Some(DisposalMethod::RestoreBackground), + 0b000_110_00 => Some(DisposalMethod::RestorePrevious), + _ => None, + } + } + + pub fn set_disposal_method(&mut self, method: DisposalMethod) { match method { - DisposalMethod::Clear => self.packed &= 0b111_000_1_1, + DisposalMethod::NoAction => self.packed &= 0b111_000_1_1, DisposalMethod::DoNotDispose => self.packed |= 0b000_100_0_0, DisposalMethod::RestoreBackground => self.packed |= 0b000_010_0_0, DisposalMethod::RestorePrevious => self.packed |= 0b000_110_0_0, }; } + pub fn transparency_index(&self) -> u8 { + self.transparency_index + } + pub fn user_input(&mut self, flag: bool) { if flag { self.packed |= 0b000_000_1_0; @@ -78,9 +92,23 @@ impl From<[u8; 4]> for GraphicControl { } } +#[derive(Clone, Copy, Debug, PartialEq)] pub enum DisposalMethod { - Clear, + NoAction, DoNotDispose, RestoreBackground, RestorePrevious, } + +impl fmt::Display for DisposalMethod { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let st = match self { + DisposalMethod::NoAction => "Dispose as Normal", + DisposalMethod::DoNotDispose => "No Dispose", + DisposalMethod::RestoreBackground => "Restore to background", + DisposalMethod::RestorePrevious => "Restore previous image", + }; + + write!(f, "{}", st) + } +} diff --git a/src/block/extension/mod.rs b/src/block/extension/mod.rs index d0e57c6..f328357 100644 --- a/src/block/extension/mod.rs +++ b/src/block/extension/mod.rs @@ -2,6 +2,7 @@ mod application; mod graphiccontrol; pub use graphiccontrol::{DisposalMethod, GraphicControl}; +use owo_colors::colors::xterm::GrandisCaramel; pub use self::application::Application; @@ -41,3 +42,9 @@ impl From<&Extension> for Box<[u8]> { vec.into_boxed_slice() } } + +impl From<GraphicControl> for Extension { + fn from(gce: GraphicControl) -> Self { + Extension::GraphicControl(gce) + } +} diff --git a/src/block/indexedimage.rs b/src/block/indexedimage.rs index 52be3d5..0be066f 100644 --- a/src/block/indexedimage.rs +++ b/src/block/indexedimage.rs @@ -10,6 +10,22 @@ pub struct IndexedImage { } impl IndexedImage { + pub fn left(&self) -> u16 { + self.image_descriptor.left + } + + pub fn top(&self) -> u16 { + self.image_descriptor.left + } + + pub fn width(&self) -> u16 { + self.image_descriptor.width + } + + pub fn height(&self) -> u16 { + self.image_descriptor.height + } + pub fn as_boxed_slice(&self, minimum_code_size: u8) -> Box<[u8]> { let mut out = vec![]; @@ -46,7 +62,7 @@ impl IndexedImage { } } -pub struct BlockedImage { +pub struct CompressedImage { pub image_descriptor: ImageDescriptor, pub local_color_table: Option<ColorTable>, pub lzw_minimum_code_size: u8, diff --git a/src/block/mod.rs b/src/block/mod.rs index e3136bf..645c11d 100644 --- a/src/block/mod.rs +++ b/src/block/mod.rs @@ -7,13 +7,19 @@ mod version; pub use colortable::ColorTable; pub use imagedescriptor::ImageDescriptor; -pub use indexedimage::BlockedImage; +pub use indexedimage::CompressedImage; pub use indexedimage::IndexedImage; pub use screendescriptor::ScreenDescriptor; pub use version::Version; +use crate::writer::ImageBuilder; + pub enum Block { IndexedImage(IndexedImage), - BlockedImage(BlockedImage), Extension(extension::Extension), } + +enum WriteBlock { + ImageBuilder(ImageBuilder), + Block(Block), +} diff --git a/src/block/screendescriptor.rs b/src/block/screendescriptor.rs index ff70896..444b44f 100644 --- a/src/block/screendescriptor.rs +++ b/src/block/screendescriptor.rs @@ -9,6 +9,16 @@ pub struct ScreenDescriptor { } impl ScreenDescriptor { + pub fn new(width: u16, height: u16) -> Self { + Self { + width, + height, + packed: 0, + background_color_index: 0, + pixel_aspect_ratio: 0, + } + } + pub fn set_color_table_present(&mut self, is_present: bool) { if is_present { self.packed |= 0b1000_0000; diff --git a/src/block/version.rs b/src/block/version.rs index b785f27..c52439c 100644 --- a/src/block/version.rs +++ b/src/block/version.rs @@ -1,5 +1,6 @@ use std::fmt; +#[derive(Clone, Copy, Debug, PartialEq)] pub enum Version { Gif87a, Gif89a, |