GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_image_reader_jpeg_decode.c Lines: 438 453 96.7 %
Date: 2024-12-05 08:52:37 Branches: 248 276 89.9 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** GUIX Component                                                        */
16
/**                                                                       */
17
/**   Utility Management (Utility)                                        */
18
/**                                                                       */
19
/**************************************************************************/
20
21
#define GX_SOURCE_CODE
22
23
/* Include necessary system files.  */
24
25
#include "gx_api.h"
26
#include "gx_context.h"
27
#include "gx_system.h"
28
#include "gx_utility.h"
29
#include "gx_image_reader.h"
30
31
#if defined(GX_SOFTWARE_DECODER_SUPPORT)
32
33
#define GX_SATURATE_TO_UBYTE(result, i) \
34
    {                                   \
35
        if ((i) < 0)                    \
36
        {                               \
37
            (result) = 0;               \
38
        }                               \
39
        else if ((i) > 255)             \
40
        {                               \
41
            (result) = 255;             \
42
        }                               \
43
        else                            \
44
        {                               \
45
            (result) = (GX_UBYTE)(i);   \
46
        }                               \
47
    }
48
49
#define GX_SATURATE_TO_BYTE(result, i) \
50
    {                                  \
51
        if ((i) < -128)                \
52
        {                              \
53
            (result) = -128;           \
54
        }                              \
55
        else if ((i) > 127)            \
56
        {                              \
57
            (result) = 127;            \
58
        }                              \
59
        else                           \
60
        {                              \
61
            (result) = (GX_BYTE)(i);   \
62
        }                              \
63
    }
64
65
#define GX_JPEG_BITS_GET(jpeg_info, num_of_bits)                                                                                                                    \
66
    while (jpeg_info -> gx_jpeg_bit_count <= num_of_bits)                                                                                                           \
67
    {                                                                                                                                                               \
68
        if ((jpeg_info -> gx_jpeg_data_index < jpeg_info -> gx_jpeg_data_size) && (jpeg_info -> gx_jpeg_bit_count <= 24))                                           \
69
        {                                                                                                                                                           \
70
            jpeg_info -> gx_jpeg_bit_buffer |= ((UINT)(jpeg_info -> gx_jpeg_data[jpeg_info -> gx_jpeg_data_index]) << (UINT)(24 - jpeg_info -> gx_jpeg_bit_count)); \
71
                                                                                                                                                                    \
72
            /* 2 byte 'FF00' sequence should be considered as just a byte 0xFF. */                                                                                  \
73
            if ((jpeg_info -> gx_jpeg_data[jpeg_info -> gx_jpeg_data_index] == 0xff) &&                                                                             \
74
                (jpeg_info -> gx_jpeg_data_index + 1 < jpeg_info -> gx_jpeg_data_size) &&                                                                           \
75
                (jpeg_info -> gx_jpeg_data[jpeg_info -> gx_jpeg_data_index + 1] == 0x00))                                                                           \
76
            {                                                                                                                                                       \
77
                jpeg_info -> gx_jpeg_data_index += 2;                                                                                                               \
78
            }                                                                                                                                                       \
79
            else                                                                                                                                                    \
80
            {                                                                                                                                                       \
81
                jpeg_info -> gx_jpeg_data_index += 1;                                                                                                               \
82
            }                                                                                                                                                       \
83
        }                                                                                                                                                           \
84
                                                                                                                                                                    \
85
        jpeg_info -> gx_jpeg_bit_count += 8;                                                                                                                        \
86
    }
87
88
#define GX_JPEG_BITS_SKIP(jpeg_info, skip_bits)        \
89
    (jpeg_info) -> gx_jpeg_bit_buffer <<= (skip_bits); \
90
    (jpeg_info) -> gx_jpeg_bit_count -= (skip_bits);
91
92
/**************************************************************************/
93
/*                                                                        */
94
/*  FUNCTION                                               RELEASE        */
95
/*                                                                        */
96
/*    _gx_dislay_driver_jpeg_quantization_table_set       PORTABLE C      */
97
/*                                                           6.2.0        */
98
/*  AUTHOR                                                                */
99
/*                                                                        */
100
/*    Kenneth Maxwell, Microsoft Corporation                              */
101
/*                                                                        */
102
/*  DESCRIPTION                                                           */
103
/*                                                                        */
104
/*    Sets the JPEG quantization table.                                   */
105
/*                                                                        */
106
/*  INPUT                                                                 */
107
/*                                                                        */
108
/*    jpeg_info                             JPEG data control block       */
109
/*    segment_len                           Initial length of the segment */
110
/*                                                                        */
111
/*  OUTPUT                                                                */
112
/*                                                                        */
113
/*    None                                                                */
114
/*                                                                        */
115
/*  CALLS                                                                 */
116
/*                                                                        */
117
/*    None                                                                */
118
/*                                                                        */
119
/*  CALLED BY                                                             */
120
/*                                                                        */
121
/*    _gx_image_reader_jpeg_decode                                        */
122
/*                                                                        */
123
/*  RELEASE HISTORY                                                       */
124
/*                                                                        */
125
/*    DATE              NAME                      DESCRIPTION             */
126
/*                                                                        */
127
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
128
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
129
/*                                            resulting in version 6.1    */
130
/*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
131
/*                                            prevented underflow from    */
132
/*                                            bad input data,             */
133
/*                                            resulting in version 6.2.0  */
134
/*                                                                        */
135
/**************************************************************************/
136
842
static UINT _gx_image_reader_jpeg_quantization_table_set(GX_JPEG_INFO *jpeg_info, UINT segment_len)
137
{
138
GX_UBYTE  table_index;
139
842
GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index;
140
INT       index;
141
142
    /* Minus two-byte length. */
143
842
    jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
144
842
    segment_len -= 2;
145
842
    jpeg_data += 2;
146
147
2022
    while (segment_len)
148
    {
149
        /* The upper 4 bits specify the element precision: 0 indicates 8-bit, 1 indecates 16-bit. */
150
1181
        if ((*jpeg_data) & 0xf0)
151
        {
152
            /* Baseline DCT-based jpeg only support 8-bit precision. */
153
1
            return GX_NOT_SUPPORTED;
154
        }
155
156
        /* The lower 4 bits specify the table destination identifier, specify one of four possible destinations. */
157
1180
        table_index = (*jpeg_data++) & 0x03;
158
159
        /* Read quantization table element. */
160
76700
        for (index = 0; index < 64; index++)
161
        {
162
75520
            jpeg_info -> gx_jpeg_quantization_table[table_index][index] = *jpeg_data++;
163
        }
164
165
1180
        if (segment_len < 65)
166
        {
167
            return GX_INVALID_FORMAT;
168
        }
169
1180
        segment_len -= 65;
170
    }
171
172
841
    return GX_SUCCESS;
173
}
174
175
/**************************************************************************/
176
/*                                                                        */
177
/*  FUNCTION                                               RELEASE        */
178
/*                                                                        */
179
/*    _gx_image_reader_jpeg_huffcode_find                 PORTABLE C      */
180
/*                                                           6.3.0        */
181
/*  AUTHOR                                                                */
182
/*                                                                        */
183
/*    Kenneth Maxwell, Microsoft Corporation                              */
184
/*                                                                        */
185
/*  DESCRIPTION                                                           */
186
/*                                                                        */
187
/*    Lookup the huffman code.                                            */
188
/*                                                                        */
189
/*  INPUT                                                                 */
190
/*                                                                        */
191
/*    jpeg_info                             JPEG data control block       */
192
/*    table_class                           Table class, 0 = DC table,    */
193
/*                                          1 = AC table                  */
194
/*    table_id                              Table index                   */
195
/*    scan_buffer                           Buffer to search from         */
196
/*    bit_len                               Retrieved Huffman Code Length */
197
/*    code_value                            Retrieved Huffman Code        */
198
/*                                                                        */
199
/*  OUTPUT                                                                */
200
/*                                                                        */
201
/*    Status Code                                                         */
202
/*                                                                        */
203
/*  CALLS                                                                 */
204
/*                                                                        */
205
/*    None                                                                */
206
/*                                                                        */
207
/*  CALLED BY                                                             */
208
/*                                                                        */
209
/*    _gx_image_reader_jpeg_dc_decode                                     */
210
/*    _gx_image_reader_jpeg_ac_decode                                     */
211
/*                                                                        */
212
/*  RELEASE HISTORY                                                       */
213
/*                                                                        */
214
/*    DATE              NAME                      DESCRIPTION             */
215
/*                                                                        */
216
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
217
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
218
/*                                            resulting in version 6.1    */
219
/*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
220
/*                                            changed bit_count to        */
221
/*                                            GX_VALUE data type,         */
222
/*                                            resulting in version 6.2.0  */
223
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
224
/*                                            improved logic,             */
225
/*                                            resulting in version 6.3.0  */
226
/*                                                                        */
227
/**************************************************************************/
228
28037764
static UINT _gx_image_reader_jpeg_huffcode_find(GX_JPEG_INFO *jpeg_info,
229
                                                UINT table_class,
230
                                                UINT table_id,
231
                                                UINT *bit_len,
232
                                                GX_UBYTE *code_value)
233
{
234
GX_UBYTE          index;
235
USHORT            code;
236
USHORT            code_index;
237
GX_HUFFCODE_INFO *code_info;
238
239
72498987
    for (index = 0; index < 16; index++)
240
    {
241
72498987
        code_info = &jpeg_info -> gx_jpeg_huffman_code_info[table_class][table_id][index];
242
72498987
        if (code_info -> bits)
243
        {
244
72498664
            code = (USHORT)((jpeg_info -> gx_jpeg_bit_buffer) >> (32 - code_info -> bits));
245
246
72498664
            if (code <= code_info -> end)
247
            {
248
28037441
                code_index = (USHORT)(code_info -> index + code - code_info -> start);
249
28037441
                *bit_len = code_info -> bits;
250
28037441
                *code_value = jpeg_info -> gx_jpeg_huffman_table[table_class][table_id][code_index];
251
28037441
                return GX_SUCCESS;
252
            }
253
        }
254
        else
255
        {
256
323
            break;
257
        }
258
    }
259
260
323
    return GX_FAILURE;
261
}
262
263
/**************************************************************************/
264
/*                                                                        */
265
/*  FUNCTION                                               RELEASE        */
266
/*                                                                        */
267
/*    _gx_image_reader_huffman_table_set                  PORTABLE C      */
268
/*                                                           6.3.0        */
269
/*  AUTHOR                                                                */
270
/*                                                                        */
271
/*    Kenneth Maxwell, Microsoft Corporation                              */
272
/*                                                                        */
273
/*  DESCRIPTION                                                           */
274
/*                                                                        */
275
/*    Sets up the huffman table.                                          */
276
/*                                                                        */
277
/*  INPUT                                                                 */
278
/*                                                                        */
279
/*    jpeg_info                             JPEG data control block       */
280
/*    segment_len                           Initial length of the segment */
281
/*                                                                        */
282
/*  OUTPUT                                                                */
283
/*                                                                        */
284
/*    None                                                                */
285
/*                                                                        */
286
/*  CALLS                                                                 */
287
/*                                                                        */
288
/*    None                                                                */
289
/*                                                                        */
290
/*  CALLED BY                                                             */
291
/*                                                                        */
292
/*    _gx_image_reader_jpeg_decode_blocks                                 */
293
/*                                                                        */
294
/*  RELEASE HISTORY                                                       */
295
/*                                                                        */
296
/*    DATE              NAME                      DESCRIPTION             */
297
/*                                                                        */
298
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
299
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
300
/*                                            resulting in version 6.1    */
301
/*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
302
/*                                            added range test to prevent */
303
/*                                            underflow,                  */
304
/*                                            resulting in version 6.2.0  */
305
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
306
/*                                            improved logic,             */
307
/*                                            resulting in version 6.3.0  */
308
/*                                                                        */
309
/**************************************************************************/
310
1335
static UINT _gx_image_reader_huffman_table_set(GX_JPEG_INFO *jpeg_info, UINT segment_len)
311
{
312
1335
GX_UBYTE         *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index;
313
GX_UBYTE          table_class;
314
GX_UBYTE          table_id;
315
GX_UBYTE          bit_count;
316
UINT              i_bits;
317
USHORT            i_table_size;
318
GX_HUFFCODE_INFO *code_info;
319
1335
INT               index = 0;
320
1335
USHORT            code = 0;
321
322
    /* must have at least one code for each of 16 huffman bit lengths */
323
1335
    if (segment_len < 19)
324
    {
325
        return GX_INVALID_FORMAT;
326
    }
327
328
    /* Minus two-byte length. */
329
1335
    jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
330
1335
    segment_len -= 2;
331
1335
    jpeg_data += 2;
332
333
3687
    while (segment_len)
334
    {
335
        /* table_calss: 0 DC 1 AC */
336
2352
        table_class = ((*jpeg_data) >> 4) & 1;
337
2352
        table_id = (*jpeg_data++) & 0x01;
338
339
2352
        if (segment_len < 17)
340
        {
341
            return GX_INVALID_FORMAT;
342
        }
343
2352
        segment_len -= 17;
344
345
2352
        i_table_size = 0;
346
347
2352
        index = 0;
348
2352
        code = 0;
349
350
        /* Read the number of Huffman codes for each bit length, from 1 to 16. */
351
39984
        for (i_bits = 0; i_bits < 16; i_bits++)
352
        {
353
37632
            bit_count = *jpeg_data++;
354
355
37632
            if (bit_count)
356
            {
357
24977
                code_info = &jpeg_info -> gx_jpeg_huffman_code_info[table_class][table_id][index++];
358
24977
                code_info -> index = i_table_size;
359
24977
                code_info -> start = code;
360
24977
                code_info -> end = (USHORT)(code + bit_count - 1);
361
24977
                code_info -> bits = (GX_UBYTE)(i_bits + 1);
362
            }
363
37632
            code = (USHORT)((code + bit_count) << 1);
364
365
37632
            i_table_size = (USHORT)(i_table_size + bit_count);
366
        }
367
368
2352
        if (segment_len < i_table_size)
369
        {
370
            return GX_INVALID_FORMAT;
371
        }
372
373
2352
        segment_len -= i_table_size;
374
375
        /* Load the start address of the specified huffman table. */
376
2352
        jpeg_info -> gx_jpeg_huffman_table[table_class][table_id] = jpeg_data;
377
2352
        jpeg_data += i_table_size;
378
    }
379
380
1335
    return GX_SUCCESS;
381
}
382
383
/**************************************************************************/
384
/*                                                                        */
385
/*  FUNCTION                                               RELEASE        */
386
/*                                                                        */
387
/*    _gx_display_driver_jpeg_frame_header_read           PORTABLE C      */
388
/*                                                           6.1          */
389
/*  AUTHOR                                                                */
390
/*                                                                        */
391
/*    Kenneth Maxwell, Microsoft Corporation                              */
392
/*                                                                        */
393
/*  DESCRIPTION                                                           */
394
/*                                                                        */
395
/*    Reads in the frame header infomration.                              */
396
/*                                                                        */
397
/*  INPUT                                                                 */
398
/*                                                                        */
399
/*    jpeg_info                             JPEG data control block       */
400
/*    segment_len                           Initial length of the segment */
401
/*                                                                        */
402
/*  OUTPUT                                                                */
403
/*                                                                        */
404
/*    None                                                                */
405
/*                                                                        */
406
/*  CALLS                                                                 */
407
/*                                                                        */
408
/*    None                                                                */
409
/*                                                                        */
410
/*  CALLED BY                                                             */
411
/*                                                                        */
412
/*    _gx_image_reader_jpeg_decode_blocks                                 */
413
/*                                                                        */
414
/*  RELEASE HISTORY                                                       */
415
/*                                                                        */
416
/*    DATE              NAME                      DESCRIPTION             */
417
/*                                                                        */
418
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
419
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
420
/*                                            resulting in version 6.1    */
421
/*                                                                        */
422
/**************************************************************************/
423
590
static UINT _gx_image_reader_jpeg_frame_header_read(GX_JPEG_INFO *jpeg_info, UINT segment_len)
424
{
425
590
GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index;
426
INT       i_component;
427
428
590
    jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
429
590
    jpeg_data += 2;
430
431
    /* Skip precision field. */
432
590
    jpeg_data++;
433
434
    /* Read image width, WORD */
435
590
    jpeg_info -> gx_jpeg_height = *jpeg_data++;
436
590
    jpeg_info -> gx_jpeg_height = (USHORT)(jpeg_info -> gx_jpeg_height << 8);
437
590
    jpeg_info -> gx_jpeg_height = (USHORT)(jpeg_info -> gx_jpeg_height | (*jpeg_data++));
438
439
    /* Limit max jpeg height to 14 bits. */
440
590
    if (jpeg_info -> gx_jpeg_height > GX_MAX_PIXELMAP_RESOLUTION)
441
    {
442
1
        return GX_INVALID_HEIGHT;
443
    }
444
445
    /* Read image height, WORD */
446
589
    jpeg_info -> gx_jpeg_width = *jpeg_data++;
447
589
    jpeg_info -> gx_jpeg_width = (USHORT)(jpeg_info -> gx_jpeg_width << 8);
448
589
    jpeg_info -> gx_jpeg_width = (USHORT)(jpeg_info -> gx_jpeg_width | (*jpeg_data++));
449
450
    /* Limit max jpeg width to 14 bits. */
451
589
    if (jpeg_info -> gx_jpeg_width > GX_MAX_PIXELMAP_RESOLUTION)
452
    {
453
1
        return GX_INVALID_WIDTH;
454
    }
455
456
    /* Read image components. */
457
588
    jpeg_info -> gx_jpeg_num_of_components = *jpeg_data++;
458
459
588
    if (jpeg_info -> gx_jpeg_num_of_components > JPG_MAX_COMPONENTS)
460
    {
461
        return GX_FAILURE;
462
    }
463
464
2350
    for (i_component = 0; i_component < jpeg_info -> gx_jpeg_num_of_components; i_component++)
465
    {
466
        /* Read component id */
467
1762
        jpeg_info -> gx_jpeg_component_id[i_component] = *jpeg_data++;
468
469
        /* Read sample factor */
470
1762
        jpeg_info -> gx_jpeg_sample_factor[i_component] = *jpeg_data++;
471
472
        /* Read quantization table index */
473
1762
        jpeg_info -> gx_jpeg_qantization_table_index[i_component] = *jpeg_data++;
474
    }
475
476
588
    return GX_SUCCESS;
477
}
478
479
/**************************************************************************/
480
/*                                                                        */
481
/*  FUNCTION                                               RELEASE        */
482
/*                                                                        */
483
/*    _gx_image_reader_jpeg_scan_header_read              PORTABLE C      */
484
/*                                                           6.1          */
485
/*  AUTHOR                                                                */
486
/*                                                                        */
487
/*    Kenneth Maxwell, Microsoft Corporation                              */
488
/*                                                                        */
489
/*  DESCRIPTION                                                           */
490
/*                                                                        */
491
/*    Reads in the scan header information.                               */
492
/*                                                                        */
493
/*  INPUT                                                                 */
494
/*                                                                        */
495
/*    jpeg_info                             JPEG data control block       */
496
/*    segment_len                           Initial length of the segment */
497
/*                                                                        */
498
/*  OUTPUT                                                                */
499
/*                                                                        */
500
/*    None                                                                */
501
/*                                                                        */
502
/*  CALLS                                                                 */
503
/*                                                                        */
504
/*    None                                                                */
505
/*                                                                        */
506
/*  CALLED BY                                                             */
507
/*                                                                        */
508
/*    _gx_image_reader_jpeg_decode_blocks                                 */
509
/*                                                                        */
510
/*  RELEASE HISTORY                                                       */
511
/*                                                                        */
512
/*    DATE              NAME                      DESCRIPTION             */
513
/*                                                                        */
514
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
515
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
516
/*                                            resulting in version 6.1    */
517
/*                                                                        */
518
/**************************************************************************/
519
588
static UINT _gx_image_reader_jpeg_scan_header_read(GX_JPEG_INFO *jpeg_info, UINT segment_len)
520
{
521
588
GX_UBYTE *jpeg_data = jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index;
522
INT       index;
523
524
588
    jpeg_data += 2;
525
588
    jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
526
527
    /* Read the number of image components.  */
528
588
    jpeg_info -> gx_jpeg_num_of_components = *jpeg_data++;
529
530
588
    if (jpeg_info -> gx_jpeg_num_of_components > JPG_MAX_COMPONENTS)
531
    {
532
        return GX_FAILURE;
533
    }
534
535
2350
    for (index = 0; index < jpeg_info -> gx_jpeg_num_of_components; index++)
536
    {
537
        /* skip image component */
538
1762
        jpeg_data++;
539
540
        /* high bits correspond to DC table index.
541
           low bits correspond to AC table index
542
           0: Y Huffman table
543
           1: Chrominance Huffman table. */
544
1762
        jpeg_info -> gx_jpeg_dc_table_index[index] = ((*jpeg_data) & 0xf0) >> 4;
545
1762
        jpeg_info -> gx_jpeg_ac_table_index[index] = (*jpeg_data++) & 0x0f;
546
    }
547
548
588
    return GX_SUCCESS;
549
}
550
551
/**************************************************************************/
552
/*                                                                        */
553
/*  FUNCTION                                               RELEASE        */
554
/*                                                                        */
555
/*    _gx_image_reader_jpeg_dc_decode                     PORTABLE C      */
556
/*                                                           6.3.0        */
557
/*  AUTHOR                                                                */
558
/*                                                                        */
559
/*    Kenneth Maxwell, Microsoft Corporation                              */
560
/*                                                                        */
561
/*  DESCRIPTION                                                           */
562
/*                                                                        */
563
/*    Decode the DC component.                                            */
564
/*                                                                        */
565
/*  INPUT                                                                 */
566
/*                                                                        */
567
/*    jpeg_info                             JPEG data control block       */
568
/*    i_component                           Component index               */
569
/*                                                                        */
570
/*  OUTPUT                                                                */
571
/*                                                                        */
572
/*    Status                                                              */
573
/*                                                                        */
574
/*  CALLS                                                                 */
575
/*                                                                        */
576
/*    GX_JPEG_BITS_GET                       Extract a specified number of*/
577
/*                                             bits from JPEG data stream */
578
/*    GX_JPEG_BITS_SKIP                      Skips bits from tempory JPEG */
579
/*                                             data stream                */
580
/*    _gx_image_reader_jpeg_huffman_code_find                             */
581
/*                                           Lookup the huffman code      */
582
/*                                                                        */
583
/*  CALLED BY                                                             */
584
/*                                                                        */
585
/*    _gx_image_reader_jpeg_one_block_decode                              */
586
/*                                                                        */
587
/*  RELEASE HISTORY                                                       */
588
/*                                                                        */
589
/*    DATE              NAME                      DESCRIPTION             */
590
/*                                                                        */
591
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
592
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
593
/*                                            resulting in version 6.1    */
594
/*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
595
/*                                            added range test,           */
596
/*                                            resulting in version 6.2.0  */
597
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
598
/*                                            improved logic,             */
599
/*                                            resulting in version 6.3.0  */
600
/*                                                                        */
601
/**************************************************************************/
602
1379818
static UINT _gx_image_reader_jpeg_dc_decode(GX_JPEG_INFO *jpeg_info, UINT i_component)
603
{
604
1379818
UINT     i_bits = 0;
605
GX_UBYTE code_value;
606
INT      diff;
607
1379818
UINT     table_index = jpeg_info -> gx_jpeg_dc_table_index[i_component];
608
GX_BOOL  negative;
609
610
1379818
    if (table_index >= HUFF_TABLE_DIMENSION)
611
    {
612
        return GX_FAILURE;
613
    }
614
615



2050747
    GX_JPEG_BITS_GET(jpeg_info, 16);
616
617
1379818
    if (_gx_image_reader_jpeg_huffcode_find(jpeg_info, 0, table_index, &i_bits, &code_value) == 0)
618
    {
619
1379607
        GX_JPEG_BITS_SKIP(jpeg_info, i_bits);
620
621
1379607
        if (code_value == 0)
622
        {
623
85828
            jpeg_info -> gx_jpeg_vecter[0] = jpeg_info -> gx_jpeg_pre_dc[i_component];
624
        }
625
        else
626
        {
627
628



1295084
            GX_JPEG_BITS_GET(jpeg_info, code_value);
629
1293779
            diff = (INT)(((UINT)jpeg_info -> gx_jpeg_bit_buffer) >> (32 - code_value));
630
1293779
            GX_JPEG_BITS_SKIP(jpeg_info, code_value);
631
632
1293779
            negative = !(diff >> (code_value - 1));
633
634
1293779
            if (negative)
635
            {
636
663058
                diff += 1 - (1 << code_value);
637
            }
638
639
1293779
            jpeg_info -> gx_jpeg_vecter[0] = diff + jpeg_info -> gx_jpeg_pre_dc[i_component];
640
1293779
            jpeg_info -> gx_jpeg_pre_dc[i_component] = jpeg_info -> gx_jpeg_vecter[0];
641
        }
642
    }
643
    else
644
    {
645
211
        return GX_FAILURE;
646
    }
647
648
1379607
    return GX_SUCCESS;
649
}
650
651
/**************************************************************************/
652
/*                                                                        */
653
/*  FUNCTION                                               RELEASE        */
654
/*                                                                        */
655
/*    _gx_image_reader_jpeg_ac_decode                     PORTABLE C      */
656
/*                                                           6.3.0        */
657
/*  AUTHOR                                                                */
658
/*                                                                        */
659
/*    Kenneth Maxwell, Microsoft Corporation                              */
660
/*                                                                        */
661
/*  DESCRIPTION                                                           */
662
/*                                                                        */
663
/*    Decode the AC component.                                            */
664
/*                                                                        */
665
/*  INPUT                                                                 */
666
/*                                                                        */
667
/*    jpeg_info                             JPEG data control block       */
668
/*    i_component                           Component index               */
669
/*                                                                        */
670
/*  OUTPUT                                                                */
671
/*                                                                        */
672
/*    Status Code                                                         */
673
/*                                                                        */
674
/*  CALLS                                                                 */
675
/*                                                                        */
676
/*    GX_JPEG_BITS_GET                       Extract a specified number of*/
677
/*                                             bits from JPEG data stream */
678
/*    GX_JPEG_BITS_SKIP                      Skips bits from tempory JPEG */
679
/*                                             data stream                */
680
/*    _gx_image_reader_jpeg_huffman_code_find                             */
681
/*                                           Lookup the huffman code      */
682
/*                                                                        */
683
/*  CALLED BY                                                             */
684
/*                                                                        */
685
/*    _gx_image_reader_jpeg_one_block_decode                              */
686
/*                                                                        */
687
/*  RELEASE HISTORY                                                       */
688
/*                                                                        */
689
/*    DATE              NAME                      DESCRIPTION             */
690
/*                                                                        */
691
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
692
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
693
/*                                            resulting in version 6.1    */
694
/*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
695
/*                                            added range test,           */
696
/*                                            resulting in version 6.2.0  */
697
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
698
/*                                            improved logic,             */
699
/*                                            resulting in version 6.3.0  */
700
/*                                                                        */
701
/**************************************************************************/
702
1379818
static UINT _gx_image_reader_jpeg_ac_decode(GX_JPEG_INFO *jpeg_info, UINT i_component)
703
{
704
1379818
UINT     i_bits = 0;
705
GX_UBYTE code_value;
706
GX_UBYTE catogory;
707
GX_UBYTE runs_of_zero;
708
INT      ac_coefficient;
709
1379818
UINT     ac_counter = 1;
710
1379818
UINT     table_index = jpeg_info -> gx_jpeg_ac_table_index[i_component];
711
INT      negative;
712
713
1379818
    if (table_index >= HUFF_TABLE_DIMENSION)
714
    {
715
        return GX_FAILURE;
716
    }
717
718
28037652
    while (ac_counter < 64)
719
    {
720
26657946
        i_bits = 0;
721



46850731
        GX_JPEG_BITS_GET(jpeg_info, 16);
722
723
26657946
        if (_gx_image_reader_jpeg_huffcode_find(jpeg_info, 1, table_index, &i_bits, &code_value) == 0)
724
        {
725
26657834
            GX_JPEG_BITS_SKIP(jpeg_info, i_bits);
726
727
26657834
            runs_of_zero = (0xf0 & code_value) >> 4;
728
26657834
            catogory = 0x0f & code_value;
729
730
26657834
            if (catogory == 0)
731
            {
732
                /* EOB encountered. */
733
1379459
                if (runs_of_zero == 0)
734
                {
735
1375290
                    ac_counter = 64;
736
                }
737
4169
                else if (runs_of_zero == 0x0f)
738
                {
739
4134
                    ac_counter += 16;
740
                }
741
            }
742
            else
743
            {
744
25278375
                ac_counter += runs_of_zero;
745
746



25345914
                GX_JPEG_BITS_GET(jpeg_info, catogory);
747
25278375
                ac_coefficient = (INT)((jpeg_info -> gx_jpeg_bit_buffer) >> (32 - catogory));
748
25278375
                GX_JPEG_BITS_SKIP(jpeg_info, catogory);
749
750
25278375
                negative = !(ac_coefficient >> (catogory - 1));
751
752
25278375
                if (negative)
753
                {
754
12532773
                    ac_coefficient += 1 - (1 << catogory);
755
                }
756
757
25278375
                if (ac_counter < 64)
758
                {
759
25278271
                    jpeg_info -> gx_jpeg_vecter[ac_counter++] = ac_coefficient;
760
                }
761
            }
762
        }
763
        else
764
        {
765
112
            return GX_FAILURE;
766
        }
767
    }
768
769
1379706
    return GX_SUCCESS;
770
}
771
772
#if defined(GX_ENABLE_ARM_HELIUM)
773
/* Define the triple Bufferfly Addition operation */
774
#define VBUTTERFLY_ADDITION(a, b) \
775
    vtemp = vaddq_s32(a, b);      \
776
    b = vsubq_s32(a, b);          \
777
    a = vtemp
778
779
/* Define the butterfly Multiplication */
780
#define VBUTTERFLY_MULTIPLICATION(a, b, cos, sin) \
781
    vtempa = vmulq_n_s32(a, cos);                 \
782
    vtempb = vmulq_n_s32(b, sin);                 \
783
    vtemp = vaddq_s32(vtempa, vtempb);            \
784
    vtempa = vmulq_n_s32(a, sin);                 \
785
    vtempb = vmulq_n_s32(b, cos);                 \
786
    b = vsubq_s32(vtempb, vtempa);                \
787
    a = vtemp
788
789
#define VBUTTERFLY_MULTIPLICATION_SHR6(a, b, cos, sin) \
790
    vtempa = vmulq_n_s32(a, cos);                      \
791
    vtempb = vmulq_n_s32(b, sin);                      \
792
    vtemp = vaddq_s32(vtempa, vtempb);                 \
793
    vtempa = vmulq_n_s32(a, sin);                      \
794
    vtempb = vmulq_n_s32(b, cos);                      \
795
    b = vsubq_s32(vtempb, vtempa);                     \
796
    b = vshrq_n_s32(b, 6);                             \
797
    a = vshrq_n_s32(vtemp, 6)
798
#else
799
800
/* Define the triple Bufferfly Addition operation */
801
#define BUTTERFLY_ADDITION(a, b) \
802
    t = a + b;                   \
803
    b = a - b;                   \
804
    a = t
805
806
/* Define the butterfly Multiplication */
807
#define BUTTERFLY_MULTIPLICATION(a, b, cos, sin) \
808
    t = (a * cos + b * sin);                     \
809
    b = (b * cos - a * sin);                     \
810
    a = t
811
812
#define BUTTERFLY_MULTIPLICATION_SHR6(a, b, cos, sin) \
813
    t = (a * cos + b * sin) >> 6;                     \
814
    b = (b * cos - a * sin) >> 6;                     \
815
    a = t
816
817
#endif
818
819
/* Define constants.  */
820
#define R2_SHR7   181 /* = sqrt(2) << 7.  */
821
#define C1_SHR8   251 /* = cos(pi/16) << 8.  */
822
#define S1_SHR8   50  /* = sin(pi/16) << 8.  */
823
#define C3_SHR8   213 /* = cos(3pi/16)*sqrt(2) << 8.  */
824
#define S3_SHR8   142 /* = sin(3pi/16)*sqrt(2) << 8.  */
825
#define C6R2_SHR9 277 /* = cos(pi/16)*sqrt(2) << 9.  */
826
#define S6R2_SHR9 669 /* = sin(3pi/16)*sqrt(2) << 9.  */
827
#define POSTSH1   9
828
#define POSTSH2   12
829
830
#if defined(GX_ENABLE_ARM_HELIUM)
831
/**************************************************************************/
832
/*                                                                        */
833
/*  FUNCTION                                               RELEASE        */
834
/*                                                                        */
835
/*    _gx_image_reader_jpeg_dequantize_idct               PORTABLE C      */
836
/*                                                           6.3.0        */
837
/*  AUTHOR                                                                */
838
/*                                                                        */
839
/*    Ting Zhu, Microsoft Corporation                                     */
840
/*                                                                        */
841
/*  DESCRIPTION                                                           */
842
/*                                                                        */
843
/*    Dequatilizes decoded data and performs Inverse Discrete Consine     */
844
/*    Transformation using helium intrinsics.                             */
845
/*                                                                        */
846
/*  INPUT                                                                 */
847
/*                                                                        */
848
/*    block                                 Pointer to decoded data       */
849
/*    quant_table                           Pointer to quantization table */
850
/*    out                                   Buffer for output data        */
851
/*    stride                                Stride of output data         */
852
/*                                                                        */
853
/*  OUTPUT                                                                */
854
/*                                                                        */
855
/*    None                                                                */
856
/*                                                                        */
857
/*  CALLS                                                                 */
858
/*                                                                        */
859
/*    vldrwq_gather_shifted_offset_s32      Gather data from memory       */
860
/*    vmulq_s32                             Multiply two vectors          */
861
/*    vmulq_n_s32                           Multiply by scaler            */
862
/*    vqrshlq_n_s32                         Shift each element of a       */
863
/*                                            vector register left by     */
864
/*                                            the immediate value         */
865
/*    vaddq_s32                             Add two vectors               */
866
/*    vrshrq_n_s32                          Shift each element of a       */
867
/*                                            vector register right by    */
868
/*                                            the immediate value         */
869
/*    vstrhq_scatter_offset_s32             Scatter store data to memory  */
870
/*    vldrhq_s32                            Load vector register          */
871
/*    vqrshrnbq_n_s32                       Shift right with saturation,  */
872
/*                                            and write the result to the */
873
/*                                            bottom half of the result   */
874
/*                                            element                     */
875
/*    vqmovntq_s16                          Saturate to half width and    */
876
/*                                            write the result to the     */
877
/*                                            top of the result element   */
878
/*    vstrbq_scatter_offset_s8              Scatter store data to memory  */
879
/*    VBUTTERFLY_ADDITION                   Perform butterfly addition    */
880
/*    VBUTTERFLY_MULTIPLICATION             Perform butterfly             */
881
/*                                            multiplication              */
882
/*    VBUTTERFLY_MULTIPLICATION_SHR6        Perform butterfly             */
883
/*                                            multiplication with shift   */
884
/*                                                                        */
885
/*  CALLED BY                                                             */
886
/*                                                                        */
887
/*    _gx_image_reader_jpeg_one_block_decode                              */
888
/*                                                                        */
889
/*  RELEASE HISTORY                                                       */
890
/*                                                                        */
891
/*    DATE              NAME                      DESCRIPTION             */
892
/*                                                                        */
893
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
894
/*                                                                        */
895
/**************************************************************************/
896
static VOID _gx_image_reader_jpeg_dequantize_idct(INT *block, INT *quant_table, GX_BYTE *out, INT stride)
897
{
898
static uint32x4_t voffset[8][2] = {
899
    {{0,  2,  3,  9}, {10, 20, 21, 35}},
900
    {{1,  4,  8,  11}, {19, 22, 34, 36}},
901
    {{5,  7,  12, 18}, {23, 33, 37, 48}},
902
    {{6,  13, 17, 24}, {32, 38, 47, 49}},
903
    {{14, 16, 25, 31}, {39, 46, 50, 57}},
904
    {{15, 26, 30, 40}, {45, 51, 56, 58}},
905
    {{27, 29, 41, 44}, {52, 55, 59, 62}},
906
    {{28, 42, 43, 53}, {54, 60, 61, 63}}
907
};
908
static uint32x4_t vstroffset1= {0, 16, 32, 48};
909
INT               index;
910
GX_VALUE          temp_block[64];
911
GX_VALUE         *output_data;
912
int32x4_t         vrow0, vrow1,  vrow2, vrow3, vrow4, vrow5, vrow6, vrow7, vtemp, vtempa, vtempb;
913
uint8x16_t        vstroffset = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3};
914
int16x8_t         vtemp16;
915
int8x16_t         vtemp8;
916
int16_t const    *base;
917
918
    /* Perform 2-D DCT by applying first a 1-D DCT over the rows
919
       followed by a 1-D DCT over the columns of the input-data matrix.*/
920
    for (index = 0; index < 4; index++)
921
    {
922
        vstroffset[0 + index * 4] += (stride * 3);
923
        vstroffset[1 + index * 4] += stride;
924
        vstroffset[2 + index * 4] += (stride << 1);
925
    }
926
927
928
    for (index = 0; index < 2; index++)
929
    {
930
        output_data = temp_block + 32 * index;
931
932
        /* Load data. */
933
        vrow0 = vldrwq_gather_shifted_offset_s32(block, voffset[0][index]);
934
        vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[0][index]);
935
        vrow0 = vmulq_s32(vrow0, vtemp);
936
937
        vrow1 = vldrwq_gather_shifted_offset_s32(block, voffset[1][index]);
938
        vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[1][index]);
939
        vrow1 = vmulq_s32(vrow1, vtemp);
940
941
        vrow2 = vldrwq_gather_shifted_offset_s32(block, voffset[2][index]);
942
        vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[2][index]);
943
        vrow2 = vmulq_s32(vrow2, vtemp);
944
945
        vrow3 = vldrwq_gather_shifted_offset_s32(block, voffset[3][index]);
946
        vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[3][index]);
947
        vrow3 = vmulq_s32(vrow3, vtemp);
948
949
        vrow4 = vldrwq_gather_shifted_offset_s32(block, voffset[4][index]);
950
        vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[4][index]);
951
        vrow4 = vmulq_s32(vrow4, vtemp);
952
953
        vrow5 = vldrwq_gather_shifted_offset_s32(block, voffset[5][index]);
954
        vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[5][index]);
955
        vrow5 = vmulq_s32(vrow5, vtemp);
956
957
        vrow6 = vldrwq_gather_shifted_offset_s32(block, voffset[6][index]);
958
        vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[6][index]);
959
        vrow6 = vmulq_s32(vrow6, vtemp);
960
961
        vrow7 = vldrwq_gather_shifted_offset_s32(block, voffset[7][index]);
962
        vtemp = vldrwq_gather_shifted_offset_s32(quant_table, voffset[7][index]);
963
        vrow7 = vmulq_s32(vrow7, vtemp);
964
965
        /*  Prescale.  */
966
        vrow0 = vqrshlq_n_s32(vrow0, 9);
967
        vrow1 = vqrshlq_n_s32(vrow1, 7);
968
        vrow4 = vqrshlq_n_s32(vrow4, 9);
969
        vrow7 = vqrshlq_n_s32(vrow7, 7);
970
971
        /* stage 1.  */
972
        VBUTTERFLY_ADDITION(vrow1, vrow7);
973
974
        vrow3 = vmulq_n_s32(vrow3, R2_SHR7);
975
        vrow5 = vmulq_n_s32(vrow5, R2_SHR7);
976
977
        /* stage 2.  */
978
        VBUTTERFLY_ADDITION(vrow0, vrow4);
979
        VBUTTERFLY_MULTIPLICATION(vrow6, vrow2, C6R2_SHR9, S6R2_SHR9);
980
        VBUTTERFLY_ADDITION(vrow7, vrow5);
981
        VBUTTERFLY_ADDITION(vrow1, vrow3);
982
983
        /* stage 3.  */
984
        VBUTTERFLY_ADDITION(vrow0, vrow6);
985
        VBUTTERFLY_ADDITION(vrow4, vrow2);
986
        VBUTTERFLY_MULTIPLICATION_SHR6(vrow5, vrow3, C1_SHR8, S1_SHR8);
987
        VBUTTERFLY_MULTIPLICATION_SHR6(vrow1, vrow7, C3_SHR8, S3_SHR8);
988
989
        /* stage 4.  */
990
        vtemp = vaddq_s32(vrow0, vrow1);
991
        vtemp = vrshrq_n_s32(vtemp, POSTSH1);
992
        vstrhq_scatter_offset_s32(output_data, vstroffset1, vtemp);
993
994
        vtemp = vaddq_s32(vrow4, vrow5);
995
        vtemp = vrshrq_n_s32(vtemp, POSTSH1);
996
        vstrhq_scatter_offset_s32(output_data + 1, vstroffset1, vtemp);
997
998
        vtemp = vaddq_s32(vrow2, vrow3);
999
        vtemp = vrshrq_n_s32(vtemp, POSTSH1);
1000
        vstrhq_scatter_offset_s32(output_data + 2, vstroffset1, vtemp);
1001
1002
        vtemp = vaddq_s32(vrow6, vrow7);
1003
        vtemp = vrshrq_n_s32(vtemp, POSTSH1);
1004
        vstrhq_scatter_offset_s32(output_data + 3, vstroffset1, vtemp);
1005
1006
        vtemp = vsubq_s32(vrow6, vrow7);
1007
        vtemp = vrshrq_n_s32(vtemp, POSTSH1);
1008
        vstrhq_scatter_offset_s32(output_data + 4, vstroffset1, vtemp);
1009
1010
        vtemp = vsubq_s32(vrow2, vrow3);
1011
        vtemp = vrshrq_n_s32(vtemp, POSTSH1);
1012
        vstrhq_scatter_offset_s32(output_data + 5, vstroffset1, vtemp);
1013
1014
        vtemp = vsubq_s32(vrow4, vrow5);
1015
        vtemp = vrshrq_n_s32(vtemp, POSTSH1);
1016
        vstrhq_scatter_offset_s32(output_data + 6, vstroffset1, vtemp);
1017
1018
        vtemp = vsubq_s32(vrow0, vrow1);
1019
        vtemp = vrshrq_n_s32(vtemp, POSTSH1);
1020
        vstrhq_scatter_offset_s32(output_data + 7, vstroffset1, vtemp);
1021
    }
1022
1023
    for (index = 0; index < 2; index++)
1024
    {
1025
        base = (int16_t const *)(temp_block + 4 * index);
1026
1027
        /* Load data. */
1028
        vrow0 = vldrhq_s32(base);
1029
        vrow1 = vldrhq_s32(base + 8);
1030
        vrow2 = vldrhq_s32(base + 16);
1031
        vrow3 = vldrhq_s32(base + 24);
1032
        vrow4 = vldrhq_s32(base + 32);
1033
        vrow5 = vldrhq_s32(base + 40);
1034
        vrow6 = vldrhq_s32(base + 48);
1035
        vrow7 = vldrhq_s32(base + 56);
1036
1037
        /*  Prescale.  */
1038
        vrow0 = vqrshlq_n_s32(vrow0, 9);
1039
        vrow1 = vqrshlq_n_s32(vrow1, 7);
1040
        vrow4 = vqrshlq_n_s32(vrow4, 9);
1041
        vrow7 = vqrshlq_n_s32(vrow7, 7);
1042
1043
        /* stage 1.  */
1044
        VBUTTERFLY_ADDITION(vrow1, vrow7);
1045
1046
        vrow3 = vmulq_n_s32(vrow3, R2_SHR7);
1047
        vrow5 = vmulq_n_s32(vrow5, R2_SHR7);
1048
1049
        /* stage 2.  */
1050
        VBUTTERFLY_ADDITION(vrow0, vrow4);
1051
        VBUTTERFLY_MULTIPLICATION(vrow6, vrow2, C6R2_SHR9, S6R2_SHR9);
1052
        VBUTTERFLY_ADDITION(vrow7, vrow5);
1053
        VBUTTERFLY_ADDITION(vrow1, vrow3);
1054
1055
        /* stage 3.  */
1056
        VBUTTERFLY_ADDITION(vrow0, vrow6);
1057
        VBUTTERFLY_ADDITION(vrow4, vrow2);
1058
        VBUTTERFLY_MULTIPLICATION_SHR6(vrow5, vrow3, C1_SHR8, S1_SHR8);
1059
        VBUTTERFLY_MULTIPLICATION_SHR6(vrow1, vrow7, C3_SHR8, S3_SHR8);
1060
1061
        /* stage 4.  */
1062
1063
        vtemp = vaddq_s32(vrow0, vrow1);
1064
        vtemp16 = vqrshrntq_n_s32(vtemp16, vtemp, POSTSH2);
1065
1066
        vtemp = vaddq_s32(vrow4, vrow5);
1067
        vtemp16 = vqrshrnbq_n_s32(vtemp16, vtemp, POSTSH2);
1068
        vtemp8 = vqmovntq_s16(vtemp8, vtemp16);
1069
1070
        vtemp = vaddq_s32(vrow2, vrow3);
1071
        vtemp16 = vqrshrntq_n_s32(vtemp16, vtemp, POSTSH2);
1072
1073
        vtemp = vaddq_s32(vrow6, vrow7);
1074
        vtemp16 = vqrshrnbq_n_s32(vtemp16, vtemp, POSTSH2);
1075
        vtemp8 = vqmovnbq_s16(vtemp8, vtemp16);
1076
        vstrbq_scatter_offset_s8(out + 4 * index, vstroffset, vtemp8);
1077
1078
        vtemp = vsubq_s32(vrow6, vrow7);
1079
        vtemp16 = vqrshrntq_n_s32(vtemp16, vtemp, POSTSH2);
1080
1081
        vtemp = vsubq_s32(vrow2, vrow3);
1082
        vtemp16 = vqrshrnbq_n_s32(vtemp16, vtemp, POSTSH2);
1083
        vtemp8 = vqmovntq_s16(vtemp8, vtemp16);
1084
1085
        vtemp = vsubq_s32(vrow4, vrow5);
1086
        vtemp16 = vqrshrntq_n_s32(vtemp16, vtemp, POSTSH2);
1087
1088
        vtemp = vsubq_s32(vrow0, vrow1);
1089
        vtemp16 = vqrshrnbq_n_s32(vtemp16, vtemp, POSTSH2);
1090
        vtemp8 = vqmovnbq_s16(vtemp8, vtemp16);
1091
        vstrbq_scatter_offset_s8(out + (stride << 2) + 4 * index, vstroffset, vtemp8);
1092
    }
1093
}
1094
#else
1095
1096
/**************************************************************************/
1097
/*                                                                        */
1098
/*  FUNCTION                                               RELEASE        */
1099
/*                                                                        */
1100
/*    _gx_image_reader_jpeg_1d_idct                       PORTABLE C      */
1101
/*                                                           6.3.0        */
1102
/*  AUTHOR                                                                */
1103
/*                                                                        */
1104
/*    Kenneth Maxwell, Microsoft Corporation                              */
1105
/*                                                                        */
1106
/*  DESCRIPTION                                                           */
1107
/*                                                                        */
1108
/*    Performs 1D Inverse Discrete Consine Transformation.  It is an      */
1109
/*    implementation of LLM (Loeffler, Lighenberg, Moschytz) algorithm.   */
1110
/*                                                                        */
1111
/*  INPUT                                                                 */
1112
/*                                                                        */
1113
/*    input_data                            Input data                    */
1114
/*    output_data                           Buffer for output data        */
1115
/*    post_scale                            Post scale value              */
1116
/*    round                                 Value to reduce round error   */
1117
/*                                                                        */
1118
/*  OUTPUT                                                                */
1119
/*                                                                        */
1120
/*    None                                                                */
1121
/*                                                                        */
1122
/*  CALLS                                                                 */
1123
/*                                                                        */
1124
/*    None                                                                */
1125
/*                                                                        */
1126
/*  CALLED BY                                                             */
1127
/*                                                                        */
1128
/*    _gx_image_reader_jpeg_2d_idct                                       */
1129
/*                                                                        */
1130
/*  RELEASE HISTORY                                                       */
1131
/*                                                                        */
1132
/*    DATE              NAME                      DESCRIPTION             */
1133
/*                                                                        */
1134
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1135
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1136
/*                                            resulting in version 6.1    */
1137
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
1138
/*                                            improved logic,             */
1139
/*                                            resulting in version 6.3.0  */
1140
/*                                                                        */
1141
/**************************************************************************/
1142
22077088
static VOID _gx_image_reader_jpeg_1d_idct(INT *input_data, INT *output_data, INT post_scale, INT round)
1143
{
1144
INT t;
1145
1146
22077088
    input_data[0] <<= 9;
1147
22077088
    input_data[1] <<= 7;
1148
22077088
    input_data[4] <<= 9;
1149
22077088
    input_data[7] <<= 7;
1150
1151
    /* iDCT computation .*/
1152
1153
    /* stage 1.  */
1154
22077088
    BUTTERFLY_ADDITION(input_data[1], input_data[7]);
1155
1156
22077088
    input_data[3] *= R2_SHR7;
1157
22077088
    input_data[5] *= R2_SHR7;
1158
1159
    /* stage 2.  */
1160
22077088
    BUTTERFLY_ADDITION(input_data[0], input_data[4]);
1161
22077088
    BUTTERFLY_MULTIPLICATION(input_data[6], input_data[2], C6R2_SHR9, S6R2_SHR9);
1162
22077088
    BUTTERFLY_ADDITION(input_data[7], input_data[5]);
1163
22077088
    BUTTERFLY_ADDITION(input_data[1], input_data[3]);
1164
1165
    /* staget 3.  */
1166
22077088
    BUTTERFLY_ADDITION(input_data[0], input_data[6]);
1167
22077088
    BUTTERFLY_ADDITION(input_data[4], input_data[2]);
1168
22077088
    BUTTERFLY_MULTIPLICATION_SHR6(input_data[5], input_data[3], C1_SHR8, S1_SHR8);
1169
22077088
    BUTTERFLY_MULTIPLICATION_SHR6(input_data[1], input_data[7], C3_SHR8, S3_SHR8);
1170
1171
    /* stage 4.  */
1172
22077088
    input_data[0] += round;
1173
22077088
    input_data[4] += round;
1174
22077088
    input_data[2] += round;
1175
22077088
    input_data[6] += round;
1176
1177
22077088
    output_data[0] = (input_data[0] + input_data[1]) >> post_scale;
1178
22077088
    output_data[8] = (input_data[4] + input_data[5]) >> post_scale;
1179
22077088
    output_data[16] = (input_data[2] + input_data[3]) >> post_scale;
1180
22077088
    output_data[24] = (input_data[6] + input_data[7]) >> post_scale;
1181
22077088
    output_data[32] = (input_data[6] - input_data[7]) >> post_scale;
1182
22077088
    output_data[40] = (input_data[2] - input_data[3]) >> post_scale;
1183
22077088
    output_data[48] = (input_data[4] - input_data[5]) >> post_scale;
1184
22077088
    output_data[56] = (input_data[0] - input_data[1]) >> post_scale;
1185
22077088
}
1186
1187
/**************************************************************************/
1188
/*                                                                        */
1189
/*  FUNCTION                                               RELEASE        */
1190
/*                                                                        */
1191
/*    _gx_image_reader_jpeg_dequantize_idct               PORTABLE C      */
1192
/*                                                           6.3.0        */
1193
/*  AUTHOR                                                                */
1194
/*                                                                        */
1195
/*    Kenneth Maxwell, Microsoft Corporation                              */
1196
/*                                                                        */
1197
/*  DESCRIPTION                                                           */
1198
/*                                                                        */
1199
/*    Dequatilizes decoded data and performs Inverse Discrete Consine     */
1200
/*    Transformation.                                                     */
1201
/*                                                                        */
1202
/*  INPUT                                                                 */
1203
/*                                                                        */
1204
/*    block                                 Pointer to decoded data       */
1205
/*    quant_table                           Pointer to quantization table */
1206
/*    out                                   Buffer for output data        */
1207
/*    stride                                Stride of output data         */
1208
/*                                                                        */
1209
/*  OUTPUT                                                                */
1210
/*                                                                        */
1211
/*    None                                                                */
1212
/*                                                                        */
1213
/*  CALLS                                                                 */
1214
/*                                                                        */
1215
/*    _gx_image_reader_jpeg_1d_idct         Perform 1D Inverse Discrete   */
1216
/*                                            Consine Transformation      */
1217
/*    GX_SATURATE_TO_BYTE                   Saturate to [-128, 127]       */
1218
/*                                                                        */
1219
/*  CALLED BY                                                             */
1220
/*                                                                        */
1221
/*    _gx_image_reader_jpeg_one_block_decode                              */
1222
/*                                                                        */
1223
/*  RELEASE HISTORY                                                       */
1224
/*                                                                        */
1225
/*    DATE              NAME                      DESCRIPTION             */
1226
/*                                                                        */
1227
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1228
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1229
/*                                            resulting in version 6.1    */
1230
/*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
1231
/*                                            added range check for       */
1232
/*                                            stride, changed return val, */
1233
/*                                            added range check for       */
1234
/*                                            table_index,                */
1235
/*                                            resulting in version 6.2.0  */
1236
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
1237
/*                                            improved logic,             */
1238
/*                                            resulting in version 6.3.0  */
1239
/*                                                                        */
1240
/**************************************************************************/
1241
1379818
static VOID _gx_image_reader_jpeg_dequantize_idct(INT *block, INT *quant_table, GX_BYTE *out, INT stride)
1242
{
1243
static GX_CONST GX_UBYTE reorder_index[] = {
1244
    0, 1, 8, 16, 9, 2, 3, 10,
1245
    17, 24, 32, 25, 18, 11, 4, 5,
1246
    12, 19, 26, 33, 40, 48, 41, 34,
1247
    27, 20, 13, 6, 7, 14, 21, 28,
1248
    35, 42, 49, 56, 57, 50, 43, 36,
1249
    29, 22, 15, 23, 30, 37, 44, 51,
1250
    58, 59, 52, 45, 38, 31, 39, 46,
1251
    53, 60, 61, 54, 47, 55, 62, 63
1252
};
1253
INT                      index;
1254
INT                      jpeg_block[64];
1255
INT                      temp_block[64];
1256
INT                      row;
1257
1258
89688170
    for (index = 0; index < 64; index++)
1259
    {
1260
88308352
        block[index] *= quant_table[index];
1261
1262
        /* Reorder from zig-zag order to 8*8 block */
1263
88308352
        jpeg_block[reorder_index[index]] = block[index];
1264
    }
1265
1266
12418362
    for (index = 0; index < 8; index++)
1267
    {
1268
11038544
        _gx_image_reader_jpeg_1d_idct(jpeg_block + index * 8, temp_block + index, 9, 256);     /* row */
1269
    }
1270
1271
12418362
    for (index = 0; index < 8; index++)
1272
    {
1273
11038544
        _gx_image_reader_jpeg_1d_idct(temp_block + index * 8, jpeg_block + index, 12, 2048);     /* col */
1274
    }
1275
1276
12418362
    for (row = 0; row < 8; row++)
1277
    {
1278
99346896
        for (index = 0; index < 8; index++)
1279
        {
1280

88308352
            GX_SATURATE_TO_BYTE(out[index], jpeg_block[row * 8 + index]);
1281
        }
1282
1283
11038544
        out += stride;
1284
    }
1285
1379818
}
1286
#endif
1287
1288
/**************************************************************************/
1289
/*                                                                        */
1290
/*  FUNCTION                                               RELEASE        */
1291
/*                                                                        */
1292
/*    _gx_image_reader_jpeg_one_block_decode              PORTABLE C      */
1293
/*                                                           6.3.0        */
1294
/*  AUTHOR                                                                */
1295
/*                                                                        */
1296
/*    Kenneth Maxwell, Microsoft Corporation                              */
1297
/*                                                                        */
1298
/*  DESCRIPTION                                                           */
1299
/*                                                                        */
1300
/*    Decode one block of JPEG data.                                      */
1301
/*                                                                        */
1302
/*  INPUT                                                                 */
1303
/*                                                                        */
1304
/*    jpeg_info                             JPEG data control block       */
1305
/*    icomponent                            Component index               */
1306
/*    block_data                            Pointer to decoded data       */
1307
/*                                                                        */
1308
/*  OUTPUT                                                                */
1309
/*                                                                        */
1310
/*    Status Code                                                         */
1311
/*                                                                        */
1312
/*  CALLS                                                                 */
1313
/*                                                                        */
1314
/*    memset                                                              */
1315
/*    _gx_image_reader_jpeg_dc_decode       Decode dc component           */
1316
/*    _gx_image_reader_jpeg_ac_decode       Decode ac component           */
1317
/*    _gx_image_reader_jpeg_dequantize_idct Dequatilize decoded data      */
1318
/*                                                                        */
1319
/*  CALLED BY                                                             */
1320
/*                                                                        */
1321
/*    _gx_image_reader_jpeg_decode                                        */
1322
/*                                                                        */
1323
/*  RELEASE HISTORY                                                       */
1324
/*                                                                        */
1325
/*    DATE              NAME                      DESCRIPTION             */
1326
/*                                                                        */
1327
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1328
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1329
/*                                            resulting in version 6.1    */
1330
/*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
1331
/*                                            returned result of          */
1332
/*                                            dequantize_idct,            */
1333
/*                                            resulting in version 6.2.0  */
1334
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
1335
/*                                            improved logic,             */
1336
/*                                            resulting in version 6.3.0  */
1337
/*                                                                        */
1338
/**************************************************************************/
1339
1379818
static UINT _gx_image_reader_jpeg_one_block_decode(GX_JPEG_INFO *jpeg_info, UINT i_component, GX_BYTE *block_data)
1340
{
1341
INT table_index;
1342
INT stride;
1343
1344
1379818
    memset(jpeg_info -> gx_jpeg_vecter, 0, 64 * sizeof(UINT));
1345
1379818
    _gx_image_reader_jpeg_dc_decode(jpeg_info, i_component);
1346
1379818
    _gx_image_reader_jpeg_ac_decode(jpeg_info, i_component);
1347
1348
1379818
    if (i_component >= JPG_MAX_COMPONENTS)
1349
    {
1350
        return GX_FAILURE;
1351
    }
1352
1353
1379818
    stride = ((jpeg_info -> gx_jpeg_sample_factor[i_component] & 0xf0) >> 1);
1354
1355
1379818
    if (i_component == 0)
1356
    {
1357
817636
        if (stride > 32)
1358
        {
1359
            return GX_FAILURE;
1360
        }
1361
    }
1362
    else
1363
    {
1364
562182
        if (stride > 8)
1365
        {
1366
            return GX_FAILURE;
1367
        }
1368
    }
1369
1370
1379818
    table_index = jpeg_info -> gx_jpeg_qantization_table_index[i_component];
1371
1372
1379818
    if (table_index >= JPG_QUANT_TABLE_DIMENSION)
1373
    {
1374
        return GX_FAILURE;
1375
    }
1376
1377
1379818
    _gx_image_reader_jpeg_dequantize_idct(jpeg_info -> gx_jpeg_vecter, jpeg_info -> gx_jpeg_quantization_table[table_index], block_data, stride);
1378
1379818
    return GX_SUCCESS;
1379
}
1380
1381
1382
#if defined(GX_ENABLE_ARM_HELIUM)
1383
/**************************************************************************/
1384
/*                                                                        */
1385
/*  FUNCTION                                               RELEASE        */
1386
/*                                                                        */
1387
/*    _gx_image_reader_jpeg_24xrgb_pixel_write_helium     PORTABLE C      */
1388
/*                                                           6.3.0        */
1389
/*  AUTHOR                                                                */
1390
/*                                                                        */
1391
/*    Ting Zhu, Microsoft Corporation                                     */
1392
/*                                                                        */
1393
/*  DESCRIPTION                                                           */
1394
/*                                                                        */
1395
/*    Write 24xrgb pixel to memory using Helium intrinsics.               */
1396
/*                                                                        */
1397
/*  INPUT                                                                 */
1398
/*                                                                        */
1399
/*    jpeg_info                             JPEG control block            */
1400
/*    vred                                  Red value vector              */
1401
/*    vgreen                                Green value vector            */
1402
/*    vblue                                 Blue value vector             */
1403
/*    size                                  Number of pixels to write     */
1404
/*                                                                        */
1405
/*  OUTPUT                                                                */
1406
/*                                                                        */
1407
/*    vstrbq_scatter_offset_u8              Scatter 8-bit values to       */
1408
/*                                            memory                      */
1409
/*    vstrbq_scatter_offset_p_u8            Optionaly scatter 8-bit       */
1410
/*                                            values to memory            */
1411
/*                                                                        */
1412
/*  CALLS                                                                 */
1413
/*                                                                        */
1414
/*    None                                                                */
1415
/*                                                                        */
1416
/*  CALLED BY                                                             */
1417
/*                                                                        */
1418
/*    _gx_image_reader_jpeg_one_mcu_write                                 */
1419
/*    _gx_image_reader_jpeg_one_mcu_rotated_write                         */
1420
/*                                                                        */
1421
/*  RELEASE HISTORY                                                       */
1422
/*                                                                        */
1423
/*    DATE              NAME                      DESCRIPTION             */
1424
/*                                                                        */
1425
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
1426
/*                                                                        */
1427
/**************************************************************************/
1428
static VOID _gx_image_reader_jpeg_24xrgb_pixel_write_helium(GX_JPEG_INFO *jpeg_info, uint8x16_t vred, uint8x16_t vgreen, uint8x16_t vblue, INT size)
1429
{
1430
INT index;
1431
1432
    for(index = 0; index < size; index++)
1433
    {
1434
        *((GX_COLOR *)jpeg_info -> gx_jpeg_putdata) = 0xff000000 | ((ULONG)vred[index] << 16) | ((ULONG)vgreen[index] << 8) | (ULONG)vblue[index];
1435
1436
        jpeg_info -> gx_jpeg_putdata += 4;
1437
    }
1438
}
1439
#else
1440
/**************************************************************************/
1441
/*                                                                        */
1442
/*  FUNCTION                                               RELEASE        */
1443
/*                                                                        */
1444
/*    _gx_image_reader_jpeg_1555xrgb_pixel_write          PORTABLE C      */
1445
/*                                                           6.3.0        */
1446
/*  AUTHOR                                                                */
1447
/*                                                                        */
1448
/*    Ting Zhu, Microsoft Corporation                                     */
1449
/*                                                                        */
1450
/*  DESCRIPTION                                                           */
1451
/*                                                                        */
1452
/*    Write 24xrgb pixel to memory.                                       */
1453
/*                                                                        */
1454
/*  INPUT                                                                 */
1455
/*                                                                        */
1456
/*    jpeg_info                             JPEG control block            */
1457
/*    red                                   Red value                     */
1458
/*    green                                 Green value                   */
1459
/*    blue                                  Blue value                    */
1460
/*                                                                        */
1461
/*  OUTPUT                                                                */
1462
/*                                                                        */
1463
/*    None                                                                */
1464
/*                                                                        */
1465
/*  CALLS                                                                 */
1466
/*                                                                        */
1467
/*    None                                                                */
1468
/*                                                                        */
1469
/*  CALLED BY                                                             */
1470
/*                                                                        */
1471
/*    _gx_image_reader_jpeg_one_mcu_write                                 */
1472
/*    _gx_image_reader_jpeg_one_mcu_rotated_write                         */
1473
/*                                                                        */
1474
/*  RELEASE HISTORY                                                       */
1475
/*                                                                        */
1476
/*    DATE              NAME                      DESCRIPTION             */
1477
/*                                                                        */
1478
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
1479
/*                                                                        */
1480
/**************************************************************************/
1481
7943561
static VOID _gx_image_reader_jpeg_24xrgb_pixel_write(GX_JPEG_INFO *jpeg_info, GX_UBYTE red, GX_UBYTE green, GX_UBYTE blue)
1482
{
1483
7943561
    *((GX_COLOR *)jpeg_info -> gx_jpeg_putdata) = 0xff000000 | ((ULONG)red << 16) | ((ULONG)green << 8) | (ULONG)blue;
1484
1485
7943561
    jpeg_info -> gx_jpeg_putdata += 4;
1486
7943561
}
1487
#endif
1488
1489
#if defined(GX_ENABLE_ARM_HELIUM)
1490
/**************************************************************************/
1491
/*                                                                        */
1492
/*  FUNCTION                                               RELEASE        */
1493
/*                                                                        */
1494
/*    _gx_image_reader_jpeg_24bpp_pixel_write_helium      PORTABLE C      */
1495
/*                                                           6.3.0        */
1496
/*  AUTHOR                                                                */
1497
/*                                                                        */
1498
/*    Ting Zhu, Microsoft Corporation                                     */
1499
/*                                                                        */
1500
/*  DESCRIPTION                                                           */
1501
/*                                                                        */
1502
/*    Internal helper function to write 24xrgb pixel to memory using      */
1503
/*    Helium intrinsics.                                                  */
1504
/*                                                                        */
1505
/*  INPUT                                                                 */
1506
/*                                                                        */
1507
/*    jpeg_info                             JPEG control block            */
1508
/*    vred                                  Red value vector              */
1509
/*    vgreen                                Green value vector            */
1510
/*    vblue                                 Blue value vector            */
1511
/*    size                                  Number of pixels to write     */
1512
/*                                                                        */
1513
/*  OUTPUT                                                                */
1514
/*                                                                        */
1515
/*    vstrbq_scatter_offset_u8              Scatter 8-bit values to       */
1516
/*                                            memory                      */
1517
/*    vstrbq_scatter_offset_p_u8            Optionally scatter 8-bit      */
1518
/*                                            values to memory            */
1519
/*                                                                        */
1520
/*  CALLS                                                                 */
1521
/*                                                                        */
1522
/*    None                                                                */
1523
/*                                                                        */
1524
/*  CALLED BY                                                             */
1525
/*                                                                        */
1526
/*    _gx_image_reader_jpeg_one_mcu_write                                 */
1527
/*    _gx_image_reader_jpeg_one_mcu_rotated_write                         */
1528
/*                                                                        */
1529
/*  RELEASE HISTORY                                                       */
1530
/*                                                                        */
1531
/*    DATE              NAME                      DESCRIPTION             */
1532
/*                                                                        */
1533
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
1534
/*                                                                        */
1535
/**************************************************************************/
1536
static VOID _gx_image_reader_jpeg_24bpp_pixel_write_helium(GX_JPEG_INFO *jpeg_info, uint8x16_t vred, uint8x16_t vgreen, uint8x16_t vblue, INT size)
1537
{
1538
static uint8x16_t voffset = {0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45};
1539
mve_pred16_t      p;
1540
1541
    if (size == 16)
1542
    {
1543
        vstrbq_scatter_offset_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vred);
1544
        vstrbq_scatter_offset_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vgreen);
1545
        vstrbq_scatter_offset_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vblue);
1546
        jpeg_info -> gx_jpeg_putdata += 45;
1547
    }
1548
    else
1549
    {
1550
        /* Write the specified size of RGB values to memory.  */
1551
        p = 0xffff >> (16 - size);
1552
        vstrbq_scatter_offset_p_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vred, p);
1553
        vstrbq_scatter_offset_p_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vgreen, p);
1554
        vstrbq_scatter_offset_p_u8(jpeg_info -> gx_jpeg_putdata++, voffset, vblue, p);
1555
        jpeg_info -> gx_jpeg_putdata += (size - 1) * 3;
1556
    }
1557
}
1558
#else
1559
/**************************************************************************/
1560
/*                                                                        */
1561
/*  FUNCTION                                               RELEASE        */
1562
/*                                                                        */
1563
/*    _gx_image_reader_jpeg_24bpp_pixel_write             PORTABLE C      */
1564
/*                                                           6.3.0        */
1565
/*  AUTHOR                                                                */
1566
/*                                                                        */
1567
/*    Ting Zhu, Microsoft Corporation                                     */
1568
/*                                                                        */
1569
/*  DESCRIPTION                                                           */
1570
/*                                                                        */
1571
/*    Write 24bpp pixel to memory.                                        */
1572
/*                                                                        */
1573
/*  INPUT                                                                 */
1574
/*                                                                        */
1575
/*    jpeg_info                             JPEG control block            */
1576
/*    red                                   Red value                     */
1577
/*    green                                 Green value                   */
1578
/*    blue                                  Blue value                    */
1579
/*                                                                        */
1580
/*  OUTPUT                                                                */
1581
/*                                                                        */
1582
/*    None                                                                */
1583
/*                                                                        */
1584
/*  CALLS                                                                 */
1585
/*                                                                        */
1586
/*    None                                                                */
1587
/*                                                                        */
1588
/*  CALLED BY                                                             */
1589
/*                                                                        */
1590
/*    _gx_image_reader_jpeg_one_mcu_write                                 */
1591
/*    _gx_image_reader_jpeg_one_mcu_rotated_write                         */
1592
/*                                                                        */
1593
/*  RELEASE HISTORY                                                       */
1594
/*                                                                        */
1595
/*    DATE              NAME                      DESCRIPTION             */
1596
/*                                                                        */
1597
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
1598
/*                                                                        */
1599
/**************************************************************************/
1600
8129360
static VOID _gx_image_reader_jpeg_24bpp_pixel_write(GX_JPEG_INFO *jpeg_info, GX_UBYTE red, GX_UBYTE green, GX_UBYTE blue)
1601
{
1602
8129360
    *jpeg_info -> gx_jpeg_putdata++ = red;
1603
8129360
    *jpeg_info -> gx_jpeg_putdata++ = green;
1604
8129360
    *jpeg_info -> gx_jpeg_putdata++ = blue;
1605
8129360
}
1606
#endif
1607
1608
#if defined(GX_ENABLE_ARM_HELIUM)
1609
/**************************************************************************/
1610
/*                                                                        */
1611
/*  FUNCTION                                               RELEASE        */
1612
/*                                                                        */
1613
/*    _gx_image_reader_jpeg_565rgb_pixel_write_helium     PORTABLE C      */
1614
/*                                                           6.3.0        */
1615
/*  AUTHOR                                                                */
1616
/*                                                                        */
1617
/*    Ting Zhu, Microsoft Corporation                                     */
1618
/*                                                                        */
1619
/*  DESCRIPTION                                                           */
1620
/*                                                                        */
1621
/*    Internal helper function to write 565rgb pixel to memory using      */
1622
/*    Helium intrinsics.                                                  */
1623
/*                                                                        */
1624
/*  INPUT                                                                 */
1625
/*                                                                        */
1626
/*    jpeg_info                             JPEG control block            */
1627
/*    vred                                  Red value vector              */
1628
/*    vgreen                                Green value vector            */
1629
/*    vblue                                 Blue value vector            */
1630
/*    size                                  Number of pixels to write     */
1631
/*                                                                        */
1632
/*  OUTPUT                                                                */
1633
/*                                                                        */
1634
/*    vshrq_n_u8                            Unsigned 8-bit shift right    */
1635
/*    vldrbq_u16                            Load 8-bit value to a         */
1636
/*                                            destination register        */
1637
/*    vshlq_n_u16                           Unsigned 16-bit shift left    */
1638
/*    vorrq_u16                             Unsigned 16-bit OR            */
1639
/*    vstrhq_u16                            Store 16-bit values from      */
1640
/*                                            register to memory          */
1641
/*    vstrhq_p_u16                          Optionally store 16-bit       */
1642
/*                                            values from register to     */
1643
/*                                            memory                      */
1644
/*                                                                        */
1645
/*  CALLS                                                                 */
1646
/*                                                                        */
1647
/*    None                                                                */
1648
/*                                                                        */
1649
/*  CALLED BY                                                             */
1650
/*                                                                        */
1651
/*    _gx_image_reader_jpeg_one_mcu_write                                 */
1652
/*    _gx_image_reader_jpeg_one_mcu_rotated_write                         */
1653
/*                                                                        */
1654
/*  RELEASE HISTORY                                                       */
1655
/*                                                                        */
1656
/*    DATE              NAME                      DESCRIPTION             */
1657
/*                                                                        */
1658
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
1659
/*                                                                        */
1660
/**************************************************************************/
1661
static VOID _gx_image_reader_jpeg_565rgb_pixel_write_helium(GX_JPEG_INFO *jpeg_info, uint8x16_t vred, uint8x16_t vgreen, uint8x16_t vblue, INT size)
1662
{
1663
uint16x8_t   vresult;
1664
uint16x8_t   vtemp;
1665
INT          index;
1666
mve_pred16_t p;
1667
uint16_t    *put = (uint16_t *)jpeg_info -> gx_jpeg_putdata;
1668
GX_UBYTE     red[16];
1669
GX_UBYTE     green[16];
1670
GX_UBYTE     blue[16];
1671
1672
    vred = vshrq_n_u8(vred, 3);
1673
    vgreen = vshrq_n_u8(vgreen, 2);
1674
    vblue = vshrq_n_u8(vblue, 3);
1675
1676
    vstrbq(red, vred);
1677
    vstrbq(green, vgreen);
1678
    vstrbq(blue, vblue);
1679
1680
    for (index = 0; index <= 8; index += 8)
1681
    {
1682
        vtemp = vldrbq_u16(&red[index]);
1683
        vresult = vshlq_n_u16(vtemp, 11);
1684
1685
        vtemp = vldrbq_u16(&green[index]);
1686
        vtemp = vshlq_n_u16(vtemp, 5);
1687
        vresult = vorrq_u16(vresult, vtemp);
1688
1689
        vtemp = vldrbq_u16(&blue[index]);
1690
        vresult = vorrq_u16(vresult, vtemp);
1691
1692
        if (size >= 8)
1693
        {
1694
            vstrhq_u16(put, vresult);
1695
            put += 8;
1696
            size -= 8;
1697
        }
1698
        else
1699
        {
1700
            p = 0xffff >> (16 - (size << 1));
1701
            vstrhq_p_u16(put, vresult, p);
1702
            put += size;
1703
            break;
1704
        }
1705
    }
1706
1707
    jpeg_info -> gx_jpeg_putdata = (GX_UBYTE *)put;
1708
}
1709
#else
1710
/**************************************************************************/
1711
/*                                                                        */
1712
/*  FUNCTION                                               RELEASE        */
1713
/*                                                                        */
1714
/*    _gx_image_reader_jpeg_1555xrgb_pixel_write          PORTABLE C      */
1715
/*                                                           6.3.0        */
1716
/*  AUTHOR                                                                */
1717
/*                                                                        */
1718
/*    Ting Zhu, Microsoft Corporation                                     */
1719
/*                                                                        */
1720
/*  DESCRIPTION                                                           */
1721
/*                                                                        */
1722
/*    Write 1555xrgb pixel to memory.                                     */
1723
/*                                                                        */
1724
/*  INPUT                                                                 */
1725
/*                                                                        */
1726
/*    jpeg_info                             JPEG control block            */
1727
/*    red                                   Red value                     */
1728
/*    green                                 Green value                   */
1729
/*    blue                                  Blue value                    */
1730
/*                                                                        */
1731
/*  OUTPUT                                                                */
1732
/*                                                                        */
1733
/*    None                                                                */
1734
/*                                                                        */
1735
/*  CALLS                                                                 */
1736
/*                                                                        */
1737
/*    GX_SATURATE_TO_5BIT                   Saturate the value to 5 bits  */
1738
/*                                                                        */
1739
/*  CALLED BY                                                             */
1740
/*                                                                        */
1741
/*    _gx_image_reader_jpeg_one_mcu_write                                 */
1742
/*    _gx_image_reader_jpeg_one_mcu_rotated_write                         */
1743
/*                                                                        */
1744
/*  RELEASE HISTORY                                                       */
1745
/*                                                                        */
1746
/*    DATE              NAME                      DESCRIPTION             */
1747
/*                                                                        */
1748
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
1749
/*                                                                        */
1750
/**************************************************************************/
1751
13671747
static VOID _gx_image_reader_jpeg_565rgb_pixel_write(GX_JPEG_INFO *jpeg_info, GX_UBYTE red, GX_UBYTE green, GX_UBYTE blue)
1752
{
1753
    /* Make sure the range of the RGB values are within bound. */
1754
13671747
    red >>= 3;
1755
13671747
    green >>= 2;
1756
13671747
    blue >>= 3;
1757
1758
13671747
    *((USHORT *)jpeg_info -> gx_jpeg_putdata) = (USHORT)((red << 11) | (green << 5 | blue));
1759
13671747
    jpeg_info -> gx_jpeg_putdata += 2;
1760
13671747
}
1761
#endif
1762
1763
#if defined(GX_ENABLE_ARM_HELIUM)
1764
/**************************************************************************/
1765
/*                                                                        */
1766
/*  FUNCTION                                               RELEASE        */
1767
/*                                                                        */
1768
/*    _gx_image_reader_jpeg_1555xrgb_pixel_write_helium   PORTABLE C      */
1769
/*                                                           6.3.0        */
1770
/*  AUTHOR                                                                */
1771
/*                                                                        */
1772
/*    Ting Zhu, Microsoft Corporation                                     */
1773
/*                                                                        */
1774
/*  DESCRIPTION                                                           */
1775
/*                                                                        */
1776
/*    Internal helper function to write 1555xrgb pixel to memory using    */
1777
/*    Helium intrinsics.                                                  */
1778
/*                                                                        */
1779
/*  INPUT                                                                 */
1780
/*                                                                        */
1781
/*    jpeg_info                             JPEG control block            */
1782
/*    vred                                  Red value vector              */
1783
/*    vgreen                                Green value vector            */
1784
/*    vblue                                 Blue value vector            */
1785
/*    size                                  Number of pixels to write     */
1786
/*                                                                        */
1787
/*  OUTPUT                                                                */
1788
/*                                                                        */
1789
/*    vshrq_n_u8                            Unsigned 8-bit shift right    */
1790
/*    vldrbq_u16                            Load 8-bit value to a         */
1791
/*                                            destination register        */
1792
/*    vshlq_n_u16                           Unsigned 16-bit shift left    */
1793
/*    vorrq_u16                             Unsigned 16-bit OR            */
1794
/*    vstrhq_u16                            Store 16-bit values from      */
1795
/*                                            register to memory          */
1796
/*    vstrhq_p_u16                          Optionally store 16-bit       */
1797
/*                                            values from register to     */
1798
/*                                            memory                      */
1799
/*                                                                        */
1800
/*  CALLS                                                                 */
1801
/*                                                                        */
1802
/*    None                                                                */
1803
/*                                                                        */
1804
/*  CALLED BY                                                             */
1805
/*                                                                        */
1806
/*    _gx_image_reader_jpeg_one_mcu_write                                 */
1807
/*    _gx_image_reader_jpeg_one_mcu_rotated_write                         */
1808
/*                                                                        */
1809
/*  RELEASE HISTORY                                                       */
1810
/*                                                                        */
1811
/*    DATE              NAME                      DESCRIPTION             */
1812
/*                                                                        */
1813
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
1814
/*                                                                        */
1815
/**************************************************************************/
1816
static VOID _gx_image_reader_jpeg_1555xrgb_pixel_write_helium(GX_JPEG_INFO *jpeg_info, uint8x16_t vred, uint8x16_t vgreen, uint8x16_t vblue, INT size)
1817
{
1818
uint16x8_t   vresult;
1819
uint16x8_t   vtemp;
1820
INT          index;
1821
uint16_t    *put = (uint16_t *)jpeg_info -> gx_jpeg_putdata;
1822
mve_pred16_t p;
1823
GX_UBYTE     red[16];
1824
GX_UBYTE     green[16];
1825
GX_UBYTE     blue[16];
1826
1827
    vred = vshrq_n_u8(vred, 3);
1828
    vgreen = vshrq_n_u8(vgreen, 3);
1829
    vblue = vshrq_n_u8(vblue, 3);
1830
1831
    vstrbq(red, vred);
1832
    vstrbq(green, vgreen);
1833
    vstrbq(blue, vblue);
1834
1835
    for (index = 0; index <= 8; index += 8)
1836
    {
1837
        vtemp = vldrbq_u16(&red[index]);
1838
        vresult = vshlq_n_u16(vtemp, 10);
1839
1840
        vtemp = vldrbq_u16(&green[index]);
1841
        vtemp = vshlq_n_u16(vtemp, 5);
1842
        vresult = vorrq_u16(vresult, vtemp);
1843
1844
        vtemp = vldrbq_u16(&blue[index]);
1845
        vresult = vorrq_u16(vresult, vtemp);
1846
1847
        if (size >= 8)
1848
        {
1849
            vstrhq_u16(put, vresult);
1850
            put += 8;
1851
            size -= 8;
1852
        }
1853
        else
1854
        {
1855
            p = 0xffff >> (16 - (size << 1));
1856
            vstrhq_p_u16(put, vresult, p);
1857
            put += size;
1858
            break;
1859
        }
1860
    }
1861
1862
    jpeg_info -> gx_jpeg_putdata = (GX_UBYTE *)put;
1863
}
1864
#else
1865
/**************************************************************************/
1866
/*                                                                        */
1867
/*  FUNCTION                                               RELEASE        */
1868
/*                                                                        */
1869
/*    _gx_image_reader_jpeg_1555xrgb_pixel_write          PORTABLE C      */
1870
/*                                                           6.3.0        */
1871
/*  AUTHOR                                                                */
1872
/*                                                                        */
1873
/*    Ting Zhu, Microsoft Corporation                                     */
1874
/*                                                                        */
1875
/*  DESCRIPTION                                                           */
1876
/*                                                                        */
1877
/*    Write 1555xrgb pixel to memory.                                     */
1878
/*                                                                        */
1879
/*  INPUT                                                                 */
1880
/*                                                                        */
1881
/*    jpeg_info                             JPEG control block            */
1882
/*    red                                   Red value                     */
1883
/*    green                                 Green value                   */
1884
/*    blue                                  Blue value                    */
1885
/*                                                                        */
1886
/*  OUTPUT                                                                */
1887
/*                                                                        */
1888
/*    None                                                                */
1889
/*                                                                        */
1890
/*  CALLS                                                                 */
1891
/*                                                                        */
1892
/*    GX_SATURATE_TO_5BIT                   Saturate the value to 5 bits  */
1893
/*                                                                        */
1894
/*  CALLED BY                                                             */
1895
/*                                                                        */
1896
/*    _gx_image_reader_jpeg_one_mcu_write                                 */
1897
/*    _gx_image_reader_jpeg_one_mcu_rotated_write                         */
1898
/*                                                                        */
1899
/*  RELEASE HISTORY                                                       */
1900
/*                                                                        */
1901
/*    DATE              NAME                      DESCRIPTION             */
1902
/*                                                                        */
1903
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
1904
/*                                                                        */
1905
/**************************************************************************/
1906
360820
static VOID _gx_image_reader_jpeg_1555xrgb_pixel_write(GX_JPEG_INFO *jpeg_info, GX_UBYTE red, GX_UBYTE green, GX_UBYTE blue)
1907
{
1908
    /* Make sure the range of the RGB values are within bound. */
1909
360820
    red >>= 3;
1910
360820
    green >>= 3;
1911
360820
    blue >>= 3;
1912
1913
360820
    *((USHORT *)jpeg_info -> gx_jpeg_putdata) = (USHORT)((red << 10) | (green << 5 | blue));
1914
360820
    jpeg_info -> gx_jpeg_putdata += 2;
1915
360820
}
1916
#endif
1917
1918
/**************************************************************************/
1919
/*                                                                        */
1920
/*  FUNCTION                                               RELEASE        */
1921
/*                                                                        */
1922
/*    _gx_image_reader_jpeg_pixel_write_info_set          PORTABLE C      */
1923
/*                                                           6.3.0        */
1924
/*  AUTHOR                                                                */
1925
/*                                                                        */
1926
/*    Ting Zhu, Microsoft Corporation                                     */
1927
/*                                                                        */
1928
/*  DESCRIPTION                                                           */
1929
/*                                                                        */
1930
/*    Set information for writing pixel to memory.                        */
1931
/*                                                                        */
1932
/*  INPUT                                                                 */
1933
/*                                                                        */
1934
/*    jpeg_info                             JPEG control block            */
1935
/*                                                                        */
1936
/*  OUTPUT                                                                */
1937
/*                                                                        */
1938
/*    Status Code                                                         */
1939
/*                                                                        */
1940
/*  CALLS                                                                 */
1941
/*                                                                        */
1942
/*    _gx_image_reader_jpeg_565rgb_pixel_write_helium                     */
1943
/*                                          Write 565rgb pixel to memory  */
1944
/*    _gx_image_reader_jpeg_565rgb_pixel_write                            */
1945
/*                                          Write 565rgb pixel to memory  */
1946
/*    _gx_image_reader_jpeg_1555xrgb_pixel_write_helium                   */
1947
/*                                          Write 1555xrgb pixel to memory*/
1948
/*    _gx_image_reader_jpeg_1555xrgb_pixel_write                          */
1949
/*                                          Write 1555xrgb pixel to memory*/
1950
/*    _gx_image_reader_jpeg_24xrgb_24bpp_pixel_write_helium               */
1951
/*                                          Write 24xrgb or 24rgb pixel   */
1952
/*                                            to memory                   */
1953
/*    _gx_image_reader_jpeg_24xrgb_24bpp_pixel_write                      */
1954
/*                                          Write 24xrgb or 24rgb pixel   */
1955
/*                                            to memory                   */
1956
/*                                                                        */
1957
/*  CALLED BY                                                             */
1958
/*                                                                        */
1959
/*    _gx_image_reader_jpeg_decompress                                    */
1960
/*                                                                        */
1961
/*  RELEASE HISTORY                                                       */
1962
/*                                                                        */
1963
/*    DATE              NAME                      DESCRIPTION             */
1964
/*                                                                        */
1965
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
1966
/*                                                                        */
1967
/**************************************************************************/
1968
588
static UINT _gx_image_reader_jpeg_pixel_write_info_set(GX_JPEG_INFO *jpeg_info)
1969
{
1970
588
    if (!jpeg_info -> gx_jpeg_output_width)
1971
    {
1972
219
        jpeg_info -> gx_jpeg_output_width = jpeg_info -> gx_jpeg_width;
1973
219
        jpeg_info -> gx_jpeg_output_height = jpeg_info -> gx_jpeg_height;
1974
1975
219
        _gx_utility_rectangle_define(&jpeg_info -> gx_jpeg_output_clip, 0, 0, (GX_VALUE)(jpeg_info -> gx_jpeg_width - 1), (GX_VALUE)(jpeg_info -> gx_jpeg_height - 1));
1976
    }
1977
1978
588
    jpeg_info -> gx_jpeg_output_stride = jpeg_info -> gx_jpeg_output_rotation_angle == 0 ? jpeg_info -> gx_jpeg_output_width : jpeg_info -> gx_jpeg_output_height;
1979
1980
    /* Set pixel write callback.  */
1981

588
    switch (jpeg_info -> gx_jpeg_output_color_format)
1982
    {
1983
156
    case GX_COLOR_FORMAT_565RGB:
1984
#if defined(GX_ENABLE_ARM_HELIUM)
1985
        jpeg_info -> gx_jpeg_pixel_write_helium = _gx_image_reader_jpeg_565rgb_pixel_write_helium;
1986
#else
1987
156
        jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_565rgb_pixel_write;
1988
#endif
1989
156
        jpeg_info -> gx_jpeg_output_bpp = 2;
1990
156
        jpeg_info -> gx_jpeg_output_stride <<= 1;
1991
156
        break;
1992
1993
10
    case GX_COLOR_FORMAT_1555XRGB:
1994
#if defined(GX_ENABLE_ARM_HELIUM)
1995
        jpeg_info -> gx_jpeg_pixel_write_helium = _gx_image_reader_jpeg_1555xrgb_pixel_write_helium;
1996
#else
1997
10
        jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_1555xrgb_pixel_write;
1998
#endif
1999
10
        jpeg_info -> gx_jpeg_output_bpp = 2;
2000
10
        jpeg_info -> gx_jpeg_output_stride <<= 1;
2001
10
        break;
2002
2003
194
    case GX_COLOR_FORMAT_32ARGB:
2004
    case GX_COLOR_FORMAT_24XRGB:
2005
#if defined(GX_ENABLE_ARM_HELIUM)
2006
        jpeg_info -> gx_jpeg_pixel_write_helium = _gx_image_reader_jpeg_24xrgb_pixel_write_helium;
2007
#else
2008
194
        jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_24xrgb_pixel_write;
2009
#endif
2010
194
        jpeg_info -> gx_jpeg_output_bpp = 4;
2011
194
        jpeg_info -> gx_jpeg_output_stride <<= 2;
2012
194
        break;
2013
2014
228
    case GX_IMAGE_FORMAT_24BPP:
2015
    default:
2016
#if defined(GX_ENABLE_ARM_HELIUM)
2017
        jpeg_info -> gx_jpeg_pixel_write_helium = _gx_image_reader_jpeg_24bpp_pixel_write_helium;
2018
#else
2019
228
        jpeg_info -> gx_jpeg_pixel_write = _gx_image_reader_jpeg_24bpp_pixel_write;
2020
#endif
2021
228
        jpeg_info -> gx_jpeg_output_bpp = 3;
2022
228
        jpeg_info -> gx_jpeg_output_stride = (jpeg_info -> gx_jpeg_output_width * 3);
2023
228
        jpeg_info -> gx_jpeg_output_color_format = GX_IMAGE_FORMAT_24BPP;
2024
2025
228
        if (jpeg_info -> gx_jpeg_output_buffer)
2026
        {
2027
60
            return GX_NOT_SUPPORTED;
2028
        }
2029
168
        break;
2030
    }
2031
2032
528
    if (!jpeg_info -> gx_jpeg_output_buffer)
2033
    {
2034
219
        jpeg_info -> gx_jpeg_output_buffer = (GX_UBYTE *)_gx_system_memory_allocator((ULONG)(jpeg_info -> gx_jpeg_height * jpeg_info -> gx_jpeg_width * jpeg_info -> gx_jpeg_output_bpp));
2035
219
        if (!jpeg_info -> gx_jpeg_output_buffer)
2036
        {
2037
1
            return GX_SYSTEM_MEMORY_ERROR;
2038
        }
2039
    }
2040
2041
527
    return GX_SUCCESS;
2042
}
2043
2044
/**************************************************************************/
2045
/*                                                                        */
2046
/*  FUNCTION                                               RELEASE        */
2047
/*                                                                        */
2048
/*    _gx_image_reader_jpeg_one_mcu_write                 PORTABLE C      */
2049
/*                                                           6.3.0        */
2050
/*  AUTHOR                                                                */
2051
/*                                                                        */
2052
/*    Kenneth Maxwell, Microsoft Corporation                              */
2053
/*                                                                        */
2054
/*  DESCRIPTION                                                           */
2055
/*                                                                        */
2056
/*    Write decoded data of one MCU block into specified memory.          */
2057
/*                                                                        */
2058
/*  INPUT                                                                 */
2059
/*                                                                        */
2060
/*    jpeg_info                             JPEG control block            */
2061
/*    xpos                                  X position in image           */
2062
/*    ypos                                  y position in image           */
2063
/*    h                                     Horizontal sampling factor    */
2064
/*    v                                     Vertical sampling factor      */
2065
/*                                                                        */
2066
/*  OUTPUT                                                                */
2067
/*                                                                        */
2068
/*    Status Code                                                         */
2069
/*                                                                        */
2070
/*  CALLS                                                                 */
2071
/*                                                                        */
2072
/*    vldrbq_gather_offset_s8               Gather bytes from memory      */
2073
/*    GX_JPEG_DECODE_YCBCR2RGB_HELIUM       Convert YCbCr to RGB          */
2074
/*    GX_JPEG_DECODE_YCBCR2RGB              Convert YCbCr to RGB          */
2075
/*    [gx_jpeg_pixel_write_helium]          Write pixel to memory         */
2076
/*    [gx_jpeg_pixel_write]                 Write pixel to memory         */
2077
/*                                                                        */
2078
/*  CALLED BY                                                             */
2079
/*                                                                        */
2080
/*    _gx_image_reader_jpeg_decode                                        */
2081
/*                                                                        */
2082
/*  RELEASE HISTORY                                                       */
2083
/*                                                                        */
2084
/*    DATE              NAME                      DESCRIPTION             */
2085
/*                                                                        */
2086
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
2087
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
2088
/*                                            resulting in version 6.1    */
2089
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
2090
/*                                            added Helium support,       */
2091
/*                                            added partial canvas buffer */
2092
/*                                            support,                    */
2093
/*                                            resulting in version 6.3.0  */
2094
/*                                                                        */
2095
/**************************************************************************/
2096
126089
static UINT _gx_image_reader_jpeg_one_mcu_write(GX_JPEG_INFO *jpeg_info, INT xpos, INT ypos, INT h, INT v)
2097
{
2098
GX_UBYTE *put;
2099
INT       x;
2100
INT       y;
2101
INT       coff;
2102
126089
INT       xstart = 0;
2103
INT       xend;
2104
126089
INT       ystart = 0;
2105
INT       yend;
2106
2107
#if defined(GX_ENABLE_ARM_HELIUM)
2108
int8x16_t  vY;
2109
int8x16_t  vCb;
2110
int8x16_t  vCr;
2111
GX_UBYTE   size;
2112
uint8x16_t vred;
2113
uint8x16_t vgreen;
2114
uint8x16_t vblue;
2115
GX_UBYTE   index;
2116
#else
2117
GX_BYTE    Y;
2118
GX_BYTE    Cb;
2119
GX_BYTE    Cr;
2120
INT        red;
2121
INT        green;
2122
INT        blue;
2123
#endif
2124
2125
126089
    yend = (v << 3);
2126
126089
    xend = (h << 3);
2127
2128
2129
126089
    if (xpos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left)
2130
    {
2131
409
        xstart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left - xpos;
2132
    }
2133
2134
126089
    if (xpos + xend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right + 1)
2135
    {
2136
26704
        xend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right + 1 - xpos;
2137
    }
2138
2139
126089
    if (ypos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top)
2140
    {
2141
589
        ystart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top - ypos;
2142
    }
2143
2144
126089
    if (ypos + yend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom + 1)
2145
    {
2146
20149
        yend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom  + 1 - ypos;
2147
    }
2148
2149
126089
    put = (GX_UBYTE *)jpeg_info -> gx_jpeg_output_buffer;
2150
#if defined(GX_ENABLE_CANVAS_PARTIAL_FRAME_BUFFER)
2151
    put += (ypos + ystart - jpeg_info -> gx_jpeg_output_buffer_offset_y) * jpeg_info -> gx_jpeg_output_stride;
2152
    put += (xpos + xstart - jpeg_info -> gx_jpeg_output_buffer_offset_x) * jpeg_info -> gx_jpeg_output_bpp;
2153
#else
2154
126089
    put += (ypos + ystart) * jpeg_info -> gx_jpeg_output_stride;
2155
126089
    put += (xpos + xstart) * jpeg_info -> gx_jpeg_output_bpp;
2156
#endif
2157
2158
#if defined(GX_ENABLE_ARM_HELIUM)
2159
    index = (h == 1 ? 0 : (h - 1 + (xstart % h)));
2160
#endif
2161
2162
1323405
    for (y = ystart; y < yend; y++)
2163
    {
2164
1197316
        jpeg_info -> gx_jpeg_putdata = put;
2165
2166
#if defined(GX_ENABLE_ARM_HELIUM)
2167
        for (x = xstart; x < xend; x += size)
2168
        {
2169
            size = xend - x;
2170
2171
            if (size > 16)
2172
            {
2173
                size = 16;
2174
            }
2175
2176
            coff = x / h + ((y / v) << 3);
2177
2178
            vY = vldrbq_s8(jpeg_info -> gx_jpeg_Y_block + x + y * h * 8);
2179
            vCb = vldrbq_gather_offset_s8(jpeg_info -> gx_jpeg_Cb_block + coff, _gx_jpeg_cbcr_offset_table[index]);
2180
            vCr = vldrbq_gather_offset_s8(jpeg_info -> gx_jpeg_Cr_block + coff, _gx_jpeg_cbcr_offset_table[index]);
2181
2182
            /* Convert YCbCr to RGB.  */
2183
            GX_JPEG_DECODE_YCBCR2RGB_HELIUM(vred, vgreen, vblue, vY, vCb, vCr);
2184
2185
            jpeg_info -> gx_jpeg_pixel_write_helium(jpeg_info, vred, vgreen, vblue, size);
2186
        }
2187
#else
2188
15541564
        for (x = xstart; x < xend; x++)
2189
        {
2190
14344248
            coff = x / h + ((y / v) << 3);
2191
2192
14344248
            Y = jpeg_info -> gx_jpeg_Y_block[x + y * h * 8];
2193
14344248
            Cb = jpeg_info -> gx_jpeg_Cb_block[coff];
2194
14344248
            Cr = jpeg_info -> gx_jpeg_Cr_block[coff];
2195
2196
14344248
            GX_JPEG_DECODE_YCBCR2RGB(red, green, blue, Y, Cb, Cr);
2197
2198

14344248
            GX_SATURATE_TO_UBYTE(red, red);
2199

14344248
            GX_SATURATE_TO_UBYTE(green, green);
2200

14344248
            GX_SATURATE_TO_UBYTE(blue, blue);
2201
2202
14344248
            jpeg_info -> gx_jpeg_pixel_write(jpeg_info, (GX_UBYTE)red, (GX_UBYTE)green, (GX_UBYTE)blue);
2203
        }
2204
#endif
2205
2206
1197316
        put += jpeg_info -> gx_jpeg_output_stride;
2207
    }
2208
2209
126089
    return GX_SUCCESS;
2210
}
2211
2212
/**************************************************************************/
2213
/*                                                                        */
2214
/*  FUNCTION                                               RELEASE        */
2215
/*                                                                        */
2216
/*    _gx_image_reader_jpeg_one_mcu_rotated_write         PORTABLE C      */
2217
/*                                                           6.3.0        */
2218
/*  AUTHOR                                                                */
2219
/*                                                                        */
2220
/*    Ting Zhu, Microsoft Corporation                                     */
2221
/*                                                                        */
2222
/*  DESCRIPTION                                                           */
2223
/*                                                                        */
2224
/*    Write decoded data of one MCU block into specified memory.          */
2225
/*                                                                        */
2226
/*  INPUT                                                                 */
2227
/*                                                                        */
2228
/*    jpeg_info                             JPEG control block            */
2229
/*    xpos                                  X position in image           */
2230
/*    ypos                                  y position in image           */
2231
/*    h                                     Horizontal sampling factor    */
2232
/*    v                                     Vertical sampling factor      */
2233
/*                                                                        */
2234
/*  OUTPUT                                                                */
2235
/*                                                                        */
2236
/*    Status Code                                                         */
2237
/*                                                                        */
2238
/*  CALLS                                                                 */
2239
/*                                                                        */
2240
/*    vldrbq_gather_offset_s8               Gather bytes from memory      */
2241
/*    GX_JPEG_DECODE_YCBCR2RGB_HELIUM       Convert YCbCr to RGB          */
2242
/*    GX_JPEG_DECODE_YCBCR2RGB              Convert YCbCr to RGB          */
2243
/*    [gx_jpeg_pixel_write_helium]          Write pixel to memory         */
2244
/*    [gx_jpeg_pixel_write]                 Write pixel to memory         */
2245
/*                                                                        */
2246
/*  CALLED BY                                                             */
2247
/*                                                                        */
2248
/*    _gx_image_reader_jpeg_decode                                        */
2249
/*                                                                        */
2250
/*  RELEASE HISTORY                                                       */
2251
/*                                                                        */
2252
/*    DATE              NAME                      DESCRIPTION             */
2253
/*                                                                        */
2254
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
2255
/*                                                                        */
2256
/**************************************************************************/
2257
155006
static UINT _gx_image_reader_jpeg_one_mcu_rotated_write(GX_JPEG_INFO *jpeg_info, INT xpos, INT ypos, INT h, INT v)
2258
{
2259
GX_UBYTE *put;
2260
INT       x;
2261
INT       coff;
2262
155006
INT       xstart = 0;
2263
INT       xend;
2264
155006
INT       ystart = 0;
2265
INT       yend;
2266
INT       stride;
2267
2268
#if defined(GX_ENABLE_ARM_HELIUM)
2269
int8x16_t  vY;
2270
int8x16_t  vCb;
2271
int8x16_t  vCr;
2272
uint8x16_t vred;
2273
uint8x16_t vgreen;
2274
uint8x16_t vblue;
2275
INT        size;
2276
GX_UBYTE   index;
2277
uint8x16_t yoffset;
2278
uint8x16_t cbcroffset;
2279
#else
2280
GX_BYTE    Y;
2281
GX_BYTE    Cb;
2282
GX_BYTE    Cr;
2283
INT        red;
2284
INT        green;
2285
INT        blue;
2286
INT        y;
2287
155006
GX_BYTE    sign = 1;
2288
#endif
2289
2290
155006
    xend = (h << 3) - 1;
2291
155006
    yend = (v << 3) - 1;
2292
2293
155006
    if (xpos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left)
2294
    {
2295
21404
        xstart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_left - xpos;
2296
    }
2297
2298
155006
    if (xpos + xend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right)
2299
    {
2300
24590
        xend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_right - xpos;
2301
    }
2302
2303
155006
    if (xstart > xend)
2304
    {
2305
38648
        return GX_SUCCESS;
2306
    }
2307
2308
116358
    if (ypos < jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top)
2309
    {
2310
11111
        ystart = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_top - ypos;
2311
    }
2312
2313
116358
    if (ypos + yend > jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom)
2314
    {
2315
13773
        yend = jpeg_info -> gx_jpeg_output_clip.gx_rectangle_bottom - ypos;
2316
    }
2317
2318
116358
    if (ystart > yend)
2319
    {
2320
17589
        return GX_SUCCESS;
2321
    }
2322
2323
#if defined(GX_ENABLE_ARM_HELIUM)
2324
    size = yend - ystart + 1;
2325
#endif
2326
2327
98769
    stride = jpeg_info -> gx_jpeg_output_stride;
2328
98769
    put = (GX_UBYTE *)jpeg_info -> gx_jpeg_output_buffer;
2329
2330
98769
    if (jpeg_info -> gx_jpeg_output_rotation_angle == GX_SCREEN_ROTATION_CW)
2331
    {
2332
66192
        put += (jpeg_info -> gx_jpeg_output_width - xpos - 1 - xstart) * stride;
2333
66192
        put += (ypos + ystart) * jpeg_info -> gx_jpeg_output_bpp;
2334
66192
        stride = (-stride);
2335
    }
2336
    else
2337
    {
2338
32577
        put += (xpos + xstart) * stride;
2339
32577
        put += (jpeg_info -> gx_jpeg_output_height - ypos - 1 - yend) * jpeg_info -> gx_jpeg_output_bpp;
2340
2341
#if defined(GX_ENABLE_ARM_HELIUM)
2342
        ystart = (v << 3) - 1 - yend;
2343
#else
2344
32577
        GX_SWAP_VALS(ystart, yend);
2345
32577
        sign = -1;
2346
#endif
2347
    }
2348
2349
#if defined(GX_ENABLE_ARM_HELIUM)
2350
    if (jpeg_info -> gx_jpeg_output_rotation_angle == GX_SCREEN_ROTATION_CW)
2351
    {
2352
        index = (v == 2 ? (1 + (ystart % 2)) : 0);
2353
2354
        yoffset = _gx_jpeg_y_offset_rotated_table_cw[h >> 1];
2355
        cbcroffset = _gx_jpeg_cbcr_offset_rotated_table_cw[index];
2356
    }
2357
    else
2358
    {
2359
        yoffset = _gx_jpeg_y_offset_rotated_table_ccw[h + v - 2];
2360
        cbcroffset = _gx_jpeg_cbcr_offset_rotated_table_ccw[v - 1];
2361
2362
        if(ystart)
2363
        {
2364
            for (x = 0; x < 16 - ystart; x++)
2365
            {
2366
                yoffset[x] = yoffset[ystart + x];
2367
                cbcroffset[x] = cbcroffset[ystart + x];
2368
            }
2369
2370
            ystart = 0;
2371
        }
2372
    }
2373
#endif
2374
2375
1498068
    for (x = xstart; x <= xend; x++)
2376
    {
2377
1399299
        jpeg_info -> gx_jpeg_putdata = put;
2378
2379
#if defined(GX_ENABLE_ARM_HELIUM)
2380
        coff = x / h + ((ystart / v) << 3);
2381
2382
        vY = vldrbq_gather_offset_s8(jpeg_info -> gx_jpeg_Y_block + x + ystart * h * 8, yoffset);
2383
        vCb = vldrbq_gather_offset_s8(jpeg_info -> gx_jpeg_Cb_block + coff, cbcroffset);
2384
        vCr = vldrbq_gather_offset_s8(jpeg_info -> gx_jpeg_Cr_block + coff, cbcroffset);
2385
2386
        /* Convert YCbCr to RGB.  */
2387
        GX_JPEG_DECODE_YCBCR2RGB_HELIUM(vred, vgreen, vblue, vY, vCb, vCr);
2388
2389
        jpeg_info -> gx_jpeg_pixel_write_helium(jpeg_info, vred, vgreen, vblue, size);
2390
2391
#else
2392
17160539
        for (y = ystart; y != yend + sign; y += sign)
2393
        {
2394
15761240
            coff = x / h + ((y / v) << 3);
2395
2396
15761240
            Y = jpeg_info -> gx_jpeg_Y_block[x + y * h * 8];
2397
15761240
            Cb = jpeg_info -> gx_jpeg_Cb_block[coff];
2398
15761240
            Cr = jpeg_info -> gx_jpeg_Cr_block[coff];
2399
2400
15761240
            GX_JPEG_DECODE_YCBCR2RGB(red, green, blue, Y, Cb, Cr);
2401
2402

15761240
            GX_SATURATE_TO_UBYTE(red, red);
2403

15761240
            GX_SATURATE_TO_UBYTE(green, green);
2404

15761240
            GX_SATURATE_TO_UBYTE(blue, blue);
2405
2406
15761240
            jpeg_info -> gx_jpeg_pixel_write(jpeg_info, (GX_UBYTE)red, (GX_UBYTE)green, (GX_UBYTE)blue);
2407
        }
2408
#endif
2409
1399299
        put += stride;
2410
    }
2411
2412
98769
    return GX_SUCCESS;
2413
}
2414
2415
/**************************************************************************/
2416
/*                                                                        */
2417
/*  FUNCTION                                               RELEASE        */
2418
/*                                                                        */
2419
/*    _gx_image_reader_jpeg_decompress                    PORTABLE C      */
2420
/*                                                           6.3.0        */
2421
/*  AUTHOR                                                                */
2422
/*                                                                        */
2423
/*    Kenneth Maxwell, Microsoft Corporation                              */
2424
/*                                                                        */
2425
/*  DESCRIPTION                                                           */
2426
/*                                                                        */
2427
/*    Decompress JPG data stream.                                         */
2428
/*                                                                        */
2429
/*  INPUT                                                                 */
2430
/*                                                                        */
2431
/*    jpeg_info                             JPEG control block            */
2432
/*                                                                        */
2433
/*  OUTPUT                                                                */
2434
/*                                                                        */
2435
/*    Status Code                                                         */
2436
/*                                                                        */
2437
/*  CALLS                                                                 */
2438
/*                                                                        */
2439
/*    _gx_image_reader_jpeg_one_block_decode                              */
2440
/*                                          Decode one blcok of jpeg data */
2441
/*    _gx_image_reader_jpeg_one_mcu_write   Write decoded data to         */
2442
/*                                            specified memory            */
2443
/*                                                                        */
2444
/*  CALLED BY                                                             */
2445
/*                                                                        */
2446
/*    _gx_image_reader_jpeg_decode                                        */
2447
/*                                                                        */
2448
/*  RELEASE HISTORY                                                       */
2449
/*                                                                        */
2450
/*    DATE              NAME                      DESCRIPTION             */
2451
/*                                                                        */
2452
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
2453
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
2454
/*                                            resulting in version 6.1    */
2455
/*  10-31-2022     Kenneth Maxwell          Modified comment(s),          */
2456
/*                                            abort if block decode fails,*/
2457
/*                                            resulting in version 6.2.0  */
2458
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
2459
/*                                            improved logic,             */
2460
/*                                            resulting in version 6.3.0  */
2461
/*                                                                        */
2462
/**************************************************************************/
2463
588
static UINT _gx_image_reader_jpeg_decompress(GX_JPEG_INFO *jpeg_info)
2464
{
2465
int  h;
2466
int  v;
2467
int  x;
2468
int  y;
2469
int  xx;
2470
int  yy;
2471
588
UINT status = GX_SUCCESS;
2472
UINT (*one_mcu_write)(GX_JPEG_INFO *jpeg_info, INT xpos, INT ypos, INT h, INT v);
2473
2474
588
    h = (jpeg_info -> gx_jpeg_sample_factor[0] >> 4);
2475
588
    v = (jpeg_info -> gx_jpeg_sample_factor[0] & 0x0f);
2476
2477
588
    if (v > 2)
2478
    {
2479
        return GX_INVALID_FORMAT;
2480
    }
2481
2482
588
    status = _gx_image_reader_jpeg_pixel_write_info_set(jpeg_info);
2483
2484
588
    if ((jpeg_info -> gx_jpeg_output_rotation_angle != 0) &&
2485
270
        (jpeg_info -> gx_jpeg_output_color_format != GX_IMAGE_FORMAT_24BPP))
2486
    {
2487
210
        one_mcu_write = _gx_image_reader_jpeg_one_mcu_rotated_write;
2488
    }
2489
    else
2490
    {
2491
378
        one_mcu_write = _gx_image_reader_jpeg_one_mcu_write;
2492
    }
2493
2494
11554
    for (y = 0; y < jpeg_info -> gx_jpeg_height; y += 8 * v)
2495
    {
2496
315912
        for (x = 0; x < jpeg_info -> gx_jpeg_width; x += 8 * h)
2497
        {
2498
            /* Decode one MCU */
2499

732038
            for (yy = 0; yy < v && status == GX_SUCCESS; yy++)
2500
            {
2501

1244728
                for (xx = 0; xx < h && status == GX_SUCCESS; xx++)
2502
                {
2503
                    /* Y */
2504
817636
                    status = _gx_image_reader_jpeg_one_block_decode(jpeg_info, 0, jpeg_info -> gx_jpeg_Y_block + yy * 128 + xx * 8);
2505
                }
2506
            }
2507
2508

304946
            if (status == GX_SUCCESS && jpeg_info -> gx_jpeg_num_of_components > 1)
2509
            {
2510
                /* Cb */
2511
281091
                status = _gx_image_reader_jpeg_one_block_decode(jpeg_info, 1, jpeg_info -> gx_jpeg_Cb_block);
2512
2513
                /* Cr */
2514
281091
                if (status == GX_SUCCESS)
2515
                {
2516
281091
                    status = _gx_image_reader_jpeg_one_block_decode(jpeg_info, 2, jpeg_info -> gx_jpeg_Cr_block);
2517
                }
2518
            }
2519
2520
304946
            if (status == GX_SUCCESS)
2521
            {
2522
281095
                one_mcu_write(jpeg_info, jpeg_info -> gx_jpeg_output_xpos + x, jpeg_info -> gx_jpeg_output_ypos + y, h, v);
2523
            }
2524
        }
2525
    }
2526
2527
588
    return status;
2528
}
2529
2530
/**************************************************************************/
2531
/*                                                                        */
2532
/*  FUNCTION                                               RELEASE        */
2533
/*                                                                        */
2534
/*    _gx_image_reader_jpeg_decode_blocks                 PORTABLE C      */
2535
/*                                                           6.3.0        */
2536
/*  AUTHOR                                                                */
2537
/*                                                                        */
2538
/*    Kenneth Maxwell, Microsoft Corporation                              */
2539
/*                                                                        */
2540
/*  DESCRIPTION                                                           */
2541
/*                                                                        */
2542
/*    This function decode a jpg format image.                            */
2543
/*                                                                        */
2544
/*  INPUT                                                                 */
2545
/*                                                                        */
2546
/*    jpeg_info                             Jpeg decode control block     */
2547
/*                                                                        */
2548
/*  OUTPUT                                                                */
2549
/*                                                                        */
2550
/*    status                                Completion status             */
2551
/*                                                                        */
2552
/*  CALLS                                                                 */
2553
/*                                                                        */
2554
/*    _gx_image_reader_jpeg_quantization_table_set                        */
2555
/*                                          Set jpeg quantization table   */
2556
/*    _gx_image_reader_jpeg_frame_header_read                             */
2557
/*                                          Read frame header information */
2558
/*    _gx_image_reader_huffman_table_set    Set up huffman table          */
2559
/*    _gx_image_reader_jpeg_scan_header_read                              */
2560
/*                                          Read scan header information  */
2561
/*    _gx_image_reader_jpeg_decompress      Decompress jped data stream   */
2562
/*    _gx_system_memory_free                Application defined memory    */
2563
/*                                            free function               */
2564
/*                                                                        */
2565
/*  CALLED BY                                                             */
2566
/*                                                                        */
2567
/*    _gx_image_reader_jpeg_decode                                        */
2568
/*    _gx_image_reader_jpeg_mcu_decode                                    */
2569
/*                                                                        */
2570
/*  RELEASE HISTORY                                                       */
2571
/*                                                                        */
2572
/*    DATE              NAME                      DESCRIPTION             */
2573
/*                                                                        */
2574
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
2575
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
2576
/*                                            resulting in version 6.1    */
2577
/*  10-31-2023     Ting Zhu                 Modified comment(s), removed  */
2578
/*                                            huffman table free logic,   */
2579
/*                                            resulting in version 6.3.0  */
2580
/*                                                                        */
2581
/**************************************************************************/
2582
596
static UINT _gx_image_reader_jpeg_decode_blocks(GX_JPEG_INFO *jpeg_info)
2583
{
2584
GX_UBYTE *jpeg_data;
2585
GX_UBYTE  marker;
2586
UINT      segment_len;
2587
596
UINT      status = GX_SUCCESS;
2588
2589

596
    if (jpeg_info -> gx_jpeg_data == GX_NULL || jpeg_info -> gx_jpeg_data_size < 10)
2590
    {
2591
2
        return GX_INVALID_VALUE;
2592
    }
2593
2594
594
    jpeg_data = jpeg_info -> gx_jpeg_data;
2595
2596
    /* Read JPEG File flag that mark the start of a JPEG image. */
2597

594
    if ((*jpeg_data++ != 0xff) || (*jpeg_data++ != 0xd8))
2598
    {
2599
2
        return GX_INVALID_FORMAT; /*Not a jpeg file */
2600
    }
2601
2602
592
    jpeg_info -> gx_jpeg_data_index += 2;
2603
2604

19376
    while ((jpeg_info -> gx_jpeg_data_index + 3 < jpeg_info -> gx_jpeg_data_size) &&
2605
           (status == GX_SUCCESS))
2606
    {
2607
18785
        jpeg_data = (jpeg_info -> gx_jpeg_data + jpeg_info -> gx_jpeg_data_index);
2608
18785
        marker = *(jpeg_data + 1);
2609
2610

18785
        if ((*jpeg_data == 0xff) && (marker != 0) && (marker != 0xff))
2611
        {
2612
4221
            jpeg_data += 2;
2613
4221
            jpeg_info -> gx_jpeg_data_index += 2;
2614
2615
            /* Read WORD length */
2616
4221
            segment_len = *(jpeg_data);
2617
4221
            segment_len <<= 8;
2618
4221
            segment_len |= *(jpeg_data + 1);
2619
2620
4221
            if ((UINT)jpeg_info -> gx_jpeg_data_index + segment_len > (UINT)jpeg_info -> gx_jpeg_data_size)
2621
            {
2622
                /* Invalid data size. */
2623
1
                status = GX_FAILURE;
2624
1
                break;
2625
            }
2626
2627

4220
            switch (marker)
2628
            {
2629
842
            case 0xdb:
2630
                /* Define Quantization Table */
2631
842
                status = _gx_image_reader_jpeg_quantization_table_set(jpeg_info, segment_len);
2632
842
                break;
2633
2634
590
            case 0xc0:
2635
                /* Start of Frame */
2636
590
                status = _gx_image_reader_jpeg_frame_header_read(jpeg_info, segment_len);
2637
590
                break;
2638
2639
1335
            case 0xc4:
2640
                /* Define Huffman Table */
2641
1335
                status = _gx_image_reader_huffman_table_set(jpeg_info, segment_len);
2642
1335
                break;
2643
2644
7
            case 0xdd:
2645
                /* Read restart interval which specifies the number of MCU in restart interval. */
2646
7
                jpeg_data += 2;
2647
7
                jpeg_info -> gx_jpeg_restart_interval = *jpeg_data++;
2648
7
                jpeg_info -> gx_jpeg_restart_interval <<= 8;
2649
7
                jpeg_info -> gx_jpeg_restart_interval |= *jpeg_data++;
2650
7
                jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
2651
7
                break;
2652
2653
588
            case 0xda:
2654
                /* Start of Scan, stores which Huffman tables are associated with which components
2655
                   The program start decoding the data section directly after it reads in this header. */
2656
588
                _gx_image_reader_jpeg_scan_header_read(jpeg_info, segment_len);
2657
2658
                /* Start decoding jpeg data stream. */
2659
588
                status = _gx_image_reader_jpeg_decompress(jpeg_info);
2660
588
                break;
2661
2662
858
            default:
2663
                /* Unkown marker, skip */
2664
858
                jpeg_info -> gx_jpeg_data_index += (INT)segment_len;
2665
858
                break;
2666
            }
2667
        }
2668
        else
2669
        {
2670
14564
            jpeg_info -> gx_jpeg_data_index++;
2671
        }
2672
    }
2673
2674
592
    return status;
2675
}
2676
2677
/**************************************************************************/
2678
/*                                                                        */
2679
/*  FUNCTION                                               RELEASE        */
2680
/*                                                                        */
2681
/*    _gx_image_reader_jpeg_decode                        PORTABLE C      */
2682
/*                                                           6.3.0        */
2683
/*  AUTHOR                                                                */
2684
/*                                                                        */
2685
/*    Kenneth Maxwell, Microsoft Corporation                              */
2686
/*                                                                        */
2687
/*  DESCRIPTION                                                           */
2688
/*                                                                        */
2689
/*    This function decodes a jpg format image and saves the decoded data */
2690
/*    to a GX_PIXELMAP structure.                                         */
2691
/*                                                                        */
2692
/*  INPUT                                                                 */
2693
/*                                                                        */
2694
/*    read_data                             Input JPEG data stream        */
2695
/*    data_size                             JPEG size in bytes            */
2696
/*    outmap                                Output pixelmap               */
2697
/*                                                                        */
2698
/*  OUTPUT                                                                */
2699
/*                                                                        */
2700
/*    status                                Completion status             */
2701
/*                                                                        */
2702
/*  CALLS                                                                 */
2703
/*                                                                        */
2704
/*    _gx_image_reader_jpeg_decode_blocks   Decode a jpeg format image    */
2705
/*                                                                        */
2706
/*  CALLED BY                                                             */
2707
/*                                                                        */
2708
/*    _gx_image_reader_image_decode                                       */
2709
/*                                                                        */
2710
/*  RELEASE HISTORY                                                       */
2711
/*                                                                        */
2712
/*    DATE              NAME                      DESCRIPTION             */
2713
/*                                                                        */
2714
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
2715
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
2716
/*                                            resulting in version 6.1    */
2717
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
2718
/*                                            improved logic,             */
2719
/*                                            resulting in version 6.3.0  */
2720
/*                                                                        */
2721
/**************************************************************************/
2722
231
UINT _gx_image_reader_jpeg_decode(GX_IMAGE_READER *image_reader, GX_PIXELMAP *outmap)
2723
{
2724
UINT          status;
2725
GX_JPEG_INFO *jpeg_info;
2726
2727
2728

231
    if ((!_gx_system_memory_allocator) || (!_gx_system_memory_free))
2729
    {
2730
2
        return GX_SYSTEM_MEMORY_ERROR;
2731
    }
2732
2733
229
    jpeg_info = (GX_JPEG_INFO *)_gx_system_memory_allocator(sizeof(GX_JPEG_INFO));
2734
2735
229
    if (!jpeg_info)
2736
    {
2737
2
        return GX_SYSTEM_MEMORY_ERROR;
2738
    }
2739
2740
227
    memset(jpeg_info, 0, sizeof(GX_JPEG_INFO));
2741
2742
2743
227
    jpeg_info -> gx_jpeg_data = (GX_UBYTE *)image_reader -> gx_image_reader_source_data;
2744
227
    jpeg_info -> gx_jpeg_data_size = (INT)image_reader -> gx_image_reader_source_data_size;
2745
227
    jpeg_info -> gx_jpeg_data_index = 0;
2746
2747
227
    if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_DITHER)
2748
    {
2749
92
        jpeg_info -> gx_jpeg_output_color_format  = GX_IMAGE_FORMAT_24BPP;
2750
    }
2751
    else
2752
    {
2753
135
        jpeg_info -> gx_jpeg_output_color_format  = image_reader -> gx_image_reader_color_format;
2754
    }
2755
2756
227
    if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ROTATE_CW)
2757
    {
2758
        jpeg_info -> gx_jpeg_output_rotation_angle =  GX_SCREEN_ROTATION_CW;
2759
    }
2760
227
    else if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ROTATE_CCW)
2761
    {
2762
        jpeg_info -> gx_jpeg_output_rotation_angle =  GX_SCREEN_ROTATION_CCW;
2763
    }
2764
2765
227
    status = _gx_image_reader_jpeg_decode_blocks(jpeg_info);
2766
2767
227
    if (status == GX_SUCCESS)
2768
    {
2769
218
        outmap -> gx_pixelmap_data = jpeg_info -> gx_jpeg_output_buffer;
2770
218
        outmap -> gx_pixelmap_data_size = (ULONG)(jpeg_info -> gx_jpeg_output_stride * jpeg_info -> gx_jpeg_height);
2771
218
        outmap -> gx_pixelmap_width = (GX_VALUE)jpeg_info -> gx_jpeg_width;
2772
218
        outmap -> gx_pixelmap_height = (GX_VALUE)jpeg_info -> gx_jpeg_height;
2773
218
        outmap -> gx_pixelmap_flags = 0;
2774
218
        outmap -> gx_pixelmap_format = jpeg_info -> gx_jpeg_output_color_format;
2775
    }
2776
2777
227
    _gx_system_memory_free((void *)jpeg_info);
2778
2779
227
    return status;
2780
}
2781
2782
/**************************************************************************/
2783
/*                                                                        */
2784
/*  FUNCTION                                               RELEASE        */
2785
/*                                                                        */
2786
/*    _gx_image_reader_jpeg_mcu_decode                    PORTABLE C      */
2787
/*                                                           6.3.0        */
2788
/*  AUTHOR                                                                */
2789
/*                                                                        */
2790
/*    Kenneth Maxwell, Microsoft Corporation                              */
2791
/*                                                                        */
2792
/*  DESCRIPTION                                                           */
2793
/*                                                                        */
2794
/*    This function decodes a jpg format image and draw it to canvas      */
2795
/*    directly.                                                           */
2796
/*                                                                        */
2797
/*  INPUT                                                                 */
2798
/*                                                                        */
2799
/*    read_data                             Input JPEG data               */
2800
/*    data_size                             JPEG size in bytes            */
2801
/*    context                               Drawing contex                */
2802
/*    xpos                                  X-coord of draw start point in*/
2803
/*                                            canvas                      */
2804
/*    ypos                                  Y-coord of draw start point in*/
2805
/*                                            canvas                      */
2806
/*                                                                        */
2807
/*  OUTPUT                                                                */
2808
/*                                                                        */
2809
/*    status                                Completion status             */
2810
/*                                                                        */
2811
/*  CALLS                                                                 */
2812
/*                                                                        */
2813
/*    _gx_image_reader_jpeg_decode_blocks   Decode a jpeg format image    */
2814
/*                                                                        */
2815
/*  CALLED BY                                                             */
2816
/*                                                                        */
2817
/*    GUIX Internal Code                                                  */
2818
/*                                                                        */
2819
/*  RELEASE HISTORY                                                       */
2820
/*                                                                        */
2821
/*    DATE              NAME                      DESCRIPTION             */
2822
/*                                                                        */
2823
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
2824
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
2825
/*                                            resulting in version 6.1    */
2826
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
2827
/*                                            improved logic,             */
2828
/*                                            resulting in version 6.3.0  */
2829
/*                                                                        */
2830
/**************************************************************************/
2831
403
UINT _gx_image_reader_jpeg_mcu_decode(GX_CONST GX_UBYTE *read_data, ULONG data_size,
2832
                                      GX_DRAW_CONTEXT *context, INT xpos, INT ypos)
2833
{
2834
UINT          status;
2835
GX_JPEG_INFO *jpeg_info;
2836
2837

403
    if ((!_gx_system_memory_allocator) || (!_gx_system_memory_free))
2838
    {
2839
22
        return GX_SYSTEM_MEMORY_ERROR;
2840
    }
2841
2842
381
    jpeg_info = (GX_JPEG_INFO *)_gx_system_memory_allocator(sizeof(GX_JPEG_INFO));
2843
2844
381
    if (!jpeg_info)
2845
    {
2846
11
        return GX_SYSTEM_MEMORY_ERROR;
2847
    }
2848
2849
370
    if (!context)
2850
    {
2851
1
        return GX_INVALID_CONTEXT;
2852
    }
2853
2854
369
    memset(jpeg_info, 0, sizeof(GX_JPEG_INFO));
2855
2856
369
    jpeg_info -> gx_jpeg_data = (GX_UBYTE *)read_data;
2857
369
    jpeg_info -> gx_jpeg_data_size = (INT)data_size;
2858
369
    jpeg_info -> gx_jpeg_data_index = 0;
2859
369
    jpeg_info -> gx_jpeg_output_xpos = xpos;
2860
369
    jpeg_info -> gx_jpeg_output_ypos = ypos;
2861
369
    jpeg_info -> gx_jpeg_output_color_format = context -> gx_draw_context_display -> gx_display_color_format;
2862
369
    jpeg_info -> gx_jpeg_output_rotation_angle = context -> gx_draw_context_display -> gx_display_rotation_angle;
2863
369
    jpeg_info -> gx_jpeg_output_buffer = (GX_UBYTE *)context -> gx_draw_context_memory;
2864
#ifdef GX_ENABLE_CANVAS_PARTIAL_FRAME_BUFFER
2865
    jpeg_info -> gx_jpeg_output_width = (USHORT)context -> gx_draw_context_canvas -> gx_canvas_memory_width;
2866
    jpeg_info -> gx_jpeg_output_height = (USHORT)context -> gx_draw_context_canvas -> gx_canvas_memory_height;
2867
    jpeg_info -> gx_jpeg_output_buffer_offset_x = context -> gx_draw_context_offset_x;
2868
    jpeg_info -> gx_jpeg_output_buffer_offset_y = context -> gx_draw_context_offset_y;
2869
#else
2870
369
    jpeg_info -> gx_jpeg_output_width = (USHORT)context -> gx_draw_context_canvas -> gx_canvas_x_resolution;
2871
369
    jpeg_info -> gx_jpeg_output_height = (USHORT)context -> gx_draw_context_canvas -> gx_canvas_y_resolution;
2872
#endif
2873
369
    jpeg_info -> gx_jpeg_output_clip = *context -> gx_draw_context_clip;
2874
2875
2876
369
    status = _gx_image_reader_jpeg_decode_blocks(jpeg_info);
2877
2878
369
    _gx_system_memory_free((void *)jpeg_info);
2879
2880
369
    return status;
2881
}
2882
#endif
2883