pub const MAGIC_HEADER: &[u8; 10] = b"CLOUDINI_V";
pub const ENCODING_VERSION: u8 = 3;
pub const POINTS_PER_CHUNK: usize = 32 * 1024;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum FieldType {
Unknown = 0,
Int8 = 1,
Uint8 = 2,
Int16 = 3,
Uint16 = 4,
Int32 = 5,
Uint32 = 6,
Float32 = 7,
Float64 = 8,
Int64 = 9,
Uint64 = 10,
}
impl FieldType {
pub fn size_of(self) -> usize {
match self {
FieldType::Int8 | FieldType::Uint8 => 1,
FieldType::Int16 | FieldType::Uint16 => 2,
FieldType::Int32 | FieldType::Uint32 | FieldType::Float32 => 4,
FieldType::Float64 | FieldType::Int64 | FieldType::Uint64 => 8,
FieldType::Unknown => 0,
}
}
pub fn from_yaml(s: &str) -> Option<Self> {
match s {
"INT8" => Some(FieldType::Int8),
"UINT8" => Some(FieldType::Uint8),
"INT16" => Some(FieldType::Int16),
"UINT16" => Some(FieldType::Uint16),
"INT32" => Some(FieldType::Int32),
"UINT32" => Some(FieldType::Uint32),
"FLOAT32" => Some(FieldType::Float32),
"FLOAT64" => Some(FieldType::Float64),
"INT64" => Some(FieldType::Int64),
"UINT64" => Some(FieldType::Uint64),
_ => {
if let Ok(v) = s.parse::<u8>() {
return match v {
0 => Some(FieldType::Unknown),
1 => Some(FieldType::Int8),
2 => Some(FieldType::Uint8),
3 => Some(FieldType::Int16),
4 => Some(FieldType::Uint16),
5 => Some(FieldType::Int32),
6 => Some(FieldType::Uint32),
7 => Some(FieldType::Float32),
8 => Some(FieldType::Float64),
9 => Some(FieldType::Int64),
10 => Some(FieldType::Uint64),
_ => None,
};
}
None
}
}
}
pub fn as_str(self) -> &'static str {
match self {
FieldType::Int8 => "INT8",
FieldType::Uint8 => "UINT8",
FieldType::Int16 => "INT16",
FieldType::Uint16 => "UINT16",
FieldType::Int32 => "INT32",
FieldType::Uint32 => "UINT32",
FieldType::Float32 => "FLOAT32",
FieldType::Float64 => "FLOAT64",
FieldType::Int64 => "INT64",
FieldType::Uint64 => "UINT64",
FieldType::Unknown => "UNKNOWN",
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct PointField {
pub name: String,
pub offset: u32,
pub field_type: FieldType,
pub resolution: Option<f32>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum EncodingOptions {
None = 0,
Lossy = 1,
Lossless = 2,
}
impl EncodingOptions {
pub fn from_yaml(s: &str) -> Option<Self> {
match s {
"NONE" => Some(EncodingOptions::None),
"LOSSY" => Some(EncodingOptions::Lossy),
"LOSSLESS" => Some(EncodingOptions::Lossless),
_ => {
if let Ok(v) = s.parse::<u8>() {
return match v {
0 => Some(EncodingOptions::None),
1 => Some(EncodingOptions::Lossy),
2 => Some(EncodingOptions::Lossless),
_ => None,
};
}
None
}
}
}
pub fn as_str(self) -> &'static str {
match self {
EncodingOptions::None => "NONE",
EncodingOptions::Lossy => "LOSSY",
EncodingOptions::Lossless => "LOSSLESS",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum CompressionOption {
None = 0,
Lz4 = 1,
Zstd = 2,
}
impl CompressionOption {
pub fn from_yaml(s: &str) -> Option<Self> {
match s {
"NONE" => Some(CompressionOption::None),
"LZ4" => Some(CompressionOption::Lz4),
"ZSTD" => Some(CompressionOption::Zstd),
_ => {
if let Ok(v) = s.parse::<u8>() {
return match v {
0 => Some(CompressionOption::None),
1 => Some(CompressionOption::Lz4),
2 => Some(CompressionOption::Zstd),
_ => None,
};
}
None
}
}
}
pub fn as_str(self) -> &'static str {
match self {
CompressionOption::None => "NONE",
CompressionOption::Lz4 => "LZ4",
CompressionOption::Zstd => "ZSTD",
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct EncodingInfo {
pub fields: Vec<PointField>,
pub width: u32,
pub height: u32,
pub point_step: u32,
pub encoding_opt: EncodingOptions,
pub compression_opt: CompressionOption,
pub encoding_config: String,
pub version: u8,
}
impl Default for EncodingInfo {
fn default() -> Self {
Self {
fields: Vec::new(),
width: 0,
height: 1,
point_step: 0,
encoding_opt: EncodingOptions::Lossy,
compression_opt: CompressionOption::Zstd,
encoding_config: String::new(),
version: ENCODING_VERSION,
}
}
}