逐位读取字节片&[u8]

问题描述 投票:0回答:1

我正在编写一个用于隐藏 PNG 文件中的数据的程序。我遇到的问题是以

&[u8]
(或
Vec<u8>
)形式一点一点地读取数据。


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
    }
}

我需要这种形式的数据的原因是我想用

Vec<u8>

中的位替换 png 中颜色值的最低有效位
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
rust stream byte bit
1个回答
0
投票

可能不是性能最好的,但应该是您所需要的。

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
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.