use laz::laszip::LazVlr;
use laz::record::{LayeredPointRecordDecompressor, RecordDecompressor};
use std::io::{Read, Seek, SeekFrom};
pub(crate) struct CopcDecompressor<'a, R: Read + Seek> {
start: u64,
vlr: &'a LazVlr,
record_decompressor: LayeredPointRecordDecompressor<'a, R>,
}
impl<'a, R: Read + Seek> CopcDecompressor<'a, R> {
pub(crate) fn new(mut source: R, vlr: &'a LazVlr) -> laz::Result<Self> {
let start = source.stream_position()?;
let mut record_decompressor = LayeredPointRecordDecompressor::new(source);
record_decompressor.set_fields_from(vlr.items())?;
Ok(Self {
start,
vlr,
record_decompressor,
})
}
#[inline]
pub(crate) fn source_seek(&mut self, offset: u64) -> laz::Result<()> {
self.record_decompressor
.get_mut()
.seek(SeekFrom::Start(offset + self.start))?;
self.record_decompressor.reset();
self.record_decompressor.set_fields_from(self.vlr.items())
}
#[inline]
pub(crate) fn decompress_one(&mut self, out: &mut [u8]) -> laz::Result<()> {
self.record_decompressor
.decompress_next(out)
.map_err(laz::errors::LasZipError::IoError)
}
}