about summary refs log tree commit diff
path: root/src/block
diff options
context:
space:
mode:
authorGenny <gen@nyble.dev>2021-09-23 20:33:50 -0500
committerGenny <gen@nyble.dev>2021-09-23 20:33:50 -0500
commit637441239434fabedfe83f5abc1af4232c802f7a (patch)
treedbc84cd1a31686077fc046fd42d223f1ca08f890 /src/block
parent7b8081a79fb3db4a76f9e4cca8f8a88e6e7f873c (diff)
downloadgifed-637441239434fabedfe83f5abc1af4232c802f7a.tar.gz
gifed-637441239434fabedfe83f5abc1af4232c802f7a.zip
Improve API, monocommit, sorry
Diffstat (limited to 'src/block')
-rw-r--r--src/block/colortable.rs47
-rw-r--r--src/block/extension/graphiccontrol.rs38
-rw-r--r--src/block/extension/mod.rs7
-rw-r--r--src/block/indexedimage.rs18
-rw-r--r--src/block/mod.rs10
-rw-r--r--src/block/screendescriptor.rs10
-rw-r--r--src/block/version.rs1
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,