[librsvg: 4/12] Define Pixel as an alias for rgb::RGBA8




commit 5d00cb6a8650c1c4ec0a5285191c3364624064e9
Author: Sven Neumann <sven svenfoo org>
Date:   Fri Oct 9 10:19:44 2020 +0200

    Define Pixel as an alias for rgb::RGBA8

 librsvg/pixbuf_utils.rs                            | 36 +++--------
 librsvg_crate/tests/utils/compare_surfaces.rs      |  2 +-
 rsvg_internals/benches/pixel_ops.rs                |  2 +-
 rsvg_internals/src/filters/turbulence.rs           |  2 +-
 rsvg_internals/src/surface_utils/mod.rs            | 74 ++++++++++++----------
 rsvg_internals/src/surface_utils/shared_surface.rs | 27 ++------
 6 files changed, 57 insertions(+), 86 deletions(-)
---
diff --git a/librsvg/pixbuf_utils.rs b/librsvg/pixbuf_utils.rs
index eb11b5fb..53e1406b 100644
--- a/librsvg/pixbuf_utils.rs
+++ b/librsvg/pixbuf_utils.rs
@@ -4,14 +4,14 @@ use std::ptr;
 use gdk_pixbuf::{Colorspace, Pixbuf};
 use gio::prelude::*;
 use glib::translate::*;
-use rgb::{FromSlice, RGBA8};
+use rgb::FromSlice;
 use url::Url;
 
 use crate::c_api::checked_i32;
 
 use rsvg_internals::{
-    Dpi, Handle, LoadOptions, LoadingError, Pixel, RenderingError, SharedImageSurface, SurfaceType,
-    UrlResolver,
+    surface_utils::PixelOps, Dpi, Handle, LoadOptions, LoadingError, Pixel, RenderingError,
+    SharedImageSurface, SurfaceType, UrlResolver,
 };
 
 use crate::c_api::set_gerror;
@@ -42,39 +42,21 @@ pub fn pixbuf_from_surface(surface: &SharedImageSurface) -> Result<Pixbuf, Rende
     assert!(pixbuf.get_n_channels() == 4);
 
     let pixels = unsafe { pixbuf.get_pixels() };
-    let width = width as usize;
-    let height = height as usize;
     let stride = pixbuf.get_rowstride() as usize;
-    let width_in_bytes = width * 4;
-    assert!(width_in_bytes <= stride);
 
     // We use chunks_mut(), not chunks_exact_mut(), because gdk-pixbuf tends
     // to make the last row *not* have the full stride (i.e. it is
     // only as wide as the pixels in that row).
-    let pixbuf_rows = pixels.chunks_mut(stride).take(height);
+    let pixbuf_rows = pixels.chunks_mut(stride).take(height as usize);
 
     for (src_row, dest_row) in surface.rows().zip(pixbuf_rows) {
-        let row: &mut [RGBA8] = dest_row[..width_in_bytes].as_rgba_mut();
-
+        let row: &mut [Pixel] = dest_row.as_rgba_mut();
         for (src, dest) in src_row.iter().zip(row.iter_mut()) {
-            let (r, g, b, a) = if src.a == 0 {
-                (0, 0, 0, 0)
+            *dest = if src.a == 0 {
+                Pixel::default()
             } else {
-                let pixel = Pixel {
-                    r: src.r,
-                    g: src.g,
-                    b: src.b,
-                    a: src.a,
-                }
-                .unpremultiply();
-
-                (pixel.r, pixel.g, pixel.b, pixel.a)
-            };
-
-            dest.r = r;
-            dest.g = g;
-            dest.b = b;
-            dest.a = a;
+                Pixel::from(*src).unpremultiply()
+            }
         }
     }
 
diff --git a/librsvg_crate/tests/utils/compare_surfaces.rs b/librsvg_crate/tests/utils/compare_surfaces.rs
index 0a6e48e2..3b9f2ad9 100644
--- a/librsvg_crate/tests/utils/compare_surfaces.rs
+++ b/librsvg_crate/tests/utils/compare_surfaces.rs
@@ -1,7 +1,7 @@
 use self::rsvg_internals::surface_utils::{
     iterators::Pixels,
     shared_surface::{SharedImageSurface, SurfaceType},
-    ImageSurfaceDataExt, Pixel,
+    ImageSurfaceDataExt, Pixel, PixelOps,
 };
 use self::rsvg_internals::{IRect, RenderingError};
 use rsvg_internals;
diff --git a/rsvg_internals/benches/pixel_ops.rs b/rsvg_internals/benches/pixel_ops.rs
index e4cee1e6..58c09ea5 100644
--- a/rsvg_internals/benches/pixel_ops.rs
+++ b/rsvg_internals/benches/pixel_ops.rs
@@ -1,6 +1,6 @@
 use criterion::{black_box, criterion_group, criterion_main, Criterion};
 
-use rsvg_internals::surface_utils::Pixel;
+use rsvg_internals::surface_utils::{Pixel, PixelOps};
 
 const OTHER: Pixel = Pixel {
     r: 0x10,
diff --git a/rsvg_internals/src/filters/turbulence.rs b/rsvg_internals/src/filters/turbulence.rs
index 22caf895..7a76fcdb 100644
--- a/rsvg_internals/src/filters/turbulence.rs
+++ b/rsvg_internals/src/filters/turbulence.rs
@@ -10,7 +10,7 @@ use crate::node::{CascadedValues, Node};
 use crate::parsers::{NumberOptionalNumber, Parse, ParseValue};
 use crate::surface_utils::{
     shared_surface::{ExclusiveImageSurface, SurfaceType},
-    ImageSurfaceDataExt, Pixel,
+    ImageSurfaceDataExt, Pixel, PixelOps,
 };
 use crate::util::clamp;
 
diff --git a/rsvg_internals/src/surface_utils/mod.rs b/rsvg_internals/src/surface_utils/mod.rs
index 8bbc57d1..5d74eae4 100644
--- a/rsvg_internals/src/surface_utils/mod.rs
+++ b/rsvg_internals/src/surface_utils/mod.rs
@@ -41,15 +41,6 @@ impl<T: Copy> AsCairoARGB<T> for [T] {
     }
 }
 
-/// A pixel consisting of R, G, B and A values.
-#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
-pub struct Pixel {
-    pub r: u8,
-    pub g: u8,
-    pub b: u8,
-    pub a: u8,
-}
-
 /// Modes which specify how the values of out of bounds pixels are computed.
 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
 pub enum EdgeMode {
@@ -77,10 +68,22 @@ pub trait ImageSurfaceDataExt: DerefMut<Target = [u8]> {
     }
 }
 
-impl Pixel {
+/// A pixel consisting of R, G, B and A values.
+pub type Pixel = rgb::RGBA8;
+
+pub trait PixelOps {
+    fn premultiply(self) -> Self;
+    fn unpremultiply(self) -> Self;
+    fn to_mask(self, opacity: u8) -> Self;
+    fn diff(self, other: &Self) -> Self;
+    fn to_u32(self) -> u32;
+    fn from_u32(x: u32) -> Self;
+}
+
+impl PixelOps for Pixel {
     /// Returns an unpremultiplied value of this pixel.
     #[inline]
-    pub fn unpremultiply(self) -> Self {
+    fn unpremultiply(self) -> Self {
         if self.a == 0 {
             self
         } else {
@@ -98,7 +101,7 @@ impl Pixel {
 
     /// Returns a premultiplied value of this pixel.
     #[inline]
-    pub fn premultiply(self) -> Self {
+    fn premultiply(self) -> Self {
         let alpha = f64::from(self.a) / 255.0;
         let premultiply = |x| ((f64::from(x) * alpha) + 0.5) as u8;
 
@@ -110,26 +113,6 @@ impl Pixel {
         }
     }
 
-    /// Returns the pixel value as a `u32`, in the same format as `cairo::Format::ARgb32`.
-    #[inline]
-    pub fn to_u32(self) -> u32 {
-        (u32::from(self.a) << 24)
-            | (u32::from(self.r) << 16)
-            | (u32::from(self.g) << 8)
-            | u32::from(self.b)
-    }
-
-    /// Converts a `u32` in the same format as `cairo::Format::ARgb32` into a `Pixel`.
-    #[inline]
-    pub fn from_u32(x: u32) -> Self {
-        Self {
-            r: ((x >> 16) & 0xFF) as u8,
-            g: ((x >> 8) & 0xFF) as u8,
-            b: (x & 0xFF) as u8,
-            a: ((x >> 24) & 0xFF) as u8,
-        }
-    }
-
     /// Returns a 'mask' pixel with only the alpha channel
     ///
     /// Assuming, the pixel is linear RGB (not sRGB)
@@ -145,11 +128,12 @@ impl Pixel {
     /// b_mult = 0xFFFFFFFF / (255.0 * 255.0) * .0722 =  4768.88  ~= 4769
     ///
     /// This allows for the following expected behaviour:
-    ///    (we only care about the most sig byte)
+    ///    (we only care about the most significant byte)
     /// if pixel = 0x00FFFFFF, pixel' = 0xFF......
     /// if pixel = 0x00020202, pixel' = 0x02......
     /// if pixel = 0x00000000, pixel' = 0x00......
-    pub fn to_mask(self, opacity: u8) -> Self {
+    #[inline]
+    fn to_mask(self, opacity: u8) -> Self {
         let r = u32::from(self.r);
         let g = u32::from(self.g);
         let b = u32::from(self.b);
@@ -164,7 +148,7 @@ impl Pixel {
     }
 
     #[inline]
-    pub fn diff(self, pixel: &Pixel) -> Pixel {
+    fn diff(self, pixel: &Pixel) -> Pixel {
         let a_r = i32::from(self.r);
         let a_g = i32::from(self.g);
         let a_b = i32::from(self.b);
@@ -182,6 +166,26 @@ impl Pixel {
 
         Pixel { r, g, b, a }
     }
+
+    /// Returns the pixel value as a `u32`, in the same format as `cairo::Format::ARgb32`.
+    #[inline]
+    fn to_u32(self) -> u32 {
+        (u32::from(self.a) << 24)
+            | (u32::from(self.r) << 16)
+            | (u32::from(self.g) << 8)
+            | u32::from(self.b)
+    }
+
+    /// Converts a `u32` in the same format as `cairo::Format::ARgb32` into a `Pixel`.
+    #[inline]
+    fn from_u32(x: u32) -> Self {
+        Self {
+            r: ((x >> 16) & 0xFF) as u8,
+            g: ((x >> 8) & 0xFF) as u8,
+            b: (x & 0xFF) as u8,
+            a: ((x >> 24) & 0xFF) as u8,
+        }
+    }
 }
 
 impl<'a> ImageSurfaceDataExt for cairo::ImageSurfaceData<'a> {}
diff --git a/rsvg_internals/src/surface_utils/shared_surface.rs 
b/rsvg_internals/src/surface_utils/shared_surface.rs
index e954c5ee..6103daba 100644
--- a/rsvg_internals/src/surface_utils/shared_surface.rs
+++ b/rsvg_internals/src/surface_utils/shared_surface.rs
@@ -6,7 +6,7 @@ use std::slice;
 
 use gdk_pixbuf::{Colorspace, Pixbuf};
 use nalgebra::{storage::Storage, Dim, Matrix};
-use rgb::{FromSlice, RGB8, RGBA8};
+use rgb::{FromSlice, RGB8};
 
 use crate::rect::{IRect, Rect};
 use crate::surface_utils::srgb;
@@ -15,7 +15,7 @@ use crate::util::clamp;
 
 use super::{
     iterators::{PixelRectangle, Pixels},
-    AsCairoARGB, CairoARGB, EdgeMode, ImageSurfaceDataExt, Pixel,
+    AsCairoARGB, CairoARGB, EdgeMode, ImageSurfaceDataExt, Pixel, PixelOps,
 };
 
 /// Types of pixel data in a `ImageSurface`.
@@ -281,32 +281,19 @@ impl ImageSurface<Shared> {
 
         let mut surf = ExclusiveImageSurface::new(width, height, SurfaceType::SRgb)?;
 
-        let width = width as usize;
-        let height = height as usize;
-
         {
             // We use chunks(), not chunks_exact(), because gdk-pixbuf tends
             // to make the last row *not* have the full stride (i.e. it is
             // only as wide as the pixels in that row).
-            let pixbuf_rows = pixbuf_data.chunks(pixbuf_stride).take(height);
-
+            let pixbuf_rows = pixbuf_data.chunks(pixbuf_stride).take(height as usize);
             let surf_rows = surf.rows_mut();
 
             if has_alpha {
-                let width_in_bytes = width * 4;
-
                 for (pixbuf_row, surf_row) in pixbuf_rows.zip(surf_rows) {
-                    let pixbuf_row: &[RGBA8] = pixbuf_row[..width_in_bytes].as_rgba();
+                    let pixbuf_row: &[Pixel] = pixbuf_row.as_rgba();
 
                     for (src, dest) in pixbuf_row.iter().zip(surf_row.iter_mut()) {
-                        let pixel = Pixel {
-                            r: src.r,
-                            g: src.g,
-                            b: src.b,
-                            a: src.a,
-                        };
-
-                        let pixel = pixel.premultiply();
+                        let pixel = src.premultiply();
                         dest.r = pixel.r;
                         dest.g = pixel.g;
                         dest.b = pixel.b;
@@ -314,10 +301,8 @@ impl ImageSurface<Shared> {
                     }
                 }
             } else {
-                let width_in_bytes = width * 3;
-
                 for (pixbuf_row, surf_row) in pixbuf_rows.zip(surf_rows) {
-                    let pixbuf_row: &[RGB8] = pixbuf_row[..width_in_bytes].as_rgb();
+                    let pixbuf_row: &[RGB8] = pixbuf_row.as_rgb();
 
                     for (src, dest) in pixbuf_row.iter().zip(surf_row.iter_mut()) {
                         dest.r = src.r;


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