[librsvg: 13/30] convolve_matrix: do not raise parse error on divisor set to 0




commit fb0560f65aa49254fa8985cbe6d9913bfe7b79f4
Author: Paolo Borelli <pborelli gnome org>
Date:   Wed Dec 23 22:56:19 2020 +0100

    convolve_matrix: do not raise parse error on divisor set to 0
    
    The spec says to fallback to 1, not error out.
    This in turns means we can simplify the parsing since we do not
    need anymore the NonZero helper struct and check the value of
    divisor when rendering.

 src/filters/convolve_matrix.rs | 36 ++++++++++++++++++------------------
 src/parsers.rs                 | 16 ----------------
 2 files changed, 18 insertions(+), 34 deletions(-)
---
diff --git a/src/filters/convolve_matrix.rs b/src/filters/convolve_matrix.rs
index bb2760b3..98366123 100644
--- a/src/filters/convolve_matrix.rs
+++ b/src/filters/convolve_matrix.rs
@@ -9,7 +9,7 @@ use crate::element::{ElementResult, SetAttributes};
 use crate::error::*;
 use crate::node::Node;
 use crate::number_list::{NumberList, NumberListLength};
-use crate::parsers::{NonNegative, NonZero, NumberOptionalNumber, Parse, ParseValue};
+use crate::parsers::{NonNegative, NumberOptionalNumber, Parse, ParseValue};
 use crate::rect::IRect;
 use crate::surface_utils::{
     iterators::{PixelRectangle, Pixels},
@@ -26,7 +26,7 @@ pub struct FeConvolveMatrix {
     base: PrimitiveWithInput,
     order: (u32, u32),
     kernel_matrix: Option<DMatrix<f64>>,
-    divisor: Option<f64>,
+    divisor: f64,
     bias: f64,
     target_x: Option<u32>,
     target_y: Option<u32>,
@@ -43,7 +43,7 @@ impl Default for FeConvolveMatrix {
             base: PrimitiveWithInput::new::<Self>(),
             order: (3, 3),
             kernel_matrix: None,
-            divisor: None,
+            divisor: 0.0,
             bias: 0.0,
             target_x: None,
             target_y: None,
@@ -64,10 +64,7 @@ impl SetAttributes for FeConvolveMatrix {
                     let NumberOptionalNumber(x, y) = attr.parse(value)?;
                     self.order = (x, y);
                 }
-                expanded_name!("", "divisor") => {
-                    let NonZero(d) = attr.parse(value)?;
-                    self.divisor = Some(d);
-                }
+                expanded_name!("", "divisor") => self.divisor = attr.parse(value)?,
                 expanded_name!("", "bias") => self.bias = attr.parse(value)?,
                 expanded_name!("", "targetX") => self.target_x = attr.parse(value)?,
                 expanded_name!("", "targetY") => self.target_y = attr.parse(value)?,
@@ -117,15 +114,6 @@ impl SetAttributes for FeConvolveMatrix {
                 .attribute(QualName::new(None, ns!(svg), local_name!("kernelMatrix")));
         }
 
-        // Default value for the divisor.
-        if self.divisor.is_none() {
-            self.divisor = Some(self.kernel_matrix.as_ref().unwrap().iter().sum());
-
-            if self.divisor.unwrap() == 0.0 {
-                self.divisor = Some(1.0);
-            }
-        }
-
         Ok(())
     }
 }
@@ -189,6 +177,18 @@ impl FilterEffect for FeConvolveMatrix {
 
         let matrix = self.kernel_matrix.as_ref().unwrap();
 
+        let divisor = if self.divisor != 0.0 {
+            self.divisor
+        } else {
+            let d = matrix.iter().sum();
+
+            if d != 0.0 {
+                d
+            } else {
+                1.0
+            }
+        };
+
         let mut surface = ExclusiveImageSurface::new(
             input_surface.width(),
             input_surface.height(),
@@ -230,13 +230,13 @@ impl FilterEffect for FeConvolveMatrix {
                 if self.preserve_alpha {
                     a = f64::from(pixel.a) / 255.0;
                 } else {
-                    a = a / self.divisor.unwrap() + self.bias;
+                    a = a / divisor + self.bias;
                 }
 
                 let clamped_a = clamp(a, 0.0, 1.0);
 
                 let compute = |x| {
-                    let x = x / self.divisor.unwrap() + self.bias * a;
+                    let x = x / divisor + self.bias * a;
 
                     let x = if self.preserve_alpha {
                         // Premultiply the output value.
diff --git a/src/parsers.rs b/src/parsers.rs
index b4d7f455..c0507b93 100644
--- a/src/parsers.rs
+++ b/src/parsers.rs
@@ -74,22 +74,6 @@ impl Parse for f64 {
     }
 }
 
-/// Non-Zero number (for instance useful for "divisor")
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct NonZero(pub f64);
-
-impl Parse for NonZero {
-    fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<Self, ParseError<'i>> {
-        let loc = parser.current_source_location();
-        let n = Parse::parse(parser)?;
-        if n != 0.0 {
-            Ok(NonZero(n))
-        } else {
-            Err(loc.new_custom_error(ValueErrorKind::value_error("expected non zero number")))
-        }
-    }
-}
-
 /// Non-Negative number
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub struct NonNegative(pub f64);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]