pub mod error;
pub mod ifd;
pub mod rawfile;
pub mod thumbnail;
pub mod utils;
use std::ffi::CStr;
use std::ffi::OsString;
use libopenraw_sys as ffi;
pub type Result<T> = std::result::Result<T, error::Error>;
pub use error::Error;
pub use ifd::Ifd;
pub use rawfile::{RawFile, RawFileType};
pub use thumbnail::Thumbnail;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum DataType {
None,
Pixmap8Rgb,
Pixmap16Rgb,
Jpeg,
Tiff,
Png,
Raw,
CompressedRaw,
Unknown,
}
impl From<ffi::or_data_type> for DataType {
fn from(t: ffi::or_data_type) -> Self {
use ffi::or_data_type::*;
match t {
OR_DATA_TYPE_NONE => Self::None,
OR_DATA_TYPE_PIXMAP_8RGB => Self::Pixmap8Rgb,
OR_DATA_TYPE_PIXMAP_16RGB => Self::Pixmap16Rgb,
OR_DATA_TYPE_JPEG => Self::Jpeg,
OR_DATA_TYPE_TIFF => Self::Tiff,
OR_DATA_TYPE_PNG => Self::Png,
OR_DATA_TYPE_RAW => Self::Raw,
OR_DATA_TYPE_COMPRESSED_RAW => Self::CompressedRaw,
OR_DATA_TYPE_UNKNOWN => Self::Unknown,
}
}
}
impl From<DataType> for ffi::or_data_type {
fn from(t: DataType) -> Self {
use ffi::or_data_type::*;
match t {
DataType::None => OR_DATA_TYPE_NONE,
DataType::Pixmap8Rgb => OR_DATA_TYPE_PIXMAP_8RGB,
DataType::Pixmap16Rgb => OR_DATA_TYPE_PIXMAP_16RGB,
DataType::Jpeg => OR_DATA_TYPE_JPEG,
DataType::Tiff => OR_DATA_TYPE_TIFF,
DataType::Png => OR_DATA_TYPE_PNG,
DataType::Raw => OR_DATA_TYPE_RAW,
DataType::CompressedRaw => OR_DATA_TYPE_COMPRESSED_RAW,
DataType::Unknown => OR_DATA_TYPE_UNKNOWN,
}
}
}
pub fn extract_thumbnail<P: AsRef<std::path::Path>>(
filename: P,
preferred_size: u32,
thumbnail: Option<Thumbnail>,
) -> Result<Thumbnail> {
let mut thumbnail = thumbnail.unwrap_or_else(Thumbnail::new);
let cstr = crate::utils::path_to_filename(filename);
let err =
unsafe { ffi::or_get_extract_thumbnail(cstr.as_ptr(), preferred_size, &mut thumbnail.0) };
if err == ffi::or_error::OR_ERROR_NONE {
Ok(thumbnail)
} else {
Err(err.into())
}
}
lazy_static::lazy_static! {
static ref EXTENSIONS: Vec<OsString> = {
let mut v = vec![];
let extensions = unsafe { ffi::or_get_file_extensions() };
let mut current = extensions;
if !current.is_null() {
while unsafe { !(*current).is_null() } {
let s = unsafe { CStr::from_ptr(*current) };
v.push(OsString::from(&*s.to_string_lossy()));
current = unsafe { current.offset(1) };
}
}
v
};
}
pub fn file_extensions() -> &'static [OsString] {
&EXTENSIONS
}
#[cfg(test)]
mod test {
use super::file_extensions;
#[test]
fn test_extensions() {
let extensions = file_extensions();
assert_eq!(extensions.len(), 17);
}
}