use libopenraw_sys as ffi;
use super::Error;
use super::Result;
use crate::ifd;
use crate::ifd::Ifd;
use crate::thumbnail::Thumbnail;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum RawFileType {
Unknown,
Cr2,
Crw,
Nef,
Mrw,
Arw,
Dng,
Orf,
Pef,
Erf,
Tiff,
Nrw,
Rw2,
Raf,
Cr3,
Gpr,
Sr2,
}
impl From<ffi::or_rawfile_type> for RawFileType {
fn from(t: ffi::or_rawfile_type) -> RawFileType {
use ffi::or_rawfile_type::*;
match t {
OR_RAWFILE_TYPE_UNKNOWN => Self::Unknown,
OR_RAWFILE_TYPE_CR2 => Self::Cr2,
OR_RAWFILE_TYPE_CRW => Self::Crw,
OR_RAWFILE_TYPE_NEF => Self::Nef,
OR_RAWFILE_TYPE_MRW => Self::Mrw,
OR_RAWFILE_TYPE_ARW => Self::Arw,
OR_RAWFILE_TYPE_DNG => Self::Dng,
OR_RAWFILE_TYPE_ORF => Self::Orf,
OR_RAWFILE_TYPE_PEF => Self::Pef,
OR_RAWFILE_TYPE_ERF => Self::Erf,
OR_RAWFILE_TYPE_TIFF => Self::Tiff,
OR_RAWFILE_TYPE_NRW => Self::Nrw,
OR_RAWFILE_TYPE_RW2 => Self::Rw2,
OR_RAWFILE_TYPE_RAF => Self::Raf,
OR_RAWFILE_TYPE_CR3 => Self::Cr3,
OR_RAWFILE_TYPE_GPR => Self::Gpr,
OR_RAWFILE_TYPE_SR2 => Self::Sr2,
}
}
}
impl From<RawFileType> for ffi::or_rawfile_type {
fn from(t: RawFileType) -> Self {
use ffi::or_rawfile_type::*;
match t {
RawFileType::Unknown => OR_RAWFILE_TYPE_UNKNOWN,
RawFileType::Cr2 => OR_RAWFILE_TYPE_CR2,
RawFileType::Crw => OR_RAWFILE_TYPE_CRW,
RawFileType::Nef => OR_RAWFILE_TYPE_NEF,
RawFileType::Mrw => OR_RAWFILE_TYPE_MRW,
RawFileType::Arw => OR_RAWFILE_TYPE_ARW,
RawFileType::Dng => OR_RAWFILE_TYPE_DNG,
RawFileType::Orf => OR_RAWFILE_TYPE_ORF,
RawFileType::Pef => OR_RAWFILE_TYPE_PEF,
RawFileType::Erf => OR_RAWFILE_TYPE_ERF,
RawFileType::Tiff => OR_RAWFILE_TYPE_TIFF,
RawFileType::Nrw => OR_RAWFILE_TYPE_NRW,
RawFileType::Rw2 => OR_RAWFILE_TYPE_RW2,
RawFileType::Raf => OR_RAWFILE_TYPE_RAF,
RawFileType::Cr3 => OR_RAWFILE_TYPE_CR3,
RawFileType::Gpr => OR_RAWFILE_TYPE_GPR,
RawFileType::Sr2 => OR_RAWFILE_TYPE_SR2,
}
}
}
pub struct RawFile(ffi::ORRawFileRef);
impl RawFile {
pub fn from_file<P: AsRef<std::path::Path>>(filename: P, type_: RawFileType) -> Result<Self> {
let cstr = crate::utils::path_to_filename(filename);
let rf = unsafe { ffi::or_rawfile_new(cstr.as_ptr(), type_.into()) };
if rf.is_null() {
Err(Error::CantOpen)
} else {
Ok(Self(rf))
}
}
pub fn from_memory(buffer: &[u8], type_: RawFileType) -> Result<Self> {
let rf = unsafe {
ffi::or_rawfile_new_from_memory(buffer.as_ptr(), buffer.len() as u32, type_.into())
};
if rf.is_null() {
Err(Error::CantOpen)
} else {
Ok(Self(rf))
}
}
pub fn get_orientation(&self) -> i32 {
unsafe { ffi::or_rawfile_get_orientation(self.0) }
}
pub fn get_thumbnail(&self, preferred_size: u32) -> Result<Thumbnail> {
let thumbnail = Thumbnail::new();
let error = unsafe { ffi::or_rawfile_get_thumbnail(self.0, preferred_size, thumbnail.0) };
if error != ffi::or_error::OR_ERROR_NONE {
Err(error.into())
} else {
Ok(thumbnail)
}
}
pub fn get_ifd(&self, ifd_type: ifd::DirType) -> ifd::Ifd {
Ifd::new(unsafe { ffi::or_rawfile_get_ifd(self.0, ifd_type.into()) })
}
}
impl Drop for RawFile {
fn drop(&mut self) {
unsafe {
ffi::or_rawfile_release(self.0);
}
}
}