GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/*************************************************************************** |
||
2 |
* Copyright (c) 2024 Microsoft Corporation |
||
3 |
* |
||
4 |
* This program and the accompanying materials are made available under the |
||
5 |
* terms of the MIT License which is available at |
||
6 |
* https://opensource.org/licenses/MIT. |
||
7 |
* |
||
8 |
* SPDX-License-Identifier: MIT |
||
9 |
**************************************************************************/ |
||
10 |
|||
11 |
|||
12 |
/**************************************************************************/ |
||
13 |
/**************************************************************************/ |
||
14 |
/** */ |
||
15 |
/** GUIX Component */ |
||
16 |
/** */ |
||
17 |
/** Utility Management (Utility) */ |
||
18 |
/** */ |
||
19 |
/**************************************************************************/ |
||
20 |
|||
21 |
#define GX_SOURCE_CODE |
||
22 |
|||
23 |
/* Include necessary system files. */ |
||
24 |
|||
25 |
#include "gx_api.h" |
||
26 |
#include "gx_context.h" |
||
27 |
#include "gx_system.h" |
||
28 |
#include "gx_utility.h" |
||
29 |
#include "gx_image_reader.h" |
||
30 |
|||
31 |
#if defined(GX_SOFTWARE_DECODER_SUPPORT) |
||
32 |
|||
33 |
#define GX_SATURATE_TO_UBYTE(result, i) \ |
||
34 |
{ \ |
||
35 |
if ((i) < 0) \ |
||
36 |
{ \ |
||
37 |
(result) = 0; \ |
||
38 |
} \ |
||
39 |
else if ((i) > 255) \ |
||
40 |
{ \ |
||
41 |
(result) = 255; \ |
||
42 |
} \ |
||
43 |
else \ |
||
44 |
{ \ |
||
45 |
(result) = (GX_UBYTE)(i); \ |
||
46 |
} \ |
||
47 |
} |
||
48 |
|||
49 |
#define GX_SATURATE_TO_BYTE(result, i) \ |
||
50 |
{ \ |
||
51 |
if ((i) < -128) \ |
||
52 |
{ \ |
||
53 |
(result) = -128; \ |
||
54 |
} \ |
||
55 |
else if ((i) > 127) \ |
||
56 |
{ \ |
||
57 |
(result) = 127; \ |
||
58 |
} \ |
||
59 |
else \ |
||
60 |
{ \ |
||
61 |
(result) = (GX_BYTE)(i); \ |
||
62 |
} \ |
||
63 |
} |
||
64 |
|||
65 |
#define GX_JPEG_BITS_GET(jpeg_info, num_of_bits) \ |
||
66 |
while (jpeg_info -> gx_jpeg_bit_count <= num_of_bits) \ |
||
67 |
{ \ |
||
68 |
if ((jpeg_info -> gx_jpeg_data_index < jpeg_info -> gx_jpeg_data_size) && (jpeg_info -> gx_jpeg_bit_count <= 24)) \ |
||
69 |
{ \ |
||
70 |
jpeg_info -> gx_jpeg_bit_buffer |= ((UINT)(jpeg_info -> gx_jpeg_data[jpeg_info -> gx_jpeg_data_index]) << (UINT)(24 - jpeg_info -> gx_jpeg_bit_count)); \ |
||
71 |
\ |
||
72 |
/* 2 byte 'FF00' sequence should be considered as just a byte 0xFF. */ \ |
||
73 |
if ((jpeg_info -> gx_jpeg_data[jpeg_info -> gx_jpeg_data_index] == 0xff) && \ |
||
74 |
(jpeg_info -> gx_jpeg_data_index + 1 < jpeg_info -> gx_jpeg_data_size) && \ |
||
75 |
(jpeg_info -> gx_jpeg_data[jpeg_info -> gx_jpeg_data_index + 1] == 0x00)) \ |
||
76 |
{ \ |
||
77 |
jpeg_info -> gx_jpeg_data_index += 2; \ |
||
78 |
} \ |
||
79 |
else \ |
||
80 |
{ \ |
||
81 |
jpeg_info -> gx_jpeg_data_index += 1; \ |
||
82 |
} \ |
||
83 |
} \ |
||
84 |
\ |
||
85 |
jpeg_info -> gx_jpeg_bit_count += 8; \ |
||
86 |
} |
||
87 |
|||
88 |
#define GX_JPEG_BITS_SKIP(jpeg_info, skip_bits) \ |
||
89 |
(jpeg_info) -> gx_jpeg_bit_buffer <<= (skip_bits); \ |
||
90 |
(jpeg_info) -> gx_jpeg_bit_count -= (skip_bits); |
||
91 |
|||
92 |
/**************************************************************************/ |
||
93 |
/* */ |
||
94 |
/* FUNCTION RELEASE */ |
||
95 |
/* */ |
||
96 |
/* _gx_dislay_driver_jpeg_quantization_table_set PORTABLE C */ |
||
97 |
/* 6.2.0 */ |
||
98 |
/* AUTHOR */ |
||
99 |
/* */ |
||
100 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
101 |
/* */ |
||
102 |
/* DESCRIPTION */ |
||
103 |
/* */ |
||
104 |
/* Sets the JPEG quantization table. */ |
||
105 |
/* */ |
||
106 |
/* INPUT */ |
||
107 |
/* */ |
||
108 |
/* jpeg_info JPEG data control block */ |
||
109 |
/* segment_len Initial length of the segment */ |
||
110 |
/* */ |
||
111 |
/* OUTPUT */ |
||
112 |
/* */ |
||
113 |
/* None */ |
||
114 |
/* */ |
||
115 |
/* CALLS */ |
||
116 |
/* */ |
||
117 |
/* None */ |
||
118 |
/* */ |
||
119 |
/* CALLED BY */ |
||
120 |
/* */ |
||
121 |
/* _gx_image_reader_jpeg_decode */ |
||
122 |
/* */ |
||
123 |
/* RELEASE HISTORY */ |
||
124 |
/* */ |
||
125 |
/* DATE NAME DESCRIPTION */ |
||
126 |
/* */ |
||
127 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
128 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
129 |
/* resulting in version 6.1 */ |
||
130 |
/* 10-31-2022 Kenneth Maxwell Modified comment(s), */ |
||
131 |
/* prevented underflow from */ |
||
132 |
/* bad input data, */ |
||
133 |
/* resulting in version 6.2.0 */ |
||
134 |
/* */ |
||
135 |
/**************************************************************************/ |
||
136 |
842 |
static UINT _gx_image_reader_jpeg_quantization_table_set(GX_JPEG_INFO *jpeg_info, UINT segment_len) |
|
137 |
{ |
||
138 |
GX_UBYTE table_index; |
||
139 |
842 |
GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index; |
|
140 |
INT index; |
||
141 |
|||
142 |
/* Minus two-byte length. */ |
||
143 |
842 |
jpeg_info -> gx_jpeg_data_index += (INT)segment_len; |
|
144 |
842 |
segment_len -= 2; |
|
145 |
842 |
jpeg_data += 2; |
|
146 |
|||
147 |
✓✓ | 2022 |
while (segment_len) |
148 |
{ |
||
149 |
/* The upper 4 bits specify the element precision: 0 indicates 8-bit, 1 indecates 16-bit. */ |
||
150 |
✓✓ | 1181 |
if ((*jpeg_data) & 0xf0) |
151 |
{ |
||
152 |
/* Baseline DCT-based jpeg only support 8-bit precision. */ |
||
153 |
1 |
return GX_NOT_SUPPORTED; |
|
154 |
} |
||
155 |
|||
156 |
/* The lower 4 bits specify the table destination identifier, specify one of four possible destinations. */ |
||
157 |
1180 |
table_index = (*jpeg_data++) & 0x03; |
|
158 |
|||
159 |
/* Read quantization table element. */ |
||
160 |
✓✓ | 76700 |
for (index = 0; index < 64; index++) |
161 |
{ |
||
162 |
75520 |
jpeg_info -> gx_jpeg_quantization_table[table_index][index] = *jpeg_data++; |
|
163 |
} |
||
164 |
|||
165 |
✗✓ | 1180 |
if (segment_len < 65) |
166 |
{ |
||
167 |
return GX_INVALID_FORMAT; |
||
168 |
} |
||
169 |
1180 |
segment_len -= 65; |
|
170 |
} |
||
171 |
|||
172 |
841 |
return GX_SUCCESS; |
|
173 |
} |
||
174 |
|||
175 |
/**************************************************************************/ |
||
176 |
/* */ |
||
177 |
/* FUNCTION RELEASE */ |
||
178 |
/* */ |
||
179 |
/* _gx_image_reader_jpeg_huffcode_find PORTABLE C */ |
||
180 |
/* 6.3.0 */ |
||
181 |
/* AUTHOR */ |
||
182 |
/* */ |
||
183 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
184 |
/* */ |
||
185 |
/* DESCRIPTION */ |
||
186 |
/* */ |
||
187 |
/* Lookup the huffman code. */ |
||
188 |
/* */ |
||
189 |
/* INPUT */ |
||
190 |
/* */ |
||
191 |
/* jpeg_info JPEG data control block */ |
||
192 |
/* table_class Table class, 0 = DC table, */ |
||
193 |
/* 1 = AC table */ |
||
194 |
/* table_id Table index */ |
||
195 |
/* scan_buffer Buffer to search from */ |
||
196 |
/* bit_len Retrieved Huffman Code Length */ |
||
197 |
/* code_value Retrieved Huffman Code */ |
||
198 |
/* */ |
||
199 |
/* OUTPUT */ |
||
200 |
/* */ |
||
201 |
/* Status Code */ |
||
202 |
/* */ |
||
203 |
/* CALLS */ |
||
204 |
/* */ |
||
205 |
/* None */ |
||
206 |
/* */ |
||
207 |
/* CALLED BY */ |
||
208 |
/* */ |
||
209 |
/* _gx_image_reader_jpeg_dc_decode */ |
||
210 |
/* _gx_image_reader_jpeg_ac_decode */ |
||
211 |
/* */ |
||
212 |
/* RELEASE HISTORY */ |
||
213 |
/* */ |
||
214 |
/* DATE NAME DESCRIPTION */ |
||
215 |
/* */ |
||
216 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
217 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
218 |
/* resulting in version 6.1 */ |
||
219 |
/* 10-31-2022 Kenneth Maxwell Modified comment(s), */ |
||
220 |
/* changed bit_count to */ |
||
221 |
/* GX_VALUE data type, */ |
||
222 |
/* resulting in version 6.2.0 */ |
||
223 |
/* 10-31-2023 Ting Zhu Modified comment(s), */ |
||
224 |
/* improved logic, */ |
||
225 |
/* resulting in version 6.3.0 */ |
||
226 |
/* */ |
||
227 |
/**************************************************************************/ |
||
228 |
28037764 |
static UINT _gx_image_reader_jpeg_huffcode_find(GX_JPEG_INFO *jpeg_info, |
|
229 |
UINT table_class, |
||
230 |
UINT table_id, |
||
231 |
UINT *bit_len, |
||
232 |
GX_UBYTE *code_value) |
||
233 |
{ |
||
234 |
GX_UBYTE index; |
||
235 |
USHORT code; |
||
236 |
USHORT code_index; |
||
237 |
GX_HUFFCODE_INFO *code_info; |
||
238 |
|||
239 |
✓✗ | 72498987 |
for (index = 0; index < 16; index++) |
240 |
{ |
||
241 |
72498987 |
code_info = &jpeg_info -> gx_jpeg_huffman_code_info[table_class][table_id][index]; |
|
242 |
✓✓ | 72498987 |
if (code_info -> bits) |
243 |
{ |
||
244 |
72498664 |
code = (USHORT)((jpeg_info -> gx_jpeg_bit_buffer) >> (32 - code_info -> bits)); |
|
245 |
|||
246 |
✓✓ | 72498664 |
if (code <= code_info -> end) |
247 |
{ |
||
248 |
28037441 |
code_index = (USHORT)(code_info -> index + code - code_info -> start); |
|
249 |
28037441 |
*bit_len = code_info -> bits; |
|
250 |
28037441 |
*code_value = jpeg_info -> gx_jpeg_huffman_table[table_class][table_id][code_index]; |
|
251 |
28037441 |
return GX_SUCCESS; |
|
252 |
} |
||
253 |
} |
||
254 |
else |
||
255 |
{ |
||
256 |
323 |
break; |
|
257 |
} |
||
258 |
} |
||
259 |
|||
260 |
323 |
return GX_FAILURE; |
|
261 |
} |
||
262 |
|||
263 |
/**************************************************************************/ |
||
264 |
/* */ |
||
265 |
/* FUNCTION RELEASE */ |
||
266 |
/* */ |
||
267 |
/* _gx_image_reader_huffman_table_set PORTABLE C */ |
||
268 |
/* 6.3.0 */ |
||
269 |
/* AUTHOR */ |
||
270 |
/* */ |
||
271 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
272 |
/* */ |
||
273 |
/* DESCRIPTION */ |
||
274 |
/* */ |
||
275 |
/* Sets up the huffman table. */ |
||
276 |
/* */ |
||
277 |
/* INPUT */ |
||
278 |
/* */ |
||
279 |
/* jpeg_info JPEG data control block */ |
||
280 |
/* segment_len Initial length of the segment */ |
||
281 |
/* */ |
||
282 |
/* OUTPUT */ |
||
283 |
/* */ |
||
284 |
/* None */ |
||
285 |
/* */ |
||
286 |
/* CALLS */ |
||
287 |
/* */ |
||
288 |
/* None */ |
||
289 |
/* */ |
||
290 |
/* CALLED BY */ |
||
291 |
/* */ |
||
292 |
/* _gx_image_reader_jpeg_decode_blocks */ |
||
293 |
/* */ |
||
294 |
/* RELEASE HISTORY */ |
||
295 |
/* */ |
||
296 |
/* DATE NAME DESCRIPTION */ |
||
297 |
/* */ |
||
298 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
299 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
300 |
/* resulting in version 6.1 */ |
||
301 |
/* 10-31-2022 Kenneth Maxwell Modified comment(s), */ |
||
302 |
/* added range test to prevent */ |
||
303 |
/* underflow, */ |
||
304 |
/* resulting in version 6.2.0 */ |
||
305 |
/* 10-31-2023 Ting Zhu Modified comment(s), */ |
||
306 |
/* improved logic, */ |
||
307 |
/* resulting in version 6.3.0 */ |
||
308 |
/* */ |
||
309 |
/**************************************************************************/ |
||
310 |
1335 |
static UINT _gx_image_reader_huffman_table_set(GX_JPEG_INFO *jpeg_info, UINT segment_len) |
|
311 |
{ |
||
312 |
1335 |
GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index; |
|
313 |
GX_UBYTE table_class; |
||
314 |
GX_UBYTE table_id; |
||
315 |
GX_UBYTE bit_count; |
||
316 |
UINT i_bits; |
||
317 |
USHORT i_table_size; |
||
318 |
GX_HUFFCODE_INFO *code_info; |
||
319 |
1335 |
INT index = 0; |
|
320 |
1335 |
USHORT code = 0; |
|
321 |
|||
322 |
/* must have at least one code for each of 16 huffman bit lengths */ |
||
323 |
✗✓ | 1335 |
if (segment_len < 19) |
324 |
{ |
||
325 |
return GX_INVALID_FORMAT; |
||
326 |
} |
||
327 |
|||
328 |
/* Minus two-byte length. */ |
||
329 |
1335 |
jpeg_info -> gx_jpeg_data_index += (INT)segment_len; |
|
330 |
1335 |
segment_len -= 2; |
|
331 |
1335 |
jpeg_data += 2; |
|
332 |
|||
333 |
✓✓ | 3687 |
while (segment_len) |
334 |
{ |
||
335 |
/* table_calss: 0 DC 1 AC */ |
||
336 |
2352 |
table_class = ((*jpeg_data) >> 4) & 1; |
|
337 |
2352 |
table_id = (*jpeg_data++) & 0x01; |
|
338 |
|||
339 |
✗✓ | 2352 |
if (segment_len < 17) |
340 |
{ |
||
341 |
return GX_INVALID_FORMAT; |
||
342 |
} |
||
343 |
2352 |
segment_len -= 17; |
|
344 |
|||
345 |
2352 |
i_table_size = 0; |
|
346 |
|||
347 |
2352 |
index = 0; |
|
348 |
2352 |
code = 0; |
|
349 |
|||
350 |
/* Read the number of Huffman codes for each bit length, from 1 to 16. */ |
||
351 |
✓✓ | 39984 |
for (i_bits = 0; i_bits < 16; i_bits++) |
352 |
{ |
||
353 |
37632 |
bit_count = *jpeg_data++; |
|
354 |
|||
355 |
✓✓ | 37632 |
if (bit_count) |
356 |
{ |
||
357 |
24977 |
code_info = &jpeg_info -> gx_jpeg_huffman_code_info[table_class][table_id][index++]; |
|
358 |
24977 |
code_info -> index = i_table_size; |
|
359 |
24977 |
code_info -> start = code; |
|
360 |
24977 |
code_info -> end = (USHORT)(code + bit_count - 1); |
|
361 |
24977 |
code_info -> bits = (GX_UBYTE)(i_bits + 1); |
|
362 |
} |
||
363 |
37632 |
code = (USHORT)((code + bit_count) << 1); |
|
364 |
|||
365 |
37632 |
i_table_size = (USHORT)(i_table_size + bit_count); |
|
366 |
} |
||
367 |
|||
368 |
✗✓ | 2352 |
if (segment_len < i_table_size) |
369 |
{ |
||
370 |
return GX_INVALID_FORMAT; |
||
371 |
} |
||
372 |
|||
373 |
2352 |
segment_len -= i_table_size; |
|
374 |
|||
375 |
/* Load the start address of the specified huffman table. */ |
||
376 |
2352 |
jpeg_info -> gx_jpeg_huffman_table[table_class][table_id] = jpeg_data; |
|
377 |
2352 |
jpeg_data += i_table_size; |
|
378 |
} |
||
379 |
|||
380 |
1335 |
return GX_SUCCESS; |
|
381 |
} |
||
382 |
|||
383 |
/**************************************************************************/ |
||
384 |
/* */ |
||
385 |
/* FUNCTION RELEASE */ |
||
386 |
/* */ |
||
387 |
/* _gx_display_driver_jpeg_frame_header_read PORTABLE C */ |
||
388 |
/* 6.1 */ |
||
389 |
/* AUTHOR */ |
||
390 |
/* */ |
||
391 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
392 |
/* */ |
||
393 |
/* DESCRIPTION */ |
||
394 |
/* */ |
||
395 |
/* Reads in the frame header infomration. */ |
||
396 |
/* */ |
||
397 |
/* INPUT */ |
||
398 |
/* */ |
||
399 |
/* jpeg_info JPEG data control block */ |
||
400 |
/* segment_len Initial length of the segment */ |
||
401 |
/* */ |
||
402 |
/* OUTPUT */ |
||
403 |
/* */ |
||
404 |
/* None */ |
||
405 |
/* */ |
||
406 |
/* CALLS */ |
||
407 |
/* */ |
||
408 |
/* None */ |
||
409 |
/* */ |
||
410 |
/* CALLED BY */ |
||
411 |
/* */ |
||
412 |
/* _gx_image_reader_jpeg_decode_blocks */ |
||
413 |
/* */ |
||
414 |
/* RELEASE HISTORY */ |
||
415 |
/* */ |
||
416 |
/* DATE NAME DESCRIPTION */ |
||
417 |
/* */ |
||
418 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
419 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
420 |
/* resulting in version 6.1 */ |
||
421 |
/* */ |
||
422 |
/**************************************************************************/ |
||
423 |
590 |
static UINT _gx_image_reader_jpeg_frame_header_read(GX_JPEG_INFO *jpeg_info, UINT segment_len) |
|
424 |
{ |
||
425 |
590 |
GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index; |
|
426 |
INT i_component; |
||
427 |
|||
428 |
590 |
jpeg_info -> gx_jpeg_data_index += (INT)segment_len; |
|
429 |
590 |
jpeg_data += 2; |
|
430 |
|||
431 |
/* Skip precision field. */ |
||
432 |
590 |
jpeg_data++; |
|
433 |
|||
434 |
/* Read image width, WORD */ |
||
435 |
590 |
jpeg_info -> gx_jpeg_height = *jpeg_data++; |
|
436 |
590 |
jpeg_info -> gx_jpeg_height = (USHORT)(jpeg_info -> gx_jpeg_height << 8); |
|
437 |
590 |
jpeg_info -> gx_jpeg_height = (USHORT)(jpeg_info -> gx_jpeg_height | (*jpeg_data++)); |
|
438 |
|||
439 |
/* Limit max jpeg height to 14 bits. */ |
||
440 |
✓✓ | 590 |
if (jpeg_info -> gx_jpeg_height > GX_MAX_PIXELMAP_RESOLUTION) |
441 |
{ |
||
442 |
1 |
return GX_INVALID_HEIGHT; |
|
443 |
} |
||
444 |
|||
445 |
/* Read image height, WORD */ |
||
446 |
589 |
jpeg_info -> gx_jpeg_width = *jpeg_data++; |
|
447 |
589 |
jpeg_info -> gx_jpeg_width = (USHORT)(jpeg_info -> gx_jpeg_width << 8); |
|
448 |
589 |
jpeg_info -> gx_jpeg_width = (USHORT)(jpeg_info -> gx_jpeg_width | (*jpeg_data++)); |
|
449 |
|||
450 |
/* Limit max jpeg width to 14 bits. */ |
||
451 |
✓✓ | 589 |
if (jpeg_info -> gx_jpeg_width > GX_MAX_PIXELMAP_RESOLUTION) |
452 |
{ |
||
453 |
1 |
return GX_INVALID_WIDTH; |
|
454 |
} |
||
455 |
|||
456 |
/* Read image components. */ |
||
457 |
588 |
jpeg_info -> gx_jpeg_num_of_components = *jpeg_data++; |
|
458 |
|||
459 |
✗✓ | 588 |
if (jpeg_info -> gx_jpeg_num_of_components > JPG_MAX_COMPONENTS) |
460 |
{ |
||
461 |
return GX_FAILURE; |
||
462 |
} |
||
463 |
|||
464 |
✓✓ | 2350 |
for (i_component = 0; i_component < jpeg_info -> gx_jpeg_num_of_components; i_component++) |
465 |
{ |
||
466 |
/* Read component id */ |
||
467 |
1762 |
jpeg_info -> gx_jpeg_component_id[i_component] = *jpeg_data++; |
|
468 |
|||
469 |
/* Read sample factor */ |
||
470 |
1762 |
jpeg_info -> gx_jpeg_sample_factor[i_component] = *jpeg_data++; |
|
471 |
|||
472 |
/* Read quantization table index */ |
||
473 |
1762 |
jpeg_info -> gx_jpeg_qantization_table_index[i_component] = *jpeg_data++; |
|
474 |
} |
||
475 |
|||
476 |
588 |
return GX_SUCCESS; |
|
477 |
} |
||
478 |
|||
479 |
/**************************************************************************/ |
||
480 |
/* */ |
||
481 |
/* FUNCTION RELEASE */ |
||
482 |
/* */ |
||
483 |
/* _gx_image_reader_jpeg_scan_header_read PORTABLE C */ |
||
484 |
/* 6.1 */ |
||
485 |
/* AUTHOR */ |
||
486 |
/* */ |
||
487 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
488 |
/* */ |
||
489 |
/* DESCRIPTION */ |
||
490 |
/* */ |
||
491 |
/* Reads in the scan header information. */ |
||
492 |
/* */ |
||
493 |
/* INPUT */ |
||
494 |
/* */ |
||
495 |
/* jpeg_info JPEG data control block */ |
||
496 |
/* segment_len Initial length of the segment */ |
||
497 |
/* */ |
||
498 |
/* OUTPUT */ |
||
499 |
/* */ |
||
500 |
/* None */ |
||
501 |
/* */ |
||
502 |
/* CALLS */ |
||
503 |
/* */ |
||
504 |
/* None */ |
||
505 |
/* */ |
||
506 |
/* CALLED BY */ |
||
507 |
/* */ |
||
508 |
/* _gx_image_reader_jpeg_decode_blocks */ |
||
509 |
/* */ |
||
510 |
/* RELEASE HISTORY */ |
||
511 |
/* */ |
||
512 |
/* DATE NAME DESCRIPTION */ |
||
513 |
/* */ |
||
514 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
515 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
516 |
/* resulting in version 6.1 */ |
||
517 |
/* */ |
||
518 |
/**************************************************************************/ |
||
519 |
588 |
static UINT _gx_image_reader_jpeg_scan_header_read(GX_JPEG_INFO *jpeg_info, UINT segment_len) |
|
520 |
{ |
||
521 |
588 |
GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index; |
|
522 |
INT index; |
||
523 |
|||
524 |
588 |
jpeg_data += 2; |
|
525 |
588 |
jpeg_info -> gx_jpeg_data_index += (INT)segment_len; |
|
526 |
|||
527 |
/* Read the number of image components. */ |
||
528 |
588 |
jpeg_info -> gx_jpeg_num_of_components = *jpeg_data++; |
|
529 |
|||
530 |
✗✓ | 588 |
if (jpeg_info -> gx_jpeg_num_of_components > JPG_MAX_COMPONENTS) |
531 |
{ |
||
532 |
return GX_FAILURE; |
||
533 |
} |
||
534 |
|||
535 |
✓✓ | 2350 |
for (index = 0; index < jpeg_info -> gx_jpeg_num_of_components; index++) |
536 |
{ |
||
537 |
/* skip image component */ |
||
538 |
1762 |
jpeg_data++; |
|
539 |
|||
540 |
/* high bits correspond to DC table index. |
||
541 |
low bits correspond to AC table index |
||
542 |
0: Y Huffman table |
||
543 |
1: Chrominance Huffman table. */ |
||
544 |
1762 |
jpeg_info -> gx_jpeg_dc_table_index[index] = ((*jpeg_data) & 0xf0) >> 4; |
|
545 |
1762 |
jpeg_info -> gx_jpeg_ac_table_index[index] = (*jpeg_data++) & 0x0f; |
|
546 |
} |
||
547 |
|||
548 |
588 |
return GX_SUCCESS; |
|
549 |
} |
||
550 |
|||
551 |
/**************************************************************************/ |
||
552 |
/* */ |
||
553 |
/* FUNCTION RELEASE */ |
||
554 |
/* */ |
||
555 |
/* _gx_image_reader_jpeg_dc_decode PORTABLE C */ |
||
556 |
/* 6.3.0 */ |
||
557 |
/* AUTHOR */ |
||
558 |
/* */ |
||
559 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
560 |
/* */ |
||
561 |
/* DESCRIPTION */ |
||
562 |
/* */ |
||
563 |
/* Decode the DC component. */ |
||
564 |
/* */ |
||
565 |
/* INPUT */ |
||
566 |
/* */ |
||
567 |
/* jpeg_info JPEG data control block */ |
||
568 |
/* i_component Component index */ |
||
569 |
/* */ |
||
570 |
/* OUTPUT */ |
||
571 |
/* */ |
||
572 |
/* Status */ |
||
573 |
/* */ |
||
574 |
/* CALLS */ |
||
575 |
/* */ |
||
576 |
/* GX_JPEG_BITS_GET Extract a specified number of*/ |
||
577 |
/* bits from JPEG data stream */ |
||
578 |
/* GX_JPEG_BITS_SKIP Skips bits from tempory JPEG */ |
||
579 |
/* data stream */ |
||
580 |
/* _gx_image_reader_jpeg_huffman_code_find */ |
||
581 |
/* Lookup the huffman code */ |
||
582 |
/* */ |
||
583 |
/* CALLED BY */ |
||
584 |
/* */ |
||
585 |
/* _gx_image_reader_jpeg_one_block_decode */ |
||
586 |
/* */ |
||
587 |
/* RELEASE HISTORY */ |
||
588 |
/* */ |
||
589 |
/* DATE NAME DESCRIPTION */ |
||
590 |
/* */ |
||
591 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
592 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
593 |
/* resulting in version 6.1 */ |
||
594 |
/* 10-31-2022 Kenneth Maxwell Modified comment(s), */ |
||
595 |
/* added range test, */ |
||
596 |
/* resulting in version 6.2.0 */ |
||
597 |
/* 10-31-2023 Ting Zhu Modified comment(s), */ |
||
598 |
/* improved logic, */ |
||
599 |
/* resulting in version 6.3.0 */ |
||
600 |
/* */ |
||
601 |
/**************************************************************************/ |
||
602 |
1379818 |
static UINT _gx_image_reader_jpeg_dc_decode(GX_JPEG_INFO *jpeg_info, UINT i_component) |
|
603 |
{ |
||
604 |
1379818 |
UINT i_bits = 0; |
|
605 |
GX_UBYTE code_value; |
||
606 |
INT diff; |
||
607 |
1379818 |
UINT table_index = jpeg_info -> gx_jpeg_dc_table_index[i_component]; |
|
608 |
GX_BOOL negative; |
||
609 |
|||
610 |
✗✓ | 1379818 |
if (table_index >= HUFF_TABLE_DIMENSION) |
611 |
{ |
||
612 |
return GX_FAILURE; |
||
613 |
} |
||
614 |
|||
615 |
✓✓✓✗ ✓✓✓✓ ✓✓✓✓ |
2050747 |
GX_JPEG_BITS_GET(jpeg_info, 16); |
616 |
|||
617 |
✓✓ | 1379818 |
if (_gx_image_reader_jpeg_huffcode_find(jpeg_info, 0, table_index, &i_bits, &code_value) == 0) |
618 |
{ |
||
619 |
1379607 |
GX_JPEG_BITS_SKIP(jpeg_info, i_bits); |
|
620 |
|||
621 |
✓✓ | 1379607 |
if (code_value == 0) |
622 |
{ |
||
623 |
85828 |
jpeg_info -> gx_jpeg_vecter[0] = jpeg_info -> gx_jpeg_pre_dc[i_component]; |
|
624 |
} |
||
625 |
else |
||
626 |
{ |
||
627 |
|||
628 |
✓✗✓✓ ✓✓✓✗ ✓✗✓✓ |
1295084 |
GX_JPEG_BITS_GET(jpeg_info, code_value); |
629 |
1293779 |
diff = (INT)(((UINT)jpeg_info -> gx_jpeg_bit_buffer) >> (32 - code_value)); |
|
630 |
1293779 |
GX_JPEG_BITS_SKIP(jpeg_info, code_value); |
|
631 |
|||
632 |
1293779 |
negative = !(diff >> (code_value - 1)); |
|
633 |
|||
634 |
✓✓ | 1293779 |
if (negative) |
635 |
{ |
||
636 |
663058 |
diff += 1 - (1 << code_value); |
|
637 |
} |
||
638 |
|||
639 |
1293779 |
jpeg_info -> gx_jpeg_vecter[0] = diff + jpeg_info -> gx_jpeg_pre_dc[i_component]; |
|
640 |
1293779 |
jpeg_info -> gx_jpeg_pre_dc[i_component] = jpeg_info -> gx_jpeg_vecter[0]; |
|
641 |
} |
||
642 |
} |
||
643 |
else |
||
644 |
{ |
||
645 |
211 |
return GX_FAILURE; |
|
646 |
} |
||
647 |
|||
648 |
1379607 |
return GX_SUCCESS; |
|
649 |
} |
||
650 |
|||
651 |
/**************************************************************************/ |
||
652 |
/* */ |
||
653 |
/* FUNCTION RELEASE */ |
||
654 |
/* */ |
||
655 |
/* _gx_image_reader_jpeg_ac_decode PORTABLE C */ |
||
656 |
/* 6.3.0 */ |
||
657 |
/* AUTHOR */ |
||
658 |
/* */ |
||
659 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
660 |
/* */ |
||
661 |
/* DESCRIPTION */ |
||
662 |
/* */ |
||
663 |
/* Decode the AC component. */ |
||
664 |
/* */ |
||
665 |
/* INPUT */ |
||
666 |
/* */ |
||
667 |
/* jpeg_info JPEG data control block */ |
||
668 |
/* i_component Component index */ |
||
669 |
/* */ |
||
670 |
/* OUTPUT */ |
||
671 |
/* */ |
||
672 |
/* Status Code */ |
||
673 |
/* */ |
||
674 |
/* CALLS */ |
||
675 |
/* */ |
||
676 |
/* GX_JPEG_BITS_GET Extract a specified number of*/ |
||
677 |
/* bits from JPEG data stream */ |
||
678 |
/* GX_JPEG_BITS_SKIP Skips bits from tempory JPEG */ |
||
679 |
/* data stream */ |
||
680 |
/* _gx_image_reader_jpeg_huffman_code_find */ |
||
681 |
/* Lookup the huffman code */ |
||
682 |
/* */ |
||
683 |
/* CALLED BY */ |
||
684 |
/* */ |
||
685 |
/* _gx_image_reader_jpeg_one_block_decode */ |
||
686 |
/* */ |
||
687 |
/* RELEASE HISTORY */ |
||
688 |
/* */ |
||
689 |
/* DATE NAME DESCRIPTION */ |
||
690 |
/* */ |
||
691 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
692 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
693 |
/* resulting in version 6.1 */ |
||
694 |
/* 10-31-2022 Kenneth Maxwell Modified comment(s), */ |
||
695 |
/* added range test, */ |
||
696 |
/* resulting in version 6.2.0 */ |
||
697 |
/* 10-31-2023 Ting Zhu Modified comment(s), */ |
||
698 |
/* improved logic, */ |
||
699 |
/* resulting in version 6.3.0 */ |
||
700 |
/* */ |
||
701 |
/**************************************************************************/ |
||
702 |
1379818 |
static UINT _gx_image_reader_jpeg_ac_decode(GX_JPEG_INFO *jpeg_info, UINT i_component) |
|
703 |
{ |
||
704 |
1379818 |
UINT i_bits = 0; |
|
705 |
GX_UBYTE code_value; |
||
706 |
GX_UBYTE catogory; |
||
707 |
GX_UBYTE runs_of_zero; |
||
708 |
INT ac_coefficient; |
||
709 |
1379818 |
UINT ac_counter = 1; |
|
710 |
1379818 |
UINT table_index = jpeg_info -> gx_jpeg_ac_table_index[i_component]; |
|
711 |
INT negative; |
||
712 |
|||
713 |
✗✓ | 1379818 |
if (table_index >= HUFF_TABLE_DIMENSION) |
714 |
{ |
||
715 |
return GX_FAILURE; |
||
716 |
} |
||
717 |
|||
718 |
✓✓ | 28037652 |
while (ac_counter < 64) |
719 |
{ |
||
720 |
26657946 |
i_bits = 0; |
|
721 |
✓✓✓✗ ✓✓✓✗ ✓✓✓✓ |
46850731 |
GX_JPEG_BITS_GET(jpeg_info, 16); |
722 |
|||
723 |
✓✓ | 26657946 |
if (_gx_image_reader_jpeg_huffcode_find(jpeg_info, 1, table_index, &i_bits, &code_value) == 0) |
724 |
{ |
||
725 |
26657834 |
GX_JPEG_BITS_SKIP(jpeg_info, i_bits); |
|
726 |
|||
727 |
26657834 |
runs_of_zero = (0xf0 & code_value) >> 4; |
|
728 |
26657834 |
catogory = 0x0f & code_value; |
|
729 |
|||
730 |
✓✓ | 26657834 |
if (catogory == 0) |
731 |
{ |
||
732 |
/* EOB encountered. */ |
||
733 |
✓✓ | 1379459 |
if (runs_of_zero == 0) |
734 |
{ |
||
735 |
1375290 |
ac_counter = 64; |
|
736 |
} |
||
737 |
✓✓ | 4169 |
else if (runs_of_zero == 0x0f) |
738 |
{ |
||
739 |
4134 |
ac_counter += 16; |
|
740 |
} |
||
741 |
} |
||
742 |
else |
||
743 |
{ |
||
744 |
25278375 |
ac_counter += runs_of_zero; |
|
745 |
|||
746 |
✓✗✓✗ ✓✓✓✗ ✓✗✓✓ |
25345914 |
GX_JPEG_BITS_GET(jpeg_info, catogory); |
747 |
25278375 |
ac_coefficient = (INT)((jpeg_info -> gx_jpeg_bit_buffer) >> (32 - catogory)); |
|
748 |
25278375 |
GX_JPEG_BITS_SKIP(jpeg_info, catogory); |
|
749 |
|||
750 |
25278375 |
negative = !(ac_coefficient >> (catogory - 1)); |
|
751 |
|||
752 |
✓✓ | 25278375 |
if (negative) |
753 |
{ |
||
754 |
12532773 |
ac_coefficient += 1 - (1 << catogory); |
|
755 |
} |
||
756 |
|||
757 |
✓✓ | 25278375 |
if (ac_counter < 64) |
758 |
{ |
||
759 |
25278271 |
jpeg_info -> gx_jpeg_vecter[ac_counter++] = ac_coefficient; |
|
760 |
} |
||
761 |
} |
||
762 |
} |
||
763 |
else |
||
764 |
{ |
||
765 |
112 |
return GX_FAILURE; |
|
766 |
} |
||
767 |
} |
||
768 |
|||
769 |
1379706 |
return GX_SUCCESS; |
|
770 |
} |
||
771 |
|||
772 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
773 |
/* Define the triple Bufferfly Addition operation */ |
||
774 |
#define VBUTTERFLY_ADDITION(a, b) \ |
||
775 |
vtemp = vaddq_s32(a, b); \ |
||
776 |
b = vsubq_s32(a, b); \ |
||
777 |
a = vtemp |
||
778 |
|||
779 |
/* Define the butterfly Multiplication */ |
||
780 |
#define VBUTTERFLY_MULTIPLICATION(a, b, cos, sin) \ |
||
781 |
vtempa = vmulq_n_s32(a, cos); \ |
||
782 |
vtempb = vmulq_n_s32(b, sin); \ |
||
783 |
vtemp = vaddq_s32(vtempa, vtempb); \ |
||
784 |
vtempa = vmulq_n_s32(a, sin); \ |
||
785 |
vtempb = vmulq_n_s32(b, cos); \ |
||
786 |
b = vsubq_s32(vtempb, vtempa); \ |
||
787 |
a = vtemp |
||
788 |
|||
789 |
#define VBUTTERFLY_MULTIPLICATION_SHR6(a, b, cos, sin) \ |
||
790 |
vtempa = vmulq_n_s32(a, cos); \ |
||
791 |
vtempb = vmulq_n_s32(b, sin); \ |
||
792 |
vtemp = vaddq_s32(vtempa, vtempb); \ |
||
793 |
vtempa = vmulq_n_s32(a, sin); \ |
||
794 |
vtempb = vmulq_n_s32(b, cos); \ |
||
795 |
b = vsubq_s32(vtempb, vtempa); \ |
||
796 |
b = vshrq_n_s32(b, 6); \ |
||
797 |
a = vshrq_n_s32(vtemp, 6) |
||
798 |
#else |
||
799 |
|||
800 |
/* Define the triple Bufferfly Addition operation */ |
||
801 |
#define BUTTERFLY_ADDITION(a, b) \ |
||
802 |
t = a + b; \ |
||
803 |
b = a - b; \ |
||
804 |
a = t |
||
805 |
|||
806 |
/* Define the butterfly Multiplication */ |
||
807 |
#define BUTTERFLY_MULTIPLICATION(a, b, cos, sin) \ |
||
808 |
t = (a * cos + b * sin); \ |
||
809 |
b = (b * cos - a * sin); \ |
||
810 |
a = t |
||
811 |
|||
812 |
#define BUTTERFLY_MULTIPLICATION_SHR6(a, b, cos, sin) \ |
||
813 |
t = (a * cos + b * sin) >> 6; \ |
||
814 |
b = (b * cos - a * sin) >> 6; \ |
||
815 |
a = t |
||
816 |
|||
817 |
#endif |
||
818 |
|||
819 |
/* Define constants. */ |
||
820 |
#define R2_SHR7 181 /* = sqrt(2) << 7. */ |
||
821 |
#define C1_SHR8 251 /* = cos(pi/16) << 8. */ |
||
822 |
#define S1_SHR8 50 /* = sin(pi/16) << 8. */ |
||
823 |
#define C3_SHR8 213 /* = cos(3pi/16)*sqrt(2) << 8. */ |
||
824 |
#define S3_SHR8 142 /* = sin(3pi/16)*sqrt(2) << 8. */ |
||
825 |
#define C6R2_SHR9 277 /* = cos(pi/16)*sqrt(2) << 9. */ |
||
826 |
#define S6R2_SHR9 669 /* = sin(3pi/16)*sqrt(2) << 9. */ |
||
827 |
#define POSTSH1 9 |
||
828 |
#define POSTSH2 12 |
||
829 |
|||
830 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
831 |
/**************************************************************************/ |
||
832 |
/* */ |
||
833 |
/* FUNCTION RELEASE */ |
||
834 |
/* */ |
||
835 |
/* _gx_image_reader_jpeg_dequantize_idct PORTABLE C */ |
||
836 |
/* 6.3.0 */ |
||
837 |
/* AUTHOR */ |
||
838 |
/* */ |
||
839 |
/* Ting Zhu, Microsoft Corporation */ |
||
840 |
/* */ |
||
841 |
/* DESCRIPTION */ |
||
842 |
/* */ |
||
843 |
/* Dequatilizes decoded data and performs Inverse Discrete Consine */ |
||
844 |
/* Transformation using helium intrinsics. */ |
||
845 |
/* */ |
||
846 |
/* INPUT */ |
||
847 |
/* */ |
||
848 |
/* block Pointer to decoded data */ |
||
849 |
/* quant_table Pointer to quantization table */ |
||
850 |
/* out Buffer for output data */ |
||
851 |
/* stride Stride of output data */ |
||
852 |
/* */ |
||
853 |
/* OUTPUT */ |
||
854 |
/* */ |
||
855 |
/* None */ |
||
856 |
/* */ |
||
857 |
/* CALLS */ |
||
858 |
/* */ |
||
859 |
/* vldrwq_gather_shifted_offset_s32 Gather data from memory */ |
||
860 |
/* vmulq_s32 Multiply two vectors */ |
||
861 |
/* vmulq_n_s32 Multiply by scaler */ |
||
862 |
/* vqrshlq_n_s32 Shift each element of a */ |
||
863 |
/* vector register left by */ |
||
864 |
/* the immediate value */ |
||
865 |
/* vaddq_s32 Add two vectors */ |
||
866 |
/* vrshrq_n_s32 Shift each element of a */ |
||
867 |
/* vector register right by */ |
||
868 |
/* the immediate value */ |
||
869 |
/* vstrhq_scatter_offset_s32 Scatter store data to memory */ |
||
870 |
/* vldrhq_s32 Load vector register */ |
||
871 |
/* vqrshrnbq_n_s32 Shift right with saturation, */ |
||
872 |
/* and write the result to the */ |
||
873 |
/* bottom half of the result */ |
||
874 |
/* element */ |
||
875 |
/* vqmovntq_s16 Saturate to half width and */ |
||
876 |
/* write the result to the */ |
||
877 |
/* top of the result element */ |
||
878 |
/* vstrbq_scatter_offset_s8 Scatter store data to memory */ |
||
879 |
/* VBUTTERFLY_ADDITION Perform butterfly addition */ |
||
880 |
/* VBUTTERFLY_MULTIPLICATION Perform butterfly */ |
||
881 |
/* multiplication */ |
||
882 |
/* VBUTTERFLY_MULTIPLICATION_SHR6 Perform butterfly */ |
||
883 |
/* multiplication with shift */ |
||
884 |
/* */ |
||
885 |
/* CALLED BY */ |
||
886 |
/* */ |
||
887 |
/* _gx_image_reader_jpeg_one_block_decode */ |
||
888 |
/* */ |
||
889 |
/* RELEASE HISTORY */ |
||
890 |
/* */ |
||
891 |
/* DATE NAME DESCRIPTION */ |
||
892 |
/* */ |
||
893 |
/* 10-31-2023 Ting Zhu Initial Version 6.3.0 */ |
||
894 |
/* */ |
||
895 |
/**************************************************************************/ |
||
896 |
static VOID _gx_image_reader_jpeg_dequantize_idct(INT *block, INT *quant_table, GX_BYTE *out, INT stride) |
||
897 |
{ |
||
898 |
static uint32x4_t voffset[8][2] = { |
||
899 |
{{0, 2, 3, 9}, {10, 20, 21, 35}}, |
||
900 |
{{1, 4, 8, 11}, {19, 22, 34, 36}}, |
||
901 |
{{5, 7, 12, 18}, {23, 33, 37, 48}}, |
||
902 |
{{6, 13, 17, 24}, {32, 38, 47, 49}}, |
||
903 |
{{14, 16, 25, 31}, {39, 46, 50, 57}}, |
||
904 |
{{15, 26, 30, 40}, {45, 51, 56, 58}}, |
||
905 |
{{27, 29, 41, 44}, {52, 55, 59, 62}}, |
||
906 |
{{28, 42, 43, 53}, {54, 60, 61, 63}} |
||
907 |
}; |
||
908 |
static uint32x4_t vstroffset1= {0, 16, 32, 48}; |
||
909 |
INT index; |
||
910 |
GX_VALUE temp_block[64]; |
||
911 |
GX_VALUE *output_data; |
||
912 |
int32x4_t vrow0, vrow1, vrow2, vrow3, vrow4, vrow5, vrow6, vrow7, vtemp, vtempa, vtempb; |
||
913 |
uint8x16_t vstroffset = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3}; |
||
914 |
int16x8_t vtemp16; |
||
915 |
int8x16_t vtemp8; |
||
916 |
int16_t const *base; |
||
917 |
|||
918 |
/* Perform 2-D DCT by applying first a 1-D DCT over the rows |
||
919 |
followed by a 1-D DCT over the columns of the input-data matrix.*/ |
||
920 |
for (index = 0; index < 4; index++) |
||
921 |
{ |
||
922 |
vstroffset[0 + index * 4] += (stride * 3); |
||
923 |
vstroffset[1 + index * 4] += stride; |
||
924 |
vstroffset[2 + index * 4] += (stride << 1); |
||
925 |
} |
||
926 |
|||
927 |
|||
928 |
for (index = 0; index < 2; index++) |
||
929 |
{ |
||
930 |
output_data = temp_block + 32 * index; |
||
931 |
|||
932 |
/* Load data. */ |
||
933 |
vrow0 = vldrwq_gather_shifted_offset_s32(block, voffset[0][index]); |
||
934 |
vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[0][index]); |
||
935 |
vrow0 = vmulq_s32(vrow0, vtemp); |
||
936 |
|||
937 |
vrow1 = vldrwq_gather_shifted_offset_s32(block, voffset[1][index]); |
||
938 |
vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[1][index]); |
||
939 |
vrow1 = vmulq_s32(vrow1, vtemp); |
||
940 |
|||
941 |
vrow2 = vldrwq_gather_shifted_offset_s32(block, voffset[2][index]); |
||
942 |
vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[2][index]); |
||
943 |
vrow2 = vmulq_s32(vrow2, vtemp); |
||
944 |
|||
945 |
vrow3 = vldrwq_gather_shifted_offset_s32(block, voffset[3][index]); |
||
946 |
vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[3][index]); |
||
947 |
vrow3 = vmulq_s32(vrow3, vtemp); |
||
948 |
|||
949 |
vrow4 = vldrwq_gather_shifted_offset_s32(block, voffset[4][index]); |
||
950 |
vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[4][index]); |
||
951 |
vrow4 = vmulq_s32(vrow4, vtemp); |
||
952 |
|||
953 |
vrow5 = vldrwq_gather_shifted_offset_s32(block, voffset[5][index]); |
||
954 |
vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[5][index]); |
||
955 |
vrow5 = vmulq_s32(vrow5, vtemp); |
||
956 |
|||
957 |
vrow6 = vldrwq_gather_shifted_offset_s32(block, voffset[6][index]); |
||
958 |
vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[6][index]); |
||
959 |
vrow6 = vmulq_s32(vrow6, vtemp); |
||
960 |
|||
961 |
vrow7 = vldrwq_gather_shifted_offset_s32(block, voffset[7][index]); |
||
962 |
vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[7][index]); |
||
963 |
vrow7 = vmulq_s32(vrow7, vtemp); |
||
964 |
|||
965 |
/* Prescale. */ |
||
966 |
vrow0 = vqrshlq_n_s32(vrow0, 9); |
||
967 |
vrow1 = vqrshlq_n_s32(vrow1, 7); |
||
968 |
vrow4 = vqrshlq_n_s32(vrow4, 9); |
||
969 |
vrow7 = vqrshlq_n_s32(vrow7, 7); |
||
970 |
|||
971 |
/* stage 1. */ |
||
972 |
VBUTTERFLY_ADDITION(vrow1, vrow7); |
||
973 |
|||
974 |
vrow3 = vmulq_n_s32(vrow3, R2_SHR7); |
||
975 |
vrow5 = vmulq_n_s32(vrow5, R2_SHR7); |
||
976 |
|||
977 |
/* stage 2. */ |
||
978 |
VBUTTERFLY_ADDITION(vrow0, vrow4); |
||
979 |
VBUTTERFLY_MULTIPLICATION(vrow6, vrow2, C6R2_SHR9, S6R2_SHR9); |
||
980 |
VBUTTERFLY_ADDITION(vrow7, vrow5); |
||
981 |
VBUTTERFLY_ADDITION(vrow1, vrow3); |
||
982 |
|||
983 |
/* stage 3. */ |
||
984 |
VBUTTERFLY_ADDITION(vrow0, vrow6); |
||
985 |
VBUTTERFLY_ADDITION(vrow4, vrow2); |
||
986 |
VBUTTERFLY_MULTIPLICATION_SHR6(vrow5, vrow3, C1_SHR8, S1_SHR8); |
||
987 |
VBUTTERFLY_MULTIPLICATION_SHR6(vrow1, vrow7, C3_SHR8, S3_SHR8); |
||
988 |
|||
989 |
/* stage 4. */ |
||
990 |
vtemp = vaddq_s32(vrow0, vrow1); |
||
991 |
vtemp = vrshrq_n_s32(vtemp, POSTSH1); |
||
992 |
vstrhq_scatter_offset_s32(output_data, vstroffset1, vtemp); |
||
993 |
|||
994 |
vtemp = vaddq_s32(vrow4, vrow5); |
||
995 |
vtemp = vrshrq_n_s32(vtemp, POSTSH1); |
||
996 |
vstrhq_scatter_offset_s32(output_data + 1, vstroffset1, vtemp); |
||
997 |
|||
998 |
vtemp = vaddq_s32(vrow2, vrow3); |
||
999 |
vtemp = vrshrq_n_s32(vtemp, POSTSH1); |
||
1000 |
vstrhq_scatter_offset_s32(output_data + 2, vstroffset1, vtemp); |
||
1001 |
|||
1002 |
vtemp = vaddq_s32(vrow6, vrow7); |
||
1003 |
vtemp = vrshrq_n_s32(vtemp, POSTSH1); |
||
1004 |
vstrhq_scatter_offset_s32(output_data + 3, vstroffset1, vtemp); |
||
1005 |
|||
1006 |
vtemp = vsubq_s32(vrow6, vrow7); |
||
1007 |
vtemp = vrshrq_n_s32(vtemp, POSTSH1); |
||
1008 |
vstrhq_scatter_offset_s32(output_data + 4, vstroffset1, vtemp); |
||
1009 |
|||
1010 |
vtemp = vsubq_s32(vrow2, vrow3); |
||
1011 |
vtemp = vrshrq_n_s32(vtemp, POSTSH1); |
||
1012 |
vstrhq_scatter_offset_s32(output_data + 5, vstroffset1, vtemp); |
||
1013 |
|||
1014 |
vtemp = vsubq_s32(vrow4, vrow5); |
||
1015 |
vtemp = vrshrq_n_s32(vtemp, POSTSH1); |
||
1016 |
vstrhq_scatter_offset_s32(output_data + 6, vstroffset1, vtemp); |
||
1017 |
|||
1018 |
vtemp = vsubq_s32(vrow0, vrow1); |
||
1019 |
vtemp = vrshrq_n_s32(vtemp, POSTSH1); |
||
1020 |
vstrhq_scatter_offset_s32(output_data + 7, vstroffset1, vtemp); |
||
1021 |
} |
||
1022 |
|||
1023 |
for (index = 0; index < 2; index++) |
||
1024 |
{ |
||
1025 |
base = (int16_t const *)(temp_block + 4 * index); |
||
1026 |
|||
1027 |
/* Load data. */ |
||
1028 |
vrow0 = vldrhq_s32(base); |
||
1029 |
vrow1 = vldrhq_s32(base + 8); |
||
1030 |
vrow2 = vldrhq_s32(base + 16); |
||
1031 |
vrow3 = vldrhq_s32(base + 24); |
||
1032 |
vrow4 = vldrhq_s32(base + 32); |
||
1033 |
vrow5 = vldrhq_s32(base + 40); |
||
1034 |
vrow6 = vldrhq_s32(base + 48); |
||
1035 |
vrow7 = vldrhq_s32(base + 56); |
||
1036 |
|||
1037 |
/* Prescale. */ |
||
1038 |
vrow0 = vqrshlq_n_s32(vrow0, 9); |
||
1039 |
vrow1 = vqrshlq_n_s32(vrow1, 7); |
||
1040 |
vrow4 = vqrshlq_n_s32(vrow4, 9); |
||
1041 |
vrow7 = vqrshlq_n_s32(vrow7, 7); |
||
1042 |
|||
1043 |
/* stage 1. */ |
||
1044 |
VBUTTERFLY_ADDITION(vrow1, vrow7); |
||
1045 |
|||
1046 |
vrow3 = vmulq_n_s32(vrow3, R2_SHR7); |
||
1047 |
vrow5 = vmulq_n_s32(vrow5, R2_SHR7); |
||
1048 |
|||
1049 |
/* stage 2. */ |
||
1050 |
VBUTTERFLY_ADDITION(vrow0, vrow4); |
||
1051 |
VBUTTERFLY_MULTIPLICATION(vrow6, vrow2, C6R2_SHR9, S6R2_SHR9); |
||
1052 |
VBUTTERFLY_ADDITION(vrow7, vrow5); |
||
1053 |
VBUTTERFLY_ADDITION(vrow1, vrow3); |
||
1054 |
|||
1055 |
/* stage 3. */ |
||
1056 |
VBUTTERFLY_ADDITION(vrow0, vrow6); |
||
1057 |
VBUTTERFLY_ADDITION(vrow4, vrow2); |
||
1058 |
VBUTTERFLY_MULTIPLICATION_SHR6(vrow5, vrow3, C1_SHR8, S1_SHR8); |
||
1059 |
VBUTTERFLY_MULTIPLICATION_SHR6(vrow1, vrow7, C3_SHR8, S3_SHR8); |
||
1060 |
|||
1061 |
/* stage 4. */ |
||
1062 |
|||
1063 |
vtemp = vaddq_s32(vrow0, vrow1); |
||
1064 |
vtemp16 = vqrshrntq_n_s32(vtemp16, vtemp, POSTSH2); |
||
1065 |
|||
1066 |
vtemp = vaddq_s32(vrow4, vrow5); |
||
1067 |
vtemp16 = vqrshrnbq_n_s32(vtemp16, vtemp, POSTSH2); |
||
1068 |
vtemp8 = vqmovntq_s16(vtemp8, vtemp16); |
||
1069 |
|||
1070 |
vtemp = vaddq_s32(vrow2, vrow3); |
||
1071 |
vtemp16 = vqrshrntq_n_s32(vtemp16, vtemp, POSTSH2); |
||
1072 |
|||
1073 |
vtemp = vaddq_s32(vrow6, vrow7); |
||
1074 |
vtemp16 = vqrshrnbq_n_s32(vtemp16, vtemp, POSTSH2); |
||
1075 |
vtemp8 = vqmovnbq_s16(vtemp8, vtemp16); |
||
1076 |
vstrbq_scatter_offset_s8(out + 4 * index, vstroffset, vtemp8); |
||
1077 |
|||
1078 |
vtemp = vsubq_s32(vrow6, vrow7); |
||
1079 |
vtemp16 = vqrshrntq_n_s32(vtemp16, vtemp, POSTSH2); |
||
1080 |
|||
1081 |
vtemp = vsubq_s32(vrow2, vrow3); |
||
1082 |
vtemp16 = vqrshrnbq_n_s32(vtemp16, vtemp, POSTSH2); |
||
1083 |
vtemp8 = vqmovntq_s16(vtemp8, vtemp16); |
||
1084 |
|||
1085 |
vtemp = vsubq_s32(vrow4, vrow5); |
||
1086 |
vtemp16 = vqrshrntq_n_s32(vtemp16, vtemp, POSTSH2); |
||
1087 |
|||
1088 |
vtemp = vsubq_s32(vrow0, vrow1); |
||
1089 |
vtemp16 = vqrshrnbq_n_s32(vtemp16, vtemp, POSTSH2); |
||
1090 |
vtemp8 = vqmovnbq_s16(vtemp8, vtemp16); |
||
1091 |
vstrbq_scatter_offset_s8(out + (stride << 2) + 4 * index, vstroffset, vtemp8); |
||
1092 |
} |
||
1093 |
} |
||
1094 |
#else |
||
1095 |
|||
1096 |
/**************************************************************************/ |
||
1097 |
/* */ |
||
1098 |
/* FUNCTION RELEASE */ |
||
1099 |
/* */ |
||
1100 |
/* _gx_image_reader_jpeg_1d_idct PORTABLE C */ |
||
1101 |
/* 6.3.0 */ |
||
1102 |
/* AUTHOR */ |
||
1103 |
/* */ |
||
1104 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
1105 |
/* */ |
||
1106 |
/* DESCRIPTION */ |
||
1107 |
/* */ |
||
1108 |
/* Performs 1D Inverse Discrete Consine Transformation. It is an */ |
||
1109 |
/* implementation of LLM (Loeffler, Lighenberg, Moschytz) algorithm. */ |
||
1110 |
/* */ |
||
1111 |
/* INPUT */ |
||
1112 |
/* */ |
||
1113 |
/* input_data Input data */ |
||
1114 |
/* output_data Buffer for output data */ |
||
1115 |
/* post_scale Post scale value */ |
||
1116 |
/* round Value to reduce round error */ |
||
1117 |
/* */ |
||
1118 |
/* OUTPUT */ |
||
1119 |
/* */ |
||
1120 |
/* None */ |
||
1121 |
/* */ |
||
1122 |
/* CALLS */ |
||
1123 |
/* */ |
||
1124 |
/* None */ |
||
1125 |
/* */ |
||
1126 |
/* CALLED BY */ |
||
1127 |
/* */ |
||
1128 |
/* _gx_image_reader_jpeg_2d_idct */ |
||
1129 |
/* */ |
||
1130 |
/* RELEASE HISTORY */ |
||
1131 |
/* */ |
||
1132 |
/* DATE NAME DESCRIPTION */ |
||
1133 |
/* */ |
||
1134 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
1135 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
1136 |
/* resulting in version 6.1 */ |
||
1137 |
/* 10-31-2023 Ting Zhu Modified comment(s), */ |
||
1138 |
/* improved logic, */ |
||
1139 |
/* resulting in version 6.3.0 */ |
||
1140 |
/* */ |
||
1141 |
/**************************************************************************/ |
||
1142 |
22077088 |
static VOID _gx_image_reader_jpeg_1d_idct(INT *input_data, INT *output_data, INT post_scale, INT round) |
|
1143 |
{ |
||
1144 |
INT t; |
||
1145 |
|||
1146 |
22077088 |
input_data[0] <<= 9; |
|
1147 |
22077088 |
input_data[1] <<= 7; |
|
1148 |
22077088 |
input_data[4] <<= 9; |
|
1149 |
22077088 |
input_data[7] <<= 7; |
|
1150 |
|||
1151 |
/* iDCT computation .*/ |
||
1152 |
|||
1153 |
/* stage 1. */ |
||
1154 |
22077088 |
BUTTERFLY_ADDITION(input_data[1], input_data[7]); |
|
1155 |
|||
1156 |
22077088 |
input_data[3] *= R2_SHR7; |
|
1157 |
22077088 |
input_data[5] *= R2_SHR7; |
|
1158 |
|||
1159 |
/* stage 2. */ |
||
1160 |
22077088 |
BUTTERFLY_ADDITION(input_data[0], input_data[4]); |
|
1161 |
22077088 |
BUTTERFLY_MULTIPLICATION(input_data[6], input_data[2], C6R2_SHR9, S6R2_SHR9); |
|
1162 |
22077088 |
BUTTERFLY_ADDITION(input_data[7], input_data[5]); |
|
1163 |
22077088 |
BUTTERFLY_ADDITION(input_data[1], input_data[3]); |
|
1164 |
|||
1165 |
/* staget 3. */ |
||
1166 |
22077088 |
BUTTERFLY_ADDITION(input_data[0], input_data[6]); |
|
1167 |
22077088 |
BUTTERFLY_ADDITION(input_data[4], input_data[2]); |
|
1168 |
22077088 |
BUTTERFLY_MULTIPLICATION_SHR6(input_data[5], input_data[3], C1_SHR8, S1_SHR8); |
|
1169 |
22077088 |
BUTTERFLY_MULTIPLICATION_SHR6(input_data[1], input_data[7], C3_SHR8, S3_SHR8); |
|
1170 |
|||
1171 |
/* stage 4. */ |
||
1172 |
22077088 |
input_data[0] += round; |
|
1173 |
22077088 |
input_data[4] += round; |
|
1174 |
22077088 |
input_data[2] += round; |
|
1175 |
22077088 |
input_data[6] += round; |
|
1176 |
|||
1177 |
22077088 |
output_data[0] = (input_data[0] + input_data[1]) >> post_scale; |
|
1178 |
22077088 |
output_data[8] = (input_data[4] + input_data[5]) >> post_scale; |
|
1179 |
22077088 |
output_data[16] = (input_data[2] + input_data[3]) >> post_scale; |
|
1180 |
22077088 |
output_data[24] = (input_data[6] + input_data[7]) >> post_scale; |
|
1181 |
22077088 |
output_data[32] = (input_data[6] - input_data[7]) >> post_scale; |
|
1182 |
22077088 |
output_data[40] = (input_data[2] - input_data[3]) >> post_scale; |
|
1183 |
22077088 |
output_data[48] = (input_data[4] - input_data[5]) >> post_scale; |
|
1184 |
22077088 |
output_data[56] = (input_data[0] - input_data[1]) >> post_scale; |
|
1185 |
22077088 |
} |
|
1186 |
|||
1187 |
/**************************************************************************/ |
||
1188 |
/* */ |
||
1189 |
/* FUNCTION RELEASE */ |
||
1190 |
/* */ |
||
1191 |
/* _gx_image_reader_jpeg_dequantize_idct PORTABLE C */ |
||
1192 |
/* 6.3.0 */ |
||
1193 |
/* AUTHOR */ |
||
1194 |
/* */ |
||
1195 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
1196 |
/* */ |
||
1197 |
/* DESCRIPTION */ |
||
1198 |
/* */ |
||
1199 |
/* Dequatilizes decoded data and performs Inverse Discrete Consine */ |
||
1200 |
/* Transformation. */ |
||
1201 |
/* */ |
||
1202 |
/* INPUT */ |
||
1203 |
/* */ |
||
1204 |
/* block Pointer to decoded data */ |
||
1205 |
/* quant_table Pointer to quantization table */ |
||
1206 |
/* out Buffer for output data */ |
||
1207 |
/* stride Stride of output data */ |
||
1208 |
/* */ |
||
1209 |
/* OUTPUT */ |
||
1210 |
/* */ |
||
1211 |
/* None */ |
||
1212 |
/* */ |
||
1213 |
/* CALLS */ |
||
1214 |
/* */ |
||
1215 |
/* _gx_image_reader_jpeg_1d_idct Perform 1D Inverse Discrete */ |
||
1216 |
/* Consine Transformation */ |
||
1217 |
/* GX_SATURATE_TO_BYTE Saturate to [-128, 127] */ |
||
1218 |
/* */ |
||
1219 |
/* CALLED BY */ |
||
1220 |
/* */ |
||
1221 |
/* _gx_image_reader_jpeg_one_block_decode */ |
||
1222 |
/* */ |
||
1223 |
/* RELEASE HISTORY */ |
||
1224 |
/* */ |
||
1225 |
/* DATE NAME DESCRIPTION */ |
||
1226 |
/* */ |
||
1227 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
1228 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
1229 |
/* resulting in version 6.1 */ |
||
1230 |
/* 10-31-2022 Kenneth Maxwell Modified comment(s), */ |
||
1231 |
/* added range check for */ |
||
1232 |
/* stride, changed return val, */ |
||
1233 |
/* added range check for */ |
||
1234 |
/* table_index, */ |
||
1235 |
/* resulting in version 6.2.0 */ |
||
1236 |
/* 10-31-2023 Ting Zhu Modified comment(s), */ |
||
1237 |
/* improved logic, */ |
||
1238 |
/* resulting in version 6.3.0 */ |
||
1239 |
/* */ |
||
1240 |
/**************************************************************************/ |
||
1241 |
1379818 |
static VOID _gx_image_reader_jpeg_dequantize_idct(INT *block, INT *quant_table, GX_BYTE *out, INT stride) |
|
1242 |
{ |
||
1243 |
static GX_CONST GX_UBYTE reorder_index[] = { |
||
1244 |
0, 1, 8, 16, 9, 2, 3, 10, |
||
1245 |
17, 24, 32, 25, 18, 11, 4, 5, |
||
1246 |
12, 19, 26, 33, 40, 48, 41, 34, |
||
1247 |
27, 20, 13, 6, 7, 14, 21, 28, |
||
1248 |
35, 42, 49, 56, 57, 50, 43, 36, |
||
1249 |
29, 22, 15, 23, 30, 37, 44, 51, |
||
1250 |
58, 59, 52, 45, 38, 31, 39, 46, |
||
1251 |
53, 60, 61, 54, 47, 55, 62, 63 |
||
1252 |
}; |
||
1253 |
INT index; |
||
1254 |
INT jpeg_block[64]; |
||
1255 |
INT temp_block[64]; |
||
1256 |
INT row; |
||
1257 |
|||
1258 |
✓✓ | 89688170 |
for (index = 0; index < 64; index++) |
1259 |
{ |
||
1260 |
88308352 |
block[index] *= quant_table[index]; |
|
1261 |
|||
1262 |
/* Reorder from zig-zag order to 8*8 block */ |
||
1263 |
88308352 |
jpeg_block[reorder_index[index]] = block[index]; |
|
1264 |
} |
||
1265 |
|||
1266 |
✓✓ | 12418362 |
for (index = 0; index < 8; index++) |
1267 |
{ |
||
1268 |
11038544 |
_gx_image_reader_jpeg_1d_idct(jpeg_block + index * 8, temp_block + index, 9, 256); /* row */ |
|
1269 |
} |
||
1270 |
|||
1271 |
✓✓ | 12418362 |
for (index = 0; index < 8; index++) |
1272 |
{ |
||
1273 |
11038544 |
_gx_image_reader_jpeg_1d_idct(temp_block + index * 8, jpeg_block + index, 12, 2048); /* col */ |
|
1274 |
} |
||
1275 |
|||
1276 |
✓✓ | 12418362 |
for (row = 0; row < 8; row++) |
1277 |
{ |
||
1278 |
✓✓ | 99346896 |
for (index = 0; index < 8; index++) |
1279 |
{ |
||
1280 |
✓✓✓✓ |
88308352 |
GX_SATURATE_TO_BYTE(out[index], jpeg_block[row * 8 + index]); |
1281 |
} |
||
1282 |
|||
1283 |
11038544 |
out += stride; |
|
1284 |
} |
||
1285 |
1379818 |
} |
|
1286 |
#endif |
||
1287 |
|||
1288 |
/**************************************************************************/ |
||
1289 |
/* */ |
||
1290 |
/* FUNCTION RELEASE */ |
||
1291 |
/* */ |
||
1292 |
/* _gx_image_reader_jpeg_one_block_decode PORTABLE C */ |
||
1293 |
/* 6.3.0 */ |
||
1294 |
/* AUTHOR */ |
||
1295 |
/* */ |
||
1296 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
1297 |
/* */ |
||
1298 |
/* DESCRIPTION */ |
||
1299 |
/* */ |
||
1300 |
/* Decode one block of JPEG data. */ |
||
1301 |
/* */ |
||
1302 |
/* INPUT */ |
||
1303 |
/* */ |
||
1304 |
/* jpeg_info JPEG data control block */ |
||
1305 |
/* icomponent Component index */ |
||
1306 |
/* block_data Pointer to decoded data */ |
||
1307 |
/* */ |
||
1308 |
/* OUTPUT */ |
||
1309 |
/* */ |
||
1310 |
/* Status Code */ |
||
1311 |
/* */ |
||
1312 |
/* CALLS */ |
||
1313 |
/* */ |
||
1314 |
/* memset */ |
||
1315 |
/* _gx_image_reader_jpeg_dc_decode Decode dc component */ |
||
1316 |
/* _gx_image_reader_jpeg_ac_decode Decode ac component */ |
||
1317 |
/* _gx_image_reader_jpeg_dequantize_idct Dequatilize decoded data */ |
||
1318 |
/* */ |
||
1319 |
/* CALLED BY */ |
||
1320 |
/* */ |
||
1321 |
/* _gx_image_reader_jpeg_decode */ |
||
1322 |
/* */ |
||
1323 |
/* RELEASE HISTORY */ |
||
1324 |
/* */ |
||
1325 |
/* DATE NAME DESCRIPTION */ |
||
1326 |
/* */ |
||
1327 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
1328 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
1329 |
/* resulting in version 6.1 */ |
||
1330 |
/* 10-31-2022 Kenneth Maxwell Modified comment(s), */ |
||
1331 |
/* returned result of */ |
||
1332 |
/* dequantize_idct, */ |
||
1333 |
/* resulting in version 6.2.0 */ |
||
1334 |
/* 10-31-2023 Ting Zhu Modified comment(s), */ |
||
1335 |
/* improved logic, */ |
||
1336 |
/* resulting in version 6.3.0 */ |
||
1337 |
/* */ |
||
1338 |
/**************************************************************************/ |
||
1339 |
1379818 |
static UINT _gx_image_reader_jpeg_one_block_decode(GX_JPEG_INFO *jpeg_info, UINT i_component, GX_BYTE *block_data) |
|
1340 |
{ |
||
1341 |
INT table_index; |
||
1342 |
INT stride; |
||
1343 |
|||
1344 |
1379818 |
memset(jpeg_info -> gx_jpeg_vecter, 0, 64 * sizeof(UINT)); |
|
1345 |
1379818 |
_gx_image_reader_jpeg_dc_decode(jpeg_info, i_component); |
|
1346 |
1379818 |
_gx_image_reader_jpeg_ac_decode(jpeg_info, i_component); |
|
1347 |
|||
1348 |
✗✓ | 1379818 |
if (i_component >= JPG_MAX_COMPONENTS) |
1349 |
{ |
||
1350 |
return GX_FAILURE; |
||
1351 |
} |
||
1352 |
|||
1353 |
1379818 |
stride = ((jpeg_info -> gx_jpeg_sample_factor[i_component] & 0xf0) >> 1); |
|
1354 |
|||
1355 |
✓✓ | 1379818 |
if (i_component == 0) |
1356 |
{ |
||
1357 |
✗✓ | 817636 |
if (stride > 32) |
1358 |
{ |
||
1359 |
return GX_FAILURE; |
||
1360 |
} |
||
1361 |
} |
||
1362 |
else |
||
1363 |
{ |
||
1364 |
✗✓ | 562182 |
if (stride > 8) |
1365 |
{ |
||
1366 |
return GX_FAILURE; |
||
1367 |
} |
||
1368 |
} |
||
1369 |
|||
1370 |
1379818 |
table_index = jpeg_info -> gx_jpeg_qantization_table_index[i_component]; |
|
1371 |
|||
1372 |
✗✓ | 1379818 |
if (table_index >= JPG_QUANT_TABLE_DIMENSION) |
1373 |
{ |
||
1374 |
return GX_FAILURE; |
||
1375 |
} |
||
1376 |
|||
1377 |
1379818 |
_gx_image_reader_jpeg_dequantize_idct(jpeg_info -> gx_jpeg_vecter, jpeg_info -> gx_jpeg_quantization_table[table_index], block_data, stride); |
|
1378 |
1379818 |
return GX_SUCCESS; |
|
1379 |
} |
||
1380 |
|||
1381 |
|||
1382 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
1383 |
/**************************************************************************/ |
||
1384 |
/* */ |
||
1385 |
/* FUNCTION RELEASE */ |
||
1386 |
/* */ |
||
1387 |
/* _gx_image_reader_jpeg_24xrgb_pixel_write_helium PORTABLE C */ |
||
1388 |
/* 6.3.0 */ |
||
1389 |
/* AUTHOR */ |
||
1390 |
/* */ |
||
1391 |
/* Ting Zhu, Microsoft Corporation */ |
||
1392 |
/* */ |
||
1393 |
/* DESCRIPTION */ |
||
1394 |
/* */ |
||
1395 |
/* Write 24xrgb pixel to memory using Helium intrinsics. */ |
||
1396 |
/* */ |
||
1397 |
/* INPUT */ |
||
1398 |
/* */ |
||
1399 |
/* jpeg_info JPEG control block */ |
||
1400 |
/* vred Red value vector */ |
||
1401 |
/* vgreen Green value vector */ |
||
1402 |
/* vblue Blue value vector */ |
||
1403 |
/* size Number of pixels to write */ |
||
1404 |
/* */ |
||
1405 |
/* OUTPUT */ |
||
1406 |
/* */ |
||
1407 |
/* vstrbq_scatter_offset_u8 Scatter 8-bit values to */ |
||
1408 |
/* memory */ |
||
1409 |
/* vstrbq_scatter_offset_p_u8 Optionaly scatter 8-bit */ |
||
1410 |
/* values to memory */ |
||
1411 |
/* */ |
||
1412 |
/* CALLS */ |
||
1413 |
/* */ |
||
1414 |
/* None */ |
||
1415 |
/* */ |
||
1416 |
/* CALLED BY */ |
||
1417 |
/* */ |
||
1418 |
/* _gx_image_reader_jpeg_one_mcu_write */ |
||
1419 |
/* _gx_image_reader_jpeg_one_mcu_rotated_write */ |
||
1420 |
/* */ |
||
1421 |
/* RELEASE HISTORY */ |
||
1422 |
/* */ |
||
1423 |
/* DATE NAME DESCRIPTION */ |
||
1424 |
/* */ |
||
1425 |
/* 10-31-2023 Ting Zhu Initial Version 6.3.0 */ |
||
1426 |
/* */ |
||
1427 |
/**************************************************************************/ |
||
1428 |
static VOID _gx_image_reader_jpeg_24xrgb_pixel_write_helium(GX_JPEG_INFO *jpeg_info, uint8x16_t vred, uint8x16_t vgreen, uint8x16_t vblue, INT size) |
||
1429 |
{ |
||
1430 |
INT index; |
||
1431 |
|||
1432 |
for(index = 0; index < size; index++) |
||
1433 |
{ |
||
1434 |
*((GX_COLOR *)jpeg_info -> gx_jpeg_putdata) = 0xff000000 | ((ULONG)vred[index] << 16) | ((ULONG)vgreen[index] << 8) | (ULONG)vblue[index]; |
||
1435 |
|||
1436 |
jpeg_info -> gx_jpeg_putdata += 4; |
||
1437 |
} |
||
1438 |
} |
||
1439 |
#else |
||
1440 |
/**************************************************************************/ |
||
1441 |
/* */ |
||
1442 |
/* FUNCTION RELEASE */ |
||
1443 |
/* */ |
||
1444 |
/* _gx_image_reader_jpeg_1555xrgb_pixel_write PORTABLE C */ |
||
1445 |
/* 6.3.0 */ |
||
1446 |
/* AUTHOR */ |
||
1447 |
/* */ |
||
1448 |
/* Ting Zhu, Microsoft Corporation */ |
||
1449 |
/* */ |
||
1450 |
/* DESCRIPTION */ |
||
1451 |
/* */ |
||
1452 |
/* Write 24xrgb pixel to memory. */ |
||
1453 |
/* */ |
||
1454 |
/* INPUT */ |
||
1455 |
/* */ |
||
1456 |
/* jpeg_info JPEG control block */ |
||
1457 |
/* red Red value */ |
||
1458 |
/* green Green value */ |
||
1459 |
/* blue Blue value */ |
||
1460 |
/* */ |
||
1461 |
/* OUTPUT */ |
||
1462 |
/* */ |
||
1463 |
/* None */ |
||
1464 |
/* */ |
||
1465 |
/* CALLS */ |
||
1466 |
/* */ |
||
1467 |
/* None */ |
||
1468 |
/* */ |
||
1469 |
/* CALLED BY */ |
||
1470 |
/* */ |
||
1471 |
/* _gx_image_reader_jpeg_one_mcu_write */ |
||
1472 |
/* _gx_image_reader_jpeg_one_mcu_rotated_write */ |
||
1473 |
/* */ |
||
1474 |
/* RELEASE HISTORY */ |
||
1475 |
/* */ |
||
1476 |
/* DATE NAME DESCRIPTION */ |
||
1477 |
/* */ |
||
1478 |
/* 10-31-2023 Ting Zhu Initial Version 6.3.0 */ |
||
1479 |
/* */ |
||
1480 |
/**************************************************************************/ |
||
1481 |
7943561 |
static VOID _gx_image_reader_jpeg_24xrgb_pixel_write(GX_JPEG_INFO *jpeg_info, GX_UBYTE red, GX_UBYTE green, GX_UBYTE blue) |
|
1482 |
{ |
||
1483 |
7943561 |
*((GX_COLOR *)jpeg_info -> gx_jpeg_putdata) = 0xff000000 | ((ULONG)red << 16) | ((ULONG)green << 8) | (ULONG)blue; |
|
1484 |
|||
1485 |
7943561 |
jpeg_info -> gx_jpeg_putdata += 4; |
|
1486 |
7943561 |
} |
|
1487 |
#endif |
||
1488 |
|||
1489 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
1490 |
/**************************************************************************/ |
||
1491 |
/* */ |
||
1492 |
/* FUNCTION RELEASE */ |
||
1493 |
/* */ |
||
1494 |
/* _gx_image_reader_jpeg_24bpp_pixel_write_helium PORTABLE C */ |
||
1495 |
/* 6.3.0 */ |
||
1496 |
/* AUTHOR */ |
||
1497 |
/* */ |
||
1498 |
/* Ting Zhu, Microsoft Corporation */ |
||
1499 |
/* */ |
||
1500 |
/* DESCRIPTION */ |
||
1501 |
/* */ |
||
1502 |
/* Internal helper function to write 24xrgb pixel to memory using */ |
||
1503 |
/* Helium intrinsics. */ |
||
1504 |
/* */ |
||
1505 |
/* INPUT */ |
||
1506 |
/* */ |
||
1507 |
/* jpeg_info JPEG control block */ |
||
1508 |
/* vred Red value vector */ |
||
1509 |
/* vgreen Green value vector */ |
||
1510 |
/* vblue Blue value vector */ |
||
1511 |
/* size Number of pixels to write */ |
||
1512 |
/* */ |
||
1513 |
/* OUTPUT */ |
||
1514 |
/* */ |
||
1515 |
/* vstrbq_scatter_offset_u8 Scatter 8-bit values to */ |
||
1516 |
/* memory */ |
||
1517 |
/* vstrbq_scatter_offset_p_u8 Optionally scatter 8-bit */ |
||
1518 |
/* values to memory */ |
||
1519 |
/* */ |
||
1520 |
/* CALLS */ |
||
1521 |
/* */ |
||
1522 |
/* None */ |
||
1523 |
/* */ |
||
1524 |
/* CALLED BY */ |
||
1525 |
/* */ |
||
1526 |
/* _gx_image_reader_jpeg_one_mcu_write */ |
||
1527 |
/* _gx_image_reader_jpeg_one_mcu_rotated_write */ |
||
1528 |
/* */ |
||
1529 |
/* RELEASE HISTORY */ |
||
1530 |
/* */ |
||
1531 |
/* DATE NAME DESCRIPTION */ |
||
1532 |
/* */ |
||
1533 |
/* 10-31-2023 Ting Zhu Initial Version 6.3.0 */ |
||
1534 |
/* */ |
||
1535 |
/**************************************************************************/ |
||
1536 |
static VOID _gx_image_reader_jpeg_24bpp_pixel_write_helium(GX_JPEG_INFO *jpeg_info, uint8x16_t vred, uint8x16_t vgreen, uint8x16_t vblue, INT size) |
||
1537 |
{ |
||
1538 |
static uint8x16_t voffset = {0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45}; |
||
1539 |
mve_pred16_t p; |
||
1540 |
|||
1541 |
if (size == 16) |
||
1542 |
{ |
||
1543 |
vstrbq_scatter_offset_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vred); |
||
1544 |
vstrbq_scatter_offset_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vgreen); |
||
1545 |
vstrbq_scatter_offset_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vblue); |
||
1546 |
jpeg_info -> gx_jpeg_putdata += 45; |
||
1547 |
} |
||
1548 |
else |
||
1549 |
{ |
||
1550 |
/* Write the specified size of RGB values to memory. */ |
||
1551 |
p = 0xffff >> (16 - size); |
||
1552 |
vstrbq_scatter_offset_p_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vred, p); |
||
1553 |
vstrbq_scatter_offset_p_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vgreen, p); |
||
1554 |
vstrbq_scatter_offset_p_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vblue, p); |
||
1555 |
jpeg_info -> gx_jpeg_putdata += (size - 1) * 3; |
||
1556 |
} |
||
1557 |
} |
||
1558 |
#else |
||
1559 |
/**************************************************************************/ |
||
1560 |
/* */ |
||
1561 |
/* FUNCTION RELEASE */ |
||
1562 |
/* */ |
||
1563 |
/* _gx_image_reader_jpeg_24bpp_pixel_write PORTABLE C */ |
||
1564 |
/* 6.3.0 */ |
||
1565 |
/* AUTHOR */ |
||
1566 |
/* */ |
||
1567 |
/* Ting Zhu, Microsoft Corporation */ |
||
1568 |
/* */ |
||
1569 |
/* DESCRIPTION */ |
||
1570 |
/* */ |
||
1571 |
/* Write 24bpp pixel to memory. */ |
||
1572 |
/* */ |
||
1573 |
/* INPUT */ |
||
1574 |
/* */ |
||
1575 |
/* jpeg_info JPEG control block */ |
||
1576 |
/* red Red value */ |
||
1577 |
/* green Green value */ |
||
1578 |
/* blue Blue value */ |
||
1579 |
/* */ |
||
1580 |
/* OUTPUT */ |
||
1581 |
/* */ |
||
1582 |
/* None */ |
||
1583 |
/* */ |
||
1584 |
/* CALLS */ |
||
1585 |
/* */ |
||
1586 |
/* None */ |
||
1587 |
/* */ |
||
1588 |
/* CALLED BY */ |
||
1589 |
/* */ |
||
1590 |
/* _gx_image_reader_jpeg_one_mcu_write */ |
||
1591 |
/* _gx_image_reader_jpeg_one_mcu_rotated_write */ |
||
1592 |
/* */ |
||
1593 |
/* RELEASE HISTORY */ |
||
1594 |
/* */ |
||
1595 |
/* DATE NAME DESCRIPTION */ |
||
1596 |
/* */ |
||
1597 |
/* 10-31-2023 Ting Zhu Initial Version 6.3.0 */ |
||
1598 |
/* */ |
||
1599 |
/**************************************************************************/ |
||
1600 |
8129360 |
static VOID _gx_image_reader_jpeg_24bpp_pixel_write(GX_JPEG_INFO *jpeg_info, GX_UBYTE red, GX_UBYTE green, GX_UBYTE blue) |
|
1601 |
{ |
||
1602 |
8129360 |
*jpeg_info -> gx_jpeg_putdata++ = red; |
|
1603 |
8129360 |
*jpeg_info -> gx_jpeg_putdata++ = green; |
|
1604 |
8129360 |
*jpeg_info -> gx_jpeg_putdata++ = blue; |
|
1605 |
8129360 |
} |
|
1606 |
#endif |
||
1607 |
|||
1608 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
1609 |
/**************************************************************************/ |
||
1610 |
/* */ |
||
1611 |
/* FUNCTION RELEASE */ |
||
1612 |
/* */ |
||
1613 |
/* _gx_image_reader_jpeg_565rgb_pixel_write_helium PORTABLE C */ |
||
1614 |
/* 6.3.0 */ |
||
1615 |
/* AUTHOR */ |
||
1616 |
/* */ |
||
1617 |
/* Ting Zhu, Microsoft Corporation */ |
||
1618 |
/* */ |
||
1619 |
/* DESCRIPTION */ |
||
1620 |
/* */ |
||
1621 |
/* Internal helper function to write 565rgb pixel to memory using */ |
||
1622 |
/* Helium intrinsics. */ |
||
1623 |
/* */ |
||
1624 |
/* INPUT */ |
||
1625 |
/* */ |
||
1626 |
/* jpeg_info JPEG control block */ |
||
1627 |
/* vred Red value vector */ |
||
1628 |
/* vgreen Green value vector */ |
||
1629 |
/* vblue Blue value vector */ |
||
1630 |
/* size Number of pixels to write */ |
||
1631 |
/* */ |
||
1632 |
/* OUTPUT */ |
||
1633 |
/* */ |
||
1634 |
/* vshrq_n_u8 Unsigned 8-bit shift right */ |
||
1635 |
/* vldrbq_u16 Load 8-bit value to a */ |
||
1636 |
/* destination register */ |
||
1637 |
/* vshlq_n_u16 Unsigned 16-bit shift left */ |
||
1638 |
/* vorrq_u16 Unsigned 16-bit OR */ |
||
1639 |
/* vstrhq_u16 Store 16-bit values from */ |
||
1640 |
/* register to memory */ |
||
1641 |
/* vstrhq_p_u16 Optionally store 16-bit */ |
||
1642 |
/* values from register to */ |
||
1643 |
/* memory */ |
||
1644 |
/* */ |
||
1645 |
/* CALLS */ |
||
1646 |
/* */ |
||
1647 |
/* None */ |
||
1648 |
/* */ |
||
1649 |
/* CALLED BY */ |
||
1650 |
/* */ |
||
1651 |
/* _gx_image_reader_jpeg_one_mcu_write */ |
||
1652 |
/* _gx_image_reader_jpeg_one_mcu_rotated_write */ |
||
1653 |
/* */ |
||
1654 |
/* RELEASE HISTORY */ |
||
1655 |
/* */ |
||
1656 |
/* DATE NAME DESCRIPTION */ |
||
1657 |
/* */ |
||
1658 |
/* 10-31-2023 Ting Zhu Initial Version 6.3.0 */ |
||
1659 |
/* */ |
||
1660 |
/**************************************************************************/ |
||
1661 |
static VOID _gx_image_reader_jpeg_565rgb_pixel_write_helium(GX_JPEG_INFO *jpeg_info, uint8x16_t vred, uint8x16_t vgreen, uint8x16_t vblue, INT size) |
||
1662 |
{ |
||
1663 |
uint16x8_t vresult; |
||
1664 |
uint16x8_t vtemp; |
||
1665 |
INT index; |
||
1666 |
mve_pred16_t p; |
||
1667 |
uint16_t *put = (uint16_t *)jpeg_info -> gx_jpeg_putdata; |
||
1668 |
GX_UBYTE red[16]; |
||
1669 |
GX_UBYTE green[16]; |
||
1670 |
GX_UBYTE blue[16]; |
||
1671 |
|||
1672 |
vred = vshrq_n_u8(vred, 3); |
||
1673 |
vgreen = vshrq_n_u8(vgreen, 2); |
||
1674 |
vblue = vshrq_n_u8(vblue, 3); |
||
1675 |
|||
1676 |
vstrbq(red, vred); |
||
1677 |
vstrbq(green, vgreen); |
||
1678 |
vstrbq(blue, vblue); |
||
1679 |
|||
1680 |
for (index = 0; index <= 8; index += 8) |
||
1681 |
{ |
||
1682 |
vtemp = vldrbq_u16(&red[index]); |
||
1683 |
vresult = vshlq_n_u16(vtemp, 11); |
||
1684 |
|||
1685 |
vtemp = vldrbq_u16(&green[index]); |
||
1686 |
vtemp = vshlq_n_u16(vtemp, 5); |
||
1687 |
vresult = vorrq_u16(vresult, vtemp); |
||
1688 |
|||
1689 |
vtemp = vldrbq_u16(&blue[index]); |
||
1690 |
vresult = vorrq_u16(vresult, vtemp); |
||
1691 |
|||
1692 |
if (size >= 8) |
||
1693 |
{ |
||
1694 |
vstrhq_u16(put, vresult); |
||
1695 |
put += 8; |
||
1696 |
size -= 8; |
||
1697 |
} |
||
1698 |
else |
||
1699 |
{ |
||
1700 |
p = 0xffff >> (16 - (size << 1)); |
||
1701 |
vstrhq_p_u16(put, vresult, p); |
||
1702 |
put += size; |
||
1703 |
break; |
||
1704 |
} |
||
1705 |
} |
||
1706 |
|||
1707 |
jpeg_info -> gx_jpeg_putdata = (GX_UBYTE *)put; |
||
1708 |
} |
||
1709 |
#else |
||
1710 |
/**************************************************************************/ |
||
1711 |
/* */ |
||
1712 |
/* FUNCTION RELEASE */ |
||
1713 |
/* */ |
||
1714 |
/* _gx_image_reader_jpeg_1555xrgb_pixel_write PORTABLE C */ |
||
1715 |
/* 6.3.0 */ |
||
1716 |
/* AUTHOR */ |
||
1717 |
/* */ |
||
1718 |
/* Ting Zhu, Microsoft Corporation */ |
||
1719 |
/* */ |
||
1720 |
/* DESCRIPTION */ |
||
1721 |
/* */ |
||
1722 |
/* Write 1555xrgb pixel to memory. */ |
||
1723 |
/* */ |
||
1724 |
/* INPUT */ |
||
1725 |
/* */ |
||
1726 |
/* jpeg_info JPEG control block */ |
||
1727 |
/* red Red value */ |
||
1728 |
/* green Green value */ |
||
1729 |
/* blue Blue value */ |
||
1730 |
/* */ |
||
1731 |
/* OUTPUT */ |
||
1732 |
/* */ |
||
1733 |
/* None */ |
||
1734 |
/* */ |
||
1735 |
/* CALLS */ |
||
1736 |
/* */ |
||
1737 |
/* GX_SATURATE_TO_5BIT Saturate the value to 5 bits */ |
||
1738 |
/* */ |
||
1739 |
/* CALLED BY */ |
||
1740 |
/* */ |
||
1741 |
/* _gx_image_reader_jpeg_one_mcu_write */ |
||
1742 |
/* _gx_image_reader_jpeg_one_mcu_rotated_write */ |
||
1743 |
/* */ |
||
1744 |
/* RELEASE HISTORY */ |
||
1745 |
/* */ |
||
1746 |
/* DATE NAME DESCRIPTION */ |
||
1747 |
/* */ |
||
1748 |
/* 10-31-2023 Ting Zhu Initial Version 6.3.0 */ |
||
1749 |
/* */ |
||
1750 |
/**************************************************************************/ |
||
1751 |
13671747 |
static VOID _gx_image_reader_jpeg_565rgb_pixel_write(GX_JPEG_INFO *jpeg_info, GX_UBYTE red, GX_UBYTE green, GX_UBYTE blue) |
|
1752 |
{ |
||
1753 |
/* Make sure the range of the RGB values are within bound. */ |
||
1754 |
13671747 |
red >>= 3; |
|
1755 |
13671747 |
green >>= 2; |
|
1756 |
13671747 |
blue >>= 3; |
|
1757 |
|||
1758 |
13671747 |
*((USHORT *)jpeg_info -> gx_jpeg_putdata) = (USHORT)((red << 11) | (green << 5 | blue)); |
|
1759 |
13671747 |
jpeg_info -> gx_jpeg_putdata += 2; |
|
1760 |
13671747 |
} |
|
1761 |
#endif |
||
1762 |
|||
1763 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
1764 |
/**************************************************************************/ |
||
1765 |
/* */ |
||
1766 |
/* FUNCTION RELEASE */ |
||
1767 |
/* */ |
||
1768 |
/* _gx_image_reader_jpeg_1555xrgb_pixel_write_helium PORTABLE C */ |
||
1769 |
/* 6.3.0 */ |
||
1770 |
/* AUTHOR */ |
||
1771 |
/* */ |
||
1772 |
/* Ting Zhu, Microsoft Corporation */ |
||
1773 |
/* */ |
||
1774 |
/* DESCRIPTION */ |
||
1775 |
/* */ |
||
1776 |
/* Internal helper function to write 1555xrgb pixel to memory using */ |
||
1777 |
/* Helium intrinsics. */ |
||
1778 |
/* */ |
||
1779 |
/* INPUT */ |
||
1780 |
/* */ |
||
1781 |
/* jpeg_info JPEG control block */ |
||
1782 |
/* vred Red value vector */ |
||
1783 |
/* vgreen Green value vector */ |
||
1784 |
/* vblue Blue value vector */ |
||
1785 |
/* size Number of pixels to write */ |
||
1786 |
/* */ |
||
1787 |
/* OUTPUT */ |
||
1788 |
/* */ |
||
1789 |
/* vshrq_n_u8 Unsigned 8-bit shift right */ |
||
1790 |
/* vldrbq_u16 Load 8-bit value to a */ |
||
1791 |
/* destination register */ |
||
1792 |
/* vshlq_n_u16 Unsigned 16-bit shift left */ |
||
1793 |
/* vorrq_u16 Unsigned 16-bit OR */ |
||
1794 |
/* vstrhq_u16 Store 16-bit values from */ |
||
1795 |
/* register to memory */ |
||
1796 |
/* vstrhq_p_u16 Optionally store 16-bit */ |
||
1797 |
/* values from register to */ |
||
1798 |
/* memory */ |
||
1799 |
/* */ |
||
1800 |
/* CALLS */ |
||
1801 |
/* */ |
||
1802 |
/* None */ |
||
1803 |
/* */ |
||
1804 |
/* CALLED BY */ |
||
1805 |
/* */ |
||
1806 |
/* _gx_image_reader_jpeg_one_mcu_write */ |
||
1807 |
/* _gx_image_reader_jpeg_one_mcu_rotated_write */ |
||
1808 |
/* */ |
||
1809 |
/* RELEASE HISTORY */ |
||
1810 |
/* */ |
||
1811 |
/* DATE NAME DESCRIPTION */ |
||
1812 |
/* */ |
||
1813 |
/* 10-31-2023 Ting Zhu Initial Version 6.3.0 */ |
||
1814 |
/* */ |
||
1815 |
/**************************************************************************/ |
||
1816 |
static VOID _gx_image_reader_jpeg_1555xrgb_pixel_write_helium(GX_JPEG_INFO *jpeg_info, uint8x16_t vred, uint8x16_t vgreen, uint8x16_t vblue, INT size) |
||
1817 |
{ |
||
1818 |
uint16x8_t vresult; |
||
1819 |
uint16x8_t vtemp; |
||
1820 |
INT index; |
||
1821 |
uint16_t *put = (uint16_t *)jpeg_info -> gx_jpeg_putdata; |
||
1822 |
mve_pred16_t p; |
||
1823 |
GX_UBYTE red[16]; |
||
1824 |
GX_UBYTE green[16]; |
||
1825 |
GX_UBYTE blue[16]; |
||
1826 |
|||
1827 |
vred = vshrq_n_u8(vred, 3); |
||
1828 |
vgreen = vshrq_n_u8(vgreen, 3); |
||
1829 |
vblue = vshrq_n_u8(vblue, 3); |
||
1830 |
|||
1831 |
vstrbq(red, vred); |
||
1832 |
vstrbq(green, vgreen); |
||
1833 |
vstrbq(blue, vblue); |
||
1834 |
|||
1835 |
for (index = 0; index <= 8; index += 8) |
||
1836 |
{ |
||
1837 |
vtemp = vldrbq_u16(&red[index]); |
||
1838 |
vresult = vshlq_n_u16(vtemp, 10); |
||
1839 |
|||
1840 |
vtemp = vldrbq_u16(&green[index]); |
||
1841 |
vtemp = vshlq_n_u16(vtemp, 5); |
||
1842 |
vresult = vorrq_u16(vresult, vtemp); |
||
1843 |
|||
1844 |
vtemp = vldrbq_u16(&blue[index]); |
||
1845 |
vresult = vorrq_u16(vresult, vtemp); |
||
1846 |
|||
1847 |
if (size >= 8) |
||
1848 |
{ |
||
1849 |
vstrhq_u16(put, vresult); |
||
1850 |
put += 8; |
||
1851 |
size -= 8; |
||
1852 |
} |
||
1853 |
else |
||
1854 |
{ |
||
1855 |
p = 0xffff >> (16 - (size << 1)); |
||
1856 |
vstrhq_p_u16(put, vresult, p); |
||
1857 |
put += size; |
||
1858 |
break; |
||
1859 |
} |
||
1860 |
} |
||
1861 |
|||
1862 |
jpeg_info -> gx_jpeg_putdata = (GX_UBYTE *)put; |
||
1863 |
} |
||
1864 |
#else |
||
1865 |
/**************************************************************************/ |
||
1866 |
/* */ |
||
1867 |
/* FUNCTION RELEASE */ |
||
1868 |
/* */ |
||
1869 |
/* _gx_image_reader_jpeg_1555xrgb_pixel_write PORTABLE C */ |
||
1870 |
/* 6.3.0 */ |
||
1871 |
/* AUTHOR */ |
||
1872 |
/* */ |
||
1873 |
/* Ting Zhu, Microsoft Corporation */ |
||
1874 |
/* */ |
||
1875 |
/* DESCRIPTION */ |
||
1876 |
/* */ |
||
1877 |
/* Write 1555xrgb pixel to memory. */ |
||
1878 |
/* */ |
||
1879 |
/* INPUT */ |
||
1880 |
/* */ |
||
1881 |
/* jpeg_info JPEG control block */ |
||
1882 |
/* red Red value */ |
||
1883 |
/* green Green value */ |
||
1884 |
/* blue Blue value */ |
||
1885 |
/* */ |
||
1886 |
/* OUTPUT */ |
||
1887 |
/* */ |
||
1888 |
/* None */ |
||
1889 |
/* */ |
||
1890 |
/* CALLS */ |
||
1891 |
/* */ |
||
1892 |
/* GX_SATURATE_TO_5BIT Saturate the value to 5 bits */ |
||
1893 |
/* */ |
||
1894 |
/* CALLED BY */ |
||
1895 |
/* */ |
||
1896 |
/* _gx_image_reader_jpeg_one_mcu_write */ |
||
1897 |
/* _gx_image_reader_jpeg_one_mcu_rotated_write */ |
||
1898 |
/* */ |
||
1899 |
/* RELEASE HISTORY */ |
||
1900 |
/* */ |
||
1901 |
/* DATE NAME DESCRIPTION */ |
||
1902 |
/* */ |
||
1903 |
/* 10-31-2023 Ting Zhu Initial Version 6.3.0 */ |
||
1904 |
/* */ |
||
1905 |
/**************************************************************************/ |
||
1906 |
360820 |
static VOID _gx_image_reader_jpeg_1555xrgb_pixel_write(GX_JPEG_INFO *jpeg_info, GX_UBYTE red, GX_UBYTE green, GX_UBYTE blue) |
|
1907 |
{ |
||
1908 |
/* Make sure the range of the RGB values are within bound. */ |
||
1909 |
360820 |
red >>= 3; |
|
1910 |
360820 |
green >>= 3; |
|
1911 |
360820 |
blue >>= 3; |
|
1912 |
|||
1913 |
360820 |
*((USHORT *)jpeg_info -> gx_jpeg_putdata) = (USHORT)((red << 10) | (green << 5 | blue)); |
|
1914 |
360820 |
jpeg_info -> gx_jpeg_putdata += 2; |
|
1915 |
360820 |
} |
|
1916 |
#endif |
||
1917 |
|||
1918 |
/**************************************************************************/ |
||
1919 |
/* */ |
||
1920 |
/* FUNCTION RELEASE */ |
||
1921 |
/* */ |
||
1922 |
/* _gx_image_reader_jpeg_pixel_write_info_set PORTABLE C */ |
||
1923 |
/* 6.3.0 */ |
||
1924 |
/* AUTHOR */ |
||
1925 |
/* */ |
||
1926 |
/* Ting Zhu, Microsoft Corporation */ |
||
1927 |
/* */ |
||
1928 |
/* DESCRIPTION */ |
||
1929 |
/* */ |
||
1930 |
/* Set information for writing pixel to memory. */ |
||
1931 |
/* */ |
||
1932 |
/* INPUT */ |
||
1933 |
/* */ |
||
1934 |
/* jpeg_info JPEG control block */ |
||
1935 |
/* */ |
||
1936 |
/* OUTPUT */ |
||
1937 |
/* */ |
||
1938 |
/* Status Code */ |
||
1939 |
/* */ |
||
1940 |
/* CALLS */ |
||
1941 |
/* */ |
||
1942 |
/* _gx_image_reader_jpeg_565rgb_pixel_write_helium */ |
||
1943 |
/* Write 565rgb pixel to memory */ |
||
1944 |
/* _gx_image_reader_jpeg_565rgb_pixel_write */ |
||
1945 |
/* Write 565rgb pixel to memory */ |
||
1946 |
/* _gx_image_reader_jpeg_1555xrgb_pixel_write_helium */ |
||
1947 |
/* Write 1555xrgb pixel to memory*/ |
||
1948 |
/* _gx_image_reader_jpeg_1555xrgb_pixel_write */ |
||
1949 |
/* Write 1555xrgb pixel to memory*/ |
||
1950 |
/* _gx_image_reader_jpeg_24xrgb_24bpp_pixel_write_helium */ |
||
1951 |
/* Write 24xrgb or 24rgb pixel */ |
||
1952 |
/* to memory */ |
||
1953 |
/* _gx_image_reader_jpeg_24xrgb_24bpp_pixel_write */ |
||
1954 |
/* Write 24xrgb or 24rgb pixel */ |
||
1955 |
/* to memory */ |
||
1956 |
/* */ |
||
1957 |
/* CALLED BY */ |
||
1958 |
/* */ |
||
1959 |
/* _gx_image_reader_jpeg_decompress */ |
||
1960 |
/* */ |
||
1961 |
/* RELEASE HISTORY */ |
||
1962 |
/* */ |
||
1963 |
/* DATE NAME DESCRIPTION */ |
||
1964 |
/* */ |
||
1965 |
/* 10-31-2023 Ting Zhu Initial Version 6.3.0 */ |
||
1966 |
/* */ |
||
1967 |
/**************************************************************************/ |
||
1968 |
588 |
static UINT _gx_image_reader_jpeg_pixel_write_info_set(GX_JPEG_INFO *jpeg_info) |
|
1969 |
{ |
||
1970 |
✓✓ | 588 |
if (!jpeg_info -> gx_jpeg_output_width) |
1971 |
{ |
||
1972 |
219 |
jpeg_info -> gx_jpeg_output_width = jpeg_info -> gx_jpeg_width; |
|
1973 |
219 |
jpeg_info -> gx_jpeg_output_height = jpeg_info -> gx_jpeg_height; |
|
1974 |
|||
1975 |
219 |
_gx_utility_rectangle_define(&jpeg_info -> gx_jpeg_output_clip, 0, 0, (GX_VALUE)(jpeg_info -> gx_jpeg_width - 1), (GX_VALUE)(jpeg_info -> gx_jpeg_height - 1)); |
|
1976 |
} |
||
1977 |
|||
1978 |
✓✓ | 588 |
jpeg_info -> gx_jpeg_output_stride = jpeg_info -> gx_jpeg_output_rotation_angle == 0 ? jpeg_info -> gx_jpeg_output_width : jpeg_info -> gx_jpeg_output_height; |
1979 |
|||
1980 |
/* Set pixel write callback. */ |
||
1981 |
✓✓✓✓ |
588 |
switch (jpeg_info -> gx_jpeg_output_color_format) |
1982 |
{ |
||
1983 |
156 |
case GX_COLOR_FORMAT_565RGB: |
|
1984 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
1985 |
jpeg_info -> gx_jpeg_pixel_write_helium = _gx_image_reader_jpeg_565rgb_pixel_write_helium; |
||
1986 |
#else |
||
1987 |
156 |
jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_565rgb_pixel_write; |
|
1988 |
#endif |
||
1989 |
156 |
jpeg_info -> gx_jpeg_output_bpp = 2; |
|
1990 |
156 |
jpeg_info -> gx_jpeg_output_stride <<= 1; |
|
1991 |
156 |
break; |
|
1992 |
|||
1993 |
10 |
case GX_COLOR_FORMAT_1555XRGB: |
|
1994 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
1995 |
jpeg_info -> gx_jpeg_pixel_write_helium = _gx_image_reader_jpeg_1555xrgb_pixel_write_helium; |
||
1996 |
#else |
||
1997 |
10 |
jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_1555xrgb_pixel_write; |
|
1998 |
#endif |
||
1999 |
10 |
jpeg_info -> gx_jpeg_output_bpp = 2; |
|
2000 |
10 |
jpeg_info -> gx_jpeg_output_stride <<= 1; |
|
2001 |
10 |
break; |
|
2002 |
|||
2003 |
194 |
case GX_COLOR_FORMAT_32ARGB: |
|
2004 |
case GX_COLOR_FORMAT_24XRGB: |
||
2005 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
2006 |
jpeg_info -> gx_jpeg_pixel_write_helium = _gx_image_reader_jpeg_24xrgb_pixel_write_helium; |
||
2007 |
#else |
||
2008 |
194 |
jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_24xrgb_pixel_write; |
|
2009 |
#endif |
||
2010 |
194 |
jpeg_info -> gx_jpeg_output_bpp = 4; |
|
2011 |
194 |
jpeg_info -> gx_jpeg_output_stride <<= 2; |
|
2012 |
194 |
break; |
|
2013 |
|||
2014 |
228 |
case GX_IMAGE_FORMAT_24BPP: |
|
2015 |
default: |
||
2016 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
2017 |
jpeg_info -> gx_jpeg_pixel_write_helium = _gx_image_reader_jpeg_24bpp_pixel_write_helium; |
||
2018 |
#else |
||
2019 |
228 |
jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_24bpp_pixel_write; |
|
2020 |
#endif |
||
2021 |
228 |
jpeg_info -> gx_jpeg_output_bpp = 3; |
|
2022 |
228 |
jpeg_info -> gx_jpeg_output_stride = (jpeg_info -> gx_jpeg_output_width * 3); |
|
2023 |
228 |
jpeg_info -> gx_jpeg_output_color_format = GX_IMAGE_FORMAT_24BPP; |
|
2024 |
|||
2025 |
✓✓ | 228 |
if (jpeg_info -> gx_jpeg_output_buffer) |
2026 |
{ |
||
2027 |
60 |
return GX_NOT_SUPPORTED; |
|
2028 |
} |
||
2029 |
168 |
break; |
|
2030 |
} |
||
2031 |
|||
2032 |
✓✓ | 528 |
if (!jpeg_info -> gx_jpeg_output_buffer) |
2033 |
{ |
||
2034 |
219 |
jpeg_info -> gx_jpeg_output_buffer = (GX_UBYTE *)_gx_system_memory_allocator((ULONG)(jpeg_info -> gx_jpeg_height * jpeg_info -> gx_jpeg_width * jpeg_info -> gx_jpeg_output_bpp)); |
|
2035 |
✓✓ | 219 |
if (!jpeg_info -> gx_jpeg_output_buffer) |
2036 |
{ |
||
2037 |
1 |
return GX_SYSTEM_MEMORY_ERROR; |
|
2038 |
} |
||
2039 |
} |
||
2040 |
|||
2041 |
527 |
return GX_SUCCESS; |
|
2042 |
} |
||
2043 |
|||
2044 |
/**************************************************************************/ |
||
2045 |
/* */ |
||
2046 |
/* FUNCTION RELEASE */ |
||
2047 |
/* */ |
||
2048 |
/* _gx_image_reader_jpeg_one_mcu_write PORTABLE C */ |
||
2049 |
/* 6.3.0 */ |
||
2050 |
/* AUTHOR */ |
||
2051 |
/* */ |
||
2052 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
2053 |
/* */ |
||
2054 |
/* DESCRIPTION */ |
||
2055 |
/* */ |
||
2056 |
/* Write decoded data of one MCU block into specified memory. */ |
||
2057 |
/* */ |
||
2058 |
/* INPUT */ |
||
2059 |
/* */ |
||
2060 |
/* jpeg_info JPEG control block */ |
||
2061 |
/* xpos X position in image */ |
||
2062 |
/* ypos y position in image */ |
||
2063 |
/* h Horizontal sampling factor */ |
||
2064 |
/* v Vertical sampling factor */ |
||
2065 |
/* */ |
||
2066 |
/* OUTPUT */ |
||
2067 |
/* */ |
||
2068 |
/* Status Code */ |
||
2069 |
/* */ |
||
2070 |
/* CALLS */ |
||
2071 |
/* */ |
||
2072 |
/* vldrbq_gather_offset_s8 Gather bytes from memory */ |
||
2073 |
/* GX_JPEG_DECODE_YCBCR2RGB_HELIUM Convert YCbCr to RGB */ |
||
2074 |
/* GX_JPEG_DECODE_YCBCR2RGB Convert YCbCr to RGB */ |
||
2075 |
/* [gx_jpeg_pixel_write_helium] Write pixel to memory */ |
||
2076 |
/* [gx_jpeg_pixel_write] Write pixel to memory */ |
||
2077 |
/* */ |
||
2078 |
/* CALLED BY */ |
||
2079 |
/* */ |
||
2080 |
/* _gx_image_reader_jpeg_decode */ |
||
2081 |
/* */ |
||
2082 |
/* RELEASE HISTORY */ |
||
2083 |
/* */ |
||
2084 |
/* DATE NAME DESCRIPTION */ |
||
2085 |
/* */ |
||
2086 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
2087 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
2088 |
/* resulting in version 6.1 */ |
||
2089 |
/* 10-31-2023 Ting Zhu Modified comment(s), */ |
||
2090 |
/* added Helium support, */ |
||
2091 |
/* added partial canvas buffer */ |
||
2092 |
/* support, */ |
||
2093 |
/* resulting in version 6.3.0 */ |
||
2094 |
/* */ |
||
2095 |
/**************************************************************************/ |
||
2096 |
126089 |
static UINT _gx_image_reader_jpeg_one_mcu_write(GX_JPEG_INFO *jpeg_info, INT xpos, INT ypos, INT h, INT v) |
|
2097 |
{ |
||
2098 |
GX_UBYTE *put; |
||
2099 |
INT x; |
||
2100 |
INT y; |
||
2101 |
INT coff; |
||
2102 |
126089 |
INT xstart = 0; |
|
2103 |
INT xend; |
||
2104 |
126089 |
INT ystart = 0; |
|
2105 |
INT yend; |
||
2106 |
|||
2107 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
2108 |
int8x16_t vY; |
||
2109 |
int8x16_t vCb; |
||
2110 |
int8x16_t vCr; |
||
2111 |
GX_UBYTE size; |
||
2112 |
uint8x16_t vred; |
||
2113 |
uint8x16_t vgreen; |
||
2114 |
uint8x16_t vblue; |
||
2115 |
GX_UBYTE index; |
||
2116 |
#else |
||
2117 |
GX_BYTE Y; |
||
2118 |
GX_BYTE Cb; |
||
2119 |
GX_BYTE Cr; |
||
2120 |
INT red; |
||
2121 |
INT green; |
||
2122 |
INT blue; |
||
2123 |
#endif |
||
2124 |
|||
2125 |
126089 |
yend = (v << 3); |
|
2126 |
126089 |
xend = (h << 3); |
|
2127 |
|||
2128 |
|||
2129 |
✓✓ | 126089 |
if (xpos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left) |
2130 |
{ |
||
2131 |
409 |
xstart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left - xpos; |
|
2132 |
} |
||
2133 |
|||
2134 |
✓✓ | 126089 |
if (xpos + xend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right + 1) |
2135 |
{ |
||
2136 |
26704 |
xend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right + 1 - xpos; |
|
2137 |
} |
||
2138 |
|||
2139 |
✓✓ | 126089 |
if (ypos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top) |
2140 |
{ |
||
2141 |
589 |
ystart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top - ypos; |
|
2142 |
} |
||
2143 |
|||
2144 |
✓✓ | 126089 |
if (ypos + yend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom + 1) |
2145 |
{ |
||
2146 |
20149 |
yend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom + 1 - ypos; |
|
2147 |
} |
||
2148 |
|||
2149 |
126089 |
put = (GX_UBYTE *)jpeg_info -> gx_jpeg_output_buffer; |
|
2150 |
#if defined(GX_ENABLE_CANVAS_PARTIAL_FRAME_BUFFER) |
||
2151 |
put += (ypos + ystart - jpeg_info -> gx_jpeg_output_buffer_offset_y) * jpeg_info -> gx_jpeg_output_stride; |
||
2152 |
put += (xpos + xstart - jpeg_info -> gx_jpeg_output_buffer_offset_x) * jpeg_info -> gx_jpeg_output_bpp; |
||
2153 |
#else |
||
2154 |
126089 |
put += (ypos + ystart) * jpeg_info -> gx_jpeg_output_stride; |
|
2155 |
126089 |
put += (xpos + xstart) * jpeg_info -> gx_jpeg_output_bpp; |
|
2156 |
#endif |
||
2157 |
|||
2158 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
2159 |
index = (h == 1 ? 0 : (h - 1 + (xstart % h))); |
||
2160 |
#endif |
||
2161 |
|||
2162 |
✓✓ | 1323405 |
for (y = ystart; y < yend; y++) |
2163 |
{ |
||
2164 |
1197316 |
jpeg_info -> gx_jpeg_putdata = put; |
|
2165 |
|||
2166 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
2167 |
for (x = xstart; x < xend; x += size) |
||
2168 |
{ |
||
2169 |
size = xend - x; |
||
2170 |
|||
2171 |
if (size > 16) |
||
2172 |
{ |
||
2173 |
size = 16; |
||
2174 |
} |
||
2175 |
|||
2176 |
coff = x / h + ((y / v) << 3); |
||
2177 |
|||
2178 |
vY = vldrbq_s8(jpeg_info -> gx_jpeg_Y_block + x + y * h * 8); |
||
2179 |
vCb = vldrbq_gather_offset_s8(jpeg_info -> gx_jpeg_Cb_block + coff, _gx_jpeg_cbcr_offset_table[index]); |
||
2180 |
vCr = vldrbq_gather_offset_s8(jpeg_info -> gx_jpeg_Cr_block + coff, _gx_jpeg_cbcr_offset_table[index]); |
||
2181 |
|||
2182 |
/* Convert YCbCr to RGB. */ |
||
2183 |
GX_JPEG_DECODE_YCBCR2RGB_HELIUM(vred, vgreen, vblue, vY, vCb, vCr); |
||
2184 |
|||
2185 |
jpeg_info -> gx_jpeg_pixel_write_helium(jpeg_info, vred, vgreen, vblue, size); |
||
2186 |
} |
||
2187 |
#else |
||
2188 |
✓✓ | 15541564 |
for (x = xstart; x < xend; x++) |
2189 |
{ |
||
2190 |
14344248 |
coff = x / h + ((y / v) << 3); |
|
2191 |
|||
2192 |
14344248 |
Y = jpeg_info -> gx_jpeg_Y_block[x + y * h * 8]; |
|
2193 |
14344248 |
Cb = jpeg_info -> gx_jpeg_Cb_block[coff]; |
|
2194 |
14344248 |
Cr = jpeg_info -> gx_jpeg_Cr_block[coff]; |
|
2195 |
|||
2196 |
14344248 |
GX_JPEG_DECODE_YCBCR2RGB(red, green, blue, Y, Cb, Cr); |
|
2197 |
|||
2198 |
✓✓✓✓ |
14344248 |
GX_SATURATE_TO_UBYTE(red, red); |
2199 |
✓✓✓✓ |
14344248 |
GX_SATURATE_TO_UBYTE(green, green); |
2200 |
✓✓✓✓ |
14344248 |
GX_SATURATE_TO_UBYTE(blue, blue); |
2201 |
|||
2202 |
14344248 |
jpeg_info -> gx_jpeg_pixel_write(jpeg_info, (GX_UBYTE)red, (GX_UBYTE)green, (GX_UBYTE)blue); |
|
2203 |
} |
||
2204 |
#endif |
||
2205 |
|||
2206 |
1197316 |
put += jpeg_info -> gx_jpeg_output_stride; |
|
2207 |
} |
||
2208 |
|||
2209 |
126089 |
return GX_SUCCESS; |
|
2210 |
} |
||
2211 |
|||
2212 |
/**************************************************************************/ |
||
2213 |
/* */ |
||
2214 |
/* FUNCTION RELEASE */ |
||
2215 |
/* */ |
||
2216 |
/* _gx_image_reader_jpeg_one_mcu_rotated_write PORTABLE C */ |
||
2217 |
/* 6.3.0 */ |
||
2218 |
/* AUTHOR */ |
||
2219 |
/* */ |
||
2220 |
/* Ting Zhu, Microsoft Corporation */ |
||
2221 |
/* */ |
||
2222 |
/* DESCRIPTION */ |
||
2223 |
/* */ |
||
2224 |
/* Write decoded data of one MCU block into specified memory. */ |
||
2225 |
/* */ |
||
2226 |
/* INPUT */ |
||
2227 |
/* */ |
||
2228 |
/* jpeg_info JPEG control block */ |
||
2229 |
/* xpos X position in image */ |
||
2230 |
/* ypos y position in image */ |
||
2231 |
/* h Horizontal sampling factor */ |
||
2232 |
/* v Vertical sampling factor */ |
||
2233 |
/* */ |
||
2234 |
/* OUTPUT */ |
||
2235 |
/* */ |
||
2236 |
/* Status Code */ |
||
2237 |
/* */ |
||
2238 |
/* CALLS */ |
||
2239 |
/* */ |
||
2240 |
/* vldrbq_gather_offset_s8 Gather bytes from memory */ |
||
2241 |
/* GX_JPEG_DECODE_YCBCR2RGB_HELIUM Convert YCbCr to RGB */ |
||
2242 |
/* GX_JPEG_DECODE_YCBCR2RGB Convert YCbCr to RGB */ |
||
2243 |
/* [gx_jpeg_pixel_write_helium] Write pixel to memory */ |
||
2244 |
/* [gx_jpeg_pixel_write] Write pixel to memory */ |
||
2245 |
/* */ |
||
2246 |
/* CALLED BY */ |
||
2247 |
/* */ |
||
2248 |
/* _gx_image_reader_jpeg_decode */ |
||
2249 |
/* */ |
||
2250 |
/* RELEASE HISTORY */ |
||
2251 |
/* */ |
||
2252 |
/* DATE NAME DESCRIPTION */ |
||
2253 |
/* */ |
||
2254 |
/* 10-31-2023 Ting Zhu Initial Version 6.3.0 */ |
||
2255 |
/* */ |
||
2256 |
/**************************************************************************/ |
||
2257 |
155006 |
static UINT _gx_image_reader_jpeg_one_mcu_rotated_write(GX_JPEG_INFO *jpeg_info, INT xpos, INT ypos, INT h, INT v) |
|
2258 |
{ |
||
2259 |
GX_UBYTE *put; |
||
2260 |
INT x; |
||
2261 |
INT coff; |
||
2262 |
155006 |
INT xstart = 0; |
|
2263 |
INT xend; |
||
2264 |
155006 |
INT ystart = 0; |
|
2265 |
INT yend; |
||
2266 |
INT stride; |
||
2267 |
|||
2268 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
2269 |
int8x16_t vY; |
||
2270 |
int8x16_t vCb; |
||
2271 |
int8x16_t vCr; |
||
2272 |
uint8x16_t vred; |
||
2273 |
uint8x16_t vgreen; |
||
2274 |
uint8x16_t vblue; |
||
2275 |
INT size; |
||
2276 |
GX_UBYTE index; |
||
2277 |
uint8x16_t yoffset; |
||
2278 |
uint8x16_t cbcroffset; |
||
2279 |
#else |
||
2280 |
GX_BYTE Y; |
||
2281 |
GX_BYTE Cb; |
||
2282 |
GX_BYTE Cr; |
||
2283 |
INT red; |
||
2284 |
INT green; |
||
2285 |
INT blue; |
||
2286 |
INT y; |
||
2287 |
155006 |
GX_BYTE sign = 1; |
|
2288 |
#endif |
||
2289 |
|||
2290 |
155006 |
xend = (h << 3) - 1; |
|
2291 |
155006 |
yend = (v << 3) - 1; |
|
2292 |
|||
2293 |
✓✓ | 155006 |
if (xpos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left) |
2294 |
{ |
||
2295 |
21404 |
xstart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left - xpos; |
|
2296 |
} |
||
2297 |
|||
2298 |
✓✓ | 155006 |
if (xpos + xend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right) |
2299 |
{ |
||
2300 |
24590 |
xend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right - xpos; |
|
2301 |
} |
||
2302 |
|||
2303 |
✓✓ | 155006 |
if (xstart > xend) |
2304 |
{ |
||
2305 |
38648 |
return GX_SUCCESS; |
|
2306 |
} |
||
2307 |
|||
2308 |
✓✓ | 116358 |
if (ypos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top) |
2309 |
{ |
||
2310 |
11111 |
ystart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top - ypos; |
|
2311 |
} |
||
2312 |
|||
2313 |
✓✓ | 116358 |
if (ypos + yend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom) |
2314 |
{ |
||
2315 |
13773 |
yend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom - ypos; |
|
2316 |
} |
||
2317 |
|||
2318 |
✓✓ | 116358 |
if (ystart > yend) |
2319 |
{ |
||
2320 |
17589 |
return GX_SUCCESS; |
|
2321 |
} |
||
2322 |
|||
2323 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
2324 |
size = yend - ystart + 1; |
||
2325 |
#endif |
||
2326 |
|||
2327 |
98769 |
stride = jpeg_info -> gx_jpeg_output_stride; |
|
2328 |
98769 |
put = (GX_UBYTE *)jpeg_info -> gx_jpeg_output_buffer; |
|
2329 |
|||
2330 |
✓✓ | 98769 |
if (jpeg_info -> gx_jpeg_output_rotation_angle == GX_SCREEN_ROTATION_CW) |
2331 |
{ |
||
2332 |
66192 |
put += (jpeg_info -> gx_jpeg_output_width - xpos - 1 - xstart) * stride; |
|
2333 |
66192 |
put += (ypos + ystart) * jpeg_info -> gx_jpeg_output_bpp; |
|
2334 |
66192 |
stride = (-stride); |
|
2335 |
} |
||
2336 |
else |
||
2337 |
{ |
||
2338 |
32577 |
put += (xpos + xstart) * stride; |
|
2339 |
32577 |
put += (jpeg_info -> gx_jpeg_output_height - ypos - 1 - yend) * jpeg_info -> gx_jpeg_output_bpp; |
|
2340 |
|||
2341 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
2342 |
ystart = (v << 3) - 1 - yend; |
||
2343 |
#else |
||
2344 |
32577 |
GX_SWAP_VALS(ystart, yend); |
|
2345 |
32577 |
sign = -1; |
|
2346 |
#endif |
||
2347 |
} |
||
2348 |
|||
2349 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
2350 |
if (jpeg_info -> gx_jpeg_output_rotation_angle == GX_SCREEN_ROTATION_CW) |
||
2351 |
{ |
||
2352 |
index = (v == 2 ? (1 + (ystart % 2)) : 0); |
||
2353 |
|||
2354 |
yoffset = _gx_jpeg_y_offset_rotated_table_cw[h >> 1]; |
||
2355 |
cbcroffset = _gx_jpeg_cbcr_offset_rotated_table_cw[index]; |
||
2356 |
} |
||
2357 |
else |
||
2358 |
{ |
||
2359 |
yoffset = _gx_jpeg_y_offset_rotated_table_ccw[h + v - 2]; |
||
2360 |
cbcroffset = _gx_jpeg_cbcr_offset_rotated_table_ccw[v - 1]; |
||
2361 |
|||
2362 |
if(ystart) |
||
2363 |
{ |
||
2364 |
for (x = 0; x < 16 - ystart; x++) |
||
2365 |
{ |
||
2366 |
yoffset[x] = yoffset[ystart + x]; |
||
2367 |
cbcroffset[x] = cbcroffset[ystart + x]; |
||
2368 |
} |
||
2369 |
|||
2370 |
ystart = 0; |
||
2371 |
} |
||
2372 |
} |
||
2373 |
#endif |
||
2374 |
|||
2375 |
✓✓ | 1498068 |
for (x = xstart; x <= xend; x++) |
2376 |
{ |
||
2377 |
1399299 |
jpeg_info -> gx_jpeg_putdata = put; |
|
2378 |
|||
2379 |
#if defined(GX_ENABLE_ARM_HELIUM) |
||
2380 |
coff = x / h + ((ystart / v) << 3); |
||
2381 |
|||
2382 |
vY = vldrbq_gather_offset_s8(jpeg_info -> gx_jpeg_Y_block + x + ystart * h * 8, yoffset); |
||
2383 |
vCb = vldrbq_gather_offset_s8(jpeg_info -> gx_jpeg_Cb_block + coff, cbcroffset); |
||
2384 |
vCr = vldrbq_gather_offset_s8(jpeg_info -> gx_jpeg_Cr_block + coff, cbcroffset); |
||
2385 |
|||
2386 |
/* Convert YCbCr to RGB. */ |
||
2387 |
GX_JPEG_DECODE_YCBCR2RGB_HELIUM(vred, vgreen, vblue, vY, vCb, vCr); |
||
2388 |
|||
2389 |
jpeg_info -> gx_jpeg_pixel_write_helium(jpeg_info, vred, vgreen, vblue, size); |
||
2390 |
|||
2391 |
#else |
||
2392 |
✓✓ | 17160539 |
for (y = ystart; y != yend + sign; y += sign) |
2393 |
{ |
||
2394 |
15761240 |
coff = x / h + ((y / v) << 3); |
|
2395 |
|||
2396 |
15761240 |
Y = jpeg_info -> gx_jpeg_Y_block[x + y * h * 8]; |
|
2397 |
15761240 |
Cb = jpeg_info -> gx_jpeg_Cb_block[coff]; |
|
2398 |
15761240 |
Cr = jpeg_info -> gx_jpeg_Cr_block[coff]; |
|
2399 |
|||
2400 |
15761240 |
GX_JPEG_DECODE_YCBCR2RGB(red, green, blue, Y, Cb, Cr); |
|
2401 |
|||
2402 |
✓✓✓✓ |
15761240 |
GX_SATURATE_TO_UBYTE(red, red); |
2403 |
✓✓✓✓ |
15761240 |
GX_SATURATE_TO_UBYTE(green, green); |
2404 |
✓✓✓✓ |
15761240 |
GX_SATURATE_TO_UBYTE(blue, blue); |
2405 |
|||
2406 |
15761240 |
jpeg_info -> gx_jpeg_pixel_write(jpeg_info, (GX_UBYTE)red, (GX_UBYTE)green, (GX_UBYTE)blue); |
|
2407 |
} |
||
2408 |
#endif |
||
2409 |
1399299 |
put += stride; |
|
2410 |
} |
||
2411 |
|||
2412 |
98769 |
return GX_SUCCESS; |
|
2413 |
} |
||
2414 |
|||
2415 |
/**************************************************************************/ |
||
2416 |
/* */ |
||
2417 |
/* FUNCTION RELEASE */ |
||
2418 |
/* */ |
||
2419 |
/* _gx_image_reader_jpeg_decompress PORTABLE C */ |
||
2420 |
/* 6.3.0 */ |
||
2421 |
/* AUTHOR */ |
||
2422 |
/* */ |
||
2423 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
2424 |
/* */ |
||
2425 |
/* DESCRIPTION */ |
||
2426 |
/* */ |
||
2427 |
/* Decompress JPG data stream. */ |
||
2428 |
/* */ |
||
2429 |
/* INPUT */ |
||
2430 |
/* */ |
||
2431 |
/* jpeg_info JPEG control block */ |
||
2432 |
/* */ |
||
2433 |
/* OUTPUT */ |
||
2434 |
/* */ |
||
2435 |
/* Status Code */ |
||
2436 |
/* */ |
||
2437 |
/* CALLS */ |
||
2438 |
/* */ |
||
2439 |
/* _gx_image_reader_jpeg_one_block_decode */ |
||
2440 |
/* Decode one blcok of jpeg data */ |
||
2441 |
/* _gx_image_reader_jpeg_one_mcu_write Write decoded data to */ |
||
2442 |
/* specified memory */ |
||
2443 |
/* */ |
||
2444 |
/* CALLED BY */ |
||
2445 |
/* */ |
||
2446 |
/* _gx_image_reader_jpeg_decode */ |
||
2447 |
/* */ |
||
2448 |
/* RELEASE HISTORY */ |
||
2449 |
/* */ |
||
2450 |
/* DATE NAME DESCRIPTION */ |
||
2451 |
/* */ |
||
2452 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
2453 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
2454 |
/* resulting in version 6.1 */ |
||
2455 |
/* 10-31-2022 Kenneth Maxwell Modified comment(s), */ |
||
2456 |
/* abort if block decode fails,*/ |
||
2457 |
/* resulting in version 6.2.0 */ |
||
2458 |
/* 10-31-2023 Ting Zhu Modified comment(s), */ |
||
2459 |
/* improved logic, */ |
||
2460 |
/* resulting in version 6.3.0 */ |
||
2461 |
/* */ |
||
2462 |
/**************************************************************************/ |
||
2463 |
588 |
static UINT _gx_image_reader_jpeg_decompress(GX_JPEG_INFO *jpeg_info) |
|
2464 |
{ |
||
2465 |
int h; |
||
2466 |
int v; |
||
2467 |
int x; |
||
2468 |
int y; |
||
2469 |
int xx; |
||
2470 |
int yy; |
||
2471 |
588 |
UINT status = GX_SUCCESS; |
|
2472 |
UINT (*one_mcu_write)(GX_JPEG_INFO *jpeg_info, INT xpos, INT ypos, INT h, INT v); |
||
2473 |
|||
2474 |
588 |
h = (jpeg_info -> gx_jpeg_sample_factor[0] >> 4); |
|
2475 |
588 |
v = (jpeg_info -> gx_jpeg_sample_factor[0] & 0x0f); |
|
2476 |
|||
2477 |
✗✓ | 588 |
if (v > 2) |
2478 |
{ |
||
2479 |
return GX_INVALID_FORMAT; |
||
2480 |
} |
||
2481 |
|||
2482 |
588 |
status = _gx_image_reader_jpeg_pixel_write_info_set(jpeg_info); |
|
2483 |
|||
2484 |
✓✓ | 588 |
if ((jpeg_info -> gx_jpeg_output_rotation_angle != 0) && |
2485 |
✓✓ | 270 |
(jpeg_info -> gx_jpeg_output_color_format != GX_IMAGE_FORMAT_24BPP)) |
2486 |
{ |
||
2487 |
210 |
one_mcu_write = _gx_image_reader_jpeg_one_mcu_rotated_write; |
|
2488 |
} |
||
2489 |
else |
||
2490 |
{ |
||
2491 |
378 |
one_mcu_write = _gx_image_reader_jpeg_one_mcu_write; |
|
2492 |
} |
||
2493 |
|||
2494 |
✓✓ | 11554 |
for (y = 0; y < jpeg_info -> gx_jpeg_height; y += 8 * v) |
2495 |
{ |
||
2496 |
✓✓ | 315912 |
for (x = 0; x < jpeg_info -> gx_jpeg_width; x += 8 * h) |
2497 |
{ |
||
2498 |
/* Decode one MCU */ |
||
2499 |
✓✓✓✓ |
732038 |
for (yy = 0; yy < v && status == GX_SUCCESS; yy++) |
2500 |
{ |
||
2501 |
✓✓✓✗ |
1244728 |
for (xx = 0; xx < h && status == GX_SUCCESS; xx++) |
2502 |
{ |
||
2503 |
/* Y */ |
||
2504 |
817636 |
status = _gx_image_reader_jpeg_one_block_decode(jpeg_info, 0, jpeg_info -> gx_jpeg_Y_block + yy * 128 + xx * 8); |
|
2505 |
} |
||
2506 |
} |
||
2507 |
|||
2508 |
✓✓✓✓ |
304946 |
if (status == GX_SUCCESS && jpeg_info -> gx_jpeg_num_of_components > 1) |
2509 |
{ |
||
2510 |
/* Cb */ |
||
2511 |
281091 |
status = _gx_image_reader_jpeg_one_block_decode(jpeg_info, 1, jpeg_info -> gx_jpeg_Cb_block); |
|
2512 |
|||
2513 |
/* Cr */ |
||
2514 |
✓✗ | 281091 |
if (status == GX_SUCCESS) |
2515 |
{ |
||
2516 |
281091 |
status = _gx_image_reader_jpeg_one_block_decode(jpeg_info, 2, jpeg_info -> gx_jpeg_Cr_block); |
|
2517 |
} |
||
2518 |
} |
||
2519 |
|||
2520 |
✓✓ | 304946 |
if (status == GX_SUCCESS) |
2521 |
{ |
||
2522 |
281095 |
one_mcu_write(jpeg_info, jpeg_info -> gx_jpeg_output_xpos + x, jpeg_info -> gx_jpeg_output_ypos + y, h, v); |
|
2523 |
} |
||
2524 |
} |
||
2525 |
} |
||
2526 |
|||
2527 |
588 |
return status; |
|
2528 |
} |
||
2529 |
|||
2530 |
/**************************************************************************/ |
||
2531 |
/* */ |
||
2532 |
/* FUNCTION RELEASE */ |
||
2533 |
/* */ |
||
2534 |
/* _gx_image_reader_jpeg_decode_blocks PORTABLE C */ |
||
2535 |
/* 6.3.0 */ |
||
2536 |
/* AUTHOR */ |
||
2537 |
/* */ |
||
2538 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
2539 |
/* */ |
||
2540 |
/* DESCRIPTION */ |
||
2541 |
/* */ |
||
2542 |
/* This function decode a jpg format image. */ |
||
2543 |
/* */ |
||
2544 |
/* INPUT */ |
||
2545 |
/* */ |
||
2546 |
/* jpeg_info Jpeg decode control block */ |
||
2547 |
/* */ |
||
2548 |
/* OUTPUT */ |
||
2549 |
/* */ |
||
2550 |
/* status Completion status */ |
||
2551 |
/* */ |
||
2552 |
/* CALLS */ |
||
2553 |
/* */ |
||
2554 |
/* _gx_image_reader_jpeg_quantization_table_set */ |
||
2555 |
/* Set jpeg quantization table */ |
||
2556 |
/* _gx_image_reader_jpeg_frame_header_read */ |
||
2557 |
/* Read frame header information */ |
||
2558 |
/* _gx_image_reader_huffman_table_set Set up huffman table */ |
||
2559 |
/* _gx_image_reader_jpeg_scan_header_read */ |
||
2560 |
/* Read scan header information */ |
||
2561 |
/* _gx_image_reader_jpeg_decompress Decompress jped data stream */ |
||
2562 |
/* _gx_system_memory_free Application defined memory */ |
||
2563 |
/* free function */ |
||
2564 |
/* */ |
||
2565 |
/* CALLED BY */ |
||
2566 |
/* */ |
||
2567 |
/* _gx_image_reader_jpeg_decode */ |
||
2568 |
/* _gx_image_reader_jpeg_mcu_decode */ |
||
2569 |
/* */ |
||
2570 |
/* RELEASE HISTORY */ |
||
2571 |
/* */ |
||
2572 |
/* DATE NAME DESCRIPTION */ |
||
2573 |
/* */ |
||
2574 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
2575 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
2576 |
/* resulting in version 6.1 */ |
||
2577 |
/* 10-31-2023 Ting Zhu Modified comment(s), removed */ |
||
2578 |
/* huffman table free logic, */ |
||
2579 |
/* resulting in version 6.3.0 */ |
||
2580 |
/* */ |
||
2581 |
/**************************************************************************/ |
||
2582 |
596 |
static UINT _gx_image_reader_jpeg_decode_blocks(GX_JPEG_INFO *jpeg_info) |
|
2583 |
{ |
||
2584 |
GX_UBYTE *jpeg_data; |
||
2585 |
GX_UBYTE marker; |
||
2586 |
UINT segment_len; |
||
2587 |
596 |
UINT status = GX_SUCCESS; |
|
2588 |
|||
2589 |
✓✓✓✓ |
596 |
if (jpeg_info -> gx_jpeg_data == GX_NULL || jpeg_info -> gx_jpeg_data_size < 10) |
2590 |
{ |
||
2591 |
2 |
return GX_INVALID_VALUE; |
|
2592 |
} |
||
2593 |
|||
2594 |
594 |
jpeg_data = jpeg_info -> gx_jpeg_data; |
|
2595 |
|||
2596 |
/* Read JPEG File flag that mark the start of a JPEG image. */ |
||
2597 |
✓✓✓✓ |
594 |
if ((*jpeg_data++ != 0xff) || (*jpeg_data++ != 0xd8)) |
2598 |
{ |
||
2599 |
2 |
return GX_INVALID_FORMAT; /*Not a jpeg file */ |
|
2600 |
} |
||
2601 |
|||
2602 |
592 |
jpeg_info -> gx_jpeg_data_index += 2; |
|
2603 |
|||
2604 |
✓✓✓✓ |
19376 |
while ((jpeg_info -> gx_jpeg_data_index + 3 < jpeg_info -> gx_jpeg_data_size) && |
2605 |
(status == GX_SUCCESS)) |
||
2606 |
{ |
||
2607 |
18785 |
jpeg_data = (jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index); |
|
2608 |
18785 |
marker = *(jpeg_data + 1); |
|
2609 |
|||
2610 |
✓✓✓✓ ✓✓ |
18785 |
if ((*jpeg_data == 0xff) && (marker != 0) && (marker != 0xff)) |
2611 |
{ |
||
2612 |
4221 |
jpeg_data += 2; |
|
2613 |
4221 |
jpeg_info -> gx_jpeg_data_index += 2; |
|
2614 |
|||
2615 |
/* Read WORD length */ |
||
2616 |
4221 |
segment_len = *(jpeg_data); |
|
2617 |
4221 |
segment_len <<= 8; |
|
2618 |
4221 |
segment_len |= *(jpeg_data + 1); |
|
2619 |
|||
2620 |
✓✓ | 4221 |
if ((UINT)jpeg_info -> gx_jpeg_data_index + segment_len > (UINT)jpeg_info -> gx_jpeg_data_size) |
2621 |
{ |
||
2622 |
/* Invalid data size. */ |
||
2623 |
1 |
status = GX_FAILURE; |
|
2624 |
1 |
break; |
|
2625 |
} |
||
2626 |
|||
2627 |
✓✓✓✓ ✓✓ |
4220 |
switch (marker) |
2628 |
{ |
||
2629 |
842 |
case 0xdb: |
|
2630 |
/* Define Quantization Table */ |
||
2631 |
842 |
status = _gx_image_reader_jpeg_quantization_table_set(jpeg_info, segment_len); |
|
2632 |
842 |
break; |
|
2633 |
|||
2634 |
590 |
case 0xc0: |
|
2635 |
/* Start of Frame */ |
||
2636 |
590 |
status = _gx_image_reader_jpeg_frame_header_read(jpeg_info, segment_len); |
|
2637 |
590 |
break; |
|
2638 |
|||
2639 |
1335 |
case 0xc4: |
|
2640 |
/* Define Huffman Table */ |
||
2641 |
1335 |
status = _gx_image_reader_huffman_table_set(jpeg_info, segment_len); |
|
2642 |
1335 |
break; |
|
2643 |
|||
2644 |
7 |
case 0xdd: |
|
2645 |
/* Read restart interval which specifies the number of MCU in restart interval. */ |
||
2646 |
7 |
jpeg_data += 2; |
|
2647 |
7 |
jpeg_info -> gx_jpeg_restart_interval = *jpeg_data++; |
|
2648 |
7 |
jpeg_info -> gx_jpeg_restart_interval <<= 8; |
|
2649 |
7 |
jpeg_info -> gx_jpeg_restart_interval |= *jpeg_data++; |
|
2650 |
7 |
jpeg_info -> gx_jpeg_data_index += (INT)segment_len; |
|
2651 |
7 |
break; |
|
2652 |
|||
2653 |
588 |
case 0xda: |
|
2654 |
/* Start of Scan, stores which Huffman tables are associated with which components |
||
2655 |
The program start decoding the data section directly after it reads in this header. */ |
||
2656 |
588 |
_gx_image_reader_jpeg_scan_header_read(jpeg_info, segment_len); |
|
2657 |
|||
2658 |
/* Start decoding jpeg data stream. */ |
||
2659 |
588 |
status = _gx_image_reader_jpeg_decompress(jpeg_info); |
|
2660 |
588 |
break; |
|
2661 |
|||
2662 |
858 |
default: |
|
2663 |
/* Unkown marker, skip */ |
||
2664 |
858 |
jpeg_info -> gx_jpeg_data_index += (INT)segment_len; |
|
2665 |
858 |
break; |
|
2666 |
} |
||
2667 |
} |
||
2668 |
else |
||
2669 |
{ |
||
2670 |
14564 |
jpeg_info -> gx_jpeg_data_index++; |
|
2671 |
} |
||
2672 |
} |
||
2673 |
|||
2674 |
592 |
return status; |
|
2675 |
} |
||
2676 |
|||
2677 |
/**************************************************************************/ |
||
2678 |
/* */ |
||
2679 |
/* FUNCTION RELEASE */ |
||
2680 |
/* */ |
||
2681 |
/* _gx_image_reader_jpeg_decode PORTABLE C */ |
||
2682 |
/* 6.3.0 */ |
||
2683 |
/* AUTHOR */ |
||
2684 |
/* */ |
||
2685 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
2686 |
/* */ |
||
2687 |
/* DESCRIPTION */ |
||
2688 |
/* */ |
||
2689 |
/* This function decodes a jpg format image and saves the decoded data */ |
||
2690 |
/* to a GX_PIXELMAP structure. */ |
||
2691 |
/* */ |
||
2692 |
/* INPUT */ |
||
2693 |
/* */ |
||
2694 |
/* read_data Input JPEG data stream */ |
||
2695 |
/* data_size JPEG size in bytes */ |
||
2696 |
/* outmap Output pixelmap */ |
||
2697 |
/* */ |
||
2698 |
/* OUTPUT */ |
||
2699 |
/* */ |
||
2700 |
/* status Completion status */ |
||
2701 |
/* */ |
||
2702 |
/* CALLS */ |
||
2703 |
/* */ |
||
2704 |
/* _gx_image_reader_jpeg_decode_blocks Decode a jpeg format image */ |
||
2705 |
/* */ |
||
2706 |
/* CALLED BY */ |
||
2707 |
/* */ |
||
2708 |
/* _gx_image_reader_image_decode */ |
||
2709 |
/* */ |
||
2710 |
/* RELEASE HISTORY */ |
||
2711 |
/* */ |
||
2712 |
/* DATE NAME DESCRIPTION */ |
||
2713 |
/* */ |
||
2714 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
2715 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
2716 |
/* resulting in version 6.1 */ |
||
2717 |
/* 10-31-2023 Ting Zhu Modified comment(s), */ |
||
2718 |
/* improved logic, */ |
||
2719 |
/* resulting in version 6.3.0 */ |
||
2720 |
/* */ |
||
2721 |
/**************************************************************************/ |
||
2722 |
231 |
UINT _gx_image_reader_jpeg_decode(GX_IMAGE_READER *image_reader, GX_PIXELMAP *outmap) |
|
2723 |
{ |
||
2724 |
UINT status; |
||
2725 |
GX_JPEG_INFO *jpeg_info; |
||
2726 |
|||
2727 |
|||
2728 |
✓✓✓✓ |
231 |
if ((!_gx_system_memory_allocator) || (!_gx_system_memory_free)) |
2729 |
{ |
||
2730 |
2 |
return GX_SYSTEM_MEMORY_ERROR; |
|
2731 |
} |
||
2732 |
|||
2733 |
229 |
jpeg_info = (GX_JPEG_INFO *)_gx_system_memory_allocator(sizeof(GX_JPEG_INFO)); |
|
2734 |
|||
2735 |
✓✓ | 229 |
if (!jpeg_info) |
2736 |
{ |
||
2737 |
2 |
return GX_SYSTEM_MEMORY_ERROR; |
|
2738 |
} |
||
2739 |
|||
2740 |
227 |
memset(jpeg_info, 0, sizeof(GX_JPEG_INFO)); |
|
2741 |
|||
2742 |
|||
2743 |
227 |
jpeg_info -> gx_jpeg_data = (GX_UBYTE *)image_reader -> gx_image_reader_source_data; |
|
2744 |
227 |
jpeg_info -> gx_jpeg_data_size = (INT)image_reader -> gx_image_reader_source_data_size; |
|
2745 |
227 |
jpeg_info -> gx_jpeg_data_index = 0; |
|
2746 |
|||
2747 |
✓✓ | 227 |
if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_DITHER) |
2748 |
{ |
||
2749 |
92 |
jpeg_info -> gx_jpeg_output_color_format = GX_IMAGE_FORMAT_24BPP; |
|
2750 |
} |
||
2751 |
else |
||
2752 |
{ |
||
2753 |
135 |
jpeg_info -> gx_jpeg_output_color_format = image_reader -> gx_image_reader_color_format; |
|
2754 |
} |
||
2755 |
|||
2756 |
✗✓ | 227 |
if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ROTATE_CW) |
2757 |
{ |
||
2758 |
jpeg_info -> gx_jpeg_output_rotation_angle = GX_SCREEN_ROTATION_CW; |
||
2759 |
} |
||
2760 |
✗✓ | 227 |
else if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ROTATE_CCW) |
2761 |
{ |
||
2762 |
jpeg_info -> gx_jpeg_output_rotation_angle = GX_SCREEN_ROTATION_CCW; |
||
2763 |
} |
||
2764 |
|||
2765 |
227 |
status = _gx_image_reader_jpeg_decode_blocks(jpeg_info); |
|
2766 |
|||
2767 |
✓✓ | 227 |
if (status == GX_SUCCESS) |
2768 |
{ |
||
2769 |
218 |
outmap -> gx_pixelmap_data = jpeg_info -> gx_jpeg_output_buffer; |
|
2770 |
218 |
outmap -> gx_pixelmap_data_size = (ULONG)(jpeg_info -> gx_jpeg_output_stride * jpeg_info -> gx_jpeg_height); |
|
2771 |
218 |
outmap -> gx_pixelmap_width = (GX_VALUE)jpeg_info -> gx_jpeg_width; |
|
2772 |
218 |
outmap -> gx_pixelmap_height = (GX_VALUE)jpeg_info -> gx_jpeg_height; |
|
2773 |
218 |
outmap -> gx_pixelmap_flags = 0; |
|
2774 |
218 |
outmap -> gx_pixelmap_format = jpeg_info -> gx_jpeg_output_color_format; |
|
2775 |
} |
||
2776 |
|||
2777 |
227 |
_gx_system_memory_free((void *)jpeg_info); |
|
2778 |
|||
2779 |
227 |
return status; |
|
2780 |
} |
||
2781 |
|||
2782 |
/**************************************************************************/ |
||
2783 |
/* */ |
||
2784 |
/* FUNCTION RELEASE */ |
||
2785 |
/* */ |
||
2786 |
/* _gx_image_reader_jpeg_mcu_decode PORTABLE C */ |
||
2787 |
/* 6.3.0 */ |
||
2788 |
/* AUTHOR */ |
||
2789 |
/* */ |
||
2790 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
2791 |
/* */ |
||
2792 |
/* DESCRIPTION */ |
||
2793 |
/* */ |
||
2794 |
/* This function decodes a jpg format image and draw it to canvas */ |
||
2795 |
/* directly. */ |
||
2796 |
/* */ |
||
2797 |
/* INPUT */ |
||
2798 |
/* */ |
||
2799 |
/* read_data Input JPEG data */ |
||
2800 |
/* data_size JPEG size in bytes */ |
||
2801 |
/* context Drawing contex */ |
||
2802 |
/* xpos X-coord of draw start point in*/ |
||
2803 |
/* canvas */ |
||
2804 |
/* ypos Y-coord of draw start point in*/ |
||
2805 |
/* canvas */ |
||
2806 |
/* */ |
||
2807 |
/* OUTPUT */ |
||
2808 |
/* */ |
||
2809 |
/* status Completion status */ |
||
2810 |
/* */ |
||
2811 |
/* CALLS */ |
||
2812 |
/* */ |
||
2813 |
/* _gx_image_reader_jpeg_decode_blocks Decode a jpeg format image */ |
||
2814 |
/* */ |
||
2815 |
/* CALLED BY */ |
||
2816 |
/* */ |
||
2817 |
/* GUIX Internal Code */ |
||
2818 |
/* */ |
||
2819 |
/* RELEASE HISTORY */ |
||
2820 |
/* */ |
||
2821 |
/* DATE NAME DESCRIPTION */ |
||
2822 |
/* */ |
||
2823 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
2824 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
2825 |
/* resulting in version 6.1 */ |
||
2826 |
/* 10-31-2023 Ting Zhu Modified comment(s), */ |
||
2827 |
/* improved logic, */ |
||
2828 |
/* resulting in version 6.3.0 */ |
||
2829 |
/* */ |
||
2830 |
/**************************************************************************/ |
||
2831 |
403 |
UINT _gx_image_reader_jpeg_mcu_decode(GX_CONST GX_UBYTE *read_data, ULONG data_size, |
|
2832 |
GX_DRAW_CONTEXT *context, INT xpos, INT ypos) |
||
2833 |
{ |
||
2834 |
UINT status; |
||
2835 |
GX_JPEG_INFO *jpeg_info; |
||
2836 |
|||
2837 |
✓✓✓✓ |
403 |
if ((!_gx_system_memory_allocator) || (!_gx_system_memory_free)) |
2838 |
{ |
||
2839 |
22 |
return GX_SYSTEM_MEMORY_ERROR; |
|
2840 |
} |
||
2841 |
|||
2842 |
381 |
jpeg_info = (GX_JPEG_INFO *)_gx_system_memory_allocator(sizeof(GX_JPEG_INFO)); |
|
2843 |
|||
2844 |
✓✓ | 381 |
if (!jpeg_info) |
2845 |
{ |
||
2846 |
11 |
return GX_SYSTEM_MEMORY_ERROR; |
|
2847 |
} |
||
2848 |
|||
2849 |
✓✓ | 370 |
if (!context) |
2850 |
{ |
||
2851 |
1 |
return GX_INVALID_CONTEXT; |
|
2852 |
} |
||
2853 |
|||
2854 |
369 |
memset(jpeg_info, 0, sizeof(GX_JPEG_INFO)); |
|
2855 |
|||
2856 |
369 |
jpeg_info -> gx_jpeg_data = (GX_UBYTE *)read_data; |
|
2857 |
369 |
jpeg_info -> gx_jpeg_data_size = (INT)data_size; |
|
2858 |
369 |
jpeg_info -> gx_jpeg_data_index = 0; |
|
2859 |
369 |
jpeg_info -> gx_jpeg_output_xpos = xpos; |
|
2860 |
369 |
jpeg_info -> gx_jpeg_output_ypos = ypos; |
|
2861 |
369 |
jpeg_info -> gx_jpeg_output_color_format = context -> gx_draw_context_display -> gx_display_color_format; |
|
2862 |
369 |
jpeg_info -> gx_jpeg_output_rotation_angle = context -> gx_draw_context_display -> gx_display_rotation_angle; |
|
2863 |
369 |
jpeg_info -> gx_jpeg_output_buffer = (GX_UBYTE *)context -> gx_draw_context_memory; |
|
2864 |
#ifdef GX_ENABLE_CANVAS_PARTIAL_FRAME_BUFFER |
||
2865 |
jpeg_info -> gx_jpeg_output_width = (USHORT)context -> gx_draw_context_canvas -> gx_canvas_memory_width; |
||
2866 |
jpeg_info -> gx_jpeg_output_height = (USHORT)context -> gx_draw_context_canvas -> gx_canvas_memory_height; |
||
2867 |
jpeg_info -> gx_jpeg_output_buffer_offset_x = context -> gx_draw_context_offset_x; |
||
2868 |
jpeg_info -> gx_jpeg_output_buffer_offset_y = context -> gx_draw_context_offset_y; |
||
2869 |
#else |
||
2870 |
369 |
jpeg_info -> gx_jpeg_output_width = (USHORT)context -> gx_draw_context_canvas -> gx_canvas_x_resolution; |
|
2871 |
369 |
jpeg_info -> gx_jpeg_output_height = (USHORT)context -> gx_draw_context_canvas -> gx_canvas_y_resolution; |
|
2872 |
#endif |
||
2873 |
369 |
jpeg_info -> gx_jpeg_output_clip = *context -> gx_draw_context_clip; |
|
2874 |
|||
2875 |
|||
2876 |
369 |
status = _gx_image_reader_jpeg_decode_blocks(jpeg_info); |
|
2877 |
|||
2878 |
369 |
_gx_system_memory_free((void *)jpeg_info); |
|
2879 |
|||
2880 |
369 |
return status; |
|
2881 |
} |
||
2882 |
#endif |
||
2883 |
Generated by: GCOVR (Version 4.1) |