/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tiff-0.10.3/src/decoder/ifd.rs
Line | Count | Source |
1 | | //! Function for reading TIFF tags |
2 | | |
3 | | use std::collections::HashMap; |
4 | | use std::io::{self, Read, Seek}; |
5 | | use std::mem; |
6 | | use std::str; |
7 | | |
8 | | use super::stream::{ByteOrder, EndianReader}; |
9 | | use crate::tags::{IfdPointer, Tag, Type}; |
10 | | use crate::{TiffError, TiffFormatError, TiffResult}; |
11 | | |
12 | | use self::Value::{ |
13 | | Ascii, Byte, Double, Float, Ifd, IfdBig, List, Rational, RationalBig, SRational, SRationalBig, |
14 | | Short, Signed, SignedBig, SignedByte, SignedShort, Unsigned, UnsignedBig, |
15 | | }; |
16 | | |
17 | | #[allow(unused_qualifications)] |
18 | | #[derive(Debug, Clone, PartialEq)] |
19 | | #[non_exhaustive] |
20 | | pub enum Value { |
21 | | Byte(u8), |
22 | | Short(u16), |
23 | | SignedByte(i8), |
24 | | SignedShort(i16), |
25 | | Signed(i32), |
26 | | SignedBig(i64), |
27 | | Unsigned(u32), |
28 | | UnsignedBig(u64), |
29 | | Float(f32), |
30 | | Double(f64), |
31 | | List(Vec<Value>), |
32 | | Rational(u32, u32), |
33 | | RationalBig(u64, u64), |
34 | | SRational(i32, i32), |
35 | | SRationalBig(i64, i64), |
36 | | Ascii(String), |
37 | | Ifd(u32), |
38 | | IfdBig(u64), |
39 | | } |
40 | | |
41 | | impl Value { |
42 | 843k | pub fn into_u8(self) -> TiffResult<u8> { |
43 | 843k | match self { |
44 | 843k | Byte(val) => Ok(val), |
45 | 2 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
46 | | } |
47 | 843k | } |
48 | 0 | pub fn into_i8(self) -> TiffResult<i8> { |
49 | 0 | match self { |
50 | 0 | SignedByte(val) => Ok(val), |
51 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
52 | | } |
53 | 0 | } |
54 | | |
55 | 27.4k | pub fn into_u16(self) -> TiffResult<u16> { |
56 | 27.4k | match self { |
57 | 107 | Byte(val) => Ok(val.into()), |
58 | 27.3k | Short(val) => Ok(val), |
59 | 5 | Unsigned(val) => Ok(u16::try_from(val)?), |
60 | 59 | UnsignedBig(val) => Ok(u16::try_from(val)?), |
61 | 3 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
62 | | } |
63 | 27.4k | } |
64 | | |
65 | 0 | pub fn into_i16(self) -> TiffResult<i16> { |
66 | 0 | match self { |
67 | 0 | SignedByte(val) => Ok(val.into()), |
68 | 0 | SignedShort(val) => Ok(val), |
69 | 0 | Signed(val) => Ok(i16::try_from(val)?), |
70 | 0 | SignedBig(val) => Ok(i16::try_from(val)?), |
71 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
72 | | } |
73 | 0 | } |
74 | | |
75 | 24.9k | pub fn into_u32(self) -> TiffResult<u32> { |
76 | 24.9k | match self { |
77 | 123 | Byte(val) => Ok(val.into()), |
78 | 24.7k | Short(val) => Ok(val.into()), |
79 | 81 | Unsigned(val) => Ok(val), |
80 | 1 | UnsignedBig(val) => Ok(u32::try_from(val)?), |
81 | 11 | Ifd(val) => Ok(val), |
82 | 8 | IfdBig(val) => Ok(u32::try_from(val)?), |
83 | 14 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
84 | | } |
85 | 24.9k | } |
86 | | |
87 | 0 | pub fn into_i32(self) -> TiffResult<i32> { |
88 | 0 | match self { |
89 | 0 | SignedByte(val) => Ok(val.into()), |
90 | 0 | SignedShort(val) => Ok(val.into()), |
91 | 0 | Signed(val) => Ok(val), |
92 | 0 | SignedBig(val) => Ok(i32::try_from(val)?), |
93 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
94 | | } |
95 | 0 | } |
96 | | |
97 | 1.89M | pub fn into_u64(self) -> TiffResult<u64> { |
98 | 1.89M | match self { |
99 | 991k | Byte(val) => Ok(val.into()), |
100 | 770k | Short(val) => Ok(val.into()), |
101 | 116k | Unsigned(val) => Ok(val.into()), |
102 | 12.0k | UnsignedBig(val) => Ok(val), |
103 | 824 | Ifd(val) => Ok(val.into()), |
104 | 1.28k | IfdBig(val) => Ok(val), |
105 | 8 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
106 | | } |
107 | 1.89M | } |
108 | | |
109 | 0 | pub fn into_i64(self) -> TiffResult<i64> { |
110 | 0 | match self { |
111 | 0 | SignedByte(val) => Ok(val.into()), |
112 | 0 | SignedShort(val) => Ok(val.into()), |
113 | 0 | Signed(val) => Ok(val.into()), |
114 | 0 | SignedBig(val) => Ok(val), |
115 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
116 | | } |
117 | 0 | } |
118 | | |
119 | 0 | pub fn into_f32(self) -> TiffResult<f32> { |
120 | 0 | match self { |
121 | 0 | Float(val) => Ok(val), |
122 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
123 | | } |
124 | 0 | } |
125 | | |
126 | 0 | pub fn into_f64(self) -> TiffResult<f64> { |
127 | 0 | match self { |
128 | 0 | Double(val) => Ok(val), |
129 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
130 | | } |
131 | 0 | } |
132 | | |
133 | | /// Turn this value into an `IfdPointer`. |
134 | | /// |
135 | | /// Notice that this does not take an argument, a 64-bit IFD is always allowed. If the |
136 | | /// difference is crucial and you do not want to be permissive you're expected to filter this |
137 | | /// out before. |
138 | | /// |
139 | | /// For compatibility the smaller sized tags should always be allowed i.e. you might use a |
140 | | /// non-bigtiff's directory and its tag types and move it straight to a bigtiff. For instance |
141 | | /// the SubIFD tag is defined as `LONG or IFD`: |
142 | | /// |
143 | | /// <https://web.archive.org/web/20181105221012/https://www.awaresystems.be/imaging/tiff/tifftags/subifds.html> |
144 | 0 | pub fn into_ifd_pointer(self) -> TiffResult<IfdPointer> { |
145 | 0 | match self { |
146 | 0 | Unsigned(val) | Ifd(val) => Ok(IfdPointer(val.into())), |
147 | 0 | IfdBig(val) => Ok(IfdPointer(val)), |
148 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
149 | | } |
150 | 0 | } |
151 | | |
152 | 0 | pub fn into_string(self) -> TiffResult<String> { |
153 | 0 | match self { |
154 | 0 | Ascii(val) => Ok(val), |
155 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
156 | | } |
157 | 0 | } |
158 | | |
159 | 0 | pub fn into_u32_vec(self) -> TiffResult<Vec<u32>> { |
160 | 0 | match self { |
161 | 0 | List(vec) => { |
162 | 0 | let mut new_vec = Vec::with_capacity(vec.len()); |
163 | 0 | for v in vec { |
164 | 0 | new_vec.push(v.into_u32()?) |
165 | | } |
166 | 0 | Ok(new_vec) |
167 | | } |
168 | 0 | Byte(val) => Ok(vec![val.into()]), |
169 | 0 | Short(val) => Ok(vec![val.into()]), |
170 | 0 | Unsigned(val) => Ok(vec![val]), |
171 | 0 | UnsignedBig(val) => Ok(vec![u32::try_from(val)?]), |
172 | 0 | Rational(numerator, denominator) => Ok(vec![numerator, denominator]), |
173 | 0 | RationalBig(numerator, denominator) => { |
174 | 0 | Ok(vec![u32::try_from(numerator)?, u32::try_from(denominator)?]) |
175 | | } |
176 | 0 | Ifd(val) => Ok(vec![val]), |
177 | 0 | IfdBig(val) => Ok(vec![u32::try_from(val)?]), |
178 | 0 | Ascii(val) => Ok(val.chars().map(u32::from).collect()), |
179 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
180 | | } |
181 | 0 | } |
182 | | |
183 | 1.30k | pub fn into_u8_vec(self) -> TiffResult<Vec<u8>> { |
184 | 1.30k | match self { |
185 | 1.30k | List(vec) => { |
186 | 1.30k | let mut new_vec = Vec::with_capacity(vec.len()); |
187 | 844k | for v in vec { |
188 | 843k | new_vec.push(v.into_u8()?) |
189 | | } |
190 | 1.30k | Ok(new_vec) |
191 | | } |
192 | 1 | Byte(val) => Ok(vec![val]), |
193 | | |
194 | 1 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
195 | | } |
196 | 1.30k | } |
197 | | |
198 | 0 | pub fn into_u16_vec(self) -> TiffResult<Vec<u16>> { |
199 | 0 | match self { |
200 | 0 | List(vec) => { |
201 | 0 | let mut new_vec = Vec::with_capacity(vec.len()); |
202 | 0 | for v in vec { |
203 | 0 | new_vec.push(v.into_u16()?) |
204 | | } |
205 | 0 | Ok(new_vec) |
206 | | } |
207 | 0 | Byte(val) => Ok(vec![val.into()]), |
208 | 0 | Short(val) => Ok(vec![val]), |
209 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
210 | | } |
211 | 0 | } |
212 | | |
213 | 0 | pub fn into_i32_vec(self) -> TiffResult<Vec<i32>> { |
214 | 0 | match self { |
215 | 0 | List(vec) => { |
216 | 0 | let mut new_vec = Vec::with_capacity(vec.len()); |
217 | 0 | for v in vec { |
218 | 0 | match v { |
219 | 0 | SRational(numerator, denominator) => { |
220 | 0 | new_vec.push(numerator); |
221 | 0 | new_vec.push(denominator); |
222 | 0 | } |
223 | 0 | SRationalBig(numerator, denominator) => { |
224 | 0 | new_vec.push(i32::try_from(numerator)?); |
225 | 0 | new_vec.push(i32::try_from(denominator)?); |
226 | | } |
227 | 0 | _ => new_vec.push(v.into_i32()?), |
228 | | } |
229 | | } |
230 | 0 | Ok(new_vec) |
231 | | } |
232 | 0 | SignedByte(val) => Ok(vec![val.into()]), |
233 | 0 | SignedShort(val) => Ok(vec![val.into()]), |
234 | 0 | Signed(val) => Ok(vec![val]), |
235 | 0 | SignedBig(val) => Ok(vec![i32::try_from(val)?]), |
236 | 0 | SRational(numerator, denominator) => Ok(vec![numerator, denominator]), |
237 | 0 | SRationalBig(numerator, denominator) => { |
238 | 0 | Ok(vec![i32::try_from(numerator)?, i32::try_from(denominator)?]) |
239 | | } |
240 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
241 | | } |
242 | 0 | } |
243 | | |
244 | 0 | pub fn into_f32_vec(self) -> TiffResult<Vec<f32>> { |
245 | 0 | match self { |
246 | 0 | List(vec) => { |
247 | 0 | let mut new_vec = Vec::with_capacity(vec.len()); |
248 | 0 | for v in vec { |
249 | 0 | new_vec.push(v.into_f32()?) |
250 | | } |
251 | 0 | Ok(new_vec) |
252 | | } |
253 | 0 | Float(val) => Ok(vec![val]), |
254 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
255 | | } |
256 | 0 | } |
257 | | |
258 | 0 | pub fn into_f64_vec(self) -> TiffResult<Vec<f64>> { |
259 | 0 | match self { |
260 | 0 | List(vec) => { |
261 | 0 | let mut new_vec = Vec::with_capacity(vec.len()); |
262 | 0 | for v in vec { |
263 | 0 | new_vec.push(v.into_f64()?) |
264 | | } |
265 | 0 | Ok(new_vec) |
266 | | } |
267 | 0 | Double(val) => Ok(vec![val]), |
268 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
269 | | } |
270 | 0 | } |
271 | | |
272 | 24.7k | pub fn into_u64_vec(self) -> TiffResult<Vec<u64>> { |
273 | 24.7k | match self { |
274 | 6.81k | List(vec) => { |
275 | 6.81k | let mut new_vec = Vec::with_capacity(vec.len()); |
276 | 1.89M | for v in vec { |
277 | 1.89M | new_vec.push(v.into_u64()?) |
278 | | } |
279 | 6.80k | Ok(new_vec) |
280 | | } |
281 | 26 | Byte(val) => Ok(vec![val.into()]), |
282 | 5.66k | Short(val) => Ok(vec![val.into()]), |
283 | 12.0k | Unsigned(val) => Ok(vec![val.into()]), |
284 | 12 | UnsignedBig(val) => Ok(vec![val]), |
285 | 2 | Rational(numerator, denominator) => Ok(vec![numerator.into(), denominator.into()]), |
286 | 0 | RationalBig(numerator, denominator) => Ok(vec![numerator, denominator]), |
287 | 11 | Ifd(val) => Ok(vec![val.into()]), |
288 | 64 | IfdBig(val) => Ok(vec![val]), |
289 | 86 | Ascii(val) => Ok(val.chars().map(u32::from).map(u64::from).collect()), |
290 | 3 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
291 | | } |
292 | 24.7k | } |
293 | | |
294 | 0 | pub fn into_i64_vec(self) -> TiffResult<Vec<i64>> { |
295 | 0 | match self { |
296 | 0 | List(vec) => { |
297 | 0 | let mut new_vec = Vec::with_capacity(vec.len()); |
298 | 0 | for v in vec { |
299 | 0 | match v { |
300 | 0 | SRational(numerator, denominator) => { |
301 | 0 | new_vec.push(numerator.into()); |
302 | 0 | new_vec.push(denominator.into()); |
303 | 0 | } |
304 | 0 | SRationalBig(numerator, denominator) => { |
305 | 0 | new_vec.push(numerator); |
306 | 0 | new_vec.push(denominator); |
307 | 0 | } |
308 | 0 | _ => new_vec.push(v.into_i64()?), |
309 | | } |
310 | | } |
311 | 0 | Ok(new_vec) |
312 | | } |
313 | 0 | SignedByte(val) => Ok(vec![val.into()]), |
314 | 0 | SignedShort(val) => Ok(vec![val.into()]), |
315 | 0 | Signed(val) => Ok(vec![val.into()]), |
316 | 0 | SignedBig(val) => Ok(vec![val]), |
317 | 0 | SRational(numerator, denominator) => Ok(vec![numerator.into(), denominator.into()]), |
318 | 0 | SRationalBig(numerator, denominator) => Ok(vec![numerator, denominator]), |
319 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
320 | | } |
321 | 0 | } |
322 | | |
323 | 0 | pub fn into_ifd_vec(self) -> TiffResult<Vec<IfdPointer>> { |
324 | 0 | let vec = match self { |
325 | 0 | Unsigned(val) | Ifd(val) => return Ok(vec![IfdPointer(val.into())]), |
326 | 0 | IfdBig(val) => return Ok(vec![IfdPointer(val)]), |
327 | 0 | List(vec) => vec, |
328 | 0 | _ => return Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
329 | | }; |
330 | | |
331 | 0 | vec.into_iter().map(Self::into_ifd_pointer).collect() |
332 | 0 | } |
333 | | } |
334 | | |
335 | | #[derive(Clone)] |
336 | | pub struct Entry { |
337 | | type_: Type, |
338 | | count: u64, |
339 | | offset: [u8; 8], |
340 | | } |
341 | | |
342 | | impl ::std::fmt::Debug for Entry { |
343 | 0 | fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { |
344 | 0 | fmt.write_str(&format!( |
345 | 0 | "Entry {{ type_: {:?}, count: {:?}, offset: {:?} }}", |
346 | 0 | self.type_, self.count, &self.offset |
347 | 0 | )) |
348 | 0 | } |
349 | | } |
350 | | |
351 | | impl Entry { |
352 | 466k | pub fn new(type_: Type, count: u32, offset: [u8; 4]) -> Entry { |
353 | 466k | let mut entry_off = [0u8; 8]; |
354 | 466k | entry_off[..4].copy_from_slice(&offset); |
355 | 466k | Entry::new_u64(type_, count.into(), entry_off) |
356 | 466k | } |
357 | | |
358 | 475k | pub fn new_u64(type_: Type, count: u64, offset: [u8; 8]) -> Entry { |
359 | 475k | Entry { |
360 | 475k | type_, |
361 | 475k | count, |
362 | 475k | offset, |
363 | 475k | } |
364 | 475k | } |
365 | | |
366 | 0 | pub fn field_type(&self) -> Type { |
367 | 0 | self.type_ |
368 | 0 | } |
369 | | |
370 | 0 | pub fn count(&self) -> u64 { |
371 | 0 | self.count |
372 | 0 | } |
373 | | |
374 | 0 | pub(crate) fn offset(&self) -> &[u8] { |
375 | 0 | &self.offset |
376 | 0 | } |
377 | | |
378 | | /// Returns a mem_reader for the offset/value field |
379 | 78.3k | fn r(&self, byte_order: ByteOrder) -> EndianReader<io::Cursor<Vec<u8>>> { |
380 | 78.3k | EndianReader::new(io::Cursor::new(self.offset.to_vec()), byte_order) |
381 | 78.3k | } |
382 | | |
383 | 78.7k | pub(crate) fn val<R: Read + Seek>( |
384 | 78.7k | &self, |
385 | 78.7k | limits: &super::Limits, |
386 | 78.7k | bigtiff: bool, |
387 | 78.7k | reader: &mut EndianReader<R>, |
388 | 78.7k | ) -> TiffResult<Value> { |
389 | | // Case 1: there are no values so we can return immediately. |
390 | 78.7k | if self.count == 0 { |
391 | 8 | return Ok(List(Vec::new())); |
392 | 78.7k | } |
393 | | |
394 | 78.7k | let bo = reader.byte_order; |
395 | | |
396 | 78.7k | let tag_size = match self.type_ { |
397 | 1.78k | Type::BYTE | Type::SBYTE | Type::ASCII | Type::UNDEFINED => 1, |
398 | 60.2k | Type::SHORT | Type::SSHORT => 2, |
399 | 16.3k | Type::LONG | Type::SLONG | Type::FLOAT | Type::IFD => 4, |
400 | | Type::LONG8 |
401 | | | Type::SLONG8 |
402 | | | Type::DOUBLE |
403 | | | Type::RATIONAL |
404 | | | Type::SRATIONAL |
405 | 321 | | Type::IFD8 => 8, |
406 | | }; |
407 | | |
408 | 78.7k | let value_bytes = match self.count.checked_mul(tag_size) { |
409 | 78.7k | Some(n) => n, |
410 | | None => { |
411 | 1 | return Err(TiffError::LimitsExceeded); |
412 | | } |
413 | | }; |
414 | | |
415 | | // Case 2: there is one value. |
416 | 78.7k | if self.count == 1 { |
417 | | // 2a: the value is 5-8 bytes and we're in BigTiff mode. |
418 | 70.3k | if bigtiff && value_bytes > 4 && value_bytes <= 8 { |
419 | 2 | return Ok(match self.type_ { |
420 | 2 | Type::LONG8 => UnsignedBig(self.r(bo).read_u64()?), |
421 | 0 | Type::SLONG8 => SignedBig(self.r(bo).read_i64()?), |
422 | 0 | Type::DOUBLE => Double(self.r(bo).read_f64()?), |
423 | | Type::RATIONAL => { |
424 | 0 | let mut r = self.r(bo); |
425 | 0 | Rational(r.read_u32()?, r.read_u32()?) |
426 | | } |
427 | | Type::SRATIONAL => { |
428 | 0 | let mut r = self.r(bo); |
429 | 0 | SRational(r.read_i32()?, r.read_i32()?) |
430 | | } |
431 | 0 | Type::IFD8 => IfdBig(self.r(bo).read_u64()?), |
432 | | Type::BYTE |
433 | | | Type::SBYTE |
434 | | | Type::ASCII |
435 | | | Type::UNDEFINED |
436 | | | Type::SHORT |
437 | | | Type::SSHORT |
438 | | | Type::LONG |
439 | | | Type::SLONG |
440 | | | Type::FLOAT |
441 | 0 | | Type::IFD => unreachable!(), |
442 | | }); |
443 | 70.3k | } |
444 | | |
445 | | // 2b: the value is at most 4 bytes or doesn't fit in the offset field. |
446 | 70.3k | return Ok(match self.type_ { |
447 | 224 | Type::BYTE => Byte(self.offset[0]), |
448 | 2 | Type::SBYTE => SignedByte(self.offset[0] as i8), |
449 | 33 | Type::UNDEFINED => Byte(self.offset[0]), |
450 | 57.7k | Type::SHORT => Short(self.r(bo).read_u16()?), |
451 | 1 | Type::SSHORT => SignedShort(self.r(bo).read_i16()?), |
452 | 12.1k | Type::LONG => Unsigned(self.r(bo).read_u32()?), |
453 | 0 | Type::SLONG => Signed(self.r(bo).read_i32()?), |
454 | 0 | Type::FLOAT => Float(self.r(bo).read_f32()?), |
455 | | Type::ASCII => { |
456 | 1 | if self.offset[0] == 0 { |
457 | 1 | Ascii("".to_string()) |
458 | | } else { |
459 | 0 | return Err(TiffError::FormatError(TiffFormatError::InvalidTag)); |
460 | | } |
461 | | } |
462 | | Type::LONG8 => { |
463 | 70 | reader.goto_offset(self.r(bo).read_u32()?.into())?; |
464 | 70 | UnsignedBig(reader.read_u64()?) |
465 | | } |
466 | | Type::SLONG8 => { |
467 | 0 | reader.goto_offset(self.r(bo).read_u32()?.into())?; |
468 | 0 | SignedBig(reader.read_i64()?) |
469 | | } |
470 | | Type::DOUBLE => { |
471 | 1 | reader.goto_offset(self.r(bo).read_u32()?.into())?; |
472 | 1 | Double(reader.read_f64()?) |
473 | | } |
474 | | Type::RATIONAL => { |
475 | 4 | reader.goto_offset(self.r(bo).read_u32()?.into())?; |
476 | 4 | Rational(reader.read_u32()?, reader.read_u32()?) |
477 | | } |
478 | | Type::SRATIONAL => { |
479 | 1 | reader.goto_offset(self.r(bo).read_u32()?.into())?; |
480 | 1 | SRational(reader.read_i32()?, reader.read_i32()?) |
481 | | } |
482 | 22 | Type::IFD => Ifd(self.r(bo).read_u32()?), |
483 | | Type::IFD8 => { |
484 | 72 | reader.goto_offset(self.r(bo).read_u32()?.into())?; |
485 | 72 | IfdBig(reader.read_u64()?) |
486 | | } |
487 | | }); |
488 | 8.40k | } |
489 | | |
490 | | // Case 3: There is more than one value, but it fits in the offset field. |
491 | 8.40k | if value_bytes <= 4 || bigtiff && value_bytes <= 8 { |
492 | 48 | match self.type_ { |
493 | 22 | Type::BYTE => return offset_to_bytes(self.count as usize, self), |
494 | 0 | Type::SBYTE => return offset_to_sbytes(self.count as usize, self), |
495 | | Type::ASCII => { |
496 | 4 | let mut buf = vec![0; self.count as usize]; |
497 | 4 | buf.copy_from_slice(&self.offset[..self.count as usize]); |
498 | 4 | if buf.is_ascii() && buf.ends_with(&[0]) { |
499 | 4 | let v = str::from_utf8(&buf)?; |
500 | 4 | let v = v.trim_matches(char::from(0)); |
501 | 4 | return Ok(Ascii(v.into())); |
502 | | } else { |
503 | 0 | return Err(TiffError::FormatError(TiffFormatError::InvalidTag)); |
504 | | } |
505 | | } |
506 | | Type::UNDEFINED => { |
507 | | return Ok(List( |
508 | 9 | self.offset[0..self.count as usize] |
509 | 9 | .iter() |
510 | 25 | .map(|&b| Byte(b)) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#0}Line | Count | Source | 510 | 25 | .map(|&b| Byte(b)) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#0} |
511 | 9 | .collect(), |
512 | | )); |
513 | | } |
514 | | Type::SHORT => { |
515 | 13 | let mut r = self.r(bo); |
516 | 13 | let mut v = Vec::new(); |
517 | 13 | for _ in 0..self.count { |
518 | 27 | v.push(Short(r.read_u16()?)); |
519 | | } |
520 | 13 | return Ok(List(v)); |
521 | | } |
522 | | Type::SSHORT => { |
523 | 0 | let mut r = self.r(bo); |
524 | 0 | let mut v = Vec::new(); |
525 | 0 | for _ in 0..self.count { |
526 | 0 | v.push(SignedShort(r.read_i16()?)); |
527 | | } |
528 | 0 | return Ok(List(v)); |
529 | | } |
530 | | Type::LONG => { |
531 | 0 | let mut r = self.r(bo); |
532 | 0 | let mut v = Vec::new(); |
533 | 0 | for _ in 0..self.count { |
534 | 0 | v.push(Unsigned(r.read_u32()?)); |
535 | | } |
536 | 0 | return Ok(List(v)); |
537 | | } |
538 | | Type::SLONG => { |
539 | 0 | let mut r = self.r(bo); |
540 | 0 | let mut v = Vec::new(); |
541 | 0 | for _ in 0..self.count { |
542 | 0 | v.push(Signed(r.read_i32()?)); |
543 | | } |
544 | 0 | return Ok(List(v)); |
545 | | } |
546 | | Type::FLOAT => { |
547 | 0 | let mut r = self.r(bo); |
548 | 0 | let mut v = Vec::new(); |
549 | 0 | for _ in 0..self.count { |
550 | 0 | v.push(Float(r.read_f32()?)); |
551 | | } |
552 | 0 | return Ok(List(v)); |
553 | | } |
554 | | Type::IFD => { |
555 | 0 | let mut r = self.r(bo); |
556 | 0 | let mut v = Vec::new(); |
557 | 0 | for _ in 0..self.count { |
558 | 0 | v.push(Ifd(r.read_u32()?)); |
559 | | } |
560 | 0 | return Ok(List(v)); |
561 | | } |
562 | | Type::LONG8 |
563 | | | Type::SLONG8 |
564 | | | Type::RATIONAL |
565 | | | Type::SRATIONAL |
566 | | | Type::DOUBLE |
567 | | | Type::IFD8 => { |
568 | 0 | unreachable!() |
569 | | } |
570 | | } |
571 | 8.35k | } |
572 | | |
573 | | // Case 4: there is more than one value, and it doesn't fit in the offset field. |
574 | 8.35k | match self.type_ { |
575 | | // TODO check if this could give wrong results |
576 | | // at a different endianess of file/computer. |
577 | 531k | Type::BYTE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
578 | 531k | let mut buf = [0; 1]; |
579 | 531k | reader.inner().read_exact(&mut buf)?; |
580 | 531k | Ok(Byte(buf[0])) |
581 | 531k | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#1}Line | Count | Source | 577 | 531k | Type::BYTE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 578 | 531k | let mut buf = [0; 1]; | 579 | 531k | reader.inner().read_exact(&mut buf)?; | 580 | 531k | Ok(Byte(buf[0])) | 581 | 531k | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#1} |
582 | 265 | Type::SBYTE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
583 | 265 | Ok(SignedByte(reader.read_i8()?)) |
584 | 265 | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#2}Line | Count | Source | 582 | 265 | Type::SBYTE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 583 | 265 | Ok(SignedByte(reader.read_i8()?)) | 584 | 265 | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#2} |
585 | 790k | Type::SHORT => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
586 | 790k | Ok(Short(reader.read_u16()?)) |
587 | 790k | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#3}Line | Count | Source | 585 | 790k | Type::SHORT => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 586 | 790k | Ok(Short(reader.read_u16()?)) | 587 | 790k | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#3} |
588 | 732 | Type::SSHORT => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
589 | 732 | Ok(SignedShort(reader.read_i16()?)) |
590 | 732 | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#4}Line | Count | Source | 588 | 732 | Type::SSHORT => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 589 | 732 | Ok(SignedShort(reader.read_i16()?)) | 590 | 732 | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#4} |
591 | 325k | Type::LONG => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
592 | 325k | Ok(Unsigned(reader.read_u32()?)) |
593 | 325k | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#5}Line | Count | Source | 591 | 325k | Type::LONG => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 592 | 325k | Ok(Unsigned(reader.read_u32()?)) | 593 | 325k | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#5} |
594 | 132 | Type::SLONG => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
595 | 132 | Ok(Signed(reader.read_i32()?)) |
596 | 132 | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#6}Line | Count | Source | 594 | 132 | Type::SLONG => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 595 | 132 | Ok(Signed(reader.read_i32()?)) | 596 | 132 | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#6} |
597 | 157 | Type::FLOAT => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
598 | 157 | Ok(Float(reader.read_f32()?)) |
599 | 157 | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#7}Line | Count | Source | 597 | 157 | Type::FLOAT => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 598 | 157 | Ok(Float(reader.read_f32()?)) | 599 | 157 | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#7} |
600 | 291 | Type::DOUBLE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
601 | 291 | Ok(Double(reader.read_f64()?)) |
602 | 291 | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#8}Line | Count | Source | 600 | 291 | Type::DOUBLE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 601 | 291 | Ok(Double(reader.read_f64()?)) | 602 | 291 | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#8} |
603 | | Type::RATIONAL => { |
604 | 833 | self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
605 | 833 | Ok(Rational(reader.read_u32()?, reader.read_u32()?)) |
606 | 833 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#9}Line | Count | Source | 604 | 833 | self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 605 | 833 | Ok(Rational(reader.read_u32()?, reader.read_u32()?)) | 606 | 833 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#9} |
607 | | } |
608 | | Type::SRATIONAL => { |
609 | 829 | self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
610 | 829 | Ok(SRational(reader.read_i32()?, reader.read_i32()?)) |
611 | 829 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#10}Line | Count | Source | 609 | 829 | self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 610 | 829 | Ok(SRational(reader.read_i32()?, reader.read_i32()?)) | 611 | 829 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#10} |
612 | | } |
613 | 12.5k | Type::LONG8 => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
614 | 12.5k | Ok(UnsignedBig(reader.read_u64()?)) |
615 | 12.5k | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#11}Line | Count | Source | 613 | 12.5k | Type::LONG8 => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 614 | 12.5k | Ok(UnsignedBig(reader.read_u64()?)) | 615 | 12.5k | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#11} |
616 | 337 | Type::SLONG8 => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
617 | 337 | Ok(SignedBig(reader.read_i64()?)) |
618 | 337 | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#12}Line | Count | Source | 616 | 337 | Type::SLONG8 => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 617 | 337 | Ok(SignedBig(reader.read_i64()?)) | 618 | 337 | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#12} |
619 | 956 | Type::IFD => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
620 | 956 | Ok(Ifd(reader.read_u32()?)) |
621 | 956 | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#13}Line | Count | Source | 619 | 956 | Type::IFD => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 620 | 956 | Ok(Ifd(reader.read_u32()?)) | 621 | 956 | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#13} |
622 | 1.57k | Type::IFD8 => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
623 | 1.57k | Ok(IfdBig(reader.read_u64()?)) |
624 | 1.57k | }), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#14}Line | Count | Source | 622 | 1.57k | Type::IFD8 => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 623 | 1.57k | Ok(IfdBig(reader.read_u64()?)) | 624 | 1.57k | }), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#14} |
625 | | Type::UNDEFINED => { |
626 | 1.30M | self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { |
627 | 1.30M | let mut buf = [0; 1]; |
628 | 1.30M | reader.inner().read_exact(&mut buf)?; |
629 | 1.30M | Ok(Byte(buf[0])) |
630 | 1.30M | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#15}Line | Count | Source | 626 | 1.30M | self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 627 | 1.30M | let mut buf = [0; 1]; | 628 | 1.30M | reader.inner().read_exact(&mut buf)?; | 629 | 1.30M | Ok(Byte(buf[0])) | 630 | 1.30M | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#15} |
631 | | } |
632 | | Type::ASCII => { |
633 | 91 | let n = usize::try_from(self.count)?; |
634 | 91 | if n > limits.decoding_buffer_size { |
635 | 1 | return Err(TiffError::LimitsExceeded); |
636 | 90 | } |
637 | | |
638 | 90 | if bigtiff { |
639 | 0 | reader.goto_offset(self.r(bo).read_u64()?)? |
640 | | } else { |
641 | 90 | reader.goto_offset(self.r(bo).read_u32()?.into())? |
642 | | } |
643 | | |
644 | 90 | let mut out = vec![0; n]; |
645 | 90 | reader.inner().read_exact(&mut out)?; |
646 | | // Strings may be null-terminated, so we trim anything downstream of the null byte |
647 | 106k | if let Some(first) = out.iter().position(|&b| b == 0) {<tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#16}Line | Count | Source | 647 | 106k | if let Some(first) = out.iter().position(|&b| b == 0) { |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#16} |
648 | 74 | out.truncate(first); |
649 | 74 | } |
650 | 84 | Ok(Ascii(String::from_utf8(out)?)) |
651 | | } |
652 | | } |
653 | 78.7k | } <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>> Line | Count | Source | 383 | 78.7k | pub(crate) fn val<R: Read + Seek>( | 384 | 78.7k | &self, | 385 | 78.7k | limits: &super::Limits, | 386 | 78.7k | bigtiff: bool, | 387 | 78.7k | reader: &mut EndianReader<R>, | 388 | 78.7k | ) -> TiffResult<Value> { | 389 | | // Case 1: there are no values so we can return immediately. | 390 | 78.7k | if self.count == 0 { | 391 | 8 | return Ok(List(Vec::new())); | 392 | 78.7k | } | 393 | | | 394 | 78.7k | let bo = reader.byte_order; | 395 | | | 396 | 78.7k | let tag_size = match self.type_ { | 397 | 1.78k | Type::BYTE | Type::SBYTE | Type::ASCII | Type::UNDEFINED => 1, | 398 | 60.2k | Type::SHORT | Type::SSHORT => 2, | 399 | 16.3k | Type::LONG | Type::SLONG | Type::FLOAT | Type::IFD => 4, | 400 | | Type::LONG8 | 401 | | | Type::SLONG8 | 402 | | | Type::DOUBLE | 403 | | | Type::RATIONAL | 404 | | | Type::SRATIONAL | 405 | 321 | | Type::IFD8 => 8, | 406 | | }; | 407 | | | 408 | 78.7k | let value_bytes = match self.count.checked_mul(tag_size) { | 409 | 78.7k | Some(n) => n, | 410 | | None => { | 411 | 1 | return Err(TiffError::LimitsExceeded); | 412 | | } | 413 | | }; | 414 | | | 415 | | // Case 2: there is one value. | 416 | 78.7k | if self.count == 1 { | 417 | | // 2a: the value is 5-8 bytes and we're in BigTiff mode. | 418 | 70.3k | if bigtiff && value_bytes > 4 && value_bytes <= 8 { | 419 | 2 | return Ok(match self.type_ { | 420 | 2 | Type::LONG8 => UnsignedBig(self.r(bo).read_u64()?), | 421 | 0 | Type::SLONG8 => SignedBig(self.r(bo).read_i64()?), | 422 | 0 | Type::DOUBLE => Double(self.r(bo).read_f64()?), | 423 | | Type::RATIONAL => { | 424 | 0 | let mut r = self.r(bo); | 425 | 0 | Rational(r.read_u32()?, r.read_u32()?) | 426 | | } | 427 | | Type::SRATIONAL => { | 428 | 0 | let mut r = self.r(bo); | 429 | 0 | SRational(r.read_i32()?, r.read_i32()?) | 430 | | } | 431 | 0 | Type::IFD8 => IfdBig(self.r(bo).read_u64()?), | 432 | | Type::BYTE | 433 | | | Type::SBYTE | 434 | | | Type::ASCII | 435 | | | Type::UNDEFINED | 436 | | | Type::SHORT | 437 | | | Type::SSHORT | 438 | | | Type::LONG | 439 | | | Type::SLONG | 440 | | | Type::FLOAT | 441 | 0 | | Type::IFD => unreachable!(), | 442 | | }); | 443 | 70.3k | } | 444 | | | 445 | | // 2b: the value is at most 4 bytes or doesn't fit in the offset field. | 446 | 70.3k | return Ok(match self.type_ { | 447 | 224 | Type::BYTE => Byte(self.offset[0]), | 448 | 2 | Type::SBYTE => SignedByte(self.offset[0] as i8), | 449 | 33 | Type::UNDEFINED => Byte(self.offset[0]), | 450 | 57.7k | Type::SHORT => Short(self.r(bo).read_u16()?), | 451 | 1 | Type::SSHORT => SignedShort(self.r(bo).read_i16()?), | 452 | 12.1k | Type::LONG => Unsigned(self.r(bo).read_u32()?), | 453 | 0 | Type::SLONG => Signed(self.r(bo).read_i32()?), | 454 | 0 | Type::FLOAT => Float(self.r(bo).read_f32()?), | 455 | | Type::ASCII => { | 456 | 1 | if self.offset[0] == 0 { | 457 | 1 | Ascii("".to_string()) | 458 | | } else { | 459 | 0 | return Err(TiffError::FormatError(TiffFormatError::InvalidTag)); | 460 | | } | 461 | | } | 462 | | Type::LONG8 => { | 463 | 70 | reader.goto_offset(self.r(bo).read_u32()?.into())?; | 464 | 70 | UnsignedBig(reader.read_u64()?) | 465 | | } | 466 | | Type::SLONG8 => { | 467 | 0 | reader.goto_offset(self.r(bo).read_u32()?.into())?; | 468 | 0 | SignedBig(reader.read_i64()?) | 469 | | } | 470 | | Type::DOUBLE => { | 471 | 1 | reader.goto_offset(self.r(bo).read_u32()?.into())?; | 472 | 1 | Double(reader.read_f64()?) | 473 | | } | 474 | | Type::RATIONAL => { | 475 | 4 | reader.goto_offset(self.r(bo).read_u32()?.into())?; | 476 | 4 | Rational(reader.read_u32()?, reader.read_u32()?) | 477 | | } | 478 | | Type::SRATIONAL => { | 479 | 1 | reader.goto_offset(self.r(bo).read_u32()?.into())?; | 480 | 1 | SRational(reader.read_i32()?, reader.read_i32()?) | 481 | | } | 482 | 22 | Type::IFD => Ifd(self.r(bo).read_u32()?), | 483 | | Type::IFD8 => { | 484 | 72 | reader.goto_offset(self.r(bo).read_u32()?.into())?; | 485 | 72 | IfdBig(reader.read_u64()?) | 486 | | } | 487 | | }); | 488 | 8.40k | } | 489 | | | 490 | | // Case 3: There is more than one value, but it fits in the offset field. | 491 | 8.40k | if value_bytes <= 4 || bigtiff && value_bytes <= 8 { | 492 | 48 | match self.type_ { | 493 | 22 | Type::BYTE => return offset_to_bytes(self.count as usize, self), | 494 | 0 | Type::SBYTE => return offset_to_sbytes(self.count as usize, self), | 495 | | Type::ASCII => { | 496 | 4 | let mut buf = vec![0; self.count as usize]; | 497 | 4 | buf.copy_from_slice(&self.offset[..self.count as usize]); | 498 | 4 | if buf.is_ascii() && buf.ends_with(&[0]) { | 499 | 4 | let v = str::from_utf8(&buf)?; | 500 | 4 | let v = v.trim_matches(char::from(0)); | 501 | 4 | return Ok(Ascii(v.into())); | 502 | | } else { | 503 | 0 | return Err(TiffError::FormatError(TiffFormatError::InvalidTag)); | 504 | | } | 505 | | } | 506 | | Type::UNDEFINED => { | 507 | | return Ok(List( | 508 | 9 | self.offset[0..self.count as usize] | 509 | 9 | .iter() | 510 | 9 | .map(|&b| Byte(b)) | 511 | 9 | .collect(), | 512 | | )); | 513 | | } | 514 | | Type::SHORT => { | 515 | 13 | let mut r = self.r(bo); | 516 | 13 | let mut v = Vec::new(); | 517 | 13 | for _ in 0..self.count { | 518 | 27 | v.push(Short(r.read_u16()?)); | 519 | | } | 520 | 13 | return Ok(List(v)); | 521 | | } | 522 | | Type::SSHORT => { | 523 | 0 | let mut r = self.r(bo); | 524 | 0 | let mut v = Vec::new(); | 525 | 0 | for _ in 0..self.count { | 526 | 0 | v.push(SignedShort(r.read_i16()?)); | 527 | | } | 528 | 0 | return Ok(List(v)); | 529 | | } | 530 | | Type::LONG => { | 531 | 0 | let mut r = self.r(bo); | 532 | 0 | let mut v = Vec::new(); | 533 | 0 | for _ in 0..self.count { | 534 | 0 | v.push(Unsigned(r.read_u32()?)); | 535 | | } | 536 | 0 | return Ok(List(v)); | 537 | | } | 538 | | Type::SLONG => { | 539 | 0 | let mut r = self.r(bo); | 540 | 0 | let mut v = Vec::new(); | 541 | 0 | for _ in 0..self.count { | 542 | 0 | v.push(Signed(r.read_i32()?)); | 543 | | } | 544 | 0 | return Ok(List(v)); | 545 | | } | 546 | | Type::FLOAT => { | 547 | 0 | let mut r = self.r(bo); | 548 | 0 | let mut v = Vec::new(); | 549 | 0 | for _ in 0..self.count { | 550 | 0 | v.push(Float(r.read_f32()?)); | 551 | | } | 552 | 0 | return Ok(List(v)); | 553 | | } | 554 | | Type::IFD => { | 555 | 0 | let mut r = self.r(bo); | 556 | 0 | let mut v = Vec::new(); | 557 | 0 | for _ in 0..self.count { | 558 | 0 | v.push(Ifd(r.read_u32()?)); | 559 | | } | 560 | 0 | return Ok(List(v)); | 561 | | } | 562 | | Type::LONG8 | 563 | | | Type::SLONG8 | 564 | | | Type::RATIONAL | 565 | | | Type::SRATIONAL | 566 | | | Type::DOUBLE | 567 | | | Type::IFD8 => { | 568 | 0 | unreachable!() | 569 | | } | 570 | | } | 571 | 8.35k | } | 572 | | | 573 | | // Case 4: there is more than one value, and it doesn't fit in the offset field. | 574 | 8.35k | match self.type_ { | 575 | | // TODO check if this could give wrong results | 576 | | // at a different endianess of file/computer. | 577 | 64 | Type::BYTE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 578 | | let mut buf = [0; 1]; | 579 | | reader.inner().read_exact(&mut buf)?; | 580 | | Ok(Byte(buf[0])) | 581 | | }), | 582 | 6 | Type::SBYTE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 583 | | Ok(SignedByte(reader.read_i8()?)) | 584 | | }), | 585 | 2.54k | Type::SHORT => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 586 | | Ok(Short(reader.read_u16()?)) | 587 | | }), | 588 | 16 | Type::SSHORT => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 589 | | Ok(SignedShort(reader.read_i16()?)) | 590 | | }), | 591 | 4.12k | Type::LONG => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 592 | | Ok(Unsigned(reader.read_u32()?)) | 593 | | }), | 594 | 2 | Type::SLONG => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 595 | | Ok(Signed(reader.read_i32()?)) | 596 | | }), | 597 | 5 | Type::FLOAT => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 598 | | Ok(Float(reader.read_f32()?)) | 599 | | }), | 600 | 5 | Type::DOUBLE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 601 | | Ok(Double(reader.read_f64()?)) | 602 | | }), | 603 | | Type::RATIONAL => { | 604 | 13 | self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 605 | | Ok(Rational(reader.read_u32()?, reader.read_u32()?)) | 606 | | }) | 607 | | } | 608 | | Type::SRATIONAL => { | 609 | 14 | self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 610 | | Ok(SRational(reader.read_i32()?, reader.read_i32()?)) | 611 | | }) | 612 | | } | 613 | 74 | Type::LONG8 => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 614 | | Ok(UnsignedBig(reader.read_u64()?)) | 615 | | }), | 616 | 7 | Type::SLONG8 => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 617 | | Ok(SignedBig(reader.read_i64()?)) | 618 | | }), | 619 | 17 | Type::IFD => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 620 | | Ok(Ifd(reader.read_u32()?)) | 621 | | }), | 622 | 58 | Type::IFD8 => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 623 | | Ok(IfdBig(reader.read_u64()?)) | 624 | | }), | 625 | | Type::UNDEFINED => { | 626 | 1.32k | self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| { | 627 | | let mut buf = [0; 1]; | 628 | | reader.inner().read_exact(&mut buf)?; | 629 | | Ok(Byte(buf[0])) | 630 | | }) | 631 | | } | 632 | | Type::ASCII => { | 633 | 91 | let n = usize::try_from(self.count)?; | 634 | 91 | if n > limits.decoding_buffer_size { | 635 | 1 | return Err(TiffError::LimitsExceeded); | 636 | 90 | } | 637 | | | 638 | 90 | if bigtiff { | 639 | 0 | reader.goto_offset(self.r(bo).read_u64()?)? | 640 | | } else { | 641 | 90 | reader.goto_offset(self.r(bo).read_u32()?.into())? | 642 | | } | 643 | | | 644 | 90 | let mut out = vec![0; n]; | 645 | 90 | reader.inner().read_exact(&mut out)?; | 646 | | // Strings may be null-terminated, so we trim anything downstream of the null byte | 647 | 84 | if let Some(first) = out.iter().position(|&b| b == 0) { | 648 | 74 | out.truncate(first); | 649 | 74 | } | 650 | 84 | Ok(Ascii(String::from_utf8(out)?)) | 651 | | } | 652 | | } | 653 | 78.7k | } |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_> |
654 | | |
655 | | #[inline] |
656 | 8.26k | fn decode_offset<R, F>( |
657 | 8.26k | &self, |
658 | 8.26k | value_count: u64, |
659 | 8.26k | bo: ByteOrder, |
660 | 8.26k | bigtiff: bool, |
661 | 8.26k | limits: &super::Limits, |
662 | 8.26k | reader: &mut EndianReader<R>, |
663 | 8.26k | decode_fn: F, |
664 | 8.26k | ) -> TiffResult<Value> |
665 | 8.26k | where |
666 | 8.26k | R: Read + Seek, |
667 | 8.26k | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, |
668 | | { |
669 | 8.26k | let value_count = usize::try_from(value_count)?; |
670 | 8.26k | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { |
671 | 80 | return Err(TiffError::LimitsExceeded); |
672 | 8.18k | } |
673 | | |
674 | 8.18k | let mut v = Vec::with_capacity(value_count); |
675 | | |
676 | 8.18k | let offset = if bigtiff { |
677 | 11 | self.r(bo).read_u64()? |
678 | | } else { |
679 | 8.17k | self.r(bo).read_u32()?.into() |
680 | | }; |
681 | 8.18k | reader.goto_offset(offset)?; |
682 | | |
683 | 8.18k | for _ in 0..value_count { |
684 | 2.97M | v.push(decode_fn(reader)?) |
685 | | } |
686 | 8.07k | Ok(List(v)) |
687 | 8.26k | } <tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#2}>Line | Count | Source | 656 | 6 | fn decode_offset<R, F>( | 657 | 6 | &self, | 658 | 6 | value_count: u64, | 659 | 6 | bo: ByteOrder, | 660 | 6 | bigtiff: bool, | 661 | 6 | limits: &super::Limits, | 662 | 6 | reader: &mut EndianReader<R>, | 663 | 6 | decode_fn: F, | 664 | 6 | ) -> TiffResult<Value> | 665 | 6 | where | 666 | 6 | R: Read + Seek, | 667 | 6 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 6 | let value_count = usize::try_from(value_count)?; | 670 | 6 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 3 | return Err(TiffError::LimitsExceeded); | 672 | 3 | } | 673 | | | 674 | 3 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 3 | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 3 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 3 | reader.goto_offset(offset)?; | 682 | | | 683 | 3 | for _ in 0..value_count { | 684 | 265 | v.push(decode_fn(reader)?) | 685 | | } | 686 | 2 | Ok(List(v)) | 687 | 6 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#3}>Line | Count | Source | 656 | 2.54k | fn decode_offset<R, F>( | 657 | 2.54k | &self, | 658 | 2.54k | value_count: u64, | 659 | 2.54k | bo: ByteOrder, | 660 | 2.54k | bigtiff: bool, | 661 | 2.54k | limits: &super::Limits, | 662 | 2.54k | reader: &mut EndianReader<R>, | 663 | 2.54k | decode_fn: F, | 664 | 2.54k | ) -> TiffResult<Value> | 665 | 2.54k | where | 666 | 2.54k | R: Read + Seek, | 667 | 2.54k | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 2.54k | let value_count = usize::try_from(value_count)?; | 670 | 2.54k | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 15 | return Err(TiffError::LimitsExceeded); | 672 | 2.52k | } | 673 | | | 674 | 2.52k | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 2.52k | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 2.52k | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 2.52k | reader.goto_offset(offset)?; | 682 | | | 683 | 2.52k | for _ in 0..value_count { | 684 | 790k | v.push(decode_fn(reader)?) | 685 | | } | 686 | 2.50k | Ok(List(v)) | 687 | 2.54k | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#4}>Line | Count | Source | 656 | 16 | fn decode_offset<R, F>( | 657 | 16 | &self, | 658 | 16 | value_count: u64, | 659 | 16 | bo: ByteOrder, | 660 | 16 | bigtiff: bool, | 661 | 16 | limits: &super::Limits, | 662 | 16 | reader: &mut EndianReader<R>, | 663 | 16 | decode_fn: F, | 664 | 16 | ) -> TiffResult<Value> | 665 | 16 | where | 666 | 16 | R: Read + Seek, | 667 | 16 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 16 | let value_count = usize::try_from(value_count)?; | 670 | 16 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 11 | return Err(TiffError::LimitsExceeded); | 672 | 5 | } | 673 | | | 674 | 5 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 5 | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 5 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 5 | reader.goto_offset(offset)?; | 682 | | | 683 | 5 | for _ in 0..value_count { | 684 | 732 | v.push(decode_fn(reader)?) | 685 | | } | 686 | 1 | Ok(List(v)) | 687 | 16 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#5}>Line | Count | Source | 656 | 4.12k | fn decode_offset<R, F>( | 657 | 4.12k | &self, | 658 | 4.12k | value_count: u64, | 659 | 4.12k | bo: ByteOrder, | 660 | 4.12k | bigtiff: bool, | 661 | 4.12k | limits: &super::Limits, | 662 | 4.12k | reader: &mut EndianReader<R>, | 663 | 4.12k | decode_fn: F, | 664 | 4.12k | ) -> TiffResult<Value> | 665 | 4.12k | where | 666 | 4.12k | R: Read + Seek, | 667 | 4.12k | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 4.12k | let value_count = usize::try_from(value_count)?; | 670 | 4.12k | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 22 | return Err(TiffError::LimitsExceeded); | 672 | 4.09k | } | 673 | | | 674 | 4.09k | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 4.09k | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 4.09k | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 4.09k | reader.goto_offset(offset)?; | 682 | | | 683 | 4.09k | for _ in 0..value_count { | 684 | 325k | v.push(decode_fn(reader)?) | 685 | | } | 686 | 4.07k | Ok(List(v)) | 687 | 4.12k | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#6}>Line | Count | Source | 656 | 2 | fn decode_offset<R, F>( | 657 | 2 | &self, | 658 | 2 | value_count: u64, | 659 | 2 | bo: ByteOrder, | 660 | 2 | bigtiff: bool, | 661 | 2 | limits: &super::Limits, | 662 | 2 | reader: &mut EndianReader<R>, | 663 | 2 | decode_fn: F, | 664 | 2 | ) -> TiffResult<Value> | 665 | 2 | where | 666 | 2 | R: Read + Seek, | 667 | 2 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 2 | let value_count = usize::try_from(value_count)?; | 670 | 2 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 0 | return Err(TiffError::LimitsExceeded); | 672 | 2 | } | 673 | | | 674 | 2 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 2 | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 2 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 2 | reader.goto_offset(offset)?; | 682 | | | 683 | 2 | for _ in 0..value_count { | 684 | 132 | v.push(decode_fn(reader)?) | 685 | | } | 686 | 1 | Ok(List(v)) | 687 | 2 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#7}>Line | Count | Source | 656 | 5 | fn decode_offset<R, F>( | 657 | 5 | &self, | 658 | 5 | value_count: u64, | 659 | 5 | bo: ByteOrder, | 660 | 5 | bigtiff: bool, | 661 | 5 | limits: &super::Limits, | 662 | 5 | reader: &mut EndianReader<R>, | 663 | 5 | decode_fn: F, | 664 | 5 | ) -> TiffResult<Value> | 665 | 5 | where | 666 | 5 | R: Read + Seek, | 667 | 5 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 5 | let value_count = usize::try_from(value_count)?; | 670 | 5 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 2 | return Err(TiffError::LimitsExceeded); | 672 | 3 | } | 673 | | | 674 | 3 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 3 | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 3 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 3 | reader.goto_offset(offset)?; | 682 | | | 683 | 3 | for _ in 0..value_count { | 684 | 157 | v.push(decode_fn(reader)?) | 685 | | } | 686 | 2 | Ok(List(v)) | 687 | 5 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#8}>Line | Count | Source | 656 | 5 | fn decode_offset<R, F>( | 657 | 5 | &self, | 658 | 5 | value_count: u64, | 659 | 5 | bo: ByteOrder, | 660 | 5 | bigtiff: bool, | 661 | 5 | limits: &super::Limits, | 662 | 5 | reader: &mut EndianReader<R>, | 663 | 5 | decode_fn: F, | 664 | 5 | ) -> TiffResult<Value> | 665 | 5 | where | 666 | 5 | R: Read + Seek, | 667 | 5 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 5 | let value_count = usize::try_from(value_count)?; | 670 | 5 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 2 | return Err(TiffError::LimitsExceeded); | 672 | 3 | } | 673 | | | 674 | 3 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 3 | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 3 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 3 | reader.goto_offset(offset)?; | 682 | | | 683 | 3 | for _ in 0..value_count { | 684 | 291 | v.push(decode_fn(reader)?) | 685 | | } | 686 | 0 | Ok(List(v)) | 687 | 5 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#9}>Line | Count | Source | 656 | 13 | fn decode_offset<R, F>( | 657 | 13 | &self, | 658 | 13 | value_count: u64, | 659 | 13 | bo: ByteOrder, | 660 | 13 | bigtiff: bool, | 661 | 13 | limits: &super::Limits, | 662 | 13 | reader: &mut EndianReader<R>, | 663 | 13 | decode_fn: F, | 664 | 13 | ) -> TiffResult<Value> | 665 | 13 | where | 666 | 13 | R: Read + Seek, | 667 | 13 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 13 | let value_count = usize::try_from(value_count)?; | 670 | 13 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 0 | return Err(TiffError::LimitsExceeded); | 672 | 13 | } | 673 | | | 674 | 13 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 13 | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 13 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 13 | reader.goto_offset(offset)?; | 682 | | | 683 | 13 | for _ in 0..value_count { | 684 | 833 | v.push(decode_fn(reader)?) | 685 | | } | 686 | 2 | Ok(List(v)) | 687 | 13 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#10}>Line | Count | Source | 656 | 14 | fn decode_offset<R, F>( | 657 | 14 | &self, | 658 | 14 | value_count: u64, | 659 | 14 | bo: ByteOrder, | 660 | 14 | bigtiff: bool, | 661 | 14 | limits: &super::Limits, | 662 | 14 | reader: &mut EndianReader<R>, | 663 | 14 | decode_fn: F, | 664 | 14 | ) -> TiffResult<Value> | 665 | 14 | where | 666 | 14 | R: Read + Seek, | 667 | 14 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 14 | let value_count = usize::try_from(value_count)?; | 670 | 14 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 4 | return Err(TiffError::LimitsExceeded); | 672 | 10 | } | 673 | | | 674 | 10 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 10 | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 10 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 10 | reader.goto_offset(offset)?; | 682 | | | 683 | 10 | for _ in 0..value_count { | 684 | 829 | v.push(decode_fn(reader)?) | 685 | | } | 686 | 1 | Ok(List(v)) | 687 | 14 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#11}>Line | Count | Source | 656 | 74 | fn decode_offset<R, F>( | 657 | 74 | &self, | 658 | 74 | value_count: u64, | 659 | 74 | bo: ByteOrder, | 660 | 74 | bigtiff: bool, | 661 | 74 | limits: &super::Limits, | 662 | 74 | reader: &mut EndianReader<R>, | 663 | 74 | decode_fn: F, | 664 | 74 | ) -> TiffResult<Value> | 665 | 74 | where | 666 | 74 | R: Read + Seek, | 667 | 74 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 74 | let value_count = usize::try_from(value_count)?; | 670 | 74 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 5 | return Err(TiffError::LimitsExceeded); | 672 | 69 | } | 673 | | | 674 | 69 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 69 | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 69 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 69 | reader.goto_offset(offset)?; | 682 | | | 683 | 69 | for _ in 0..value_count { | 684 | 12.5k | v.push(decode_fn(reader)?) | 685 | | } | 686 | 65 | Ok(List(v)) | 687 | 74 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#1}>Line | Count | Source | 656 | 64 | fn decode_offset<R, F>( | 657 | 64 | &self, | 658 | 64 | value_count: u64, | 659 | 64 | bo: ByteOrder, | 660 | 64 | bigtiff: bool, | 661 | 64 | limits: &super::Limits, | 662 | 64 | reader: &mut EndianReader<R>, | 663 | 64 | decode_fn: F, | 664 | 64 | ) -> TiffResult<Value> | 665 | 64 | where | 666 | 64 | R: Read + Seek, | 667 | 64 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 64 | let value_count = usize::try_from(value_count)?; | 670 | 64 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 8 | return Err(TiffError::LimitsExceeded); | 672 | 56 | } | 673 | | | 674 | 56 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 56 | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 56 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 56 | reader.goto_offset(offset)?; | 682 | | | 683 | 56 | for _ in 0..value_count { | 684 | 531k | v.push(decode_fn(reader)?) | 685 | | } | 686 | 51 | Ok(List(v)) | 687 | 64 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#12}>Line | Count | Source | 656 | 7 | fn decode_offset<R, F>( | 657 | 7 | &self, | 658 | 7 | value_count: u64, | 659 | 7 | bo: ByteOrder, | 660 | 7 | bigtiff: bool, | 661 | 7 | limits: &super::Limits, | 662 | 7 | reader: &mut EndianReader<R>, | 663 | 7 | decode_fn: F, | 664 | 7 | ) -> TiffResult<Value> | 665 | 7 | where | 666 | 7 | R: Read + Seek, | 667 | 7 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 7 | let value_count = usize::try_from(value_count)?; | 670 | 7 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 3 | return Err(TiffError::LimitsExceeded); | 672 | 4 | } | 673 | | | 674 | 4 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 4 | let offset = if bigtiff { | 677 | 1 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 3 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 4 | reader.goto_offset(offset)?; | 682 | | | 683 | 4 | for _ in 0..value_count { | 684 | 337 | v.push(decode_fn(reader)?) | 685 | | } | 686 | 0 | Ok(List(v)) | 687 | 7 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#13}>Line | Count | Source | 656 | 17 | fn decode_offset<R, F>( | 657 | 17 | &self, | 658 | 17 | value_count: u64, | 659 | 17 | bo: ByteOrder, | 660 | 17 | bigtiff: bool, | 661 | 17 | limits: &super::Limits, | 662 | 17 | reader: &mut EndianReader<R>, | 663 | 17 | decode_fn: F, | 664 | 17 | ) -> TiffResult<Value> | 665 | 17 | where | 666 | 17 | R: Read + Seek, | 667 | 17 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 17 | let value_count = usize::try_from(value_count)?; | 670 | 17 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 1 | return Err(TiffError::LimitsExceeded); | 672 | 16 | } | 673 | | | 674 | 16 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 16 | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 16 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 16 | reader.goto_offset(offset)?; | 682 | | | 683 | 16 | for _ in 0..value_count { | 684 | 956 | v.push(decode_fn(reader)?) | 685 | | } | 686 | 14 | Ok(List(v)) | 687 | 17 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#14}>Line | Count | Source | 656 | 58 | fn decode_offset<R, F>( | 657 | 58 | &self, | 658 | 58 | value_count: u64, | 659 | 58 | bo: ByteOrder, | 660 | 58 | bigtiff: bool, | 661 | 58 | limits: &super::Limits, | 662 | 58 | reader: &mut EndianReader<R>, | 663 | 58 | decode_fn: F, | 664 | 58 | ) -> TiffResult<Value> | 665 | 58 | where | 666 | 58 | R: Read + Seek, | 667 | 58 | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 58 | let value_count = usize::try_from(value_count)?; | 670 | 58 | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 2 | return Err(TiffError::LimitsExceeded); | 672 | 56 | } | 673 | | | 674 | 56 | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 56 | let offset = if bigtiff { | 677 | 0 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 56 | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 56 | reader.goto_offset(offset)?; | 682 | | | 683 | 56 | for _ in 0..value_count { | 684 | 1.57k | v.push(decode_fn(reader)?) | 685 | | } | 686 | 53 | Ok(List(v)) | 687 | 58 | } |
<tiff::decoder::ifd::Entry>::decode_offset::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#15}>Line | Count | Source | 656 | 1.32k | fn decode_offset<R, F>( | 657 | 1.32k | &self, | 658 | 1.32k | value_count: u64, | 659 | 1.32k | bo: ByteOrder, | 660 | 1.32k | bigtiff: bool, | 661 | 1.32k | limits: &super::Limits, | 662 | 1.32k | reader: &mut EndianReader<R>, | 663 | 1.32k | decode_fn: F, | 664 | 1.32k | ) -> TiffResult<Value> | 665 | 1.32k | where | 666 | 1.32k | R: Read + Seek, | 667 | 1.32k | F: Fn(&mut EndianReader<R>) -> TiffResult<Value>, | 668 | | { | 669 | 1.32k | let value_count = usize::try_from(value_count)?; | 670 | 1.32k | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { | 671 | 2 | return Err(TiffError::LimitsExceeded); | 672 | 1.32k | } | 673 | | | 674 | 1.32k | let mut v = Vec::with_capacity(value_count); | 675 | | | 676 | 1.32k | let offset = if bigtiff { | 677 | 10 | self.r(bo).read_u64()? | 678 | | } else { | 679 | 1.31k | self.r(bo).read_u32()?.into() | 680 | | }; | 681 | 1.32k | reader.goto_offset(offset)?; | 682 | | | 683 | 1.32k | for _ in 0..value_count { | 684 | 1.30M | v.push(decode_fn(reader)?) | 685 | | } | 686 | 1.30k | Ok(List(v)) | 687 | 1.32k | } |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::decode_offset::<_, _> |
688 | | } |
689 | | |
690 | | /// Extracts a list of BYTE tags stored in an offset |
691 | | #[inline] |
692 | 22 | fn offset_to_bytes(n: usize, entry: &Entry) -> TiffResult<Value> { |
693 | | Ok(List( |
694 | 22 | entry.offset[0..n] |
695 | 22 | .iter() |
696 | 78 | .map(|&e| Unsigned(u32::from(e))) tiff::decoder::ifd::offset_to_bytes::{closure#0}Line | Count | Source | 696 | 78 | .map(|&e| Unsigned(u32::from(e))) |
Unexecuted instantiation: tiff::decoder::ifd::offset_to_bytes::{closure#0} |
697 | 22 | .collect(), |
698 | | )) |
699 | 22 | } tiff::decoder::ifd::offset_to_bytes Line | Count | Source | 692 | 22 | fn offset_to_bytes(n: usize, entry: &Entry) -> TiffResult<Value> { | 693 | | Ok(List( | 694 | 22 | entry.offset[0..n] | 695 | 22 | .iter() | 696 | 22 | .map(|&e| Unsigned(u32::from(e))) | 697 | 22 | .collect(), | 698 | | )) | 699 | 22 | } |
Unexecuted instantiation: tiff::decoder::ifd::offset_to_bytes |
700 | | |
701 | | /// Extracts a list of SBYTE tags stored in an offset |
702 | | #[inline] |
703 | 0 | fn offset_to_sbytes(n: usize, entry: &Entry) -> TiffResult<Value> { |
704 | | Ok(List( |
705 | 0 | entry.offset[0..n] |
706 | 0 | .iter() |
707 | 0 | .map(|&e| Signed(i32::from(e as i8))) Unexecuted instantiation: tiff::decoder::ifd::offset_to_sbytes::{closure#0}Unexecuted instantiation: tiff::decoder::ifd::offset_to_sbytes::{closure#0} |
708 | 0 | .collect(), |
709 | | )) |
710 | 0 | } Unexecuted instantiation: tiff::decoder::ifd::offset_to_sbytes Unexecuted instantiation: tiff::decoder::ifd::offset_to_sbytes |
711 | | |
712 | | /// Type representing an Image File Directory |
713 | | #[doc(hidden)] |
714 | | #[deprecated = "Use struct `tiff::Directory` instead which contains all fields relevant to an Image File Directory, including the offset to the next directory"] |
715 | | pub type Directory = HashMap<Tag, Entry>; |