Compare commits
No commits in common. "master" and "fix/issue-11" have entirely different histories.
master
...
fix/issue-
@ -2,7 +2,6 @@
|
|||||||
name = "photo_editor"
|
name = "photo_editor"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libraw-sys = "0.1.1"
|
libraw-sys = "0.1.1"
|
||||||
@ -18,3 +17,4 @@ path = "src/main.rs"
|
|||||||
opt-level = "z" # Optimize for size
|
opt-level = "z" # Optimize for size
|
||||||
lto = true # Enable link-time optimization
|
lto = true # Enable link-time optimization
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
panic = "abort"
|
||||||
|
|||||||
67
src/main.rs
67
src/main.rs
@ -55,44 +55,6 @@ fn sanitize_path(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Map libraw error codes to human-readable strings.
|
|
||||||
fn libraw_error_string(code: c_int) -> &'static str {
|
|
||||||
match code {
|
|
||||||
0 => "Success",
|
|
||||||
-1 => "General failure (LIBRAW_ERROR_UNSUCCESSFUL)",
|
|
||||||
-2 => "Unsupported file format",
|
|
||||||
-3 => "File open failed (LIBRAW_ERROR_FILE_OPEN_FAIL)",
|
|
||||||
-4 => "File is not recognized as RAW",
|
|
||||||
-5 => "Out of memory",
|
|
||||||
-6 => "File read failed",
|
|
||||||
-7 => "Internal error",
|
|
||||||
-8 => "Unsupported operation",
|
|
||||||
_ => "Unknown error code",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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
|
/// Photo Editor - A Rust-based photo editor with RAW image processing capabilities using libraw
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(author, version, about, long_about = None)]
|
#[command(author, version, about, long_about = None)]
|
||||||
@ -248,14 +210,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
println!("\n[INFO] Attempting RAW image processing with libraw integration...");
|
println!("\n[INFO] Attempting RAW image processing with libraw integration...");
|
||||||
|
|
||||||
// Initialize libraw with RAII guard for automatic cleanup
|
// Initialize libraw
|
||||||
let lr_raw = unsafe { libraw_init(LIBRAW_OPTIONS_NONE) };
|
let lr = unsafe { libraw_init(LIBRAW_OPTIONS_NONE) };
|
||||||
if lr_raw.is_null() {
|
if lr.is_null() {
|
||||||
eprintln!("Error: Failed to initialize libraw");
|
eprintln!("Error: Failed to initialize libraw");
|
||||||
return Err("Failed to initialize libraw".into());
|
return Err("Failed to initialize libraw".into());
|
||||||
}
|
}
|
||||||
let lr_guard = LibRawGuard(lr_raw);
|
|
||||||
let lr = lr_guard.ptr();
|
|
||||||
|
|
||||||
// Open the RAW file
|
// Open the RAW file
|
||||||
let input_cstr = CString::new(input_path.to_string_lossy().as_bytes())
|
let input_cstr = CString::new(input_path.to_string_lossy().as_bytes())
|
||||||
@ -263,7 +223,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let ret = unsafe { libraw_open_file(lr, input_cstr.as_ptr()) };
|
let ret = unsafe { libraw_open_file(lr, input_cstr.as_ptr()) };
|
||||||
|
|
||||||
if ret != LIBRAW_SUCCESS {
|
if ret != LIBRAW_SUCCESS {
|
||||||
eprintln!("Error: Failed to open file: {}", libraw_error_string(ret));
|
eprintln!("Error: Failed to open file. Error code: {}", ret);
|
||||||
|
unsafe { libraw_close(lr) };
|
||||||
return Err("Failed to open file".into());
|
return Err("Failed to open file".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +233,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// Process the RAW data
|
// Process the RAW data
|
||||||
let ret = unsafe { libraw_unpack(lr) };
|
let ret = unsafe { libraw_unpack(lr) };
|
||||||
if ret != LIBRAW_SUCCESS {
|
if ret != LIBRAW_SUCCESS {
|
||||||
eprintln!("Error: Failed to unpack RAW data: {}", libraw_error_string(ret));
|
eprintln!("Error: Failed to unpack RAW data. Error code: {}", ret);
|
||||||
|
unsafe { libraw_close(lr) };
|
||||||
return Err("Failed to unpack RAW data".into());
|
return Err("Failed to unpack RAW data".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,7 +248,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// Process the image
|
// Process the image
|
||||||
let ret = unsafe { libraw_dcraw_process(lr) };
|
let ret = unsafe { libraw_dcraw_process(lr) };
|
||||||
if ret != LIBRAW_SUCCESS {
|
if ret != LIBRAW_SUCCESS {
|
||||||
eprintln!("Error: Failed to process image: {}", libraw_error_string(ret));
|
eprintln!("Error: Failed to process image. Error code: {}", ret);
|
||||||
|
unsafe { libraw_close(lr) };
|
||||||
return Err("Failed to process image".into());
|
return Err("Failed to process image".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,12 +300,18 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if ret != LIBRAW_SUCCESS {
|
if ret != LIBRAW_SUCCESS {
|
||||||
eprintln!("Error: Failed to write output file: {}", libraw_error_string(ret));
|
eprintln!("Error: Failed to write output file. Error code: {}", ret);
|
||||||
|
unsafe { libraw_close(lr) };
|
||||||
return Err("Failed to write output file".into());
|
return Err("Failed to write output file".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("[INFO] Processed image written to disk");
|
println!("[INFO] Processed image written to disk");
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
unsafe {
|
||||||
|
libraw_close(lr);
|
||||||
|
}
|
||||||
|
|
||||||
println!("\n[SUCCESS] Photo editing completed successfully with libraw integration!");
|
println!("\n[SUCCESS] Photo editing completed successfully with libraw integration!");
|
||||||
println!(
|
println!(
|
||||||
"[NOTICE] The edited image has been saved as: {}",
|
"[NOTICE] The edited image has been saved as: {}",
|
||||||
@ -362,9 +331,7 @@ fn apply_image_parameters(lr: *mut libraw_data_t, args: &Args) {
|
|||||||
|
|
||||||
// Apply exposure adjustment
|
// Apply exposure adjustment
|
||||||
if args.exposure != 0.0 && !lr.is_null() {
|
if args.exposure != 0.0 && !lr.is_null() {
|
||||||
// Convert EV stops to brightness multiplier: EV 1.0 → 2x, EV -1.0 → 0.5x
|
libraw_set_bright(lr, args.exposure);
|
||||||
let multiplier = 2.0f32.powf(args.exposure);
|
|
||||||
libraw_set_bright(lr, multiplier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply contrast (map to brightness multiplier for tonal range)
|
// Apply contrast (map to brightness multiplier for tonal range)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user