use super::lowlevel::*;
use super::types::*;
use crate::ifdformat::NumArray;
use std::error::Error;
use std::fmt::Display;
use std::{fmt, io};
#[deprecated(note = "Use IfdFormat::new(n)")]
#[doc(hidden)]
#[must_use]
pub fn ifdformat_new(n: u16) -> IfdFormat {
IfdFormat::new(n)
}
impl IfdFormat {
#[must_use]
pub const fn new(code: u16) -> Self {
match code {
1 => Self::U8,
2 => Self::Ascii,
3 => Self::U16,
4 => Self::U32,
5 => Self::URational,
6 => Self::I8,
7 => Self::Undefined,
8 => Self::I16,
9 => Self::I32,
10 => Self::IRational,
11 => Self::F32,
12 => Self::F64,
_ => Self::Unknown,
}
}
}
impl IfdEntry {
#[deprecated]
#[must_use]
pub fn data_as_offset(&self) -> usize {
self.try_data_as_offset().unwrap()
}
#[inline]
#[must_use]
pub fn try_data_as_offset(&self) -> Option<usize> {
read_u32(self.le, &self.ifd_data).map(|l| l as usize)
}
#[must_use]
pub const fn size(&self) -> u8 {
match self.format {
IfdFormat::U8 => 1,
IfdFormat::Ascii => 1,
IfdFormat::U16 => 2,
IfdFormat::U32 => 4,
IfdFormat::URational => 8,
IfdFormat::I8 => 1,
IfdFormat::Undefined => 1,
IfdFormat::I16 => 2,
IfdFormat::I32 => 4,
IfdFormat::IRational => 8,
IfdFormat::F32 => 4,
IfdFormat::F64 => 8,
IfdFormat::Unknown => 1,
}
}
#[inline]
#[must_use]
pub fn length(&self) -> usize {
(self.size() as usize) * (self.count as usize)
}
#[inline]
#[must_use]
pub fn in_ifd(&self) -> bool {
self.length() <= 4
}
pub fn copy_data(&mut self, contents: &[u8]) -> bool {
if self.in_ifd() {
self.data = self.ifd_data.clone();
return true;
}
let offset = match self.try_data_as_offset() {
Some(o) => o,
_ => return false,
};
if let Some(ext_data) = contents.get(offset..(offset + self.length())) {
self.ext_data.clear();
self.ext_data.extend(ext_data);
self.data = self.ext_data.clone();
return true;
}
false
}
}
impl Error for ExifError {
}
impl Display for ExifError {
#[cold]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ExifError::IoError(ref e) => e.fmt(f),
ExifError::FileTypeUnknown => f.write_str("File type unknown"),
ExifError::JpegWithoutExif(ref s) => write!(f, "JPEG without EXIF section: {s}"),
ExifError::TiffTruncated => f.write_str("TIFF truncated at start"),
ExifError::TiffBadPreamble(ref s) => write!(f, "TIFF with bad preamble: {s}"),
ExifError::IfdTruncated => f.write_str("TIFF IFD truncated"),
ExifError::ExifIfdTruncated(ref s) => write!(f, "TIFF Exif IFD truncated: {s}"),
ExifError::ExifIfdEntryNotFound => f.write_str("TIFF Exif IFD not found"),
ExifError::UnsupportedNamespace => f.write_str("Only standar namespace can be serialized"),
ExifError::MissingExifOffset => f.write_str("Expected to have seen ExifOffset tagin IFD0"),
}
}
}
impl From<io::Error> for ExifError {
#[cold]
fn from(err: io::Error) -> Self {
Self::IoError(err)
}
}
impl fmt::Display for TagValue {
#[cold]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TagValue::Ascii(s) => f.write_str(s),
TagValue::U16(a) => write!(f, "{}", NumArray::new(a)),
TagValue::I16(a) => write!(f, "{}", NumArray::new(a)),
TagValue::U8(a) => write!(f, "{}", NumArray::new(a)),
TagValue::I8(a) => write!(f, "{}", NumArray::new(a)),
TagValue::U32(a) => write!(f, "{}", NumArray::new(a)),
TagValue::I32(a) => write!(f, "{}", NumArray::new(a)),
TagValue::F32(a) => write!(f, "{}", NumArray::new(a)),
TagValue::F64(a) => write!(f, "{}", NumArray::new(a)),
TagValue::URational(a) => write!(f, "{}", NumArray::new(a)),
TagValue::IRational(a) => write!(f, "{}", NumArray::new(a)),
TagValue::Undefined(a, _) => write!(f, "{}", NumArray::new(a)),
TagValue::Unknown(a, _) => write!(f, "<unknown {}>", NumArray::new(a)),
TagValue::Invalid(a, ..) => write!(f, "<invalid {}>", NumArray::new(a)),
}
}
}