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 /**************************************************************************/
_gx_image_reader_jpeg_quantization_table_set(GX_JPEG_INFO * jpeg_info,UINT segment_len)136 static UINT _gx_image_reader_jpeg_quantization_table_set(GX_JPEG_INFO *jpeg_info, UINT segment_len)
137 {
138 GX_UBYTE  table_index;
139 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     jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
144     segment_len -= 2;
145     jpeg_data += 2;
146 
147     while (segment_len)
148     {
149         /* The upper 4 bits specify the element precision: 0 indicates 8-bit, 1 indecates 16-bit. */
150         if ((*jpeg_data) & 0xf0)
151         {
152             /* Baseline DCT-based jpeg only support 8-bit precision. */
153             return GX_NOT_SUPPORTED;
154         }
155 
156         /* The lower 4 bits specify the table destination identifier, specify one of four possible destinations. */
157         table_index = (*jpeg_data++) & 0x03;
158 
159         /* Read quantization table element. */
160         for (index = 0; index < 64; index++)
161         {
162             jpeg_info -> gx_jpeg_quantization_table[table_index][index] = *jpeg_data++;
163         }
164 
165         if (segment_len < 65)
166         {
167             return GX_INVALID_FORMAT;
168         }
169         segment_len -= 65;
170     }
171 
172     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 /**************************************************************************/
_gx_image_reader_jpeg_huffcode_find(GX_JPEG_INFO * jpeg_info,UINT table_class,UINT table_id,UINT * bit_len,GX_UBYTE * code_value)228 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     for (index = 0; index < 16; index++)
240     {
241         code_info = &jpeg_info -> gx_jpeg_huffman_code_info[table_class][table_id][index];
242         if (code_info -> bits)
243         {
244             code = (USHORT)((jpeg_info -> gx_jpeg_bit_buffer) >> (32 - code_info -> bits));
245 
246             if (code <= code_info -> end)
247             {
248                 code_index = (USHORT)(code_info -> index + code - code_info -> start);
249                 *bit_len = code_info -> bits;
250                 *code_value = jpeg_info -> gx_jpeg_huffman_table[table_class][table_id][code_index];
251                 return GX_SUCCESS;
252             }
253         }
254         else
255         {
256             break;
257         }
258     }
259 
260     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 /**************************************************************************/
_gx_image_reader_huffman_table_set(GX_JPEG_INFO * jpeg_info,UINT segment_len)310 static UINT _gx_image_reader_huffman_table_set(GX_JPEG_INFO *jpeg_info, UINT segment_len)
311 {
312 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 INT               index = 0;
320 USHORT            code = 0;
321 
322     /* must have at least one code for each of 16 huffman bit lengths */
323     if (segment_len < 19)
324     {
325         return GX_INVALID_FORMAT;
326     }
327 
328     /* Minus two-byte length. */
329     jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
330     segment_len -= 2;
331     jpeg_data += 2;
332 
333     while (segment_len)
334     {
335         /* table_calss: 0 DC 1 AC */
336         table_class = ((*jpeg_data) >> 4) & 1;
337         table_id = (*jpeg_data++) & 0x01;
338 
339         if (segment_len < 17)
340         {
341             return GX_INVALID_FORMAT;
342         }
343         segment_len -= 17;
344 
345         i_table_size = 0;
346 
347         index = 0;
348         code = 0;
349 
350         /* Read the number of Huffman codes for each bit length, from 1 to 16. */
351         for (i_bits = 0; i_bits < 16; i_bits++)
352         {
353             bit_count = *jpeg_data++;
354 
355             if (bit_count)
356             {
357                 code_info = &jpeg_info -> gx_jpeg_huffman_code_info[table_class][table_id][index++];
358                 code_info -> index = i_table_size;
359                 code_info -> start = code;
360                 code_info -> end = (USHORT)(code + bit_count - 1);
361                 code_info -> bits = (GX_UBYTE)(i_bits + 1);
362             }
363             code = (USHORT)((code + bit_count) << 1);
364 
365             i_table_size = (USHORT)(i_table_size + bit_count);
366         }
367 
368         if (segment_len < i_table_size)
369         {
370             return GX_INVALID_FORMAT;
371         }
372 
373         segment_len -= i_table_size;
374 
375         /* Load the start address of the specified huffman table. */
376         jpeg_info -> gx_jpeg_huffman_table[table_class][table_id] = jpeg_data;
377         jpeg_data += i_table_size;
378     }
379 
380     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 /**************************************************************************/
_gx_image_reader_jpeg_frame_header_read(GX_JPEG_INFO * jpeg_info,UINT segment_len)423 static UINT _gx_image_reader_jpeg_frame_header_read(GX_JPEG_INFO *jpeg_info, UINT segment_len)
424 {
425 GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index;
426 INT       i_component;
427 
428     jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
429     jpeg_data += 2;
430 
431     /* Skip precision field. */
432     jpeg_data++;
433 
434     /* Read image width, WORD */
435     jpeg_info -> gx_jpeg_height = *jpeg_data++;
436     jpeg_info -> gx_jpeg_height = (USHORT)(jpeg_info -> gx_jpeg_height << 8);
437     jpeg_info -> gx_jpeg_height = (USHORT)(jpeg_info -> gx_jpeg_height | (*jpeg_data++));
438 
439     /* Limit max jpeg height to 14 bits. */
440     if (jpeg_info -> gx_jpeg_height > GX_MAX_PIXELMAP_RESOLUTION)
441     {
442         return GX_INVALID_HEIGHT;
443     }
444 
445     /* Read image height, WORD */
446     jpeg_info -> gx_jpeg_width = *jpeg_data++;
447     jpeg_info -> gx_jpeg_width = (USHORT)(jpeg_info -> gx_jpeg_width << 8);
448     jpeg_info -> gx_jpeg_width = (USHORT)(jpeg_info -> gx_jpeg_width | (*jpeg_data++));
449 
450     /* Limit max jpeg width to 14 bits. */
451     if (jpeg_info -> gx_jpeg_width > GX_MAX_PIXELMAP_RESOLUTION)
452     {
453         return GX_INVALID_WIDTH;
454     }
455 
456     /* Read image components. */
457     jpeg_info -> gx_jpeg_num_of_components = *jpeg_data++;
458 
459     if (jpeg_info -> gx_jpeg_num_of_components > JPG_MAX_COMPONENTS)
460     {
461         return GX_FAILURE;
462     }
463 
464     for (i_component = 0; i_component < jpeg_info -> gx_jpeg_num_of_components; i_component++)
465     {
466         /* Read component id */
467         jpeg_info -> gx_jpeg_component_id[i_component] = *jpeg_data++;
468 
469         /* Read sample factor */
470         jpeg_info -> gx_jpeg_sample_factor[i_component] = *jpeg_data++;
471 
472         /* Read quantization table index */
473         jpeg_info -> gx_jpeg_qantization_table_index[i_component] = *jpeg_data++;
474     }
475 
476     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 /**************************************************************************/
_gx_image_reader_jpeg_scan_header_read(GX_JPEG_INFO * jpeg_info,UINT segment_len)519 static UINT _gx_image_reader_jpeg_scan_header_read(GX_JPEG_INFO *jpeg_info, UINT segment_len)
520 {
521 GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index;
522 INT       index;
523 
524     jpeg_data += 2;
525     jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
526 
527     /* Read the number of image components.  */
528     jpeg_info -> gx_jpeg_num_of_components = *jpeg_data++;
529 
530     if (jpeg_info -> gx_jpeg_num_of_components > JPG_MAX_COMPONENTS)
531     {
532         return GX_FAILURE;
533     }
534 
535     for (index = 0; index < jpeg_info -> gx_jpeg_num_of_components; index++)
536     {
537         /* skip image component */
538         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         jpeg_info -> gx_jpeg_dc_table_index[index] = ((*jpeg_data) & 0xf0) >> 4;
545         jpeg_info -> gx_jpeg_ac_table_index[index] = (*jpeg_data++) & 0x0f;
546     }
547 
548     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 /**************************************************************************/
_gx_image_reader_jpeg_dc_decode(GX_JPEG_INFO * jpeg_info,UINT i_component)602 static UINT _gx_image_reader_jpeg_dc_decode(GX_JPEG_INFO *jpeg_info, UINT i_component)
603 {
604 UINT     i_bits = 0;
605 GX_UBYTE code_value;
606 INT      diff;
607 UINT     table_index = jpeg_info -> gx_jpeg_dc_table_index[i_component];
608 GX_BOOL  negative;
609 
610     if (table_index >= HUFF_TABLE_DIMENSION)
611     {
612         return GX_FAILURE;
613     }
614 
615     GX_JPEG_BITS_GET(jpeg_info, 16);
616 
617     if (_gx_image_reader_jpeg_huffcode_find(jpeg_info, 0, table_index, &i_bits, &code_value) == 0)
618     {
619         GX_JPEG_BITS_SKIP(jpeg_info, i_bits);
620 
621         if (code_value == 0)
622         {
623             jpeg_info -> gx_jpeg_vecter[0] = jpeg_info -> gx_jpeg_pre_dc[i_component];
624         }
625         else
626         {
627 
628             GX_JPEG_BITS_GET(jpeg_info, code_value);
629             diff = (INT)(((UINT)jpeg_info -> gx_jpeg_bit_buffer) >> (32 - code_value));
630             GX_JPEG_BITS_SKIP(jpeg_info, code_value);
631 
632             negative = !(diff >> (code_value - 1));
633 
634             if (negative)
635             {
636                 diff += 1 - (1 << code_value);
637             }
638 
639             jpeg_info -> gx_jpeg_vecter[0] = diff + jpeg_info -> gx_jpeg_pre_dc[i_component];
640             jpeg_info -> gx_jpeg_pre_dc[i_component] = jpeg_info -> gx_jpeg_vecter[0];
641         }
642     }
643     else
644     {
645         return GX_FAILURE;
646     }
647 
648     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 /**************************************************************************/
_gx_image_reader_jpeg_ac_decode(GX_JPEG_INFO * jpeg_info,UINT i_component)702 static UINT _gx_image_reader_jpeg_ac_decode(GX_JPEG_INFO *jpeg_info, UINT i_component)
703 {
704 UINT     i_bits = 0;
705 GX_UBYTE code_value;
706 GX_UBYTE catogory;
707 GX_UBYTE runs_of_zero;
708 INT      ac_coefficient;
709 UINT     ac_counter = 1;
710 UINT     table_index = jpeg_info -> gx_jpeg_ac_table_index[i_component];
711 INT      negative;
712 
713     if (table_index >= HUFF_TABLE_DIMENSION)
714     {
715         return GX_FAILURE;
716     }
717 
718     while (ac_counter < 64)
719     {
720         i_bits = 0;
721         GX_JPEG_BITS_GET(jpeg_info, 16);
722 
723         if (_gx_image_reader_jpeg_huffcode_find(jpeg_info, 1, table_index, &i_bits, &code_value) == 0)
724         {
725             GX_JPEG_BITS_SKIP(jpeg_info, i_bits);
726 
727             runs_of_zero = (0xf0 & code_value) >> 4;
728             catogory = 0x0f & code_value;
729 
730             if (catogory == 0)
731             {
732                 /* EOB encountered. */
733                 if (runs_of_zero == 0)
734                 {
735                     ac_counter = 64;
736                 }
737                 else if (runs_of_zero == 0x0f)
738                 {
739                     ac_counter += 16;
740                 }
741             }
742             else
743             {
744                 ac_counter += runs_of_zero;
745 
746                 GX_JPEG_BITS_GET(jpeg_info, catogory);
747                 ac_coefficient = (INT)((jpeg_info -> gx_jpeg_bit_buffer) >> (32 - catogory));
748                 GX_JPEG_BITS_SKIP(jpeg_info, catogory);
749 
750                 negative = !(ac_coefficient >> (catogory - 1));
751 
752                 if (negative)
753                 {
754                     ac_coefficient += 1 - (1 << catogory);
755                 }
756 
757                 if (ac_counter < 64)
758                 {
759                     jpeg_info -> gx_jpeg_vecter[ac_counter++] = ac_coefficient;
760                 }
761             }
762         }
763         else
764         {
765             return GX_FAILURE;
766         }
767     }
768 
769     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 /**************************************************************************/
_gx_image_reader_jpeg_dequantize_idct(INT * block,INT * quant_table,GX_BYTE * out,INT stride)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 /**************************************************************************/
_gx_image_reader_jpeg_1d_idct(INT * input_data,INT * output_data,INT post_scale,INT round)1142 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     input_data[0] <<= 9;
1147     input_data[1] <<= 7;
1148     input_data[4] <<= 9;
1149     input_data[7] <<= 7;
1150 
1151     /* iDCT computation .*/
1152 
1153     /* stage 1.  */
1154     BUTTERFLY_ADDITION(input_data[1], input_data[7]);
1155 
1156     input_data[3] *= R2_SHR7;
1157     input_data[5] *= R2_SHR7;
1158 
1159     /* stage 2.  */
1160     BUTTERFLY_ADDITION(input_data[0], input_data[4]);
1161     BUTTERFLY_MULTIPLICATION(input_data[6], input_data[2], C6R2_SHR9, S6R2_SHR9);
1162     BUTTERFLY_ADDITION(input_data[7], input_data[5]);
1163     BUTTERFLY_ADDITION(input_data[1], input_data[3]);
1164 
1165     /* staget 3.  */
1166     BUTTERFLY_ADDITION(input_data[0], input_data[6]);
1167     BUTTERFLY_ADDITION(input_data[4], input_data[2]);
1168     BUTTERFLY_MULTIPLICATION_SHR6(input_data[5], input_data[3], C1_SHR8, S1_SHR8);
1169     BUTTERFLY_MULTIPLICATION_SHR6(input_data[1], input_data[7], C3_SHR8, S3_SHR8);
1170 
1171     /* stage 4.  */
1172     input_data[0] += round;
1173     input_data[4] += round;
1174     input_data[2] += round;
1175     input_data[6] += round;
1176 
1177     output_data[0] = (input_data[0] + input_data[1]) >> post_scale;
1178     output_data[8] = (input_data[4] + input_data[5]) >> post_scale;
1179     output_data[16] = (input_data[2] + input_data[3]) >> post_scale;
1180     output_data[24] = (input_data[6] + input_data[7]) >> post_scale;
1181     output_data[32] = (input_data[6] - input_data[7]) >> post_scale;
1182     output_data[40] = (input_data[2] - input_data[3]) >> post_scale;
1183     output_data[48] = (input_data[4] - input_data[5]) >> post_scale;
1184     output_data[56] = (input_data[0] - input_data[1]) >> post_scale;
1185 }
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 /**************************************************************************/
_gx_image_reader_jpeg_dequantize_idct(INT * block,INT * quant_table,GX_BYTE * out,INT stride)1241 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     for (index = 0; index < 64; index++)
1259     {
1260         block[index] *= quant_table[index];
1261 
1262         /* Reorder from zig-zag order to 8*8 block */
1263         jpeg_block[reorder_index[index]] = block[index];
1264     }
1265 
1266     for (index = 0; index < 8; index++)
1267     {
1268         _gx_image_reader_jpeg_1d_idct(jpeg_block + index * 8, temp_block + index, 9, 256);     /* row */
1269     }
1270 
1271     for (index = 0; index < 8; index++)
1272     {
1273         _gx_image_reader_jpeg_1d_idct(temp_block + index * 8, jpeg_block + index, 12, 2048);     /* col */
1274     }
1275 
1276     for (row = 0; row < 8; row++)
1277     {
1278         for (index = 0; index < 8; index++)
1279         {
1280             GX_SATURATE_TO_BYTE(out[index], jpeg_block[row * 8 + index]);
1281         }
1282 
1283         out += stride;
1284     }
1285 }
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 /**************************************************************************/
_gx_image_reader_jpeg_one_block_decode(GX_JPEG_INFO * jpeg_info,UINT i_component,GX_BYTE * block_data)1339 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     memset(jpeg_info -> gx_jpeg_vecter, 0, 64 * sizeof(UINT));
1345     _gx_image_reader_jpeg_dc_decode(jpeg_info, i_component);
1346     _gx_image_reader_jpeg_ac_decode(jpeg_info, i_component);
1347 
1348     if (i_component >= JPG_MAX_COMPONENTS)
1349     {
1350         return GX_FAILURE;
1351     }
1352 
1353     stride = ((jpeg_info -> gx_jpeg_sample_factor[i_component] & 0xf0) >> 1);
1354 
1355     if (i_component == 0)
1356     {
1357         if (stride > 32)
1358         {
1359             return GX_FAILURE;
1360         }
1361     }
1362     else
1363     {
1364         if (stride > 8)
1365         {
1366             return GX_FAILURE;
1367         }
1368     }
1369 
1370     table_index = jpeg_info -> gx_jpeg_qantization_table_index[i_component];
1371 
1372     if (table_index >= JPG_QUANT_TABLE_DIMENSION)
1373     {
1374         return GX_FAILURE;
1375     }
1376 
1377     _gx_image_reader_jpeg_dequantize_idct(jpeg_info -> gx_jpeg_vecter, jpeg_info -> gx_jpeg_quantization_table[table_index], block_data, stride);
1378     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 /**************************************************************************/
_gx_image_reader_jpeg_24xrgb_pixel_write_helium(GX_JPEG_INFO * jpeg_info,uint8x16_t vred,uint8x16_t vgreen,uint8x16_t vblue,INT size)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 /**************************************************************************/
_gx_image_reader_jpeg_24xrgb_pixel_write(GX_JPEG_INFO * jpeg_info,GX_UBYTE red,GX_UBYTE green,GX_UBYTE blue)1481 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     *((GX_COLOR *)jpeg_info -> gx_jpeg_putdata) = 0xff000000 | ((ULONG)red << 16) | ((ULONG)green << 8) | (ULONG)blue;
1484 
1485     jpeg_info -> gx_jpeg_putdata += 4;
1486 }
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 /**************************************************************************/
_gx_image_reader_jpeg_24bpp_pixel_write_helium(GX_JPEG_INFO * jpeg_info,uint8x16_t vred,uint8x16_t vgreen,uint8x16_t vblue,INT size)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 /**************************************************************************/
_gx_image_reader_jpeg_24bpp_pixel_write(GX_JPEG_INFO * jpeg_info,GX_UBYTE red,GX_UBYTE green,GX_UBYTE blue)1600 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     *jpeg_info -> gx_jpeg_putdata++ = red;
1603     *jpeg_info -> gx_jpeg_putdata++ = green;
1604     *jpeg_info -> gx_jpeg_putdata++ = blue;
1605 }
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 /**************************************************************************/
_gx_image_reader_jpeg_565rgb_pixel_write_helium(GX_JPEG_INFO * jpeg_info,uint8x16_t vred,uint8x16_t vgreen,uint8x16_t vblue,INT size)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 /**************************************************************************/
_gx_image_reader_jpeg_565rgb_pixel_write(GX_JPEG_INFO * jpeg_info,GX_UBYTE red,GX_UBYTE green,GX_UBYTE blue)1751 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     red >>= 3;
1755     green >>= 2;
1756     blue >>= 3;
1757 
1758     *((USHORT *)jpeg_info -> gx_jpeg_putdata) = (USHORT)((red << 11) | (green << 5 | blue));
1759     jpeg_info -> gx_jpeg_putdata += 2;
1760 }
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 /**************************************************************************/
_gx_image_reader_jpeg_1555xrgb_pixel_write_helium(GX_JPEG_INFO * jpeg_info,uint8x16_t vred,uint8x16_t vgreen,uint8x16_t vblue,INT size)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 /**************************************************************************/
_gx_image_reader_jpeg_1555xrgb_pixel_write(GX_JPEG_INFO * jpeg_info,GX_UBYTE red,GX_UBYTE green,GX_UBYTE blue)1906 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     red >>= 3;
1910     green >>= 3;
1911     blue >>= 3;
1912 
1913     *((USHORT *)jpeg_info -> gx_jpeg_putdata) = (USHORT)((red << 10) | (green << 5 | blue));
1914     jpeg_info -> gx_jpeg_putdata += 2;
1915 }
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 /**************************************************************************/
_gx_image_reader_jpeg_pixel_write_info_set(GX_JPEG_INFO * jpeg_info)1968 static UINT _gx_image_reader_jpeg_pixel_write_info_set(GX_JPEG_INFO *jpeg_info)
1969 {
1970     if (!jpeg_info -> gx_jpeg_output_width)
1971     {
1972         jpeg_info -> gx_jpeg_output_width = jpeg_info -> gx_jpeg_width;
1973         jpeg_info -> gx_jpeg_output_height = jpeg_info -> gx_jpeg_height;
1974 
1975         _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     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     switch (jpeg_info -> gx_jpeg_output_color_format)
1982     {
1983     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         jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_565rgb_pixel_write;
1988 #endif
1989         jpeg_info -> gx_jpeg_output_bpp = 2;
1990         jpeg_info -> gx_jpeg_output_stride <<= 1;
1991         break;
1992 
1993     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         jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_1555xrgb_pixel_write;
1998 #endif
1999         jpeg_info -> gx_jpeg_output_bpp = 2;
2000         jpeg_info -> gx_jpeg_output_stride <<= 1;
2001         break;
2002 
2003     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         jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_24xrgb_pixel_write;
2009 #endif
2010         jpeg_info -> gx_jpeg_output_bpp = 4;
2011         jpeg_info -> gx_jpeg_output_stride <<= 2;
2012         break;
2013 
2014     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         jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_24bpp_pixel_write;
2020 #endif
2021         jpeg_info -> gx_jpeg_output_bpp = 3;
2022         jpeg_info -> gx_jpeg_output_stride = (jpeg_info -> gx_jpeg_output_width * 3);
2023         jpeg_info -> gx_jpeg_output_color_format = GX_IMAGE_FORMAT_24BPP;
2024 
2025         if (jpeg_info -> gx_jpeg_output_buffer)
2026         {
2027             return GX_NOT_SUPPORTED;
2028         }
2029         break;
2030     }
2031 
2032     if (!jpeg_info -> gx_jpeg_output_buffer)
2033     {
2034         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         if (!jpeg_info -> gx_jpeg_output_buffer)
2036         {
2037             return GX_SYSTEM_MEMORY_ERROR;
2038         }
2039     }
2040 
2041     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 /**************************************************************************/
_gx_image_reader_jpeg_one_mcu_write(GX_JPEG_INFO * jpeg_info,INT xpos,INT ypos,INT h,INT v)2096 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 INT       xstart = 0;
2103 INT       xend;
2104 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     yend = (v << 3);
2126     xend = (h << 3);
2127 
2128 
2129     if (xpos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left)
2130     {
2131         xstart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left - xpos;
2132     }
2133 
2134     if (xpos + xend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right + 1)
2135     {
2136         xend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right + 1 - xpos;
2137     }
2138 
2139     if (ypos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top)
2140     {
2141         ystart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top - ypos;
2142     }
2143 
2144     if (ypos + yend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom + 1)
2145     {
2146         yend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom  + 1 - ypos;
2147     }
2148 
2149     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     put += (ypos + ystart) * jpeg_info -> gx_jpeg_output_stride;
2155     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     for (y = ystart; y < yend; y++)
2163     {
2164         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         for (x = xstart; x < xend; x++)
2189         {
2190             coff = x / h + ((y / v) << 3);
2191 
2192             Y = jpeg_info -> gx_jpeg_Y_block[x + y * h * 8];
2193             Cb = jpeg_info -> gx_jpeg_Cb_block[coff];
2194             Cr = jpeg_info -> gx_jpeg_Cr_block[coff];
2195 
2196             GX_JPEG_DECODE_YCBCR2RGB(red, green, blue, Y, Cb, Cr);
2197 
2198             GX_SATURATE_TO_UBYTE(red, red);
2199             GX_SATURATE_TO_UBYTE(green, green);
2200             GX_SATURATE_TO_UBYTE(blue, blue);
2201 
2202             jpeg_info -> gx_jpeg_pixel_write(jpeg_info, (GX_UBYTE)red, (GX_UBYTE)green, (GX_UBYTE)blue);
2203         }
2204 #endif
2205 
2206         put += jpeg_info -> gx_jpeg_output_stride;
2207     }
2208 
2209     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 /**************************************************************************/
_gx_image_reader_jpeg_one_mcu_rotated_write(GX_JPEG_INFO * jpeg_info,INT xpos,INT ypos,INT h,INT v)2257 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 INT       xstart = 0;
2263 INT       xend;
2264 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 GX_BYTE    sign = 1;
2288 #endif
2289 
2290     xend = (h << 3) - 1;
2291     yend = (v << 3) - 1;
2292 
2293     if (xpos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left)
2294     {
2295         xstart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left - xpos;
2296     }
2297 
2298     if (xpos + xend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right)
2299     {
2300         xend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right - xpos;
2301     }
2302 
2303     if (xstart > xend)
2304     {
2305         return GX_SUCCESS;
2306     }
2307 
2308     if (ypos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top)
2309     {
2310         ystart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top - ypos;
2311     }
2312 
2313     if (ypos + yend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom)
2314     {
2315         yend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom - ypos;
2316     }
2317 
2318     if (ystart > yend)
2319     {
2320         return GX_SUCCESS;
2321     }
2322 
2323 #if defined(GX_ENABLE_ARM_HELIUM)
2324     size = yend - ystart + 1;
2325 #endif
2326 
2327     stride = jpeg_info -> gx_jpeg_output_stride;
2328     put = (GX_UBYTE *)jpeg_info -> gx_jpeg_output_buffer;
2329 
2330     if (jpeg_info -> gx_jpeg_output_rotation_angle == GX_SCREEN_ROTATION_CW)
2331     {
2332         put += (jpeg_info -> gx_jpeg_output_width - xpos - 1 - xstart) * stride;
2333         put += (ypos + ystart) * jpeg_info -> gx_jpeg_output_bpp;
2334         stride = (-stride);
2335     }
2336     else
2337     {
2338         put += (xpos + xstart) * stride;
2339         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         GX_SWAP_VALS(ystart, yend);
2345         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     for (x = xstart; x <= xend; x++)
2376     {
2377         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         for (y = ystart; y != yend + sign; y += sign)
2393         {
2394             coff = x / h + ((y / v) << 3);
2395 
2396             Y = jpeg_info -> gx_jpeg_Y_block[x + y * h * 8];
2397             Cb = jpeg_info -> gx_jpeg_Cb_block[coff];
2398             Cr = jpeg_info -> gx_jpeg_Cr_block[coff];
2399 
2400             GX_JPEG_DECODE_YCBCR2RGB(red, green, blue, Y, Cb, Cr);
2401 
2402             GX_SATURATE_TO_UBYTE(red, red);
2403             GX_SATURATE_TO_UBYTE(green, green);
2404             GX_SATURATE_TO_UBYTE(blue, blue);
2405 
2406             jpeg_info -> gx_jpeg_pixel_write(jpeg_info, (GX_UBYTE)red, (GX_UBYTE)green, (GX_UBYTE)blue);
2407         }
2408 #endif
2409         put += stride;
2410     }
2411 
2412     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 /**************************************************************************/
_gx_image_reader_jpeg_decompress(GX_JPEG_INFO * jpeg_info)2463 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 UINT status = GX_SUCCESS;
2472 UINT (*one_mcu_write)(GX_JPEG_INFO *jpeg_info, INT xpos, INT ypos, INT h, INT v);
2473 
2474     h = (jpeg_info -> gx_jpeg_sample_factor[0] >> 4);
2475     v = (jpeg_info -> gx_jpeg_sample_factor[0] & 0x0f);
2476 
2477     if (v > 2)
2478     {
2479         return GX_INVALID_FORMAT;
2480     }
2481 
2482     status = _gx_image_reader_jpeg_pixel_write_info_set(jpeg_info);
2483 
2484     if ((jpeg_info -> gx_jpeg_output_rotation_angle != 0) &&
2485         (jpeg_info -> gx_jpeg_output_color_format != GX_IMAGE_FORMAT_24BPP))
2486     {
2487         one_mcu_write = _gx_image_reader_jpeg_one_mcu_rotated_write;
2488     }
2489     else
2490     {
2491         one_mcu_write = _gx_image_reader_jpeg_one_mcu_write;
2492     }
2493 
2494     for (y = 0; y < jpeg_info -> gx_jpeg_height; y += 8 * v)
2495     {
2496         for (x = 0; x < jpeg_info -> gx_jpeg_width; x += 8 * h)
2497         {
2498             /* Decode one MCU */
2499             for (yy = 0; yy < v && status == GX_SUCCESS; yy++)
2500             {
2501                 for (xx = 0; xx < h && status == GX_SUCCESS; xx++)
2502                 {
2503                     /* Y */
2504                     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             if (status == GX_SUCCESS && jpeg_info -> gx_jpeg_num_of_components > 1)
2509             {
2510                 /* Cb */
2511                 status = _gx_image_reader_jpeg_one_block_decode(jpeg_info, 1, jpeg_info -> gx_jpeg_Cb_block);
2512 
2513                 /* Cr */
2514                 if (status == GX_SUCCESS)
2515                 {
2516                     status = _gx_image_reader_jpeg_one_block_decode(jpeg_info, 2, jpeg_info -> gx_jpeg_Cr_block);
2517                 }
2518             }
2519 
2520             if (status == GX_SUCCESS)
2521             {
2522                 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     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 /**************************************************************************/
_gx_image_reader_jpeg_decode_blocks(GX_JPEG_INFO * jpeg_info)2582 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 UINT      status = GX_SUCCESS;
2588 
2589     if (jpeg_info -> gx_jpeg_data == GX_NULL || jpeg_info -> gx_jpeg_data_size < 10)
2590     {
2591         return GX_INVALID_VALUE;
2592     }
2593 
2594     jpeg_data = jpeg_info -> gx_jpeg_data;
2595 
2596     /* Read JPEG File flag that mark the start of a JPEG image. */
2597     if ((*jpeg_data++ != 0xff) || (*jpeg_data++ != 0xd8))
2598     {
2599         return GX_INVALID_FORMAT; /*Not a jpeg file */
2600     }
2601 
2602     jpeg_info -> gx_jpeg_data_index += 2;
2603 
2604     while ((jpeg_info -> gx_jpeg_data_index + 3 < jpeg_info -> gx_jpeg_data_size) &&
2605            (status == GX_SUCCESS))
2606     {
2607         jpeg_data = (jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index);
2608         marker = *(jpeg_data + 1);
2609 
2610         if ((*jpeg_data == 0xff) && (marker != 0) && (marker != 0xff))
2611         {
2612             jpeg_data += 2;
2613             jpeg_info -> gx_jpeg_data_index += 2;
2614 
2615             /* Read WORD length */
2616             segment_len = *(jpeg_data);
2617             segment_len <<= 8;
2618             segment_len |= *(jpeg_data + 1);
2619 
2620             if ((UINT)jpeg_info -> gx_jpeg_data_index + segment_len > (UINT)jpeg_info -> gx_jpeg_data_size)
2621             {
2622                 /* Invalid data size. */
2623                 status = GX_FAILURE;
2624                 break;
2625             }
2626 
2627             switch (marker)
2628             {
2629             case 0xdb:
2630                 /* Define Quantization Table */
2631                 status = _gx_image_reader_jpeg_quantization_table_set(jpeg_info, segment_len);
2632                 break;
2633 
2634             case 0xc0:
2635                 /* Start of Frame */
2636                 status = _gx_image_reader_jpeg_frame_header_read(jpeg_info, segment_len);
2637                 break;
2638 
2639             case 0xc4:
2640                 /* Define Huffman Table */
2641                 status = _gx_image_reader_huffman_table_set(jpeg_info, segment_len);
2642                 break;
2643 
2644             case 0xdd:
2645                 /* Read restart interval which specifies the number of MCU in restart interval. */
2646                 jpeg_data += 2;
2647                 jpeg_info -> gx_jpeg_restart_interval = *jpeg_data++;
2648                 jpeg_info -> gx_jpeg_restart_interval <<= 8;
2649                 jpeg_info -> gx_jpeg_restart_interval |= *jpeg_data++;
2650                 jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
2651                 break;
2652 
2653             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                 _gx_image_reader_jpeg_scan_header_read(jpeg_info, segment_len);
2657 
2658                 /* Start decoding jpeg data stream. */
2659                 status = _gx_image_reader_jpeg_decompress(jpeg_info);
2660                 break;
2661 
2662             default:
2663                 /* Unkown marker, skip */
2664                 jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
2665                 break;
2666             }
2667         }
2668         else
2669         {
2670             jpeg_info -> gx_jpeg_data_index++;
2671         }
2672     }
2673 
2674     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 /**************************************************************************/
_gx_image_reader_jpeg_decode(GX_IMAGE_READER * image_reader,GX_PIXELMAP * outmap)2722 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     if ((!_gx_system_memory_allocator) || (!_gx_system_memory_free))
2729     {
2730         return GX_SYSTEM_MEMORY_ERROR;
2731     }
2732 
2733     jpeg_info = (GX_JPEG_INFO *)_gx_system_memory_allocator(sizeof(GX_JPEG_INFO));
2734 
2735     if (!jpeg_info)
2736     {
2737         return GX_SYSTEM_MEMORY_ERROR;
2738     }
2739 
2740     memset(jpeg_info, 0, sizeof(GX_JPEG_INFO));
2741 
2742 
2743     jpeg_info -> gx_jpeg_data = (GX_UBYTE *)image_reader -> gx_image_reader_source_data;
2744     jpeg_info -> gx_jpeg_data_size = (INT)image_reader -> gx_image_reader_source_data_size;
2745     jpeg_info -> gx_jpeg_data_index = 0;
2746 
2747     if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_DITHER)
2748     {
2749         jpeg_info -> gx_jpeg_output_color_format  = GX_IMAGE_FORMAT_24BPP;
2750     }
2751     else
2752     {
2753         jpeg_info -> gx_jpeg_output_color_format  = image_reader -> gx_image_reader_color_format;
2754     }
2755 
2756     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     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     status = _gx_image_reader_jpeg_decode_blocks(jpeg_info);
2766 
2767     if (status == GX_SUCCESS)
2768     {
2769         outmap -> gx_pixelmap_data = jpeg_info -> gx_jpeg_output_buffer;
2770         outmap -> gx_pixelmap_data_size = (ULONG)(jpeg_info -> gx_jpeg_output_stride * jpeg_info -> gx_jpeg_height);
2771         outmap -> gx_pixelmap_width = (GX_VALUE)jpeg_info -> gx_jpeg_width;
2772         outmap -> gx_pixelmap_height = (GX_VALUE)jpeg_info -> gx_jpeg_height;
2773         outmap -> gx_pixelmap_flags = 0;
2774         outmap -> gx_pixelmap_format = jpeg_info -> gx_jpeg_output_color_format;
2775     }
2776 
2777     _gx_system_memory_free((void *)jpeg_info);
2778 
2779     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 /**************************************************************************/
_gx_image_reader_jpeg_mcu_decode(GX_CONST GX_UBYTE * read_data,ULONG data_size,GX_DRAW_CONTEXT * context,INT xpos,INT ypos)2831 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     if ((!_gx_system_memory_allocator) || (!_gx_system_memory_free))
2838     {
2839         return GX_SYSTEM_MEMORY_ERROR;
2840     }
2841 
2842     jpeg_info = (GX_JPEG_INFO *)_gx_system_memory_allocator(sizeof(GX_JPEG_INFO));
2843 
2844     if (!jpeg_info)
2845     {
2846         return GX_SYSTEM_MEMORY_ERROR;
2847     }
2848 
2849     if (!context)
2850     {
2851         return GX_INVALID_CONTEXT;
2852     }
2853 
2854     memset(jpeg_info, 0, sizeof(GX_JPEG_INFO));
2855 
2856     jpeg_info -> gx_jpeg_data = (GX_UBYTE *)read_data;
2857     jpeg_info -> gx_jpeg_data_size = (INT)data_size;
2858     jpeg_info -> gx_jpeg_data_index = 0;
2859     jpeg_info -> gx_jpeg_output_xpos = xpos;
2860     jpeg_info -> gx_jpeg_output_ypos = ypos;
2861     jpeg_info -> gx_jpeg_output_color_format = context -> gx_draw_context_display -> gx_display_color_format;
2862     jpeg_info -> gx_jpeg_output_rotation_angle = context -> gx_draw_context_display -> gx_display_rotation_angle;
2863     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     jpeg_info -> gx_jpeg_output_width = (USHORT)context -> gx_draw_context_canvas -> gx_canvas_x_resolution;
2871     jpeg_info -> gx_jpeg_output_height = (USHORT)context -> gx_draw_context_canvas -> gx_canvas_y_resolution;
2872 #endif
2873     jpeg_info -> gx_jpeg_output_clip = *context -> gx_draw_context_clip;
2874 
2875 
2876     status = _gx_image_reader_jpeg_decode_blocks(jpeg_info);
2877 
2878     _gx_system_memory_free((void *)jpeg_info);
2879 
2880     return status;
2881 }
2882 #endif
2883 
2884