[librsvg/wip/aruiz/rust-pixbuf-loader] pixbuf loader: remove leaks
- From: Alberto Ruiz <aruiz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/wip/aruiz/rust-pixbuf-loader] pixbuf loader: remove leaks
- Date: Thu, 28 Jul 2022 15:34:33 +0000 (UTC)
commit 9666db61df79cc239cd3e243c691129a2f822f9a
Author: Alberto Ruiz <aruiz redhat com>
Date: Thu Jul 28 16:34:25 2022 +0100
pixbuf loader: remove leaks
gdk-pixbuf-loader/src/lib.rs | 131 +++++++++++++++++--------------------------
1 file changed, 53 insertions(+), 78 deletions(-)
---
diff --git a/gdk-pixbuf-loader/src/lib.rs b/gdk-pixbuf-loader/src/lib.rs
index 06e433ef6..b784f6629 100644
--- a/gdk-pixbuf-loader/src/lib.rs
+++ b/gdk-pixbuf-loader/src/lib.rs
@@ -7,6 +7,7 @@ use gdk_pixbuf_sys::{
};
use glib_sys::GError;
+use gobject_sys::GObject;
use libc::{c_char, c_int, c_uint, c_void};
use gio::prelude::MemoryInputStreamExt;
@@ -89,89 +90,61 @@ unsafe extern "C" fn stop_load(user_data: *mut c_void, error: *mut *mut GError)
*error = null_mut();
}
- let handle = match Loader::new().read_stream::<_, gio::File, gio::Cancellable>(
- &ctx.stream,
- None,
- None,
- ) {
- Ok(handle) => handle,
- Err(e) => {
- let gerr = glib::Error::new(gdk_pixbuf::PixbufError::Failed, &e.to_string());
- *error = gerr.into_raw();
- return 0;
- }
- };
-
- let renderer = librsvg::CairoRenderer::new(&handle);
- let (w, h) = match renderer.intrinsic_size_in_pixels() {
- Some((w, h)) => (w, h),
- None => {
- let gerr = glib::Error::new(
- gdk_pixbuf::PixbufError::Failed,
- "Could not get intrinsic size in pixel of Cairo memory surface",
- );
- *error = gerr.into_raw();
- return 0;
- }
- };
-
- let surface = match cairo::ImageSurface::create(
- cairo::Format::ARgb32,
- w.ceil() as i32,
- h.ceil() as i32,
- ) {
- Ok(sfc) => sfc,
- Err(e) => {
- let gerr = glib::Error::new(gdk_pixbuf::PixbufError::Failed, &e.to_string());
- *error = gerr.into_raw();
- return 0;
- }
- };
-
- let cr = match cairo::Context::new(&surface) {
- Ok(cr) => cr,
- Err(e) => {
- let gerr = glib::Error::new(gdk_pixbuf::PixbufError::Failed, &e.to_string());
- *error = gerr.into_raw();
- return 0;
- }
- };
-
- match renderer.render_document(
- &cr,
- &cairo::Rectangle {
- x: 0.0,
- y: 0.0,
- width: w,
- height: h,
- },
- ) {
- Err(e) => {
- let gerr = glib::Error::new(gdk_pixbuf::PixbufError::Failed, &e.to_string());
- *error = gerr.into_raw();
- return 0;
- }
- _ => {}
- };
-
- let mut w = w.ceil() as i32;
- let mut h = h.ceil() as i32;
+ fn _inner_stop_load(ctx: &Box<SvgContext>) -> Result<(Vec<u8>, i32, i32, i32), String> {
+ let handle = Loader::new()
+ .read_stream::<_, gio::File, gio::Cancellable>(&ctx.stream, None, None)
+ .map_err(|e| e.to_string())?;
+
+ let renderer = librsvg::CairoRenderer::new(&handle);
+ let (w, h) = match renderer.intrinsic_size_in_pixels() {
+ Some((w, h)) => (w, h),
+ None => {
+ return Err(String::from(
+ "Could not get intrinsic size in pixel of Cairo memory surface",
+ ));
+ }
+ };
+
+ let surface =
+ cairo::ImageSurface::create(cairo::Format::ARgb32, w.ceil() as i32, h.ceil() as i32)
+ .map_err(|e| e.to_string())?;
+
+ let cr = cairo::Context::new(&surface).map_err(|e| e.to_string())?;
+
+ renderer
+ .render_document(
+ &cr,
+ &cairo::Rectangle {
+ x: 0.0,
+ y: 0.0,
+ width: w,
+ height: h,
+ },
+ )
+ .map_err(|e| e.to_string())?;
+
+ let w = w.ceil() as i32;
+ let h = h.ceil() as i32;
+
+ let stride = surface.stride();
+ // The cairo::Context holds a reference to the surface which needs to be dropped to access the data
+ std::mem::drop(cr);
+ let sfc_data = surface.take_data().map_err(|e| e.to_string())?;
+ let sfc_data = unsafe { std::slice::from_raw_parts(sfc_data.as_ptr(), sfc_data.len()) }; // This is
just a slice to the canonical data
+ // We need
it as a mutable vector to move the alpha channel around
+ let pb_data = sfc_data.to_vec();
+
+ Ok((pb_data, w, h, stride))
+ }
- let stride = surface.stride();
- // The cairo::Context holds a reference to the surface which needs to be dropped to access the data
- std::mem::drop(cr);
- let sfc_data = match surface.take_data() {
- Ok(data) => data,
+ let (mut pb_data, mut w, mut h, stride) = match _inner_stop_load(&ctx) {
+ Ok(r) => r,
Err(e) => {
let gerr = glib::Error::new(gdk_pixbuf::PixbufError::Failed, &e.to_string());
*error = gerr.into_raw();
return 0;
}
};
- let sfc_data = std::slice::from_raw_parts(sfc_data.as_ptr(), sfc_data.len()); // This is just a slice to
the canonical data
-
- // We need it as a mutable vector to move the alpha channel around
- let mut pb_data = sfc_data.to_vec();
// GDK Pixbuf only support RGBA and Cairo only ARGB32, we swap channels around
argb_to_rgba(&mut pb_data, w as usize, h as usize, stride as usize);
@@ -181,7 +154,7 @@ unsafe extern "C" fn stop_load(user_data: *mut c_void, error: *mut *mut GError)
// Function to free the pixel data by rebuilding the Vec object
#[no_mangle]
- unsafe extern "C" fn destroy_fn(pixels: *mut u8, user_data: *mut c_void) {
+ unsafe extern "C" fn destroy_cb_foo(pixels: *mut u8, user_data: *mut c_void) {
let data = Box::<(usize, usize)>::from_raw(user_data as *mut (usize, usize));
Vec::from_raw_parts(pixels, data.0, data.1);
}
@@ -195,7 +168,7 @@ unsafe extern "C" fn stop_load(user_data: *mut c_void, error: *mut *mut GError)
w,
h,
stride,
- Some(destroy_fn),
+ Some(destroy_cb_foo),
Box::into_raw(cb_data) as *mut c_void,
);
if let Some(size_func) = ctx.size_func {
@@ -208,6 +181,8 @@ unsafe extern "C" fn stop_load(user_data: *mut c_void, error: *mut *mut GError)
prep_func(pixbuf, null_mut(), ctx.user_data);
}
+ gobject_sys::g_object_unref(pixbuf as *mut GObject);
+
1
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]