[librsvg: 11/12] Move the check for fully transparent pixels into Pixel::unpremultiply()




commit df058363e415e127b2d687a7e33309db92f96f7b
Author: Sven Neumann <sven svenfoo org>
Date:   Tue Oct 13 13:50:36 2020 +0200

    Move the check for fully transparent pixels into Pixel::unpremultiply()
    
    This removes a branch from the inner loop of pixbuf_from_surface and
    speeds it up significantly.
    
    This is a change in behaviour, but as far as I can see the only other
    user is ImageSurface::unpremultiply() which is used by ConvolveMatrix.
    There the pixels' contribution to the output pixel is weighted by
    their alpha channel. Thus the colors of transparent pixels should not
    be relevant.

 librsvg/pixbuf_utils.rs                 | 6 +-----
 rsvg_internals/src/surface_utils/mod.rs | 9 ++++++++-
 2 files changed, 9 insertions(+), 6 deletions(-)
---
diff --git a/librsvg/pixbuf_utils.rs b/librsvg/pixbuf_utils.rs
index ebb92734..808f1225 100644
--- a/librsvg/pixbuf_utils.rs
+++ b/librsvg/pixbuf_utils.rs
@@ -53,11 +53,7 @@ pub fn pixbuf_from_surface(surface: &SharedImageSurface) -> Result<Pixbuf, Rende
         let row: &mut [Pixel] = dest_row.as_rgba_mut();
 
         for (src, dest) in src_row.iter().zip(row.iter_mut()) {
-            *dest = if src.a == 0 {
-                Pixel::default()
-            } else {
-                Pixel::from(*src).unpremultiply()
-            }
+            *dest = Pixel::from(*src).unpremultiply();
         }
     }
 
diff --git a/rsvg_internals/src/surface_utils/mod.rs b/rsvg_internals/src/surface_utils/mod.rs
index 7fb35984..0d2d6ec1 100644
--- a/rsvg_internals/src/surface_utils/mod.rs
+++ b/rsvg_internals/src/surface_utils/mod.rs
@@ -82,10 +82,17 @@ pub trait PixelOps {
 
 impl PixelOps for Pixel {
     /// Returns an unpremultiplied value of this pixel.
+    ///
+    /// For a fully transparent pixel, a transparent black pixel will be returned.
     #[inline]
     fn unpremultiply(self) -> Self {
         if self.a == 0 {
-            self
+            Self {
+                r: 0,
+                g: 0,
+                b: 0,
+                a: 0,
+            }
         } else {
             let alpha = f32::from(self.a) / 255.0;
             self.map_rgb(|x| ((f32::from(x) / alpha) + 0.5) as u8)


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