1use std::mem;
2
3use crate::{Error, ProcessedImage, RawImage, Result};
4use libraw_sys as sys;
5
6pub struct Processor {
7 pub(crate) inner: *mut sys::libraw_data_t,
8}
9
10impl Processor {
11 pub fn new() -> Self {
12 let inner = unsafe { sys::libraw_init(0) };
13 Self { inner }
14 }
15
16 fn open(&self, buf: &[u8]) -> Result<()> {
17 Error::check(unsafe {
18 sys::libraw_open_buffer(self.inner, buf.as_ptr() as *const _, buf.len())
19 })?;
20 Error::check(unsafe { sys::libraw_unpack(self.inner) })?;
21
22 Ok(())
23 }
24
25 pub fn decode(self, buf: &[u8]) -> Result<RawImage> {
26 self.open(buf)?;
27
28 let decoded = RawImage::new(self);
29 Ok(decoded)
30 }
31
32 #[inline]
33 pub fn process_8bit(self, buf: &[u8]) -> Result<ProcessedImage<u8>> {
34 self.process(buf)
35 }
36
37 #[inline]
38 pub fn process_16bit(self, buf: &[u8]) -> Result<ProcessedImage<u16>> {
39 self.process(buf)
40 }
41
42 fn process<T>(self, buf: &[u8]) -> Result<ProcessedImage<T>> {
43 let bps = mem::size_of::<T>() * 8;
44 debug_assert!(bps == 8 || bps == 16);
45 unsafe { (*self.inner).params.output_bps = bps as i32 };
46
47 self.open(buf)?;
48 Error::check(unsafe { sys::libraw_dcraw_process(self.inner) })?;
49
50 let mut result = 0i32;
51 let processed = unsafe { sys::libraw_dcraw_make_mem_image(self.inner, &mut result) };
52 Error::check(result)?;
53
54 let processed = unsafe { ProcessedImage::from_raw(processed) };
55 Ok(processed)
56 }
57}
58
59impl Drop for Processor {
60 fn drop(&mut self) {
61 unsafe { sys::libraw_close(self.inner) }
62 }
63}
64
65impl Default for Processor {
66 fn default() -> Self {
67 Self::new()
68 }
69}