Skip to content
Open
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
17 changes: 12 additions & 5 deletions src/imageops/sample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<I, P, S>(image: &I, kernel: &[f32; 9]) -> ImageBuffer<P, Vec<S>>
where
I: GenericImageView<Pixel = P>,
Expand All @@ -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();
Expand All @@ -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);

Expand Down
4 changes: 4 additions & 0 deletions src/images/dynimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
Loading