[librsvg: 2/7] SharedImageSurface::from_pixbuf() - Implement this in Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 2/7] SharedImageSurface::from_pixbuf() - Implement this in Rust
- Date: Mon, 1 Oct 2018 19:36:45 +0000 (UTC)
commit 5ca2ec545e9fad4bd546b7cc378a8af1e409788f
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]