diff --git a/src/main.rs b/src/main.rs index 569793e..bfa7d5d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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> { 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> { 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> { 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> { 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> { 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: {}",