[librsvg] librsvg_crate/tests/compare_surfaces.rs: New file, port of test_utils_compare_surfaces() to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] librsvg_crate/tests/compare_surfaces.rs: New file, port of test_utils_compare_surfaces() to Rust
- Date: Sat, 2 Mar 2019 01:48:33 +0000 (UTC)
commit 49c18f068419c9882c94c4c24b7ad16889e0b6a9
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Mar 1 19:45:48 2019 -0600
librsvg_crate/tests/compare_surfaces.rs: New file, port of test_utils_compare_surfaces() to Rust
librsvg_crate/Cargo.toml | 1 +
librsvg_crate/tests/compare_surfaces.rs | 140 ++++++++++++++++++++++++++++++++
rsvg_internals/src/lib.rs | 2 +
rsvg_internals/src/surface_utils/mod.rs | 20 +++++
4 files changed, 163 insertions(+)
---
diff --git a/librsvg_crate/Cargo.toml b/librsvg_crate/Cargo.toml
index c4a9aa2b..8e6ce710 100644
--- a/librsvg_crate/Cargo.toml
+++ b/librsvg_crate/Cargo.toml
@@ -17,6 +17,7 @@ url = "1.7.2"
[dev-dependencies]
cairo-rs = { version = "0.6.0", features = ["png"] }
+rsvg_internals = { path = "../rsvg_internals" }
[build-dependencies]
pkg-config = "0.3.14"
diff --git a/librsvg_crate/tests/compare_surfaces.rs b/librsvg_crate/tests/compare_surfaces.rs
new file mode 100644
index 00000000..229f494c
--- /dev/null
+++ b/librsvg_crate/tests/compare_surfaces.rs
@@ -0,0 +1,140 @@
+extern crate cairo;
+extern crate rsvg_internals;
+
+use cairo::ImageSurface;
+
+use rsvg_internals::{IRect, RenderingError};
+use rsvg_internals::surface_utils::{
+ iterators::Pixels,
+ shared_surface::{SharedImageSurface, SurfaceType},
+ ImageSurfaceDataExt,
+ Pixel,
+};
+
+pub enum BufferDiff {
+ DifferentSizes,
+ Diff(Diff),
+}
+
+pub struct Diff {
+ num_pixels_changed: usize,
+ max_diff: u8,
+ surface: SharedImageSurface,
+}
+
+#[inline]
+fn pixel_max(p: &Pixel) -> u8 {
+ p.r.max(p.g).max(p.b).max(p.a)
+}
+
+#[inline]
+fn emphasize(p: &Pixel) -> Pixel {
+ let mut r = p.r as u32;
+ let mut g = p.g as u32;
+ let mut b = p.b as u32;
+ let mut a = p.a as u32;
+
+ // emphasize
+ r = r * 4;
+ g = g * 4;
+ b = b * 4;
+ a = a * 4;
+
+ // make sure they are visible
+ if r > 0 {
+ r += 128;
+ }
+
+ if g > 0 {
+ g += 128;
+ }
+
+ if b > 0 {
+ b += 128;
+ }
+
+ if a > 0 {
+ a += 128;
+ }
+
+ let r = r.min(255) as u8;
+ let g = g.min(255) as u8;
+ let b = b.min(255) as u8;
+ let a = a.min(255) as u8;
+
+ Pixel { r, g, b, a }
+}
+
+pub fn compare_surfaces(
+ surf_a: &SharedImageSurface,
+ surf_b: &SharedImageSurface,
+) -> Result<BufferDiff, RenderingError> {
+ let a_width = surf_a.width();
+ let a_height = surf_a.height();
+
+ let b_width = surf_b.width();
+ let b_height = surf_b.height();
+
+ if a_width != b_width || a_height != b_height {
+ return Ok(BufferDiff::DifferentSizes);
+ }
+
+ let mut surf_diff = ImageSurface::create(cairo::Format::ARgb32, a_width, a_height)?;
+ let diff_stride = surf_diff.get_stride() as usize;
+
+ let bounds = IRect {
+ x0: 0,
+ y0: 0,
+ x1: a_width,
+ y1: a_height,
+ };
+
+ let mut num_pixels_changed = 0;
+ let mut max_diff = 0;
+
+ {
+ let mut diff_data = surf_diff.get_data().unwrap();
+
+ for ((xa, ya, pixel_a), (_, _, pixel_b)) in
+ Pixels::new(surf_a, bounds).zip(Pixels::new(surf_b, bounds))
+ {
+ if pixel_a != pixel_b {
+ num_pixels_changed += 1;
+
+ let pixel_diff = pixel_a.diff(&pixel_b);
+
+ let pixel_max_diff = pixel_max(&pixel_diff);
+
+ max_diff = max_diff.max(pixel_max_diff);
+
+ let mut pixel_diff = emphasize(&pixel_diff);
+
+ if pixel_diff.r == 0 && pixel_diff.g == 0 && pixel_diff.b == 0 {
+ // alpha only difference; convert alpha to gray
+
+ pixel_diff.r = pixel_diff.a;
+ pixel_diff.g = pixel_diff.a;
+ pixel_diff.b = pixel_diff.a;
+ }
+
+ diff_data.set_pixel(diff_stride, pixel_diff, xa, ya);
+ } else {
+ let black = Pixel {
+ r: 0,
+ g: 0,
+ b: 0,
+ a: 0,
+ };
+ diff_data.set_pixel(diff_stride, black, xa, ya);
+ }
+ }
+ }
+
+ let surface = SharedImageSurface::new(surf_diff, SurfaceType::SRgb)?;
+
+ Ok(BufferDiff::Diff(Diff {
+ num_pixels_changed,
+ max_diff,
+ surface,
+ }))
+}
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 5f9b9b94..df93fa7f 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -101,6 +101,8 @@ pub use pixbuf_utils::{
rsvg_rust_pixbuf_from_file_at_zoom_with_max,
};
+pub use rect::IRect;
+
#[macro_use]
mod log;
diff --git a/rsvg_internals/src/surface_utils/mod.rs b/rsvg_internals/src/surface_utils/mod.rs
index 00a58306..efc28542 100644
--- a/rsvg_internals/src/surface_utils/mod.rs
+++ b/rsvg_internals/src/surface_utils/mod.rs
@@ -125,6 +125,26 @@ impl Pixel {
a: (((r * 14042 + g * 47240 + b * 4769) * o) >> 24) as u8,
}
}
+
+ #[inline]
+ pub fn diff(self, p: &Pixel) -> Pixel {
+ let a_r = self.r as i32;
+ let a_g = self.g as i32;
+ let a_b = self.b as i32;
+ let a_a = self.a as i32;
+
+ let b_r = p.r as i32;
+ let b_g = p.g as i32;
+ let b_b = p.b as i32;
+ let b_a = p.a as i32;
+
+ let r = (a_r - b_r).abs() as u8;
+ let g = (a_g - b_g).abs() as u8;
+ let b = (a_b - b_b).abs() as u8;
+ let a = (a_a - b_a).abs() as u8;
+
+ Pixel { r, g, b, a }
+ }
}
impl<'a> ImageSurfaceDataExt for cairo::ImageSurfaceData<'a> {}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]