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