use std::convert::AsRef;
use std::io;
use crate::ifd::values::TiffTypeValues;
use crate::write::EndianFile;
pub trait TiffType {
fn id() -> u16;
fn size() -> u32;
fn write_to(self, file: &mut EndianFile) -> io::Result<()>;
}
#[derive(Debug, PartialEq)]
pub struct BYTE(pub u8);
impl BYTE {
pub fn values<T: AsRef<[u8]>>(values: T) -> TiffTypeValues<BYTE> {
TiffTypeValues::new(values.as_ref().iter().map(|&value| BYTE(value)).collect())
}
pub fn single(value: u8) -> TiffTypeValues<BYTE> {
TiffTypeValues::new(vec![BYTE(value)])
}
}
impl TiffType for BYTE {
fn id() -> u16 {
1
}
fn size() -> u32 {
1
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_u8(self.0)
}
}
#[macro_export]
macro_rules! BYTE {
($($values: expr),+) => {
$crate::ifd::values::TiffTypeValues::new(vec![$($crate::ifd::types::BYTE($values)),+])
};
}
#[derive(Debug, PartialEq)]
pub struct ASCII(u8);
impl ASCII {
pub fn from_str(s: &str) -> TiffTypeValues<ASCII> {
let mut values = Vec::with_capacity(s.chars().count());
for c in s.chars() {
if c >= (128 as char) {
panic!("String contains non-ASCII character {}.", c)
}
values.push(c as u8);
}
Self::values(values)
}
pub fn values<T: AsRef<[u8]>>(values: T) -> TiffTypeValues<ASCII> {
let values = values.as_ref();
if values.len() == 0 {
panic!("Cannot create an empty instance of TiffTypeValues.")
}
let add_nul = *values.last().unwrap() != 0;
let mut values: Vec<_> = values.iter().map(|&value| ASCII::new(value)).collect();
if add_nul {
values.push(ASCII::new(0))
}
TiffTypeValues::new(values)
}
pub fn new(value: u8) -> ASCII {
if value >= 128 {
panic!("Tried to create an ASCII encoded by the value {}.\n An ASCII value can only range from 0 to 127.", value);
}
ASCII(value)
}
}
impl TiffType for ASCII {
fn id() -> u16 {
2
}
fn size() -> u32 {
1
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_u8(self.0)
}
}
#[macro_export]
macro_rules! ASCII {
($string: expr) => {
$crate::ifd::types::ASCII::from_str($string)
};
}
#[derive(Debug, PartialEq)]
pub struct SHORT(pub u16);
impl SHORT {
pub fn values<T: AsRef<[u16]>>(values: T) -> TiffTypeValues<SHORT> {
TiffTypeValues::new(values.as_ref().iter().map(|&value| SHORT(value)).collect())
}
pub fn single(value: u16) -> TiffTypeValues<SHORT> {
TiffTypeValues::new(vec![SHORT(value)])
}
}
impl TiffType for SHORT {
fn id() -> u16 {
3
}
fn size() -> u32 {
2
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_u16(self.0)
}
}
#[macro_export]
macro_rules! SHORT {
($($values: expr),+) => {
$crate::ifd::values::TiffTypeValues::new(vec![$($crate::ifd::types::SHORT($values)),+])
};
}
#[derive(Debug, PartialEq)]
pub struct LONG(pub u32);
impl LONG {
pub fn values<T: AsRef<[u32]>>(values: T) -> TiffTypeValues<LONG> {
TiffTypeValues::new(values.as_ref().iter().map(|&value| LONG(value)).collect())
}
pub fn single(value: u32) -> TiffTypeValues<LONG> {
TiffTypeValues::new(vec![LONG(value)])
}
}
impl TiffType for LONG {
fn id() -> u16 {
4
}
fn size() -> u32 {
4
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_u32(self.0)
}
}
#[macro_export]
macro_rules! LONG {
($($values: expr),+) => {
$crate::ifd::values::TiffTypeValues::new(vec![$($crate::ifd::types::LONG($values)),+])
};
}
#[derive(Debug, PartialEq)]
pub struct RATIONAL {
pub numerator: u32,
pub denominator: u32,
}
impl RATIONAL {
pub fn values<T: AsRef<[(u32, u32)]>>(values: T) -> TiffTypeValues<RATIONAL> {
TiffTypeValues::new(
values
.as_ref()
.iter()
.map(|&(numerator, denominator)| RATIONAL {
numerator,
denominator,
})
.collect(),
)
}
pub fn single(numerator: u32, denominator: u32) -> TiffTypeValues<RATIONAL> {
TiffTypeValues::new(vec![RATIONAL {
numerator,
denominator,
}])
}
}
impl TiffType for RATIONAL {
fn id() -> u16 {
5
}
fn size() -> u32 {
8
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_u32(self.numerator)?;
file.write_u32(self.denominator)?;
Ok(())
}
}
#[macro_export]
macro_rules! RATIONAL {
($(($num: expr, $den: expr)),+) => {
$crate::ifd::values::TiffTypeValues::new(vec![$($crate::ifd::types::RATIONAL{numerator: $num, denominator: $den}),+])
};
}
#[derive(Debug, PartialEq)]
pub struct SBYTE(pub i8);
impl SBYTE {
pub fn values<T: AsRef<[i8]>>(values: T) -> TiffTypeValues<SBYTE> {
TiffTypeValues::new(values.as_ref().iter().map(|&value| SBYTE(value)).collect())
}
pub fn single(value: i8) -> TiffTypeValues<SBYTE> {
TiffTypeValues::new(vec![SBYTE(value)])
}
}
impl TiffType for SBYTE {
fn id() -> u16 {
6
}
fn size() -> u32 {
1
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_i8(self.0)
}
}
#[macro_export]
macro_rules! SBYTE {
($($values: expr),+) => {
$crate::ifd::values::TiffTypeValues::new(vec![$($crate::ifd::types::SBYTE($values)),+])
};
}
#[derive(Debug, PartialEq)]
pub struct UNDEFINED(pub u8);
impl UNDEFINED {
pub fn values<T: AsRef<[u8]>>(values: T) -> TiffTypeValues<UNDEFINED> {
TiffTypeValues::new(
values
.as_ref()
.iter()
.map(|&value| UNDEFINED(value))
.collect(),
)
}
pub fn single(value: u8) -> TiffTypeValues<UNDEFINED> {
TiffTypeValues::new(vec![UNDEFINED(value)])
}
}
impl TiffType for UNDEFINED {
fn id() -> u16 {
7
}
fn size() -> u32 {
1
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_u8(self.0)
}
}
#[macro_export]
macro_rules! UNDEFINED {
($($values: expr),+) => {
$crate::ifd::values::TiffTypeValues::new(vec![$($crate::ifd::types::UNDEFINED($values)),+])
};
}
#[derive(Debug, PartialEq)]
pub struct SSHORT(pub i16);
impl SSHORT {
pub fn values<T: AsRef<[i16]>>(values: T) -> TiffTypeValues<SSHORT> {
TiffTypeValues::new(values.as_ref().iter().map(|&value| SSHORT(value)).collect())
}
pub fn single(value: i16) -> TiffTypeValues<SSHORT> {
TiffTypeValues::new(vec![SSHORT(value)])
}
}
impl TiffType for SSHORT {
fn id() -> u16 {
8
}
fn size() -> u32 {
2
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_i16(self.0)
}
}
#[macro_export]
macro_rules! SSHORT {
($($values: expr),+) => {
$crate::ifd::values::TiffTypeValues::new(vec![$($crate::ifd::types::SSHORT($values)),+])
};
}
#[derive(Debug, PartialEq)]
pub struct SLONG(pub i32);
impl SLONG {
pub fn values<T: AsRef<[i32]>>(values: T) -> TiffTypeValues<SLONG> {
TiffTypeValues::new(values.as_ref().iter().map(|&value| SLONG(value)).collect())
}
pub fn single(value: i32) -> TiffTypeValues<SLONG> {
TiffTypeValues::new(vec![SLONG(value)])
}
}
impl TiffType for SLONG {
fn id() -> u16 {
9
}
fn size() -> u32 {
4
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_i32(self.0)
}
}
#[macro_export]
macro_rules! SLONG {
($($values: expr),+) => {
$crate::ifd::values::TiffTypeValues::new(vec![$($crate::ifd::types::SLONG($values)),+])
};
}
#[derive(Debug, PartialEq)]
pub struct SRATIONAL {
pub numerator: i32,
pub denominator: i32,
}
impl SRATIONAL {
pub fn values<T: AsRef<[(i32, i32)]>>(values: T) -> TiffTypeValues<SRATIONAL> {
TiffTypeValues::new(
values
.as_ref()
.iter()
.map(|&(numerator, denominator)| SRATIONAL {
numerator,
denominator,
})
.collect(),
)
}
pub fn single(numerator: i32, denominator: i32) -> TiffTypeValues<SRATIONAL> {
TiffTypeValues::new(vec![SRATIONAL {
numerator,
denominator,
}])
}
}
impl TiffType for SRATIONAL {
fn id() -> u16 {
10
}
fn size() -> u32 {
8
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_i32(self.numerator)?;
file.write_i32(self.denominator)?;
Ok(())
}
}
#[macro_export]
macro_rules! SRATIONAL {
($(($num: expr, $den: expr)),+) => {
$crate::ifd::values::TiffTypeValues::new(vec![$($crate::ifd::types::SRATIONAL{numerator: $num, denominator: $den}),+])
};
}
#[derive(Debug, PartialEq)]
pub struct FLOAT(pub f32);
impl FLOAT {
pub fn values<T: AsRef<[f32]>>(values: T) -> TiffTypeValues<FLOAT> {
TiffTypeValues::new(values.as_ref().iter().map(|&value| FLOAT(value)).collect())
}
pub fn single(value: f32) -> TiffTypeValues<FLOAT> {
TiffTypeValues::new(vec![FLOAT(value)])
}
}
impl TiffType for FLOAT {
fn id() -> u16 {
11
}
fn size() -> u32 {
4
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_f32(self.0)
}
}
#[macro_export]
macro_rules! FLOAT {
($($values: expr),+) => {
$crate::ifd::values::TiffTypeValues::new(vec![$($crate::ifd::types::FLOAT($values)),+])
};
}
#[derive(Debug, PartialEq)]
pub struct DOUBLE(pub f64);
impl DOUBLE {
pub fn values<T: AsRef<[f64]>>(values: T) -> TiffTypeValues<DOUBLE> {
TiffTypeValues::new(values.as_ref().iter().map(|&value| DOUBLE(value)).collect())
}
pub fn single(value: f64) -> TiffTypeValues<DOUBLE> {
TiffTypeValues::new(vec![DOUBLE(value)])
}
}
impl TiffType for DOUBLE {
fn id() -> u16 {
12
}
fn size() -> u32 {
8
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_f64(self.0)
}
}
#[macro_export]
macro_rules! DOUBLE {
($($values: expr),+) => {
$crate::ifd::values::TiffTypeValues::new(vec![$($crate::ifd::types::DOUBLE($values)),+])
};
}
#[derive(Debug, PartialEq)]
pub struct IFD(pub(crate) u32);
impl TiffType for IFD {
fn id() -> u16 {
13
}
fn size() -> u32 {
4
}
fn write_to(self, file: &mut EndianFile) -> io::Result<()> {
file.write_u32(self.0)
}
}