fix(#2): proper JPEG output via libraw_dcraw_make_mem_image + image crate
This commit is contained in:
parent
2481ed644b
commit
462541e096
@ -7,6 +7,7 @@ edition = "2024"
|
||||
libraw-sys = "0.1.1"
|
||||
image = "0.24"
|
||||
clap = { version = "4.0", features = ["derive"] }
|
||||
libc = "0.2"
|
||||
|
||||
[[bin]]
|
||||
name = "photo_editor"
|
||||
|
||||
43
src/main.rs
43
src/main.rs
@ -1,8 +1,10 @@
|
||||
use clap::Parser;
|
||||
use image::{DynamicImage, ImageBuffer, Rgb};
|
||||
use libraw_sys::*;
|
||||
use std::ffi::CString;
|
||||
use std::os::raw::c_int;
|
||||
use std::os::raw::{c_int, c_size_t};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::ptr::null_mut;
|
||||
|
||||
/// Resolve and sanitize a user-provided path.
|
||||
/// - Resolves to absolute path via canonicalize (or parent canonicalization for output)
|
||||
@ -195,9 +197,42 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.unwrap_or("jpg")
|
||||
.to_lowercase();
|
||||
|
||||
let output_cstr = CString::new(output_path.to_string_lossy().as_bytes())
|
||||
.map_err(|_| "Output path contains null bytes, cannot process".into())?;
|
||||
let ret = unsafe { libraw_dcraw_ppm_tiff_writer(lr, output_cstr.as_ptr()) };
|
||||
let ret = if ext == "jpg" || ext == "jpeg" {
|
||||
// Use libraw_dcraw_make_mem_image + image crate for proper JPEG encoding
|
||||
let mut imgdata: *mut std::os::raw::c_uchar = null_mut();
|
||||
let mut imgsize: c_size_t = 0;
|
||||
let ret = unsafe { libraw_dcraw_make_mem_image(lr, &mut imgdata, &mut imgsize) };
|
||||
if ret != LIBRAW_SUCCESS {
|
||||
ret
|
||||
} else {
|
||||
let width = unsafe { (*(*lr).internal_data).imgdata.idata.width } as u32;
|
||||
let height = unsafe { (*(*lr).internal_data).imgdata.idata.height } as u32;
|
||||
let bytes = unsafe { std::slice::from_raw_parts(imgdata, imgsize as usize) };
|
||||
let img = DynamicImage::ImageRgb8(ImageBuffer::<Rgb<u8>, Vec<u8>>::from_raw(
|
||||
width,
|
||||
height,
|
||||
bytes.to_vec(),
|
||||
).ok_or("Failed to create image from libraw data")?);
|
||||
unsafe {
|
||||
let freedata = *(*lr).internal_data.imgdata.freedata;
|
||||
let freesize = *(*lr).internal_data.imgdata.freesize;
|
||||
if !freedata.is_null() {
|
||||
libc::free(freedata as *mut std::os::raw::c_void);
|
||||
}
|
||||
}
|
||||
img.save_with_format(&output_path, image::ImageOutputFormat::Jpeg(90))
|
||||
.map_err(|e| {
|
||||
eprintln!("Error: Failed to write JPEG: {}", e);
|
||||
"Failed to write JPEG".to_string()
|
||||
})?;
|
||||
LIBRAW_SUCCESS
|
||||
}
|
||||
} else {
|
||||
// For TIFF/PPM, use libraw_dcraw_ppm_tiff_writer
|
||||
let output_cstr = CString::new(output_path.to_string_lossy().as_bytes())
|
||||
.map_err(|_| "Output path contains null bytes, cannot process".into())?;
|
||||
unsafe { libraw_dcraw_ppm_tiff_writer(lr, output_cstr.as_ptr()) }
|
||||
};
|
||||
|
||||
if ret != LIBRAW_SUCCESS {
|
||||
eprintln!("Error: Failed to write output file. Error code: {}", ret);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user