Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Ecmwf CCSDS Decompression #66

Merged
merged 9 commits into from
Dec 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
*.sublime-workspace
*.DS_Store
target/
temp/
temp/
testdata/
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions gribberish/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ itertools = "0.10.5"
mappers = "0.7.1"
bitvec = "1.0.1"
thiserror = "1.0.60"
bitflags = "2.6.0"

[features]
default = ["png", "jpeg"]
Expand Down
4 changes: 3 additions & 1 deletion gribberish/src/sections/data_representation.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::utils::{read_u16_from_bytes, read_u32_from_bytes};
use crate::templates::data_representation::{DataRepresentationTemplate, SimplePackingDataRepresentationTemplate, ComplexPackingDataRepresentationTemplate, ComplexSpatialPackingDataRepresentationTemplate};
use crate::templates::data_representation::{DataRepresentationTemplate, SimplePackingDataRepresentationTemplate, ComplexPackingDataRepresentationTemplate, ComplexSpatialPackingDataRepresentationTemplate, CCSDSDataRepresentationTemplate};

#[cfg(feature = "jpeg")]
use crate::templates::data_representation::JPEGDataRepresentationTemplate;
#[cfg(feature = "png")]
Expand Down Expand Up @@ -36,6 +37,7 @@ impl <'a> DataRepresentationSection<'a> {
40 => Some(Box::new(JPEGDataRepresentationTemplate::new(self.data.to_vec()))),
#[cfg(feature = "png")]
41 => Some(Box::new(PNGDataRepresentationTemplate::new(self.data.to_vec()))),
42 => Some(Box::new(CCSDSDataRepresentationTemplate::new(self.data.to_vec()))),
_ => None,
}
}
Expand Down
132 changes: 132 additions & 0 deletions gribberish/src/templates/data_representation/ccsds_template.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use bitvec::prelude::*;

use super::data_representation_template::DataRepresentationTemplate;
use super::tables::OriginalFieldValue;
use crate::utils::read_f32_from_bytes;
use crate::{
error::GribberishError,
templates::template::{Template, TemplateType},
utils::{
extract_ccsds_data, iter::ScaleGribValueIterator, read_u16_from_bytes, read_u32_from_bytes,
},
};

pub struct CCSDSDataRepresentationTemplate {
data: Vec<u8>,
}

impl Template for CCSDSDataRepresentationTemplate {
fn data(&self) -> &[u8] {
self.data.as_slice()
}

fn template_number(&self) -> u16 {
42
}

fn template_type(&self) -> TemplateType {
TemplateType::DataRepresentation
}

fn template_name(&self) -> &str {
"grid point and spectral data - CCSDS recommended lossless compression"
}
}

impl CCSDSDataRepresentationTemplate {
pub fn new(data: Vec<u8>) -> CCSDSDataRepresentationTemplate {
CCSDSDataRepresentationTemplate { data }
}

pub fn data_point_count(&self) -> usize {
read_u32_from_bytes(self.data.as_slice(), 5).unwrap_or(0) as usize
}

pub fn reference_value(&self) -> f32 {
read_f32_from_bytes(self.data.as_slice(), 11).unwrap_or(0.0)
}

pub fn binary_scale_factor(&self) -> i16 {
as_signed!(
read_u16_from_bytes(self.data.as_slice(), 15).unwrap_or(0),
16,
i16
)
}

pub fn decimal_scale_factor(&self) -> i16 {
as_signed!(
read_u16_from_bytes(self.data.as_slice(), 17).unwrap_or(0),
16,
i16
)
}

// Nbits
pub fn bit_count(&self) -> u8 {
self.data[19]
}

pub fn original_field_value(&self) -> OriginalFieldValue {
self.data[20].into()
}

pub fn ccsds_compression_options_mask(&self) -> u8 {
self.data[21]
}

pub fn block_size(&self) -> u8 {
self.data[22]
}

// restart interval
pub fn reference_sample_interval(&self) -> u16 {
read_u16_from_bytes(self.data.as_slice(), 23).unwrap_or(0)
}
}

impl DataRepresentationTemplate<f64> for CCSDSDataRepresentationTemplate {
fn compression_type(&self) -> String {
"CCSDS".into()
}

fn bit_count_per_datapoint(&self) -> usize {
self.bit_count() as usize
}

fn unpack(&self, bits: &BitSlice<u8, Msb0>) -> Result<Vec<f64>, GribberishError> {
let bits_per_val: usize = self.bit_count().into();
if bits_per_val == 0 {
return Ok(vec![]);
}

let bytes: Vec<u8> = bits.to_bitvec().into();

let nbytes_per_sample: usize = (bits_per_val + 7) / 8;

let size = self.data_point_count() * nbytes_per_sample;
let outputwr = extract_ccsds_data(
bytes,
self.block_size(),
self.ccsds_compression_options_mask(),
size,
self.reference_sample_interval(),
bits_per_val,
);

match outputwr {
Ok(output_value) => {
// Ok(output_value)
Ok(output_value
.into_iter()
.scale_value_by(
self.binary_scale_factor(),
self.decimal_scale_factor(),
self.reference_value(),
)
.collect())
}
Err(e) => Err(e),
}
}
}
6 changes: 4 additions & 2 deletions gribberish/src/templates/data_representation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub mod data_representation_template;
pub mod simple_packing_template;
pub mod complex_packing_template;
pub mod complex_spatial_packing_template;

pub mod ccsds_template;
#[cfg(feature = "jpeg")]
pub mod jpeg_template;

Expand All @@ -19,4 +19,6 @@ pub use complex_spatial_packing_template::ComplexSpatialPackingDataRepresentatio
pub use jpeg_template::JPEGDataRepresentationTemplate;

#[cfg(feature = "png")]
pub use png_template::PNGDataRepresentationTemplate;
pub use png_template::PNGDataRepresentationTemplate;

pub use ccsds_template::CCSDSDataRepresentationTemplate;
Loading
Loading