[librsvg/librsvg-2.48] (#604): Fix build of the rgb crate on big-endian machines



commit 24ef7b91cb9477802e15735d49ff732bf5407ac1
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Jun 1 18:39:07 2020 -0500

    (#604): Fix build of the rgb crate on big-endian machines
    
    The ARGB<T> types, used to represent Cairo pixels, are only available
    through the "argb" feature.  I forgot to enable that, oops!
    
    Also, switch to the rgb::FromSlice trait instead of AsPixels.
    
    Since FromSlice is not defined for the ABGR types, we define our own
    AsCairoARGB in an analogous way to the rgb crate.
    
    Fixes https://gitlab.gnome.org/GNOME/librsvg/-/issues/604

 librsvg/Cargo.toml                                 |  2 +-
 librsvg/pixbuf_utils.rs                            |  4 ++--
 rsvg_internals/Cargo.toml                          |  2 +-
 rsvg_internals/src/surface_utils/mod.rs            | 27 ++++++++++++++++++++++
 rsvg_internals/src/surface_utils/shared_surface.rs | 12 +++++-----
 5 files changed, 37 insertions(+), 10 deletions(-)
---
diff --git a/librsvg/Cargo.toml b/librsvg/Cargo.toml
index cb2c9f19..edb17da9 100644
--- a/librsvg/Cargo.toml
+++ b/librsvg/Cargo.toml
@@ -23,7 +23,7 @@ gio = { version="0.8.0", features=["v2_50"] } # per configure.ac
 gio-sys = "0.9.0"
 gobject-sys = "0.9.0"
 libc = "0.2"
-rgb = "0.8.17"
+rgb = { version="0.8.17", features=["argb"] }
 rsvg_internals = { path = "../rsvg_internals" }
 url = "2"
 
diff --git a/librsvg/pixbuf_utils.rs b/librsvg/pixbuf_utils.rs
index 139328d9..b7fc563d 100644
--- a/librsvg/pixbuf_utils.rs
+++ b/librsvg/pixbuf_utils.rs
@@ -4,7 +4,7 @@ use std::ptr;
 use gdk_pixbuf::{Colorspace, Pixbuf};
 use gio::prelude::*;
 use glib::translate::*;
-use rgb::{AsPixels, RGBA8};
+use rgb::{FromSlice, RGBA8};
 use url::Url;
 
 use crate::c_api::checked_i32;
@@ -54,7 +54,7 @@ pub fn pixbuf_from_surface(surface: &SharedImageSurface) -> Result<Pixbuf, Rende
     let pixbuf_rows = pixels.chunks_mut(stride).take(height);
 
     for (src_row, dest_row) in surface.rows().zip(pixbuf_rows) {
-        let row: &mut [RGBA8] = dest_row[..width_in_bytes].as_pixels_mut();
+        let row: &mut [RGBA8] = dest_row[..width_in_bytes].as_rgba_mut();
 
         for (src, dest) in src_row.iter().zip(row.iter_mut()) {
             let (r, g, b, a) = if src.a == 0 {
diff --git a/rsvg_internals/Cargo.toml b/rsvg_internals/Cargo.toml
index 3a3fe6bb..53bcdb2f 100644
--- a/rsvg_internals/Cargo.toml
+++ b/rsvg_internals/Cargo.toml
@@ -36,7 +36,7 @@ pango-sys = "0.9.0"
 pangocairo = "0.9.0"
 rayon = "1"
 rctree = "0.3.3"
-rgb = "0.8.17"
+rgb = { version="0.8.17", features=["argb"] }
 regex = "1"
 selectors = "0.22.0"
 url = "2"
diff --git a/rsvg_internals/src/surface_utils/mod.rs b/rsvg_internals/src/surface_utils/mod.rs
index 206f82b0..6ee579b4 100644
--- a/rsvg_internals/src/surface_utils/mod.rs
+++ b/rsvg_internals/src/surface_utils/mod.rs
@@ -1,6 +1,8 @@
 //! Various utilities for working with Cairo image surfaces.
 
+use std::mem;
 use std::ops::DerefMut;
+use std::slice;
 
 pub mod iterators;
 pub mod shared_surface;
@@ -18,6 +20,31 @@ use rgb::alt::ARGB8;
 #[cfg(target_endian = "big")]
 pub type CairoARGB = ARGB8;
 
+/// Analogous to `rgb::FromSlice`, to convert from `[T]` to `[CairoARGB]`
+pub trait AsCairoARGB<T: Copy> {
+    /// Reinterpret slice as `CairoARGB` pixels.
+    fn as_cairo_argb(&self) -> &[CairoARGB];
+
+    /// Reinterpret mutable slice as `CairoARGB` pixels.
+    fn as_cairo_argb_mut(&mut self) -> &mut [CairoARGB];
+}
+
+impl<T: Copy> AsCairoARGB<T> for [T] {
+    fn as_cairo_argb(&self) -> &[CairoARGB] {
+        debug_assert_eq!(4, mem::size_of::<CairoARGB>() / mem::size_of::<T>());
+        unsafe {
+            slice::from_raw_parts(self.as_ptr() as *const _, self.len() / 4)
+        }
+    }
+
+    fn as_cairo_argb_mut(&mut self) -> &mut [CairoARGB] {
+        debug_assert_eq!(4, mem::size_of::<CairoARGB>() / mem::size_of::<T>());
+        unsafe {
+            slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() / 4)
+        }
+    }
+}
+
 /// A pixel consisting of R, G, B and A values.
 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
 pub struct Pixel {
diff --git a/rsvg_internals/src/surface_utils/shared_surface.rs 
b/rsvg_internals/src/surface_utils/shared_surface.rs
index 6f7654e3..d357b19d 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::{AsPixels, RGB8, RGBA8};
+use rgb::{FromSlice, RGB8, RGBA8};
 
 use crate::rect::{IRect, Rect};
 use crate::surface_utils::srgb;
@@ -15,7 +15,7 @@ use crate::util::clamp;
 
 use super::{
     iterators::{PixelRectangle, Pixels},
-    CairoARGB, EdgeMode, ImageSurfaceDataExt, Pixel,
+    AsCairoARGB, CairoARGB, EdgeMode, ImageSurfaceDataExt, Pixel,
 };
 
 /// Types of pixel data in a `ImageSurface`.
@@ -296,7 +296,7 @@ impl ImageSurface<Shared> {
                 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_pixels();
+                    let pixbuf_row: &[RGBA8] = pixbuf_row[..width_in_bytes].as_rgba();
 
                     for (src, dest) in pixbuf_row.iter().zip(surf_row.iter_mut()) {
                         let pixel = Pixel {
@@ -317,7 +317,7 @@ impl ImageSurface<Shared> {
                 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_pixels();
+                    let pixbuf_row: &[RGB8] = pixbuf_row[..width_in_bytes].as_rgb();
 
                     for (src, dest) in pixbuf_row.iter().zip(surf_row.iter_mut()) {
                         dest.r = src.r;
@@ -1197,7 +1197,7 @@ impl<'a> Iterator for Rows<'a> {
         unsafe {
             let row_ptr = self.surface.data_ptr.as_ptr().offset(row as isize * self.surface.stride);
             let row_of_bytes = slice::from_raw_parts(row_ptr, self.surface.width as usize * 4);
-            let pixels = row_of_bytes.as_pixels();
+            let pixels = row_of_bytes.as_cairo_argb();
             assert!(pixels.len() == self.surface.width as usize);
             Some(pixels)
         }
@@ -1224,7 +1224,7 @@ impl<'a> Iterator for RowsMut<'a> {
             let data_ptr = self.data.as_mut_ptr();
             let row_ptr = data_ptr.offset(row as isize * self.stride as isize);
             let row_of_bytes = slice::from_raw_parts_mut(row_ptr, self.width as usize * 4);
-            let pixels = row_of_bytes.as_pixels_mut();
+            let pixels = row_of_bytes.as_cairo_argb_mut();
             assert!(pixels.len() == self.width as usize);
             Some(pixels)
         }


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