Coverage Report

Created: 2025-07-01 06:50

/rust/registry/src/index.crates.io-6f17d22bba15001f/zune-jpeg-0.4.18/src/mcu.rs
Line
Count
Source (jump to first uncovered line)
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
use alloc::{format, vec};
10
use core::cmp::min;
11
use zune_core::bytestream::ZReaderTrait;
12
use zune_core::colorspace::ColorSpace;
13
use zune_core::colorspace::ColorSpace::Luma;
14
use zune_core::log::{error, trace, warn};
15
16
use crate::bitstream::BitStream;
17
use crate::components::SampleRatios;
18
use crate::decoder::MAX_COMPONENTS;
19
use crate::errors::DecodeErrors;
20
use crate::marker::Marker;
21
use crate::mcu_prog::get_marker;
22
use crate::misc::{calculate_padded_width, setup_component_params};
23
use crate::worker::{color_convert, upsample};
24
use crate::JpegDecoder;
25
26
/// The size of a DC block for a MCU.
27
28
pub const DCT_BLOCK: usize = 64;
29
30
impl<T: ZReaderTrait> JpegDecoder<T> {
31
    /// Check for existence of DC and AC Huffman Tables
32
0
    pub(crate) fn check_tables(&self) -> Result<(), DecodeErrors> {
33
        // check that dc and AC tables exist outside the hot path
34
0
        for component in &self.components {
35
0
            let _ = &self
36
0
                .dc_huffman_tables
37
0
                .get(component.dc_huff_table)
38
0
                .as_ref()
39
0
                .ok_or_else(|| {
40
0
                    DecodeErrors::HuffmanDecode(format!(
41
0
                        "No Huffman DC table for component {:?} ",
42
0
                        component.component_id
43
0
                    ))
44
0
                })?
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#0}
45
0
                .as_ref()
46
0
                .ok_or_else(|| {
47
0
                    DecodeErrors::HuffmanDecode(format!(
48
0
                        "No DC table for component {:?}",
49
0
                        component.component_id
50
0
                    ))
51
0
                })?;
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#1}
52
53
0
            let _ = &self
54
0
                .ac_huffman_tables
55
0
                .get(component.ac_huff_table)
56
0
                .as_ref()
57
0
                .ok_or_else(|| {
58
0
                    DecodeErrors::HuffmanDecode(format!(
59
0
                        "No Huffman AC table for component {:?} ",
60
0
                        component.component_id
61
0
                    ))
62
0
                })?
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#2}
63
0
                .as_ref()
64
0
                .ok_or_else(|| {
65
0
                    DecodeErrors::HuffmanDecode(format!(
66
0
                        "No AC table for component {:?}",
67
0
                        component.component_id
68
0
                    ))
69
0
                })?;
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables::{closure#3}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables::{closure#3}
70
        }
71
0
        Ok(())
72
0
    }
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::check_tables
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::check_tables
73
74
    /// Decode MCUs and carry out post processing.
75
    ///
76
    /// This is the main decoder loop for the library, the hot path.
77
    ///
78
    /// Because of this, we pull in some very crazy optimization tricks hence readability is a pinch
79
    /// here.
80
    #[allow(
81
        clippy::similar_names,
82
        clippy::too_many_lines,
83
        clippy::cast_possible_truncation
84
    )]
85
    #[inline(never)]
86
0
    pub(crate) fn decode_mcu_ycbcr_baseline(
87
0
        &mut self, pixels: &mut [u8]
88
0
    ) -> Result<(), DecodeErrors> {
89
0
        setup_component_params(self)?;
90
91
        // check dc and AC tables
92
0
        self.check_tables()?;
93
94
        let (mut mcu_width, mut mcu_height);
95
96
0
        if self.is_interleaved {
97
            // set upsampling functions
98
0
            self.set_upsampling()?;
99
100
0
            mcu_width = self.mcu_x;
101
0
            mcu_height = self.mcu_y;
102
0
        } else {
103
0
            // For non-interleaved images( (1*1) subsampling)
104
0
            // number of MCU's are the widths (+7 to account for paddings) divided bu 8.
105
0
            mcu_width = ((self.info.width + 7) / 8) as usize;
106
0
            mcu_height = ((self.info.height + 7) / 8) as usize;
107
0
        }
108
0
        if self.is_interleaved
109
0
            && self.input_colorspace.num_components() > 1
110
0
            && self.options.jpeg_get_out_colorspace().num_components() == 1
111
0
            && (self.sub_sample_ratio == SampleRatios::V
112
0
                || self.sub_sample_ratio == SampleRatios::HV)
113
0
        {
114
0
            // For a specific set of images, e.g interleaved,
115
0
            // when converting from YcbCr to grayscale, we need to
116
0
            // take into account mcu height since the MCU decoding needs to take
117
0
            // it into account for padding purposes and the post processor
118
0
            // parses two rows per mcu width.
119
0
            //
120
0
            // set coeff to be 2 to ensure that we increment two rows
121
0
            // for every mcu processed also
122
0
            mcu_height *= self.v_max;
123
0
            mcu_height /= self.h_max;
124
0
            self.coeff = 2;
125
0
        }
126
127
0
        if self.input_colorspace == ColorSpace::Luma && self.is_interleaved {
128
0
            warn!("Grayscale image with down-sampled component, resetting component details");
129
0
130
0
            self.reset_params();
131
0
132
0
            mcu_width = ((self.info.width + 7) / 8) as usize;
133
0
            mcu_height = ((self.info.height + 7) / 8) as usize;
134
0
        }
135
0
        let width = usize::from(self.info.width);
136
0
137
0
        let padded_width = calculate_padded_width(width, self.sub_sample_ratio);
138
0
139
0
        let mut stream = BitStream::new();
140
0
        let mut tmp = [0_i32; DCT_BLOCK];
141
0
142
0
        let comp_len = self.components.len();
143
144
0
        for (pos, comp) in self.components.iter_mut().enumerate() {
145
            // Allocate only needed components.
146
            //
147
            // For special colorspaces i.e YCCK and CMYK, just allocate all of the needed
148
            // components.
149
0
            if min(
150
0
                self.options.jpeg_get_out_colorspace().num_components() - 1,
151
0
                pos
152
0
            ) == pos
153
0
                || comp_len == 4
154
            // Special colorspace
155
0
            {
156
0
                // allocate enough space to hold a whole MCU width
157
0
                // this means we should take into account sampling ratios
158
0
                // `*8` is because each MCU spans 8 widths.
159
0
                let len = comp.width_stride * comp.vertical_sample * 8;
160
0
161
0
                comp.needed = true;
162
0
                comp.raw_coeff = vec![0; len];
163
0
            } else {
164
0
                comp.needed = false;
165
0
            }
166
        }
167
168
0
        let mut pixels_written = 0;
169
0
170
0
        let is_hv = usize::from(self.is_interleaved);
171
0
        let upsampler_scratch_size = is_hv * self.components[0].width_stride;
172
0
        let mut upsampler_scratch_space = vec![0; upsampler_scratch_size];
173
174
0
        for i in 0..mcu_height {
175
            // Report if we have no more bytes
176
            // This may generate false negatives since we over-read bytes
177
            // hence that why 37 is chosen(we assume if we over-read more than 37 bytes, we have a problem)
178
0
            if stream.overread_by > 37
179
            // favourite number :)
180
            {
181
0
                if self.options.get_strict_mode() {
182
0
                    return Err(DecodeErrors::FormatStatic("Premature end of buffer"));
183
0
                };
184
0
185
0
                error!("Premature end of buffer");
186
0
                break;
187
0
            }
188
189
            // decode a whole MCU width,
190
            // this takes into account interleaved components.
191
0
            let terminate = self.decode_mcu_width(mcu_width, &mut tmp, &mut stream)?;
192
            // if i >=7{
193
            //     panic!()
194
            // }
195
            // process that width up until it's impossible
196
197
0
            self.post_process(
198
0
                pixels,
199
0
                i,
200
0
                mcu_height,
201
0
                width,
202
0
                padded_width,
203
0
                &mut pixels_written,
204
0
                &mut upsampler_scratch_space
205
0
            )?;
206
0
            if terminate {
207
0
                warn!("Got terminate signal, will not process further");
208
0
                return Ok(());
209
0
            }
210
        }
211
        // it may happen that some images don't have the whole buffer
212
        // so we can't panic in case of that
213
        // assert_eq!(pixels_written, pixels.len());
214
215
        // For UHD usecases that tie two images separating them with EOI and
216
        // SOI markers, it may happen that we do not reach this image end of image
217
        // So this ensures we reach it
218
        // Ensure we read EOI
219
0
        if !stream.seen_eoi {
220
0
            let marker = get_marker(&mut self.stream, &mut stream);
221
0
            match marker {
222
0
                Ok(_m) => {
223
0
                    trace!("Found marker {:?}", _m);
224
0
                }
225
0
                Err(_) => {
226
0
                    // ignore error
227
0
                }
228
            }
229
0
        }
230
231
        trace!("Finished decoding image");
232
233
0
        Ok(())
234
0
    }
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_ycbcr_baseline
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_ycbcr_baseline
235
0
    fn decode_mcu_width(
236
0
        &mut self, mcu_width: usize, tmp: &mut [i32; 64], stream: &mut BitStream
237
0
    ) -> Result<bool, DecodeErrors> {
238
0
        for j in 0..mcu_width {
239
            // iterate over components
240
0
            for component in &mut self.components {
241
0
                let dc_table = self.dc_huffman_tables[component.dc_huff_table % MAX_COMPONENTS]
242
0
                    .as_ref()
243
0
                    .unwrap();
244
0
245
0
                let ac_table = self.ac_huffman_tables[component.ac_huff_table % MAX_COMPONENTS]
246
0
                    .as_ref()
247
0
                    .unwrap();
248
0
249
0
                let qt_table = &component.quantization_table;
250
0
                let channel = &mut component.raw_coeff;
251
252
                // If image is interleaved iterate over scan components,
253
                // otherwise if it-s non-interleaved, these routines iterate in
254
                // trivial scanline order(Y,Cb,Cr)
255
0
                for v_samp in 0..component.vertical_sample {
256
0
                    for h_samp in 0..component.horizontal_sample {
257
                        // Fill the array with zeroes, decode_mcu_block expects
258
                        // a zero based array.
259
0
                        tmp.fill(0);
260
0
261
0
                        stream.decode_mcu_block(
262
0
                            &mut self.stream,
263
0
                            dc_table,
264
0
                            ac_table,
265
0
                            qt_table,
266
0
                            tmp,
267
0
                            &mut component.dc_pred
268
0
                        )?;
269
270
0
                        if component.needed {
271
0
                            let idct_position = {
272
0
                                // derived from stb and rewritten for my tastes
273
0
                                let c2 = v_samp * 8;
274
0
                                let c3 = ((j * component.horizontal_sample) + h_samp) * 8;
275
0
276
0
                                component.width_stride * c2 + c3
277
0
                            };
278
0
279
0
                            let idct_pos = channel.get_mut(idct_position..).unwrap();
280
0
                            //  call idct.
281
0
                            (self.idct_func)(tmp, idct_pos, component.width_stride);
282
0
                        }
283
                    }
284
                }
285
            }
286
0
            self.todo = self.todo.wrapping_sub(1);
287
0
288
0
            if self.todo == 0 {
289
0
                self.handle_rst_main(stream)?;
290
0
            }
291
292
            // After all interleaved components, that's an MCU
293
            // handle stream markers
294
            //
295
            // In some corrupt images, it may occur that header markers occur in the stream.
296
            // The spec EXPLICITLY FORBIDS this, specifically, in
297
            // routine F.2.2.5  it says
298
            // `The only valid marker which may occur within the Huffman coded data is the RSTm marker.`
299
            //
300
            // But libjpeg-turbo allows it because of some weird reason. so I'll also
301
            // allow it because of some weird reason.
302
0
            if let Some(m) = stream.marker {
303
0
                if m == Marker::EOI {
304
0
                    // acknowledge and ignore EOI marker.
305
0
                    stream.marker.take();
306
0
                    trace!("Found EOI marker");
307
0
                    // Google Introduced the Ultra-HD image format which is basically
308
0
                    // stitching two images into one container.
309
0
                    // They basically separate two images via a EOI and SOI marker
310
0
                    // so let's just ensure if we ever see EOI, we never read past that
311
0
                    // ever.
312
0
                    // https://github.com/google/libultrahdr
313
0
                    stream.seen_eoi = true;
314
0
                } else if let Marker::RST(_) = m {
315
                    //debug_assert_eq!(self.todo, 0);
316
0
                    if self.todo == 0 {
317
0
                        self.handle_rst(stream)?;
318
0
                    }
319
                } else {
320
0
                    if self.options.get_strict_mode() {
321
0
                        return Err(DecodeErrors::Format(format!(
322
0
                            "Marker {m:?} found where not expected"
323
0
                        )));
324
0
                    }
325
0
                    error!(
326
0
                        "Marker `{:?}` Found within Huffman Stream, possibly corrupt jpeg",
327
0
                        m
328
0
                    );
329
0
                    self.parse_marker_inner(m)?;
330
0
                    if m == Marker::SOS {
331
0
                        return Ok(true);
332
0
                    }
333
                }
334
0
            }
335
        }
336
0
        Ok(false)
337
0
    }
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::decode_mcu_width
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::decode_mcu_width
338
    // handle RST markers.
339
    // No-op if not using restarts
340
    // this routine is shared with mcu_prog
341
    #[cold]
342
0
    pub(crate) fn handle_rst(&mut self, stream: &mut BitStream) -> Result<(), DecodeErrors> {
343
0
        self.todo = self.restart_interval;
344
345
0
        if let Some(marker) = stream.marker {
346
            // Found a marker
347
            // Read stream and see what marker is stored there
348
0
            match marker {
349
0
                Marker::RST(_) => {
350
0
                    // reset stream
351
0
                    stream.reset();
352
0
                    // Initialize dc predictions to zero for all components
353
0
                    self.components.iter_mut().for_each(|x| x.dc_pred = 0);
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst::{closure#0}
354
0
                    // Start iterating again. from position.
355
0
                }
356
0
                Marker::EOI => {
357
0
                    // silent pass
358
0
                }
359
                _ => {
360
0
                    return Err(DecodeErrors::MCUError(format!(
361
0
                        "Marker {marker:?} found in bitstream, possibly corrupt jpeg"
362
0
                    )));
363
                }
364
            }
365
0
        }
366
0
        Ok(())
367
0
    }
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::handle_rst
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::handle_rst
368
    #[allow(clippy::too_many_lines, clippy::too_many_arguments)]
369
0
    pub(crate) fn post_process(
370
0
        &mut self, pixels: &mut [u8], i: usize, mcu_height: usize, width: usize,
371
0
        padded_width: usize, pixels_written: &mut usize, upsampler_scratch_space: &mut [i16]
372
0
    ) -> Result<(), DecodeErrors> {
373
0
        let out_colorspace_components = self.options.jpeg_get_out_colorspace().num_components();
374
0
375
0
        let mut px = *pixels_written;
376
0
        // indicates whether image is vertically up-sampled
377
0
        let is_vertically_sampled = self
378
0
            .components
379
0
            .iter()
380
0
            .any(|c| c.sample_ratio == SampleRatios::HV || c.sample_ratio == SampleRatios::V);
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#0}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#0}
381
0
382
0
        let mut comp_len = self.components.len();
383
0
384
0
        // If we are moving from YCbCr-> Luma, we do not allocate storage for other components, so we
385
0
        // will panic when we are trying to read samples, so for that case,
386
0
        // hardcode it so that we  don't panic when doing
387
0
        //   *samp = &samples[j][pos * padded_width..(pos + 1) * padded_width]
388
0
        if out_colorspace_components < comp_len && self.options.jpeg_get_out_colorspace() == Luma {
389
0
            comp_len = out_colorspace_components;
390
0
        }
391
0
        let mut color_conv_function =
392
0
            |num_iters: usize, samples: [&[i16]; 4]| -> Result<(), DecodeErrors> {
393
0
                for (pos, output) in pixels[px..]
394
0
                    .chunks_exact_mut(width * out_colorspace_components)
395
0
                    .take(num_iters)
396
0
                    .enumerate()
397
                {
398
0
                    let mut raw_samples: [&[i16]; 4] = [&[], &[], &[], &[]];
399
400
                    // iterate over each line, since color-convert needs only
401
                    // one line
402
0
                    for (j, samp) in raw_samples.iter_mut().enumerate().take(comp_len) {
403
0
                        *samp = &samples[j][pos * padded_width..(pos + 1) * padded_width];
404
0
                    }
405
0
                    color_convert(
406
0
                        &raw_samples,
407
0
                        self.color_convert_16,
408
0
                        self.input_colorspace,
409
0
                        self.options.jpeg_get_out_colorspace(),
410
0
                        output,
411
0
                        width,
412
0
                        padded_width
413
0
                    )?;
414
0
                    px += width * out_colorspace_components;
415
                }
416
0
                Ok(())
417
0
            };
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#1}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#1}
418
419
0
        let comps = &mut self.components[..];
420
0
421
0
        if self.is_interleaved && self.options.jpeg_get_out_colorspace() != ColorSpace::Luma {
422
            {
423
                // duplicated so that we can check that samples match
424
                // Fixes bug https://github.com/etemesi254/zune-image/issues/151
425
0
                let mut samples: [&[i16]; 4] = [&[], &[], &[], &[]];
426
427
0
                for (samp, component) in samples.iter_mut().zip(comps.iter()) {
428
0
                    *samp = if component.sample_ratio == SampleRatios::None {
429
0
                        &component.raw_coeff
430
                    } else {
431
0
                        &component.upsample_dest
432
                    };
433
                }
434
            }
435
0
            for comp in comps.iter_mut() {
436
0
                upsample(
437
0
                    comp,
438
0
                    mcu_height,
439
0
                    i,
440
0
                    upsampler_scratch_space,
441
0
                    is_vertically_sampled
442
0
                );
443
0
            }
444
445
0
            if is_vertically_sampled {
446
0
                if i > 0 {
447
                    // write the last line, it wasn't  up-sampled as we didn't have row_down
448
                    // yet
449
0
                    let mut samples: [&[i16]; 4] = [&[], &[], &[], &[]];
450
451
0
                    for (samp, component) in samples.iter_mut().zip(comps.iter()) {
452
0
                        *samp = &component.first_row_upsample_dest;
453
0
                    }
454
455
                    // ensure length matches for all samples
456
0
                    let _first_len = samples[0].len();
457
0
458
0
                    // This was a good check, but can be caused to panic, esp on invalid/corrupt images.
459
0
                    // See one in issue https://github.com/etemesi254/zune-image/issues/262, so for now
460
0
                    // we just ignore and generate invalid images at the end.
461
0
462
0
                    //
463
0
                    //
464
0
                    // for samp in samples.iter().take(comp_len) {
465
0
                    //     assert_eq!(first_len, samp.len());
466
0
                    // }
467
0
                    let num_iters = self.coeff * self.v_max;
468
0
469
0
                    color_conv_function(num_iters, samples)?;
470
0
                }
471
472
                // After up-sampling the last row, save  any row that can be used for
473
                // a later up-sampling,
474
                //
475
                // E.g the Y sample is not sampled but we haven't finished upsampling the last row of
476
                // the previous mcu, since we don't have the down row, so save it
477
0
                for component in comps.iter_mut() {
478
0
                    if component.sample_ratio != SampleRatios::H {
479
0
                        // We don't care about H sampling factors, since it's copied in the workers function
480
0
481
0
                        // copy last row to be used for the  next color conversion
482
0
                        let size = component.vertical_sample
483
0
                            * component.width_stride
484
0
                            * component.sample_ratio.sample();
485
0
486
0
                        let last_bytes =
487
0
                            component.raw_coeff.rchunks_exact_mut(size).next().unwrap();
488
0
489
0
                        component
490
0
                            .first_row_upsample_dest
491
0
                            .copy_from_slice(last_bytes);
492
0
                    }
493
                }
494
0
            }
495
496
0
            let mut samples: [&[i16]; 4] = [&[], &[], &[], &[]];
497
498
0
            for (samp, component) in samples.iter_mut().zip(comps.iter()) {
499
0
                *samp = if component.sample_ratio == SampleRatios::None {
500
0
                    &component.raw_coeff
501
                } else {
502
0
                    &component.upsample_dest
503
                };
504
            }
505
506
            // we either do 7 or 8 MCU's depending on the state, this only applies to
507
            // vertically sampled images
508
            //
509
            // for rows up until the last MCU, we do not upsample the last stride of the MCU
510
            // which means that the number of iterations should take that into account is one less the
511
            // up-sampled size
512
            //
513
            // For the last MCU, we upsample the last stride, meaning that if we hit the last MCU, we
514
            // should sample full raw coeffs
515
0
            let is_last_considered = is_vertically_sampled && (i != mcu_height.saturating_sub(1));
516
517
0
            let num_iters = (8 - usize::from(is_last_considered)) * self.coeff * self.v_max;
518
0
519
0
            color_conv_function(num_iters, samples)?;
520
        } else {
521
0
            let mut channels_ref: [&[i16]; MAX_COMPONENTS] = [&[]; MAX_COMPONENTS];
522
0
523
0
            self.components
524
0
                .iter()
525
0
                .enumerate()
526
0
                .for_each(|(pos, x)| channels_ref[pos] = &x.raw_coeff);
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process::{closure#2}
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process::{closure#2}
527
0
528
0
            color_conv_function(8 * self.coeff, channels_ref)?;
529
        }
530
531
0
        *pixels_written = px;
532
0
        Ok(())
533
0
    }
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<_>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<alloc::vec::Vec<u8>>>::post_process
Unexecuted instantiation: <zune_jpeg::decoder::JpegDecoder<&[u8]>>::post_process
534
}