[librsvg: 4/14] filters: port convolution matrix to ExclusiveImageSurface
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 4/14] filters: port convolution matrix to ExclusiveImageSurface
- Date: Wed, 15 Jan 2020 00:32:29 +0000 (UTC)
commit 0b35920df6ec9d3c4e52122002376f816ced2123
Author: Paolo Borelli <pborelli gnome org>
Date: Tue Jan 14 01:22:59 2020 +0100
filters: port convolution matrix to ExclusiveImageSurface
rsvg_internals/src/filters/convolve_matrix.rs | 127 ++++++++++++--------------
1 file changed, 59 insertions(+), 68 deletions(-)
---
diff --git a/rsvg_internals/src/filters/convolve_matrix.rs b/rsvg_internals/src/filters/convolve_matrix.rs
index 4a22a028..0d49ab80 100644
--- a/rsvg_internals/src/filters/convolve_matrix.rs
+++ b/rsvg_internals/src/filters/convolve_matrix.rs
@@ -11,8 +11,8 @@ use crate::property_bag::PropertyBag;
use crate::rect::IRect;
use crate::surface_utils::{
iterators::{PixelRectangle, Pixels},
- shared_surface::SharedImageSurface,
- EdgeMode, ImageSurfaceDataExt, Pixel,
+ shared_surface::ExclusiveImageSurface,
+ EdgeMode, Pixel,
};
use crate::util::clamp;
@@ -229,85 +229,79 @@ impl FilterEffect for FeConvolveMatrix {
let matrix = self.kernel_matrix.as_ref().unwrap();
- let mut output_surface = cairo::ImageSurface::create(
- cairo::Format::ARgb32,
+ let mut surface = ExclusiveImageSurface::new(
input_surface.width(),
input_surface.height(),
+ input.surface().surface_type(),
)?;
- let output_stride = output_surface.get_stride() as usize;
- {
- let mut output_data = output_surface.get_data().unwrap();
-
- for (x, y, pixel) in Pixels::within(&input_surface, bounds) {
- // Compute the convolution rectangle bounds.
- let kernel_bounds = IRect::new(
- x as i32 - self.target_x.unwrap() as i32,
- y as i32 - self.target_y.unwrap() as i32,
- x as i32 - self.target_x.unwrap() as i32 + self.order.0 as i32,
- y as i32 - self.target_y.unwrap() as i32 + self.order.1 as i32,
- );
-
- // Do the convolution.
- let mut r = 0.0;
- let mut g = 0.0;
- let mut b = 0.0;
- let mut a = 0.0;
-
- for (x, y, pixel) in
- PixelRectangle::within(&input_surface, bounds, kernel_bounds, self.edge_mode)
- {
- let kernel_x = (kernel_bounds.x1 - x - 1) as usize;
- let kernel_y = (kernel_bounds.y1 - y - 1) as usize;
-
- r += f64::from(pixel.r) / 255.0 * matrix[(kernel_y, kernel_x)];
- g += f64::from(pixel.g) / 255.0 * matrix[(kernel_y, kernel_x)];
- b += f64::from(pixel.b) / 255.0 * matrix[(kernel_y, kernel_x)];
-
- if !self.preserve_alpha {
- a += f64::from(pixel.a) / 255.0 * matrix[(kernel_y, kernel_x)];
- }
- }
-
- // If preserve_alpha is true, set a to the source alpha value.
- if self.preserve_alpha {
- a = f64::from(pixel.a) / 255.0;
- } else {
- a = a / self.divisor.unwrap() + self.bias;
+ for (x, y, pixel) in Pixels::within(&input_surface, bounds) {
+ // Compute the convolution rectangle bounds.
+ let kernel_bounds = IRect::new(
+ x as i32 - self.target_x.unwrap() as i32,
+ y as i32 - self.target_y.unwrap() as i32,
+ x as i32 - self.target_x.unwrap() as i32 + self.order.0 as i32,
+ y as i32 - self.target_y.unwrap() as i32 + self.order.1 as i32,
+ );
+
+ // Do the convolution.
+ let mut r = 0.0;
+ let mut g = 0.0;
+ let mut b = 0.0;
+ let mut a = 0.0;
+
+ for (x, y, pixel) in
+ PixelRectangle::within(&input_surface, bounds, kernel_bounds, self.edge_mode)
+ {
+ let kernel_x = (kernel_bounds.x1 - x - 1) as usize;
+ let kernel_y = (kernel_bounds.y1 - y - 1) as usize;
+
+ r += f64::from(pixel.r) / 255.0 * matrix[(kernel_y, kernel_x)];
+ g += f64::from(pixel.g) / 255.0 * matrix[(kernel_y, kernel_x)];
+ b += f64::from(pixel.b) / 255.0 * matrix[(kernel_y, kernel_x)];
+
+ if !self.preserve_alpha {
+ a += f64::from(pixel.a) / 255.0 * matrix[(kernel_y, kernel_x)];
}
+ }
- let clamped_a = clamp(a, 0.0, 1.0);
+ // If preserve_alpha is true, set a to the source alpha value.
+ if self.preserve_alpha {
+ a = f64::from(pixel.a) / 255.0;
+ } else {
+ a = a / self.divisor.unwrap() + self.bias;
+ }
- let compute = |x| {
- let x = x / self.divisor.unwrap() + self.bias * a;
+ let clamped_a = clamp(a, 0.0, 1.0);
- let x = if self.preserve_alpha {
- // Premultiply the output value.
- clamp(x, 0.0, 1.0) * clamped_a
- } else {
- clamp(x, 0.0, clamped_a)
- };
+ let compute = |x| {
+ let x = x / self.divisor.unwrap() + self.bias * a;
- ((x * 255.0) + 0.5) as u8
+ let x = if self.preserve_alpha {
+ // Premultiply the output value.
+ clamp(x, 0.0, 1.0) * clamped_a
+ } else {
+ clamp(x, 0.0, clamped_a)
};
- let output_pixel = Pixel {
- r: compute(r),
- g: compute(g),
- b: compute(b),
- a: ((clamped_a * 255.0) + 0.5) as u8,
- };
+ ((x * 255.0) + 0.5) as u8
+ };
- output_data.set_pixel(output_stride, output_pixel, x, y);
- }
+ let output_pixel = Pixel {
+ r: compute(r),
+ g: compute(g),
+ b: compute(b),
+ a: ((clamped_a * 255.0) + 0.5) as u8,
+ };
+
+ surface.set_pixel(output_pixel, x, y);
}
- let mut output_surface =
- SharedImageSurface::wrap(output_surface, input.surface().surface_type())?;
+ let mut surface = surface.share()?;
if let Some((ox, oy)) = scale {
// Scale the output surface back.
- output_surface = output_surface.scale_to(
+ surface = surface.scale_to(
ctx.source_graphic().width(),
ctx.source_graphic().height(),
original_bounds,
@@ -320,10 +314,7 @@ impl FilterEffect for FeConvolveMatrix {
Ok(FilterResult {
name: self.base.result.clone(),
- output: FilterOutput {
- surface: output_surface,
- bounds,
- },
+ output: FilterOutput { surface, bounds },
})
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]