/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 | } |