Tile-level RLE
This commit is contained in:
parent
4edf6831d0
commit
90d1c5c4ef
@ -11,6 +11,7 @@ struct CoefTile {
|
||||
coefs: [i16; TILE_SZ2]
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct QuantTile {
|
||||
quants: [i16; TILE_SZ2]
|
||||
}
|
||||
@ -53,8 +54,10 @@ pub fn compress<W: Write>(
|
||||
for t in tiles.iter() {
|
||||
t.write_zero(writer)?;
|
||||
}
|
||||
for t in tiles.iter() {
|
||||
t.write_rest(writer)?;
|
||||
for ti in 0..tiles.len() {
|
||||
let prev = if ti > 0 { Some(tiles[ti - 1]) } else { None };
|
||||
let t = tiles[ti];
|
||||
t.write_rest(prev, writer)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -116,9 +119,28 @@ impl QuantTile {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_rest<W: Write>(&self, writer: &mut ProtocolWriter<W>) -> ProtocolWriterResult<()> {
|
||||
for i in 1..self.quants.len() {
|
||||
fn write_rest<W: Write>(&self, prev: Option<QuantTile>, writer: &mut ProtocolWriter<W>) -> ProtocolWriterResult<()> {
|
||||
if let Some(p) = prev {
|
||||
if self.quants[1..] == p.quants[1..] {
|
||||
// 255 zeroes can also encode "copy the rest from the previous tile"
|
||||
writer.write_u8_wide(0xff)?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let mut i = 0;
|
||||
loop {
|
||||
let mut zeros: u8 = 0;
|
||||
while i < TILE_SZ2 && self.quants[i] == 0 {
|
||||
zeros += 1;
|
||||
i += 1;
|
||||
}
|
||||
writer.write_u8_wide(zeros)?;
|
||||
|
||||
if i >= TILE_SZ2 { break; }
|
||||
|
||||
writer.write_i16_packed(self.quants[i])?;
|
||||
i += 1;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ struct CoefTile {
|
||||
coefs: [i16; TILE_SZ2]
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct QuantTile {
|
||||
quants: [i16; TILE_SZ2]
|
||||
}
|
||||
@ -42,7 +42,11 @@ pub fn decompress<R: Read>(
|
||||
tiles[i].load_zero(reader)?;
|
||||
}
|
||||
for i in 0..n_tiles {
|
||||
tiles[i].load_rest(reader)?;
|
||||
let prev = if i > 0 { Some(tiles[i - 1]) } else { None };
|
||||
tiles[i].load_rest(
|
||||
prev,
|
||||
reader
|
||||
)?;
|
||||
}
|
||||
|
||||
let mut tile_i = 0;
|
||||
@ -120,10 +124,28 @@ impl QuantTile {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load_rest<R: Read>(&mut self, reader: &mut ProtocolReader<R>) -> ProtocolReaderResult<()> {
|
||||
for i in 1..self.quants.len() {
|
||||
fn load_rest<R: Read>(&
|
||||
mut self,
|
||||
prev: Option<QuantTile>,
|
||||
reader: &mut ProtocolReader<R>
|
||||
) -> ProtocolReaderResult<()> {
|
||||
let mut i: usize = 0;
|
||||
loop {
|
||||
let cmd = reader.read_u8_wide()? as usize;
|
||||
if let Some(p) = prev {
|
||||
if cmd == 0xff {
|
||||
self.quants[1..].copy_from_slice(&p.quants[1..]);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
i += cmd;
|
||||
if i >= TILE_SZ2 { break; }
|
||||
|
||||
self.quants[i] = reader.read_i16_packed()?;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,10 @@ impl<W: Write> ProtocolWriter<W> {
|
||||
self.writer.write_all(&value.to_le_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn write_u8_wide(&mut self, value: u8) -> ProtocolWriterResult<()> {
|
||||
self.writer.write_all(&value.to_le_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn write_i16_packed(&mut self, value: i16) -> ProtocolWriterResult<()> {
|
||||
// We reserve i8::MAX and i16::MAX as signal values that `value` is too big
|
||||
// for each respective type
|
||||
@ -110,6 +114,13 @@ impl<R: Read> ProtocolReader<R> {
|
||||
Ok(i16::from_le_bytes(i16_buf))
|
||||
}
|
||||
|
||||
pub fn read_u8_wide(&mut self) -> ProtocolReaderResult<u8> {
|
||||
let mut u8_buf = [0; 1];
|
||||
self.read_exact(&mut u8_buf)?;
|
||||
|
||||
Ok(u8::from_le_bytes(u8_buf))
|
||||
}
|
||||
|
||||
pub fn read_i16_packed(&mut self) -> ProtocolReaderResult<i16> {
|
||||
let mut i8_buf = [0; 1];
|
||||
self.read_exact(&mut i8_buf)?;
|
||||
|
Loading…
Reference in New Issue
Block a user