Replace bit-vec

This commit is contained in:
Andrew 2022-11-04 19:47:37 +13:00
parent 19030b8c6a
commit f0a77e4777
4 changed files with 28 additions and 37 deletions

7
Cargo.lock generated
View file

@ -31,12 +31,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -380,7 +374,6 @@ checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
name = "oxipng" name = "oxipng"
version = "6.0.1" version = "6.0.1"
dependencies = [ dependencies = [
"bit-vec",
"bitvec", "bitvec",
"clap", "clap",
"crossbeam-channel", "crossbeam-channel",

View file

@ -23,7 +23,6 @@ path = "src/main.rs"
required-features = ["binary"] required-features = ["binary"]
[dependencies] [dependencies]
bit-vec = "0.6.3"
itertools = "0.10.3" itertools = "0.10.3"
zopfli = { version = "0.7.1", optional = true } zopfli = { version = "0.7.1", optional = true }
rgb = "0.8.33" rgb = "0.8.33"
@ -75,5 +74,5 @@ opt-level = 2
[profile.release] [profile.release]
lto = "thin" lto = "thin"
[profile.dev.package.bit-vec] [profile.dev.package.bitvec]
opt-level = 3 opt-level = 3

View file

@ -1,47 +1,47 @@
use crate::headers::IhdrData; use crate::headers::IhdrData;
use crate::png::PngImage; use crate::png::PngImage;
use bit_vec::BitVec; use bitvec::prelude::*;
#[must_use] #[must_use]
pub fn interlace_image(png: &PngImage) -> PngImage { pub fn interlace_image(png: &PngImage) -> PngImage {
let mut passes: Vec<BitVec> = vec![BitVec::new(); 7]; let mut passes: Vec<BitVec<u8, Msb0>> = vec![BitVec::new(); 7];
let bits_per_pixel = png.ihdr.bpp(); let bits_per_pixel = png.ihdr.bpp();
for (index, line) in png.scan_lines().enumerate() { for (index, line) in png.scan_lines().enumerate() {
match index % 8 { match index % 8 {
// Add filter bytes to passes that will be in the output image // Add filter bytes to passes that will be in the output image
0 => { 0 => {
passes[0].extend(BitVec::from_elem(8, false)); passes[0].extend_from_raw_slice(&[0]);
if png.ihdr.width >= 5 { if png.ihdr.width >= 5 {
passes[1].extend(BitVec::from_elem(8, false)); passes[1].extend_from_raw_slice(&[0]);
} }
if png.ihdr.width >= 3 { if png.ihdr.width >= 3 {
passes[3].extend(BitVec::from_elem(8, false)); passes[3].extend_from_raw_slice(&[0]);
} }
if png.ihdr.width >= 2 { if png.ihdr.width >= 2 {
passes[5].extend(BitVec::from_elem(8, false)); passes[5].extend_from_raw_slice(&[0]);
} }
} }
4 => { 4 => {
passes[2].extend(BitVec::from_elem(8, false)); passes[2].extend_from_raw_slice(&[0]);
if png.ihdr.width >= 3 { if png.ihdr.width >= 3 {
passes[3].extend(BitVec::from_elem(8, false)); passes[3].extend_from_raw_slice(&[0]);
} }
if png.ihdr.width >= 2 { if png.ihdr.width >= 2 {
passes[5].extend(BitVec::from_elem(8, false)); passes[5].extend_from_raw_slice(&[0]);
} }
} }
2 | 6 => { 2 | 6 => {
passes[4].extend(BitVec::from_elem(8, false)); passes[4].extend_from_raw_slice(&[0]);
if png.ihdr.width >= 2 { if png.ihdr.width >= 2 {
passes[5].extend(BitVec::from_elem(8, false)); passes[5].extend_from_raw_slice(&[0]);
} }
} }
_ => { _ => {
passes[6].extend(BitVec::from_elem(8, false)); passes[6].extend_from_raw_slice(&[0]);
} }
} }
let bit_vec = BitVec::from_bytes(line.data); let bit_vec = line.data.view_bits::<Msb0>();
for (i, bit) in bit_vec.iter().enumerate() { for (i, bit) in bit_vec.iter().by_vals().enumerate() {
// Avoid moving padded 0's into new image // Avoid moving padded 0's into new image
if i >= (png.ihdr.width * u32::from(bits_per_pixel)) as usize { if i >= (png.ihdr.width * u32::from(bits_per_pixel)) as usize {
break; break;
@ -79,7 +79,7 @@ pub fn interlace_image(png: &PngImage) -> PngImage {
let mut output = Vec::with_capacity(png.data.len()); let mut output = Vec::with_capacity(png.data.len());
for pass in &passes { for pass in &passes {
output.extend(pass.to_bytes()); output.extend_from_slice(pass.as_raw_slice());
} }
PngImage { PngImage {
@ -99,19 +99,19 @@ pub fn deinterlace_image(png: &PngImage) -> PngImage {
let bits_per_line = 8 + bits_per_pixel as usize * png.ihdr.width as usize; let bits_per_line = 8 + bits_per_pixel as usize * png.ihdr.width as usize;
// Initialize each output line with a starting filter byte of 0 // Initialize each output line with a starting filter byte of 0
// as well as some blank data // as well as some blank data
let mut lines: Vec<BitVec> = let mut lines: Vec<BitVec<u8, Msb0>> =
vec![BitVec::from_elem(bits_per_line, false); png.ihdr.height as usize]; vec![bitvec![u8, Msb0; 0; bits_per_line]; png.ihdr.height as usize];
let mut current_pass = 1; let mut current_pass = 1;
let mut pass_constants = interlaced_constants(current_pass); let mut pass_constants = interlaced_constants(current_pass);
let mut current_y: usize = pass_constants.y_shift as usize; let mut current_y: usize = pass_constants.y_shift as usize;
for line in png.scan_lines() { for line in png.scan_lines() {
let bit_vec = BitVec::from_bytes(line.data); let bit_vec = line.data.view_bits::<Msb0>();
let bits_in_line = ((png.ihdr.width - u32::from(pass_constants.x_shift) let bits_in_line = ((png.ihdr.width - u32::from(pass_constants.x_shift)
+ u32::from(pass_constants.x_step) + u32::from(pass_constants.x_step)
- 1) - 1)
/ u32::from(pass_constants.x_step)) as usize / u32::from(pass_constants.x_step)) as usize
* bits_per_pixel as usize; * bits_per_pixel as usize;
for (i, bit) in bit_vec.iter().enumerate() { for (i, bit) in bit_vec.iter().by_vals().enumerate() {
// Avoid moving padded 0's into new image // Avoid moving padded 0's into new image
if i >= bits_in_line { if i >= bits_in_line {
break; break;
@ -157,7 +157,7 @@ pub fn deinterlace_image(png: &PngImage) -> PngImage {
while line.len() % 8 != 0 { while line.len() % 8 != 0 {
line.push(false); line.push(false);
} }
output.extend(line.to_bytes()); output.extend_from_slice(line.as_raw_slice());
} }
PngImage { PngImage {
data: output, data: output,

View file

@ -1,7 +1,7 @@
use crate::colors::{BitDepth, ColorType}; use crate::colors::{BitDepth, ColorType};
use crate::headers::IhdrData; use crate::headers::IhdrData;
use crate::png::PngImage; use crate::png::PngImage;
use bit_vec::BitVec; use bitvec::prelude::*;
const ONE_BIT_PERMUTATIONS: [u8; 2] = [0b0000_0000, 0b1111_1111]; const ONE_BIT_PERMUTATIONS: [u8; 2] = [0b0000_0000, 0b1111_1111];
const TWO_BIT_PERMUTATIONS: [u8; 4] = [0b0000_0000, 0b0101_0101, 0b1010_1010, 0b1111_1111]; const TWO_BIT_PERMUTATIONS: [u8; 4] = [0b0000_0000, 0b0101_0101, 0b1010_1010, 0b1111_1111];
@ -108,8 +108,7 @@ pub fn reduce_bit_depth_8_or_less(png: &PngImage, mut minimum_bits: usize) -> Op
} }
} }
} else { } else {
let bit_vec = BitVec::from_bytes(line.data); for &byte in line.data {
for byte in bit_vec.to_bytes() {
while minimum_bits < bit_depth { while minimum_bits < bit_depth {
let permutations: &[u8] = if minimum_bits == 1 { let permutations: &[u8] = if minimum_bits == 1 {
&ONE_BIT_PERMUTATIONS &ONE_BIT_PERMUTATIONS
@ -129,11 +128,11 @@ pub fn reduce_bit_depth_8_or_less(png: &PngImage, mut minimum_bits: usize) -> Op
} }
} }
let mut reduced = BitVec::with_capacity(png.data.len() * 8); let mut reduced = BitVec::<u8, Msb0>::with_capacity(png.data.len() * 8);
for line in png.scan_lines() { for line in png.scan_lines() {
reduced.extend(BitVec::from_bytes(&[line.filter])); reduced.extend_from_raw_slice(&[line.filter]);
let bit_vec = BitVec::from_bytes(line.data); let bit_vec = line.data.view_bits::<Msb0>();
for (i, bit) in bit_vec.iter().enumerate() { for (i, bit) in bit_vec.iter().by_vals().enumerate() {
let bit_index = bit_depth - (i % bit_depth); let bit_index = bit_depth - (i % bit_depth);
if bit_index <= minimum_bits { if bit_index <= minimum_bits {
reduced.push(bit); reduced.push(bit);
@ -146,7 +145,7 @@ pub fn reduce_bit_depth_8_or_less(png: &PngImage, mut minimum_bits: usize) -> Op
} }
Some(PngImage { Some(PngImage {
data: reduced.to_bytes(), data: reduced.as_raw_slice().to_vec(),
ihdr: IhdrData { ihdr: IhdrData {
bit_depth: BitDepth::from_u8(minimum_bits as u8), bit_depth: BitDepth::from_u8(minimum_bits as u8),
..png.ihdr ..png.ihdr