From c75aa98ce237f22f282595188d5fb48cadaaa329 Mon Sep 17 00:00:00 2001 From: Stephen Judkins Date: Tue, 9 Apr 2024 23:02:19 -0700 Subject: [PATCH] bit-addressable output (doesn't work yet) --- Cargo.toml | 1 + src/decoder/image.rs | 39 ++++++++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ab2b849..3b021b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ flate2 = { version = "1.0.20", optional = true } weezl = { version = "0.1.10", optional = true } zstd = { version = "0.13", optional = true } zune-jpeg = { version = "0.4.17", optional = true } +bitvec = "1.0.1" [dev-dependencies] criterion = "0.3.1" diff --git a/src/decoder/image.rs b/src/decoder/image.rs index 12752e4..868a13e 100644 --- a/src/decoder/image.rs +++ b/src/decoder/image.rs @@ -12,7 +12,6 @@ use crate::{ #[cfg(feature = "fax")] use std::collections::VecDeque; - use std::io::{self, Cursor, Read, Seek}; use std::num::NonZeroUsize; use std::sync::Arc; @@ -465,7 +464,8 @@ impl Image { struct Group4Reader { decoder: fax::decoder::Group4Decoder>, - line_buf: VecDeque, + bits: bitvec::vec::BitVec, + byte_buf: VecDeque, y: u16, height: u16, width: u16, @@ -473,30 +473,38 @@ impl Image { impl Read for Group4Reader { fn read(&mut self, buf: &mut [u8]) -> io::Result { - if self.line_buf.is_empty() && self.y < self.height { + if self.byte_buf.is_empty() && self.y < self.height { let next = self .decoder .advance() .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?; match next { - fax::decoder::DecodeStatus::End => (), + fax::decoder::DecodeStatus::End => { + // eprintln!("DONE!"); + self.byte_buf.extend(self.bits.as_raw_slice()) + } fax::decoder::DecodeStatus::Incomplete => { self.y += 1; - self.line_buf.extend( - // all extant tiff/fax4 decoders I've found always assume that the photometric interpretation - // is `WhiteIsZero`, ignoring the tag. ImageMagick appears to generate fax4-encoded tiffs - // with the tag incorrectly set to `BlackIsZero`. + // eprintln!("{:?}", self.y); + for c in fax::decoder::pels(self.decoder.transition(), self.width) - .map(|c| match c { - fax::Color::Black => 255, - fax::Color::White => 0, - }), - ); + { + self.bits.push(match c { + fax::Color::Black => true, + fax::Color::White => false, + }); + if self.bits.len() == 8 { + self.byte_buf.extend(self.bits.as_raw_slice()); + self.bits.clear() + } + } } } } - self.line_buf.read(buf) + // eprintln!("{:?}: {:?} / {:?}", self.y, self.byte_buf.len(), self.bits.len()); + + self.byte_buf.read(buf) } } @@ -505,7 +513,8 @@ impl Image { reader.take(compressed_length).bytes(), width, )?, - line_buf: VecDeque::with_capacity(usize::from(width)), + bits: bitvec::vec::BitVec::new(), + byte_buf: VecDeque::new(), y: 0, width: width, height: height,