Factor tags into own module

Tag representations are not decoder- or encoder-specific, so should live
in their own module accessible to both for reuse. The decoder::ifd
module remains since this module is mainly dedicated to decoding the
IFD.
This commit is contained in:
Andrew Champion committed 2019-12-21 15:57:24 +00:00
1 parent f9cace84da
commit f92be13f6c
9 files changed
+242 -238

No files matched your search

+1 -138
View File
@@ -5,148 +5,11 @@ use std::io::{self, Read, Seek};
use std::mem;
use super::stream::{ByteOrder, EndianReader, SmartReader};
use tags::{Tag, Type};
use {TiffError, TiffFormatError, TiffResult, TiffUnsupportedError};
use self::Value::{Ascii, List, Rational, Unsigned, Signed, SRational};
pub(crate) mod seals {
pub trait TagConversion<T>: Sized {
fn __from_inner_type(T) -> Result<Self, T>;
fn __to_inner_type(&self) -> T;
}
}
pub trait U16Tag: Sized {
fn from_u16(val: u16) -> Option<Self>;
fn to_u16(&self) -> u16;
}
impl<T: seals::TagConversion<u16>> U16Tag for T {
fn from_u16(val: u16) -> Option<Self> {
Self::__from_inner_type(val).ok()
}
fn to_u16(&self) -> u16 {
Self::__to_inner_type(self)
}
}
macro_rules! tags {
{
// Permit arbitrary meta items, which include documentation.
$( #[$enum_attr:meta] )*
$vis:vis enum $name:ident($ty:ty) $(unknown($unknown_doc:literal))* {
// Each of the `Name = Val,` permitting documentation.
$($(#[$ident_attr:meta])* $tag:ident = $val:expr,)*
}
} => {
$( #[$enum_attr] )*
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub enum $name {
$($(#[$ident_attr])* $tag,)*
// FIXME: switch to non_exhaustive once stabilized and compiler requirement new enough
#[doc(hidden)]
__NonExhaustive,
$(
#[doc = $unknown_doc]
Unknown($ty),
)*
}
impl ::decoder::ifd::seals::TagConversion<$ty> for $name {
#[inline(always)]
fn __from_inner_type(n: $ty) -> Result<Self, $ty> {
match n {
$( $val => Ok($name::$tag), )*
n => Err(n),
}
}
#[inline(always)]
fn __to_inner_type(&self) -> $ty {
match *self {
$( $name::$tag => $val, )*
$( $name::Unknown(n) => { $unknown_doc; n }, )*
$name::__NonExhaustive => unreachable!(),
}
}
}
}
}
// Note: These tags appear in the order they are mentioned in the TIFF reference
tags! {
/// TIFF tags
pub enum Tag(u16) unknown("A private or extension tag") {
// Baseline tags:
Artist = 315,
// grayscale images PhotometricInterpretation 1 or 3
BitsPerSample = 258,
CellLength = 265, // TODO add support
CellWidth = 264, // TODO add support
// palette-color images (PhotometricInterpretation 3)
ColorMap = 320, // TODO add support
Compression = 259, // TODO add support for 2 and 32773
Copyright = 33_432,
DateTime = 306,
ExtraSamples = 338, // TODO add support
FillOrder = 266, // TODO add support
FreeByteCounts = 289, // TODO add support
FreeOffsets = 288, // TODO add support
GrayResponseCurve = 291, // TODO add support
GrayResponseUnit = 290, // TODO add support
HostComputer = 316,
ImageDescription = 270,
ImageLength = 257,
ImageWidth = 256,
Make = 271,
MaxSampleValue = 281, // TODO add support
MinSampleValue = 280, // TODO add support
Model = 272,
NewSubfileType = 254, // TODO add support
Orientation = 274, // TODO add support
PhotometricInterpretation = 262,
PlanarConfiguration = 284,
ResolutionUnit = 296, // TODO add support
RowsPerStrip = 278,
SamplesPerPixel = 277,
Software = 305,
StripByteCounts = 279,
StripOffsets = 273,
SubfileType = 255, // TODO add support
Threshholding = 263, // TODO add support
XResolution = 282,
YResolution = 283,
// Advanced tags
Predictor = 317,
}
}
impl Tag {
pub fn from_u16_exhaustive(val: u16) -> Self {
Self::from_u16(val).unwrap_or_else(|| Tag::Unknown(val))
}
}
tags! {
/// The type of an IFD entry (a 2 byte field).
pub enum Type(u16) {
BYTE = 1,
ASCII = 2,
SHORT = 3,
LONG = 4,
RATIONAL = 5,
SBYTE = 6,
SSHORT = 8,
SLONG = 9,
SRATIONAL = 10,
/// BigTIFF 64-bit unsigned integer
LONG8 = 16,
}
}
#[allow(unused_qualifications)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]