diff options
author | Genny <gen@nyble.dev> | 2022-11-24 22:15:20 -0600 |
---|---|---|
committer | Genny <gen@nyble.dev> | 2022-11-24 22:15:20 -0600 |
commit | ac8578823b9ef467dc58a6afd5f7f4adfdb4c8bd (patch) | |
tree | 62e6c61feaf1fd63eb09f04d74dd179611aac991 /gifed/src | |
parent | 8d0ed482d292e0a8fe8ea7c0c83b0fdb2d786729 (diff) | |
download | gifed-ac8578823b9ef467dc58a6afd5f7f4adfdb4c8bd.tar.gz gifed-ac8578823b9ef467dc58a6afd5f7f4adfdb4c8bd.zip |
Add write example, remove bad read example
Diffstat (limited to 'gifed/src')
-rw-r--r-- | gifed/src/block/indexedimage.rs | 8 | ||||
-rw-r--r-- | gifed/src/block/mod.rs | 10 | ||||
-rw-r--r-- | gifed/src/block/palette.rs | 4 | ||||
-rw-r--r-- | gifed/src/block/screendescriptor.rs | 16 | ||||
-rw-r--r-- | gifed/src/block/version.rs | 6 | ||||
-rw-r--r-- | gifed/src/gif.rs | 18 | ||||
-rw-r--r-- | gifed/src/writer/gifbuilder.rs | 12 |
7 files changed, 46 insertions, 28 deletions
diff --git a/gifed/src/block/indexedimage.rs b/gifed/src/block/indexedimage.rs index 25eadbe..d27d463 100644 --- a/gifed/src/block/indexedimage.rs +++ b/gifed/src/block/indexedimage.rs @@ -33,9 +33,13 @@ impl IndexedImage { /// LZW Minimum Code Size here. It is equal to the value of [Palette::packed_len], but /// must also be at least 2. pub fn compress(self, lzw_code_size: Option<u8>) -> Result<CompressedImage, EncodeError> { - //TODO: gen- The old code had a +1 here. Why? + // gen- The old code had a +1 here. Why? + // In the spec, under the section for the Logical Screen Descriptor, it + // mentions that the size in the packed field is calculated with + // 2 ^ (packed + 1) and the code size is supposed to be the "number + // of color bits", which I guess is the exponent? let mcs = match self.local_color_table.as_ref() { - Some(palette) => palette.packed_len(), + Some(palette) => palette.lzw_code_size(), None => match lzw_code_size { None => return Err(EncodeError::InvalidCodeSize { lzw_code_size: 0 }), Some(mcs) => mcs, diff --git a/gifed/src/block/mod.rs b/gifed/src/block/mod.rs index 99075cf..5eb8a78 100644 --- a/gifed/src/block/mod.rs +++ b/gifed/src/block/mod.rs @@ -38,7 +38,15 @@ pub enum LoopCount { Number(u16), } -pub(crate) fn encode_block(mcs: u8, block: &Block) -> Vec<u8> { +impl LoopCount { + /// Set a fixed loop count. A value of 0 means forever, which you should + /// probably use [LoopCount::Forever] for. + pub fn count(count: u16) -> Self { + Self::Number(count) + } +} + +pub(crate) fn encode_block(block: &Block) -> Vec<u8> { match block { Block::CompressedImage(img) => img.as_bytes(), Block::GraphicControlExtension(_) => encode_extension(block), diff --git a/gifed/src/block/palette.rs b/gifed/src/block/palette.rs index 8f58b40..f2f4de3 100644 --- a/gifed/src/block/palette.rs +++ b/gifed/src/block/palette.rs @@ -25,6 +25,10 @@ impl Palette { ((self.table.len() as f32).log2().ceil() - 1f32) as u8 } + pub fn lzw_code_size(&self) -> u8 { + self.packed_len() + 1 + } + /// Returns the number of items in the table pub fn len(&self) -> usize { self.table.len() diff --git a/gifed/src/block/screendescriptor.rs b/gifed/src/block/screendescriptor.rs index 766ad66..aaeea53 100644 --- a/gifed/src/block/screendescriptor.rs +++ b/gifed/src/block/screendescriptor.rs @@ -42,18 +42,16 @@ impl ScreenDescriptor { pub fn color_table_len(&self) -> usize { crate::packed_to_color_table_length(self.packed.color_table_size()) } -} -impl From<&ScreenDescriptor> for Box<[u8]> { - fn from(lsd: &ScreenDescriptor) -> Self { + pub fn as_bytes(&self) -> Vec<u8> { let mut vec = vec![]; - vec.extend_from_slice(&lsd.width.to_le_bytes()); - vec.extend_from_slice(&lsd.height.to_le_bytes()); - vec.push(lsd.packed.raw); - vec.push(lsd.background_color_index); - vec.push(lsd.pixel_aspect_ratio); + vec.extend_from_slice(&self.width.to_le_bytes()); + vec.extend_from_slice(&self.height.to_le_bytes()); + vec.push(self.packed.raw); + vec.push(self.background_color_index); + vec.push(self.pixel_aspect_ratio); - vec.into_boxed_slice() + vec } } diff --git a/gifed/src/block/version.rs b/gifed/src/block/version.rs index 0171ad4..c26ebb5 100644 --- a/gifed/src/block/version.rs +++ b/gifed/src/block/version.rs @@ -6,6 +6,12 @@ pub enum Version { Gif89a, } +impl Version { + pub fn as_bytes(&self) -> &[u8] { + self.into() + } +} + impl From<&Version> for &[u8] { fn from(version: &Version) -> Self { match version { diff --git a/gifed/src/gif.rs b/gifed/src/gif.rs index 5ee6906..fd3a322 100644 --- a/gifed/src/gif.rs +++ b/gifed/src/gif.rs @@ -24,23 +24,15 @@ impl Gif { pub fn as_bytes(&self) -> Vec<u8> { let mut out = vec![]; - out.extend_from_slice((&self.header).into()); + out.extend_from_slice(&self.header.as_bytes()); + out.extend_from_slice(&self.screen_descriptor.as_bytes()); - let mut boxed: Box<[u8]> = (&self.screen_descriptor).into(); - out.extend_from_slice(&*boxed); - - // 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 { + if let Some(gct) = &self.global_color_table { out.extend_from_slice(&gct.as_bytes()); - - gct.packed_len() - } else { - 0 - }; + } for block in self.blocks.iter() { - out.extend_from_slice(&encode_block(mcs, block)); + out.extend_from_slice(&encode_block(block)); } // Write Trailer diff --git a/gifed/src/writer/gifbuilder.rs b/gifed/src/writer/gifbuilder.rs index 3e26c24..4ea88ec 100644 --- a/gifed/src/writer/gifbuilder.rs +++ b/gifed/src/writer/gifbuilder.rs @@ -2,8 +2,8 @@ use std::io::Write; use crate::{ block::{ - packed::ScreenPacked, Block, CompressedImage, IndexedImage, Palette, ScreenDescriptor, - Version, + packed::ScreenPacked, Block, CompressedImage, IndexedImage, LoopCount, Palette, + ScreenDescriptor, Version, }, EncodeError, Gif, }; @@ -48,6 +48,12 @@ impl GifBuilder { self } + pub fn repeat(mut self, count: LoopCount) -> Self { + self.blocks + .push(BuildBlock::Block(Block::LoopingExtension(count))); + self + } + pub fn image<I: Into<EncodeImage>>(mut self, img: I) -> Self { match img.into() { EncodeImage::CompressedImage(ci) => self @@ -87,7 +93,7 @@ impl GifBuilder { blocks: vec![], }; - let lzw_gct_size = gif.global_color_table.as_ref().map(|ct| ct.packed_len()); + let lzw_gct_size = gif.global_color_table.as_ref().map(|ct| ct.lzw_code_size()); for block in self.blocks { match block { |