diff --git a/src/imageops/sample.rs b/src/imageops/sample.rs
index 6797f7b41c..25a5a47d99 100644
--- a/src/imageops/sample.rs
+++ b/src/imageops/sample.rs
@@ -856,13 +856,17 @@ where
/// Perform a 3x3 box filter on the supplied image.
///
-/// # Arguments:
+/// # Arguments
///
/// * `image` - source image.
/// * `kernel` - is an array of the filter weights of length 9.
///
+/// # Notes
+///
/// This method typically assumes that the input is scene-linear light.
/// If it is not, color distortion may occur.
+///
+/// This operations uses the clamp/replicate abyss policy. I.e. `aaa|abcdef|fff`.
pub fn filter3x3(image: &I, kernel: &[f32; 9]) -> ImageBuffer
>
where
I: GenericImageView,
@@ -884,6 +888,9 @@ where
let (width, height) = image.dimensions();
let mut out = image.buffer_like();
+ if width == 0 || height == 0 {
+ return out;
+ }
let max = S::DEFAULT_MAX_VALUE;
let max: f32 = NumCast::from(max).unwrap();
@@ -893,16 +900,16 @@ where
sum => 1.0 / sum,
};
- for y in 1..height - 1 {
- for x in 1..width - 1 {
+ for y in 0..height {
+ for x in 0..width {
let mut t = [0.0; MAX_CHANNEL];
// TODO: There is no need to recalculate the kernel for each pixel.
// Only a subtract and addition is needed for pixels after the first
// in each row.
for (&k, &(a, b)) in kernel.iter().zip(taps.iter()) {
- let x0 = x as isize + a;
- let y0 = y as isize + b;
+ let x0 = (x as isize + a).clamp(0, (width - 1) as isize);
+ let y0 = (y as isize + b).clamp(0, (height - 1) as isize);
let p = image.get_pixel(x0 as u32, y0 as u32);
diff --git a/src/images/dynimage.rs b/src/images/dynimage.rs
index d6a69d01c8..e272046c79 100644
--- a/src/images/dynimage.rs
+++ b/src/images/dynimage.rs
@@ -1039,9 +1039,13 @@ impl DynamicImage {
///
/// * `kernel` - array contains filter.
///
+ /// # Notes
+ ///
/// This method typically assumes that the input is scene-linear light. It operates on pixel
/// channel values directly without taking into account color space data. If it is not, color
/// distortion may occur.
+ ///
+ /// This operations uses the clamp/replicate abyss policy. I.e. `aaa|abcdef|fff`.
#[must_use]
pub fn filter3x3(&self, kernel: &[f32; 9]) -> DynamicImage {
dynamic_map!(*self, ref p => imageops::filter3x3(p, kernel))