[librsvg/librsvg-2.44] SharedImageSurface::from_pixbuf() - Implement this in Rust



commit fb379d899ec72deb92366f43eeadb68bc1496491
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Oct 1 10:59:03 2018 -0500

    SharedImageSurface::from_pixbuf() - Implement this in Rust

 Cargo.lock                                         | 58 ++++++++++++++++++
 rsvg_internals/Cargo.toml                          |  3 +
 rsvg_internals/src/lib.rs                          |  1 +
 rsvg_internals/src/surface_utils/shared_surface.rs | 68 ++++++++++++++++++++++
 4 files changed, 130 insertions(+)
---
diff --git a/Cargo.lock b/Cargo.lock
index 5fef23ca..605bdc4e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -345,6 +345,33 @@ name = "fuchsia-zircon-sys"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 
+[[package]]
+name = "gdk-pixbuf"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "gdk-pixbuf-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "gdk-pixbuf-sys"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "generic-array"
 version = "0.11.1"
@@ -353,6 +380,32 @@ dependencies = [
  "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "gio"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "gio-sys"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "glib"
 version = "0.5.0"
@@ -767,6 +820,7 @@ dependencies = [
  "cssparser 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "downcast-rs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gdk-pixbuf 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1048,7 +1102,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 "checksum float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600"
 "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = 
"2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = 
"3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
+"checksum gdk-pixbuf 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"c2d2199eba47ebcb9977ce28179649bdd59305ef465c4e6f9b65aaa41c24e6b5"
+"checksum gdk-pixbuf-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"df6a3b73e04fafc07f5ebc083f1096a773412e627828e1103a55e921f81187d8"
 "checksum generic-array 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"8107dafa78c80c848b71b60133954b4a58609a3a1a5f9af037ecc7f67280f369"
+"checksum gio 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"2db9fad8f1b0d4c7338a210a6cbdf081dcc1a3c223718c698c4f313f6c288acb"
+"checksum gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"2a57872499171d279f8577ce83837da4cae62b08dd32892236ed67ab7ea61030"
 "checksum glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"5e0be1b1432e227bcd1a9b28db9dc1474a7e7fd4227e08e16f35304f32d09b61"
 "checksum glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"615bef979b5838526aee99241afc80cfb2e34a8735d4bcb8ec6072598c18a408"
 "checksum gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"70409d6405db8b1591602fcd0cbe8af52cd9976dd39194442b4c149ba343f86d"
diff --git a/rsvg_internals/Cargo.toml b/rsvg_internals/Cargo.toml
index c859cd29..cb927e1f 100644
--- a/rsvg_internals/Cargo.toml
+++ b/rsvg_internals/Cargo.toml
@@ -63,6 +63,9 @@ version = "0.6"
 #git = "https://github.com/gtk-rs/sys";
 #branch = "master"
 
+[dependencies.gdk-pixbuf]
+version = "0.4"
+
 [dev-dependencies]
 criterion = "0.2"
 
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index c0147338..c40204a5 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -6,6 +6,7 @@ extern crate cairo;
 extern crate cairo_sys;
 extern crate cssparser;
 extern crate float_cmp;
+extern crate gdk_pixbuf;
 extern crate glib;
 extern crate glib_sys;
 extern crate itertools;
diff --git a/rsvg_internals/src/surface_utils/shared_surface.rs 
b/rsvg_internals/src/surface_utils/shared_surface.rs
index e90f4345..36852c09 100644
--- a/rsvg_internals/src/surface_utils/shared_surface.rs
+++ b/rsvg_internals/src/surface_utils/shared_surface.rs
@@ -6,6 +6,7 @@ use std::ptr::NonNull;
 use cairo::prelude::SurfaceExt;
 use cairo::{self, ImageSurface};
 use cairo_sys;
+use gdk_pixbuf::{Colorspace, Pixbuf, PixbufExt};
 use glib::translate::{Stash, ToGlibPtr};
 use nalgebra::{storage::Storage, Dim, Matrix};
 use rayon;
@@ -166,6 +167,73 @@ impl SharedImageSurface {
         }
     }
 
+    pub fn from_pixbuf(pixbuf: &Pixbuf) -> Result<SharedImageSurface, cairo::Status> {
+        assert!(pixbuf.get_colorspace() == Colorspace::Rgb);
+
+        let n_channels = pixbuf.get_n_channels();
+        assert!(n_channels == 3 || n_channels == 4);
+        let has_alpha = n_channels == 4;
+
+        let width = pixbuf.get_width();
+        assert!(width > 0);
+
+        let height = pixbuf.get_height();
+        assert!(height > 0);
+
+        let pixbuf_stride = pixbuf.get_rowstride();
+        assert!(pixbuf_stride > 0);
+        let pixbuf_stride = pixbuf_stride as usize;
+
+        let pixbuf_data = unsafe { pixbuf.get_pixels() };
+
+        let mut surf = ImageSurface::create(cairo::Format::ARgb32, width, height)?;
+
+        let width = width as usize;
+        let height = height as usize;
+
+        {
+            let surf_stride = surf.get_stride() as usize;
+
+            let mut surf_data = surf.get_data().unwrap();
+
+            if has_alpha {
+                for y in 0..height {
+                    for x in 0..width {
+                        let ofs = pixbuf_stride * y + 4 * x;
+
+                        let pixel = Pixel {
+                            r: pixbuf_data[ofs],
+                            g: pixbuf_data[ofs + 1],
+                            b: pixbuf_data[ofs + 2],
+                            a: pixbuf_data[ofs + 3],
+                        };
+
+                        let pixel = pixel.premultiply();
+
+                        surf_data.set_pixel(surf_stride, pixel, x as u32, y as u32);
+                    }
+                }
+            } else {
+                for y in 0..height {
+                    for x in 0..width {
+                        let ofs = pixbuf_stride * y + 3 * x;
+
+                        let pixel = Pixel {
+                            r: pixbuf_data[ofs],
+                            g: pixbuf_data[ofs + 1],
+                            b: pixbuf_data[ofs + 2],
+                            a: 0xff,
+                        };
+
+                        surf_data.set_pixel(surf_stride, pixel, x as u32, y as u32);
+                    }
+                }
+            }
+        }
+
+        Self::new(surf, SurfaceType::SRgb)
+    }
+
     /// Returns the surface width.
     #[inline]
     pub fn width(&self) -> i32 {


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