/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tiff-0.11.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, ValueBuffer}; |
10 | | use crate::{TiffError, TiffFormatError, TiffResult}; |
11 | | |
12 | | use self::Value::{ |
13 | | Ascii, Byte, Double, Float, Ifd, IfdBig, List, Rational, SRational, Short, Signed, SignedBig, |
14 | | 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 | | #[deprecated( |
34 | | note = "Not implemented in BigTIFF with a standard tag value", |
35 | | since = "0.11.1" |
36 | | )] |
37 | | RationalBig(u64, u64), |
38 | | SRational(i32, i32), |
39 | | #[deprecated( |
40 | | note = "Not implemented in BigTIFF with a standard tag value", |
41 | | since = "0.11.1" |
42 | | )] |
43 | | SRationalBig(i64, i64), |
44 | | Ascii(String), |
45 | | Ifd(u32), |
46 | | IfdBig(u64), |
47 | | } |
48 | | |
49 | | impl Value { |
50 | 2.96M | pub fn into_u8(self) -> TiffResult<u8> { |
51 | 2.96M | match self { |
52 | 2.96M | Byte(val) => Ok(val), |
53 | 3 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
54 | | } |
55 | 2.96M | } |
56 | 0 | pub fn into_i8(self) -> TiffResult<i8> { |
57 | 0 | match self { |
58 | 0 | SignedByte(val) => Ok(val), |
59 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
60 | | } |
61 | 0 | } |
62 | | |
63 | 27.1k | pub fn into_u16(self) -> TiffResult<u16> { |
64 | 27.1k | match self { |
65 | 1.92k | Byte(val) => Ok(val.into()), |
66 | 24.6k | Short(val) => Ok(val), |
67 | 246 | Unsigned(val) => Ok(u16::try_from(val)?), |
68 | 273 | UnsignedBig(val) => Ok(u16::try_from(val)?), |
69 | 29 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
70 | | } |
71 | 27.1k | } |
72 | | |
73 | 0 | pub fn into_i16(self) -> TiffResult<i16> { |
74 | 0 | match self { |
75 | 0 | SignedByte(val) => Ok(val.into()), |
76 | 0 | SignedShort(val) => Ok(val), |
77 | 0 | Signed(val) => Ok(i16::try_from(val)?), |
78 | 0 | SignedBig(val) => Ok(i16::try_from(val)?), |
79 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
80 | | } |
81 | 0 | } |
82 | | |
83 | 28.9k | pub fn into_u32(self) -> TiffResult<u32> { |
84 | 28.9k | match self { |
85 | 876 | Byte(val) => Ok(val.into()), |
86 | 26.9k | Short(val) => Ok(val.into()), |
87 | 538 | Unsigned(val) => Ok(val), |
88 | 93 | UnsignedBig(val) => Ok(u32::try_from(val)?), |
89 | 186 | Ifd(val) => Ok(val), |
90 | 79 | IfdBig(val) => Ok(u32::try_from(val)?), |
91 | 247 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
92 | | } |
93 | 28.9k | } |
94 | | |
95 | 0 | pub fn into_i32(self) -> TiffResult<i32> { |
96 | 0 | match self { |
97 | 0 | SignedByte(val) => Ok(val.into()), |
98 | 0 | SignedShort(val) => Ok(val.into()), |
99 | 0 | Signed(val) => Ok(val), |
100 | 0 | SignedBig(val) => Ok(i32::try_from(val)?), |
101 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
102 | | } |
103 | 0 | } |
104 | | |
105 | 1.40M | pub fn into_u64(self) -> TiffResult<u64> { |
106 | 1.40M | match self { |
107 | 816k | Byte(val) => Ok(val.into()), |
108 | 474k | Short(val) => Ok(val.into()), |
109 | 115k | Unsigned(val) => Ok(val.into()), |
110 | 1.52k | UnsignedBig(val) => Ok(val), |
111 | 509 | Ifd(val) => Ok(val.into()), |
112 | 2.67k | IfdBig(val) => Ok(val), |
113 | 24 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
114 | | } |
115 | 1.40M | } |
116 | | |
117 | 0 | pub fn into_i64(self) -> TiffResult<i64> { |
118 | 0 | match self { |
119 | 0 | SignedByte(val) => Ok(val.into()), |
120 | 0 | SignedShort(val) => Ok(val.into()), |
121 | 0 | Signed(val) => Ok(val.into()), |
122 | 0 | SignedBig(val) => Ok(val), |
123 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
124 | | } |
125 | 0 | } |
126 | | |
127 | 0 | pub fn into_f32(self) -> TiffResult<f32> { |
128 | 0 | match self { |
129 | 0 | Float(val) => Ok(val), |
130 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
131 | | } |
132 | 0 | } |
133 | | |
134 | 0 | pub fn into_f64(self) -> TiffResult<f64> { |
135 | 0 | match self { |
136 | 0 | Double(val) => Ok(val), |
137 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
138 | | } |
139 | 0 | } |
140 | | |
141 | | /// Turn this value into an `IfdPointer`. |
142 | | /// |
143 | | /// Notice that this does not take an argument, a 64-bit IFD is always allowed. If the |
144 | | /// difference is crucial and you do not want to be permissive you're expected to filter this |
145 | | /// out before. |
146 | | /// |
147 | | /// For compatibility the smaller sized tags should always be allowed i.e. you might use a |
148 | | /// non-bigtiff's directory and its tag types and move it straight to a bigtiff. For instance |
149 | | /// the SubIFD tag is defined as `LONG or IFD`: |
150 | | /// |
151 | | /// <https://web.archive.org/web/20181105221012/https://www.awaresystems.be/imaging/tiff/tifftags/subifds.html> |
152 | 0 | pub fn into_ifd_pointer(self) -> TiffResult<IfdPointer> { |
153 | 0 | match self { |
154 | 0 | Unsigned(val) | Ifd(val) => Ok(IfdPointer(val.into())), |
155 | 0 | IfdBig(val) => Ok(IfdPointer(val)), |
156 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
157 | | } |
158 | 0 | } |
159 | | |
160 | 0 | pub fn into_string(self) -> TiffResult<String> { |
161 | 0 | match self { |
162 | 0 | Ascii(val) => Ok(val), |
163 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
164 | | } |
165 | 0 | } |
166 | | |
167 | 0 | pub fn into_u32_vec(self) -> TiffResult<Vec<u32>> { |
168 | 0 | match self { |
169 | 0 | List(vec) => { |
170 | 0 | let mut new_vec = Vec::with_capacity(vec.len()); |
171 | 0 | for v in vec { |
172 | 0 | new_vec.push(v.into_u32()?) |
173 | | } |
174 | 0 | Ok(new_vec) |
175 | | } |
176 | 0 | Byte(val) => Ok(vec![val.into()]), |
177 | 0 | Short(val) => Ok(vec![val.into()]), |
178 | 0 | Unsigned(val) => Ok(vec![val]), |
179 | 0 | UnsignedBig(val) => Ok(vec![u32::try_from(val)?]), |
180 | 0 | Rational(numerator, denominator) => Ok(vec![numerator, denominator]), |
181 | | #[expect(deprecated)] |
182 | 0 | Value::RationalBig(numerator, denominator) => { |
183 | 0 | Ok(vec![u32::try_from(numerator)?, u32::try_from(denominator)?]) |
184 | | } |
185 | 0 | Ifd(val) => Ok(vec![val]), |
186 | 0 | IfdBig(val) => Ok(vec![u32::try_from(val)?]), |
187 | 0 | Ascii(val) => Ok(val.chars().map(u32::from).collect()), |
188 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
189 | | } |
190 | 0 | } |
191 | | |
192 | 4.44k | pub fn into_u8_vec(self) -> TiffResult<Vec<u8>> { |
193 | 4.44k | match self { |
194 | 4.44k | List(vec) => { |
195 | 4.44k | let mut new_vec = Vec::with_capacity(vec.len()); |
196 | 2.96M | for v in vec { |
197 | 2.96M | new_vec.push(v.into_u8()?) |
198 | | } |
199 | 4.43k | Ok(new_vec) |
200 | | } |
201 | 1 | Byte(val) => Ok(vec![val]), |
202 | | |
203 | 3 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
204 | | } |
205 | 4.44k | } |
206 | | |
207 | 311 | pub fn into_u16_vec(self) -> TiffResult<Vec<u16>> { |
208 | 311 | match self { |
209 | 157 | List(vec) => { |
210 | 157 | let mut new_vec = Vec::with_capacity(vec.len()); |
211 | 5.18k | for v in vec { |
212 | 5.14k | new_vec.push(v.into_u16()?) |
213 | | } |
214 | 40 | Ok(new_vec) |
215 | | } |
216 | 1 | Byte(val) => Ok(vec![val.into()]), |
217 | 152 | Short(val) => Ok(vec![val]), |
218 | 1 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
219 | | } |
220 | 311 | } |
221 | | |
222 | 0 | pub fn into_i32_vec(self) -> TiffResult<Vec<i32>> { |
223 | 0 | match self { |
224 | 0 | List(vec) => { |
225 | 0 | let mut new_vec = Vec::with_capacity(vec.len()); |
226 | 0 | for v in vec { |
227 | 0 | match v { |
228 | 0 | SRational(numerator, denominator) => { |
229 | 0 | new_vec.push(numerator); |
230 | 0 | new_vec.push(denominator); |
231 | 0 | } |
232 | | #[expect(deprecated)] |
233 | 0 | Value::SRationalBig(numerator, denominator) => { |
234 | 0 | new_vec.push(i32::try_from(numerator)?); |
235 | 0 | new_vec.push(i32::try_from(denominator)?); |
236 | | } |
237 | 0 | _ => new_vec.push(v.into_i32()?), |
238 | | } |
239 | | } |
240 | 0 | Ok(new_vec) |
241 | | } |
242 | 0 | SignedByte(val) => Ok(vec![val.into()]), |
243 | 0 | SignedShort(val) => Ok(vec![val.into()]), |
244 | 0 | Signed(val) => Ok(vec![val]), |
245 | 0 | SignedBig(val) => Ok(vec![i32::try_from(val)?]), |
246 | 0 | SRational(numerator, denominator) => Ok(vec![numerator, denominator]), |
247 | | #[expect(deprecated)] |
248 | 0 | Value::SRationalBig(numerator, denominator) => { |
249 | 0 | Ok(vec![i32::try_from(numerator)?, i32::try_from(denominator)?]) |
250 | | } |
251 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
252 | | } |
253 | 0 | } |
254 | | |
255 | 0 | pub fn into_f32_vec(self) -> TiffResult<Vec<f32>> { |
256 | 0 | match self { |
257 | 0 | List(vec) => { |
258 | 0 | let mut new_vec = Vec::with_capacity(vec.len()); |
259 | 0 | for v in vec { |
260 | 0 | new_vec.push(v.into_f32()?) |
261 | | } |
262 | 0 | Ok(new_vec) |
263 | | } |
264 | 0 | Float(val) => Ok(vec![val]), |
265 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
266 | | } |
267 | 0 | } |
268 | | |
269 | 0 | pub fn into_f64_vec(self) -> TiffResult<Vec<f64>> { |
270 | 0 | match self { |
271 | 0 | List(vec) => { |
272 | 0 | let mut new_vec = Vec::with_capacity(vec.len()); |
273 | 0 | for v in vec { |
274 | 0 | new_vec.push(v.into_f64()?) |
275 | | } |
276 | 0 | Ok(new_vec) |
277 | | } |
278 | 0 | Double(val) => Ok(vec![val]), |
279 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
280 | | } |
281 | 0 | } |
282 | | |
283 | 24.2k | pub fn into_u64_vec(self) -> TiffResult<Vec<u64>> { |
284 | 24.2k | match self { |
285 | 11.5k | List(vec) => { |
286 | 11.5k | let mut new_vec = Vec::with_capacity(vec.len()); |
287 | 1.42M | for v in vec { |
288 | 1.40M | new_vec.push(v.into_u64()?) |
289 | | } |
290 | 11.5k | Ok(new_vec) |
291 | | } |
292 | 368 | Byte(val) => Ok(vec![val.into()]), |
293 | 5.65k | Short(val) => Ok(vec![val.into()]), |
294 | 6.05k | Unsigned(val) => Ok(vec![val.into()]), |
295 | 329 | UnsignedBig(val) => Ok(vec![val]), |
296 | 5 | Rational(numerator, denominator) => Ok(vec![numerator.into(), denominator.into()]), |
297 | | #[expect(deprecated)] |
298 | 0 | Value::RationalBig(numerator, denominator) => Ok(vec![numerator, denominator]), |
299 | 65 | Ifd(val) => Ok(vec![val.into()]), |
300 | 86 | IfdBig(val) => Ok(vec![val]), |
301 | 164 | Ascii(val) => Ok(val.chars().map(u32::from).map(u64::from).collect()), |
302 | 5 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
303 | | } |
304 | 24.2k | } |
305 | | |
306 | 0 | pub fn into_i64_vec(self) -> TiffResult<Vec<i64>> { |
307 | 0 | match self { |
308 | 0 | List(vec) => { |
309 | 0 | let mut new_vec = Vec::with_capacity(vec.len()); |
310 | 0 | for v in vec { |
311 | 0 | match v { |
312 | 0 | SRational(numerator, denominator) => { |
313 | 0 | new_vec.push(numerator.into()); |
314 | 0 | new_vec.push(denominator.into()); |
315 | 0 | } |
316 | | #[expect(deprecated)] |
317 | 0 | Value::SRationalBig(numerator, denominator) => { |
318 | 0 | new_vec.push(numerator); |
319 | 0 | new_vec.push(denominator); |
320 | 0 | } |
321 | 0 | _ => new_vec.push(v.into_i64()?), |
322 | | } |
323 | | } |
324 | 0 | Ok(new_vec) |
325 | | } |
326 | 0 | SignedByte(val) => Ok(vec![val.into()]), |
327 | 0 | SignedShort(val) => Ok(vec![val.into()]), |
328 | 0 | Signed(val) => Ok(vec![val.into()]), |
329 | 0 | SignedBig(val) => Ok(vec![val]), |
330 | 0 | SRational(numerator, denominator) => Ok(vec![numerator.into(), denominator.into()]), |
331 | | #[expect(deprecated)] |
332 | 0 | Value::SRationalBig(numerator, denominator) => Ok(vec![numerator, denominator]), |
333 | 0 | _ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
334 | | } |
335 | 0 | } |
336 | | |
337 | 0 | pub fn into_ifd_vec(self) -> TiffResult<Vec<IfdPointer>> { |
338 | 0 | let vec = match self { |
339 | 0 | Unsigned(val) | Ifd(val) => return Ok(vec![IfdPointer(val.into())]), |
340 | 0 | IfdBig(val) => return Ok(vec![IfdPointer(val)]), |
341 | 0 | List(vec) => vec, |
342 | 0 | _ => return Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)), |
343 | | }; |
344 | | |
345 | 0 | vec.into_iter().map(Self::into_ifd_pointer).collect() |
346 | 0 | } |
347 | | } |
348 | | |
349 | | /// A combination of type, count, and offset. |
350 | | /// |
351 | | /// In a TIFF the data offset portion of an entry is used for inline data in case the length of the |
352 | | /// encoded value does not exceed the size of the offset field. Since the size of the offset field |
353 | | /// depends on the file kind (4 bytes for standard TIFF, 8 bytes for BigTIFF) the interpretation of |
354 | | /// this struct is only complete in combination with file metadata. |
355 | | #[derive(Clone)] |
356 | | pub struct Entry { |
357 | | type_: Type, |
358 | | count: u64, |
359 | | offset: [u8; 8], |
360 | | } |
361 | | |
362 | | impl ::std::fmt::Debug for Entry { |
363 | 0 | fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { |
364 | 0 | fmt.write_str(&format!( |
365 | 0 | "Entry {{ type_: {:?}, count: {:?}, offset: {:?} }}", |
366 | 0 | self.type_, self.count, &self.offset |
367 | 0 | )) |
368 | 0 | } |
369 | | } |
370 | | |
371 | | impl Entry { |
372 | | /// Create a new entry fit to be added to a standard TIFF IFD. |
373 | 210k | pub fn new(type_: Type, count: u32, offset: [u8; 4]) -> Entry { |
374 | 210k | let mut entry_off = [0u8; 8]; |
375 | 210k | entry_off[..4].copy_from_slice(&offset); |
376 | 210k | Entry::new_u64(type_, count.into(), entry_off) |
377 | 210k | } |
378 | | |
379 | | /// Create a new entry with data for a Big TIFF IFD. |
380 | 224k | pub fn new_u64(type_: Type, count: u64, offset: [u8; 8]) -> Entry { |
381 | 224k | Entry { |
382 | 224k | type_, |
383 | 224k | count, |
384 | 224k | offset, |
385 | 224k | } |
386 | 224k | } |
387 | | |
388 | 0 | pub fn field_type(&self) -> Type { |
389 | 0 | self.type_ |
390 | 0 | } |
391 | | |
392 | 0 | pub fn count(&self) -> u64 { |
393 | 0 | self.count |
394 | 0 | } |
395 | | |
396 | 0 | pub(crate) fn offset(&self) -> &[u8] { |
397 | 0 | &self.offset |
398 | 0 | } |
399 | | |
400 | | /// Returns a mem_reader for the offset/value field |
401 | 78.9k | pub(crate) fn offset_field_reader( |
402 | 78.9k | &self, |
403 | 78.9k | byte_order: ByteOrder, |
404 | 78.9k | ) -> EndianReader<io::Cursor<Vec<u8>>> { |
405 | 78.9k | EndianReader::new(io::Cursor::new(self.offset.to_vec()), byte_order) |
406 | 78.9k | } |
407 | | |
408 | 80.7k | pub(crate) fn val<R: Read + Seek>( |
409 | 80.7k | &self, |
410 | 80.7k | limits: &super::Limits, |
411 | 80.7k | bigtiff: bool, |
412 | 80.7k | reader: &mut EndianReader<R>, |
413 | 80.7k | ) -> TiffResult<Value> { |
414 | | // Case 1: there are no values so we can return immediately. |
415 | 80.7k | if self.count == 0 { |
416 | 25 | return Ok(List(Vec::new())); |
417 | 80.7k | } |
418 | | |
419 | 80.7k | let bo = reader.byte_order; |
420 | 80.7k | let value_bytes = self.type_.value_bytes(self.count)?; |
421 | | |
422 | | // Case 2: there is one value. |
423 | 80.7k | if self.count == 1 { |
424 | | // 2a: the value is 5-8 bytes and we're in BigTiff mode. |
425 | 63.4k | if bigtiff && value_bytes > 4 && value_bytes <= 8 { |
426 | 12 | return Ok(match self.type_ { |
427 | 7 | Type::LONG8 => UnsignedBig(self.offset_field_reader(bo).read_u64()?), |
428 | 1 | Type::SLONG8 => SignedBig(self.offset_field_reader(bo).read_i64()?), |
429 | 1 | Type::DOUBLE => Double(self.offset_field_reader(bo).read_f64()?), |
430 | | Type::RATIONAL => { |
431 | 1 | let mut r = self.offset_field_reader(bo); |
432 | 1 | Rational(r.read_u32()?, r.read_u32()?) |
433 | | } |
434 | | Type::SRATIONAL => { |
435 | 1 | let mut r = self.offset_field_reader(bo); |
436 | 1 | SRational(r.read_i32()?, r.read_i32()?) |
437 | | } |
438 | 1 | Type::IFD8 => IfdBig(self.offset_field_reader(bo).read_u64()?), |
439 | | Type::BYTE |
440 | | | Type::SBYTE |
441 | | | Type::ASCII |
442 | | | Type::UNDEFINED |
443 | | | Type::SHORT |
444 | | | Type::SSHORT |
445 | | | Type::LONG |
446 | | | Type::SLONG |
447 | | | Type::FLOAT |
448 | 0 | | Type::IFD => unreachable!(), |
449 | | }); |
450 | 63.4k | } |
451 | | |
452 | | // 2b: the value is at most 4 bytes or doesn't fit in the offset field. |
453 | 63.4k | return Ok(match self.type_ { |
454 | 1.44k | Type::BYTE => Byte(self.offset[0]), |
455 | 3 | Type::SBYTE => SignedByte(self.offset[0] as i8), |
456 | 133 | Type::UNDEFINED => Byte(self.offset[0]), |
457 | 54.2k | Type::SHORT => Short(self.offset_field_reader(bo).read_u16()?), |
458 | 2 | Type::SSHORT => SignedShort(self.offset_field_reader(bo).read_i16()?), |
459 | 6.64k | Type::LONG => Unsigned(self.offset_field_reader(bo).read_u32()?), |
460 | 1 | Type::SLONG => Signed(self.offset_field_reader(bo).read_i32()?), |
461 | 4 | Type::FLOAT => Float(self.offset_field_reader(bo).read_f32()?), |
462 | | Type::ASCII => { |
463 | 6 | if self.offset[0] == 0 { |
464 | 5 | Ascii("".to_string()) |
465 | | } else { |
466 | 1 | return Err(TiffError::FormatError(TiffFormatError::InvalidTag)); |
467 | | } |
468 | | } |
469 | | Type::LONG8 => { |
470 | 495 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; |
471 | 495 | UnsignedBig(reader.read_u64()?) |
472 | | } |
473 | | Type::SLONG8 => { |
474 | 5 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; |
475 | 5 | SignedBig(reader.read_i64()?) |
476 | | } |
477 | | Type::DOUBLE => { |
478 | 8 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; |
479 | 8 | Double(reader.read_f64()?) |
480 | | } |
481 | | Type::RATIONAL => { |
482 | 16 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; |
483 | 16 | Rational(reader.read_u32()?, reader.read_u32()?) |
484 | | } |
485 | | Type::SRATIONAL => { |
486 | 15 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; |
487 | 15 | SRational(reader.read_i32()?, reader.read_i32()?) |
488 | | } |
489 | 252 | Type::IFD => Ifd(self.offset_field_reader(bo).read_u32()?), |
490 | | Type::IFD8 => { |
491 | 169 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; |
492 | 169 | IfdBig(reader.read_u64()?) |
493 | | } |
494 | | }); |
495 | 17.2k | } |
496 | | |
497 | | // Case 3: There is more than one value, but it fits in the offset field. |
498 | 17.2k | if value_bytes <= 4 || bigtiff && value_bytes <= 8 { |
499 | 260 | match self.type_ { |
500 | 42 | Type::BYTE => return offset_to_bytes(self.count as usize, self), |
501 | 8 | Type::SBYTE => return offset_to_sbytes(self.count as usize, self), |
502 | | Type::ASCII => { |
503 | 65 | let mut buf = vec![0; self.count as usize]; |
504 | 65 | buf.copy_from_slice(&self.offset[..self.count as usize]); |
505 | 65 | if buf.is_ascii() && buf.ends_with(&[0]) { |
506 | 55 | let v = str::from_utf8(&buf)?; |
507 | 55 | let v = v.trim_matches(char::from(0)); |
508 | 55 | return Ok(Ascii(v.into())); |
509 | | } else { |
510 | 10 | return Err(TiffError::FormatError(TiffFormatError::InvalidTag)); |
511 | | } |
512 | | } |
513 | | Type::UNDEFINED => { |
514 | | return Ok(List( |
515 | 68 | self.offset[0..self.count as usize] |
516 | 68 | .iter() |
517 | 201 | .map(|&b| Byte(b)) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#0}Line | Count | Source | 517 | 201 | .map(|&b| Byte(b)) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#0} |
518 | 68 | .collect(), |
519 | | )); |
520 | | } |
521 | | Type::SHORT => { |
522 | 68 | let mut r = self.offset_field_reader(bo); |
523 | 68 | let mut v = Vec::new(); |
524 | 68 | for _ in 0..self.count { |
525 | 139 | v.push(Short(r.read_u16()?)); |
526 | | } |
527 | 68 | return Ok(List(v)); |
528 | | } |
529 | | Type::SSHORT => { |
530 | 3 | let mut r = self.offset_field_reader(bo); |
531 | 3 | let mut v = Vec::new(); |
532 | 3 | for _ in 0..self.count { |
533 | 9 | v.push(SignedShort(r.read_i16()?)); |
534 | | } |
535 | 3 | return Ok(List(v)); |
536 | | } |
537 | | Type::LONG => { |
538 | 3 | let mut r = self.offset_field_reader(bo); |
539 | 3 | let mut v = Vec::new(); |
540 | 3 | for _ in 0..self.count { |
541 | 6 | v.push(Unsigned(r.read_u32()?)); |
542 | | } |
543 | 3 | return Ok(List(v)); |
544 | | } |
545 | | Type::SLONG => { |
546 | 1 | let mut r = self.offset_field_reader(bo); |
547 | 1 | let mut v = Vec::new(); |
548 | 1 | for _ in 0..self.count { |
549 | 2 | v.push(Signed(r.read_i32()?)); |
550 | | } |
551 | 1 | return Ok(List(v)); |
552 | | } |
553 | | Type::FLOAT => { |
554 | 1 | let mut r = self.offset_field_reader(bo); |
555 | 1 | let mut v = Vec::new(); |
556 | 1 | for _ in 0..self.count { |
557 | 2 | v.push(Float(r.read_f32()?)); |
558 | | } |
559 | 1 | return Ok(List(v)); |
560 | | } |
561 | | Type::IFD => { |
562 | 1 | let mut r = self.offset_field_reader(bo); |
563 | 1 | let mut v = Vec::new(); |
564 | 1 | for _ in 0..self.count { |
565 | 2 | v.push(Ifd(r.read_u32()?)); |
566 | | } |
567 | 1 | return Ok(List(v)); |
568 | | } |
569 | | Type::LONG8 |
570 | | | Type::SLONG8 |
571 | | | Type::RATIONAL |
572 | | | Type::SRATIONAL |
573 | | | Type::DOUBLE |
574 | | | Type::IFD8 => { |
575 | 0 | unreachable!() |
576 | | } |
577 | | } |
578 | 17.0k | } |
579 | | |
580 | | // Case 4: there is more than one value, and it doesn't fit in the offset field. |
581 | | let mut v; |
582 | 17.0k | self.set_reader_offset_relative(bigtiff, reader, 0)?; |
583 | | |
584 | 17.0k | match self.type_ { |
585 | | Type::BYTE | Type::UNDEFINED => { |
586 | 4.71k | v = Self::vec_with_capacity(self.count, limits)?; |
587 | 12.2k | self.decode_values(self.count, self.type_, reader, |bytes| { |
588 | 12.2k | v.extend(bytes.iter().copied().map(Byte)) |
589 | 12.2k | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#1}Line | Count | Source | 587 | 12.2k | self.decode_values(self.count, self.type_, reader, |bytes| { | 588 | 12.2k | v.extend(bytes.iter().copied().map(Byte)) | 589 | 12.2k | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#1} |
590 | | } |
591 | | Type::SBYTE => { |
592 | 63 | v = Self::vec_with_capacity(self.count, limits)?; |
593 | 469 | self.decode_values(self.count, self.type_, reader, |bytes| { |
594 | 233k | v.extend(bytes.iter().copied().map(|v| SignedByte(v as i8))) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#2}::{closure#0}Line | Count | Source | 594 | 233k | v.extend(bytes.iter().copied().map(|v| SignedByte(v as i8))) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#2}::{closure#0} |
595 | 469 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#2}Line | Count | Source | 593 | 469 | self.decode_values(self.count, self.type_, reader, |bytes| { | 594 | 469 | v.extend(bytes.iter().copied().map(|v| SignedByte(v as i8))) | 595 | 469 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#2} |
596 | | } |
597 | | Type::SHORT => { |
598 | 1.06k | v = Self::vec_with_capacity(self.count, limits)?; |
599 | 3.20k | self.decode_values(self.count, self.type_, reader, |bytes| { |
600 | 3.20k | v.extend( |
601 | 3.20k | bytes |
602 | 3.20k | .chunks_exact(2) |
603 | 570k | .map(|ch| Short(u16::from_ne_bytes(ch.try_into().unwrap()))), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#3}::{closure#0}Line | Count | Source | 603 | 570k | .map(|ch| Short(u16::from_ne_bytes(ch.try_into().unwrap()))), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#3}::{closure#0} |
604 | | ) |
605 | 3.20k | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#3}Line | Count | Source | 599 | 3.20k | self.decode_values(self.count, self.type_, reader, |bytes| { | 600 | 3.20k | v.extend( | 601 | 3.20k | bytes | 602 | 3.20k | .chunks_exact(2) | 603 | 3.20k | .map(|ch| Short(u16::from_ne_bytes(ch.try_into().unwrap()))), | 604 | | ) | 605 | 3.20k | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#3} |
606 | | } |
607 | | Type::SSHORT => { |
608 | 40 | v = Self::vec_with_capacity(self.count, limits)?; |
609 | 232 | self.decode_values(self.count, self.type_, reader, |bytes| { |
610 | 232 | v.extend( |
611 | 232 | bytes |
612 | 232 | .chunks_exact(2) |
613 | 56.1k | .map(|ch| SignedShort(i16::from_ne_bytes(ch.try_into().unwrap()))), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#4}::{closure#0}Line | Count | Source | 613 | 56.1k | .map(|ch| SignedShort(i16::from_ne_bytes(ch.try_into().unwrap()))), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#4}::{closure#0} |
614 | | ) |
615 | 232 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#4}Line | Count | Source | 609 | 232 | self.decode_values(self.count, self.type_, reader, |bytes| { | 610 | 232 | v.extend( | 611 | 232 | bytes | 612 | 232 | .chunks_exact(2) | 613 | 232 | .map(|ch| SignedShort(i16::from_ne_bytes(ch.try_into().unwrap()))), | 614 | | ) | 615 | 232 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#4} |
616 | | } |
617 | | Type::LONG => { |
618 | 9.93k | v = Self::vec_with_capacity(self.count, limits)?; |
619 | 10.5k | self.decode_values(self.count, self.type_, reader, |bytes| { |
620 | 10.5k | v.extend( |
621 | 10.5k | bytes |
622 | 10.5k | .chunks_exact(4) |
623 | 131k | .map(|ch| Unsigned(u32::from_ne_bytes(ch.try_into().unwrap()))), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#5}::{closure#0}Line | Count | Source | 623 | 131k | .map(|ch| Unsigned(u32::from_ne_bytes(ch.try_into().unwrap()))), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#5}::{closure#0} |
624 | | ) |
625 | 10.5k | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#5}Line | Count | Source | 619 | 10.5k | self.decode_values(self.count, self.type_, reader, |bytes| { | 620 | 10.5k | v.extend( | 621 | 10.5k | bytes | 622 | 10.5k | .chunks_exact(4) | 623 | 10.5k | .map(|ch| Unsigned(u32::from_ne_bytes(ch.try_into().unwrap()))), | 624 | | ) | 625 | 10.5k | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#5} |
626 | | } |
627 | | Type::SLONG => { |
628 | 46 | v = Self::vec_with_capacity(self.count, limits)?; |
629 | 320 | self.decode_values(self.count, self.type_, reader, |bytes| { |
630 | 320 | v.extend( |
631 | 320 | bytes |
632 | 320 | .chunks_exact(4) |
633 | 39.3k | .map(|ch| Signed(i32::from_ne_bytes(ch.try_into().unwrap()))), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#6}::{closure#0}Line | Count | Source | 633 | 39.3k | .map(|ch| Signed(i32::from_ne_bytes(ch.try_into().unwrap()))), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#6}::{closure#0} |
634 | | ) |
635 | 320 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#6}Line | Count | Source | 629 | 320 | self.decode_values(self.count, self.type_, reader, |bytes| { | 630 | 320 | v.extend( | 631 | 320 | bytes | 632 | 320 | .chunks_exact(4) | 633 | 320 | .map(|ch| Signed(i32::from_ne_bytes(ch.try_into().unwrap()))), | 634 | | ) | 635 | 320 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#6} |
636 | | } |
637 | | Type::FLOAT => { |
638 | 45 | v = Self::vec_with_capacity(self.count, limits)?; |
639 | 210 | self.decode_values(self.count, self.type_, reader, |bytes| { |
640 | 210 | v.extend( |
641 | 210 | bytes |
642 | 210 | .chunks_exact(4) |
643 | 25.5k | .map(|ch| Float(f32::from_ne_bytes(ch.try_into().unwrap()))), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#7}::{closure#0}Line | Count | Source | 643 | 25.5k | .map(|ch| Float(f32::from_ne_bytes(ch.try_into().unwrap()))), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#7}::{closure#0} |
644 | | ) |
645 | 210 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#7}Line | Count | Source | 639 | 210 | self.decode_values(self.count, self.type_, reader, |bytes| { | 640 | 210 | v.extend( | 641 | 210 | bytes | 642 | 210 | .chunks_exact(4) | 643 | 210 | .map(|ch| Float(f32::from_ne_bytes(ch.try_into().unwrap()))), | 644 | | ) | 645 | 210 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#7} |
646 | | } |
647 | | Type::DOUBLE => { |
648 | 45 | v = Self::vec_with_capacity(self.count, limits)?; |
649 | 226 | self.decode_values(self.count, self.type_, reader, |bytes| { |
650 | 226 | v.extend( |
651 | 226 | bytes |
652 | 226 | .chunks_exact(8) |
653 | 13.5k | .map(|ch| Double(f64::from_ne_bytes(ch.try_into().unwrap()))), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#8}::{closure#0}Line | Count | Source | 653 | 13.5k | .map(|ch| Double(f64::from_ne_bytes(ch.try_into().unwrap()))), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#8}::{closure#0} |
654 | | ) |
655 | 226 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#8}Line | Count | Source | 649 | 226 | self.decode_values(self.count, self.type_, reader, |bytes| { | 650 | 226 | v.extend( | 651 | 226 | bytes | 652 | 226 | .chunks_exact(8) | 653 | 226 | .map(|ch| Double(f64::from_ne_bytes(ch.try_into().unwrap()))), | 654 | | ) | 655 | 226 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#8} |
656 | | } |
657 | | Type::RATIONAL => { |
658 | 55 | v = Self::vec_with_capacity(self.count, limits)?; |
659 | 256 | self.decode_values(self.count, self.type_, reader, |bytes| { |
660 | 15.6k | v.extend(bytes.chunks_exact(8).map(|ch| { |
661 | 15.6k | Rational( |
662 | 15.6k | u32::from_ne_bytes(ch[..4].try_into().unwrap()), |
663 | 15.6k | u32::from_ne_bytes(ch[4..].try_into().unwrap()), |
664 | 15.6k | ) |
665 | 15.6k | })) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#9}::{closure#0}Line | Count | Source | 660 | 15.6k | v.extend(bytes.chunks_exact(8).map(|ch| { | 661 | 15.6k | Rational( | 662 | 15.6k | u32::from_ne_bytes(ch[..4].try_into().unwrap()), | 663 | 15.6k | u32::from_ne_bytes(ch[4..].try_into().unwrap()), | 664 | 15.6k | ) | 665 | 15.6k | })) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#9}::{closure#0} |
666 | 256 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#9}Line | Count | Source | 659 | 256 | self.decode_values(self.count, self.type_, reader, |bytes| { | 660 | 256 | v.extend(bytes.chunks_exact(8).map(|ch| { | 661 | | Rational( | 662 | | u32::from_ne_bytes(ch[..4].try_into().unwrap()), | 663 | | u32::from_ne_bytes(ch[4..].try_into().unwrap()), | 664 | | ) | 665 | | })) | 666 | 256 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#9} |
667 | | } |
668 | | Type::SRATIONAL => { |
669 | 54 | v = Self::vec_with_capacity(self.count, limits)?; |
670 | 220 | self.decode_values(self.count, self.type_, reader, |bytes| { |
671 | 13.4k | v.extend(bytes.chunks_exact(8).map(|ch| { |
672 | 13.4k | SRational( |
673 | 13.4k | i32::from_ne_bytes(ch[..4].try_into().unwrap()), |
674 | 13.4k | i32::from_ne_bytes(ch[4..].try_into().unwrap()), |
675 | 13.4k | ) |
676 | 13.4k | })) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#10}::{closure#0}Line | Count | Source | 671 | 13.4k | v.extend(bytes.chunks_exact(8).map(|ch| { | 672 | 13.4k | SRational( | 673 | 13.4k | i32::from_ne_bytes(ch[..4].try_into().unwrap()), | 674 | 13.4k | i32::from_ne_bytes(ch[4..].try_into().unwrap()), | 675 | 13.4k | ) | 676 | 13.4k | })) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#10}::{closure#0} |
677 | 220 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#10}Line | Count | Source | 670 | 220 | self.decode_values(self.count, self.type_, reader, |bytes| { | 671 | 220 | v.extend(bytes.chunks_exact(8).map(|ch| { | 672 | | SRational( | 673 | | i32::from_ne_bytes(ch[..4].try_into().unwrap()), | 674 | | i32::from_ne_bytes(ch[4..].try_into().unwrap()), | 675 | | ) | 676 | | })) | 677 | 220 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#10} |
678 | | } |
679 | | Type::LONG8 => { |
680 | 447 | v = Self::vec_with_capacity(self.count, limits)?; |
681 | 662 | self.decode_values(self.count, self.type_, reader, |bytes| { |
682 | 662 | v.extend( |
683 | 662 | bytes |
684 | 662 | .chunks_exact(8) |
685 | 18.1k | .map(|ch| UnsignedBig(u64::from_ne_bytes(ch.try_into().unwrap()))), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#11}::{closure#0}Line | Count | Source | 685 | 18.1k | .map(|ch| UnsignedBig(u64::from_ne_bytes(ch.try_into().unwrap()))), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#11}::{closure#0} |
686 | | ) |
687 | 662 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#11}Line | Count | Source | 681 | 662 | self.decode_values(self.count, self.type_, reader, |bytes| { | 682 | 662 | v.extend( | 683 | 662 | bytes | 684 | 662 | .chunks_exact(8) | 685 | 662 | .map(|ch| UnsignedBig(u64::from_ne_bytes(ch.try_into().unwrap()))), | 686 | | ) | 687 | 662 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#11} |
688 | | } |
689 | | Type::SLONG8 => { |
690 | 37 | v = Self::vec_with_capacity(self.count, limits)?; |
691 | 229 | self.decode_values(self.count, self.type_, reader, |bytes| { |
692 | 229 | v.extend( |
693 | 229 | bytes |
694 | 229 | .chunks_exact(8) |
695 | 14.0k | .map(|ch| SignedBig(i64::from_ne_bytes(ch.try_into().unwrap()))), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#12}::{closure#0}Line | Count | Source | 695 | 14.0k | .map(|ch| SignedBig(i64::from_ne_bytes(ch.try_into().unwrap()))), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#12}::{closure#0} |
696 | | ) |
697 | 229 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#12}Line | Count | Source | 691 | 229 | self.decode_values(self.count, self.type_, reader, |bytes| { | 692 | 229 | v.extend( | 693 | 229 | bytes | 694 | 229 | .chunks_exact(8) | 695 | 229 | .map(|ch| SignedBig(i64::from_ne_bytes(ch.try_into().unwrap()))), | 696 | | ) | 697 | 229 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#12} |
698 | | } |
699 | | Type::IFD => { |
700 | 61 | v = Self::vec_with_capacity(self.count, limits)?; |
701 | 283 | self.decode_values(self.count, self.type_, reader, |bytes| { |
702 | 283 | v.extend( |
703 | 283 | bytes |
704 | 283 | .chunks_exact(4) |
705 | 33.0k | .map(|ch| Ifd(u32::from_ne_bytes(ch.try_into().unwrap()))), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#13}::{closure#0}Line | Count | Source | 705 | 33.0k | .map(|ch| Ifd(u32::from_ne_bytes(ch.try_into().unwrap()))), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#13}::{closure#0} |
706 | | ) |
707 | 283 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#13}Line | Count | Source | 701 | 283 | self.decode_values(self.count, self.type_, reader, |bytes| { | 702 | 283 | v.extend( | 703 | 283 | bytes | 704 | 283 | .chunks_exact(4) | 705 | 283 | .map(|ch| Ifd(u32::from_ne_bytes(ch.try_into().unwrap()))), | 706 | | ) | 707 | 283 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#13} |
708 | | } |
709 | | Type::IFD8 => { |
710 | 93 | v = Self::vec_with_capacity(self.count, limits)?; |
711 | 416 | self.decode_values(self.count, self.type_, reader, |bytes| { |
712 | 416 | v.extend( |
713 | 416 | bytes |
714 | 416 | .chunks_exact(8) |
715 | 23.7k | .map(|ch| IfdBig(u64::from_ne_bytes(ch.try_into().unwrap()))), <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#14}::{closure#0}Line | Count | Source | 715 | 23.7k | .map(|ch| IfdBig(u64::from_ne_bytes(ch.try_into().unwrap()))), |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#14}::{closure#0} |
716 | | ) |
717 | 416 | }) <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#14}Line | Count | Source | 711 | 416 | self.decode_values(self.count, self.type_, reader, |bytes| { | 712 | 416 | v.extend( | 713 | 416 | bytes | 714 | 416 | .chunks_exact(8) | 715 | 416 | .map(|ch| IfdBig(u64::from_ne_bytes(ch.try_into().unwrap()))), | 716 | | ) | 717 | 416 | }) |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#14} |
718 | | } |
719 | | Type::ASCII => { |
720 | 297 | let n = usize::try_from(self.count)?; |
721 | | |
722 | 297 | if n > limits.decoding_buffer_size { |
723 | 105 | return Err(dbg!(TiffError::LimitsExceeded)); |
724 | 192 | } |
725 | | |
726 | 192 | let mut out = vec![0; n]; |
727 | 192 | reader.inner().read_exact(&mut out)?; |
728 | | // Strings may be null-terminated, so we trim anything downstream of the null byte |
729 | 178k | if let Some(first) = out.iter().position(|&b| b == 0) {<tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>>::{closure#15}Line | Count | Source | 729 | 178k | if let Some(first) = out.iter().position(|&b| b == 0) { |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_>::{closure#15} |
730 | 115 | out.truncate(first); |
731 | 115 | } |
732 | | |
733 | 153 | return Ok(Ascii(String::from_utf8(out)?)); |
734 | | } |
735 | 455 | }?; |
736 | | |
737 | 16.1k | Ok(List(v)) |
738 | 80.7k | } <tiff::decoder::ifd::Entry>::val::<std::io::cursor::Cursor<&[u8]>> Line | Count | Source | 408 | 80.7k | pub(crate) fn val<R: Read + Seek>( | 409 | 80.7k | &self, | 410 | 80.7k | limits: &super::Limits, | 411 | 80.7k | bigtiff: bool, | 412 | 80.7k | reader: &mut EndianReader<R>, | 413 | 80.7k | ) -> TiffResult<Value> { | 414 | | // Case 1: there are no values so we can return immediately. | 415 | 80.7k | if self.count == 0 { | 416 | 25 | return Ok(List(Vec::new())); | 417 | 80.7k | } | 418 | | | 419 | 80.7k | let bo = reader.byte_order; | 420 | 80.7k | let value_bytes = self.type_.value_bytes(self.count)?; | 421 | | | 422 | | // Case 2: there is one value. | 423 | 80.7k | if self.count == 1 { | 424 | | // 2a: the value is 5-8 bytes and we're in BigTiff mode. | 425 | 63.4k | if bigtiff && value_bytes > 4 && value_bytes <= 8 { | 426 | 12 | return Ok(match self.type_ { | 427 | 7 | Type::LONG8 => UnsignedBig(self.offset_field_reader(bo).read_u64()?), | 428 | 1 | Type::SLONG8 => SignedBig(self.offset_field_reader(bo).read_i64()?), | 429 | 1 | Type::DOUBLE => Double(self.offset_field_reader(bo).read_f64()?), | 430 | | Type::RATIONAL => { | 431 | 1 | let mut r = self.offset_field_reader(bo); | 432 | 1 | Rational(r.read_u32()?, r.read_u32()?) | 433 | | } | 434 | | Type::SRATIONAL => { | 435 | 1 | let mut r = self.offset_field_reader(bo); | 436 | 1 | SRational(r.read_i32()?, r.read_i32()?) | 437 | | } | 438 | 1 | Type::IFD8 => IfdBig(self.offset_field_reader(bo).read_u64()?), | 439 | | Type::BYTE | 440 | | | Type::SBYTE | 441 | | | Type::ASCII | 442 | | | Type::UNDEFINED | 443 | | | Type::SHORT | 444 | | | Type::SSHORT | 445 | | | Type::LONG | 446 | | | Type::SLONG | 447 | | | Type::FLOAT | 448 | 0 | | Type::IFD => unreachable!(), | 449 | | }); | 450 | 63.4k | } | 451 | | | 452 | | // 2b: the value is at most 4 bytes or doesn't fit in the offset field. | 453 | 63.4k | return Ok(match self.type_ { | 454 | 1.44k | Type::BYTE => Byte(self.offset[0]), | 455 | 3 | Type::SBYTE => SignedByte(self.offset[0] as i8), | 456 | 133 | Type::UNDEFINED => Byte(self.offset[0]), | 457 | 54.2k | Type::SHORT => Short(self.offset_field_reader(bo).read_u16()?), | 458 | 2 | Type::SSHORT => SignedShort(self.offset_field_reader(bo).read_i16()?), | 459 | 6.64k | Type::LONG => Unsigned(self.offset_field_reader(bo).read_u32()?), | 460 | 1 | Type::SLONG => Signed(self.offset_field_reader(bo).read_i32()?), | 461 | 4 | Type::FLOAT => Float(self.offset_field_reader(bo).read_f32()?), | 462 | | Type::ASCII => { | 463 | 6 | if self.offset[0] == 0 { | 464 | 5 | Ascii("".to_string()) | 465 | | } else { | 466 | 1 | return Err(TiffError::FormatError(TiffFormatError::InvalidTag)); | 467 | | } | 468 | | } | 469 | | Type::LONG8 => { | 470 | 495 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; | 471 | 495 | UnsignedBig(reader.read_u64()?) | 472 | | } | 473 | | Type::SLONG8 => { | 474 | 5 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; | 475 | 5 | SignedBig(reader.read_i64()?) | 476 | | } | 477 | | Type::DOUBLE => { | 478 | 8 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; | 479 | 8 | Double(reader.read_f64()?) | 480 | | } | 481 | | Type::RATIONAL => { | 482 | 16 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; | 483 | 16 | Rational(reader.read_u32()?, reader.read_u32()?) | 484 | | } | 485 | | Type::SRATIONAL => { | 486 | 15 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; | 487 | 15 | SRational(reader.read_i32()?, reader.read_i32()?) | 488 | | } | 489 | 252 | Type::IFD => Ifd(self.offset_field_reader(bo).read_u32()?), | 490 | | Type::IFD8 => { | 491 | 169 | reader.goto_offset(self.offset_field_reader(bo).read_u32()?.into())?; | 492 | 169 | IfdBig(reader.read_u64()?) | 493 | | } | 494 | | }); | 495 | 17.2k | } | 496 | | | 497 | | // Case 3: There is more than one value, but it fits in the offset field. | 498 | 17.2k | if value_bytes <= 4 || bigtiff && value_bytes <= 8 { | 499 | 260 | match self.type_ { | 500 | 42 | Type::BYTE => return offset_to_bytes(self.count as usize, self), | 501 | 8 | Type::SBYTE => return offset_to_sbytes(self.count as usize, self), | 502 | | Type::ASCII => { | 503 | 65 | let mut buf = vec![0; self.count as usize]; | 504 | 65 | buf.copy_from_slice(&self.offset[..self.count as usize]); | 505 | 65 | if buf.is_ascii() && buf.ends_with(&[0]) { | 506 | 55 | let v = str::from_utf8(&buf)?; | 507 | 55 | let v = v.trim_matches(char::from(0)); | 508 | 55 | return Ok(Ascii(v.into())); | 509 | | } else { | 510 | 10 | return Err(TiffError::FormatError(TiffFormatError::InvalidTag)); | 511 | | } | 512 | | } | 513 | | Type::UNDEFINED => { | 514 | | return Ok(List( | 515 | 68 | self.offset[0..self.count as usize] | 516 | 68 | .iter() | 517 | 68 | .map(|&b| Byte(b)) | 518 | 68 | .collect(), | 519 | | )); | 520 | | } | 521 | | Type::SHORT => { | 522 | 68 | let mut r = self.offset_field_reader(bo); | 523 | 68 | let mut v = Vec::new(); | 524 | 68 | for _ in 0..self.count { | 525 | 139 | v.push(Short(r.read_u16()?)); | 526 | | } | 527 | 68 | return Ok(List(v)); | 528 | | } | 529 | | Type::SSHORT => { | 530 | 3 | let mut r = self.offset_field_reader(bo); | 531 | 3 | let mut v = Vec::new(); | 532 | 3 | for _ in 0..self.count { | 533 | 9 | v.push(SignedShort(r.read_i16()?)); | 534 | | } | 535 | 3 | return Ok(List(v)); | 536 | | } | 537 | | Type::LONG => { | 538 | 3 | let mut r = self.offset_field_reader(bo); | 539 | 3 | let mut v = Vec::new(); | 540 | 3 | for _ in 0..self.count { | 541 | 6 | v.push(Unsigned(r.read_u32()?)); | 542 | | } | 543 | 3 | return Ok(List(v)); | 544 | | } | 545 | | Type::SLONG => { | 546 | 1 | let mut r = self.offset_field_reader(bo); | 547 | 1 | let mut v = Vec::new(); | 548 | 1 | for _ in 0..self.count { | 549 | 2 | v.push(Signed(r.read_i32()?)); | 550 | | } | 551 | 1 | return Ok(List(v)); | 552 | | } | 553 | | Type::FLOAT => { | 554 | 1 | let mut r = self.offset_field_reader(bo); | 555 | 1 | let mut v = Vec::new(); | 556 | 1 | for _ in 0..self.count { | 557 | 2 | v.push(Float(r.read_f32()?)); | 558 | | } | 559 | 1 | return Ok(List(v)); | 560 | | } | 561 | | Type::IFD => { | 562 | 1 | let mut r = self.offset_field_reader(bo); | 563 | 1 | let mut v = Vec::new(); | 564 | 1 | for _ in 0..self.count { | 565 | 2 | v.push(Ifd(r.read_u32()?)); | 566 | | } | 567 | 1 | return Ok(List(v)); | 568 | | } | 569 | | Type::LONG8 | 570 | | | Type::SLONG8 | 571 | | | Type::RATIONAL | 572 | | | Type::SRATIONAL | 573 | | | Type::DOUBLE | 574 | | | Type::IFD8 => { | 575 | 0 | unreachable!() | 576 | | } | 577 | | } | 578 | 17.0k | } | 579 | | | 580 | | // Case 4: there is more than one value, and it doesn't fit in the offset field. | 581 | | let mut v; | 582 | 17.0k | self.set_reader_offset_relative(bigtiff, reader, 0)?; | 583 | | | 584 | 17.0k | match self.type_ { | 585 | | Type::BYTE | Type::UNDEFINED => { | 586 | 4.71k | v = Self::vec_with_capacity(self.count, limits)?; | 587 | 4.66k | self.decode_values(self.count, self.type_, reader, |bytes| { | 588 | | v.extend(bytes.iter().copied().map(Byte)) | 589 | | }) | 590 | | } | 591 | | Type::SBYTE => { | 592 | 63 | v = Self::vec_with_capacity(self.count, limits)?; | 593 | 45 | self.decode_values(self.count, self.type_, reader, |bytes| { | 594 | | v.extend(bytes.iter().copied().map(|v| SignedByte(v as i8))) | 595 | | }) | 596 | | } | 597 | | Type::SHORT => { | 598 | 1.06k | v = Self::vec_with_capacity(self.count, limits)?; | 599 | 1.05k | self.decode_values(self.count, self.type_, reader, |bytes| { | 600 | | v.extend( | 601 | | bytes | 602 | | .chunks_exact(2) | 603 | | .map(|ch| Short(u16::from_ne_bytes(ch.try_into().unwrap()))), | 604 | | ) | 605 | | }) | 606 | | } | 607 | | Type::SSHORT => { | 608 | 40 | v = Self::vec_with_capacity(self.count, limits)?; | 609 | 39 | self.decode_values(self.count, self.type_, reader, |bytes| { | 610 | | v.extend( | 611 | | bytes | 612 | | .chunks_exact(2) | 613 | | .map(|ch| SignedShort(i16::from_ne_bytes(ch.try_into().unwrap()))), | 614 | | ) | 615 | | }) | 616 | | } | 617 | | Type::LONG => { | 618 | 9.93k | v = Self::vec_with_capacity(self.count, limits)?; | 619 | 9.93k | self.decode_values(self.count, self.type_, reader, |bytes| { | 620 | | v.extend( | 621 | | bytes | 622 | | .chunks_exact(4) | 623 | | .map(|ch| Unsigned(u32::from_ne_bytes(ch.try_into().unwrap()))), | 624 | | ) | 625 | | }) | 626 | | } | 627 | | Type::SLONG => { | 628 | 46 | v = Self::vec_with_capacity(self.count, limits)?; | 629 | 41 | self.decode_values(self.count, self.type_, reader, |bytes| { | 630 | | v.extend( | 631 | | bytes | 632 | | .chunks_exact(4) | 633 | | .map(|ch| Signed(i32::from_ne_bytes(ch.try_into().unwrap()))), | 634 | | ) | 635 | | }) | 636 | | } | 637 | | Type::FLOAT => { | 638 | 45 | v = Self::vec_with_capacity(self.count, limits)?; | 639 | 32 | self.decode_values(self.count, self.type_, reader, |bytes| { | 640 | | v.extend( | 641 | | bytes | 642 | | .chunks_exact(4) | 643 | | .map(|ch| Float(f32::from_ne_bytes(ch.try_into().unwrap()))), | 644 | | ) | 645 | | }) | 646 | | } | 647 | | Type::DOUBLE => { | 648 | 45 | v = Self::vec_with_capacity(self.count, limits)?; | 649 | 39 | self.decode_values(self.count, self.type_, reader, |bytes| { | 650 | | v.extend( | 651 | | bytes | 652 | | .chunks_exact(8) | 653 | | .map(|ch| Double(f64::from_ne_bytes(ch.try_into().unwrap()))), | 654 | | ) | 655 | | }) | 656 | | } | 657 | | Type::RATIONAL => { | 658 | 55 | v = Self::vec_with_capacity(self.count, limits)?; | 659 | 45 | self.decode_values(self.count, self.type_, reader, |bytes| { | 660 | | v.extend(bytes.chunks_exact(8).map(|ch| { | 661 | | Rational( | 662 | | u32::from_ne_bytes(ch[..4].try_into().unwrap()), | 663 | | u32::from_ne_bytes(ch[4..].try_into().unwrap()), | 664 | | ) | 665 | | })) | 666 | | }) | 667 | | } | 668 | | Type::SRATIONAL => { | 669 | 54 | v = Self::vec_with_capacity(self.count, limits)?; | 670 | 49 | self.decode_values(self.count, self.type_, reader, |bytes| { | 671 | | v.extend(bytes.chunks_exact(8).map(|ch| { | 672 | | SRational( | 673 | | i32::from_ne_bytes(ch[..4].try_into().unwrap()), | 674 | | i32::from_ne_bytes(ch[4..].try_into().unwrap()), | 675 | | ) | 676 | | })) | 677 | | }) | 678 | | } | 679 | | Type::LONG8 => { | 680 | 447 | v = Self::vec_with_capacity(self.count, limits)?; | 681 | 441 | self.decode_values(self.count, self.type_, reader, |bytes| { | 682 | | v.extend( | 683 | | bytes | 684 | | .chunks_exact(8) | 685 | | .map(|ch| UnsignedBig(u64::from_ne_bytes(ch.try_into().unwrap()))), | 686 | | ) | 687 | | }) | 688 | | } | 689 | | Type::SLONG8 => { | 690 | 37 | v = Self::vec_with_capacity(self.count, limits)?; | 691 | 35 | self.decode_values(self.count, self.type_, reader, |bytes| { | 692 | | v.extend( | 693 | | bytes | 694 | | .chunks_exact(8) | 695 | | .map(|ch| SignedBig(i64::from_ne_bytes(ch.try_into().unwrap()))), | 696 | | ) | 697 | | }) | 698 | | } | 699 | | Type::IFD => { | 700 | 61 | v = Self::vec_with_capacity(self.count, limits)?; | 701 | 57 | self.decode_values(self.count, self.type_, reader, |bytes| { | 702 | | v.extend( | 703 | | bytes | 704 | | .chunks_exact(4) | 705 | | .map(|ch| Ifd(u32::from_ne_bytes(ch.try_into().unwrap()))), | 706 | | ) | 707 | | }) | 708 | | } | 709 | | Type::IFD8 => { | 710 | 93 | v = Self::vec_with_capacity(self.count, limits)?; | 711 | 88 | self.decode_values(self.count, self.type_, reader, |bytes| { | 712 | | v.extend( | 713 | | bytes | 714 | | .chunks_exact(8) | 715 | | .map(|ch| IfdBig(u64::from_ne_bytes(ch.try_into().unwrap()))), | 716 | | ) | 717 | | }) | 718 | | } | 719 | | Type::ASCII => { | 720 | 297 | let n = usize::try_from(self.count)?; | 721 | | | 722 | 297 | if n > limits.decoding_buffer_size { | 723 | 105 | return Err(dbg!(TiffError::LimitsExceeded)); | 724 | 192 | } | 725 | | | 726 | 192 | let mut out = vec![0; n]; | 727 | 192 | reader.inner().read_exact(&mut out)?; | 728 | | // Strings may be null-terminated, so we trim anything downstream of the null byte | 729 | 153 | if let Some(first) = out.iter().position(|&b| b == 0) { | 730 | 115 | out.truncate(first); | 731 | 115 | } | 732 | | | 733 | 153 | return Ok(Ascii(String::from_utf8(out)?)); | 734 | | } | 735 | 455 | }?; | 736 | | | 737 | 16.1k | Ok(List(v)) | 738 | 80.7k | } |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::val::<_> |
739 | | |
740 | 0 | pub(crate) fn buffered_value<R: Read + Seek>( |
741 | 0 | &self, |
742 | 0 | buf: &mut ValueBuffer, |
743 | 0 | limits: &super::Limits, |
744 | 0 | bigtiff: bool, |
745 | 0 | reader: &mut EndianReader<R>, |
746 | 0 | ) -> TiffResult<()> { |
747 | 0 | if self.count == 0 { |
748 | 0 | buf.assume_type(self.type_, 0, reader.byte_order); |
749 | 0 | return Ok(()); |
750 | 0 | } |
751 | | |
752 | 0 | let value_bytes = self.buffer_with_capacity(buf, limits)?; |
753 | | |
754 | | // Case 1: the value fits in the offset field. |
755 | 0 | if value_bytes <= 4 || bigtiff && value_bytes <= 8 { |
756 | 0 | let src = &self.offset[..value_bytes]; |
757 | 0 | buf.raw_bytes_mut()[..value_bytes].copy_from_slice(src); |
758 | 0 | buf.assume_type(self.type_, self.count, reader.byte_order); |
759 | | |
760 | 0 | return Ok(()); |
761 | 0 | } |
762 | | |
763 | | // Case 2: the value is stored in the reader at an offset. |
764 | 0 | self.set_reader_offset_relative(bigtiff, reader, 0)?; |
765 | | |
766 | | // In case of an error we set the type and endianess. |
767 | 0 | buf.assume_type(self.type_, 0, reader.byte_order); |
768 | 0 | let target = &mut buf.raw_bytes_mut()[..value_bytes]; |
769 | | // FIXME: if the read fails we have already grown to full size, which is not great. |
770 | 0 | reader.inner().read_exact(target)?; |
771 | 0 | buf.assume_type(self.type_, self.count, reader.byte_order); |
772 | | |
773 | 0 | Ok(()) |
774 | 0 | } Unexecuted instantiation: <tiff::decoder::ifd::Entry>::buffered_value::<std::io::cursor::Cursor<&[u8]>> Unexecuted instantiation: <tiff::decoder::ifd::Entry>::buffered_value::<_> |
775 | | |
776 | 0 | pub(crate) fn raw_value_at<R: Read + Seek>( |
777 | 0 | &self, |
778 | 0 | buf: &mut [u8], |
779 | 0 | bigtiff: bool, |
780 | 0 | reader: &mut EndianReader<R>, |
781 | 0 | at: u64, |
782 | 0 | ) -> TiffResult<usize> { |
783 | 0 | if self.count == 0 { |
784 | 0 | return Ok(0); |
785 | 0 | } |
786 | | |
787 | | // We have no limits to handle, we do not allocate. |
788 | 0 | let value_bytes = self.type_.value_bytes(self.count)?; |
789 | | |
790 | | // No bytes to fill into the buffer. |
791 | 0 | if at >= value_bytes { |
792 | 0 | return Ok(0); |
793 | 0 | } |
794 | | |
795 | | // Case 1: the value fits in the offset field. |
796 | 0 | if value_bytes <= 4 || bigtiff && value_bytes <= 8 { |
797 | | // `at < value_bytes` and `value_bytes <= 8` so casting is mathematical |
798 | 0 | let src = &self.offset[..value_bytes as usize][at as usize..]; |
799 | 0 | let len = src.len().min(buf.len()); |
800 | 0 | buf[..len].copy_from_slice(&src[..len]); |
801 | 0 | return Ok(value_bytes as usize); |
802 | 0 | } |
803 | | |
804 | | // Case 2: the value is stored in the reader at an offset. We will find the offset |
805 | | // encoded in the entry, apply the relative start position and seek there. |
806 | 0 | self.set_reader_offset_relative(bigtiff, reader, at)?; |
807 | | |
808 | 0 | let remainder = value_bytes - at; |
809 | 0 | let len = usize::try_from(remainder) |
810 | 0 | .unwrap_or(usize::MAX) |
811 | 0 | .min(buf.len()); |
812 | | |
813 | 0 | let target = &mut buf[..len]; |
814 | 0 | reader.inner().read_exact(target)?; |
815 | | |
816 | | // Design note: in a previous draft we would consume the rest of the bytes of this value |
817 | | // here (into a stack buffer if need be) to verify the stream itself. But in the end we |
818 | | // have `Seek` so we better verify this by seeking over the rest of the bytes, finding if |
819 | | // the stream continues that far. Even that is maybe bad if we wanted to provide a |
820 | | // async-adaptor that `WouldBlock` errors to fill back a read window then the seek is |
821 | | // poison to that, too. |
822 | | |
823 | | // So a really simple choice: The caller is responsible for handling the fact that this did |
824 | | // not verify the whole value. Attempt a 1-byte read at the end of the value instead? |
825 | 0 | Ok(len) |
826 | 0 | } Unexecuted instantiation: <tiff::decoder::ifd::Entry>::raw_value_at::<std::io::cursor::Cursor<&[u8]>> Unexecuted instantiation: <tiff::decoder::ifd::Entry>::raw_value_at::<_> |
827 | | |
828 | | // Returns `Ok(bytes)` if our value's bytes through type and count fit into `usize` and are |
829 | | // within the limits. Extends the buffer to that many bytes. |
830 | 0 | fn buffer_with_capacity( |
831 | 0 | &self, |
832 | 0 | buf: &mut ValueBuffer, |
833 | 0 | limits: &super::Limits, |
834 | 0 | ) -> TiffResult<usize> { |
835 | 0 | let bytes = self.type_.value_bytes(self.count())?; |
836 | | |
837 | 0 | let allowed_length = usize::try_from(bytes) |
838 | 0 | .ok() |
839 | 0 | .filter(|&n| n <= limits.decoding_buffer_size) |
840 | 0 | .ok_or(TiffError::LimitsExceeded)?; |
841 | | |
842 | 0 | buf.prepare_length(allowed_length); |
843 | | |
844 | 0 | Ok(allowed_length) |
845 | 0 | } |
846 | | |
847 | 16.7k | fn vec_with_capacity( |
848 | 16.7k | value_count: u64, |
849 | 16.7k | limits: &super::Limits, |
850 | 16.7k | ) -> Result<Vec<Value>, TiffError> { |
851 | 16.7k | let value_count = usize::try_from(value_count)?; |
852 | | |
853 | 16.7k | if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() { |
854 | 143 | return Err(TiffError::LimitsExceeded); |
855 | 16.5k | } |
856 | | |
857 | 16.5k | Ok(Vec::with_capacity(value_count)) |
858 | 16.7k | } |
859 | | |
860 | | /// Seek to an offset within a value stored in the offset defined by this entry. |
861 | 17.0k | fn set_reader_offset_relative<R>( |
862 | 17.0k | &self, |
863 | 17.0k | bigtiff: bool, |
864 | 17.0k | reader: &mut EndianReader<R>, |
865 | 17.0k | at: u64, |
866 | 17.0k | ) -> TiffResult<()> |
867 | 17.0k | where |
868 | 17.0k | R: Read + Seek, |
869 | | { |
870 | 17.0k | let bo = reader.byte_order; |
871 | | |
872 | 17.0k | let offset = if bigtiff { |
873 | 206 | self.offset_field_reader(bo).read_u64()? |
874 | | } else { |
875 | 16.7k | self.offset_field_reader(bo).read_u32()?.into() |
876 | | }; |
877 | | |
878 | | // FIXME: `at` should be within `self.type_.value_bytes(self.count)` and that itself should |
879 | | // be within the bounds of the stream. But we do not check this eagerly so this below will |
880 | | // fail sometimes differently for exotic streams, depending on the method by which we read |
881 | | // (at once or through multiple raw into-byte-slice reads). |
882 | 17.0k | let offset = offset.checked_add(at).ok_or(TiffError::FormatError( |
883 | 17.0k | TiffFormatError::InconsistentSizesEncountered, |
884 | 17.0k | ))?; |
885 | | |
886 | 17.0k | reader.goto_offset(offset)?; |
887 | | |
888 | 17.0k | Ok(()) |
889 | 17.0k | } <tiff::decoder::ifd::Entry>::set_reader_offset_relative::<std::io::cursor::Cursor<&[u8]>> Line | Count | Source | 861 | 17.0k | fn set_reader_offset_relative<R>( | 862 | 17.0k | &self, | 863 | 17.0k | bigtiff: bool, | 864 | 17.0k | reader: &mut EndianReader<R>, | 865 | 17.0k | at: u64, | 866 | 17.0k | ) -> TiffResult<()> | 867 | 17.0k | where | 868 | 17.0k | R: Read + Seek, | 869 | | { | 870 | 17.0k | let bo = reader.byte_order; | 871 | | | 872 | 17.0k | let offset = if bigtiff { | 873 | 206 | self.offset_field_reader(bo).read_u64()? | 874 | | } else { | 875 | 16.7k | self.offset_field_reader(bo).read_u32()?.into() | 876 | | }; | 877 | | | 878 | | // FIXME: `at` should be within `self.type_.value_bytes(self.count)` and that itself should | 879 | | // be within the bounds of the stream. But we do not check this eagerly so this below will | 880 | | // fail sometimes differently for exotic streams, depending on the method by which we read | 881 | | // (at once or through multiple raw into-byte-slice reads). | 882 | 17.0k | let offset = offset.checked_add(at).ok_or(TiffError::FormatError( | 883 | 17.0k | TiffFormatError::InconsistentSizesEncountered, | 884 | 17.0k | ))?; | 885 | | | 886 | 17.0k | reader.goto_offset(offset)?; | 887 | | | 888 | 17.0k | Ok(()) | 889 | 17.0k | } |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::set_reader_offset_relative::<_> |
890 | | |
891 | | #[inline] |
892 | 16.5k | fn decode_values<R, F>( |
893 | 16.5k | &self, |
894 | 16.5k | value_count: u64, |
895 | 16.5k | type_: Type, |
896 | 16.5k | reader: &mut EndianReader<R>, |
897 | 16.5k | mut collect: F, |
898 | 16.5k | ) -> TiffResult<()> |
899 | 16.5k | where |
900 | 16.5k | R: Read + Seek, |
901 | 16.5k | F: FnMut(&[u8]), |
902 | | { |
903 | 16.5k | let mut total_bytes = type_.value_bytes(value_count)?; |
904 | 16.5k | let mut buffer = [0u8; 512]; |
905 | | |
906 | 16.5k | let buf_unit = usize::from(type_.byte_len()); |
907 | 16.5k | let mul_of_ty = buffer.len() / buf_unit * buf_unit; |
908 | | |
909 | 16.5k | let cls = type_.endian_bytes(); |
910 | 16.5k | let native = ByteOrder::native(); |
911 | | |
912 | 46.1k | while total_bytes > 0 { |
913 | | // `now <= mul_of_ty < 512` so casting is mathematical |
914 | 30.0k | let now = total_bytes.min(mul_of_ty as u64); |
915 | 30.0k | total_bytes -= now; |
916 | | |
917 | 30.0k | let buffer = &mut buffer[..now as usize]; |
918 | 30.0k | reader.inner().read_exact(buffer)?; |
919 | | |
920 | 29.5k | reader.byte_order.convert_endian_bytes(cls, buffer, native); |
921 | 29.5k | collect(buffer); |
922 | | } |
923 | | |
924 | 16.1k | Ok(()) |
925 | 16.5k | } <tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#2}>Line | Count | Source | 892 | 45 | fn decode_values<R, F>( | 893 | 45 | &self, | 894 | 45 | value_count: u64, | 895 | 45 | type_: Type, | 896 | 45 | reader: &mut EndianReader<R>, | 897 | 45 | mut collect: F, | 898 | 45 | ) -> TiffResult<()> | 899 | 45 | where | 900 | 45 | R: Read + Seek, | 901 | 45 | F: FnMut(&[u8]), | 902 | | { | 903 | 45 | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 45 | let mut buffer = [0u8; 512]; | 905 | | | 906 | 45 | let buf_unit = usize::from(type_.byte_len()); | 907 | 45 | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 45 | let cls = type_.endian_bytes(); | 910 | 45 | let native = ByteOrder::native(); | 911 | | | 912 | 514 | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 496 | let now = total_bytes.min(mul_of_ty as u64); | 915 | 496 | total_bytes -= now; | 916 | | | 917 | 496 | let buffer = &mut buffer[..now as usize]; | 918 | 496 | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 469 | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 469 | collect(buffer); | 922 | | } | 923 | | | 924 | 18 | Ok(()) | 925 | 45 | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#3}>Line | Count | Source | 892 | 1.05k | fn decode_values<R, F>( | 893 | 1.05k | &self, | 894 | 1.05k | value_count: u64, | 895 | 1.05k | type_: Type, | 896 | 1.05k | reader: &mut EndianReader<R>, | 897 | 1.05k | mut collect: F, | 898 | 1.05k | ) -> TiffResult<()> | 899 | 1.05k | where | 900 | 1.05k | R: Read + Seek, | 901 | 1.05k | F: FnMut(&[u8]), | 902 | | { | 903 | 1.05k | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 1.05k | let mut buffer = [0u8; 512]; | 905 | | | 906 | 1.05k | let buf_unit = usize::from(type_.byte_len()); | 907 | 1.05k | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 1.05k | let cls = type_.endian_bytes(); | 910 | 1.05k | let native = ByteOrder::native(); | 911 | | | 912 | 4.26k | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 3.25k | let now = total_bytes.min(mul_of_ty as u64); | 915 | 3.25k | total_bytes -= now; | 916 | | | 917 | 3.25k | let buffer = &mut buffer[..now as usize]; | 918 | 3.25k | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 3.20k | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 3.20k | collect(buffer); | 922 | | } | 923 | | | 924 | 1.00k | Ok(()) | 925 | 1.05k | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#4}>Line | Count | Source | 892 | 39 | fn decode_values<R, F>( | 893 | 39 | &self, | 894 | 39 | value_count: u64, | 895 | 39 | type_: Type, | 896 | 39 | reader: &mut EndianReader<R>, | 897 | 39 | mut collect: F, | 898 | 39 | ) -> TiffResult<()> | 899 | 39 | where | 900 | 39 | R: Read + Seek, | 901 | 39 | F: FnMut(&[u8]), | 902 | | { | 903 | 39 | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 39 | let mut buffer = [0u8; 512]; | 905 | | | 906 | 39 | let buf_unit = usize::from(type_.byte_len()); | 907 | 39 | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 39 | let cls = type_.endian_bytes(); | 910 | 39 | let native = ByteOrder::native(); | 911 | | | 912 | 271 | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 257 | let now = total_bytes.min(mul_of_ty as u64); | 915 | 257 | total_bytes -= now; | 916 | | | 917 | 257 | let buffer = &mut buffer[..now as usize]; | 918 | 257 | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 232 | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 232 | collect(buffer); | 922 | | } | 923 | | | 924 | 14 | Ok(()) | 925 | 39 | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#5}>Line | Count | Source | 892 | 9.93k | fn decode_values<R, F>( | 893 | 9.93k | &self, | 894 | 9.93k | value_count: u64, | 895 | 9.93k | type_: Type, | 896 | 9.93k | reader: &mut EndianReader<R>, | 897 | 9.93k | mut collect: F, | 898 | 9.93k | ) -> TiffResult<()> | 899 | 9.93k | where | 900 | 9.93k | R: Read + Seek, | 901 | 9.93k | F: FnMut(&[u8]), | 902 | | { | 903 | 9.93k | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 9.93k | let mut buffer = [0u8; 512]; | 905 | | | 906 | 9.93k | let buf_unit = usize::from(type_.byte_len()); | 907 | 9.93k | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 9.93k | let cls = type_.endian_bytes(); | 910 | 9.93k | let native = ByteOrder::native(); | 911 | | | 912 | 20.4k | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 10.5k | let now = total_bytes.min(mul_of_ty as u64); | 915 | 10.5k | total_bytes -= now; | 916 | | | 917 | 10.5k | let buffer = &mut buffer[..now as usize]; | 918 | 10.5k | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 10.5k | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 10.5k | collect(buffer); | 922 | | } | 923 | | | 924 | 9.89k | Ok(()) | 925 | 9.93k | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#6}>Line | Count | Source | 892 | 41 | fn decode_values<R, F>( | 893 | 41 | &self, | 894 | 41 | value_count: u64, | 895 | 41 | type_: Type, | 896 | 41 | reader: &mut EndianReader<R>, | 897 | 41 | mut collect: F, | 898 | 41 | ) -> TiffResult<()> | 899 | 41 | where | 900 | 41 | R: Read + Seek, | 901 | 41 | F: FnMut(&[u8]), | 902 | | { | 903 | 41 | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 41 | let mut buffer = [0u8; 512]; | 905 | | | 906 | 41 | let buf_unit = usize::from(type_.byte_len()); | 907 | 41 | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 41 | let cls = type_.endian_bytes(); | 910 | 41 | let native = ByteOrder::native(); | 911 | | | 912 | 361 | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 346 | let now = total_bytes.min(mul_of_ty as u64); | 915 | 346 | total_bytes -= now; | 916 | | | 917 | 346 | let buffer = &mut buffer[..now as usize]; | 918 | 346 | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 320 | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 320 | collect(buffer); | 922 | | } | 923 | | | 924 | 15 | Ok(()) | 925 | 41 | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#7}>Line | Count | Source | 892 | 32 | fn decode_values<R, F>( | 893 | 32 | &self, | 894 | 32 | value_count: u64, | 895 | 32 | type_: Type, | 896 | 32 | reader: &mut EndianReader<R>, | 897 | 32 | mut collect: F, | 898 | 32 | ) -> TiffResult<()> | 899 | 32 | where | 900 | 32 | R: Read + Seek, | 901 | 32 | F: FnMut(&[u8]), | 902 | | { | 903 | 32 | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 32 | let mut buffer = [0u8; 512]; | 905 | | | 906 | 32 | let buf_unit = usize::from(type_.byte_len()); | 907 | 32 | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 32 | let cls = type_.endian_bytes(); | 910 | 32 | let native = ByteOrder::native(); | 911 | | | 912 | 242 | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 230 | let now = total_bytes.min(mul_of_ty as u64); | 915 | 230 | total_bytes -= now; | 916 | | | 917 | 230 | let buffer = &mut buffer[..now as usize]; | 918 | 230 | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 210 | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 210 | collect(buffer); | 922 | | } | 923 | | | 924 | 12 | Ok(()) | 925 | 32 | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#8}>Line | Count | Source | 892 | 39 | fn decode_values<R, F>( | 893 | 39 | &self, | 894 | 39 | value_count: u64, | 895 | 39 | type_: Type, | 896 | 39 | reader: &mut EndianReader<R>, | 897 | 39 | mut collect: F, | 898 | 39 | ) -> TiffResult<()> | 899 | 39 | where | 900 | 39 | R: Read + Seek, | 901 | 39 | F: FnMut(&[u8]), | 902 | | { | 903 | 39 | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 39 | let mut buffer = [0u8; 512]; | 905 | | | 906 | 39 | let buf_unit = usize::from(type_.byte_len()); | 907 | 39 | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 39 | let cls = type_.endian_bytes(); | 910 | 39 | let native = ByteOrder::native(); | 911 | | | 912 | 265 | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 247 | let now = total_bytes.min(mul_of_ty as u64); | 915 | 247 | total_bytes -= now; | 916 | | | 917 | 247 | let buffer = &mut buffer[..now as usize]; | 918 | 247 | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 226 | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 226 | collect(buffer); | 922 | | } | 923 | | | 924 | 18 | Ok(()) | 925 | 39 | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#9}>Line | Count | Source | 892 | 45 | fn decode_values<R, F>( | 893 | 45 | &self, | 894 | 45 | value_count: u64, | 895 | 45 | type_: Type, | 896 | 45 | reader: &mut EndianReader<R>, | 897 | 45 | mut collect: F, | 898 | 45 | ) -> TiffResult<()> | 899 | 45 | where | 900 | 45 | R: Read + Seek, | 901 | 45 | F: FnMut(&[u8]), | 902 | | { | 903 | 45 | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 45 | let mut buffer = [0u8; 512]; | 905 | | | 906 | 45 | let buf_unit = usize::from(type_.byte_len()); | 907 | 45 | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 45 | let cls = type_.endian_bytes(); | 910 | 45 | let native = ByteOrder::native(); | 911 | | | 912 | 301 | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 287 | let now = total_bytes.min(mul_of_ty as u64); | 915 | 287 | total_bytes -= now; | 916 | | | 917 | 287 | let buffer = &mut buffer[..now as usize]; | 918 | 287 | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 256 | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 256 | collect(buffer); | 922 | | } | 923 | | | 924 | 14 | Ok(()) | 925 | 45 | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#10}>Line | Count | Source | 892 | 49 | fn decode_values<R, F>( | 893 | 49 | &self, | 894 | 49 | value_count: u64, | 895 | 49 | type_: Type, | 896 | 49 | reader: &mut EndianReader<R>, | 897 | 49 | mut collect: F, | 898 | 49 | ) -> TiffResult<()> | 899 | 49 | where | 900 | 49 | R: Read + Seek, | 901 | 49 | F: FnMut(&[u8]), | 902 | | { | 903 | 49 | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 49 | let mut buffer = [0u8; 512]; | 905 | | | 906 | 49 | let buf_unit = usize::from(type_.byte_len()); | 907 | 49 | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 49 | let cls = type_.endian_bytes(); | 910 | 49 | let native = ByteOrder::native(); | 911 | | | 912 | 269 | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 256 | let now = total_bytes.min(mul_of_ty as u64); | 915 | 256 | total_bytes -= now; | 916 | | | 917 | 256 | let buffer = &mut buffer[..now as usize]; | 918 | 256 | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 220 | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 220 | collect(buffer); | 922 | | } | 923 | | | 924 | 13 | Ok(()) | 925 | 49 | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#11}>Line | Count | Source | 892 | 441 | fn decode_values<R, F>( | 893 | 441 | &self, | 894 | 441 | value_count: u64, | 895 | 441 | type_: Type, | 896 | 441 | reader: &mut EndianReader<R>, | 897 | 441 | mut collect: F, | 898 | 441 | ) -> TiffResult<()> | 899 | 441 | where | 900 | 441 | R: Read + Seek, | 901 | 441 | F: FnMut(&[u8]), | 902 | | { | 903 | 441 | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 441 | let mut buffer = [0u8; 512]; | 905 | | | 906 | 441 | let buf_unit = usize::from(type_.byte_len()); | 907 | 441 | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 441 | let cls = type_.endian_bytes(); | 910 | 441 | let native = ByteOrder::native(); | 911 | | | 912 | 1.10k | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 701 | let now = total_bytes.min(mul_of_ty as u64); | 915 | 701 | total_bytes -= now; | 916 | | | 917 | 701 | let buffer = &mut buffer[..now as usize]; | 918 | 701 | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 662 | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 662 | collect(buffer); | 922 | | } | 923 | | | 924 | 402 | Ok(()) | 925 | 441 | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#1}>Line | Count | Source | 892 | 4.66k | fn decode_values<R, F>( | 893 | 4.66k | &self, | 894 | 4.66k | value_count: u64, | 895 | 4.66k | type_: Type, | 896 | 4.66k | reader: &mut EndianReader<R>, | 897 | 4.66k | mut collect: F, | 898 | 4.66k | ) -> TiffResult<()> | 899 | 4.66k | where | 900 | 4.66k | R: Read + Seek, | 901 | 4.66k | F: FnMut(&[u8]), | 902 | | { | 903 | 4.66k | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 4.66k | let mut buffer = [0u8; 512]; | 905 | | | 906 | 4.66k | let buf_unit = usize::from(type_.byte_len()); | 907 | 4.66k | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 4.66k | let cls = type_.endian_bytes(); | 910 | 4.66k | let native = ByteOrder::native(); | 911 | | | 912 | 16.9k | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 12.3k | let now = total_bytes.min(mul_of_ty as u64); | 915 | 12.3k | total_bytes -= now; | 916 | | | 917 | 12.3k | let buffer = &mut buffer[..now as usize]; | 918 | 12.3k | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 12.2k | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 12.2k | collect(buffer); | 922 | | } | 923 | | | 924 | 4.61k | Ok(()) | 925 | 4.66k | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#12}>Line | Count | Source | 892 | 35 | fn decode_values<R, F>( | 893 | 35 | &self, | 894 | 35 | value_count: u64, | 895 | 35 | type_: Type, | 896 | 35 | reader: &mut EndianReader<R>, | 897 | 35 | mut collect: F, | 898 | 35 | ) -> TiffResult<()> | 899 | 35 | where | 900 | 35 | R: Read + Seek, | 901 | 35 | F: FnMut(&[u8]), | 902 | | { | 903 | 35 | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 35 | let mut buffer = [0u8; 512]; | 905 | | | 906 | 35 | let buf_unit = usize::from(type_.byte_len()); | 907 | 35 | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 35 | let cls = type_.endian_bytes(); | 910 | 35 | let native = ByteOrder::native(); | 911 | | | 912 | 264 | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 252 | let now = total_bytes.min(mul_of_ty as u64); | 915 | 252 | total_bytes -= now; | 916 | | | 917 | 252 | let buffer = &mut buffer[..now as usize]; | 918 | 252 | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 229 | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 229 | collect(buffer); | 922 | | } | 923 | | | 924 | 12 | Ok(()) | 925 | 35 | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#13}>Line | Count | Source | 892 | 57 | fn decode_values<R, F>( | 893 | 57 | &self, | 894 | 57 | value_count: u64, | 895 | 57 | type_: Type, | 896 | 57 | reader: &mut EndianReader<R>, | 897 | 57 | mut collect: F, | 898 | 57 | ) -> TiffResult<()> | 899 | 57 | where | 900 | 57 | R: Read + Seek, | 901 | 57 | F: FnMut(&[u8]), | 902 | | { | 903 | 57 | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 57 | let mut buffer = [0u8; 512]; | 905 | | | 906 | 57 | let buf_unit = usize::from(type_.byte_len()); | 907 | 57 | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 57 | let cls = type_.endian_bytes(); | 910 | 57 | let native = ByteOrder::native(); | 911 | | | 912 | 340 | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 313 | let now = total_bytes.min(mul_of_ty as u64); | 915 | 313 | total_bytes -= now; | 916 | | | 917 | 313 | let buffer = &mut buffer[..now as usize]; | 918 | 313 | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 283 | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 283 | collect(buffer); | 922 | | } | 923 | | | 924 | 27 | Ok(()) | 925 | 57 | } |
<tiff::decoder::ifd::Entry>::decode_values::<std::io::cursor::Cursor<&[u8]>, <tiff::decoder::ifd::Entry>::val<std::io::cursor::Cursor<&[u8]>>::{closure#14}>Line | Count | Source | 892 | 88 | fn decode_values<R, F>( | 893 | 88 | &self, | 894 | 88 | value_count: u64, | 895 | 88 | type_: Type, | 896 | 88 | reader: &mut EndianReader<R>, | 897 | 88 | mut collect: F, | 898 | 88 | ) -> TiffResult<()> | 899 | 88 | where | 900 | 88 | R: Read + Seek, | 901 | 88 | F: FnMut(&[u8]), | 902 | | { | 903 | 88 | let mut total_bytes = type_.value_bytes(value_count)?; | 904 | 88 | let mut buffer = [0u8; 512]; | 905 | | | 906 | 88 | let buf_unit = usize::from(type_.byte_len()); | 907 | 88 | let mul_of_ty = buffer.len() / buf_unit * buf_unit; | 908 | | | 909 | 88 | let cls = type_.endian_bytes(); | 910 | 88 | let native = ByteOrder::native(); | 911 | | | 912 | 504 | while total_bytes > 0 { | 913 | | // `now <= mul_of_ty < 512` so casting is mathematical | 914 | 448 | let now = total_bytes.min(mul_of_ty as u64); | 915 | 448 | total_bytes -= now; | 916 | | | 917 | 448 | let buffer = &mut buffer[..now as usize]; | 918 | 448 | reader.inner().read_exact(buffer)?; | 919 | | | 920 | 416 | reader.byte_order.convert_endian_bytes(cls, buffer, native); | 921 | 416 | collect(buffer); | 922 | | } | 923 | | | 924 | 56 | Ok(()) | 925 | 88 | } |
Unexecuted instantiation: <tiff::decoder::ifd::Entry>::decode_values::<_, _> |
926 | | } |
927 | | |
928 | | /// Extracts a list of BYTE tags stored in an offset |
929 | | #[inline] |
930 | 42 | fn offset_to_bytes(n: usize, entry: &Entry) -> TiffResult<Value> { |
931 | | Ok(List( |
932 | 42 | entry.offset[0..n] |
933 | 42 | .iter() |
934 | 144 | .map(|&e| Unsigned(u32::from(e))) tiff::decoder::ifd::offset_to_bytes::{closure#0}Line | Count | Source | 934 | 144 | .map(|&e| Unsigned(u32::from(e))) |
Unexecuted instantiation: tiff::decoder::ifd::offset_to_bytes::{closure#0} |
935 | 42 | .collect(), |
936 | | )) |
937 | 42 | } tiff::decoder::ifd::offset_to_bytes Line | Count | Source | 930 | 42 | fn offset_to_bytes(n: usize, entry: &Entry) -> TiffResult<Value> { | 931 | | Ok(List( | 932 | 42 | entry.offset[0..n] | 933 | 42 | .iter() | 934 | 42 | .map(|&e| Unsigned(u32::from(e))) | 935 | 42 | .collect(), | 936 | | )) | 937 | 42 | } |
Unexecuted instantiation: tiff::decoder::ifd::offset_to_bytes |
938 | | |
939 | | /// Extracts a list of SBYTE tags stored in an offset |
940 | | #[inline] |
941 | 8 | fn offset_to_sbytes(n: usize, entry: &Entry) -> TiffResult<Value> { |
942 | | Ok(List( |
943 | 8 | entry.offset[0..n] |
944 | 8 | .iter() |
945 | 38 | .map(|&e| Signed(i32::from(e as i8))) tiff::decoder::ifd::offset_to_sbytes::{closure#0}Line | Count | Source | 945 | 38 | .map(|&e| Signed(i32::from(e as i8))) |
Unexecuted instantiation: tiff::decoder::ifd::offset_to_sbytes::{closure#0} |
946 | 8 | .collect(), |
947 | | )) |
948 | 8 | } tiff::decoder::ifd::offset_to_sbytes Line | Count | Source | 941 | 8 | fn offset_to_sbytes(n: usize, entry: &Entry) -> TiffResult<Value> { | 942 | | Ok(List( | 943 | 8 | entry.offset[0..n] | 944 | 8 | .iter() | 945 | 8 | .map(|&e| Signed(i32::from(e as i8))) | 946 | 8 | .collect(), | 947 | | )) | 948 | 8 | } |
Unexecuted instantiation: tiff::decoder::ifd::offset_to_sbytes |
949 | | |
950 | | /// Type representing an Image File Directory |
951 | | #[doc(hidden)] |
952 | | #[deprecated = "Use struct `tiff::Directory` instead which contains all fields relevant to an Image File Directory, including the offset to the next directory"] |
953 | | pub type Directory = HashMap<Tag, Entry>; |