Return allocation errors when clearing a color channel. (#4589)

This commit is contained in:
Vikram Bhaskaran 2026-10-14 03:45:49 +11:00 committed by GitHub
parent 759780e40d
commit 213770008a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 20 additions and 3 deletions

View File

@ -147,3 +147,19 @@ fn cut_a_colour_channel_clears_only_that_channel() {
s.undo();
assert!(near(&px(&s, 5, 5), &left), "one undoable step");
}
#[test]
fn clearing_a_channel_reports_allocation_failure_without_editing() {
for depth in [8, 16, 32] {
let mut s = session(depth);
let id = s.active().unwrap().active_layer.unwrap();
let before = s.active().unwrap().doc.clone();
let history = s.active().unwrap().history.entries();
crate::allocation::fail_next_for_test();
let result = s.edit("Clear", |doc, _| crate::channel_cmds::clear_color_channel(doc, id, 0, [1.0; 4]));
let _ = crate::allocation::capacity::<u8>(0, "reset failpoint");
assert!(result.is_err());
assert_eq!(*s.active().unwrap().doc, *before);
assert_eq!(s.active().unwrap().history.entries(), history);
}
}

View File

@ -746,15 +746,16 @@ pub(crate) fn clear_color_channel(doc: &mut Document, id: LayerId, k: usize, bac
if area.is_empty() {
return Ok(());
}
let cover = sel.map(|m| (m.read_region(area), m.format().channels().max(1)));
let mut px = surf.read_region(area);
let cover =
sel.as_ref().map(|m| crate::allocation::read_region(m, area, "clearing a channel selection").map(|v| (v, m.format().channels().max(1)))).transpose()?;
let mut px = crate::allocation::read_region(surf, area, "clearing a channel")?;
for (i, p) in px.chunks_exact_mut(n).enumerate() {
let w = cover.as_ref().map_or(1.0, |(m, mk)| m.get(i * mk).copied().unwrap_or(0.0));
if let Some(c) = p.get_mut(k) {
*c += (v - *c) * w.clamp(0.0, 1.0);
}
}
surf.write_region(area, &px);
surf.try_write_region(area, &px)?;
surf.prune();
Ok(())
}