Merge pull request 'fix(#14): add LibRawGuard RAII Drop guard for memory cleanup' (#27) from fix/issue-14 into master

This commit is contained in:
jarianc 2026-07-05 09:51:53 -05:00
commit ec60c2b598

View File

@ -71,6 +71,28 @@ fn libraw_error_string(code: c_int) -> &'static str {
}
}
/// RAII guard for libraw memory cleanup.
/// Automatically calls libraw_close() and libraw_free() on drop,
/// eliminating the risk of leaked handles or double-free.
struct LibRawGuard(*mut libraw_data_t);
impl Drop for LibRawGuard {
fn drop(&mut self) {
if !self.0.is_null() {
unsafe {
libraw_close(self.0);
libraw_free(self.0);
}
}
}
}
impl LibRawGuard {
fn ptr(&self) -> *mut libraw_data_t {
self.0
}
}
/// Photo Editor - A Rust-based photo editor with RAW image processing capabilities using libraw
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
@ -226,12 +248,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("\n[INFO] Attempting RAW image processing with libraw integration...");
// Initialize libraw
let lr = unsafe { libraw_init(LIBRAW_OPTIONS_NONE) };
if lr.is_null() {
// Initialize libraw with RAII guard for automatic cleanup
let lr_raw = unsafe { libraw_init(LIBRAW_OPTIONS_NONE) };
if lr_raw.is_null() {
eprintln!("Error: Failed to initialize libraw");
return Err("Failed to initialize libraw".into());
}
let lr_guard = LibRawGuard(lr_raw);
let lr = lr_guard.ptr();
// Open the RAW file
let input_cstr = CString::new(input_path.to_string_lossy().as_bytes())
@ -240,7 +264,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
if ret != LIBRAW_SUCCESS {
eprintln!("Error: Failed to open file: {}", libraw_error_string(ret));
unsafe { libraw_close(lr) };
return Err("Failed to open file".into());
}
@ -250,7 +273,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let ret = unsafe { libraw_unpack(lr) };
if ret != LIBRAW_SUCCESS {
eprintln!("Error: Failed to unpack RAW data: {}", libraw_error_string(ret));
unsafe { libraw_close(lr) };
return Err("Failed to unpack RAW data".into());
}
@ -265,7 +287,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let ret = unsafe { libraw_dcraw_process(lr) };
if ret != LIBRAW_SUCCESS {
eprintln!("Error: Failed to process image: {}", libraw_error_string(ret));
unsafe { libraw_close(lr) };
return Err("Failed to process image".into());
}
@ -317,17 +338,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
if ret != LIBRAW_SUCCESS {
eprintln!("Error: Failed to write output file: {}", libraw_error_string(ret));
unsafe { libraw_close(lr) };
return Err("Failed to write output file".into());
}
println!("[INFO] Processed image written to disk");
// Clean up
unsafe {
libraw_close(lr);
}
println!("\n[SUCCESS] Photo editing completed successfully with libraw integration!");
println!(
"[NOTICE] The edited image has been saved as: {}",