Skip to content
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ members = [
"src/metadata/camerametadata",
"src/metadata/camerasxml_parser",
"src/metadata/xmlparser",
"src/metadata/colorfilterarray",
"src/metadata/xmltokendesparsifier",
"src/metadata/xmltokenizer",
"src/misc/md5",
Expand Down
1 change: 1 addition & 0 deletions src/metadata/camerasxml_parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ license.workspace = true
workspace = true

[dependencies]
rawspeed-metadata-colorfilterarray = { path = "../colorfilterarray" }
rawspeed-metadata-xmlparser = { path = "../xmlparser" }
rawspeed-std = { path = "../../std" }
rawspeed-std-ndslice = { path = "../../std/ndslice" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,10 @@ use super::super::blackareas::IndividualBlackAreas;
use super::super::cfa::CFA;
use super::super::cfa::CFAColors;
use super::super::cfa2::CFA2;
use super::super::cfa2::CFA2Colors;
use super::super::color;
use super::super::color::Color;
use super::super::colormatrices::ColorMatrices;
use super::super::colormatrix::ColorMatrix;
use super::super::colorrow;
use super::super::colorrow::ColorRow;
use super::super::colorrow::ColorRowValues;
use super::super::crop::Crop;
use super::super::decoder_version::DecoderVersion;
use super::super::height::Height;
Expand Down Expand Up @@ -47,6 +43,8 @@ use super::model::Model;
use super::sensor;
use super::xmlparser;
use crate::camerasxml_parser::crop;
use rawspeed_metadata_colorfilterarray::colorfilterarray::ColorFilterArray;
use rawspeed_metadata_colorfilterarray::colorfilterarray::ColorVariant;
use rawspeed_std::coord_common::ColIndex;
use rawspeed_std::coord_common::Coord2D;
use rawspeed_std::coord_common::RowCount;
Expand Down Expand Up @@ -630,24 +628,10 @@ fn parse_cfa2_test() {
decoder_version: None,
supported: Supported::Supported,
id: None,
cfa: MaybeCFA::CFA2(CFA2 {
width: Width {
val: Int { val: 1 },
},
height: Height {
val: Int { val: 1 },
},
values: CFA2Colors {
values: vec![ColorRow {
y: Y {
val: Int { val: 0 },
},
value: ColorRowValues {
values: vec![colorrow::ColorVariant::G],
},
}],
},
}),
cfa: MaybeCFA::CFA2(CFA2::new(ColorFilterArray::new(
vec![ColorVariant::Green],
RowLength::new(1),
))),
crop: None,
sensors: Sensors { values: vec![] },
blackaras: None,
Expand Down
84 changes: 60 additions & 24 deletions src/metadata/camerasxml_parser/camerasxml_parser/cfa2/mod.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,74 @@
use super::super::camerasxml_parser::colorrow;
use super::height;
use super::width;
use super::xmlparser;
use rawspeed_metadata_colorfilterarray::colorfilterarray::ColorFilterArray;
use rawspeed_metadata_colorfilterarray::colorfilterarray::ColorVariant;
use rawspeed_metadata_xmlparser::xmlparser;
use rawspeed_std::coord_common::ColIndex;
use rawspeed_std::coord_common::Coord2D;
use rawspeed_std::coord_common::RowIndex;
use rawspeed_std::coord_common::RowLength;

use crate::camerasxml_parser::colorrow;

mod repr;

#[derive(Debug, Clone, PartialEq)]
pub struct CFA2Colors {
pub values: Vec<colorrow::ColorRow>,
#[non_exhaustive]
pub struct CFA2 {
data: ColorFilterArray,
}

impl CFA2 {
pub const fn new(data: ColorFilterArray) -> Self {
Self { data }
}
}

impl core::ops::Deref for CFA2 {
type Target = ColorFilterArray;

fn deref(&self) -> &Self::Target {
&self.data
}
}

impl<'a, 'b> xmlparser::Parse<'a, 'b> for CFA2Colors {
impl<'a, 'b> xmlparser::Parse<'a, 'b> for CFA2 {
fn parse(
input: &'b mut xmlparser::ParseStream<'a>,
) -> xmlparser::Result<Self> {
let mut values = Vec::new();
while let Ok(row) = input.parse() {
values.push(row);
let cfa = input.parse::<repr::CFA2>()?;
let mat = cfa.body.mat();
let real_height = mat.num_rows();
let real_width = mat.row_length();
if Ok(real_height) != (**cfa.height).try_into() {
return Err(format!(
"unexpected CFA matrix row count, got {} expected {}",
real_height, **cfa.height
));
}
if values.is_empty() {
return Err(
"unexpected end of input, expected `ColorRow`".to_owned()
);
if Ok(real_width) != (**cfa.width).try_into() {
return Err(format!(
"unexpected CFA matrix row length, got {} expected {}",
real_width, **cfa.width
));
}
Ok(Self { values })
let mut data =
Vec::with_capacity(real_width.checked_mul(real_height).unwrap());
for row in 0..real_height {
for col in 0..real_width {
let e =
mat[Coord2D::new(RowIndex::new(row), ColIndex::new(col))];
let e = match e {
colorrow::ColorVariant::R => ColorVariant::Red,
colorrow::ColorVariant::G => ColorVariant::Green,
colorrow::ColorVariant::B => ColorVariant::Blue,
};
data.push(e);
}
}
Ok(Self {
data: ColorFilterArray::new(data, RowLength::new(real_width)),
})
}
}

impl_elt_with_body_matcher!(
#[derive(Debug, Clone, PartialEq)]
struct CFA2 {
width: width::Width,
height: height::Height,
values: CFA2Colors,
}
);

#[cfg(test)]
mod tests;
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use super::super::height::Height;
use super::super::width::Width;
use crate::camerasxml_parser::colorrow::{self, ColorVariant};
use rawspeed_metadata_xmlparser::xmlparser;
use rawspeed_std::coord_common::{RowLength, RowPitch};
use rawspeed_std_ndslice::array2dref::Array2DRef;

#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub struct Matrix {
data: Vec<ColorVariant>,
row_length: RowLength,
}

impl Matrix {
pub const fn new(data: Vec<ColorVariant>, row_length: RowLength) -> Self {
let ret = Self { data, row_length };
let _ = ret.mat();
ret
}

#[inline]
#[must_use]
pub const fn mat(&self) -> Array2DRef<'_, ColorVariant> {
Array2DRef::new(
self.data.as_slice(),
self.row_length,
RowPitch::new(self.row_length.val()),
)
}
}

impl<'a, 'b> xmlparser::Parse<'a, 'b> for Matrix {
fn parse(
input: &'b mut xmlparser::ParseStream<'a>,
) -> xmlparser::Result<Self> {
let mut rows = Vec::<Vec<ColorVariant>>::new();
while let Ok(row) = input.parse::<colorrow::ColorRow>() {
if (**row.y).try_into() != Ok(rows.len()) {
return Err(format!(
"unexpected row index, expected {} got {}",
rows.len(),
**row.y
));
}
if let Some(first_row) = rows.first()
&& let first_row_length = first_row.len()
&& let curr_row_length = row.value.values.len()
&& curr_row_length != first_row_length
{
return Err(format!(
"inconsistent row length, expected {first_row_length} got {curr_row_length}",
));
}
rows.push(row.value.values);
}
if rows.is_empty() {
return Err(
"unexpected end of input, expected `ColorRow`".to_owned()
);
}
let matrix_elts = rows.iter().flat_map(|row| row.iter().copied());
let data: Vec<ColorVariant> = matrix_elts.collect();
Ok(Matrix::new(
data,
RowLength::new(rows.first().unwrap().len()),
))
}
}

impl_elt_with_body_matcher!(
#[derive(Debug, Clone, PartialEq)]
struct CFA2 {
width: Width,
height: Height,
body: Matrix,
}
);

#[cfg(test)]
mod tests;
Loading
Loading