mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-24 09:57:08 -06:00
fix(algo): normalize nonpositive filter tile sizes (#7554)
This commit is contained in:
@@ -972,6 +972,7 @@ fn auto_tile(params: &FilterParams, bounds: Rect) -> i32 {
|
||||
}
|
||||
|
||||
/// [`apply`] / [`apply_in`] with an explicit tile size (tests use it to check tile independence).
|
||||
/// Nonpositive tile sizes are treated as one pixel.
|
||||
pub fn apply_tiled(
|
||||
surface: &Surface,
|
||||
params: &FilterParams,
|
||||
@@ -1014,6 +1015,8 @@ fn apply_tiled_with_impl(
|
||||
ctl: &photocraft_raster::Interrupt,
|
||||
prepare_fast_paths: bool,
|
||||
) -> Option<Surface> {
|
||||
// Every dispatch path needs a positive step, including Motion Blur's fallback.
|
||||
let tile = tile.max(1);
|
||||
if ctl.cancelled() {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -90,6 +90,27 @@ fn radial_blur_quality_defaults_for_older_serialized_parameters() {
|
||||
assert_eq!(decoded, FilterParams::RadialBlur { amount: 20.0, method: RadialMethod::Spin, quality: RadialQuality::Good, center_x: 0.5, center_y: 0.5 });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nonpositive_tile_sizes_match_one_pixel_tiles() {
|
||||
let area = Rect::new(0, 0, 4, 3);
|
||||
for depth in [SampleType::U8, SampleType::U16, SampleType::F32] {
|
||||
let source = pattern(depth, area);
|
||||
for params in all_filters().into_iter().chain([FilterParams::ShapeBlur { radius: 3.0, shape: BlurShape::Star }]) {
|
||||
let expected = apply_tiled(&source, ¶ms, area, area, None, 1, Some(area));
|
||||
for tile in [0, -64, i32::MIN] {
|
||||
let actual = apply_tiled(&source, ¶ms, area, area, None, tile, Some(area));
|
||||
assert_eq!(actual.read_region(area), expected.read_region(area), "{}: {depth:?}, tile={tile}", params.label());
|
||||
let cancellable = apply_tiled_with(&source, ¶ms, area, area, None, tile, Some(area), &photocraft_raster::Interrupt::NONE)
|
||||
.expect("a nonpositive tile size is normalized, not rejected");
|
||||
assert_eq!(cancellable.read_region(area), expected.read_region(area), "{}: {depth:?}, tile={tile}", params.label());
|
||||
let cancelled = photocraft_raster::Interrupt::cancel_only(&|| true);
|
||||
assert!(apply_tiled_with(&source, ¶ms, area, area, None, tile, Some(area), &cancelled).is_none());
|
||||
}
|
||||
}
|
||||
assert_eq!(source.read_region(area), pattern(depth, area).read_region(area));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_filter_is_tile_independent() {
|
||||
let s = pattern(SampleType::U8, R);
|
||||
|
||||
Reference in New Issue
Block a user