1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** GUIX Component                                                        */
17 /**                                                                       */
18 /**   Utility Management (Utility)                                        */
19 /**                                                                       */
20 /**************************************************************************/
21 
22 #define GX_SOURCE_CODE
23 
24 /* Include necessary system files.  */
25 
26 #include "gx_api.h"
27 #include "gx_context.h"
28 #include "gx_system.h"
29 #include "gx_utility.h"
30 #include "gx_image_reader.h"
31 
32 #if defined(GX_SOFTWARE_DECODER_SUPPORT)
33 
34 static UINT              _gx_jpg_bit_buffer;
35 static UINT              _gx_jpg_bit_count;
36 
37 static GX_CONST GX_UBYTE _gx_jpg_reorder_index[] =
38 {
39     0, 1, 8, 16, 9, 2, 3, 10,
40     17, 24, 32, 25, 18, 11, 4, 5,
41     12, 19, 26, 33, 40, 48, 41, 34,
42     27, 20, 13, 6, 7, 14, 21, 28,
43     35, 42, 49, 56, 57, 50, 43, 36,
44     29, 22, 15, 23, 30, 37, 44, 51,
45     58, 59, 52, 45, 38, 31, 39, 46,
46     53, 60, 61, 54, 47, 55, 62, 63
47 };
48 
49 /**************************************************************************/
50 /*                                                                        */
51 /*  FUNCTION                                               RELEASE        */
52 /*                                                                        */
53 /*    _gx_image_reader_jpeg_bits_get                      PORTABLE C      */
54 /*                                                           6.1          */
55 /*  AUTHOR                                                                */
56 /*                                                                        */
57 /*    Kenneth Maxwell, Microsoft Corporation                              */
58 /*                                                                        */
59 /*  DESCRIPTION                                                           */
60 /*                                                                        */
61 /*    Extract a specified number of bits from JPEG data stream and        */
62 /*    advance the read pointer of the JPEG data stream.                   */
63 /*                                                                        */
64 /*  INPUT                                                                 */
65 /*                                                                        */
66 /*    jpeg_info                             JPEG data context             */
67 /*    num_of_bits                           Number of bits to extract     */
68 /*    return_value                          Extracted data.               */
69 /*                                                                        */
70 /*  OUTPUT                                                                */
71 /*                                                                        */
72 /*    None                                                                */
73 /*                                                                        */
74 /*  CALLS                                                                 */
75 /*                                                                        */
76 /*    None                                                                */
77 /*                                                                        */
78 /*  CALLED BY                                                             */
79 /*                                                                        */
80 /*    _gx_image_reader_jpeg_dc_decode                                     */
81 /*    _gx_image_reader_jpeg_ac_decode                                     */
82 /*                                                                        */
83 /*  RELEASE HISTORY                                                       */
84 /*                                                                        */
85 /*    DATE              NAME                      DESCRIPTION             */
86 /*                                                                        */
87 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
88 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
89 /*                                            resulting in version 6.1    */
90 /*                                                                        */
91 /**************************************************************************/
_gx_image_reader_jpeg_bits_get(GX_JPEG_INFO * jpeg_info,UINT num_of_bits,UINT * return_value)92 static void _gx_image_reader_jpeg_bits_get(GX_JPEG_INFO *jpeg_info, UINT num_of_bits, UINT *return_value)
93 {
94 INT index = jpeg_info -> gx_jpeg_data_index;
95 
96     while (_gx_jpg_bit_count <= num_of_bits)
97     {
98         if ((index < jpeg_info -> gx_jpeg_data_size) && (_gx_jpg_bit_count <= 24))
99         {
100             _gx_jpg_bit_buffer |= ((UINT)(jpeg_info -> gx_jpeg_data[index]) << (UINT)(24 - _gx_jpg_bit_count));
101 
102             if ((jpeg_info -> gx_jpeg_data[index] == 0xff) &&
103                 (index + 1 < jpeg_info -> gx_jpeg_data_size) &&
104                 (jpeg_info -> gx_jpeg_data[index + 1] == 0x00))
105             {
106                 index += 2;
107             }
108             else
109             {
110                 index += 1;
111             }
112         }
113 
114         _gx_jpg_bit_count += 8;
115     }
116 
117     jpeg_info -> gx_jpeg_data_index = index;
118 
119     (*return_value) = (UINT)_gx_jpg_bit_buffer;
120 }
121 
122 /**************************************************************************/
123 /*                                                                        */
124 /*  FUNCTION                                               RELEASE        */
125 /*                                                                        */
126 /*    _gx_image_reader_jpeg_bits_skip                     PORTABLE C      */
127 /*                                                           6.1          */
128 /*  AUTHOR                                                                */
129 /*                                                                        */
130 /*    Kenneth Maxwell, Microsoft Corporation                              */
131 /*                                                                        */
132 /*  DESCRIPTION                                                           */
133 /*                                                                        */
134 /*    Skips bits from tempory JPEG data stream.                           */
135 /*                                                                        */
136 /*  INPUT                                                                 */
137 /*                                                                        */
138 /*    skip_bits                             Number of bits to skip        */
139 /*                                                                        */
140 /*  OUTPUT                                                                */
141 /*                                                                        */
142 /*    None                                                                */
143 /*                                                                        */
144 /*  CALLS                                                                 */
145 /*                                                                        */
146 /*    None                                                                */
147 /*                                                                        */
148 /*  CALLED BY                                                             */
149 /*                                                                        */
150 /*    _gx_image_reader_jpeg_dc_decode                                     */
151 /*    _gx_image_reader_jpeg_ac_decode                                     */
152 /*                                                                        */
153 /*  RELEASE HISTORY                                                       */
154 /*                                                                        */
155 /*    DATE              NAME                      DESCRIPTION             */
156 /*                                                                        */
157 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
158 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
159 /*                                            resulting in version 6.1    */
160 /*                                                                        */
161 /**************************************************************************/
_gx_image_reader_jpeg_bits_skip(UINT skip_bits)162 static void _gx_image_reader_jpeg_bits_skip(UINT skip_bits)
163 {
164     _gx_jpg_bit_buffer <<= skip_bits;
165 
166     _gx_jpg_bit_count -= skip_bits;
167 }
168 
169 /**************************************************************************/
170 /*                                                                        */
171 /*  FUNCTION                                               RELEASE        */
172 /*                                                                        */
173 /*    _gx_image_reader_jpeg_range                         PORTABLE C      */
174 /*                                                           6.1          */
175 /*  AUTHOR                                                                */
176 /*                                                                        */
177 /*    Kenneth Maxwell, Microsoft Corporation                              */
178 /*                                                                        */
179 /*  DESCRIPTION                                                           */
180 /*                                                                        */
181 /*    Limit the value to be in the range of [0, 255]                      */
182 /*                                                                        */
183 /*  INPUT                                                                 */
184 /*                                                                        */
185 /*    value                                 Value to be checked           */
186 /*                                                                        */
187 /*  OUTPUT                                                                */
188 /*                                                                        */
189 /*    GX_UBYTE                              Output value.                 */
190 /*                                                                        */
191 /*  CALLS                                                                 */
192 /*                                                                        */
193 /*    None                                                                */
194 /*                                                                        */
195 /*  CALLED BY                                                             */
196 /*                                                                        */
197 /*    _gx_image_reader_jpeg_dequantize_idct                               */
198 /*                                                                        */
199 /*  RELEASE HISTORY                                                       */
200 /*                                                                        */
201 /*    DATE              NAME                      DESCRIPTION             */
202 /*                                                                        */
203 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
204 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
205 /*                                            resulting in version 6.1    */
206 /*                                                                        */
207 /**************************************************************************/
_gx_image_reader_jpeg_range(INT i)208 static GX_UBYTE _gx_image_reader_jpeg_range(INT i)
209 {
210     if (i < 0)
211     {
212         return 0;
213     }
214     else if (i > 255)
215     {
216         return 255;
217     }
218     else
219     {
220         return((GX_UBYTE)i);
221     }
222 }
223 
224 /**************************************************************************/
225 /*                                                                        */
226 /*  FUNCTION                                               RELEASE        */
227 /*                                                                        */
228 /*    _gx_image_reader_jpeg_YCbCr2RGB_888                 PORTABLE C      */
229 /*                                                           6.1          */
230 /*  AUTHOR                                                                */
231 /*                                                                        */
232 /*    Kenneth Maxwell, Microsoft Corporation                              */
233 /*                                                                        */
234 /*  DESCRIPTION                                                           */
235 /*                                                                        */
236 /*    Converts YCbCr value to 888RGB color space and write it to memory.  */
237 /*                                                                        */
238 /*  INPUT                                                                 */
239 /*                                                                        */
240 /*    y                                     Luminance                     */
241 /*    cb                                    Chroma (Blue-difference)      */
242 /*    cr                                    Chroma (Red-difference)       */
243 /*    put                                   Retrieved 888RGB color        */
244 /*                                                                        */
245 /*  OUTPUT                                                                */
246 /*                                                                        */
247 /*    Value                                 565 RGB value                 */
248 /*                                                                        */
249 /*  CALLS                                                                 */
250 /*                                                                        */
251 /*    _gx_image_reader_jpeg_range           Limit value in range [0, 255] */
252 /*                                                                        */
253 /*  CALLED BY                                                             */
254 /*                                                                        */
255 /*    _gx_image_reader_jpeg_one_mcu_write                                 */
256 /*                                                                        */
257 /*  RELEASE HISTORY                                                       */
258 /*                                                                        */
259 /*    DATE              NAME                      DESCRIPTION             */
260 /*                                                                        */
261 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
262 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
263 /*                                            resulting in version 6.1    */
264 /*                                                                        */
265 /**************************************************************************/
_gx_image_reader_jpeg_YCbCr2RGB_888(INT y,INT cb,INT cr,GX_UBYTE * put)266 static GX_COLOR _gx_image_reader_jpeg_YCbCr2RGB_888(INT y, INT cb, INT cr, GX_UBYTE *put)
267 {
268 INT      temp_r;
269 INT      temp_g;
270 INT      temp_b;
271 GX_UBYTE r;
272 GX_UBYTE g;
273 GX_UBYTE b;
274 
275 
276     cb -= 128;
277     cr -= 128;
278 
279     temp_r = y + cr + (cr >> 2) + (cr >> 3);
280     temp_g = y - ((cb >> 2) + (cb >> 4) + (cb >> 5)) - ((cr >> 1) + (cr >> 3) + (cr >> 4) + (cr >> 6));
281     temp_b = y + cb + (cb >> 1) + (cb >> 2);
282 
283 
284     /* Make sure the range of the RGB values are within bound. */
285     r = _gx_image_reader_jpeg_range(temp_r);
286     g = _gx_image_reader_jpeg_range(temp_g);
287     b = _gx_image_reader_jpeg_range(temp_b);
288 
289     *put = r;
290     *(put + 1) = g;
291     *(put + 2) = b;
292 
293     return 0;
294 }
295 
296 /**************************************************************************/
297 /*                                                                        */
298 /*  FUNCTION                                               RELEASE        */
299 /*                                                                        */
300 /*    _gx_dislay_driver_jpeg_quantization_table_set       PORTABLE C      */
301 /*                                                           6.2.0        */
302 /*  AUTHOR                                                                */
303 /*                                                                        */
304 /*    Kenneth Maxwell, Microsoft Corporation                              */
305 /*                                                                        */
306 /*  DESCRIPTION                                                           */
307 /*                                                                        */
308 /*    Sets the JPEG quantization table.                                   */
309 /*                                                                        */
310 /*  INPUT                                                                 */
311 /*                                                                        */
312 /*    jpeg_info                             JPEG data control block       */
313 /*    segment_len                           Initial length of the segment */
314 /*                                                                        */
315 /*  OUTPUT                                                                */
316 /*                                                                        */
317 /*    None                                                                */
318 /*                                                                        */
319 /*  CALLS                                                                 */
320 /*                                                                        */
321 /*    None                                                                */
322 /*                                                                        */
323 /*  CALLED BY                                                             */
324 /*                                                                        */
325 /*    _gx_image_reader_jpeg_decode                                        */
326 /*                                                                        */
327 /*  RELEASE HISTORY                                                       */
328 /*                                                                        */
329 /*    DATE              NAME                      DESCRIPTION             */
330 /*                                                                        */
331 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
332 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
333 /*                                            resulting in version 6.1    */
334 /*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
335 /*                                            prevented underflow from    */
336 /*                                            bad input data,             */
337 /*                                            resulting in version 6.2.0  */
338 /*                                                                        */
339 /**************************************************************************/
_gx_image_reader_jpeg_quantization_table_set(GX_JPEG_INFO * jpeg_info,UINT segment_len)340 static UINT _gx_image_reader_jpeg_quantization_table_set(GX_JPEG_INFO *jpeg_info, UINT segment_len)
341 {
342 GX_UBYTE  table_index;
343 GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index;
344 INT       index;
345 
346     /* Minus two-byte length. */
347     jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
348     segment_len -= 2;
349     jpeg_data += 2;
350 
351     while (segment_len)
352     {
353         /* The upper 4 bits specify the element precision: 0 indicates 8-bit, 1 indecates 16-bit. */
354         if ((*jpeg_data) & 0xf0)
355         {
356             /* Baseline DCT-based jpeg only support 8-bit precision. */
357             return GX_NOT_SUPPORTED;
358         }
359 
360         /* The lower 4 bits specify the table destination identifier, specify one of four possible destinations. */
361         table_index = (*jpeg_data++) & 0x03;
362 
363         /* Read quantization table element. */
364         for (index = 0; index < 64; index++)
365         {
366             jpeg_info -> gx_jpeg_quantization_table[table_index][index] = *jpeg_data++;
367         }
368 
369         if (segment_len < 65)
370         {
371             return GX_INVALID_FORMAT;
372         }
373         segment_len -= 65;
374     }
375 
376     return GX_SUCCESS;
377 }
378 
379 /**************************************************************************/
380 /*                                                                        */
381 /*  FUNCTION                                               RELEASE        */
382 /*                                                                        */
383 /*    _gx_image_reader_jpeg_huffcode_find                 PORTABLE C      */
384 /*                                                           6.2.0        */
385 /*  AUTHOR                                                                */
386 /*                                                                        */
387 /*    Kenneth Maxwell, Microsoft Corporation                              */
388 /*                                                                        */
389 /*  DESCRIPTION                                                           */
390 /*                                                                        */
391 /*    Lookup the huffman code.                                            */
392 /*                                                                        */
393 /*  INPUT                                                                 */
394 /*                                                                        */
395 /*    jpeg_info                             JPEG data control block       */
396 /*    table_class                           Table class, 0 = DC table,    */
397 /*                                          1 = AC table                  */
398 /*    table_id                              Table index                   */
399 /*    scan_buffer                           Buffer to search from         */
400 /*    bit_len                               Retrieved Huffman Code Length */
401 /*    code_value                            Retrieved Huffman Code        */
402 /*                                                                        */
403 /*  OUTPUT                                                                */
404 /*                                                                        */
405 /*    Status Code                                                         */
406 /*                                                                        */
407 /*  CALLS                                                                 */
408 /*                                                                        */
409 /*    None                                                                */
410 /*                                                                        */
411 /*  CALLED BY                                                             */
412 /*                                                                        */
413 /*    _gx_image_reader_jpeg_dc_decode                                     */
414 /*    _gx_image_reader_jpeg_ac_decode                                     */
415 /*                                                                        */
416 /*  RELEASE HISTORY                                                       */
417 /*                                                                        */
418 /*    DATE              NAME                      DESCRIPTION             */
419 /*                                                                        */
420 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
421 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
422 /*                                            resulting in version 6.1    */
423 /*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
424 /*                                            changed bit_count to		  */
425 /*											  GX_VALUE data type          */
426 /*                                            resulting in version 6.2.0  */
427 /*                                                                        */
428 /**************************************************************************/
_gx_image_reader_jpeg_huffcode_find(GX_JPEG_INFO * jpeg_info,UINT table_class,UINT table_id,UINT scan_buffer,UINT * bit_len,GX_UBYTE * code_value)429 static UINT _gx_image_reader_jpeg_huffcode_find(GX_JPEG_INFO *jpeg_info,
430                                                 UINT table_class,
431                                                 UINT table_id,
432                                                 UINT scan_buffer,
433                                                 UINT *bit_len,
434                                                 GX_UBYTE *code_value)
435 {
436 UINT i_bit;
437 GX_VALUE bit_count;
438 INT code;
439 INT code_cal = 0;
440 INT code_index = 0;
441 
442     for (i_bit = 0; i_bit < 16; i_bit++)
443     {
444         bit_count = (GX_VALUE)(jpeg_info -> gx_jpeg_huffman_bits_count[table_class][table_id][i_bit]);
445 
446         if (bit_count)
447         {
448             code = (INT) ((scan_buffer) >> (31 - i_bit));
449 
450             if (code <= code_cal + bit_count - 1)
451             {
452                 *bit_len = i_bit + 1;
453                 *code_value = (GX_UBYTE)jpeg_info -> gx_jpeg_huffman_table[table_class][table_id][code_index + code - code_cal];
454                 return GX_SUCCESS;
455             }
456             else
457             {
458                 code_index += bit_count;
459                 code_cal += bit_count;
460             }
461         }
462 
463         code_cal <<= 1;
464     }
465 
466     return GX_FAILURE;
467 }
468 
469 /**************************************************************************/
470 /*                                                                        */
471 /*  FUNCTION                                               RELEASE        */
472 /*                                                                        */
473 /*    _gx_image_reader_huffman_table_set                  PORTABLE C      */
474 /*                                                           6.2.0        */
475 /*  AUTHOR                                                                */
476 /*                                                                        */
477 /*    Kenneth Maxwell, Microsoft Corporation                              */
478 /*                                                                        */
479 /*  DESCRIPTION                                                           */
480 /*                                                                        */
481 /*    Sets up the huffman table.                                          */
482 /*                                                                        */
483 /*  INPUT                                                                 */
484 /*                                                                        */
485 /*    jpeg_info                             JPEG data control block       */
486 /*    segment_len                           Initial length of the segment */
487 /*                                                                        */
488 /*  OUTPUT                                                                */
489 /*                                                                        */
490 /*    None                                                                */
491 /*                                                                        */
492 /*  CALLS                                                                 */
493 /*                                                                        */
494 /*    None                                                                */
495 /*                                                                        */
496 /*  CALLED BY                                                             */
497 /*                                                                        */
498 /*    _gx_image_reader_jpeg_decode_blocks                                 */
499 /*                                                                        */
500 /*  RELEASE HISTORY                                                       */
501 /*                                                                        */
502 /*    DATE              NAME                      DESCRIPTION             */
503 /*                                                                        */
504 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
505 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
506 /*                                            resulting in version 6.1    */
507 /*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
508 /*                                            added range test to prevent */
509 /*                                            underflow,                  */
510 /*                                            resulting in version 6.2.0  */
511 /*                                                                        */
512 /**************************************************************************/
_gx_image_reader_huffman_table_set(GX_JPEG_INFO * jpeg_info,UINT segment_len)513 static UINT _gx_image_reader_huffman_table_set(GX_JPEG_INFO *jpeg_info, UINT segment_len)
514 {
515 GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index;
516 GX_UBYTE  table_class;
517 GX_UBYTE  table_id;
518 GX_UBYTE  bit_count;
519 UINT      code_index;
520 UINT      i_bits;
521 UINT      i_counts;
522 USHORT    i_table_size;
523 
524     /* must have at least one code for each of 16 huffman bit lengths */
525     if (segment_len < 19)
526     {
527         return GX_INVALID_FORMAT;
528     }
529 
530     /* Minus two-byte length. */
531     jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
532     segment_len -= 2;
533     jpeg_data += 2;
534 
535     while (segment_len)
536     {
537         /* table_calss: 0 DC 1 AC */
538         table_class = ((*jpeg_data) >> 4) & 1;
539         table_id = (*jpeg_data++) & 0x01;
540 
541         if (segment_len < 17)
542         {
543             return GX_INVALID_FORMAT;
544         }
545         segment_len -= 17;
546 
547         i_table_size = 0;
548         code_index = 0;
549 
550         /* Read the number of Huffman codes for each bit length, from 1 to 16. */
551         for (i_bits = 0; i_bits < 16; i_bits++)
552         {
553             bit_count = *jpeg_data++;
554 
555             if (segment_len < bit_count)
556             {
557                 return GX_INVALID_FORMAT;
558             }
559             jpeg_info -> gx_jpeg_huffman_bits_count[table_class][table_id][i_bits] = bit_count;
560             segment_len -= bit_count;
561             i_table_size = (USHORT)(i_table_size + bit_count);
562         }
563 
564         /* The max i_table_size is 16 * 255, overflow cannot occur. */
565         jpeg_info -> gx_jpeg_huffman_table[table_class][table_id] = (INT *)_gx_system_memory_allocator(i_table_size * sizeof(INT));
566 
567         if (jpeg_info -> gx_jpeg_huffman_table[table_class][table_id] == GX_NULL)
568         {
569             return GX_SYSTEM_MEMORY_ERROR;
570         }
571 
572         /* Read the bytes that the Huffman codes represent, and generate Huffman tree that
573            map a Huffman code to a represent value. */
574         for (i_bits = 0; i_bits < 16; i_bits++)
575         {
576             for (i_counts = 0; i_counts < (UINT)jpeg_info -> gx_jpeg_huffman_bits_count[table_class][table_id][i_bits]; i_counts++)
577             {
578                 /* Read byte values the Huffman code represents. */
579                 jpeg_info -> gx_jpeg_huffman_table[table_class][table_id][code_index++] = (*jpeg_data++);
580             }
581         }
582     }
583 
584     return GX_SUCCESS;
585 }
586 
587 /**************************************************************************/
588 /*                                                                        */
589 /*  FUNCTION                                               RELEASE        */
590 /*                                                                        */
591 /*    _gx_display_driver_jpeg_frame_header_read           PORTABLE C      */
592 /*                                                           6.1          */
593 /*  AUTHOR                                                                */
594 /*                                                                        */
595 /*    Kenneth Maxwell, Microsoft Corporation                              */
596 /*                                                                        */
597 /*  DESCRIPTION                                                           */
598 /*                                                                        */
599 /*    Reads in the frame header infomration.                              */
600 /*                                                                        */
601 /*  INPUT                                                                 */
602 /*                                                                        */
603 /*    jpeg_info                             JPEG data control block       */
604 /*    segment_len                           Initial length of the segment */
605 /*                                                                        */
606 /*  OUTPUT                                                                */
607 /*                                                                        */
608 /*    None                                                                */
609 /*                                                                        */
610 /*  CALLS                                                                 */
611 /*                                                                        */
612 /*    None                                                                */
613 /*                                                                        */
614 /*  CALLED BY                                                             */
615 /*                                                                        */
616 /*    _gx_image_reader_jpeg_decode_blocks                                 */
617 /*                                                                        */
618 /*  RELEASE HISTORY                                                       */
619 /*                                                                        */
620 /*    DATE              NAME                      DESCRIPTION             */
621 /*                                                                        */
622 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
623 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
624 /*                                            resulting in version 6.1    */
625 /*                                                                        */
626 /**************************************************************************/
_gx_image_reader_jpeg_frame_header_read(GX_JPEG_INFO * jpeg_info,UINT segment_len)627 static UINT _gx_image_reader_jpeg_frame_header_read(GX_JPEG_INFO *jpeg_info, UINT segment_len)
628 {
629 GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index;
630 INT       i_component;
631 
632     jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
633     jpeg_data += 2;
634 
635     /* Skip precision field. */
636     jpeg_data++;
637 
638     /* Read image width, WORD */
639     jpeg_info -> gx_jpeg_height = *jpeg_data++;
640     jpeg_info -> gx_jpeg_height = (USHORT)(jpeg_info -> gx_jpeg_height << 8);
641     jpeg_info -> gx_jpeg_height = (USHORT)(jpeg_info -> gx_jpeg_height | (*jpeg_data++));
642 
643     /* Limit max jpeg height to 14 bits. */
644     if (jpeg_info -> gx_jpeg_height > GX_MAX_PIXELMAP_RESOLUTION)
645     {
646         return GX_INVALID_HEIGHT;
647     }
648 
649     /* Read image height, WORD */
650     jpeg_info -> gx_jpeg_width = *jpeg_data++;
651     jpeg_info -> gx_jpeg_width = (USHORT)(jpeg_info -> gx_jpeg_width << 8);
652     jpeg_info -> gx_jpeg_width = (USHORT)(jpeg_info -> gx_jpeg_width | (*jpeg_data++));
653 
654     /* Limit max jpeg width to 14 bits. */
655     if (jpeg_info -> gx_jpeg_width > GX_MAX_PIXELMAP_RESOLUTION)
656     {
657         return GX_INVALID_WIDTH;
658     }
659 
660     /* Read image components. */
661     jpeg_info -> gx_jpeg_num_of_components = *jpeg_data++;
662 
663     if (jpeg_info -> gx_jpeg_num_of_components > JPG_MAX_COMPONENTS)
664     {
665         return GX_FAILURE;
666     }
667 
668     for (i_component = 0; i_component < jpeg_info -> gx_jpeg_num_of_components; i_component++)
669     {
670         /* Read component id */
671         jpeg_info -> gx_jpeg_component_id[i_component] = *jpeg_data++;
672 
673         /* Read sample factor */
674         jpeg_info -> gx_jpeg_sample_factor[i_component] = *jpeg_data++;
675 
676         /* Read quantization table index */
677         jpeg_info -> gx_jpeg_qantization_table_index[i_component] = *jpeg_data++;
678     }
679 
680     return GX_SUCCESS;
681 }
682 
683 /**************************************************************************/
684 /*                                                                        */
685 /*  FUNCTION                                               RELEASE        */
686 /*                                                                        */
687 /*    _gx_image_reader_jpeg_scan_header_read              PORTABLE C      */
688 /*                                                           6.1          */
689 /*  AUTHOR                                                                */
690 /*                                                                        */
691 /*    Kenneth Maxwell, Microsoft Corporation                              */
692 /*                                                                        */
693 /*  DESCRIPTION                                                           */
694 /*                                                                        */
695 /*    Reads in the scan header information.                               */
696 /*                                                                        */
697 /*  INPUT                                                                 */
698 /*                                                                        */
699 /*    jpeg_info                             JPEG data control block       */
700 /*    segment_len                           Initial length of the segment */
701 /*                                                                        */
702 /*  OUTPUT                                                                */
703 /*                                                                        */
704 /*    None                                                                */
705 /*                                                                        */
706 /*  CALLS                                                                 */
707 /*                                                                        */
708 /*    None                                                                */
709 /*                                                                        */
710 /*  CALLED BY                                                             */
711 /*                                                                        */
712 /*    _gx_image_reader_jpeg_decode_blocks                                 */
713 /*                                                                        */
714 /*  RELEASE HISTORY                                                       */
715 /*                                                                        */
716 /*    DATE              NAME                      DESCRIPTION             */
717 /*                                                                        */
718 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
719 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
720 /*                                            resulting in version 6.1    */
721 /*                                                                        */
722 /**************************************************************************/
_gx_image_reader_jpeg_scan_header_read(GX_JPEG_INFO * jpeg_info,UINT segment_len)723 static UINT _gx_image_reader_jpeg_scan_header_read(GX_JPEG_INFO *jpeg_info, UINT segment_len)
724 {
725 GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index;
726 INT       index;
727 
728     jpeg_data += 2;
729     jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
730 
731     /* Read the number of image components.  */
732     jpeg_info -> gx_jpeg_num_of_components = *jpeg_data++;
733 
734     if (jpeg_info -> gx_jpeg_num_of_components > JPG_MAX_COMPONENTS)
735     {
736         return GX_FAILURE;
737     }
738 
739     for (index = 0; index < jpeg_info -> gx_jpeg_num_of_components; index++)
740     {
741         /* skip image component */
742         jpeg_data++;
743 
744         /* high bits correspond to DC table index.
745            low bits correspond to AC table index
746            0: Y Huffman table
747            1: Chrominance Huffman table. */
748         jpeg_info -> gx_jpeg_dc_table_index[index] = ((*jpeg_data) & 0xf0) >> 4;
749         jpeg_info -> gx_jpeg_ac_table_index[index] = (*jpeg_data++) & 0x0f;
750     }
751 
752     return GX_SUCCESS;
753 }
754 
755 /**************************************************************************/
756 /*                                                                        */
757 /*  FUNCTION                                               RELEASE        */
758 /*                                                                        */
759 /*    _gx_image_reader_jpeg_dc_decode                     PORTABLE C      */
760 /*                                                           6.2.0        */
761 /*  AUTHOR                                                                */
762 /*                                                                        */
763 /*    Kenneth Maxwell, Microsoft Corporation                              */
764 /*                                                                        */
765 /*  DESCRIPTION                                                           */
766 /*                                                                        */
767 /*    Decode the DC component.                                            */
768 /*                                                                        */
769 /*  INPUT                                                                 */
770 /*                                                                        */
771 /*    jpeg_info                             JPEG data control block       */
772 /*    i_component                           Component index               */
773 /*                                                                        */
774 /*  OUTPUT                                                                */
775 /*                                                                        */
776 /*    Status                                                              */
777 /*                                                                        */
778 /*  CALLS                                                                 */
779 /*                                                                        */
780 /*    _gx_image_reader_jpeg_bits_get         Extract a specified number of*/
781 /*                                             bits from JPEG data stream */
782 /*    _gx_image_reader_jpeg_bits_skip        Skips bits from tempory JPEG */
783 /*                                             data stream                */
784 /*    _gx_image_reader_jpeg_huffman_code_find                             */
785 /*                                           Lookup the huffman code      */
786 /*                                                                        */
787 /*  CALLED BY                                                             */
788 /*                                                                        */
789 /*    _gx_image_reader_jpeg_one_block_decode                              */
790 /*                                                                        */
791 /*  RELEASE HISTORY                                                       */
792 /*                                                                        */
793 /*    DATE              NAME                      DESCRIPTION             */
794 /*                                                                        */
795 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
796 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
797 /*                                            resulting in version 6.1    */
798 /*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
799 /*                                            added range test,           */
800 /*                                            resulting in version 6.2.0  */
801 /*                                                                        */
802 /**************************************************************************/
_gx_image_reader_jpeg_dc_decode(GX_JPEG_INFO * jpeg_info,UINT i_component)803 static UINT _gx_image_reader_jpeg_dc_decode(GX_JPEG_INFO *jpeg_info, UINT i_component)
804 {
805 UINT     scan_buffer;
806 UINT     i_bits = 0;
807 GX_UBYTE code_value;
808 INT      Diff;
809 UINT     table_index = jpeg_info -> gx_jpeg_dc_table_index[i_component];
810 GX_BOOL  negative;
811 
812     if (table_index >= HUFF_TABLE_DIMENSION)
813     {
814         return GX_FAILURE;
815     }
816 
817     _gx_image_reader_jpeg_bits_get(jpeg_info, 16, &scan_buffer);
818 
819     if (_gx_image_reader_jpeg_huffcode_find(jpeg_info, 0, table_index, scan_buffer, &i_bits, &code_value) == 0)
820     {
821         _gx_image_reader_jpeg_bits_skip(i_bits);
822 
823         if (code_value == 0)
824         {
825             jpeg_info -> gx_jpeg_vecter[0] = jpeg_info -> gx_jpeg_pre_dc[i_component];
826         }
827         else
828         {
829 
830             _gx_image_reader_jpeg_bits_get(jpeg_info, code_value, (UINT *)&Diff);
831             _gx_image_reader_jpeg_bits_skip(code_value);
832 
833             Diff = (INT)(((UINT)Diff) >> (32 - code_value));
834 
835             negative = !(Diff >> (code_value - 1));
836 
837             if (negative)
838             {
839                 Diff += 1 - (1 << code_value);
840             }
841 
842             jpeg_info -> gx_jpeg_vecter[0] = Diff + jpeg_info -> gx_jpeg_pre_dc[i_component];
843             jpeg_info -> gx_jpeg_pre_dc[i_component] = jpeg_info -> gx_jpeg_vecter[0];
844         }
845     }
846     else
847     {
848         return GX_FAILURE;
849     }
850 
851     return GX_SUCCESS;
852 }
853 
854 /**************************************************************************/
855 /*                                                                        */
856 /*  FUNCTION                                               RELEASE        */
857 /*                                                                        */
858 /*    _gx_image_reader_jpeg_ac_decode                     PORTABLE C      */
859 /*                                                           6.2.0        */
860 /*  AUTHOR                                                                */
861 /*                                                                        */
862 /*    Kenneth Maxwell, Microsoft Corporation                              */
863 /*                                                                        */
864 /*  DESCRIPTION                                                           */
865 /*                                                                        */
866 /*    Decode the AC component.                                            */
867 /*                                                                        */
868 /*  INPUT                                                                 */
869 /*                                                                        */
870 /*    jpeg_info                             JPEG data control block       */
871 /*    i_component                           Component index               */
872 /*                                                                        */
873 /*  OUTPUT                                                                */
874 /*                                                                        */
875 /*    Status Code                                                         */
876 /*                                                                        */
877 /*  CALLS                                                                 */
878 /*                                                                        */
879 /*    _gx_image_reader_jpeg_bits_get         Extract a specified number of*/
880 /*                                             bits from JPEG data stream */
881 /*    _gx_image_reader_jpeg_bits_skip        Skips bits from tempory JPEG */
882 /*                                             data stream                */
883 /*    _gx_image_reader_jpeg_huffman_code_find                             */
884 /*                                           Lookup the huffman code      */
885 /*                                                                        */
886 /*  CALLED BY                                                             */
887 /*                                                                        */
888 /*    _gx_image_reader_jpeg_one_block_decode                              */
889 /*                                                                        */
890 /*  RELEASE HISTORY                                                       */
891 /*                                                                        */
892 /*    DATE              NAME                      DESCRIPTION             */
893 /*                                                                        */
894 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
895 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
896 /*                                            resulting in version 6.1    */
897 /*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
898 /*                                            added range test,           */
899 /*                                            resulting in version 6.2.0  */
900 /*                                                                        */
901 /**************************************************************************/
_gx_image_reader_jpeg_ac_decode(GX_JPEG_INFO * jpeg_info,UINT i_component)902 static UINT _gx_image_reader_jpeg_ac_decode(GX_JPEG_INFO *jpeg_info, UINT i_component)
903 {
904 UINT     scan_buffer;
905 UINT     i_bits = 0;
906 GX_UBYTE code_value;
907 GX_UBYTE catogory;
908 GX_UBYTE runs_of_zero;
909 INT      ac_coefficient;
910 UINT     ac_counter = 1;
911 UINT     table_index = jpeg_info -> gx_jpeg_ac_table_index[i_component];
912 INT      negative;
913 
914     if (table_index >= HUFF_TABLE_DIMENSION)
915     {
916         return GX_FAILURE;
917     }
918 
919     while (ac_counter < 64)
920     {
921         i_bits = 0;
922         _gx_image_reader_jpeg_bits_get(jpeg_info, 16, &scan_buffer);
923 
924         if (_gx_image_reader_jpeg_huffcode_find(jpeg_info, 1, table_index, scan_buffer, &i_bits, &code_value) == 0)
925         {
926             _gx_image_reader_jpeg_bits_skip(i_bits);
927 
928             runs_of_zero = (0xf0 & code_value) >> 4;
929             catogory = 0x0f & code_value;
930 
931             if (catogory == 0)
932             {
933                 /* EOB encountered. */
934                 if (runs_of_zero == 0)
935                 {
936                     ac_counter = 64;
937                 }
938                 else if (runs_of_zero == 0x0f)
939                 {
940                     ac_counter += 16;
941                 }
942             }
943             else
944             {
945                 ac_counter += runs_of_zero;
946 
947                 _gx_image_reader_jpeg_bits_get(jpeg_info, catogory, (UINT *)&ac_coefficient);
948                 _gx_image_reader_jpeg_bits_skip(catogory);
949 
950                 ac_coefficient = (INT)(((UINT)ac_coefficient) >> (32 - catogory));
951 
952                 negative = !(ac_coefficient >> (catogory - 1));
953 
954                 if (negative)
955                 {
956                     ac_coefficient += 1 - (1 << catogory);
957                 }
958 
959                 if (ac_counter < 64)
960                 {
961                     jpeg_info -> gx_jpeg_vecter[ac_counter++] = ac_coefficient;
962                 }
963             }
964         }
965         else
966         {
967             return GX_FAILURE;
968         }
969     }
970 
971     return GX_SUCCESS;
972 }
973 
974 /* Define the triple Bufferfly Addition operation */
975 #define TRIPPLE_BUTTERFLY_ADDITION(a, b, c, d, r)  p = a + b, n = a - b, a = p + c + r, b = n + d + r, c = p - c + r, d = n - d + r
976 
977 /* Define the butterfly Multiplication */
978 #define BUTTERFLY_MULTIPLICATION(a, b, k1, k2, sh) n = k1 * (a + b), p = a, a = (n + (k2 - k1) * b) >> sh, b = (n - (k2 + k1) * p) >> sh
979 
980 /**************************************************************************/
981 /*                                                                        */
982 /*  FUNCTION                                               RELEASE        */
983 /*                                                                        */
984 /*    _gx_image_reader_jpeg_1d_idct                       PORTABLE C      */
985 /*                                                           6.1          */
986 /*  AUTHOR                                                                */
987 /*                                                                        */
988 /*    Kenneth Maxwell, Microsoft Corporation                              */
989 /*                                                                        */
990 /*  DESCRIPTION                                                           */
991 /*                                                                        */
992 /*    Performs 1D Inverse Discrete Consine Transformation.  It is an      */
993 /*    implementation of LLM (Loeffler, Lighenberg, Moschytz) algorithm.   */
994 /*                                                                        */
995 /*  INPUT                                                                 */
996 /*                                                                        */
997 /*    input_data                            Input data                    */
998 /*    output_data                           Buffer for output data        */
999 /*    post_scale                            Post scale value              */
1000 /*    round                                 Value to reduce round error   */
1001 /*                                                                        */
1002 /*  OUTPUT                                                                */
1003 /*                                                                        */
1004 /*    None                                                                */
1005 /*                                                                        */
1006 /*  CALLS                                                                 */
1007 /*                                                                        */
1008 /*    None                                                                */
1009 /*                                                                        */
1010 /*  CALLED BY                                                             */
1011 /*                                                                        */
1012 /*    _gx_image_reader_jpeg_2d_idct                                       */
1013 /*                                                                        */
1014 /*  RELEASE HISTORY                                                       */
1015 /*                                                                        */
1016 /*    DATE              NAME                      DESCRIPTION             */
1017 /*                                                                        */
1018 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1019 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1020 /*                                            resulting in version 6.1    */
1021 /*                                                                        */
1022 /**************************************************************************/
_gx_image_reader_jpeg_1d_idct(INT * input_data,INT * output_data,INT post_scale,INT round)1023 static VOID _gx_image_reader_jpeg_1d_idct(INT *input_data, INT *output_data, INT post_scale, INT round)
1024 {
1025 INT p;
1026 INT n;
1027 
1028     /* Prescale */
1029     input_data[0] <<= 9;
1030     input_data[1] <<= 7;
1031     input_data[3] *= 181;
1032     input_data[4] <<= 9;
1033     input_data[5] *= 181;
1034     input_data[7] <<= 7;
1035 
1036     /* iDCT computation .*/
1037     BUTTERFLY_MULTIPLICATION(input_data[6], input_data[2], 277, 669, 0);
1038     TRIPPLE_BUTTERFLY_ADDITION(input_data[0], input_data[4], input_data[6], input_data[2], round);
1039     TRIPPLE_BUTTERFLY_ADDITION(input_data[1], input_data[7], input_data[3], input_data[5], 0);
1040     BUTTERFLY_MULTIPLICATION(input_data[5], input_data[3], 251, 50, 6);
1041     BUTTERFLY_MULTIPLICATION(input_data[1], input_data[7], 213, 142, 6);
1042 
1043     /* Post-scale */
1044     output_data[0] = (input_data[0] + input_data[1]) >> post_scale;
1045     output_data[8] = (input_data[4] + input_data[5]) >> post_scale;
1046     output_data[16] = (input_data[2] + input_data[3]) >> post_scale;
1047     output_data[24] = (input_data[6] + input_data[7]) >> post_scale;
1048     output_data[32] = (input_data[6] - input_data[7]) >> post_scale;
1049     output_data[40] = (input_data[2] - input_data[3]) >> post_scale;
1050     output_data[48] = (input_data[4] - input_data[5]) >> post_scale;
1051     output_data[56] = (input_data[0] - input_data[1]) >> post_scale;
1052 }
1053 
1054 /**************************************************************************/
1055 /*                                                                        */
1056 /*  FUNCTION                                               RELEASE        */
1057 /*                                                                        */
1058 /*    _gx_image_reader_jpeg_2d_idct                       PORTABLE C      */
1059 /*                                                           6.1          */
1060 /*  AUTHOR                                                                */
1061 /*                                                                        */
1062 /*    Kenneth Maxwell, Microsoft Corporation                              */
1063 /*                                                                        */
1064 /*  DESCRIPTION                                                           */
1065 /*                                                                        */
1066 /*    Performs 2D Inverse Discrete Consine Transformation.                */
1067 /*                                                                        */
1068 /*  INPUT                                                                 */
1069 /*                                                                        */
1070 /*    block                                 Input data                    */
1071 /*                                                                        */
1072 /*  OUTPUT                                                                */
1073 /*                                                                        */
1074 /*    None                                                                */
1075 /*                                                                        */
1076 /*  CALLS                                                                 */
1077 /*                                                                        */
1078 /*     _gx_image_reader_jpeg_1d_idct        Perform 1D Inverse Discrete   */
1079 /*                                            Consine Transformation      */
1080 /*                                                                        */
1081 /*  CALLED BY                                                             */
1082 /*                                                                        */
1083 /*     _gx_image_reader_jpeg_dequantize_idct                              */
1084 /*                                                                        */
1085 /*  RELEASE HISTORY                                                       */
1086 /*                                                                        */
1087 /*    DATE              NAME                      DESCRIPTION             */
1088 /*                                                                        */
1089 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1090 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1091 /*                                            resulting in version 6.1    */
1092 /*                                                                        */
1093 /**************************************************************************/
_gx_image_reader_jpeg_2d_idct(INT * block)1094 static VOID _gx_image_reader_jpeg_2d_idct(INT *block)
1095 {
1096 INT i;
1097 INT temp_block[64];
1098 
1099     for (i = 0; i < 8; i++)
1100     {
1101         _gx_image_reader_jpeg_1d_idct(block + i * 8, temp_block + i, 9, 512); /* row */
1102     }
1103 
1104     for (i = 0; i < 8; i++)
1105     {
1106         _gx_image_reader_jpeg_1d_idct(temp_block + i * 8, block + i, 12, 2048); /* col */
1107     }
1108 }
1109 
1110 /**************************************************************************/
1111 /*                                                                        */
1112 /*  FUNCTION                                               RELEASE        */
1113 /*                                                                        */
1114 /*    _gx_image_reader_jpeg_dequantize_idct               PORTABLE C      */
1115 /*                                                           6.2.0        */
1116 /*  AUTHOR                                                                */
1117 /*                                                                        */
1118 /*    Kenneth Maxwell, Microsoft Corporation                              */
1119 /*                                                                        */
1120 /*  DESCRIPTION                                                           */
1121 /*                                                                        */
1122 /*    Dequatilizes decoded data and performs Inverse Discrete Consine     */
1123 /*    Transformation.                                                     */
1124 /*                                                                        */
1125 /*  INPUT                                                                 */
1126 /*                                                                        */
1127 /*    jpeg_info                             JPEG data control block       */
1128 /*    data                                  Pointer to decoded data       */
1129 /*    i_component                           Component index               */
1130 /*                                                                        */
1131 /*  OUTPUT                                                                */
1132 /*                                                                        */
1133 /*    None                                                                */
1134 /*                                                                        */
1135 /*  CALLS                                                                 */
1136 /*                                                                        */
1137 /*    _gx_image_reader_jpeg_2d_idct         Perform 2D Inverse Discrete   */
1138 /*                                            Consine Transformation      */
1139 /*    _gx_image_reader_jpeg_range           Limit value in range [0, 255] */
1140 /*                                                                        */
1141 /*  CALLED BY                                                             */
1142 /*                                                                        */
1143 /*    _gx_image_reader_jpeg_one_block_decode                              */
1144 /*                                                                        */
1145 /*  RELEASE HISTORY                                                       */
1146 /*                                                                        */
1147 /*    DATE              NAME                      DESCRIPTION             */
1148 /*                                                                        */
1149 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1150 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1151 /*                                            resulting in version 6.1    */
1152 /*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
1153 /*                                            added range check for       */
1154 /*                                            stride, changed return val, */
1155 /*                                            added range check for       */
1156 /*                                            table_index,                */
1157 /*                                            resulting in version 6.2.0  */
1158 /*                                                                        */
1159 /**************************************************************************/
_gx_image_reader_jpeg_dequantize_idct(GX_JPEG_INFO * jpeg_info,GX_UBYTE * data,UINT i_component)1160 static UINT _gx_image_reader_jpeg_dequantize_idct(GX_JPEG_INFO *jpeg_info, GX_UBYTE *data, UINT i_component)
1161 {
1162 INT       table_index;
1163 INT       stride;
1164 GX_UBYTE *outptr = data;
1165 INT       index;
1166 INT       x;
1167 INT       y;
1168 INT       jpeg_block[64];
1169 
1170     if (i_component >= JPG_MAX_COMPONENTS)
1171     {
1172         return GX_FAILURE;
1173     }
1174 
1175     stride = ((jpeg_info -> gx_jpeg_sample_factor[i_component] & 0xf0) >> 1);
1176 
1177     if (i_component == 0)
1178     {
1179         if (stride > 32)
1180         {
1181             return GX_FAILURE;
1182         }
1183     }
1184     else
1185     {
1186         if (stride > 8)
1187         {
1188             return GX_FAILURE;
1189         }
1190     }
1191 
1192     table_index = jpeg_info -> gx_jpeg_qantization_table_index[i_component];
1193 
1194     if (table_index >= JPG_QUANT_TABLE_DIMENSION)
1195     {
1196         return GX_FAILURE;
1197     }
1198 
1199     for (index = 0; index < 64; index++)
1200     {
1201         jpeg_info -> gx_jpeg_vecter[index] *= jpeg_info -> gx_jpeg_quantization_table[table_index][index];
1202 
1203         /* Reorder from zig-zag order to 8*8 block */
1204         jpeg_block[_gx_jpg_reorder_index[index]] = jpeg_info -> gx_jpeg_vecter[index];
1205     }
1206 
1207     _gx_image_reader_jpeg_2d_idct(jpeg_block);
1208 
1209     for (y = 0; y < 8; y++)
1210     {
1211         for (x = 0; x < 8; x++)
1212         {
1213             outptr[x] = _gx_image_reader_jpeg_range(jpeg_block[y * 8 + x] + 128);
1214         }
1215 
1216         outptr += stride;
1217     }
1218     return GX_SUCCESS;
1219 }
1220 
1221 /**************************************************************************/
1222 /*                                                                        */
1223 /*  FUNCTION                                               RELEASE        */
1224 /*                                                                        */
1225 /*    _gx_image_reader_jpeg_one_block_decode              PORTABLE C      */
1226 /*                                                           6.2.0        */
1227 /*  AUTHOR                                                                */
1228 /*                                                                        */
1229 /*    Kenneth Maxwell, Microsoft Corporation                              */
1230 /*                                                                        */
1231 /*  DESCRIPTION                                                           */
1232 /*                                                                        */
1233 /*    Decode one block of JPEG data.                                      */
1234 /*                                                                        */
1235 /*  INPUT                                                                 */
1236 /*                                                                        */
1237 /*    jpeg_info                             JPEG data control block       */
1238 /*    icomponent                            Component index               */
1239 /*    block_data                            Pointer to decoded data       */
1240 /*                                                                        */
1241 /*  OUTPUT                                                                */
1242 /*                                                                        */
1243 /*    Status Code                                                         */
1244 /*                                                                        */
1245 /*  CALLS                                                                 */
1246 /*                                                                        */
1247 /*    memset                                                              */
1248 /*    _gx_image_reader_jpeg_dc_decode       Decode dc component           */
1249 /*    _gx_image_reader_jpeg_ac_decode       Decode ac component           */
1250 /*    _gx_image_reader_jpeg_dequantize_idct Dequatilize decoded data      */
1251 /*                                                                        */
1252 /*  CALLED BY                                                             */
1253 /*                                                                        */
1254 /*    _gx_image_reader_jpeg_decode                                        */
1255 /*                                                                        */
1256 /*  RELEASE HISTORY                                                       */
1257 /*                                                                        */
1258 /*    DATE              NAME                      DESCRIPTION             */
1259 /*                                                                        */
1260 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1261 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1262 /*                                            resulting in version 6.1    */
1263 /*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
1264 /*                                            returned result of          */
1265 /*                                            dequantize_idct,            */
1266 /*                                            resulting in version 6.2.0  */
1267 /*                                                                        */
1268 /**************************************************************************/
_gx_image_reader_jpeg_one_block_decode(GX_JPEG_INFO * jpeg_info,UINT i_component,GX_UBYTE * block_data)1269 static UINT _gx_image_reader_jpeg_one_block_decode(GX_JPEG_INFO *jpeg_info, UINT i_component, GX_UBYTE *block_data)
1270 {
1271     UINT status = GX_SUCCESS;
1272 
1273     memset(jpeg_info -> gx_jpeg_vecter, 0, 64 * sizeof(UINT));
1274     _gx_image_reader_jpeg_dc_decode(jpeg_info, i_component);
1275     _gx_image_reader_jpeg_ac_decode(jpeg_info, i_component);
1276 
1277     status = _gx_image_reader_jpeg_dequantize_idct(jpeg_info, block_data, i_component);
1278 
1279     return status;
1280 }
1281 
1282 /**************************************************************************/
1283 /*                                                                        */
1284 /*  FUNCTION                                               RELEASE        */
1285 /*                                                                        */
1286 /*    _gx_image_reader_jpeg_one_mcu_write                 PORTABLE C      */
1287 /*                                                           6.1          */
1288 /*  AUTHOR                                                                */
1289 /*                                                                        */
1290 /*    Kenneth Maxwell, Microsoft Corporation                              */
1291 /*                                                                        */
1292 /*  DESCRIPTION                                                           */
1293 /*                                                                        */
1294 /*    Write decoded data of one MCU block into specified memory.          */
1295 /*                                                                        */
1296 /*  INPUT                                                                 */
1297 /*                                                                        */
1298 /*    jpeg_info                             JPEG control block            */
1299 /*    xpos                                  X position in image           */
1300 /*    ypos                                  y position in image           */
1301 /*                                                                        */
1302 /*  OUTPUT                                                                */
1303 /*                                                                        */
1304 /*    Status Code                                                         */
1305 /*                                                                        */
1306 /*  CALLS                                                                 */
1307 /*                                                                        */
1308 /*    _gx_image_reader_jpeg_YCbCr2RGB_888  Convert YCbCr value to 888RGB  */
1309 /*                                           color space                  */
1310 /*                                                                        */
1311 /*  CALLED BY                                                             */
1312 /*                                                                        */
1313 /*    _gx_image_reader_jpeg_decode                                        */
1314 /*                                                                        */
1315 /*  RELEASE HISTORY                                                       */
1316 /*                                                                        */
1317 /*    DATE              NAME                      DESCRIPTION             */
1318 /*                                                                        */
1319 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1320 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1321 /*                                            resulting in version 6.1    */
1322 /*                                                                        */
1323 /**************************************************************************/
_gx_image_reader_jpeg_one_mcu_write(GX_JPEG_INFO * jpeg_info,INT xpos,INT ypos)1324 static UINT _gx_image_reader_jpeg_one_mcu_write(GX_JPEG_INFO *jpeg_info, INT xpos, INT ypos)
1325 {
1326 GX_UBYTE *put;
1327 INT       x;
1328 INT       y;
1329 INT       w;
1330 INT       h;
1331 INT       coff;
1332 INT       Y;
1333 INT       Cb;
1334 INT       Cr;
1335 INT       width_in_bytes;
1336 
1337     h = (jpeg_info -> gx_jpeg_sample_factor[0] >> 4);
1338     w = (jpeg_info -> gx_jpeg_sample_factor[0] & 0x0f);
1339 
1340     width_in_bytes = jpeg_info -> gx_jpeg_width * 3;
1341     put = (GX_UBYTE *)jpeg_info -> gx_jpeg_decoded_data;
1342     put += ypos * width_in_bytes;
1343     put += xpos * 3;
1344 
1345     for (y = 0; y < 8 * h; y++)
1346     {
1347         if (ypos + y >= jpeg_info -> gx_jpeg_height)
1348         {
1349             break;
1350         }
1351 
1352         for (x = 0; x < 8 * w; x++)
1353         {
1354             if (xpos + x >= jpeg_info -> gx_jpeg_width)
1355             {
1356                 break;
1357             }
1358             coff = x / w + ((y / h) << 3);
1359 
1360             Y = jpeg_info -> gx_jpeg_Y_block[x + y * w * 8];
1361             Cb = jpeg_info -> gx_jpeg_Cb_block[coff];
1362             Cr = jpeg_info -> gx_jpeg_Cr_block[coff];
1363 
1364             _gx_image_reader_jpeg_YCbCr2RGB_888(Y, Cb, Cr, put + x * 3);
1365         }
1366 
1367         put += width_in_bytes;
1368     }
1369 
1370     return GX_SUCCESS;
1371 }
1372 
1373 /**************************************************************************/
1374 /*                                                                        */
1375 /*  FUNCTION                                               RELEASE        */
1376 /*                                                                        */
1377 /*    _gx_image_reader_jpeg_decompress                    PORTABLE C      */
1378 /*                                                           6.2.0        */
1379 /*  AUTHOR                                                                */
1380 /*                                                                        */
1381 /*    Kenneth Maxwell, Microsoft Corporation                              */
1382 /*                                                                        */
1383 /*  DESCRIPTION                                                           */
1384 /*                                                                        */
1385 /*    Decompress JPG data stream.                                         */
1386 /*                                                                        */
1387 /*  INPUT                                                                 */
1388 /*                                                                        */
1389 /*    jpeg_info                             JPEG control block            */
1390 /*                                                                        */
1391 /*  OUTPUT                                                                */
1392 /*                                                                        */
1393 /*    Status Code                                                         */
1394 /*                                                                        */
1395 /*  CALLS                                                                 */
1396 /*                                                                        */
1397 /*    _gx_image_reader_jpeg_one_block_decode                              */
1398 /*                                          Decode one blcok of jpeg data */
1399 /*    _gx_image_reader_jpeg_one_mcu_write   Write decoded data to         */
1400 /*                                            specified memory            */
1401 /*                                                                        */
1402 /*  CALLED BY                                                             */
1403 /*                                                                        */
1404 /*    _gx_image_reader_jpeg_decode                                        */
1405 /*                                                                        */
1406 /*  RELEASE HISTORY                                                       */
1407 /*                                                                        */
1408 /*    DATE              NAME                      DESCRIPTION             */
1409 /*                                                                        */
1410 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1411 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1412 /*                                            resulting in version 6.1    */
1413 /*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
1414 /*                                            abort if block decode fails,*/
1415 /*                                            resulting in version 6.2.0  */
1416 /*                                                                        */
1417 /**************************************************************************/
_gx_image_reader_jpeg_decompress(GX_JPEG_INFO * jpeg_info)1418 static UINT _gx_image_reader_jpeg_decompress(GX_JPEG_INFO *jpeg_info)
1419 {
1420 int h;
1421 int w;
1422 int x;
1423 int y;
1424 int xx;
1425 int yy;
1426 UINT status = GX_SUCCESS;
1427 
1428     _gx_jpg_bit_buffer = 0;
1429     _gx_jpg_bit_count = 0;
1430 
1431     h = jpeg_info -> gx_jpeg_height * 3;
1432     w = jpeg_info -> gx_jpeg_width * 3;
1433 
1434     h = (jpeg_info -> gx_jpeg_sample_factor[0] >> 4);
1435     w = (jpeg_info -> gx_jpeg_sample_factor[0] & 0x0f);
1436 
1437     if (jpeg_info -> gx_jpeg_mcu_draw == GX_NULL)
1438     {
1439         /* Safe int math is not required here, max width and height are limited to 14 bits so
1440            overflow cannot occur. */
1441         jpeg_info -> gx_jpeg_decoded_data_size = (UINT)(jpeg_info -> gx_jpeg_width * jpeg_info -> gx_jpeg_height * 3);
1442 
1443         /* Allocate memory to load decoded data. */
1444         jpeg_info -> gx_jpeg_decoded_data = (GX_UBYTE *)_gx_system_memory_allocator((ULONG)jpeg_info -> gx_jpeg_decoded_data_size);
1445 
1446         if (jpeg_info -> gx_jpeg_decoded_data == GX_NULL)
1447         {
1448             return GX_SYSTEM_MEMORY_ERROR;
1449         }
1450     }
1451 
1452     for (y = 0; y < jpeg_info -> gx_jpeg_height; y += 8 * h)
1453     {
1454         for (x = 0; x < jpeg_info -> gx_jpeg_width; x += 8 * w)
1455         {
1456             /* Decode one MCU */
1457             for (yy = 0; yy < h && status == GX_SUCCESS; yy++)
1458             {
1459                 for (xx = 0; xx < w && status == GX_SUCCESS; xx++)
1460                 {
1461                     /* Y */
1462                     status = _gx_image_reader_jpeg_one_block_decode(jpeg_info, 0, jpeg_info -> gx_jpeg_Y_block + yy * 128 + xx * 8);
1463                 }
1464             }
1465 
1466             if (status == GX_SUCCESS && jpeg_info -> gx_jpeg_num_of_components > 1)
1467             {
1468                 /* Cb */
1469                 status = _gx_image_reader_jpeg_one_block_decode(jpeg_info, 1, jpeg_info -> gx_jpeg_Cb_block);
1470 
1471                 /* Cr */
1472                 if (status == GX_SUCCESS)
1473                 {
1474                     status = _gx_image_reader_jpeg_one_block_decode(jpeg_info, 2, jpeg_info -> gx_jpeg_Cr_block);
1475                 }
1476             }
1477 
1478             if (status == GX_SUCCESS)
1479             {
1480                 if (jpeg_info -> gx_jpeg_mcu_draw)
1481                 {
1482                     if (jpeg_info -> gx_jpeg_draw_context)
1483                     {
1484                         jpeg_info -> gx_jpeg_mcu_draw(jpeg_info,
1485                                                       jpeg_info -> gx_jpeg_draw_xpos + x,
1486                                                       jpeg_info -> gx_jpeg_draw_ypos + y);
1487                     }
1488                 }
1489                 else
1490                 {
1491                     _gx_image_reader_jpeg_one_mcu_write(jpeg_info, x, y);
1492                 }
1493             }
1494         }
1495     }
1496 
1497     return status;
1498 }
1499 
1500 /**************************************************************************/
1501 /*                                                                        */
1502 /*  FUNCTION                                               RELEASE        */
1503 /*                                                                        */
1504 /*    _gx_image_reader_jpeg_decode_blocks                 PORTABLE C      */
1505 /*                                                           6.1          */
1506 /*  AUTHOR                                                                */
1507 /*                                                                        */
1508 /*    Kenneth Maxwell, Microsoft Corporation                              */
1509 /*                                                                        */
1510 /*  DESCRIPTION                                                           */
1511 /*                                                                        */
1512 /*    This function decode a jpg format image.                            */
1513 /*                                                                        */
1514 /*  INPUT                                                                 */
1515 /*                                                                        */
1516 /*    jpeg_info                             Jpeg decode control block     */
1517 /*                                                                        */
1518 /*  OUTPUT                                                                */
1519 /*                                                                        */
1520 /*    status                                Completion status             */
1521 /*                                                                        */
1522 /*  CALLS                                                                 */
1523 /*                                                                        */
1524 /*    _gx_image_reader_jpeg_quantization_table_set                        */
1525 /*                                          Set jpeg quantization table   */
1526 /*    _gx_image_reader_jpeg_frame_header_read                             */
1527 /*                                          Read frame header information */
1528 /*    _gx_image_reader_huffman_table_set    Set up huffman table          */
1529 /*    _gx_image_reader_jpeg_scan_header_read                              */
1530 /*                                          Read scan header information  */
1531 /*    _gx_image_reader_jpeg_decompress      Decompress jped data stream   */
1532 /*    _gx_system_memory_free                Application defined memory    */
1533 /*                                            free function               */
1534 /*                                                                        */
1535 /*  CALLED BY                                                             */
1536 /*                                                                        */
1537 /*    _gx_image_reader_jpeg_decode                                        */
1538 /*    _gx_image_reader_jpeg_mcu_decode                                    */
1539 /*                                                                        */
1540 /*  RELEASE HISTORY                                                       */
1541 /*                                                                        */
1542 /*    DATE              NAME                      DESCRIPTION             */
1543 /*                                                                        */
1544 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1545 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1546 /*                                            resulting in version 6.1    */
1547 /*                                                                        */
1548 /**************************************************************************/
_gx_image_reader_jpeg_decode_blocks(GX_JPEG_INFO * jpeg_info)1549 static UINT _gx_image_reader_jpeg_decode_blocks(GX_JPEG_INFO *jpeg_info)
1550 {
1551 GX_UBYTE *jpeg_data;
1552 GX_UBYTE  marker;
1553 UINT      segment_len;
1554 UINT      index;
1555 UINT      table_class;
1556 UINT      status = GX_SUCCESS;
1557 
1558     if (jpeg_info -> gx_jpeg_data == GX_NULL || jpeg_info -> gx_jpeg_data_size < 10)
1559     {
1560         return GX_INVALID_VALUE;
1561     }
1562 
1563     jpeg_data = jpeg_info -> gx_jpeg_data;
1564 
1565     /* Read JPEG File flag that mark the start of a JPEG image. */
1566     if ((*jpeg_data++ != 0xff) || (*jpeg_data++ != 0xd8))
1567     {
1568         return GX_INVALID_FORMAT; /*Not a jpeg file */
1569     }
1570 
1571     jpeg_info -> gx_jpeg_data_index += 2;
1572 
1573     while ((jpeg_info -> gx_jpeg_data_index + 3 < jpeg_info -> gx_jpeg_data_size) &&
1574            (status == GX_SUCCESS))
1575     {
1576         jpeg_data = (jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index);
1577         marker = *(jpeg_data + 1);
1578 
1579         if ((*jpeg_data == 0xff) && (marker != 0) && (marker != 0xff))
1580         {
1581             jpeg_data += 2;
1582             jpeg_info -> gx_jpeg_data_index += 2;
1583 
1584             /* Read WORD length */
1585             segment_len = *(jpeg_data);
1586             segment_len <<= 8;
1587             segment_len |= *(jpeg_data + 1);
1588 
1589             if ((UINT)jpeg_info -> gx_jpeg_data_index + segment_len > (UINT)jpeg_info -> gx_jpeg_data_size)
1590             {
1591                 /* Invalid data size. */
1592                 status = GX_FAILURE;
1593                 break;
1594             }
1595 
1596             switch (marker)
1597             {
1598             case 0xdb:
1599                 /* Define Quantization Table */
1600                 status = _gx_image_reader_jpeg_quantization_table_set(jpeg_info, segment_len);
1601                 break;
1602 
1603             case 0xc0:
1604                 /* Start of Frame */
1605                 status = _gx_image_reader_jpeg_frame_header_read(jpeg_info, segment_len);
1606                 break;
1607 
1608             case 0xc4:
1609                 /* Define Huffman Table */
1610                 status = _gx_image_reader_huffman_table_set(jpeg_info, segment_len);
1611                 break;
1612 
1613             case 0xdd:
1614                 /* Read restart interval which specifies the number of MCU in restart interval. */
1615                 jpeg_data += 2;
1616                 jpeg_info -> gx_jpeg_restart_interval = *jpeg_data++;
1617                 jpeg_info -> gx_jpeg_restart_interval <<= 8;
1618                 jpeg_info -> gx_jpeg_restart_interval |= *jpeg_data++;
1619                 jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
1620                 break;
1621 
1622             case 0xda:
1623                 /* Start of Scan, stores which Huffman tables are associated with which components
1624                    The program start decoding the data section directly after it reads in this header. */
1625                 _gx_image_reader_jpeg_scan_header_read(jpeg_info, segment_len);
1626 
1627                 /* Start decoding jpeg data stream. */
1628                 status = _gx_image_reader_jpeg_decompress(jpeg_info);
1629                 break;
1630 
1631             default:
1632                 /* Unkown marker, skip */
1633                 jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
1634                 break;
1635             }
1636         }
1637         else
1638         {
1639             jpeg_info -> gx_jpeg_data_index++;
1640         }
1641     }
1642 
1643     for (table_class = 0; table_class < 2; table_class++)
1644     {
1645         for (index = 0; index < 2; index++)
1646         {
1647             if (jpeg_info -> gx_jpeg_huffman_table[table_class][index])
1648             {
1649                 _gx_system_memory_free(jpeg_info -> gx_jpeg_huffman_table[table_class][index]);
1650             }
1651         }
1652     }
1653 
1654     return status;
1655 }
1656 
1657 /**************************************************************************/
1658 /*                                                                        */
1659 /*  FUNCTION                                               RELEASE        */
1660 /*                                                                        */
1661 /*    _gx_image_reader_jpeg_decode                        PORTABLE C      */
1662 /*                                                           6.1          */
1663 /*  AUTHOR                                                                */
1664 /*                                                                        */
1665 /*    Kenneth Maxwell, Microsoft Corporation                              */
1666 /*                                                                        */
1667 /*  DESCRIPTION                                                           */
1668 /*                                                                        */
1669 /*    This function decodes a jpg format image and saves the decoded data */
1670 /*    to a GX_PIXELMAP structure.                                         */
1671 /*                                                                        */
1672 /*  INPUT                                                                 */
1673 /*                                                                        */
1674 /*    read_data                             Input JPEG data stream        */
1675 /*    data_size                             JPEG size in bytes            */
1676 /*    outmap                                Output pixelmap               */
1677 /*                                                                        */
1678 /*  OUTPUT                                                                */
1679 /*                                                                        */
1680 /*    status                                Completion status             */
1681 /*                                                                        */
1682 /*  CALLS                                                                 */
1683 /*                                                                        */
1684 /*    _gx_image_reader_jpeg_decode_blocks   Decode a jpeg format image    */
1685 /*                                                                        */
1686 /*  CALLED BY                                                             */
1687 /*                                                                        */
1688 /*    _gx_image_reader_image_decode                                       */
1689 /*                                                                        */
1690 /*  RELEASE HISTORY                                                       */
1691 /*                                                                        */
1692 /*    DATE              NAME                      DESCRIPTION             */
1693 /*                                                                        */
1694 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1695 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1696 /*                                            resulting in version 6.1    */
1697 /*                                                                        */
1698 /**************************************************************************/
_gx_image_reader_jpeg_decode(GX_CONST GX_UBYTE * read_data,ULONG data_size,GX_PIXELMAP * outmap)1699 UINT _gx_image_reader_jpeg_decode(GX_CONST GX_UBYTE *read_data, ULONG data_size,
1700                                   GX_PIXELMAP *outmap)
1701 {
1702 UINT          status;
1703 GX_JPEG_INFO *jpeg_info;
1704 
1705 
1706     if ((!_gx_system_memory_allocator) || (!_gx_system_memory_free))
1707     {
1708         return GX_SYSTEM_MEMORY_ERROR;
1709     }
1710 
1711     jpeg_info = (GX_JPEG_INFO *)_gx_system_memory_allocator(sizeof(GX_JPEG_INFO));
1712 
1713     if (!jpeg_info)
1714     {
1715         return GX_SYSTEM_MEMORY_ERROR;
1716     }
1717 
1718     memset(jpeg_info, 0, sizeof(GX_JPEG_INFO));
1719 
1720     jpeg_info -> gx_jpeg_data = (GX_UBYTE *)read_data;
1721     jpeg_info -> gx_jpeg_data_size = (INT)data_size;
1722     jpeg_info -> gx_jpeg_data_index = 0;
1723     jpeg_info -> gx_jpeg_draw_context = GX_NULL;
1724 
1725     status = _gx_image_reader_jpeg_decode_blocks(jpeg_info);
1726 
1727     if (status == GX_SUCCESS)
1728     {
1729         outmap -> gx_pixelmap_data = jpeg_info -> gx_jpeg_decoded_data;
1730         outmap -> gx_pixelmap_data_size = jpeg_info -> gx_jpeg_decoded_data_size;
1731         outmap -> gx_pixelmap_width = (GX_VALUE)jpeg_info -> gx_jpeg_width;
1732         outmap -> gx_pixelmap_height = (GX_VALUE)jpeg_info -> gx_jpeg_height;
1733         outmap -> gx_pixelmap_flags = GX_PIXELMAP_RAW_FORMAT;
1734         outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_24BPP;
1735     }
1736 
1737     _gx_system_memory_free((void *)jpeg_info);
1738 
1739     return status;
1740 }
1741 
1742 /**************************************************************************/
1743 /*                                                                        */
1744 /*  FUNCTION                                               RELEASE        */
1745 /*                                                                        */
1746 /*    _gx_image_reader_jpeg_mcu_decode                    PORTABLE C      */
1747 /*                                                           6.1          */
1748 /*  AUTHOR                                                                */
1749 /*                                                                        */
1750 /*    Kenneth Maxwell, Microsoft Corporation                              */
1751 /*                                                                        */
1752 /*  DESCRIPTION                                                           */
1753 /*                                                                        */
1754 /*    This function decodes a jpg format image and draw it to canvas      */
1755 /*    directly.                                                           */
1756 /*                                                                        */
1757 /*  INPUT                                                                 */
1758 /*                                                                        */
1759 /*    read_data                             Input JPEG data               */
1760 /*    data_size                             JPEG size in bytes            */
1761 /*    context                               Drawing contex                */
1762 /*    xpos                                  X-coord of draw start point in*/
1763 /*                                            canvas                      */
1764 /*    ypos                                  Y-coord of draw start point in*/
1765 /*                                            canvas                      */
1766 /*    draw_function                         Callback of one mcu draw      */
1767 /*                                                                        */
1768 /*  OUTPUT                                                                */
1769 /*                                                                        */
1770 /*    status                                Completion status             */
1771 /*                                                                        */
1772 /*  CALLS                                                                 */
1773 /*                                                                        */
1774 /*    _gx_image_reader_jpeg_decode_blocks   Decode a jpeg format image    */
1775 /*                                                                        */
1776 /*  CALLED BY                                                             */
1777 /*                                                                        */
1778 /*    GUIX Internal Code                                                  */
1779 /*                                                                        */
1780 /*  RELEASE HISTORY                                                       */
1781 /*                                                                        */
1782 /*    DATE              NAME                      DESCRIPTION             */
1783 /*                                                                        */
1784 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1785 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1786 /*                                            resulting in version 6.1    */
1787 /*                                                                        */
1788 /**************************************************************************/
_gx_image_reader_jpeg_mcu_decode(GX_CONST GX_UBYTE * read_data,ULONG data_size,GX_DRAW_CONTEXT * context,INT xpos,INT ypos,UINT (draw_function)(GX_JPEG_INFO *,INT,INT))1789 UINT _gx_image_reader_jpeg_mcu_decode(GX_CONST GX_UBYTE *read_data, ULONG data_size,
1790                                       GX_DRAW_CONTEXT *context, INT xpos, INT ypos,
1791                                       UINT(draw_function)(GX_JPEG_INFO *, INT, INT))
1792 {
1793 UINT          status;
1794 GX_JPEG_INFO *jpeg_info;
1795 
1796     if ((!_gx_system_memory_allocator) || (!_gx_system_memory_free))
1797     {
1798         return GX_SYSTEM_MEMORY_ERROR;
1799     }
1800 
1801     jpeg_info = (GX_JPEG_INFO *)_gx_system_memory_allocator(sizeof(GX_JPEG_INFO));
1802 
1803     if (!jpeg_info)
1804     {
1805         return GX_SYSTEM_MEMORY_ERROR;
1806     }
1807 
1808     memset(jpeg_info, 0, sizeof(GX_JPEG_INFO));
1809 
1810     jpeg_info -> gx_jpeg_data = (GX_UBYTE *)read_data;
1811     jpeg_info -> gx_jpeg_data_size = (INT)data_size;
1812     jpeg_info -> gx_jpeg_data_index = 0;
1813     jpeg_info -> gx_jpeg_draw_context = context;
1814     jpeg_info -> gx_jpeg_mcu_draw = draw_function;
1815     jpeg_info -> gx_jpeg_draw_xpos = xpos;
1816     jpeg_info -> gx_jpeg_draw_ypos = ypos;
1817 
1818     status = _gx_image_reader_jpeg_decode_blocks(jpeg_info);
1819 
1820     _gx_system_memory_free((void *)jpeg_info);
1821 
1822     return status;
1823 }
1824 #endif
1825 
1826