From 2a8df03dc636d3ee385ac35116186b12345855fb Mon Sep 17 00:00:00 2001 From: Fuwn Date: Tue, 1 Mar 2022 14:38:36 -0800 Subject: refactor(ppm): use rust generator instead of crate --- Cargo.toml | 3 --- src/main.rs | 2 +- src/ppm.rs | 82 +++++++++++++++++++++++++++++++----------------------------- test.gif | Bin 0 -> 31147 bytes test.png | Bin 0 -> 943 bytes 5 files changed, 44 insertions(+), 43 deletions(-) create mode 100644 test.gif create mode 100644 test.png diff --git a/Cargo.toml b/Cargo.toml index d0c7b28..50bcb84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 // SPDX-License-Identifier: MIT -#![feature(decl_macro)] +#![feature(decl_macro, generators, generator_trait)] #![deny( warnings, nonstandard_style, diff --git a/src/ppm.rs b/src/ppm.rs index f713ff1..06f696e 100644 --- a/src/ppm.rs +++ b/src/ppm.rs @@ -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::(1).unwrap() >> 7 & 0x1 != 0 } - fn read_line_types(line_types: Vec) -> generator::Generator<'static, (), (usize, u8)> { - generator::Gn::new_scoped(move |mut s| { + fn read_line_types(line_types: Vec) -> impl Generator { + 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>> { @@ -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::().unwrap(); + // Unpack chunk usage + let mut chunk_usage = self.stream.read_u32::().unwrap(); + + // Unpack pixel chunks + while pixel < 256 { + if chunk_usage & 0x8000_0000 == 0 { + pixel += 8; + } else { + let chunk = self.stream.read_uint::(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::(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::(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 new file mode 100644 index 0000000..6050f65 Binary files /dev/null and b/test.gif differ diff --git a/test.png b/test.png new file mode 100644 index 0000000..091c737 Binary files /dev/null and b/test.png differ -- cgit v1.2.3