diff --git a/crates/aep/src/import/lumetri.rs b/crates/aep/src/import/lumetri.rs index 9369155f4..194afe15f 100644 --- a/crates/aep/src/import/lumetri.rs +++ b/crates/aep/src/import/lumetri.rs @@ -590,6 +590,11 @@ pub(crate) fn import_lumetri(fx: &AepEffect<'_, '_>, params: &[EffectParam<'_, ' Role::Lut { lut } => note_lut(p, row.suffix, data(), &mut luts[usize::from(!lut)]), // The Look's colour space only applies to a Look, which is reported. Role::LookSpace => {} + Role::Data(_) if p.stored().is_some() && data().is_none() => { + // The value record is there but its aRbs/aRbp payload is not: damaged, not the + // default (a parameter without a record is the default). + col.lose(LossCategory::DamagedData, format!("{here}: the data of {label} is missing, not imported (the default used)")); + } Role::Data(Data::HslKey) => import_hsl_key(data(), &here, &mut *group, &mut *col), Role::Data(d) => { if p.is_animated() || p.stored().is_some_and(|s| s.expression().is_some()) { diff --git a/crates/aep/tests/it/import/lumetri.rs b/crates/aep/tests/it/import/lumetri.rs index a3ec9138b..d31960cef 100644 --- a/crates/aep/tests/it/import/lumetri.rs +++ b/crates/aep/tests/it/import/lumetri.rs @@ -84,6 +84,8 @@ enum Rec { Num(f64, u32), /// Arbitrary data. Data(Vec), + /// A value record whose arbitrary data (`aRbs`) is missing. + NoData, } /// A static value record after the one After Effects wrote for Glow's A & B Midpoint (its header, @@ -229,6 +231,7 @@ fn sspc(defs: &[(u16, Def)], recs: &[(u16, Rec)], template: &Chunk<'_>) -> Chunk values.push(record(template, 1, 0.0)); values.push(Chunk::list(*b"aRbs", vec![Chunk::data(*b"aRbp", d)])); } + Rec::NoData => values.push(record(template, 1, 0.0)), } } Chunk::list(*b"sspc", vec![nested(*b"fnam", b"Lumetri Color"), Chunk::list(*b"parT", part), Chunk::list(*b"tdgp", values)]) @@ -436,6 +439,21 @@ fn the_master_rgb_curve_arrives_moved_channel_curves_are_reported() { assert!(losses(&r).iter().any(|x| x.contains("RGB Curve (ADBE Lumetri-0039) is unreadable")), "{:?}", losses(&r)); } +/// A value record without its arbitrary data is damaged, not the default: reported for the RGB +/// curve and the HSL key, the neighbours stay as they were. +#[test] +fn a_value_record_without_its_data_is_reported_as_damaged() { + for (suffix, name) in [(39, "RGB Curve (ADBE Lumetri-0039)"), (73, "HSL Sliders (ADBE Lumetri-0073)")] { + let (g, r) = run(&[(suffix, Rec::NoData)]); + let l = losses(&r); + assert!(l.len() == 1 && l[0].contains(name) && l[0].contains("is missing"), "{suffix}: {l:?}"); + assert!(r.report.losses.iter().any(|x| x.category == LossCategory::DamagedData), "{suffix}"); + // The grade stays at the default. + assert_eq!(val(&g, "curves/rgbCurves/master"), Value::Str("0,0 1,1".into())); + assert_eq!(num(&g, "hslSecondary/key/hueRange"), 180.0); + } +} + #[test] fn colour_wheels_arrive_as_colours_their_brightness_is_reported() { // 1200 `-62-preset-wheels`: Shadows towards blue with the slider down, Midtones towards red,