Merge pull request #323 from image-rs/tiff-value-for-tags
Utils for working with tags
This commit is contained in:
4 files changed
+139
-3
No files matched your search
+13
@@ -1,3 +1,16 @@
|
||||
# Version 0.11.1 (Unreleased)
|
||||
|
||||
Fixes:
|
||||
- The enumeration types in `tags` are now all marked with a representation of
|
||||
their underlying TIFF type (e.g. `repr(u16)`) and variants are explicitly
|
||||
assigned their corresponding values. That is you may _read_ the raw
|
||||
discriminant and interpret that as the value—except for `Unknown` variants.
|
||||
|
||||
Additions:
|
||||
- Types in `tags` now generally implement `TiffValue` and can be handed to the
|
||||
`DirectoryEncoder::write_tag` method. Unlike primitive types they do _not_
|
||||
always implement the trait for slices of themselves.
|
||||
|
||||
# Version 0.11.0
|
||||
|
||||
- `Directory` now implements `FromIterator<(Tag, Value)>`.
|
||||
|
||||
+1
-1
@@ -582,7 +582,7 @@ impl<'a, W: 'a + Write + Seek, T: ColorType, K: TiffKind> ImageEncoder<'a, W, T,
|
||||
)?;
|
||||
encoder.write_tag(Tag::XResolution, Rational { n: 1, d: 1 })?;
|
||||
encoder.write_tag(Tag::YResolution, Rational { n: 1, d: 1 })?;
|
||||
encoder.write_tag(Tag::ResolutionUnit, ResolutionUnit::None.to_u16())?;
|
||||
encoder.write_tag(Tag::ResolutionUnit, ResolutionUnit::None)?;
|
||||
|
||||
Ok(ImageEncoder {
|
||||
encoder,
|
||||
|
||||
+123
-1
@@ -1,6 +1,6 @@
|
||||
use std::{borrow::Cow, io::Write, slice::from_ref};
|
||||
|
||||
use crate::{bytecast, tags::Type, TiffError, TiffFormatError, TiffResult};
|
||||
use crate::{bytecast, tags, tags::Type, TiffError, TiffFormatError, TiffResult};
|
||||
|
||||
use super::writer::TiffWriter;
|
||||
|
||||
@@ -458,6 +458,128 @@ impl TiffValue for str {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: held up on reading the discriminant for all but the unknown variant.
|
||||
//
|
||||
// It needs to have `repr(u16)` to have a defined layout and then we may read the tag from its
|
||||
// value representation by casting a u16 pointer to a pointer to the enum type.
|
||||
// unsafe { *<*const _>::from(self).cast::<u16>() }
|
||||
// But that is quite unsafe and needs careful review to maintain the safety requirements. Maybe we
|
||||
// could get `bytemuck` to add a trait for this (it has `TransparentWrapper`) with a derive for
|
||||
// enum types that have an explicit repr.
|
||||
//
|
||||
// This would allow returning borrowed data in more cases. For all types without an unknown, in all
|
||||
// cases including as slices, and for all types with and unknown variant when we have a single
|
||||
// value (either returning a borrowed discriminant or a borrowed value within `Unknown`).
|
||||
impl TiffValue for tags::CompressionMethod {
|
||||
const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
|
||||
const FIELD_TYPE: Type = Type::SHORT;
|
||||
|
||||
fn count(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn data(&self) -> Cow<'_, [u8]> {
|
||||
let bytes = self.to_u16().to_ne_bytes();
|
||||
Cow::Owned(bytes.to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
impl TiffValue for tags::PhotometricInterpretation {
|
||||
const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
|
||||
const FIELD_TYPE: Type = Type::SHORT;
|
||||
|
||||
fn count(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn data(&self) -> Cow<'_, [u8]> {
|
||||
self.to_u16().to_ne_bytes().to_vec().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TiffValue for tags::PlanarConfiguration {
|
||||
const BYTE_LEN: u8 = 2;
|
||||
const FIELD_TYPE: Type = Type::SHORT;
|
||||
|
||||
fn count(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn data(&self) -> Cow<'_, [u8]> {
|
||||
self.to_u16().to_ne_bytes().to_vec().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TiffValue for tags::Predictor {
|
||||
const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
|
||||
const FIELD_TYPE: Type = Type::SHORT;
|
||||
|
||||
fn count(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn data(&self) -> Cow<'_, [u8]> {
|
||||
self.to_u16().to_ne_bytes().to_vec().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TiffValue for tags::ResolutionUnit {
|
||||
const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
|
||||
const FIELD_TYPE: Type = Type::SHORT;
|
||||
|
||||
fn count(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn data(&self) -> Cow<'_, [u8]> {
|
||||
self.to_u16().to_ne_bytes().to_vec().into()
|
||||
}
|
||||
}
|
||||
|
||||
/// This is implemented for slices as the `SampleFormat` tag takes a count of `N`.
|
||||
///
|
||||
/// Use `core::slice::from_ref` if you really need to write a single element.
|
||||
///
|
||||
/// See: <https://web.archive.org/web/20191120220815/https://www.awaresystems.be/imaging/tiff/tifftags/sampleformat.html>
|
||||
impl TiffValue for [tags::SampleFormat] {
|
||||
const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
|
||||
const FIELD_TYPE: Type = Type::SHORT;
|
||||
|
||||
fn count(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
|
||||
fn data(&self) -> Cow<'_, [u8]> {
|
||||
let mut buf: Vec<u8> = Vec::with_capacity(self.len() * 2);
|
||||
for x in self {
|
||||
buf.extend_from_slice(&x.to_u16().to_ne_bytes());
|
||||
}
|
||||
Cow::Owned(buf)
|
||||
}
|
||||
}
|
||||
|
||||
/// This is implemented for slices as the `ExtraSamples` tag takes a count of `N`.
|
||||
///
|
||||
/// Use `core::slice::from_ref` if you really need to write a single element.
|
||||
///
|
||||
/// See: <https://web.archive.org/web/20191120220815/https://www.awaresystems.be/imaging/tiff/tifftags/extrasamples.html>
|
||||
impl TiffValue for [tags::ExtraSamples] {
|
||||
const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
|
||||
const FIELD_TYPE: Type = Type::SHORT;
|
||||
|
||||
fn count(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
|
||||
fn data(&self) -> Cow<'_, [u8]> {
|
||||
let mut buf: Vec<u8> = Vec::with_capacity(self.len() * 2);
|
||||
for x in self {
|
||||
buf.extend_from_slice(&x.to_u16().to_ne_bytes());
|
||||
}
|
||||
Cow::Owned(buf)
|
||||
}
|
||||
}
|
||||
|
||||
// If you pass `&Vec<_>` then you'd get at first sight the complaint:
|
||||
//
|
||||
// `Vec<T>` does not implement `TiffValue`
|
||||
|
||||
+2
-1
@@ -10,8 +10,9 @@ macro_rules! tags {
|
||||
$( #[$enum_attr] )*
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
||||
#[non_exhaustive]
|
||||
#[repr($ty)]
|
||||
pub enum $name {
|
||||
$($(#[$ident_attr])* $tag,)*
|
||||
$($(#[$ident_attr])* $tag = $val,)*
|
||||
$(
|
||||
#[$unknown_meta]
|
||||
Unknown($ty),
|
||||
|
||||
Reference in new issue
Block a user