1use super::{Entry, IFD, Result, TiffError, apply_corr, entry::RawEntry, file::TiffFile};
5use crate::{
6 bits::Endian,
7 tags::{ExifTag, TiffCommonTag, TiffTag},
8};
9use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
10use serde::{Deserialize, Serialize};
11use std::io::{Cursor, Read, Seek, SeekFrom};
12
13pub trait TiffReader {
14 fn file(&self) -> &TiffFile;
15 fn file_mut(&mut self) -> &mut TiffFile;
16
17 fn chains(&self) -> &Vec<IFD> {
18 &self.file().chain
19 }
20
21 fn get_endian(&self) -> Endian {
22 self.root_ifd().endian
23 }
24
25 fn wellknown_sub_ifd_tags(&self) -> Vec<u16> {
27 vec![
28 TiffCommonTag::SubIFDs.into(),
29 TiffCommonTag::ExifIFDPointer.into(),
30 ExifTag::GPSInfo.into(),
31 ExifTag::IccProfile.into(),
32 ]
33 }
34
35 fn root_ifd(&self) -> &IFD {
36 if self.file().chain.is_empty() {
37 panic!("TIFF must have at least one root IFD but the IFD list is empty");
38 }
39 &self.file().chain[0]
40 }
41
42 fn get_entry<T: TiffTag>(&self, tag: T) -> Option<&Entry> {
43 for ifd in &self.file().chain {
44 if let Some(x) = ifd.get_entry(tag) {
45 return Some(x);
46 }
47 }
48 None
49 }
50
51 fn get_entry_raw<'a, T: TiffTag, R: Read + Seek>(&'a self, tag: T, file: &mut R) -> Result<Option<RawEntry<'a>>> {
52 for ifd in &self.file().chain {
53 if let Some(entry) = ifd.get_entry_raw(tag, file)? {
54 return Ok(Some(entry));
55 }
56 }
57 Ok(None)
58 }
59
60 fn has_entry<T: TiffTag>(&self, tag: T) -> bool {
61 self.get_entry(tag).is_some()
62 }
63
64 fn find_ifds_with_tag<T: TiffTag>(&self, tag: T) -> Vec<&IFD> {
65 let mut ifds = Vec::new();
66 for ifd in &self.file().chain {
67 if ifd.has_entry(tag) {
68 ifds.push(ifd);
69 }
70 for subs in ifd.sub_ifds() {
72 for ifd in subs.1 {
73 if ifd.has_entry(tag) {
74 ifds.push(ifd);
75 }
76 }
77 }
78 }
79 ifds
80 }
81
82 fn find_ifds_with_filter<F: Fn(&IFD) -> bool>(&self, filter: F) -> Vec<&IFD> {
83 let mut ifds = Vec::new();
84 for ifd in &self.file().chain {
85 if filter(ifd) {
86 ifds.push(ifd);
87 }
88 for subs in ifd.sub_ifds() {
90 for ifd in subs.1 {
91 if filter(ifd) {
92 ifds.push(ifd);
93 }
94 }
95 }
96 }
97 ifds
98 }
99
100 fn find_ifd_with_new_subfile_type(&self, typ: u32) -> Option<&IFD> {
101 let list = self.find_ifds_with_tag(TiffCommonTag::NewSubFileType);
102 list
103 .iter()
104 .find(|ifd| ifd.get_entry(TiffCommonTag::NewSubFileType).expect("IFD must contain this entry").force_u32(0) == typ)
105 .copied()
106 }
107
108 fn find_first_ifd<T: TiffTag>(&self, tag: T) -> Option<&IFD> {
110 self.find_first_ifd_with_tag(tag)
111 }
112
113 fn find_first_ifd_with_tag<T: TiffTag>(&self, tag: T) -> Option<&IFD> {
114 let ifds = self.find_ifds_with_tag(tag);
115 if ifds.is_empty() { None } else { Some(ifds[0]) }
116 }
117
118 fn get_first_entry(&self, _tag: u16) -> Option<Entry> {
119 unimplemented!();
120 }
127
128 fn read_data<R: Read + Seek>(&self, file: &mut R, uncorr_offset: u32, buffer: &mut [u8]) -> Result<()> {
129 file.seek(SeekFrom::Start(apply_corr(uncorr_offset, self.file().corr) as u64))?;
130 file.read_exact(buffer)?;
131 Ok(())
132 }
133
134 fn parse_ifd<R: Read + Seek>(&self, reader: &mut R, offset: u32, base: u32, corr: i32, endian: Endian, sub_tags: &[u16]) -> Result<IFD> {
135 IFD::new(reader, offset, base, corr, endian, sub_tags)
136 }
137
138 fn parse_file<R: Read + Seek>(&mut self, file: &mut R, max_chained: Option<usize>, sub_tags: &[u16]) -> Result<()> {
143 let endian = match file.read_u16::<LittleEndian>()? {
144 0x4949 => Endian::Little,
145 0x4d4d => Endian::Big,
146 x => {
147 return Err(TiffError::General(format!("TIFF: don't know marker 0x{:x}", x)));
148 }
149 };
150 let mut reader = EndianReader::new(file, endian);
151 let magic = reader.read_u16()?;
152 if magic != 42 {
153 }
155 let mut next_ifd = reader.read_u32()?;
156 if next_ifd == 0 {
157 return Err(TiffError::General("Invalid TIFF header, contains no root IFD".to_string()));
158 }
159
160 let reader = reader.into_inner();
161
162 next_ifd = apply_corr(next_ifd, self.file().corr);
163 let mut chain = Vec::new();
164 while next_ifd != 0 {
165 let mut multi_sub_tags = self.wellknown_sub_ifd_tags();
167 multi_sub_tags.extend_from_slice(sub_tags);
168 let ifd = IFD::new(reader, next_ifd, self.file().base, self.file().corr, endian, &multi_sub_tags)?;
169 if ifd.entries.is_empty() {
170 return Err(TiffError::General("TIFF is invalid, IFD must contain at least one entry".to_string()));
171 }
172 next_ifd = ifd.next_ifd;
173 chain.push(ifd);
174 if let Some(max) = max_chained {
175 if chain.len() > max {
176 break;
177 }
178 }
179 }
180
181 if chain.is_empty() {
182 return Err(TiffError::General("TIFF is invalid, must contain at least one IFD".to_string()));
183 }
184 self.file_mut().chain = chain;
185 Ok(())
186 }
187}
188
189#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
191pub struct GenericTiffReader {
192 file: TiffFile,
193}
194
195impl TiffReader for GenericTiffReader {
196 fn file(&self) -> &TiffFile {
197 &self.file
198 }
199
200 fn file_mut(&mut self) -> &mut TiffFile {
201 &mut self.file
202 }
203}
204
205impl GenericTiffReader {
206 pub fn is_tiff<T: AsRef<[u8]>>(buffer: T) -> bool {
208 let buffer = buffer.as_ref();
209 buffer[0] == 0x49 || buffer[0] == 0x4d }
211
212 pub fn little_endian(&self) -> bool {
213 self.file.chain.first().unwrap().endian == Endian::Little
214 }
215
216 pub fn new_with_buffer<T: AsRef<[u8]>>(buffer: T, base: u32, corr: i32, max_chained: Option<usize>) -> Result<Self> {
224 let mut cursor = Cursor::new(buffer.as_ref());
225 cursor.seek(SeekFrom::Start(base as u64))?;
226 Self::new(&mut cursor, base, corr, max_chained, &[])
227 }
228
229 pub fn new<R: Read + Seek>(file: &mut R, base: u32, corr: i32, max_chained: Option<usize>, sub_tags: &[u16]) -> Result<Self> {
234 let mut ins = Self {
235 file: TiffFile::new(base, corr),
236 };
237 ins.parse_file(file, max_chained, sub_tags)?;
238 Ok(ins)
239 }
240}
241
242pub trait ReadByteOrder {
243 fn read_u8(&mut self) -> std::io::Result<u8>;
244 fn read_i8(&mut self) -> std::io::Result<i8>;
245 fn read_u16(&mut self) -> std::io::Result<u16>;
246 fn read_i16(&mut self) -> std::io::Result<i16>;
247 fn read_u32(&mut self) -> std::io::Result<u32>;
248 fn read_i32(&mut self) -> std::io::Result<i32>;
249 fn read_u64(&mut self) -> std::io::Result<u64>;
250 fn read_i64(&mut self) -> std::io::Result<i64>;
251 fn read_f32(&mut self) -> std::io::Result<f32>;
252 fn read_f64(&mut self) -> std::io::Result<f64>;
253
254 fn read_u8_into(&mut self, dst: &mut [u8]) -> std::io::Result<()>;
255 fn read_i8_into(&mut self, dst: &mut [i8]) -> std::io::Result<()>;
256 fn read_u16_into(&mut self, dst: &mut [u16]) -> std::io::Result<()>;
257 fn read_i16_into(&mut self, dst: &mut [i16]) -> std::io::Result<()>;
258 fn read_u32_into(&mut self, dst: &mut [u32]) -> std::io::Result<()>;
259 fn read_i32_into(&mut self, dst: &mut [i32]) -> std::io::Result<()>;
260 fn read_u64_into(&mut self, dst: &mut [u64]) -> std::io::Result<()>;
261 fn read_i64_into(&mut self, dst: &mut [i64]) -> std::io::Result<()>;
262 fn read_f32_into(&mut self, dst: &mut [f32]) -> std::io::Result<()>;
263 fn read_f64_into(&mut self, dst: &mut [f64]) -> std::io::Result<()>;
264}
265
266pub struct EndianReader<'a, R: Read + Seek + 'a> {
267 endian: Endian,
268 inner: &'a mut R,
269}
270
271impl<'a, R: Read + Seek + 'a> EndianReader<'a, R> {
272 pub fn new(inner: &'a mut R, endian: Endian) -> Self {
273 Self { endian, inner }
274 }
275
276 pub fn into_inner(self) -> &'a mut R {
277 self.inner
278 }
279
280 pub fn inner(&'a mut self) -> &'a mut R {
281 self.inner
282 }
283
284 pub fn position(&mut self) -> Result<u32> {
285 Ok(self.inner.stream_position().map(|v| v as u32)?)
286 }
287
288 pub fn goto(&mut self, offset: u32) -> Result<()> {
291 self.inner.seek(SeekFrom::Start(offset as u64))?;
292 Ok(())
293
294 }
296}
297
298impl<'a, R: Read + Seek + 'a> ReadByteOrder for EndianReader<'a, R> {
299 fn read_u16(&mut self) -> std::io::Result<u16> {
300 match self.endian {
301 Endian::Little => self.inner.read_u16::<LittleEndian>(),
302 Endian::Big => self.inner.read_u16::<BigEndian>(),
303 }
304 }
305
306 fn read_u8(&mut self) -> std::io::Result<u8> {
307 self.inner.read_u8()
308 }
309
310 fn read_i8(&mut self) -> std::io::Result<i8> {
311 match self.endian {
312 Endian::Little => self.inner.read_i8(),
313 Endian::Big => self.inner.read_i8(),
314 }
315 }
316
317 fn read_i16(&mut self) -> std::io::Result<i16> {
318 match self.endian {
319 Endian::Little => self.inner.read_i16::<LittleEndian>(),
320 Endian::Big => self.inner.read_i16::<BigEndian>(),
321 }
322 }
323
324 fn read_u32(&mut self) -> std::io::Result<u32> {
325 match self.endian {
326 Endian::Little => self.inner.read_u32::<LittleEndian>(),
327 Endian::Big => self.inner.read_u32::<BigEndian>(),
328 }
329 }
330
331 fn read_i32(&mut self) -> std::io::Result<i32> {
332 match self.endian {
333 Endian::Little => self.inner.read_i32::<LittleEndian>(),
334 Endian::Big => self.inner.read_i32::<BigEndian>(),
335 }
336 }
337
338 fn read_u64(&mut self) -> std::io::Result<u64> {
339 match self.endian {
340 Endian::Little => self.inner.read_u64::<LittleEndian>(),
341 Endian::Big => self.inner.read_u64::<BigEndian>(),
342 }
343 }
344
345 fn read_i64(&mut self) -> std::io::Result<i64> {
346 match self.endian {
347 Endian::Little => self.inner.read_i64::<LittleEndian>(),
348 Endian::Big => self.inner.read_i64::<BigEndian>(),
349 }
350 }
351
352 fn read_f32(&mut self) -> std::io::Result<f32> {
353 match self.endian {
354 Endian::Little => self.inner.read_f32::<LittleEndian>(),
355 Endian::Big => self.inner.read_f32::<BigEndian>(),
356 }
357 }
358
359 fn read_f64(&mut self) -> std::io::Result<f64> {
360 match self.endian {
361 Endian::Little => self.inner.read_f64::<LittleEndian>(),
362 Endian::Big => self.inner.read_f64::<BigEndian>(),
363 }
364 }
365
366 fn read_u8_into(&mut self, dst: &mut [u8]) -> std::io::Result<()> {
367 self.inner.read_exact(dst)
368 }
369
370 fn read_i8_into(&mut self, dst: &mut [i8]) -> std::io::Result<()> {
371 self.inner.read_i8_into(dst)
372 }
373
374 fn read_u16_into(&mut self, dst: &mut [u16]) -> std::io::Result<()> {
375 match self.endian {
376 Endian::Little => self.inner.read_u16_into::<LittleEndian>(dst),
377 Endian::Big => self.inner.read_u16_into::<BigEndian>(dst),
378 }
379 }
380
381 fn read_i16_into(&mut self, dst: &mut [i16]) -> std::io::Result<()> {
382 match self.endian {
383 Endian::Little => self.inner.read_i16_into::<LittleEndian>(dst),
384 Endian::Big => self.inner.read_i16_into::<BigEndian>(dst),
385 }
386 }
387
388 fn read_u32_into(&mut self, dst: &mut [u32]) -> std::io::Result<()> {
389 match self.endian {
390 Endian::Little => self.inner.read_u32_into::<LittleEndian>(dst),
391 Endian::Big => self.inner.read_u32_into::<BigEndian>(dst),
392 }
393 }
394
395 fn read_i32_into(&mut self, dst: &mut [i32]) -> std::io::Result<()> {
396 match self.endian {
397 Endian::Little => self.inner.read_i32_into::<LittleEndian>(dst),
398 Endian::Big => self.inner.read_i32_into::<BigEndian>(dst),
399 }
400 }
401
402 fn read_u64_into(&mut self, dst: &mut [u64]) -> std::io::Result<()> {
403 match self.endian {
404 Endian::Little => self.inner.read_u64_into::<LittleEndian>(dst),
405 Endian::Big => self.inner.read_u64_into::<BigEndian>(dst),
406 }
407 }
408
409 fn read_i64_into(&mut self, dst: &mut [i64]) -> std::io::Result<()> {
410 match self.endian {
411 Endian::Little => self.inner.read_i64_into::<LittleEndian>(dst),
412 Endian::Big => self.inner.read_i64_into::<BigEndian>(dst),
413 }
414 }
415
416 fn read_f32_into(&mut self, dst: &mut [f32]) -> std::io::Result<()> {
417 match self.endian {
418 Endian::Little => self.inner.read_f32_into::<LittleEndian>(dst),
419 Endian::Big => self.inner.read_f32_into::<BigEndian>(dst),
420 }
421 }
422
423 fn read_f64_into(&mut self, dst: &mut [f64]) -> std::io::Result<()> {
424 match self.endian {
425 Endian::Little => self.inner.read_f64_into::<LittleEndian>(dst),
426 Endian::Big => self.inner.read_f64_into::<BigEndian>(dst),
427 }
428 }
429}