use std::borrow::Cow;
use std::ffi::CStr;
use ffi::or_ifd_dir_type;
use libopenraw_sys as ffi;
#[repr(u32)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum DirType {
Other = or_ifd_dir_type::OR_IFD_OTHER as u32,
Main = or_ifd_dir_type::OR_IFD_MAIN as u32,
Exif = or_ifd_dir_type::OR_IFD_EXIF as u32,
MNote = or_ifd_dir_type::OR_IFD_MNOTE as u32,
Raw = or_ifd_dir_type::OR_IFD_RAW as u32,
SubIfd = or_ifd_dir_type::OR_IFD_SUBIFD as u32,
Invalid = or_ifd_dir_type::OR_IFD_INVALID as u32,
}
impl From<DirType> for ffi::or_ifd_dir_type {
fn from(t: DirType) -> Self {
match t {
DirType::Other => or_ifd_dir_type::OR_IFD_OTHER,
DirType::Main => or_ifd_dir_type::OR_IFD_MAIN,
DirType::Exif => or_ifd_dir_type::OR_IFD_EXIF,
DirType::MNote => or_ifd_dir_type::OR_IFD_MNOTE,
DirType::Raw => or_ifd_dir_type::OR_IFD_RAW,
DirType::SubIfd => or_ifd_dir_type::OR_IFD_SUBIFD,
DirType::Invalid => or_ifd_dir_type::OR_IFD_INVALID,
}
}
}
impl From<ffi::or_ifd_dir_type> for DirType {
fn from(t: ffi::or_ifd_dir_type) -> Self {
match t {
or_ifd_dir_type::OR_IFD_OTHER => Self::Other,
or_ifd_dir_type::OR_IFD_MAIN => Self::Main,
or_ifd_dir_type::OR_IFD_EXIF => Self::Exif,
or_ifd_dir_type::OR_IFD_MNOTE => Self::MNote,
or_ifd_dir_type::OR_IFD_RAW => Self::Raw,
or_ifd_dir_type::OR_IFD_SUBIFD => Self::SubIfd,
or_ifd_dir_type::OR_IFD_INVALID => Self::Invalid,
}
}
}
pub struct Ifd(ffi::ORIfdDirRef);
impl Ifd {
pub(crate) fn new(ifd: ffi::ORIfdDirRef) -> Self {
Self(ifd)
}
pub fn count_tags(&self) -> i32 {
unsafe { ffi::or_ifd_count_tags(self.0) }
}
pub fn get_makernote_id(&self) -> Cow<str> {
let id = unsafe { CStr::from_ptr(ffi::or_ifd_get_makernote_id(self.0)) };
id.to_string_lossy()
}
pub fn get_tag_name(&self, tag: u32) -> Cow<str> {
let name = unsafe { CStr::from_ptr(ffi::or_ifd_get_tag_name(self.0, tag)) };
name.to_string_lossy()
}
}
impl Drop for Ifd {
fn drop(&mut self) {
unsafe { ffi::or_ifd_release(self.0) };
}
}