Coverage Report

Created: 2026-03-10 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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>;