diff options
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | src/main.rs | 2 | ||||
| -rw-r--r-- | src/ppm.rs | 82 | ||||
| -rw-r--r-- | test.gif | bin | 0 -> 31147 bytes | |||
| -rw-r--r-- | test.png | bin | 0 -> 943 bytes |
5 files changed, 44 insertions, 43 deletions
@@ -27,9 +27,6 @@ byteorder = "1.4.3" # Time chrono = "0.4.19" -# Generators -generator = "0.7.0" - # Image encoding image = "0.24.1" diff --git a/src/main.rs b/src/main.rs index 7d10479..8541135 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ // Copyright (C) 2022-2022 Fuwn <[email protected]> // SPDX-License-Identifier: MIT -#![feature(decl_macro)] +#![feature(decl_macro, generators, generator_trait)] #![deny( warnings, nonstandard_style, @@ -7,6 +7,7 @@ use std::{ collections::HashMap, fs, io::{Cursor, Read}, + ops::Generator, }; use byteorder::{LittleEndian, ReadBytesExt}; @@ -316,15 +317,13 @@ impl PPMParser { self.stream.read_uint::<LittleEndian>(1).unwrap() >> 7 & 0x1 != 0 } - fn read_line_types(line_types: Vec<u8>) -> generator::Generator<'static, (), (usize, u8)> { - generator::Gn::new_scoped(move |mut s| { + fn read_line_types(line_types: Vec<u8>) -> impl Generator<Yield = (usize, u8), Return = ()> { + move || { for index in 0..192 { let line_type = line_types.get(index / 4).unwrap() >> ((index % 4) * 2) & 0x03; - s.yield_((index, line_type)); + yield (index, line_type); } - - generator::done!(); - }) + } } fn read_frame(&mut self, index: usize) -> &Vec<Vec<Vec<u8>>> { @@ -370,29 +369,47 @@ impl PPMParser { for layer in 0..2 { let bitmap = &mut self.layers[layer]; - for (line, line_type) in Self::read_line_types(line_types[layer].clone()) { - let mut pixel = 0; - - // No data stored for this line - if line_type == 0 { - // pass; - } else if line_type == 1 || line_type == 2 { - // Compressed line - // If `line_type == 2`, the line starts off with all the pixels set to one - if line_type == 2 { - for i in 0..256 { - bitmap[line][i] = 1; + { + let mut generator = Self::read_line_types(line_types[layer].clone()); + while let std::ops::GeneratorState::Yielded((line, line_type)) = + std::pin::Pin::new(&mut generator).resume(()) + { + let mut pixel = 0; + + // No data stored for this line + if line_type == 0 { + // pass; + } else if line_type == 1 || line_type == 2 { + // Compressed line + // If `line_type == 2`, the line starts off with all the pixels set to one + if line_type == 2 { + for i in 0..256 { + bitmap[line][i] = 1; + } } - } - // Unpack chunk usage - let mut chunk_usage = self.stream.read_u32::<byteorder::BigEndian>().unwrap(); + // Unpack chunk usage + let mut chunk_usage = self.stream.read_u32::<byteorder::BigEndian>().unwrap(); + + // Unpack pixel chunks + while pixel < 256 { + if chunk_usage & 0x8000_0000 == 0 { + pixel += 8; + } else { + let chunk = self.stream.read_uint::<LittleEndian>(1).unwrap(); - // Unpack pixel chunks - while pixel < 256 { - if chunk_usage & 0x8000_0000 == 0 { - pixel += 8; - } else { + for bit in 0..8 { + bitmap[line][pixel] = (chunk >> bit & 0x1) as u8; + pixel += 1; + } + } + + chunk_usage <<= 1; + } + // Raw line + } else if line_type == 3 { + // Unpack pixel chunks + while pixel < 256 { let chunk = self.stream.read_uint::<LittleEndian>(1).unwrap(); for bit in 0..8 { @@ -400,19 +417,6 @@ impl PPMParser { pixel += 1; } } - - chunk_usage <<= 1; - } - // Raw line - } else if line_type == 3 { - // Unpack pixel chunks - while pixel < 256 { - let chunk = self.stream.read_uint::<LittleEndian>(1).unwrap(); - - for bit in 0..8 { - bitmap[line][pixel] = (chunk >> bit & 0x1) as u8; - pixel += 1; - } } } } diff --git a/test.gif b/test.gif Binary files differnew file mode 100644 index 0000000..6050f65 --- /dev/null +++ b/test.gif diff --git a/test.png b/test.png Binary files differnew file mode 100644 index 0000000..091c737 --- /dev/null +++ b/test.png |