Coverage Report

Created: 2025-10-14 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zune-jpeg-0.4.21/src/headers.rs
Line
Count
Source
1
/*
2
 * Copyright (c) 2023.
3
 *
4
 * This software is free software;
5
 *
6
 * You can redistribute it or modify it under terms of the MIT, Apache License or Zlib license
7
 */
8
9
//! Decode Decoder markers/segments
10
//!
11
//! This file deals with decoding header information in a jpeg file
12
//!
13
use alloc::format;
14
use alloc::string::ToString;
15
use alloc::vec::Vec;
16
17
use zune_core::bytestream::ZReaderTrait;
18
use zune_core::colorspace::ColorSpace;
19
use zune_core::log::{debug, error, trace, warn};
20
21
use crate::components::Components;
22
use crate::decoder::{ICCChunk, JpegDecoder, MAX_COMPONENTS};
23
use crate::errors::DecodeErrors;
24
use crate::huffman::HuffmanTable;
25
use crate::misc::{SOFMarkers, UN_ZIGZAG};
26
27
///**B.2.4.2 Huffman table-specification syntax**
28
#[allow(clippy::similar_names, clippy::cast_sign_loss)]
29
47.2k
pub(crate) fn parse_huffman<T: ZReaderTrait>(
30
47.2k
    decoder: &mut JpegDecoder<T>
31
47.2k
) -> Result<(), DecodeErrors>
32
47.2k
where
33
{
34
    // Read the length of the Huffman table
35
47.2k
    let mut dht_length = i32::from(decoder.stream.get_u16_be_err()?.checked_sub(2).ok_or(
36
47.1k
        DecodeErrors::FormatStatic("Invalid Huffman length in image")
37
3
    )?);
38
39
132k
    while dht_length > 16 {
40
        // HT information
41
86.0k
        let ht_info = decoder.stream.get_u8_err()?;
42
        // third bit indicates whether the huffman encoding is DC or AC type
43
86.0k
        let dc_or_ac = (ht_info >> 4) & 0xF;
44
        // Indicate the position of this table, should be less than 4;
45
86.0k
        let index = (ht_info & 0xF) as usize;
46
        // read the number of symbols
47
86.0k
        let mut num_symbols: [u8; 17] = [0; 17];
48
49
86.0k
        if index >= MAX_COMPONENTS {
50
33
            return Err(DecodeErrors::HuffmanDecode(format!(
51
33
                "Invalid DHT index {index}, expected between 0 and 3"
52
33
            )));
53
85.9k
        }
54
55
85.9k
        if dc_or_ac > 1 {
56
10
            return Err(DecodeErrors::HuffmanDecode(format!(
57
10
                "Invalid DHT position {dc_or_ac}, should be 0 or 1"
58
10
            )));
59
85.9k
        }
60
61
85.9k
        decoder
62
85.9k
            .stream
63
85.9k
            .read_exact(&mut num_symbols[1..17])
64
85.9k
            .map_err(|_| DecodeErrors::ExhaustedData)?;
65
66
85.8k
        dht_length -= 1 + 16;
67
68
1.45M
        let symbols_sum: i32 = num_symbols.iter().map(|f| i32::from(*f)).sum();
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<_>::{closure#1}
zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#1}
Line
Count
Source
68
409k
        let symbols_sum: i32 = num_symbols.iter().map(|f| i32::from(*f)).sum();
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#1}
zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#1}
Line
Count
Source
68
497k
        let symbols_sum: i32 = num_symbols.iter().map(|f| i32::from(*f)).sum();
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#1}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#1}
zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#1}
Line
Count
Source
68
61.1k
        let symbols_sum: i32 = num_symbols.iter().map(|f| i32::from(*f)).sum();
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#1}
zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#1}
Line
Count
Source
68
491k
        let symbols_sum: i32 = num_symbols.iter().map(|f| i32::from(*f)).sum();
69
70
        // The sum of the number of symbols cannot be greater than 256;
71
85.8k
        if symbols_sum > 256 {
72
82
            return Err(DecodeErrors::FormatStatic(
73
82
                "Encountered Huffman table with excessive length in DHT"
74
82
            ));
75
85.7k
        }
76
85.7k
        if symbols_sum > dht_length {
77
38
            return Err(DecodeErrors::HuffmanDecode(format!(
78
38
                "Excessive Huffman table of length {symbols_sum} found when header length is {dht_length}"
79
38
            )));
80
85.7k
        }
81
85.7k
        dht_length -= symbols_sum;
82
        // A table containing symbols in increasing code length
83
85.7k
        let mut symbols = [0; 256];
84
85
85.7k
        decoder
86
85.7k
            .stream
87
85.7k
            .read_exact(&mut symbols[0..(symbols_sum as usize)])
88
85.7k
            .map_err(|x| {
89
70
                DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
90
70
            })?;
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<_>::{closure#2}
zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#2}
Line
Count
Source
88
23
            .map_err(|x| {
89
23
                DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
90
23
            })?;
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#2}
zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#2}
Line
Count
Source
88
24
            .map_err(|x| {
89
24
                DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
90
24
            })?;
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#2}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#2}
zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>::{closure#2}
Line
Count
Source
88
3
            .map_err(|x| {
89
3
                DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
90
3
            })?;
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>::{closure#2}
zune_jpeg::headers::parse_huffman::<&[u8]>::{closure#2}
Line
Count
Source
88
20
            .map_err(|x| {
89
20
                DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
90
20
            })?;
91
        // store
92
85.6k
        match dc_or_ac {
93
            0 => {
94
49.9k
                decoder.dc_huffman_tables[index] = Some(HuffmanTable::new(
95
49.9k
                    &num_symbols,
96
49.9k
                    symbols,
97
                    true,
98
49.9k
                    decoder.is_progressive
99
363
                )?);
100
            }
101
            _ => {
102
35.6k
                decoder.ac_huffman_tables[index] = Some(HuffmanTable::new(
103
35.6k
                    &num_symbols,
104
35.6k
                    symbols,
105
                    false,
106
35.6k
                    decoder.is_progressive
107
13
                )?);
108
            }
109
        }
110
    }
111
112
46.4k
    if dht_length > 0 {
113
4
        return Err(DecodeErrors::FormatStatic("Bogus Huffman table definition"));
114
46.4k
    }
115
116
46.4k
    Ok(())
117
47.2k
}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<_>
zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>
Line
Count
Source
29
11.7k
pub(crate) fn parse_huffman<T: ZReaderTrait>(
30
11.7k
    decoder: &mut JpegDecoder<T>
31
11.7k
) -> Result<(), DecodeErrors>
32
11.7k
where
33
{
34
    // Read the length of the Huffman table
35
11.7k
    let mut dht_length = i32::from(decoder.stream.get_u16_be_err()?.checked_sub(2).ok_or(
36
11.7k
        DecodeErrors::FormatStatic("Invalid Huffman length in image")
37
2
    )?);
38
39
35.6k
    while dht_length > 16 {
40
        // HT information
41
24.1k
        let ht_info = decoder.stream.get_u8_err()?;
42
        // third bit indicates whether the huffman encoding is DC or AC type
43
24.1k
        let dc_or_ac = (ht_info >> 4) & 0xF;
44
        // Indicate the position of this table, should be less than 4;
45
24.1k
        let index = (ht_info & 0xF) as usize;
46
        // read the number of symbols
47
24.1k
        let mut num_symbols: [u8; 17] = [0; 17];
48
49
24.1k
        if index >= MAX_COMPONENTS {
50
7
            return Err(DecodeErrors::HuffmanDecode(format!(
51
7
                "Invalid DHT index {index}, expected between 0 and 3"
52
7
            )));
53
24.1k
        }
54
55
24.1k
        if dc_or_ac > 1 {
56
2
            return Err(DecodeErrors::HuffmanDecode(format!(
57
2
                "Invalid DHT position {dc_or_ac}, should be 0 or 1"
58
2
            )));
59
24.1k
        }
60
61
24.1k
        decoder
62
24.1k
            .stream
63
24.1k
            .read_exact(&mut num_symbols[1..17])
64
24.1k
            .map_err(|_| DecodeErrors::ExhaustedData)?;
65
66
24.0k
        dht_length -= 1 + 16;
67
68
24.0k
        let symbols_sum: i32 = num_symbols.iter().map(|f| i32::from(*f)).sum();
69
70
        // The sum of the number of symbols cannot be greater than 256;
71
24.0k
        if symbols_sum > 256 {
72
22
            return Err(DecodeErrors::FormatStatic(
73
22
                "Encountered Huffman table with excessive length in DHT"
74
22
            ));
75
24.0k
        }
76
24.0k
        if symbols_sum > dht_length {
77
17
            return Err(DecodeErrors::HuffmanDecode(format!(
78
17
                "Excessive Huffman table of length {symbols_sum} found when header length is {dht_length}"
79
17
            )));
80
24.0k
        }
81
24.0k
        dht_length -= symbols_sum;
82
        // A table containing symbols in increasing code length
83
24.0k
        let mut symbols = [0; 256];
84
85
24.0k
        decoder
86
24.0k
            .stream
87
24.0k
            .read_exact(&mut symbols[0..(symbols_sum as usize)])
88
24.0k
            .map_err(|x| {
89
                DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
90
23
            })?;
91
        // store
92
24.0k
        match dc_or_ac {
93
            0 => {
94
16.0k
                decoder.dc_huffman_tables[index] = Some(HuffmanTable::new(
95
16.0k
                    &num_symbols,
96
16.0k
                    symbols,
97
                    true,
98
16.0k
                    decoder.is_progressive
99
77
                )?);
100
            }
101
            _ => {
102
7.99k
                decoder.ac_huffman_tables[index] = Some(HuffmanTable::new(
103
7.99k
                    &num_symbols,
104
7.99k
                    symbols,
105
                    false,
106
7.99k
                    decoder.is_progressive
107
1
                )?);
108
            }
109
        }
110
    }
111
112
11.5k
    if dht_length > 0 {
113
2
        return Err(DecodeErrors::FormatStatic("Bogus Huffman table definition"));
114
11.5k
    }
115
116
11.5k
    Ok(())
117
11.7k
}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_huffman::<&[u8]>
Line
Count
Source
29
20.3k
pub(crate) fn parse_huffman<T: ZReaderTrait>(
30
20.3k
    decoder: &mut JpegDecoder<T>
31
20.3k
) -> Result<(), DecodeErrors>
32
20.3k
where
33
{
34
    // Read the length of the Huffman table
35
20.3k
    let mut dht_length = i32::from(decoder.stream.get_u16_be_err()?.checked_sub(2).ok_or(
36
20.3k
        DecodeErrors::FormatStatic("Invalid Huffman length in image")
37
0
    )?);
38
39
49.3k
    while dht_length > 16 {
40
        // HT information
41
29.3k
        let ht_info = decoder.stream.get_u8_err()?;
42
        // third bit indicates whether the huffman encoding is DC or AC type
43
29.3k
        let dc_or_ac = (ht_info >> 4) & 0xF;
44
        // Indicate the position of this table, should be less than 4;
45
29.3k
        let index = (ht_info & 0xF) as usize;
46
        // read the number of symbols
47
29.3k
        let mut num_symbols: [u8; 17] = [0; 17];
48
49
29.3k
        if index >= MAX_COMPONENTS {
50
15
            return Err(DecodeErrors::HuffmanDecode(format!(
51
15
                "Invalid DHT index {index}, expected between 0 and 3"
52
15
            )));
53
29.3k
        }
54
55
29.3k
        if dc_or_ac > 1 {
56
4
            return Err(DecodeErrors::HuffmanDecode(format!(
57
4
                "Invalid DHT position {dc_or_ac}, should be 0 or 1"
58
4
            )));
59
29.3k
        }
60
61
29.3k
        decoder
62
29.3k
            .stream
63
29.3k
            .read_exact(&mut num_symbols[1..17])
64
29.3k
            .map_err(|_| DecodeErrors::ExhaustedData)?;
65
66
29.2k
        dht_length -= 1 + 16;
67
68
29.2k
        let symbols_sum: i32 = num_symbols.iter().map(|f| i32::from(*f)).sum();
69
70
        // The sum of the number of symbols cannot be greater than 256;
71
29.2k
        if symbols_sum > 256 {
72
21
            return Err(DecodeErrors::FormatStatic(
73
21
                "Encountered Huffman table with excessive length in DHT"
74
21
            ));
75
29.2k
        }
76
29.2k
        if symbols_sum > dht_length {
77
5
            return Err(DecodeErrors::HuffmanDecode(format!(
78
5
                "Excessive Huffman table of length {symbols_sum} found when header length is {dht_length}"
79
5
            )));
80
29.2k
        }
81
29.2k
        dht_length -= symbols_sum;
82
        // A table containing symbols in increasing code length
83
29.2k
        let mut symbols = [0; 256];
84
85
29.2k
        decoder
86
29.2k
            .stream
87
29.2k
            .read_exact(&mut symbols[0..(symbols_sum as usize)])
88
29.2k
            .map_err(|x| {
89
                DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
90
24
            })?;
91
        // store
92
29.1k
        match dc_or_ac {
93
            0 => {
94
12.7k
                decoder.dc_huffman_tables[index] = Some(HuffmanTable::new(
95
12.7k
                    &num_symbols,
96
12.7k
                    symbols,
97
                    true,
98
12.7k
                    decoder.is_progressive
99
147
                )?);
100
            }
101
            _ => {
102
16.4k
                decoder.ac_huffman_tables[index] = Some(HuffmanTable::new(
103
16.4k
                    &num_symbols,
104
16.4k
                    symbols,
105
                    false,
106
16.4k
                    decoder.is_progressive
107
7
                )?);
108
            }
109
        }
110
    }
111
112
19.9k
    if dht_length > 0 {
113
0
        return Err(DecodeErrors::FormatStatic("Bogus Huffman table definition"));
114
19.9k
    }
115
116
19.9k
    Ok(())
117
20.3k
}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&[u8]>
zune_jpeg::headers::parse_huffman::<alloc::vec::Vec<u8>>
Line
Count
Source
29
3.58k
pub(crate) fn parse_huffman<T: ZReaderTrait>(
30
3.58k
    decoder: &mut JpegDecoder<T>
31
3.58k
) -> Result<(), DecodeErrors>
32
3.58k
where
33
{
34
    // Read the length of the Huffman table
35
3.58k
    let mut dht_length = i32::from(decoder.stream.get_u16_be_err()?.checked_sub(2).ok_or(
36
3.57k
        DecodeErrors::FormatStatic("Invalid Huffman length in image")
37
1
    )?);
38
39
7.13k
    while dht_length > 16 {
40
        // HT information
41
3.60k
        let ht_info = decoder.stream.get_u8_err()?;
42
        // third bit indicates whether the huffman encoding is DC or AC type
43
3.60k
        let dc_or_ac = (ht_info >> 4) & 0xF;
44
        // Indicate the position of this table, should be less than 4;
45
3.60k
        let index = (ht_info & 0xF) as usize;
46
        // read the number of symbols
47
3.60k
        let mut num_symbols: [u8; 17] = [0; 17];
48
49
3.60k
        if index >= MAX_COMPONENTS {
50
4
            return Err(DecodeErrors::HuffmanDecode(format!(
51
4
                "Invalid DHT index {index}, expected between 0 and 3"
52
4
            )));
53
3.59k
        }
54
55
3.59k
        if dc_or_ac > 1 {
56
1
            return Err(DecodeErrors::HuffmanDecode(format!(
57
1
                "Invalid DHT position {dc_or_ac}, should be 0 or 1"
58
1
            )));
59
3.59k
        }
60
61
3.59k
        decoder
62
3.59k
            .stream
63
3.59k
            .read_exact(&mut num_symbols[1..17])
64
3.59k
            .map_err(|_| DecodeErrors::ExhaustedData)?;
65
66
3.59k
        dht_length -= 1 + 16;
67
68
3.59k
        let symbols_sum: i32 = num_symbols.iter().map(|f| i32::from(*f)).sum();
69
70
        // The sum of the number of symbols cannot be greater than 256;
71
3.59k
        if symbols_sum > 256 {
72
17
            return Err(DecodeErrors::FormatStatic(
73
17
                "Encountered Huffman table with excessive length in DHT"
74
17
            ));
75
3.57k
        }
76
3.57k
        if symbols_sum > dht_length {
77
5
            return Err(DecodeErrors::HuffmanDecode(format!(
78
5
                "Excessive Huffman table of length {symbols_sum} found when header length is {dht_length}"
79
5
            )));
80
3.57k
        }
81
3.57k
        dht_length -= symbols_sum;
82
        // A table containing symbols in increasing code length
83
3.57k
        let mut symbols = [0; 256];
84
85
3.57k
        decoder
86
3.57k
            .stream
87
3.57k
            .read_exact(&mut symbols[0..(symbols_sum as usize)])
88
3.57k
            .map_err(|x| {
89
                DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
90
3
            })?;
91
        // store
92
3.57k
        match dc_or_ac {
93
            0 => {
94
1.04k
                decoder.dc_huffman_tables[index] = Some(HuffmanTable::new(
95
1.04k
                    &num_symbols,
96
1.04k
                    symbols,
97
                    true,
98
1.04k
                    decoder.is_progressive
99
6
                )?);
100
            }
101
            _ => {
102
2.52k
                decoder.ac_huffman_tables[index] = Some(HuffmanTable::new(
103
2.52k
                    &num_symbols,
104
2.52k
                    symbols,
105
                    false,
106
2.52k
                    decoder.is_progressive
107
1
                )?);
108
            }
109
        }
110
    }
111
112
3.53k
    if dht_length > 0 {
113
1
        return Err(DecodeErrors::FormatStatic("Bogus Huffman table definition"));
114
3.53k
    }
115
116
3.53k
    Ok(())
117
3.58k
}
Unexecuted instantiation: zune_jpeg::headers::parse_huffman::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_huffman::<&[u8]>
Line
Count
Source
29
11.5k
pub(crate) fn parse_huffman<T: ZReaderTrait>(
30
11.5k
    decoder: &mut JpegDecoder<T>
31
11.5k
) -> Result<(), DecodeErrors>
32
11.5k
where
33
{
34
    // Read the length of the Huffman table
35
11.5k
    let mut dht_length = i32::from(decoder.stream.get_u16_be_err()?.checked_sub(2).ok_or(
36
11.5k
        DecodeErrors::FormatStatic("Invalid Huffman length in image")
37
0
    )?);
38
39
40.2k
    while dht_length > 16 {
40
        // HT information
41
28.9k
        let ht_info = decoder.stream.get_u8_err()?;
42
        // third bit indicates whether the huffman encoding is DC or AC type
43
28.9k
        let dc_or_ac = (ht_info >> 4) & 0xF;
44
        // Indicate the position of this table, should be less than 4;
45
28.9k
        let index = (ht_info & 0xF) as usize;
46
        // read the number of symbols
47
28.9k
        let mut num_symbols: [u8; 17] = [0; 17];
48
49
28.9k
        if index >= MAX_COMPONENTS {
50
7
            return Err(DecodeErrors::HuffmanDecode(format!(
51
7
                "Invalid DHT index {index}, expected between 0 and 3"
52
7
            )));
53
28.9k
        }
54
55
28.9k
        if dc_or_ac > 1 {
56
3
            return Err(DecodeErrors::HuffmanDecode(format!(
57
3
                "Invalid DHT position {dc_or_ac}, should be 0 or 1"
58
3
            )));
59
28.9k
        }
60
61
28.9k
        decoder
62
28.9k
            .stream
63
28.9k
            .read_exact(&mut num_symbols[1..17])
64
28.9k
            .map_err(|_| DecodeErrors::ExhaustedData)?;
65
66
28.9k
        dht_length -= 1 + 16;
67
68
28.9k
        let symbols_sum: i32 = num_symbols.iter().map(|f| i32::from(*f)).sum();
69
70
        // The sum of the number of symbols cannot be greater than 256;
71
28.9k
        if symbols_sum > 256 {
72
22
            return Err(DecodeErrors::FormatStatic(
73
22
                "Encountered Huffman table with excessive length in DHT"
74
22
            ));
75
28.9k
        }
76
28.9k
        if symbols_sum > dht_length {
77
11
            return Err(DecodeErrors::HuffmanDecode(format!(
78
11
                "Excessive Huffman table of length {symbols_sum} found when header length is {dht_length}"
79
11
            )));
80
28.8k
        }
81
28.8k
        dht_length -= symbols_sum;
82
        // A table containing symbols in increasing code length
83
28.8k
        let mut symbols = [0; 256];
84
85
28.8k
        decoder
86
28.8k
            .stream
87
28.8k
            .read_exact(&mut symbols[0..(symbols_sum as usize)])
88
28.8k
            .map_err(|x| {
89
                DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
90
20
            })?;
91
        // store
92
28.8k
        match dc_or_ac {
93
            0 => {
94
20.1k
                decoder.dc_huffman_tables[index] = Some(HuffmanTable::new(
95
20.1k
                    &num_symbols,
96
20.1k
                    symbols,
97
                    true,
98
20.1k
                    decoder.is_progressive
99
133
                )?);
100
            }
101
            _ => {
102
8.75k
                decoder.ac_huffman_tables[index] = Some(HuffmanTable::new(
103
8.75k
                    &num_symbols,
104
8.75k
                    symbols,
105
                    false,
106
8.75k
                    decoder.is_progressive
107
4
                )?);
108
            }
109
        }
110
    }
111
112
11.2k
    if dht_length > 0 {
113
1
        return Err(DecodeErrors::FormatStatic("Bogus Huffman table definition"));
114
11.2k
    }
115
116
11.2k
    Ok(())
117
11.5k
}
118
119
///**B.2.4.1 Quantization table-specification syntax**
120
#[allow(clippy::cast_possible_truncation, clippy::needless_range_loop)]
121
25.2k
pub(crate) fn parse_dqt<T: ZReaderTrait>(img: &mut JpegDecoder<T>) -> Result<(), DecodeErrors> {
122
    // read length
123
25.2k
    let mut qt_length =
124
25.2k
        img.stream
125
25.2k
            .get_u16_be_err()?
126
25.2k
            .checked_sub(2)
127
25.2k
            .ok_or(DecodeErrors::FormatStatic(
128
25.2k
                "Invalid DQT length. Length should be greater than 2"
129
25.2k
            ))?;
130
    // A single DQT header may have multiple QT's
131
53.8k
    while qt_length > 0 {
132
28.7k
        let qt_info = img.stream.get_u8_err()?;
133
        // 0 = 8 bit otherwise 16 bit dqt
134
28.7k
        let precision = (qt_info >> 4) as usize;
135
        // last 4 bits give us position
136
28.7k
        let table_position = (qt_info & 0x0f) as usize;
137
28.7k
        let precision_value = 64 * (precision + 1);
138
139
28.7k
        if (precision_value + 1) as u16 > qt_length {
140
13
            return Err(DecodeErrors::DqtError(format!("Invalid QT table bytes left :{}. Too small to construct a valid qt table which should be {} long", qt_length, precision_value + 1)));
141
28.7k
        }
142
143
28.7k
        let dct_table = match precision {
144
            0 => {
145
25.7k
                let mut qt_values = [0; 64];
146
147
25.7k
                img.stream.read_exact(&mut qt_values).map_err(|x| {
148
46
                    DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
149
46
                })?;
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<_>::{closure#0}
zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>::{closure#0}
Line
Count
Source
147
13
                img.stream.read_exact(&mut qt_values).map_err(|x| {
148
13
                    DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
149
13
                })?;
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>::{closure#0}
zune_jpeg::headers::parse_dqt::<&[u8]>::{closure#0}
Line
Count
Source
147
18
                img.stream.read_exact(&mut qt_values).map_err(|x| {
148
18
                    DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
149
18
                })?;
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>::{closure#0}
zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>::{closure#0}
Line
Count
Source
147
8
                img.stream.read_exact(&mut qt_values).map_err(|x| {
148
8
                    DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
149
8
                })?;
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>::{closure#0}
zune_jpeg::headers::parse_dqt::<&[u8]>::{closure#0}
Line
Count
Source
147
7
                img.stream.read_exact(&mut qt_values).map_err(|x| {
148
7
                    DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
149
7
                })?;
150
25.6k
                qt_length -= (precision_value as u16) + 1 /*QT BIT*/;
151
                // carry out un zig-zag here
152
25.6k
                un_zig_zag(&qt_values)
153
            }
154
            1 => {
155
                // 16 bit quantization tables
156
2.95k
                let mut qt_values = [0_u16; 64];
157
158
190k
                for i in 0..64 {
159
187k
                    qt_values[i] = img.stream.get_u16_be_err()?;
160
                }
161
2.88k
                qt_length -= (precision_value as u16) + 1;
162
163
2.88k
                un_zig_zag(&qt_values)
164
            }
165
            _ => {
166
40
                return Err(DecodeErrors::DqtError(format!(
167
40
                    "Expected QT precision value of either 0 or 1, found {precision:?}"
168
40
                )));
169
            }
170
        };
171
172
28.5k
        if table_position >= MAX_COMPONENTS {
173
21
            return Err(DecodeErrors::DqtError(format!(
174
21
                "Too large table position for QT :{table_position}, expected between 0 and 3"
175
21
            )));
176
28.5k
        }
177
178
28.5k
        img.qt_tables[table_position] = Some(dct_table);
179
    }
180
181
25.0k
    return Ok(());
182
25.2k
}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<_>
zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>
Line
Count
Source
121
5.19k
pub(crate) fn parse_dqt<T: ZReaderTrait>(img: &mut JpegDecoder<T>) -> Result<(), DecodeErrors> {
122
    // read length
123
5.19k
    let mut qt_length =
124
5.19k
        img.stream
125
5.19k
            .get_u16_be_err()?
126
5.19k
            .checked_sub(2)
127
5.19k
            .ok_or(DecodeErrors::FormatStatic(
128
5.19k
                "Invalid DQT length. Length should be greater than 2"
129
5.19k
            ))?;
130
    // A single DQT header may have multiple QT's
131
10.7k
    while qt_length > 0 {
132
5.55k
        let qt_info = img.stream.get_u8_err()?;
133
        // 0 = 8 bit otherwise 16 bit dqt
134
5.55k
        let precision = (qt_info >> 4) as usize;
135
        // last 4 bits give us position
136
5.55k
        let table_position = (qt_info & 0x0f) as usize;
137
5.55k
        let precision_value = 64 * (precision + 1);
138
139
5.55k
        if (precision_value + 1) as u16 > qt_length {
140
3
            return Err(DecodeErrors::DqtError(format!("Invalid QT table bytes left :{}. Too small to construct a valid qt table which should be {} long", qt_length, precision_value + 1)));
141
5.55k
        }
142
143
5.55k
        let dct_table = match precision {
144
            0 => {
145
5.45k
                let mut qt_values = [0; 64];
146
147
5.45k
                img.stream.read_exact(&mut qt_values).map_err(|x| {
148
                    DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
149
13
                })?;
150
5.44k
                qt_length -= (precision_value as u16) + 1 /*QT BIT*/;
151
                // carry out un zig-zag here
152
5.44k
                un_zig_zag(&qt_values)
153
            }
154
            1 => {
155
                // 16 bit quantization tables
156
78
                let mut qt_values = [0_u16; 64];
157
158
4.66k
                for i in 0..64 {
159
4.60k
                    qt_values[i] = img.stream.get_u16_be_err()?;
160
                }
161
64
                qt_length -= (precision_value as u16) + 1;
162
163
64
                un_zig_zag(&qt_values)
164
            }
165
            _ => {
166
21
                return Err(DecodeErrors::DqtError(format!(
167
21
                    "Expected QT precision value of either 0 or 1, found {precision:?}"
168
21
                )));
169
            }
170
        };
171
172
5.50k
        if table_position >= MAX_COMPONENTS {
173
1
            return Err(DecodeErrors::DqtError(format!(
174
1
                "Too large table position for QT :{table_position}, expected between 0 and 3"
175
1
            )));
176
5.50k
        }
177
178
5.50k
        img.qt_tables[table_position] = Some(dct_table);
179
    }
180
181
5.14k
    return Ok(());
182
5.19k
}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_dqt::<&[u8]>
Line
Count
Source
121
9.98k
pub(crate) fn parse_dqt<T: ZReaderTrait>(img: &mut JpegDecoder<T>) -> Result<(), DecodeErrors> {
122
    // read length
123
9.97k
    let mut qt_length =
124
9.98k
        img.stream
125
9.98k
            .get_u16_be_err()?
126
9.97k
            .checked_sub(2)
127
9.97k
            .ok_or(DecodeErrors::FormatStatic(
128
9.97k
                "Invalid DQT length. Length should be greater than 2"
129
9.97k
            ))?;
130
    // A single DQT header may have multiple QT's
131
22.7k
    while qt_length > 0 {
132
12.8k
        let qt_info = img.stream.get_u8_err()?;
133
        // 0 = 8 bit otherwise 16 bit dqt
134
12.8k
        let precision = (qt_info >> 4) as usize;
135
        // last 4 bits give us position
136
12.8k
        let table_position = (qt_info & 0x0f) as usize;
137
12.8k
        let precision_value = 64 * (precision + 1);
138
139
12.8k
        if (precision_value + 1) as u16 > qt_length {
140
3
            return Err(DecodeErrors::DqtError(format!("Invalid QT table bytes left :{}. Too small to construct a valid qt table which should be {} long", qt_length, precision_value + 1)));
141
12.8k
        }
142
143
12.8k
        let dct_table = match precision {
144
            0 => {
145
10.2k
                let mut qt_values = [0; 64];
146
147
10.2k
                img.stream.read_exact(&mut qt_values).map_err(|x| {
148
                    DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
149
18
                })?;
150
10.2k
                qt_length -= (precision_value as u16) + 1 /*QT BIT*/;
151
                // carry out un zig-zag here
152
10.2k
                un_zig_zag(&qt_values)
153
            }
154
            1 => {
155
                // 16 bit quantization tables
156
2.58k
                let mut qt_values = [0_u16; 64];
157
158
166k
                for i in 0..64 {
159
164k
                    qt_values[i] = img.stream.get_u16_be_err()?;
160
                }
161
2.54k
                qt_length -= (precision_value as u16) + 1;
162
163
2.54k
                un_zig_zag(&qt_values)
164
            }
165
            _ => {
166
7
                return Err(DecodeErrors::DqtError(format!(
167
7
                    "Expected QT precision value of either 0 or 1, found {precision:?}"
168
7
                )));
169
            }
170
        };
171
172
12.8k
        if table_position >= MAX_COMPONENTS {
173
1
            return Err(DecodeErrors::DqtError(format!(
174
1
                "Too large table position for QT :{table_position}, expected between 0 and 3"
175
1
            )));
176
12.8k
        }
177
178
12.8k
        img.qt_tables[table_position] = Some(dct_table);
179
    }
180
181
9.89k
    return Ok(());
182
9.98k
}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&[u8]>
zune_jpeg::headers::parse_dqt::<alloc::vec::Vec<u8>>
Line
Count
Source
121
2.08k
pub(crate) fn parse_dqt<T: ZReaderTrait>(img: &mut JpegDecoder<T>) -> Result<(), DecodeErrors> {
122
    // read length
123
2.07k
    let mut qt_length =
124
2.08k
        img.stream
125
2.08k
            .get_u16_be_err()?
126
2.07k
            .checked_sub(2)
127
2.07k
            .ok_or(DecodeErrors::FormatStatic(
128
2.07k
                "Invalid DQT length. Length should be greater than 2"
129
2.07k
            ))?;
130
    // A single DQT header may have multiple QT's
131
4.23k
    while qt_length > 0 {
132
2.20k
        let qt_info = img.stream.get_u8_err()?;
133
        // 0 = 8 bit otherwise 16 bit dqt
134
2.19k
        let precision = (qt_info >> 4) as usize;
135
        // last 4 bits give us position
136
2.19k
        let table_position = (qt_info & 0x0f) as usize;
137
2.19k
        let precision_value = 64 * (precision + 1);
138
139
2.19k
        if (precision_value + 1) as u16 > qt_length {
140
5
            return Err(DecodeErrors::DqtError(format!("Invalid QT table bytes left :{}. Too small to construct a valid qt table which should be {} long", qt_length, precision_value + 1)));
141
2.19k
        }
142
143
2.19k
        let dct_table = match precision {
144
            0 => {
145
2.16k
                let mut qt_values = [0; 64];
146
147
2.16k
                img.stream.read_exact(&mut qt_values).map_err(|x| {
148
                    DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
149
8
                })?;
150
2.15k
                qt_length -= (precision_value as u16) + 1 /*QT BIT*/;
151
                // carry out un zig-zag here
152
2.15k
                un_zig_zag(&qt_values)
153
            }
154
            1 => {
155
                // 16 bit quantization tables
156
19
                let mut qt_values = [0_u16; 64];
157
158
1.05k
                for i in 0..64 {
159
1.04k
                    qt_values[i] = img.stream.get_u16_be_err()?;
160
                }
161
12
                qt_length -= (precision_value as u16) + 1;
162
163
12
                un_zig_zag(&qt_values)
164
            }
165
            _ => {
166
9
                return Err(DecodeErrors::DqtError(format!(
167
9
                    "Expected QT precision value of either 0 or 1, found {precision:?}"
168
9
                )));
169
            }
170
        };
171
172
2.16k
        if table_position >= MAX_COMPONENTS {
173
10
            return Err(DecodeErrors::DqtError(format!(
174
10
                "Too large table position for QT :{table_position}, expected between 0 and 3"
175
10
            )));
176
2.15k
        }
177
178
2.15k
        img.qt_tables[table_position] = Some(dct_table);
179
    }
180
181
2.03k
    return Ok(());
182
2.08k
}
Unexecuted instantiation: zune_jpeg::headers::parse_dqt::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_dqt::<&[u8]>
Line
Count
Source
121
8.01k
pub(crate) fn parse_dqt<T: ZReaderTrait>(img: &mut JpegDecoder<T>) -> Result<(), DecodeErrors> {
122
    // read length
123
8.01k
    let mut qt_length =
124
8.01k
        img.stream
125
8.01k
            .get_u16_be_err()?
126
8.01k
            .checked_sub(2)
127
8.01k
            .ok_or(DecodeErrors::FormatStatic(
128
8.01k
                "Invalid DQT length. Length should be greater than 2"
129
8.01k
            ))?;
130
    // A single DQT header may have multiple QT's
131
16.0k
    while qt_length > 0 {
132
8.11k
        let qt_info = img.stream.get_u8_err()?;
133
        // 0 = 8 bit otherwise 16 bit dqt
134
8.10k
        let precision = (qt_info >> 4) as usize;
135
        // last 4 bits give us position
136
8.10k
        let table_position = (qt_info & 0x0f) as usize;
137
8.10k
        let precision_value = 64 * (precision + 1);
138
139
8.10k
        if (precision_value + 1) as u16 > qt_length {
140
2
            return Err(DecodeErrors::DqtError(format!("Invalid QT table bytes left :{}. Too small to construct a valid qt table which should be {} long", qt_length, precision_value + 1)));
141
8.10k
        }
142
143
8.10k
        let dct_table = match precision {
144
            0 => {
145
7.82k
                let mut qt_values = [0; 64];
146
147
7.82k
                img.stream.read_exact(&mut qt_values).map_err(|x| {
148
                    DecodeErrors::Format(format!("Could not read symbols into the buffer\n{x}"))
149
7
                })?;
150
7.81k
                qt_length -= (precision_value as u16) + 1 /*QT BIT*/;
151
                // carry out un zig-zag here
152
7.81k
                un_zig_zag(&qt_values)
153
            }
154
            1 => {
155
                // 16 bit quantization tables
156
281
                let mut qt_values = [0_u16; 64];
157
158
17.8k
                for i in 0..64 {
159
17.6k
                    qt_values[i] = img.stream.get_u16_be_err()?;
160
                }
161
264
                qt_length -= (precision_value as u16) + 1;
162
163
264
                un_zig_zag(&qt_values)
164
            }
165
            _ => {
166
3
                return Err(DecodeErrors::DqtError(format!(
167
3
                    "Expected QT precision value of either 0 or 1, found {precision:?}"
168
3
                )));
169
            }
170
        };
171
172
8.07k
        if table_position >= MAX_COMPONENTS {
173
9
            return Err(DecodeErrors::DqtError(format!(
174
9
                "Too large table position for QT :{table_position}, expected between 0 and 3"
175
9
            )));
176
8.07k
        }
177
178
8.07k
        img.qt_tables[table_position] = Some(dct_table);
179
    }
180
181
7.96k
    return Ok(());
182
8.01k
}
183
184
/// Section:`B.2.2 Frame header syntax`
185
186
16.7k
pub(crate) fn parse_start_of_frame<T: ZReaderTrait>(
187
16.7k
    sof: SOFMarkers, img: &mut JpegDecoder<T>
188
16.7k
) -> Result<(), DecodeErrors> {
189
16.7k
    if img.seen_sof {
190
130
        return Err(DecodeErrors::SofError(
191
130
            "Two Start of Frame Markers".to_string()
192
130
        ));
193
16.5k
    }
194
    // Get length of the frame header
195
16.5k
    let length = img.stream.get_u16_be_err()?;
196
    // usually 8, but can be 12 and 16, we currently support only 8
197
    // so sorry about that 12 bit images
198
16.5k
    let dt_precision = img.stream.get_u8_err()?;
199
200
16.5k
    if dt_precision != 8 {
201
5
        return Err(DecodeErrors::SofError(format!(
202
5
            "The library can only parse 8-bit images, the image has {dt_precision} bits of precision"
203
5
        )));
204
16.5k
    }
205
206
16.5k
    img.info.set_density(dt_precision);
207
208
    // read  and set the image height.
209
16.5k
    let img_height = img.stream.get_u16_be_err()?;
210
16.5k
    img.info.set_height(img_height);
211
212
    // read and set the image width
213
16.5k
    let img_width = img.stream.get_u16_be_err()?;
214
16.5k
    img.info.set_width(img_width);
215
216
    trace!("Image width  :{}", img_width);
217
    trace!("Image height :{}", img_height);
218
219
16.5k
    if usize::from(img_width) > img.options.get_max_width() {
220
1
        return Err(DecodeErrors::Format(format!("Image width {} greater than width limit {}. If use `set_limits` if you want to support huge images", img_width, img.options.get_max_width())));
221
16.5k
    }
222
223
16.5k
    if usize::from(img_height) > img.options.get_max_height() {
224
2
        return Err(DecodeErrors::Format(format!("Image height {} greater than height limit {}. If use `set_limits` if you want to support huge images", img_height, img.options.get_max_height())));
225
16.5k
    }
226
227
    // Check image width or height is zero
228
16.5k
    if img_width == 0 || img_height == 0 {
229
4
        return Err(DecodeErrors::ZeroError);
230
16.5k
    }
231
232
    // Number of components for the image.
233
16.5k
    let num_components = img.stream.get_u8_err()?;
234
235
16.5k
    if num_components == 0 {
236
4
        return Err(DecodeErrors::SofError(
237
4
            "Number of components cannot be zero.".to_string()
238
4
        ));
239
16.5k
    }
240
241
16.5k
    let expected = 8 + 3 * u16::from(num_components);
242
    // length should be equal to num components
243
16.5k
    if length != expected {
244
14
        return Err(DecodeErrors::SofError(format!(
245
14
            "Length of start of frame differs from expected {expected},value is {length}"
246
14
        )));
247
16.5k
    }
248
249
    trace!("Image components : {}", num_components);
250
251
16.5k
    if num_components == 1 {
252
11.0k
        // SOF sets the number of image components
253
11.0k
        // and that to us translates to setting input and output
254
11.0k
        // colorspaces to zero
255
11.0k
        img.input_colorspace = ColorSpace::Luma;
256
11.0k
        img.options = img.options.jpeg_set_out_colorspace(ColorSpace::Luma);
257
11.0k
        debug!("Overriding default colorspace set to Luma");
258
11.0k
    }
259
16.5k
    if num_components == 4 && img.input_colorspace == ColorSpace::YCbCr {
260
791
        trace!("Input image has 4 components, defaulting to CMYK colorspace");
261
791
        // https://entropymine.wordpress.com/2018/10/22/how-is-a-jpeg-images-color-type-determined/
262
791
        img.input_colorspace = ColorSpace::CMYK;
263
15.7k
    }
264
265
    // set number of components
266
16.5k
    img.info.components = num_components;
267
268
16.5k
    let mut components = Vec::with_capacity(num_components as usize);
269
16.5k
    let mut temp = [0; 3];
270
271
28.6k
    for pos in 0..num_components {
272
        // read 3 bytes for each component
273
28.6k
        img.stream
274
28.6k
            .read_exact(&mut temp)
275
28.6k
            .map_err(|x| DecodeErrors::Format(format!("Could not read component data\n{x}")))?;
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<_>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>::{closure#0}
zune_jpeg::headers::parse_start_of_frame::<&[u8]>::{closure#0}
Line
Count
Source
275
3
            .map_err(|x| DecodeErrors::Format(format!("Could not read component data\n{x}")))?;
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>::{closure#0}
zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>::{closure#0}
Line
Count
Source
275
1
            .map_err(|x| DecodeErrors::Format(format!("Could not read component data\n{x}")))?;
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>::{closure#0}
276
        // create a component.
277
28.6k
        let component = Components::from(temp, pos)?;
278
279
28.6k
        components.push(component);
280
    }
281
16.5k
    img.seen_sof = true;
282
283
16.5k
    img.info.set_sof_marker(sof);
284
285
16.5k
    img.components = components;
286
287
16.5k
    Ok(())
288
16.7k
}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<_>
zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>
Line
Count
Source
186
2.58k
pub(crate) fn parse_start_of_frame<T: ZReaderTrait>(
187
2.58k
    sof: SOFMarkers, img: &mut JpegDecoder<T>
188
2.58k
) -> Result<(), DecodeErrors> {
189
2.58k
    if img.seen_sof {
190
30
        return Err(DecodeErrors::SofError(
191
30
            "Two Start of Frame Markers".to_string()
192
30
        ));
193
2.55k
    }
194
    // Get length of the frame header
195
2.55k
    let length = img.stream.get_u16_be_err()?;
196
    // usually 8, but can be 12 and 16, we currently support only 8
197
    // so sorry about that 12 bit images
198
2.55k
    let dt_precision = img.stream.get_u8_err()?;
199
200
2.55k
    if dt_precision != 8 {
201
1
        return Err(DecodeErrors::SofError(format!(
202
1
            "The library can only parse 8-bit images, the image has {dt_precision} bits of precision"
203
1
        )));
204
2.55k
    }
205
206
2.55k
    img.info.set_density(dt_precision);
207
208
    // read  and set the image height.
209
2.55k
    let img_height = img.stream.get_u16_be_err()?;
210
2.55k
    img.info.set_height(img_height);
211
212
    // read and set the image width
213
2.55k
    let img_width = img.stream.get_u16_be_err()?;
214
2.55k
    img.info.set_width(img_width);
215
216
    trace!("Image width  :{}", img_width);
217
    trace!("Image height :{}", img_height);
218
219
2.55k
    if usize::from(img_width) > img.options.get_max_width() {
220
0
        return Err(DecodeErrors::Format(format!("Image width {} greater than width limit {}. If use `set_limits` if you want to support huge images", img_width, img.options.get_max_width())));
221
2.55k
    }
222
223
2.55k
    if usize::from(img_height) > img.options.get_max_height() {
224
1
        return Err(DecodeErrors::Format(format!("Image height {} greater than height limit {}. If use `set_limits` if you want to support huge images", img_height, img.options.get_max_height())));
225
2.55k
    }
226
227
    // Check image width or height is zero
228
2.55k
    if img_width == 0 || img_height == 0 {
229
1
        return Err(DecodeErrors::ZeroError);
230
2.55k
    }
231
232
    // Number of components for the image.
233
2.55k
    let num_components = img.stream.get_u8_err()?;
234
235
2.55k
    if num_components == 0 {
236
0
        return Err(DecodeErrors::SofError(
237
0
            "Number of components cannot be zero.".to_string()
238
0
        ));
239
2.55k
    }
240
241
2.55k
    let expected = 8 + 3 * u16::from(num_components);
242
    // length should be equal to num components
243
2.55k
    if length != expected {
244
7
        return Err(DecodeErrors::SofError(format!(
245
7
            "Length of start of frame differs from expected {expected},value is {length}"
246
7
        )));
247
2.54k
    }
248
249
    trace!("Image components : {}", num_components);
250
251
2.54k
    if num_components == 1 {
252
2.05k
        // SOF sets the number of image components
253
2.05k
        // and that to us translates to setting input and output
254
2.05k
        // colorspaces to zero
255
2.05k
        img.input_colorspace = ColorSpace::Luma;
256
2.05k
        img.options = img.options.jpeg_set_out_colorspace(ColorSpace::Luma);
257
2.05k
        debug!("Overriding default colorspace set to Luma");
258
2.05k
    }
259
2.54k
    if num_components == 4 && img.input_colorspace == ColorSpace::YCbCr {
260
488
        trace!("Input image has 4 components, defaulting to CMYK colorspace");
261
488
        // https://entropymine.wordpress.com/2018/10/22/how-is-a-jpeg-images-color-type-determined/
262
488
        img.input_colorspace = ColorSpace::CMYK;
263
2.05k
    }
264
265
    // set number of components
266
2.54k
    img.info.components = num_components;
267
268
2.54k
    let mut components = Vec::with_capacity(num_components as usize);
269
2.54k
    let mut temp = [0; 3];
270
271
4.00k
    for pos in 0..num_components {
272
        // read 3 bytes for each component
273
4.00k
        img.stream
274
4.00k
            .read_exact(&mut temp)
275
4.00k
            .map_err(|x| DecodeErrors::Format(format!("Could not read component data\n{x}")))?;
276
        // create a component.
277
4.00k
        let component = Components::from(temp, pos)?;
278
279
4.00k
        components.push(component);
280
    }
281
2.54k
    img.seen_sof = true;
282
283
2.54k
    img.info.set_sof_marker(sof);
284
285
2.54k
    img.components = components;
286
287
2.54k
    Ok(())
288
2.58k
}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_start_of_frame::<&[u8]>
Line
Count
Source
186
6.89k
pub(crate) fn parse_start_of_frame<T: ZReaderTrait>(
187
6.89k
    sof: SOFMarkers, img: &mut JpegDecoder<T>
188
6.89k
) -> Result<(), DecodeErrors> {
189
6.89k
    if img.seen_sof {
190
60
        return Err(DecodeErrors::SofError(
191
60
            "Two Start of Frame Markers".to_string()
192
60
        ));
193
6.83k
    }
194
    // Get length of the frame header
195
6.83k
    let length = img.stream.get_u16_be_err()?;
196
    // usually 8, but can be 12 and 16, we currently support only 8
197
    // so sorry about that 12 bit images
198
6.83k
    let dt_precision = img.stream.get_u8_err()?;
199
200
6.83k
    if dt_precision != 8 {
201
2
        return Err(DecodeErrors::SofError(format!(
202
2
            "The library can only parse 8-bit images, the image has {dt_precision} bits of precision"
203
2
        )));
204
6.83k
    }
205
206
6.83k
    img.info.set_density(dt_precision);
207
208
    // read  and set the image height.
209
6.83k
    let img_height = img.stream.get_u16_be_err()?;
210
6.83k
    img.info.set_height(img_height);
211
212
    // read and set the image width
213
6.83k
    let img_width = img.stream.get_u16_be_err()?;
214
6.82k
    img.info.set_width(img_width);
215
216
    trace!("Image width  :{}", img_width);
217
    trace!("Image height :{}", img_height);
218
219
6.82k
    if usize::from(img_width) > img.options.get_max_width() {
220
0
        return Err(DecodeErrors::Format(format!("Image width {} greater than width limit {}. If use `set_limits` if you want to support huge images", img_width, img.options.get_max_width())));
221
6.82k
    }
222
223
6.82k
    if usize::from(img_height) > img.options.get_max_height() {
224
0
        return Err(DecodeErrors::Format(format!("Image height {} greater than height limit {}. If use `set_limits` if you want to support huge images", img_height, img.options.get_max_height())));
225
6.82k
    }
226
227
    // Check image width or height is zero
228
6.82k
    if img_width == 0 || img_height == 0 {
229
0
        return Err(DecodeErrors::ZeroError);
230
6.82k
    }
231
232
    // Number of components for the image.
233
6.82k
    let num_components = img.stream.get_u8_err()?;
234
235
6.82k
    if num_components == 0 {
236
1
        return Err(DecodeErrors::SofError(
237
1
            "Number of components cannot be zero.".to_string()
238
1
        ));
239
6.82k
    }
240
241
6.82k
    let expected = 8 + 3 * u16::from(num_components);
242
    // length should be equal to num components
243
6.82k
    if length != expected {
244
4
        return Err(DecodeErrors::SofError(format!(
245
4
            "Length of start of frame differs from expected {expected},value is {length}"
246
4
        )));
247
6.82k
    }
248
249
    trace!("Image components : {}", num_components);
250
251
6.82k
    if num_components == 1 {
252
4.01k
        // SOF sets the number of image components
253
4.01k
        // and that to us translates to setting input and output
254
4.01k
        // colorspaces to zero
255
4.01k
        img.input_colorspace = ColorSpace::Luma;
256
4.01k
        img.options = img.options.jpeg_set_out_colorspace(ColorSpace::Luma);
257
4.01k
        debug!("Overriding default colorspace set to Luma");
258
4.01k
    }
259
6.82k
    if num_components == 4 && img.input_colorspace == ColorSpace::YCbCr {
260
52
        trace!("Input image has 4 components, defaulting to CMYK colorspace");
261
52
        // https://entropymine.wordpress.com/2018/10/22/how-is-a-jpeg-images-color-type-determined/
262
52
        img.input_colorspace = ColorSpace::CMYK;
263
6.76k
    }
264
265
    // set number of components
266
6.82k
    img.info.components = num_components;
267
268
6.82k
    let mut components = Vec::with_capacity(num_components as usize);
269
6.82k
    let mut temp = [0; 3];
270
271
12.5k
    for pos in 0..num_components {
272
        // read 3 bytes for each component
273
12.5k
        img.stream
274
12.5k
            .read_exact(&mut temp)
275
12.5k
            .map_err(|x| DecodeErrors::Format(format!("Could not read component data\n{x}")))?;
276
        // create a component.
277
12.5k
        let component = Components::from(temp, pos)?;
278
279
12.5k
        components.push(component);
280
    }
281
6.81k
    img.seen_sof = true;
282
283
6.81k
    img.info.set_sof_marker(sof);
284
285
6.81k
    img.components = components;
286
287
6.81k
    Ok(())
288
6.89k
}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&[u8]>
zune_jpeg::headers::parse_start_of_frame::<alloc::vec::Vec<u8>>
Line
Count
Source
186
1.85k
pub(crate) fn parse_start_of_frame<T: ZReaderTrait>(
187
1.85k
    sof: SOFMarkers, img: &mut JpegDecoder<T>
188
1.85k
) -> Result<(), DecodeErrors> {
189
1.85k
    if img.seen_sof {
190
11
        return Err(DecodeErrors::SofError(
191
11
            "Two Start of Frame Markers".to_string()
192
11
        ));
193
1.84k
    }
194
    // Get length of the frame header
195
1.84k
    let length = img.stream.get_u16_be_err()?;
196
    // usually 8, but can be 12 and 16, we currently support only 8
197
    // so sorry about that 12 bit images
198
1.84k
    let dt_precision = img.stream.get_u8_err()?;
199
200
1.84k
    if dt_precision != 8 {
201
2
        return Err(DecodeErrors::SofError(format!(
202
2
            "The library can only parse 8-bit images, the image has {dt_precision} bits of precision"
203
2
        )));
204
1.83k
    }
205
206
1.83k
    img.info.set_density(dt_precision);
207
208
    // read  and set the image height.
209
1.83k
    let img_height = img.stream.get_u16_be_err()?;
210
1.83k
    img.info.set_height(img_height);
211
212
    // read and set the image width
213
1.83k
    let img_width = img.stream.get_u16_be_err()?;
214
1.83k
    img.info.set_width(img_width);
215
216
    trace!("Image width  :{}", img_width);
217
    trace!("Image height :{}", img_height);
218
219
1.83k
    if usize::from(img_width) > img.options.get_max_width() {
220
1
        return Err(DecodeErrors::Format(format!("Image width {} greater than width limit {}. If use `set_limits` if you want to support huge images", img_width, img.options.get_max_width())));
221
1.83k
    }
222
223
1.83k
    if usize::from(img_height) > img.options.get_max_height() {
224
1
        return Err(DecodeErrors::Format(format!("Image height {} greater than height limit {}. If use `set_limits` if you want to support huge images", img_height, img.options.get_max_height())));
225
1.83k
    }
226
227
    // Check image width or height is zero
228
1.83k
    if img_width == 0 || img_height == 0 {
229
3
        return Err(DecodeErrors::ZeroError);
230
1.83k
    }
231
232
    // Number of components for the image.
233
1.83k
    let num_components = img.stream.get_u8_err()?;
234
235
1.83k
    if num_components == 0 {
236
2
        return Err(DecodeErrors::SofError(
237
2
            "Number of components cannot be zero.".to_string()
238
2
        ));
239
1.82k
    }
240
241
1.82k
    let expected = 8 + 3 * u16::from(num_components);
242
    // length should be equal to num components
243
1.82k
    if length != expected {
244
2
        return Err(DecodeErrors::SofError(format!(
245
2
            "Length of start of frame differs from expected {expected},value is {length}"
246
2
        )));
247
1.82k
    }
248
249
    trace!("Image components : {}", num_components);
250
251
1.82k
    if num_components == 1 {
252
1.57k
        // SOF sets the number of image components
253
1.57k
        // and that to us translates to setting input and output
254
1.57k
        // colorspaces to zero
255
1.57k
        img.input_colorspace = ColorSpace::Luma;
256
1.57k
        img.options = img.options.jpeg_set_out_colorspace(ColorSpace::Luma);
257
1.57k
        debug!("Overriding default colorspace set to Luma");
258
1.57k
    }
259
1.82k
    if num_components == 4 && img.input_colorspace == ColorSpace::YCbCr {
260
41
        trace!("Input image has 4 components, defaulting to CMYK colorspace");
261
41
        // https://entropymine.wordpress.com/2018/10/22/how-is-a-jpeg-images-color-type-determined/
262
41
        img.input_colorspace = ColorSpace::CMYK;
263
1.78k
    }
264
265
    // set number of components
266
1.82k
    img.info.components = num_components;
267
268
1.82k
    let mut components = Vec::with_capacity(num_components as usize);
269
1.82k
    let mut temp = [0; 3];
270
271
2.36k
    for pos in 0..num_components {
272
        // read 3 bytes for each component
273
2.36k
        img.stream
274
2.36k
            .read_exact(&mut temp)
275
2.36k
            .map_err(|x| DecodeErrors::Format(format!("Could not read component data\n{x}")))?;
276
        // create a component.
277
2.36k
        let component = Components::from(temp, pos)?;
278
279
2.36k
        components.push(component);
280
    }
281
1.82k
    img.seen_sof = true;
282
283
1.82k
    img.info.set_sof_marker(sof);
284
285
1.82k
    img.components = components;
286
287
1.82k
    Ok(())
288
1.85k
}
Unexecuted instantiation: zune_jpeg::headers::parse_start_of_frame::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_start_of_frame::<&[u8]>
Line
Count
Source
186
5.37k
pub(crate) fn parse_start_of_frame<T: ZReaderTrait>(
187
5.37k
    sof: SOFMarkers, img: &mut JpegDecoder<T>
188
5.37k
) -> Result<(), DecodeErrors> {
189
5.37k
    if img.seen_sof {
190
29
        return Err(DecodeErrors::SofError(
191
29
            "Two Start of Frame Markers".to_string()
192
29
        ));
193
5.34k
    }
194
    // Get length of the frame header
195
5.34k
    let length = img.stream.get_u16_be_err()?;
196
    // usually 8, but can be 12 and 16, we currently support only 8
197
    // so sorry about that 12 bit images
198
5.34k
    let dt_precision = img.stream.get_u8_err()?;
199
200
5.34k
    if dt_precision != 8 {
201
0
        return Err(DecodeErrors::SofError(format!(
202
0
            "The library can only parse 8-bit images, the image has {dt_precision} bits of precision"
203
0
        )));
204
5.34k
    }
205
206
5.34k
    img.info.set_density(dt_precision);
207
208
    // read  and set the image height.
209
5.34k
    let img_height = img.stream.get_u16_be_err()?;
210
5.34k
    img.info.set_height(img_height);
211
212
    // read and set the image width
213
5.34k
    let img_width = img.stream.get_u16_be_err()?;
214
5.34k
    img.info.set_width(img_width);
215
216
    trace!("Image width  :{}", img_width);
217
    trace!("Image height :{}", img_height);
218
219
5.34k
    if usize::from(img_width) > img.options.get_max_width() {
220
0
        return Err(DecodeErrors::Format(format!("Image width {} greater than width limit {}. If use `set_limits` if you want to support huge images", img_width, img.options.get_max_width())));
221
5.34k
    }
222
223
5.34k
    if usize::from(img_height) > img.options.get_max_height() {
224
0
        return Err(DecodeErrors::Format(format!("Image height {} greater than height limit {}. If use `set_limits` if you want to support huge images", img_height, img.options.get_max_height())));
225
5.34k
    }
226
227
    // Check image width or height is zero
228
5.34k
    if img_width == 0 || img_height == 0 {
229
0
        return Err(DecodeErrors::ZeroError);
230
5.34k
    }
231
232
    // Number of components for the image.
233
5.34k
    let num_components = img.stream.get_u8_err()?;
234
235
5.34k
    if num_components == 0 {
236
1
        return Err(DecodeErrors::SofError(
237
1
            "Number of components cannot be zero.".to_string()
238
1
        ));
239
5.34k
    }
240
241
5.34k
    let expected = 8 + 3 * u16::from(num_components);
242
    // length should be equal to num components
243
5.34k
    if length != expected {
244
1
        return Err(DecodeErrors::SofError(format!(
245
1
            "Length of start of frame differs from expected {expected},value is {length}"
246
1
        )));
247
5.34k
    }
248
249
    trace!("Image components : {}", num_components);
250
251
5.34k
    if num_components == 1 {
252
3.35k
        // SOF sets the number of image components
253
3.35k
        // and that to us translates to setting input and output
254
3.35k
        // colorspaces to zero
255
3.35k
        img.input_colorspace = ColorSpace::Luma;
256
3.35k
        img.options = img.options.jpeg_set_out_colorspace(ColorSpace::Luma);
257
3.35k
        debug!("Overriding default colorspace set to Luma");
258
3.35k
    }
259
5.34k
    if num_components == 4 && img.input_colorspace == ColorSpace::YCbCr {
260
210
        trace!("Input image has 4 components, defaulting to CMYK colorspace");
261
210
        // https://entropymine.wordpress.com/2018/10/22/how-is-a-jpeg-images-color-type-determined/
262
210
        img.input_colorspace = ColorSpace::CMYK;
263
5.13k
    }
264
265
    // set number of components
266
5.34k
    img.info.components = num_components;
267
268
5.34k
    let mut components = Vec::with_capacity(num_components as usize);
269
5.34k
    let mut temp = [0; 3];
270
271
9.72k
    for pos in 0..num_components {
272
        // read 3 bytes for each component
273
9.72k
        img.stream
274
9.72k
            .read_exact(&mut temp)
275
9.72k
            .map_err(|x| DecodeErrors::Format(format!("Could not read component data\n{x}")))?;
276
        // create a component.
277
9.72k
        let component = Components::from(temp, pos)?;
278
279
9.72k
        components.push(component);
280
    }
281
5.34k
    img.seen_sof = true;
282
283
5.34k
    img.info.set_sof_marker(sof);
284
285
5.34k
    img.components = components;
286
287
5.34k
    Ok(())
288
5.37k
}
289
290
/// Parse a start of scan data
291
62.5k
pub(crate) fn parse_sos<T: ZReaderTrait>(image: &mut JpegDecoder<T>) -> Result<(), DecodeErrors> {
292
    // Scan header length
293
62.5k
    let ls = image.stream.get_u16_be_err()?;
294
    // Number of image components in scan
295
62.4k
    let ns = image.stream.get_u8_err()?;
296
297
62.4k
    let mut seen = [-1; { MAX_COMPONENTS + 1 }];
298
299
62.4k
    image.num_scans = ns;
300
301
62.4k
    if ls != 6 + 2 * u16::from(ns) {
302
126
        return Err(DecodeErrors::SosError(format!(
303
126
            "Bad SOS length {ls},corrupt jpeg"
304
126
        )));
305
62.3k
    }
306
307
    // Check number of components.
308
62.3k
    if !(1..5).contains(&ns) {
309
2
        return Err(DecodeErrors::SosError(format!(
310
2
            "Number of components in start of scan should be less than 3 but more than 0. Found {ns}"
311
2
        )));
312
62.3k
    }
313
314
62.3k
    if image.info.components == 0 {
315
14
        return Err(DecodeErrors::FormatStatic(
316
14
            "Error decoding SOF Marker, Number of components cannot be zero."
317
14
        ));
318
62.3k
    }
319
320
    // consume spec parameters
321
82.9k
    for i in 0..ns {
322
        // CS_i parameter, I don't need it so I might as well delete it
323
82.9k
        let id = image.stream.get_u8_err()?;
324
325
82.9k
        if seen.contains(&i32::from(id)) {
326
4
            return Err(DecodeErrors::SofError(format!(
327
4
                "Duplicate ID {id} seen twice in the same component"
328
4
            )));
329
82.9k
        }
330
331
82.9k
        seen[usize::from(i)] = i32::from(id);
332
        // DC and AC huffman table position
333
        // top 4 bits contain dc huffman destination table
334
        // lower four bits contain ac huffman destination table
335
82.9k
        let y = image.stream.get_u8_err()?;
336
337
82.9k
        let mut j = 0;
338
339
117k
        while j < image.info.components {
340
116k
            if image.components[j as usize].id == id {
341
82.8k
                break;
342
34.0k
            }
343
344
34.0k
            j += 1;
345
        }
346
347
82.9k
        if j == image.info.components {
348
70
            return Err(DecodeErrors::SofError(format!(
349
70
                "Invalid component id {}, expected a value between 0 and {}",
350
70
                id,
351
70
                image.components.len()
352
70
            )));
353
82.8k
        }
354
355
82.8k
        image.components[usize::from(j)].dc_huff_table = usize::from((y >> 4) & 0xF);
356
82.8k
        image.components[usize::from(j)].ac_huff_table = usize::from(y & 0xF);
357
82.8k
        image.z_order[i as usize] = j as usize;
358
    }
359
360
    // Collect the component spec parameters
361
    // This is only needed for progressive images but I'll read
362
    // them in order to ensure they are correct according to the spec
363
364
    // Extract progressive information
365
366
    // https://www.w3.org/Graphics/JPEG/itu-t81.pdf
367
    // Page 42
368
369
    // Start of spectral / predictor selection. (between 0 and 63)
370
62.2k
    image.spec_start = image.stream.get_u8_err()?;
371
    // End of spectral selection
372
62.2k
    image.spec_end = image.stream.get_u8_err()?;
373
374
62.2k
    let bit_approx = image.stream.get_u8_err()?;
375
    // successive approximation bit position high
376
62.2k
    image.succ_high = bit_approx >> 4;
377
378
62.2k
    if image.spec_end > 63 {
379
42
        return Err(DecodeErrors::SosError(format!(
380
42
            "Invalid Se parameter {}, range should be 0-63",
381
42
            image.spec_end
382
42
        )));
383
62.2k
    }
384
62.2k
    if image.spec_start > 63 {
385
13
        return Err(DecodeErrors::SosError(format!(
386
13
            "Invalid Ss parameter {}, range should be 0-63",
387
13
            image.spec_start
388
13
        )));
389
62.1k
    }
390
62.1k
    if image.succ_high > 13 {
391
7
        return Err(DecodeErrors::SosError(format!(
392
7
            "Invalid Ah parameter {}, range should be 0-13",
393
7
            image.succ_low
394
7
        )));
395
62.1k
    }
396
    // successive approximation bit position low
397
62.1k
    image.succ_low = bit_approx & 0xF;
398
399
62.1k
    if image.succ_low > 13 {
400
4
        return Err(DecodeErrors::SosError(format!(
401
4
            "Invalid Al parameter {}, range should be 0-13",
402
4
            image.succ_low
403
4
        )));
404
62.1k
    }
405
406
    trace!(
407
        "Ss={}, Se={} Ah={} Al={}",
408
        image.spec_start,
409
        image.spec_end,
410
        image.succ_high,
411
        image.succ_low
412
    );
413
414
62.1k
    Ok(())
415
62.5k
}
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<_>
zune_jpeg::headers::parse_sos::<alloc::vec::Vec<u8>>
Line
Count
Source
291
15.0k
pub(crate) fn parse_sos<T: ZReaderTrait>(image: &mut JpegDecoder<T>) -> Result<(), DecodeErrors> {
292
    // Scan header length
293
15.0k
    let ls = image.stream.get_u16_be_err()?;
294
    // Number of image components in scan
295
15.0k
    let ns = image.stream.get_u8_err()?;
296
297
15.0k
    let mut seen = [-1; { MAX_COMPONENTS + 1 }];
298
299
15.0k
    image.num_scans = ns;
300
301
15.0k
    if ls != 6 + 2 * u16::from(ns) {
302
25
        return Err(DecodeErrors::SosError(format!(
303
25
            "Bad SOS length {ls},corrupt jpeg"
304
25
        )));
305
15.0k
    }
306
307
    // Check number of components.
308
15.0k
    if !(1..5).contains(&ns) {
309
1
        return Err(DecodeErrors::SosError(format!(
310
1
            "Number of components in start of scan should be less than 3 but more than 0. Found {ns}"
311
1
        )));
312
15.0k
    }
313
314
15.0k
    if image.info.components == 0 {
315
1
        return Err(DecodeErrors::FormatStatic(
316
1
            "Error decoding SOF Marker, Number of components cannot be zero."
317
1
        ));
318
15.0k
    }
319
320
    // consume spec parameters
321
16.5k
    for i in 0..ns {
322
        // CS_i parameter, I don't need it so I might as well delete it
323
16.5k
        let id = image.stream.get_u8_err()?;
324
325
16.5k
        if seen.contains(&i32::from(id)) {
326
2
            return Err(DecodeErrors::SofError(format!(
327
2
                "Duplicate ID {id} seen twice in the same component"
328
2
            )));
329
16.5k
        }
330
331
16.5k
        seen[usize::from(i)] = i32::from(id);
332
        // DC and AC huffman table position
333
        // top 4 bits contain dc huffman destination table
334
        // lower four bits contain ac huffman destination table
335
16.5k
        let y = image.stream.get_u8_err()?;
336
337
16.5k
        let mut j = 0;
338
339
19.4k
        while j < image.info.components {
340
19.4k
            if image.components[j as usize].id == id {
341
16.5k
                break;
342
2.93k
            }
343
344
2.93k
            j += 1;
345
        }
346
347
16.5k
        if j == image.info.components {
348
17
            return Err(DecodeErrors::SofError(format!(
349
17
                "Invalid component id {}, expected a value between 0 and {}",
350
17
                id,
351
17
                image.components.len()
352
17
            )));
353
16.5k
        }
354
355
16.5k
        image.components[usize::from(j)].dc_huff_table = usize::from((y >> 4) & 0xF);
356
16.5k
        image.components[usize::from(j)].ac_huff_table = usize::from(y & 0xF);
357
16.5k
        image.z_order[i as usize] = j as usize;
358
    }
359
360
    // Collect the component spec parameters
361
    // This is only needed for progressive images but I'll read
362
    // them in order to ensure they are correct according to the spec
363
364
    // Extract progressive information
365
366
    // https://www.w3.org/Graphics/JPEG/itu-t81.pdf
367
    // Page 42
368
369
    // Start of spectral / predictor selection. (between 0 and 63)
370
15.0k
    image.spec_start = image.stream.get_u8_err()?;
371
    // End of spectral selection
372
15.0k
    image.spec_end = image.stream.get_u8_err()?;
373
374
15.0k
    let bit_approx = image.stream.get_u8_err()?;
375
    // successive approximation bit position high
376
15.0k
    image.succ_high = bit_approx >> 4;
377
378
15.0k
    if image.spec_end > 63 {
379
4
        return Err(DecodeErrors::SosError(format!(
380
4
            "Invalid Se parameter {}, range should be 0-63",
381
4
            image.spec_end
382
4
        )));
383
15.0k
    }
384
15.0k
    if image.spec_start > 63 {
385
1
        return Err(DecodeErrors::SosError(format!(
386
1
            "Invalid Ss parameter {}, range should be 0-63",
387
1
            image.spec_start
388
1
        )));
389
15.0k
    }
390
15.0k
    if image.succ_high > 13 {
391
2
        return Err(DecodeErrors::SosError(format!(
392
2
            "Invalid Ah parameter {}, range should be 0-13",
393
2
            image.succ_low
394
2
        )));
395
15.0k
    }
396
    // successive approximation bit position low
397
15.0k
    image.succ_low = bit_approx & 0xF;
398
399
15.0k
    if image.succ_low > 13 {
400
0
        return Err(DecodeErrors::SosError(format!(
401
0
            "Invalid Al parameter {}, range should be 0-13",
402
0
            image.succ_low
403
0
        )));
404
15.0k
    }
405
406
    trace!(
407
        "Ss={}, Se={} Ah={} Al={}",
408
        image.spec_start,
409
        image.spec_end,
410
        image.succ_high,
411
        image.succ_low
412
    );
413
414
15.0k
    Ok(())
415
15.0k
}
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_sos::<&[u8]>
Line
Count
Source
291
24.7k
pub(crate) fn parse_sos<T: ZReaderTrait>(image: &mut JpegDecoder<T>) -> Result<(), DecodeErrors> {
292
    // Scan header length
293
24.7k
    let ls = image.stream.get_u16_be_err()?;
294
    // Number of image components in scan
295
24.7k
    let ns = image.stream.get_u8_err()?;
296
297
24.7k
    let mut seen = [-1; { MAX_COMPONENTS + 1 }];
298
299
24.7k
    image.num_scans = ns;
300
301
24.7k
    if ls != 6 + 2 * u16::from(ns) {
302
30
        return Err(DecodeErrors::SosError(format!(
303
30
            "Bad SOS length {ls},corrupt jpeg"
304
30
        )));
305
24.6k
    }
306
307
    // Check number of components.
308
24.6k
    if !(1..5).contains(&ns) {
309
0
        return Err(DecodeErrors::SosError(format!(
310
0
            "Number of components in start of scan should be less than 3 but more than 0. Found {ns}"
311
0
        )));
312
24.6k
    }
313
314
24.6k
    if image.info.components == 0 {
315
3
        return Err(DecodeErrors::FormatStatic(
316
3
            "Error decoding SOF Marker, Number of components cannot be zero."
317
3
        ));
318
24.6k
    }
319
320
    // consume spec parameters
321
38.3k
    for i in 0..ns {
322
        // CS_i parameter, I don't need it so I might as well delete it
323
38.3k
        let id = image.stream.get_u8_err()?;
324
325
38.3k
        if seen.contains(&i32::from(id)) {
326
0
            return Err(DecodeErrors::SofError(format!(
327
0
                "Duplicate ID {id} seen twice in the same component"
328
0
            )));
329
38.3k
        }
330
331
38.3k
        seen[usize::from(i)] = i32::from(id);
332
        // DC and AC huffman table position
333
        // top 4 bits contain dc huffman destination table
334
        // lower four bits contain ac huffman destination table
335
38.3k
        let y = image.stream.get_u8_err()?;
336
337
38.3k
        let mut j = 0;
338
339
59.6k
        while j < image.info.components {
340
59.5k
            if image.components[j as usize].id == id {
341
38.3k
                break;
342
21.2k
            }
343
344
21.2k
            j += 1;
345
        }
346
347
38.3k
        if j == image.info.components {
348
21
            return Err(DecodeErrors::SofError(format!(
349
21
                "Invalid component id {}, expected a value between 0 and {}",
350
21
                id,
351
21
                image.components.len()
352
21
            )));
353
38.3k
        }
354
355
38.3k
        image.components[usize::from(j)].dc_huff_table = usize::from((y >> 4) & 0xF);
356
38.3k
        image.components[usize::from(j)].ac_huff_table = usize::from(y & 0xF);
357
38.3k
        image.z_order[i as usize] = j as usize;
358
    }
359
360
    // Collect the component spec parameters
361
    // This is only needed for progressive images but I'll read
362
    // them in order to ensure they are correct according to the spec
363
364
    // Extract progressive information
365
366
    // https://www.w3.org/Graphics/JPEG/itu-t81.pdf
367
    // Page 42
368
369
    // Start of spectral / predictor selection. (between 0 and 63)
370
24.6k
    image.spec_start = image.stream.get_u8_err()?;
371
    // End of spectral selection
372
24.6k
    image.spec_end = image.stream.get_u8_err()?;
373
374
24.6k
    let bit_approx = image.stream.get_u8_err()?;
375
    // successive approximation bit position high
376
24.6k
    image.succ_high = bit_approx >> 4;
377
378
24.6k
    if image.spec_end > 63 {
379
18
        return Err(DecodeErrors::SosError(format!(
380
18
            "Invalid Se parameter {}, range should be 0-63",
381
18
            image.spec_end
382
18
        )));
383
24.6k
    }
384
24.6k
    if image.spec_start > 63 {
385
2
        return Err(DecodeErrors::SosError(format!(
386
2
            "Invalid Ss parameter {}, range should be 0-63",
387
2
            image.spec_start
388
2
        )));
389
24.6k
    }
390
24.6k
    if image.succ_high > 13 {
391
0
        return Err(DecodeErrors::SosError(format!(
392
0
            "Invalid Ah parameter {}, range should be 0-13",
393
0
            image.succ_low
394
0
        )));
395
24.6k
    }
396
    // successive approximation bit position low
397
24.6k
    image.succ_low = bit_approx & 0xF;
398
399
24.6k
    if image.succ_low > 13 {
400
0
        return Err(DecodeErrors::SosError(format!(
401
0
            "Invalid Al parameter {}, range should be 0-13",
402
0
            image.succ_low
403
0
        )));
404
24.6k
    }
405
406
    trace!(
407
        "Ss={}, Se={} Ah={} Al={}",
408
        image.spec_start,
409
        image.spec_end,
410
        image.succ_high,
411
        image.succ_low
412
    );
413
414
24.6k
    Ok(())
415
24.7k
}
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&[u8]>
zune_jpeg::headers::parse_sos::<alloc::vec::Vec<u8>>
Line
Count
Source
291
11.1k
pub(crate) fn parse_sos<T: ZReaderTrait>(image: &mut JpegDecoder<T>) -> Result<(), DecodeErrors> {
292
    // Scan header length
293
11.1k
    let ls = image.stream.get_u16_be_err()?;
294
    // Number of image components in scan
295
11.1k
    let ns = image.stream.get_u8_err()?;
296
297
11.1k
    let mut seen = [-1; { MAX_COMPONENTS + 1 }];
298
299
11.1k
    image.num_scans = ns;
300
301
11.1k
    if ls != 6 + 2 * u16::from(ns) {
302
50
        return Err(DecodeErrors::SosError(format!(
303
50
            "Bad SOS length {ls},corrupt jpeg"
304
50
        )));
305
11.0k
    }
306
307
    // Check number of components.
308
11.0k
    if !(1..5).contains(&ns) {
309
1
        return Err(DecodeErrors::SosError(format!(
310
1
            "Number of components in start of scan should be less than 3 but more than 0. Found {ns}"
311
1
        )));
312
11.0k
    }
313
314
11.0k
    if image.info.components == 0 {
315
1
        return Err(DecodeErrors::FormatStatic(
316
1
            "Error decoding SOF Marker, Number of components cannot be zero."
317
1
        ));
318
11.0k
    }
319
320
    // consume spec parameters
321
11.6k
    for i in 0..ns {
322
        // CS_i parameter, I don't need it so I might as well delete it
323
11.6k
        let id = image.stream.get_u8_err()?;
324
325
11.6k
        if seen.contains(&i32::from(id)) {
326
2
            return Err(DecodeErrors::SofError(format!(
327
2
                "Duplicate ID {id} seen twice in the same component"
328
2
            )));
329
11.5k
        }
330
331
11.5k
        seen[usize::from(i)] = i32::from(id);
332
        // DC and AC huffman table position
333
        // top 4 bits contain dc huffman destination table
334
        // lower four bits contain ac huffman destination table
335
11.5k
        let y = image.stream.get_u8_err()?;
336
337
11.5k
        let mut j = 0;
338
339
12.4k
        while j < image.info.components {
340
12.4k
            if image.components[j as usize].id == id {
341
11.5k
                break;
342
851
            }
343
344
851
            j += 1;
345
        }
346
347
11.5k
        if j == image.info.components {
348
15
            return Err(DecodeErrors::SofError(format!(
349
15
                "Invalid component id {}, expected a value between 0 and {}",
350
15
                id,
351
15
                image.components.len()
352
15
            )));
353
11.5k
        }
354
355
11.5k
        image.components[usize::from(j)].dc_huff_table = usize::from((y >> 4) & 0xF);
356
11.5k
        image.components[usize::from(j)].ac_huff_table = usize::from(y & 0xF);
357
11.5k
        image.z_order[i as usize] = j as usize;
358
    }
359
360
    // Collect the component spec parameters
361
    // This is only needed for progressive images but I'll read
362
    // them in order to ensure they are correct according to the spec
363
364
    // Extract progressive information
365
366
    // https://www.w3.org/Graphics/JPEG/itu-t81.pdf
367
    // Page 42
368
369
    // Start of spectral / predictor selection. (between 0 and 63)
370
11.0k
    image.spec_start = image.stream.get_u8_err()?;
371
    // End of spectral selection
372
11.0k
    image.spec_end = image.stream.get_u8_err()?;
373
374
11.0k
    let bit_approx = image.stream.get_u8_err()?;
375
    // successive approximation bit position high
376
11.0k
    image.succ_high = bit_approx >> 4;
377
378
11.0k
    if image.spec_end > 63 {
379
11
        return Err(DecodeErrors::SosError(format!(
380
11
            "Invalid Se parameter {}, range should be 0-63",
381
11
            image.spec_end
382
11
        )));
383
11.0k
    }
384
11.0k
    if image.spec_start > 63 {
385
5
        return Err(DecodeErrors::SosError(format!(
386
5
            "Invalid Ss parameter {}, range should be 0-63",
387
5
            image.spec_start
388
5
        )));
389
11.0k
    }
390
11.0k
    if image.succ_high > 13 {
391
2
        return Err(DecodeErrors::SosError(format!(
392
2
            "Invalid Ah parameter {}, range should be 0-13",
393
2
            image.succ_low
394
2
        )));
395
11.0k
    }
396
    // successive approximation bit position low
397
11.0k
    image.succ_low = bit_approx & 0xF;
398
399
11.0k
    if image.succ_low > 13 {
400
1
        return Err(DecodeErrors::SosError(format!(
401
1
            "Invalid Al parameter {}, range should be 0-13",
402
1
            image.succ_low
403
1
        )));
404
11.0k
    }
405
406
    trace!(
407
        "Ss={}, Se={} Ah={} Al={}",
408
        image.spec_start,
409
        image.spec_end,
410
        image.succ_high,
411
        image.succ_low
412
    );
413
414
11.0k
    Ok(())
415
11.1k
}
Unexecuted instantiation: zune_jpeg::headers::parse_sos::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_sos::<&[u8]>
Line
Count
Source
291
11.5k
pub(crate) fn parse_sos<T: ZReaderTrait>(image: &mut JpegDecoder<T>) -> Result<(), DecodeErrors> {
292
    // Scan header length
293
11.5k
    let ls = image.stream.get_u16_be_err()?;
294
    // Number of image components in scan
295
11.5k
    let ns = image.stream.get_u8_err()?;
296
297
11.5k
    let mut seen = [-1; { MAX_COMPONENTS + 1 }];
298
299
11.5k
    image.num_scans = ns;
300
301
11.5k
    if ls != 6 + 2 * u16::from(ns) {
302
21
        return Err(DecodeErrors::SosError(format!(
303
21
            "Bad SOS length {ls},corrupt jpeg"
304
21
        )));
305
11.5k
    }
306
307
    // Check number of components.
308
11.5k
    if !(1..5).contains(&ns) {
309
0
        return Err(DecodeErrors::SosError(format!(
310
0
            "Number of components in start of scan should be less than 3 but more than 0. Found {ns}"
311
0
        )));
312
11.5k
    }
313
314
11.5k
    if image.info.components == 0 {
315
9
        return Err(DecodeErrors::FormatStatic(
316
9
            "Error decoding SOF Marker, Number of components cannot be zero."
317
9
        ));
318
11.5k
    }
319
320
    // consume spec parameters
321
16.5k
    for i in 0..ns {
322
        // CS_i parameter, I don't need it so I might as well delete it
323
16.5k
        let id = image.stream.get_u8_err()?;
324
325
16.5k
        if seen.contains(&i32::from(id)) {
326
0
            return Err(DecodeErrors::SofError(format!(
327
0
                "Duplicate ID {id} seen twice in the same component"
328
0
            )));
329
16.5k
        }
330
331
16.5k
        seen[usize::from(i)] = i32::from(id);
332
        // DC and AC huffman table position
333
        // top 4 bits contain dc huffman destination table
334
        // lower four bits contain ac huffman destination table
335
16.5k
        let y = image.stream.get_u8_err()?;
336
337
16.5k
        let mut j = 0;
338
339
25.4k
        while j < image.info.components {
340
25.4k
            if image.components[j as usize].id == id {
341
16.4k
                break;
342
8.98k
            }
343
344
8.98k
            j += 1;
345
        }
346
347
16.5k
        if j == image.info.components {
348
17
            return Err(DecodeErrors::SofError(format!(
349
17
                "Invalid component id {}, expected a value between 0 and {}",
350
17
                id,
351
17
                image.components.len()
352
17
            )));
353
16.4k
        }
354
355
16.4k
        image.components[usize::from(j)].dc_huff_table = usize::from((y >> 4) & 0xF);
356
16.4k
        image.components[usize::from(j)].ac_huff_table = usize::from(y & 0xF);
357
16.4k
        image.z_order[i as usize] = j as usize;
358
    }
359
360
    // Collect the component spec parameters
361
    // This is only needed for progressive images but I'll read
362
    // them in order to ensure they are correct according to the spec
363
364
    // Extract progressive information
365
366
    // https://www.w3.org/Graphics/JPEG/itu-t81.pdf
367
    // Page 42
368
369
    // Start of spectral / predictor selection. (between 0 and 63)
370
11.4k
    image.spec_start = image.stream.get_u8_err()?;
371
    // End of spectral selection
372
11.4k
    image.spec_end = image.stream.get_u8_err()?;
373
374
11.4k
    let bit_approx = image.stream.get_u8_err()?;
375
    // successive approximation bit position high
376
11.4k
    image.succ_high = bit_approx >> 4;
377
378
11.4k
    if image.spec_end > 63 {
379
9
        return Err(DecodeErrors::SosError(format!(
380
9
            "Invalid Se parameter {}, range should be 0-63",
381
9
            image.spec_end
382
9
        )));
383
11.4k
    }
384
11.4k
    if image.spec_start > 63 {
385
5
        return Err(DecodeErrors::SosError(format!(
386
5
            "Invalid Ss parameter {}, range should be 0-63",
387
5
            image.spec_start
388
5
        )));
389
11.4k
    }
390
11.4k
    if image.succ_high > 13 {
391
3
        return Err(DecodeErrors::SosError(format!(
392
3
            "Invalid Ah parameter {}, range should be 0-13",
393
3
            image.succ_low
394
3
        )));
395
11.4k
    }
396
    // successive approximation bit position low
397
11.4k
    image.succ_low = bit_approx & 0xF;
398
399
11.4k
    if image.succ_low > 13 {
400
3
        return Err(DecodeErrors::SosError(format!(
401
3
            "Invalid Al parameter {}, range should be 0-13",
402
3
            image.succ_low
403
3
        )));
404
11.4k
    }
405
406
    trace!(
407
        "Ss={}, Se={} Ah={} Al={}",
408
        image.spec_start,
409
        image.spec_end,
410
        image.succ_high,
411
        image.succ_low
412
    );
413
414
11.4k
    Ok(())
415
11.5k
}
416
417
/// Parse the APP13 (IPTC) segment.
418
5.08k
pub(crate) fn parse_app13<T: ZReaderTrait>(
419
5.08k
    decoder: &mut JpegDecoder<T>,
420
5.08k
) -> Result<(), DecodeErrors> {
421
    const IPTC_PREFIX: &[u8] = b"Photoshop 3.0";
422
    // skip length.
423
5.08k
    let mut length = usize::from(decoder.stream.get_u16_be());
424
425
5.08k
    if length < 2 {
426
45
        return Err(DecodeErrors::FormatStatic("Too small APP13 length"));
427
5.03k
    }
428
    // length bytes.
429
5.03k
    length -= 2;
430
431
5.03k
    if length > IPTC_PREFIX.len() && decoder.stream.peek_at(0, IPTC_PREFIX.len())? == IPTC_PREFIX {
432
        // skip bytes we read above.
433
204
        decoder.stream.skip(IPTC_PREFIX.len());
434
204
        length -= IPTC_PREFIX.len();
435
436
204
        let iptc_bytes = decoder.stream.peek_at(0, length)?.to_vec();
437
438
198
        decoder.info.iptc_data = Some(iptc_bytes);
439
4.83k
    }
440
441
5.02k
    decoder.stream.skip(length);
442
5.02k
    Ok(())
443
5.08k
}
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<_>
zune_jpeg::headers::parse_app13::<alloc::vec::Vec<u8>>
Line
Count
Source
418
22
pub(crate) fn parse_app13<T: ZReaderTrait>(
419
22
    decoder: &mut JpegDecoder<T>,
420
22
) -> Result<(), DecodeErrors> {
421
    const IPTC_PREFIX: &[u8] = b"Photoshop 3.0";
422
    // skip length.
423
22
    let mut length = usize::from(decoder.stream.get_u16_be());
424
425
22
    if length < 2 {
426
1
        return Err(DecodeErrors::FormatStatic("Too small APP13 length"));
427
21
    }
428
    // length bytes.
429
21
    length -= 2;
430
431
21
    if length > IPTC_PREFIX.len() && decoder.stream.peek_at(0, IPTC_PREFIX.len())? == IPTC_PREFIX {
432
        // skip bytes we read above.
433
0
        decoder.stream.skip(IPTC_PREFIX.len());
434
0
        length -= IPTC_PREFIX.len();
435
436
0
        let iptc_bytes = decoder.stream.peek_at(0, length)?.to_vec();
437
438
0
        decoder.info.iptc_data = Some(iptc_bytes);
439
19
    }
440
441
19
    decoder.stream.skip(length);
442
19
    Ok(())
443
22
}
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_app13::<&[u8]>
Line
Count
Source
418
4.86k
pub(crate) fn parse_app13<T: ZReaderTrait>(
419
4.86k
    decoder: &mut JpegDecoder<T>,
420
4.86k
) -> Result<(), DecodeErrors> {
421
    const IPTC_PREFIX: &[u8] = b"Photoshop 3.0";
422
    // skip length.
423
4.86k
    let mut length = usize::from(decoder.stream.get_u16_be());
424
425
4.86k
    if length < 2 {
426
32
        return Err(DecodeErrors::FormatStatic("Too small APP13 length"));
427
4.83k
    }
428
    // length bytes.
429
4.83k
    length -= 2;
430
431
4.83k
    if length > IPTC_PREFIX.len() && decoder.stream.peek_at(0, IPTC_PREFIX.len())? == IPTC_PREFIX {
432
        // skip bytes we read above.
433
135
        decoder.stream.skip(IPTC_PREFIX.len());
434
135
        length -= IPTC_PREFIX.len();
435
436
135
        let iptc_bytes = decoder.stream.peek_at(0, length)?.to_vec();
437
438
133
        decoder.info.iptc_data = Some(iptc_bytes);
439
4.69k
    }
440
441
4.83k
    decoder.stream.skip(length);
442
4.83k
    Ok(())
443
4.86k
}
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&[u8]>
zune_jpeg::headers::parse_app13::<alloc::vec::Vec<u8>>
Line
Count
Source
418
54
pub(crate) fn parse_app13<T: ZReaderTrait>(
419
54
    decoder: &mut JpegDecoder<T>,
420
54
) -> Result<(), DecodeErrors> {
421
    const IPTC_PREFIX: &[u8] = b"Photoshop 3.0";
422
    // skip length.
423
54
    let mut length = usize::from(decoder.stream.get_u16_be());
424
425
54
    if length < 2 {
426
1
        return Err(DecodeErrors::FormatStatic("Too small APP13 length"));
427
53
    }
428
    // length bytes.
429
53
    length -= 2;
430
431
53
    if length > IPTC_PREFIX.len() && decoder.stream.peek_at(0, IPTC_PREFIX.len())? == IPTC_PREFIX {
432
        // skip bytes we read above.
433
2
        decoder.stream.skip(IPTC_PREFIX.len());
434
2
        length -= IPTC_PREFIX.len();
435
436
2
        let iptc_bytes = decoder.stream.peek_at(0, length)?.to_vec();
437
438
0
        decoder.info.iptc_data = Some(iptc_bytes);
439
50
    }
440
441
50
    decoder.stream.skip(length);
442
50
    Ok(())
443
54
}
Unexecuted instantiation: zune_jpeg::headers::parse_app13::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_app13::<&[u8]>
Line
Count
Source
418
143
pub(crate) fn parse_app13<T: ZReaderTrait>(
419
143
    decoder: &mut JpegDecoder<T>,
420
143
) -> Result<(), DecodeErrors> {
421
    const IPTC_PREFIX: &[u8] = b"Photoshop 3.0";
422
    // skip length.
423
143
    let mut length = usize::from(decoder.stream.get_u16_be());
424
425
143
    if length < 2 {
426
11
        return Err(DecodeErrors::FormatStatic("Too small APP13 length"));
427
132
    }
428
    // length bytes.
429
132
    length -= 2;
430
431
132
    if length > IPTC_PREFIX.len() && decoder.stream.peek_at(0, IPTC_PREFIX.len())? == IPTC_PREFIX {
432
        // skip bytes we read above.
433
67
        decoder.stream.skip(IPTC_PREFIX.len());
434
67
        length -= IPTC_PREFIX.len();
435
436
67
        let iptc_bytes = decoder.stream.peek_at(0, length)?.to_vec();
437
438
65
        decoder.info.iptc_data = Some(iptc_bytes);
439
64
    }
440
441
129
    decoder.stream.skip(length);
442
129
    Ok(())
443
143
}
444
445
/// Parse Adobe App14 segment
446
21.8k
pub(crate) fn parse_app14<T: ZReaderTrait>(
447
21.8k
    decoder: &mut JpegDecoder<T>
448
21.8k
) -> Result<(), DecodeErrors> {
449
    // skip length
450
21.8k
    let mut length = usize::from(decoder.stream.get_u16_be());
451
452
21.8k
    if length < 2 || !decoder.stream.has(length - 2) {
453
51
        return Err(DecodeErrors::ExhaustedData);
454
21.8k
    }
455
21.8k
    if length < 14 {
456
1
        return Err(DecodeErrors::FormatStatic(
457
1
            "Too short of a length for App14 segment"
458
1
        ));
459
21.8k
    }
460
21.8k
    if decoder.stream.peek_at(0, 5) == Ok(b"Adobe") {
461
        // move stream 6 bytes to remove adobe id
462
14.5k
        decoder.stream.skip(6);
463
        // skip version, flags0 and flags1
464
14.5k
        decoder.stream.skip(5);
465
        // get color transform
466
14.5k
        let transform = decoder.stream.get_u8();
467
        // https://exiftool.org/TagNames/JPEG.html#Adobe
468
14.5k
        match transform {
469
13.7k
            0 => decoder.input_colorspace = ColorSpace::CMYK,
470
777
            1 => decoder.input_colorspace = ColorSpace::YCbCr,
471
31
            2 => decoder.input_colorspace = ColorSpace::YCCK,
472
            _ => {
473
5
                return Err(DecodeErrors::Format(format!(
474
5
                    "Unknown Adobe colorspace {transform}"
475
5
                )))
476
            }
477
        }
478
        // length   = 2
479
        // adobe id = 6
480
        // version =  5
481
        // transform = 1
482
14.5k
        length = length.saturating_sub(14);
483
7.21k
    } else if decoder.options.get_strict_mode() {
484
18
        return Err(DecodeErrors::FormatStatic("Corrupt Adobe App14 segment"));
485
7.19k
    } else {
486
7.19k
        length = length.saturating_sub(2);
487
7.19k
        error!("Not a valid Adobe APP14 Segment");
488
7.19k
    }
489
    // skip any proceeding lengths.
490
    // we do not need them
491
21.7k
    decoder.stream.skip(length);
492
493
21.7k
    Ok(())
494
21.8k
}
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<_>
zune_jpeg::headers::parse_app14::<alloc::vec::Vec<u8>>
Line
Count
Source
446
17
pub(crate) fn parse_app14<T: ZReaderTrait>(
447
17
    decoder: &mut JpegDecoder<T>
448
17
) -> Result<(), DecodeErrors> {
449
    // skip length
450
17
    let mut length = usize::from(decoder.stream.get_u16_be());
451
452
17
    if length < 2 || !decoder.stream.has(length - 2) {
453
12
        return Err(DecodeErrors::ExhaustedData);
454
5
    }
455
5
    if length < 14 {
456
0
        return Err(DecodeErrors::FormatStatic(
457
0
            "Too short of a length for App14 segment"
458
0
        ));
459
5
    }
460
5
    if decoder.stream.peek_at(0, 5) == Ok(b"Adobe") {
461
        // move stream 6 bytes to remove adobe id
462
2
        decoder.stream.skip(6);
463
        // skip version, flags0 and flags1
464
2
        decoder.stream.skip(5);
465
        // get color transform
466
2
        let transform = decoder.stream.get_u8();
467
        // https://exiftool.org/TagNames/JPEG.html#Adobe
468
2
        match transform {
469
2
            0 => decoder.input_colorspace = ColorSpace::CMYK,
470
0
            1 => decoder.input_colorspace = ColorSpace::YCbCr,
471
0
            2 => decoder.input_colorspace = ColorSpace::YCCK,
472
            _ => {
473
0
                return Err(DecodeErrors::Format(format!(
474
0
                    "Unknown Adobe colorspace {transform}"
475
0
                )))
476
            }
477
        }
478
        // length   = 2
479
        // adobe id = 6
480
        // version =  5
481
        // transform = 1
482
2
        length = length.saturating_sub(14);
483
3
    } else if decoder.options.get_strict_mode() {
484
3
        return Err(DecodeErrors::FormatStatic("Corrupt Adobe App14 segment"));
485
0
    } else {
486
0
        length = length.saturating_sub(2);
487
0
        error!("Not a valid Adobe APP14 Segment");
488
0
    }
489
    // skip any proceeding lengths.
490
    // we do not need them
491
2
    decoder.stream.skip(length);
492
493
2
    Ok(())
494
17
}
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_app14::<&[u8]>
Line
Count
Source
446
19.0k
pub(crate) fn parse_app14<T: ZReaderTrait>(
447
19.0k
    decoder: &mut JpegDecoder<T>
448
19.0k
) -> Result<(), DecodeErrors> {
449
    // skip length
450
19.0k
    let mut length = usize::from(decoder.stream.get_u16_be());
451
452
19.0k
    if length < 2 || !decoder.stream.has(length - 2) {
453
15
        return Err(DecodeErrors::ExhaustedData);
454
19.0k
    }
455
19.0k
    if length < 14 {
456
0
        return Err(DecodeErrors::FormatStatic(
457
0
            "Too short of a length for App14 segment"
458
0
        ));
459
19.0k
    }
460
19.0k
    if decoder.stream.peek_at(0, 5) == Ok(b"Adobe") {
461
        // move stream 6 bytes to remove adobe id
462
13.4k
        decoder.stream.skip(6);
463
        // skip version, flags0 and flags1
464
13.4k
        decoder.stream.skip(5);
465
        // get color transform
466
13.4k
        let transform = decoder.stream.get_u8();
467
        // https://exiftool.org/TagNames/JPEG.html#Adobe
468
13.4k
        match transform {
469
13.3k
            0 => decoder.input_colorspace = ColorSpace::CMYK,
470
50
            1 => decoder.input_colorspace = ColorSpace::YCbCr,
471
7
            2 => decoder.input_colorspace = ColorSpace::YCCK,
472
            _ => {
473
4
                return Err(DecodeErrors::Format(format!(
474
4
                    "Unknown Adobe colorspace {transform}"
475
4
                )))
476
            }
477
        }
478
        // length   = 2
479
        // adobe id = 6
480
        // version =  5
481
        // transform = 1
482
13.4k
        length = length.saturating_sub(14);
483
5.57k
    } else if decoder.options.get_strict_mode() {
484
0
        return Err(DecodeErrors::FormatStatic("Corrupt Adobe App14 segment"));
485
5.57k
    } else {
486
5.57k
        length = length.saturating_sub(2);
487
5.57k
        error!("Not a valid Adobe APP14 Segment");
488
5.57k
    }
489
    // skip any proceeding lengths.
490
    // we do not need them
491
19.0k
    decoder.stream.skip(length);
492
493
19.0k
    Ok(())
494
19.0k
}
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&[u8]>
zune_jpeg::headers::parse_app14::<alloc::vec::Vec<u8>>
Line
Count
Source
446
34
pub(crate) fn parse_app14<T: ZReaderTrait>(
447
34
    decoder: &mut JpegDecoder<T>
448
34
) -> Result<(), DecodeErrors> {
449
    // skip length
450
34
    let mut length = usize::from(decoder.stream.get_u16_be());
451
452
34
    if length < 2 || !decoder.stream.has(length - 2) {
453
14
        return Err(DecodeErrors::ExhaustedData);
454
20
    }
455
20
    if length < 14 {
456
1
        return Err(DecodeErrors::FormatStatic(
457
1
            "Too short of a length for App14 segment"
458
1
        ));
459
19
    }
460
19
    if decoder.stream.peek_at(0, 5) == Ok(b"Adobe") {
461
        // move stream 6 bytes to remove adobe id
462
4
        decoder.stream.skip(6);
463
        // skip version, flags0 and flags1
464
4
        decoder.stream.skip(5);
465
        // get color transform
466
4
        let transform = decoder.stream.get_u8();
467
        // https://exiftool.org/TagNames/JPEG.html#Adobe
468
4
        match transform {
469
1
            0 => decoder.input_colorspace = ColorSpace::CMYK,
470
0
            1 => decoder.input_colorspace = ColorSpace::YCbCr,
471
2
            2 => decoder.input_colorspace = ColorSpace::YCCK,
472
            _ => {
473
1
                return Err(DecodeErrors::Format(format!(
474
1
                    "Unknown Adobe colorspace {transform}"
475
1
                )))
476
            }
477
        }
478
        // length   = 2
479
        // adobe id = 6
480
        // version =  5
481
        // transform = 1
482
3
        length = length.saturating_sub(14);
483
15
    } else if decoder.options.get_strict_mode() {
484
15
        return Err(DecodeErrors::FormatStatic("Corrupt Adobe App14 segment"));
485
0
    } else {
486
0
        length = length.saturating_sub(2);
487
0
        error!("Not a valid Adobe APP14 Segment");
488
0
    }
489
    // skip any proceeding lengths.
490
    // we do not need them
491
3
    decoder.stream.skip(length);
492
493
3
    Ok(())
494
34
}
Unexecuted instantiation: zune_jpeg::headers::parse_app14::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_app14::<&[u8]>
Line
Count
Source
446
2.77k
pub(crate) fn parse_app14<T: ZReaderTrait>(
447
2.77k
    decoder: &mut JpegDecoder<T>
448
2.77k
) -> Result<(), DecodeErrors> {
449
    // skip length
450
2.77k
    let mut length = usize::from(decoder.stream.get_u16_be());
451
452
2.77k
    if length < 2 || !decoder.stream.has(length - 2) {
453
10
        return Err(DecodeErrors::ExhaustedData);
454
2.76k
    }
455
2.76k
    if length < 14 {
456
0
        return Err(DecodeErrors::FormatStatic(
457
0
            "Too short of a length for App14 segment"
458
0
        ));
459
2.76k
    }
460
2.76k
    if decoder.stream.peek_at(0, 5) == Ok(b"Adobe") {
461
        // move stream 6 bytes to remove adobe id
462
1.14k
        decoder.stream.skip(6);
463
        // skip version, flags0 and flags1
464
1.14k
        decoder.stream.skip(5);
465
        // get color transform
466
1.14k
        let transform = decoder.stream.get_u8();
467
        // https://exiftool.org/TagNames/JPEG.html#Adobe
468
1.14k
        match transform {
469
394
            0 => decoder.input_colorspace = ColorSpace::CMYK,
470
727
            1 => decoder.input_colorspace = ColorSpace::YCbCr,
471
22
            2 => decoder.input_colorspace = ColorSpace::YCCK,
472
            _ => {
473
0
                return Err(DecodeErrors::Format(format!(
474
0
                    "Unknown Adobe colorspace {transform}"
475
0
                )))
476
            }
477
        }
478
        // length   = 2
479
        // adobe id = 6
480
        // version =  5
481
        // transform = 1
482
1.14k
        length = length.saturating_sub(14);
483
1.62k
    } else if decoder.options.get_strict_mode() {
484
0
        return Err(DecodeErrors::FormatStatic("Corrupt Adobe App14 segment"));
485
1.62k
    } else {
486
1.62k
        length = length.saturating_sub(2);
487
1.62k
        error!("Not a valid Adobe APP14 Segment");
488
1.62k
    }
489
    // skip any proceeding lengths.
490
    // we do not need them
491
2.76k
    decoder.stream.skip(length);
492
493
2.76k
    Ok(())
494
2.77k
}
495
496
/// Parse the APP1 segment
497
///
498
/// This contains the exif tag
499
46.2k
pub(crate) fn parse_app1<T: ZReaderTrait>(
500
46.2k
    decoder: &mut JpegDecoder<T>
501
46.2k
) -> Result<(), DecodeErrors> {
502
    // contains exif data
503
46.2k
    let mut length = usize::from(decoder.stream.get_u16_be());
504
505
46.2k
    if length < 2 || !decoder.stream.has(length - 2) {
506
53
        return Err(DecodeErrors::ExhaustedData);
507
46.2k
    }
508
    // length bytes
509
46.2k
    length -= 2;
510
511
46.2k
    if length > 6 && decoder.stream.peek_at(0, 6).unwrap() == b"Exif\x00\x00" {
512
3.90k
        trace!("Exif segment present");
513
3.90k
        // skip bytes we read above
514
3.90k
        decoder.stream.skip(6);
515
3.90k
        length -= 6;
516
3.90k
517
3.90k
        let exif_bytes = decoder.stream.peek_at(0, length).unwrap().to_vec();
518
3.90k
519
3.90k
        decoder.exif_data = Some(exif_bytes);
520
42.3k
    } else {
521
42.3k
        warn!("Wrongly formatted exif tag");
522
42.3k
    }
523
524
46.2k
    decoder.stream.skip(length);
525
46.2k
    Ok(())
526
46.2k
}
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<_>
zune_jpeg::headers::parse_app1::<alloc::vec::Vec<u8>>
Line
Count
Source
499
10.6k
pub(crate) fn parse_app1<T: ZReaderTrait>(
500
10.6k
    decoder: &mut JpegDecoder<T>
501
10.6k
) -> Result<(), DecodeErrors> {
502
    // contains exif data
503
10.6k
    let mut length = usize::from(decoder.stream.get_u16_be());
504
505
10.6k
    if length < 2 || !decoder.stream.has(length - 2) {
506
12
        return Err(DecodeErrors::ExhaustedData);
507
10.6k
    }
508
    // length bytes
509
10.6k
    length -= 2;
510
511
10.6k
    if length > 6 && decoder.stream.peek_at(0, 6).unwrap() == b"Exif\x00\x00" {
512
4
        trace!("Exif segment present");
513
4
        // skip bytes we read above
514
4
        decoder.stream.skip(6);
515
4
        length -= 6;
516
4
517
4
        let exif_bytes = decoder.stream.peek_at(0, length).unwrap().to_vec();
518
4
519
4
        decoder.exif_data = Some(exif_bytes);
520
10.6k
    } else {
521
10.6k
        warn!("Wrongly formatted exif tag");
522
10.6k
    }
523
524
10.6k
    decoder.stream.skip(length);
525
10.6k
    Ok(())
526
10.6k
}
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_app1::<&[u8]>
Line
Count
Source
499
29.2k
pub(crate) fn parse_app1<T: ZReaderTrait>(
500
29.2k
    decoder: &mut JpegDecoder<T>
501
29.2k
) -> Result<(), DecodeErrors> {
502
    // contains exif data
503
29.2k
    let mut length = usize::from(decoder.stream.get_u16_be());
504
505
29.2k
    if length < 2 || !decoder.stream.has(length - 2) {
506
23
        return Err(DecodeErrors::ExhaustedData);
507
29.2k
    }
508
    // length bytes
509
29.2k
    length -= 2;
510
511
29.2k
    if length > 6 && decoder.stream.peek_at(0, 6).unwrap() == b"Exif\x00\x00" {
512
2.48k
        trace!("Exif segment present");
513
2.48k
        // skip bytes we read above
514
2.48k
        decoder.stream.skip(6);
515
2.48k
        length -= 6;
516
2.48k
517
2.48k
        let exif_bytes = decoder.stream.peek_at(0, length).unwrap().to_vec();
518
2.48k
519
2.48k
        decoder.exif_data = Some(exif_bytes);
520
26.7k
    } else {
521
26.7k
        warn!("Wrongly formatted exif tag");
522
26.7k
    }
523
524
29.2k
    decoder.stream.skip(length);
525
29.2k
    Ok(())
526
29.2k
}
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&[u8]>
zune_jpeg::headers::parse_app1::<alloc::vec::Vec<u8>>
Line
Count
Source
499
966
pub(crate) fn parse_app1<T: ZReaderTrait>(
500
966
    decoder: &mut JpegDecoder<T>
501
966
) -> Result<(), DecodeErrors> {
502
    // contains exif data
503
966
    let mut length = usize::from(decoder.stream.get_u16_be());
504
505
966
    if length < 2 || !decoder.stream.has(length - 2) {
506
16
        return Err(DecodeErrors::ExhaustedData);
507
950
    }
508
    // length bytes
509
950
    length -= 2;
510
511
950
    if length > 6 && decoder.stream.peek_at(0, 6).unwrap() == b"Exif\x00\x00" {
512
203
        trace!("Exif segment present");
513
203
        // skip bytes we read above
514
203
        decoder.stream.skip(6);
515
203
        length -= 6;
516
203
517
203
        let exif_bytes = decoder.stream.peek_at(0, length).unwrap().to_vec();
518
203
519
203
        decoder.exif_data = Some(exif_bytes);
520
747
    } else {
521
747
        warn!("Wrongly formatted exif tag");
522
747
    }
523
524
950
    decoder.stream.skip(length);
525
950
    Ok(())
526
966
}
Unexecuted instantiation: zune_jpeg::headers::parse_app1::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_app1::<&[u8]>
Line
Count
Source
499
5.37k
pub(crate) fn parse_app1<T: ZReaderTrait>(
500
5.37k
    decoder: &mut JpegDecoder<T>
501
5.37k
) -> Result<(), DecodeErrors> {
502
    // contains exif data
503
5.37k
    let mut length = usize::from(decoder.stream.get_u16_be());
504
505
5.37k
    if length < 2 || !decoder.stream.has(length - 2) {
506
2
        return Err(DecodeErrors::ExhaustedData);
507
5.37k
    }
508
    // length bytes
509
5.37k
    length -= 2;
510
511
5.37k
    if length > 6 && decoder.stream.peek_at(0, 6).unwrap() == b"Exif\x00\x00" {
512
1.20k
        trace!("Exif segment present");
513
1.20k
        // skip bytes we read above
514
1.20k
        decoder.stream.skip(6);
515
1.20k
        length -= 6;
516
1.20k
517
1.20k
        let exif_bytes = decoder.stream.peek_at(0, length).unwrap().to_vec();
518
1.20k
519
1.20k
        decoder.exif_data = Some(exif_bytes);
520
4.16k
    } else {
521
4.16k
        warn!("Wrongly formatted exif tag");
522
4.16k
    }
523
524
5.37k
    decoder.stream.skip(length);
525
5.37k
    Ok(())
526
5.37k
}
527
528
191k
pub(crate) fn parse_app2<T: ZReaderTrait>(
529
191k
    decoder: &mut JpegDecoder<T>
530
191k
) -> Result<(), DecodeErrors> {
531
191k
    let mut length = usize::from(decoder.stream.get_u16_be());
532
533
191k
    if length < 2 || !decoder.stream.has(length - 2) {
534
152
        return Err(DecodeErrors::ExhaustedData);
535
190k
    }
536
    // length bytes
537
190k
    length -= 2;
538
539
190k
    if length > 14 && decoder.stream.peek_at(0, 12).unwrap() == *b"ICC_PROFILE\0" {
540
79.6k
        trace!("ICC Profile present");
541
79.6k
        // skip 12 bytes which indicate ICC profile
542
79.6k
        length -= 12;
543
79.6k
        decoder.stream.skip(12);
544
79.6k
        let seq_no = decoder.stream.get_u8();
545
79.6k
        let num_markers = decoder.stream.get_u8();
546
79.6k
        // deduct the two bytes we read above
547
79.6k
        length -= 2;
548
79.6k
549
79.6k
        let data = decoder.stream.peek_at(0, length).unwrap().to_vec();
550
79.6k
551
79.6k
        let icc_chunk = ICCChunk {
552
79.6k
            seq_no,
553
79.6k
            num_markers,
554
79.6k
            data
555
79.6k
        };
556
79.6k
        decoder.icc_data.push(icc_chunk);
557
111k
    }
558
559
190k
    decoder.stream.skip(length);
560
561
190k
    Ok(())
562
191k
}
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<_>
zune_jpeg::headers::parse_app2::<alloc::vec::Vec<u8>>
Line
Count
Source
528
55.5k
pub(crate) fn parse_app2<T: ZReaderTrait>(
529
55.5k
    decoder: &mut JpegDecoder<T>
530
55.5k
) -> Result<(), DecodeErrors> {
531
55.5k
    let mut length = usize::from(decoder.stream.get_u16_be());
532
533
55.5k
    if length < 2 || !decoder.stream.has(length - 2) {
534
61
        return Err(DecodeErrors::ExhaustedData);
535
55.4k
    }
536
    // length bytes
537
55.4k
    length -= 2;
538
539
55.4k
    if length > 14 && decoder.stream.peek_at(0, 12).unwrap() == *b"ICC_PROFILE\0" {
540
39.5k
        trace!("ICC Profile present");
541
39.5k
        // skip 12 bytes which indicate ICC profile
542
39.5k
        length -= 12;
543
39.5k
        decoder.stream.skip(12);
544
39.5k
        let seq_no = decoder.stream.get_u8();
545
39.5k
        let num_markers = decoder.stream.get_u8();
546
39.5k
        // deduct the two bytes we read above
547
39.5k
        length -= 2;
548
39.5k
549
39.5k
        let data = decoder.stream.peek_at(0, length).unwrap().to_vec();
550
39.5k
551
39.5k
        let icc_chunk = ICCChunk {
552
39.5k
            seq_no,
553
39.5k
            num_markers,
554
39.5k
            data
555
39.5k
        };
556
39.5k
        decoder.icc_data.push(icc_chunk);
557
39.5k
    }
558
559
55.4k
    decoder.stream.skip(length);
560
561
55.4k
    Ok(())
562
55.5k
}
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_app2::<&[u8]>
Line
Count
Source
528
125k
pub(crate) fn parse_app2<T: ZReaderTrait>(
529
125k
    decoder: &mut JpegDecoder<T>
530
125k
) -> Result<(), DecodeErrors> {
531
125k
    let mut length = usize::from(decoder.stream.get_u16_be());
532
533
125k
    if length < 2 || !decoder.stream.has(length - 2) {
534
56
        return Err(DecodeErrors::ExhaustedData);
535
125k
    }
536
    // length bytes
537
125k
    length -= 2;
538
539
125k
    if length > 14 && decoder.stream.peek_at(0, 12).unwrap() == *b"ICC_PROFILE\0" {
540
35.0k
        trace!("ICC Profile present");
541
35.0k
        // skip 12 bytes which indicate ICC profile
542
35.0k
        length -= 12;
543
35.0k
        decoder.stream.skip(12);
544
35.0k
        let seq_no = decoder.stream.get_u8();
545
35.0k
        let num_markers = decoder.stream.get_u8();
546
35.0k
        // deduct the two bytes we read above
547
35.0k
        length -= 2;
548
35.0k
549
35.0k
        let data = decoder.stream.peek_at(0, length).unwrap().to_vec();
550
35.0k
551
35.0k
        let icc_chunk = ICCChunk {
552
35.0k
            seq_no,
553
35.0k
            num_markers,
554
35.0k
            data
555
35.0k
        };
556
35.0k
        decoder.icc_data.push(icc_chunk);
557
90.1k
    }
558
559
125k
    decoder.stream.skip(length);
560
561
125k
    Ok(())
562
125k
}
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&[u8]>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&alloc::vec::Vec<u8>>
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&[u8]>
zune_jpeg::headers::parse_app2::<alloc::vec::Vec<u8>>
Line
Count
Source
528
235
pub(crate) fn parse_app2<T: ZReaderTrait>(
529
235
    decoder: &mut JpegDecoder<T>
530
235
) -> Result<(), DecodeErrors> {
531
235
    let mut length = usize::from(decoder.stream.get_u16_be());
532
533
235
    if length < 2 || !decoder.stream.has(length - 2) {
534
20
        return Err(DecodeErrors::ExhaustedData);
535
215
    }
536
    // length bytes
537
215
    length -= 2;
538
539
215
    if length > 14 && decoder.stream.peek_at(0, 12).unwrap() == *b"ICC_PROFILE\0" {
540
134
        trace!("ICC Profile present");
541
134
        // skip 12 bytes which indicate ICC profile
542
134
        length -= 12;
543
134
        decoder.stream.skip(12);
544
134
        let seq_no = decoder.stream.get_u8();
545
134
        let num_markers = decoder.stream.get_u8();
546
134
        // deduct the two bytes we read above
547
134
        length -= 2;
548
134
549
134
        let data = decoder.stream.peek_at(0, length).unwrap().to_vec();
550
134
551
134
        let icc_chunk = ICCChunk {
552
134
            seq_no,
553
134
            num_markers,
554
134
            data
555
134
        };
556
134
        decoder.icc_data.push(icc_chunk);
557
134
    }
558
559
215
    decoder.stream.skip(length);
560
561
215
    Ok(())
562
235
}
Unexecuted instantiation: zune_jpeg::headers::parse_app2::<&alloc::vec::Vec<u8>>
zune_jpeg::headers::parse_app2::<&[u8]>
Line
Count
Source
528
10.1k
pub(crate) fn parse_app2<T: ZReaderTrait>(
529
10.1k
    decoder: &mut JpegDecoder<T>
530
10.1k
) -> Result<(), DecodeErrors> {
531
10.1k
    let mut length = usize::from(decoder.stream.get_u16_be());
532
533
10.1k
    if length < 2 || !decoder.stream.has(length - 2) {
534
15
        return Err(DecodeErrors::ExhaustedData);
535
10.1k
    }
536
    // length bytes
537
10.1k
    length -= 2;
538
539
10.1k
    if length > 14 && decoder.stream.peek_at(0, 12).unwrap() == *b"ICC_PROFILE\0" {
540
4.98k
        trace!("ICC Profile present");
541
4.98k
        // skip 12 bytes which indicate ICC profile
542
4.98k
        length -= 12;
543
4.98k
        decoder.stream.skip(12);
544
4.98k
        let seq_no = decoder.stream.get_u8();
545
4.98k
        let num_markers = decoder.stream.get_u8();
546
4.98k
        // deduct the two bytes we read above
547
4.98k
        length -= 2;
548
4.98k
549
4.98k
        let data = decoder.stream.peek_at(0, length).unwrap().to_vec();
550
4.98k
551
4.98k
        let icc_chunk = ICCChunk {
552
4.98k
            seq_no,
553
4.98k
            num_markers,
554
4.98k
            data
555
4.98k
        };
556
4.98k
        decoder.icc_data.push(icc_chunk);
557
5.13k
    }
558
559
10.1k
    decoder.stream.skip(length);
560
561
10.1k
    Ok(())
562
10.1k
}
563
564
/// Small utility function to print Un-zig-zagged quantization tables
565
566
28.5k
fn un_zig_zag<T>(a: &[T]) -> [i32; 64]
567
28.5k
where
568
28.5k
    T: Default + Copy,
569
28.5k
    i32: core::convert::From<T>
570
{
571
28.5k
    let mut output = [i32::default(); 64];
572
573
1.85M
    for i in 0..64 {
574
1.82M
        output[UN_ZIGZAG[i]] = i32::from(a[i]);
575
1.82M
    }
576
577
28.5k
    output
578
28.5k
}
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u8>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u16>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<_>
zune_jpeg::headers::un_zig_zag::<u8>
Line
Count
Source
566
5.44k
fn un_zig_zag<T>(a: &[T]) -> [i32; 64]
567
5.44k
where
568
5.44k
    T: Default + Copy,
569
5.44k
    i32: core::convert::From<T>
570
{
571
5.44k
    let mut output = [i32::default(); 64];
572
573
353k
    for i in 0..64 {
574
348k
        output[UN_ZIGZAG[i]] = i32::from(a[i]);
575
348k
    }
576
577
5.44k
    output
578
5.44k
}
zune_jpeg::headers::un_zig_zag::<u16>
Line
Count
Source
566
64
fn un_zig_zag<T>(a: &[T]) -> [i32; 64]
567
64
where
568
64
    T: Default + Copy,
569
64
    i32: core::convert::From<T>
570
{
571
64
    let mut output = [i32::default(); 64];
572
573
4.16k
    for i in 0..64 {
574
4.09k
        output[UN_ZIGZAG[i]] = i32::from(a[i]);
575
4.09k
    }
576
577
64
    output
578
64
}
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u8>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u16>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u8>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u16>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u8>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u16>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u8>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u16>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u8>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u16>
zune_jpeg::headers::un_zig_zag::<u8>
Line
Count
Source
566
10.2k
fn un_zig_zag<T>(a: &[T]) -> [i32; 64]
567
10.2k
where
568
10.2k
    T: Default + Copy,
569
10.2k
    i32: core::convert::From<T>
570
{
571
10.2k
    let mut output = [i32::default(); 64];
572
573
668k
    for i in 0..64 {
574
657k
        output[UN_ZIGZAG[i]] = i32::from(a[i]);
575
657k
    }
576
577
10.2k
    output
578
10.2k
}
zune_jpeg::headers::un_zig_zag::<u16>
Line
Count
Source
566
2.54k
fn un_zig_zag<T>(a: &[T]) -> [i32; 64]
567
2.54k
where
568
2.54k
    T: Default + Copy,
569
2.54k
    i32: core::convert::From<T>
570
{
571
2.54k
    let mut output = [i32::default(); 64];
572
573
165k
    for i in 0..64 {
574
162k
        output[UN_ZIGZAG[i]] = i32::from(a[i]);
575
162k
    }
576
577
2.54k
    output
578
2.54k
}
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u8>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u16>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u8>
Unexecuted instantiation: zune_jpeg::headers::un_zig_zag::<u16>
zune_jpeg::headers::un_zig_zag::<u8>
Line
Count
Source
566
9.97k
fn un_zig_zag<T>(a: &[T]) -> [i32; 64]
567
9.97k
where
568
9.97k
    T: Default + Copy,
569
9.97k
    i32: core::convert::From<T>
570
{
571
9.97k
    let mut output = [i32::default(); 64];
572
573
648k
    for i in 0..64 {
574
638k
        output[UN_ZIGZAG[i]] = i32::from(a[i]);
575
638k
    }
576
577
9.97k
    output
578
9.97k
}
zune_jpeg::headers::un_zig_zag::<u16>
Line
Count
Source
566
276
fn un_zig_zag<T>(a: &[T]) -> [i32; 64]
567
276
where
568
276
    T: Default + Copy,
569
276
    i32: core::convert::From<T>
570
{
571
276
    let mut output = [i32::default(); 64];
572
573
17.9k
    for i in 0..64 {
574
17.6k
        output[UN_ZIGZAG[i]] = i32::from(a[i]);
575
17.6k
    }
576
577
276
    output
578
276
}