Coverage Report

Created: 2025-10-28 08:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zune-jpeg-0.5.5/src/misc.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
//!Miscellaneous stuff
10
#![allow(dead_code)]
11
12
use alloc::format;
13
use core::cmp::max;
14
use core::fmt;
15
use core::num::NonZeroU32;
16
17
use zune_core::bytestream::ZByteReaderTrait;
18
use zune_core::colorspace::ColorSpace;
19
use zune_core::log::{trace, warn};
20
21
use crate::components::{ComponentID, SampleRatios};
22
use crate::errors::DecodeErrors;
23
use crate::huffman::HuffmanTable;
24
use crate::JpegDecoder;
25
26
/// Start of baseline DCT Huffman coding
27
28
pub const START_OF_FRAME_BASE: u16 = 0xffc0;
29
30
/// Start of another frame
31
32
pub const START_OF_FRAME_EXT_SEQ: u16 = 0xffc1;
33
34
/// Start of progressive DCT encoding
35
36
pub const START_OF_FRAME_PROG_DCT: u16 = 0xffc2;
37
38
/// Start of Lossless sequential Huffman coding
39
40
pub const START_OF_FRAME_LOS_SEQ: u16 = 0xffc3;
41
42
/// Start of extended sequential DCT arithmetic coding
43
44
pub const START_OF_FRAME_EXT_AR: u16 = 0xffc9;
45
46
/// Start of Progressive DCT arithmetic coding
47
48
pub const START_OF_FRAME_PROG_DCT_AR: u16 = 0xffca;
49
50
/// Start of Lossless sequential Arithmetic coding
51
52
pub const START_OF_FRAME_LOS_SEQ_AR: u16 = 0xffcb;
53
54
/// Undo run length encoding of coefficients by placing them in natural order
55
///
56
/// This is an index from position-in-bitstream to position-in-row-major-order.
57
#[rustfmt::skip]
58
pub const UN_ZIGZAG: [usize; 64 + 16] = [
59
     0,  1,  8, 16,  9,  2,  3, 10,
60
    17, 24, 32, 25, 18, 11,  4,  5,
61
    12, 19, 26, 33, 40, 48, 41, 34,
62
    27, 20, 13,  6,  7, 14, 21, 28,
63
    35, 42, 49, 56, 57, 50, 43, 36,
64
    29, 22, 15, 23, 30, 37, 44, 51,
65
    58, 59, 52, 45, 38, 31, 39, 46,
66
    53, 60, 61, 54, 47, 55, 62, 63,
67
    // Prevent overflowing
68
    63, 63, 63, 63, 63, 63, 63, 63,
69
    63, 63, 63, 63, 63, 63, 63, 63
70
];
71
72
/// Align data to a 16 byte boundary
73
#[repr(align(16))]
74
#[derive(Clone)]
75
76
pub struct Aligned16<T: ?Sized>(pub T);
77
78
impl<T> Default for Aligned16<T>
79
where
80
    T: Default
81
{
82
0
    fn default() -> Self {
83
0
        Aligned16(T::default())
84
0
    }
85
}
86
87
/// Align data to a 32 byte boundary
88
#[repr(align(32))]
89
#[derive(Clone)]
90
pub struct Aligned32<T: ?Sized>(pub T);
91
92
impl<T> Default for Aligned32<T>
93
where
94
    T: Default
95
{
96
0
    fn default() -> Self {
97
0
        Aligned32(T::default())
98
0
    }
99
}
100
101
/// Markers that identify different Start of Image markers
102
/// They identify the type of encoding and whether the file use lossy(DCT) or
103
/// lossless compression and whether we use Huffman or arithmetic coding schemes
104
#[derive(Eq, PartialEq, Copy, Clone)]
105
#[allow(clippy::upper_case_acronyms)]
106
pub enum SOFMarkers {
107
    /// Baseline DCT markers
108
    BaselineDct,
109
    /// SOF_1 Extended sequential DCT,Huffman coding
110
    ExtendedSequentialHuffman,
111
    /// Progressive DCT, Huffman coding
112
    ProgressiveDctHuffman,
113
    /// Lossless (sequential), huffman coding,
114
    LosslessHuffman,
115
    /// Extended sequential DEC, arithmetic coding
116
    ExtendedSequentialDctArithmetic,
117
    /// Progressive DCT, arithmetic coding,
118
    ProgressiveDctArithmetic,
119
    /// Lossless ( sequential), arithmetic coding
120
    LosslessArithmetic
121
}
122
123
impl Default for SOFMarkers {
124
0
    fn default() -> Self {
125
0
        Self::BaselineDct
126
0
    }
127
}
128
129
impl SOFMarkers {
130
    /// Check if a certain marker is sequential DCT or not
131
132
0
    pub fn is_sequential_dct(self) -> bool {
133
0
        matches!(
134
0
            self,
135
            Self::BaselineDct
136
                | Self::ExtendedSequentialHuffman
137
                | Self::ExtendedSequentialDctArithmetic
138
        )
139
0
    }
140
141
    /// Check if a marker is a Lossles type or not
142
143
0
    pub fn is_lossless(self) -> bool {
144
0
        matches!(self, Self::LosslessHuffman | Self::LosslessArithmetic)
145
0
    }
146
147
    /// Check whether a marker is a progressive marker or not
148
149
0
    pub fn is_progressive(self) -> bool {
150
0
        matches!(
151
0
            self,
152
            Self::ProgressiveDctHuffman | Self::ProgressiveDctArithmetic
153
        )
154
0
    }
155
156
    /// Create a marker from an integer
157
158
0
    pub fn from_int(int: u16) -> Option<SOFMarkers> {
159
0
        match int {
160
0
            START_OF_FRAME_BASE => Some(Self::BaselineDct),
161
0
            START_OF_FRAME_PROG_DCT => Some(Self::ProgressiveDctHuffman),
162
0
            START_OF_FRAME_PROG_DCT_AR => Some(Self::ProgressiveDctArithmetic),
163
0
            START_OF_FRAME_LOS_SEQ => Some(Self::LosslessHuffman),
164
0
            START_OF_FRAME_LOS_SEQ_AR => Some(Self::LosslessArithmetic),
165
0
            START_OF_FRAME_EXT_SEQ => Some(Self::ExtendedSequentialHuffman),
166
0
            START_OF_FRAME_EXT_AR => Some(Self::ExtendedSequentialDctArithmetic),
167
0
            _ => None
168
        }
169
0
    }
170
}
171
172
impl fmt::Debug for SOFMarkers {
173
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
174
0
        match &self {
175
0
            Self::BaselineDct => write!(f, "Baseline DCT"),
176
            Self::ExtendedSequentialHuffman => {
177
0
                write!(f, "Extended sequential DCT, Huffman Coding")
178
            }
179
0
            Self::ProgressiveDctHuffman => write!(f, "Progressive DCT,Huffman Encoding"),
180
0
            Self::LosslessHuffman => write!(f, "Lossless (sequential) Huffman encoding"),
181
            Self::ExtendedSequentialDctArithmetic => {
182
0
                write!(f, "Extended sequential DCT, arithmetic coding")
183
            }
184
0
            Self::ProgressiveDctArithmetic => write!(f, "Progressive DCT, arithmetic coding"),
185
0
            Self::LosslessArithmetic => write!(f, "Lossless (sequential) arithmetic coding")
186
        }
187
0
    }
188
}
189
190
/// Set up component parameters.
191
///
192
/// This modifies the components in place setting up details needed by other
193
/// parts fo the decoder.
194
0
pub(crate) fn setup_component_params<T: ZByteReaderTrait>(
195
0
    img: &mut JpegDecoder<T>
196
0
) -> Result<(), DecodeErrors> {
197
0
    let img_width = img.width();
198
0
    let img_height = img.height();
199
200
    // in case of adobe app14 being present, zero may indicate
201
    // either CMYK if components are 4 or RGB if components are 3,
202
    // see https://docs.oracle.com/javase/6/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html
203
    // so since we may not know how many number of components
204
    // we have when decoding app14, we have to defer that check
205
    // until now.
206
    //
207
    // We know adobe app14 was present since it's the only one that can modify
208
    // input colorspace to be CMYK
209
0
    if img.components.len() == 3 && img.input_colorspace == ColorSpace::CMYK {
210
0
        img.input_colorspace = ColorSpace::RGB;
211
0
    }
212
213
0
    for component in &mut img.components {
214
        // compute interleaved image info
215
        // h_max contains the maximum horizontal component
216
0
        img.h_max = max(img.h_max, component.horizontal_sample);
217
        // v_max contains the maximum vertical component
218
0
        img.v_max = max(img.v_max, component.vertical_sample);
219
0
        img.mcu_width = img.h_max * 8;
220
0
        img.mcu_height = img.v_max * 8;
221
        // Number of MCU's per width
222
0
        img.mcu_x = usize::from(img.info.width).div_ceil(img.mcu_width);
223
        // Number of MCU's per height
224
0
        img.mcu_y = usize::from(img.info.height).div_ceil(img.mcu_height);
225
226
0
        if img.h_max != 1 || img.v_max != 1 {
227
0
            // interleaved images have horizontal and vertical sampling factors
228
0
            // not equal to 1.
229
0
            img.is_interleaved = true;
230
0
        }
231
        // Extract quantization tables from the arrays into components
232
0
        let qt_table = *img.qt_tables[component.quantization_table_number as usize]
233
0
            .as_ref()
234
0
            .ok_or_else(|| {
235
0
                DecodeErrors::DqtError(format!(
236
0
                    "No quantization table for component {:?}",
237
0
                    component.component_id
238
0
                ))
239
0
            })?;
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#0}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<_>::{closure#0}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#0}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#0}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#0}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#0}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#0}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#0}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#0}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#0}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#0}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#0}
240
241
0
        let x = (usize::from(img_width) * component.horizontal_sample + img.h_max - 1) / img.h_max;
242
0
        let y = (usize::from(img_height) * component.horizontal_sample + img.h_max - 1) / img.v_max;
243
0
        component.x = x;
244
0
        component.w2 = img.mcu_x * component.horizontal_sample * 8;
245
        // probably not needed. :)
246
0
        component.y = y;
247
0
        component.quantization_table = qt_table;
248
        // initially stride contains its horizontal sub-sampling
249
0
        component.width_stride *= img.mcu_x * 8;
250
    }
251
    {
252
        // Sampling factors are one thing that suck
253
        // this fixes a specific problem with images like
254
        //
255
        // (2 2) None
256
        // (2 1) H
257
        // (2 1) H
258
        //
259
        // The images exist in the wild, the images are not meant to exist
260
        // but they do, it's just an annoying horizontal sub-sampling that
261
        // I don't know why it exists.
262
        // But it does
263
        // So we try to cope with that.
264
        // I am not sure of how to explain how to fix it, but it involved a debugger
265
        // and to much coke(the legal one)
266
        //
267
        // If this wasn't present, self.upsample_dest would have the wrong length
268
0
        let mut handle_that_annoying_bug = false;
269
270
0
        if let Some(y_component) = img
271
0
            .components
272
0
            .iter()
273
0
            .find(|c| c.component_id == ComponentID::Y)
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#1}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<_>::{closure#1}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#1}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#1}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#1}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#1}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#1}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#1}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#1}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#1}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#1}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>::{closure#1}
274
        {
275
0
            if y_component.horizontal_sample == 2 || y_component.vertical_sample == 2 {
276
0
                handle_that_annoying_bug = true;
277
0
            }
278
0
        }
279
0
        if handle_that_annoying_bug {
280
0
            for comp in &mut img.components {
281
0
                if (comp.component_id != ComponentID::Y)
282
0
                    && (comp.horizontal_sample != 1 || comp.vertical_sample != 1)
283
0
                {
284
0
                    comp.fix_an_annoying_bug = 2;
285
0
                }
286
            }
287
0
        }
288
    }
289
290
0
    if img.is_mjpeg {
291
0
        fill_default_mjpeg_tables(
292
0
            img.is_progressive,
293
0
            &mut img.dc_huffman_tables,
294
0
            &mut img.ac_huffman_tables
295
0
        );
296
0
    }
297
298
    // check colorspace matches
299
0
    if img.input_colorspace.num_components() > img.components.len() {
300
0
        if img.input_colorspace == ColorSpace::YCCK {
301
            // Some images may have YCCK format (from adobe app14 segment) which is supposed to be 4 components
302
            // but only 3 components, see issue https://github.com/etemesi254/zune-image/issues/275
303
            // So this is the behaviour of other decoders
304
            // - stb_image: Treats it as YCbCr image
305
            // - libjpeg_turbo: Does not know how to parse YCCK images (transform 2 app14) so treats
306
            // it as YCbCr
307
            // So I will match that to match existing ones
308
0
            warn!("Treating YCCK colorspace as YCbCr as component length does not match");
309
0
            img.input_colorspace = ColorSpace::YCbCr
310
        } else {
311
            // Note, translated this to a warning to handle valid images of the sort
312
            // See https://github.com/etemesi254/zune-image/issues/288 where there
313
            // was a CMYK image with two components which would be decoded to 4 components
314
            // by the decoder.
315
            // So with a warning that becomes supported.
316
            //
317
            // djpeg fails to render an image from that also probably because it does not
318
            // understand the expected format.
319
0
            if !img.options.strict_mode() {
320
0
                warn!(
321
                    "Expected {} number of components but found {}",
322
                    img.input_colorspace.num_components(),
323
                    img.components.len()
324
                );
325
0
                warn!("Defaulting to multisample to decode");
326
327
                // N/B: We do not post process the color of such, treating it as multiband
328
                // is the best option since I am not aware of grayscale+alpha which is the most common
329
                // two band format in jpeg.
330
0
                if img.components.len() > 0 {
331
0
                    img.input_colorspace = ColorSpace::MultiBand(
332
0
                        NonZeroU32::new(img.components.len() as u32).unwrap()
333
0
                    );
334
0
                }
335
            } else {
336
0
                let msg = format!(
337
0
                    "Expected {} number of components but found {}",
338
0
                    img.input_colorspace.num_components(),
339
0
                    img.components.len()
340
                );
341
342
0
                return Err(DecodeErrors::Format(msg));
343
            }
344
        }
345
0
    }
346
0
    Ok(())
347
0
}
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<_>
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>
Unexecuted instantiation: zune_jpeg::misc::setup_component_params::<zune_core::bytestream::reader::no_std_readers::ZCursor<&[u8]>>
348
349
///Calculate number of fill bytes added to the end of a JPEG image
350
/// to fill the image
351
///
352
/// JPEG usually inserts padding bytes if the image width cannot be evenly divided into
353
/// 8 , 16 or 32 chunks depending on the sub sampling ratio. So given a sub-sampling ratio,
354
/// and the actual width, this calculates the padded bytes that were added to the image
355
///
356
///  # Params
357
/// -actual_width: Actual width of the image
358
/// -sub_sample: Sub sampling factor of the image
359
///
360
/// # Returns
361
/// The padded width, this is how long the width is for a particular image
362
0
pub fn calculate_padded_width(actual_width: usize, sub_sample: SampleRatios) -> usize {
363
0
    match sub_sample {
364
        SampleRatios::None | SampleRatios::V => {
365
            // None+V sends one MCU row, so that's a simple calculation
366
0
            ((actual_width + 7) / 8) * 8
367
        }
368
        SampleRatios::H | SampleRatios::HV => {
369
            // sends two rows, width can be expanded by up to 15 more bytes
370
0
            ((actual_width + 15) / 16) * 16
371
        }
372
0
        SampleRatios::Generic(h, _) => {
373
0
            ((actual_width + ((h * 8).saturating_sub(1))) / (h * 8)) * (h * 8)
374
        }
375
    }
376
0
}
377
378
// https://www.loc.gov/preservation/digital/formats/fdd/fdd000063.shtml
379
// "Avery Lee, writing in the rec.video.desktop newsgroup in 2001, commented that "MJPEG, or at
380
//  least the MJPEG in AVIs having the MJPG fourcc, is restricted JPEG with a fixed -- and
381
//  *omitted* -- Huffman table. The JPEG must be YCbCr colorspace, it must be 4:2:2, and it must
382
//  use basic Huffman encoding, not arithmetic or progressive.... You can indeed extract the
383
//  MJPEG frames and decode them with a regular JPEG decoder, but you have to prepend the DHT
384
//  segment to them, or else the decoder won't have any idea how to decompress the data.
385
//  The exact table necessary is given in the OpenDML spec.""
386
0
pub fn fill_default_mjpeg_tables(
387
0
    is_progressive: bool, dc_huffman_tables: &mut [Option<HuffmanTable>],
388
0
    ac_huffman_tables: &mut [Option<HuffmanTable>]
389
0
) {
390
    // Section K.3.3
391
    trace!("Filling with default mjpeg tables");
392
393
0
    if dc_huffman_tables[0].is_none() {
394
0
        // Table K.3
395
0
        dc_huffman_tables[0] = Some(
396
0
            HuffmanTable::new_unfilled(
397
0
                &[
398
0
                    0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
399
0
                    0x00, 0x00, 0x00, 0x00
400
0
                ],
401
0
                &[
402
0
                    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B
403
0
                ],
404
0
                true,
405
0
                is_progressive
406
0
            )
407
0
            .unwrap()
408
0
        );
409
0
    }
410
0
    if dc_huffman_tables[1].is_none() {
411
0
        // Table K.4
412
0
        dc_huffman_tables[1] = Some(
413
0
            HuffmanTable::new_unfilled(
414
0
                &[
415
0
                    0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
416
0
                    0x00, 0x00, 0x00, 0x00
417
0
                ],
418
0
                &[
419
0
                    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B
420
0
                ],
421
0
                true,
422
0
                is_progressive
423
0
            )
424
0
            .unwrap()
425
0
        );
426
0
    }
427
0
    if ac_huffman_tables[0].is_none() {
428
0
        // Table K.5
429
0
        ac_huffman_tables[0] = Some(
430
0
            HuffmanTable::new_unfilled(
431
0
                &[
432
0
                    0x00, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04,
433
0
                    0x00, 0x00, 0x01, 0x7D
434
0
                ],
435
0
                &[
436
0
                    0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13,
437
0
                    0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42,
438
0
                    0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A,
439
0
                    0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35,
440
0
                    0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
441
0
                    0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67,
442
0
                    0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84,
443
0
                    0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
444
0
                    0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3,
445
0
                    0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
446
0
                    0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1,
447
0
                    0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4,
448
0
                    0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
449
0
                ],
450
0
                false,
451
0
                is_progressive
452
0
            )
453
0
            .unwrap()
454
0
        );
455
0
    }
456
0
    if ac_huffman_tables[1].is_none() {
457
0
        // Table K.6
458
0
        ac_huffman_tables[1] = Some(
459
0
            HuffmanTable::new_unfilled(
460
0
                &[
461
0
                    0x00, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04,
462
0
                    0x00, 0x01, 0x02, 0x77
463
0
                ],
464
0
                &[
465
0
                    0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51,
466
0
                    0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1,
467
0
                    0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24,
468
0
                    0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
469
0
                    0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
470
0
                    0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
471
0
                    0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82,
472
0
                    0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
473
0
                    0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA,
474
0
                    0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5,
475
0
                    0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
476
0
                    0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4,
477
0
                    0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
478
0
                ],
479
0
                false,
480
0
                is_progressive
481
0
            )
482
0
            .unwrap()
483
0
        );
484
0
    }
485
0
}