Skip to content

Commit ff52aea

Browse files
authored
Add support for iterating over all tags (#255)
1 parent 96d3a02 commit ff52aea

File tree

2 files changed

+95
-5
lines changed

2 files changed

+95
-5
lines changed

src/decoder/mod.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
use std::collections::{HashMap, HashSet};
22
use std::io::{self, Read, Seek};
33

4+
use crate::tags::{
5+
CompressionMethod, PhotometricInterpretation, PlanarConfiguration, Predictor, SampleFormat,
6+
Tag, Type,
7+
};
48
use crate::{
59
bytecast, ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError, UsageError,
610
};
711

812
use self::ifd::Directory;
913
use self::image::Image;
10-
use crate::tags::{
11-
CompressionMethod, PhotometricInterpretation, PlanarConfiguration, Predictor, SampleFormat,
12-
Tag, Type,
13-
};
14-
1514
use self::stream::{ByteOrder, EndianReader, SmartReader};
1615

1716
pub mod ifd;
@@ -895,6 +894,15 @@ impl<R: Read + Seek> Decoder<R> {
895894
self.get_tag(tag)?.into_string()
896895
}
897896

897+
/// Returns an iterator over all tags in the current image, along with their values.
898+
pub fn tag_iter(&mut self) -> impl Iterator<Item = TiffResult<(Tag, ifd::Value)>> + '_ {
899+
self.image.ifd.as_ref().unwrap().iter().map(|(tag, entry)| {
900+
entry
901+
.val(&self.limits, self.bigtiff, &mut self.reader)
902+
.map(|value| (*tag, value))
903+
})
904+
}
905+
898906
fn check_chunk_type(&self, expected: ChunkType) -> TiffResult<()> {
899907
if expected != self.image().chunk_type {
900908
return Err(TiffError::UsageError(UsageError::InvalidChunkType(

tests/encode_images.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,47 @@ fn encode_decode() {
3636
let mut decoder = Decoder::new(&mut file).unwrap();
3737
assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(8));
3838
assert_eq!(decoder.dimensions().unwrap(), (100, 100));
39+
40+
let mut all_tags = decoder
41+
.tag_iter()
42+
.filter_map(Result::ok)
43+
.collect::<Vec<_>>();
44+
all_tags.sort_by_key(|(t, _)| t.to_u16());
45+
assert_eq!(
46+
all_tags,
47+
vec![
48+
(Tag::ImageWidth, ifd::Value::Unsigned(100)),
49+
(Tag::ImageLength, ifd::Value::Unsigned(100)),
50+
(
51+
Tag::BitsPerSample,
52+
ifd::Value::List(vec![
53+
ifd::Value::UnsignedBig(8),
54+
ifd::Value::UnsignedBig(8),
55+
ifd::Value::UnsignedBig(8)
56+
])
57+
),
58+
(Tag::Compression, ifd::Value::Unsigned(1)),
59+
(Tag::PhotometricInterpretation, ifd::Value::Unsigned(2)),
60+
(Tag::StripOffsets, ifd::Value::Unsigned(8)),
61+
(Tag::SamplesPerPixel, ifd::Value::Unsigned(3)),
62+
(Tag::RowsPerStrip, ifd::Value::Unsigned(3334)),
63+
(Tag::StripByteCounts, ifd::Value::Unsigned(30000)),
64+
(Tag::XResolution, ifd::Value::Rational(1, 1)),
65+
(Tag::YResolution, ifd::Value::Rational(1, 1)),
66+
(Tag::ResolutionUnit, ifd::Value::Unsigned(1)),
67+
(Tag::Artist, ifd::Value::Ascii("Image-tiff".into())),
68+
(Tag::Predictor, ifd::Value::Unsigned(1)),
69+
(
70+
Tag::SampleFormat,
71+
ifd::Value::List(vec![
72+
ifd::Value::UnsignedBig(1),
73+
ifd::Value::UnsignedBig(1),
74+
ifd::Value::UnsignedBig(1)
75+
])
76+
),
77+
]
78+
);
79+
3980
assert_eq!(
4081
decoder.get_tag(Tag::Artist).unwrap(),
4182
ifd::Value::Ascii("Image-tiff".into())
@@ -75,6 +116,47 @@ fn encode_decode_big() {
75116
let mut decoder = Decoder::new(&mut file).unwrap();
76117
assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(8));
77118
assert_eq!(decoder.dimensions().unwrap(), (100, 100));
119+
120+
let mut all_tags = decoder
121+
.tag_iter()
122+
.filter_map(Result::ok)
123+
.collect::<Vec<_>>();
124+
all_tags.sort_by_key(|(t, _)| t.to_u16());
125+
assert_eq!(
126+
all_tags,
127+
vec![
128+
(Tag::ImageWidth, ifd::Value::Unsigned(100)),
129+
(Tag::ImageLength, ifd::Value::Unsigned(100)),
130+
(
131+
Tag::BitsPerSample,
132+
ifd::Value::List(vec![
133+
ifd::Value::Short(8),
134+
ifd::Value::Short(8),
135+
ifd::Value::Short(8)
136+
])
137+
),
138+
(Tag::Compression, ifd::Value::Unsigned(1)),
139+
(Tag::PhotometricInterpretation, ifd::Value::Unsigned(2)),
140+
(Tag::StripOffsets, ifd::Value::UnsignedBig(16)),
141+
(Tag::SamplesPerPixel, ifd::Value::Unsigned(3)),
142+
(Tag::RowsPerStrip, ifd::Value::Unsigned(3334)),
143+
(Tag::StripByteCounts, ifd::Value::UnsignedBig(30000)),
144+
(Tag::XResolution, ifd::Value::Rational(1, 1)),
145+
(Tag::YResolution, ifd::Value::Rational(1, 1)),
146+
(Tag::ResolutionUnit, ifd::Value::Unsigned(1)),
147+
(Tag::Artist, ifd::Value::Ascii("Image-tiff".into())),
148+
(Tag::Predictor, ifd::Value::Unsigned(1)),
149+
(
150+
Tag::SampleFormat,
151+
ifd::Value::List(vec![
152+
ifd::Value::Short(1),
153+
ifd::Value::Short(1),
154+
ifd::Value::Short(1)
155+
])
156+
),
157+
]
158+
);
159+
78160
assert_eq!(
79161
decoder.get_tag(Tag::Artist).unwrap(),
80162
ifd::Value::Ascii("Image-tiff".into())

0 commit comments

Comments
 (0)