I'm writing a program for hiding data in PNG files. The problem I have is reading data in the form of &[u8]
(or Vec<u8>
) bit by bit.
struct Data {
bytes: Vec<u8>,
index: usize,
}
impl Data {
fn read_bits(&mut self, n: usize) -> u8 {
// this function is the issue I don't know how to
// do this I want this function to read n bits from
// self.bytes and return them.
// if the current read byte is 0b11001011 and n = 2
// the function should return 0b11 as u8 and update
// self.index to make sure the next read returns
// 0b10 aka the next 2 bits from 0b11001011
}
}
The reason why I need the data in this form is I want to replace the least-significant bits of the color values in a png with the bits from a Vec<u8>
let mut red = ...; // the red channel from a pixel
red = red & 0b11111100; // remove the last 2 bits
red = red + data.read_bits(2); // read two bits from data and add it to the red channel
Probably not the most performant but should be what you need.
struct BitIter<'a> {
data: &'a [u8],
index: usize
}
impl<'a> BitIter<'a> {
fn next_n(&mut self, n: usize) -> u8 {
let mut bits = 0;
for i in 0..n {
let bit = self.next().unwrap();
bits |= bit << i;
}
bits
}
}
impl<'a> Iterator for BitIter<'a> {
type Item = u8;
fn next(&mut self) -> Option<u8> {
if self.index < self.data.len() * 8 {
let bit = (self.data[self.index / 8] >> (self.index % 8)) & 1;
self.index += 1;
Some(bit)
} else {
None
}
}
}