#read-write #las #format #port #laszip

laz

Rust port of Laszip compression. of the LAS format

15 unstable releases (7 breaking)

0.8.0 Dec 27, 2022
0.7.0 Nov 22, 2022
0.6.4 Aug 16, 2022
0.6.3 May 27, 2022
0.1.0 Jun 23, 2019

#64 in Compression

Download history 240/week @ 2022-11-27 159/week @ 2022-12-04 174/week @ 2022-12-11 193/week @ 2022-12-18 321/week @ 2022-12-25 116/week @ 2023-01-01 181/week @ 2023-01-08 158/week @ 2023-01-15 151/week @ 2023-01-22 223/week @ 2023-01-29 132/week @ 2023-02-05 173/week @ 2023-02-12 203/week @ 2023-02-19 127/week @ 2023-02-26 247/week @ 2023-03-05 209/week @ 2023-03-12

822 downloads per month
Used in 5 crates (3 directly)

Apache-2.0

515KB
10K SLoC

laz-rs

Implementation or rather, translation of LAZ (laszip compression) format in Rust.

The goal of this project is to be a port of the Laszip compression, allowing LAS readers to be able to read / write LAZ data, but not a fully featured LAS reader.

If you want a user friendly Rust LAS reader, las-rs is what you are looking for. las-rs can use laz-rs to manage LAZ data by enabling the laz feature of the las-rs crate.

Original Implementations:

Minimal Rust version: 1.40.0

Running benches

cargo bench --features benchmarks

lib.rs:

Port of the Martin Isenburg's laszip compression to Rust

[LasZipCompressor] and [LasZipDecompressor] are the two types that user wishing to compress and / or decompress LAZ data should use.

LasZipCompressor Examples

use laz::{LasZipError, LasZipCompressor, LazItemType, LazItemRecordBuilder};

# fn main() -> laz::Result<()> {
// Here we use a Cursor but a std::fs::File will work just fine
let mut compressed_output = std::io::Cursor::new(vec![]);

// LazItem may have multiple versions of the compression algorithm
// the builder selects a default one
let items = LazItemRecordBuilder::new()
            .add_item(LazItemType::Point10)
            .add_item(LazItemType::RGB12)
            .build();
let mut compressor = LasZipCompressor::from_laz_items(&mut compressed_output, items)?;

let point = vec![0u8; 26];
compressor.compress_one(&point)?;
compressor.done()?; // don't forget to call done when you are...done compressing

# Ok(())
# }

LasZipCompressors can also be contructed from a LazVlr if you need to change the Chunk size or if you have the LazVlr from the orignal LAZ file that you want to write back

use laz::{LasZipError, LasZipCompressor, LazItemType, LazItemRecordBuilder, LazVlrBuilder};

# fn main() -> laz::Result<()> {

let mut compressed_output = std::io::Cursor::new(vec![]);
let items = LazItemRecordBuilder::new()
            .add_item(LazItemType::Point10)
            .add_item(LazItemType::RGB12)
            .build();
let vlr = LazVlrBuilder::from_laz_items(items)
          .with_chunk_size(5_000)
          .build();

let mut compressor = LasZipCompressor::new(&mut compressed_output, vlr)?;

let point = vec![0u8; 26];
compressor.compress_one(&point)?;
compressor.done()?;
# Ok(())
# }

To create a [LasZipDecompressor] you need to have the record_data found in the LAZ file.

LasZipDecompressor Examples

# const LAS_HEADER_SIZE: u64 = 227;
# const VLR_HEADER_SIZE: u64 = 54;
# const OFFSET_TO_LASZIP_VLR_DATA: u64 = LAS_HEADER_SIZE + VLR_HEADER_SIZE;
# const NUM_POINTS: usize = 1065;

use laz::{LasZipError, LazVlr, LasZipDecompressor};
use std::fs::File;

# fn read_first_point(path: &str, out: &mut [u8]) -> std::io::Result<()> {
#    let mut reader = laz::las::file::SimpleReader::new(File::open(path)?)?;
#    out.copy_from_slice(reader.read_next().unwrap()?);
#    Ok(())
# }
# fn seek_to_start_of_laszip_record_data(file: &mut File) -> std::io::Result<()> {
#    use std::io::{Seek, SeekFrom};
#    file.seek(SeekFrom::Start(OFFSET_TO_LASZIP_VLR_DATA))?;
#    Ok(())
# }
# fn main() -> laz::Result<()> {
let mut laz_file = File::open("tests/data/point10.laz")?;
seek_to_start_of_laszip_record_data(&mut laz_file)?;

let vlr = LazVlr::read_from(&mut laz_file)?;
let mut decompression_output = vec![0u8; vlr.items_size() as usize];
let mut decompressor = LasZipDecompressor::new(&mut laz_file, vlr)?;

let mut ground_truth = vec![0u8; decompression_output.len()];
read_first_point("tests/data/point10.las", &mut ground_truth)?;

decompressor.decompress_one(&mut decompression_output)?;
assert_eq!(&decompression_output, &ground_truth);

# Ok(())
# }

Parallelism

This crates has an optional feature 'parallel'. When using this feature, additional Par structs and par_ methods are exposed.

  • [ParLasZipCompressor]

  • [ParLasZipDecompressor]

  • [par_compress_buffer]

  • [par_decompress_buffer]

Dependencies

~185–550KB
~10K SLoC