[librsvg: 4/14] filters: port convolution matrix to ExclusiveImageSurface



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]