GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_image_reader_png_decode.c Lines: 612 612 100.0 %
Date: 2026-03-06 19:21:09 Branches: 338 339 99.7 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** GUIX Component                                                        */
17
/**                                                                       */
18
/**   Display Management (Display)                                        */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
25
/* Include necessary system files.  */
26
27
#include "gx_api.h"
28
#include "gx_system.h"
29
#include "gx_utility.h"
30
#include "gx_image_reader.h"
31
32
33
#if defined(GX_SOFTWARE_DECODER_SUPPORT)
34
static UINT _bit_buffer;
35
static UINT _bit_count;
36
37
/**************************************************************************/
38
/*                                                                        */
39
/*  FUNCTION                                               RELEASE        */
40
/*                                                                        */
41
/*    _gx_image_reader_png_crc_table_make                 PORTABLE C      */
42
/*                                                           6.1          */
43
/*  AUTHOR                                                                */
44
/*                                                                        */
45
/*    Kenneth Maxwell, Microsoft Corporation                              */
46
/*                                                                        */
47
/*  DESCRIPTION                                                           */
48
/*                                                                        */
49
/*    This function creates crc table that speed the crc calculation.     */
50
/*                                                                        */
51
/*  INPUT                                                                 */
52
/*                                                                        */
53
/*    png                                   PNG control block             */
54
/*                                                                        */
55
/*  OUTPUT                                                                */
56
/*                                                                        */
57
/*    None                                                                */
58
/*                                                                        */
59
/*  CALLS                                                                 */
60
/*                                                                        */
61
/*    None                                                                */
62
/*                                                                        */
63
/*  CALLED BY                                                             */
64
/*                                                                        */
65
/*    _gx_image_reader_png_decode                                         */
66
/*                                                                        */
67
/**************************************************************************/
68
666
static VOID _gx_image_reader_png_crc_table_make(GX_PNG *png)
69
{
70
UINT crc;
71
UINT n;
72
UINT k;
73
74
171162
    for (n = 0; n < 256; n++)
75
    {
76
170496
        crc = n;
77
1534464
        for (k = 0; k < 8; k++)
78
        {
79
1363968
            if (crc & 1)
80
            {
81
681984
                crc = 0xedb88320 ^ (crc >> 1);
82
            }
83
            else
84
            {
85
681984
                crc = crc >> 1;
86
            }
87
        }
88
170496
        png -> gx_png_crc_table[n] = crc;
89
    }
90
666
}
91
92
/**************************************************************************/
93
/*                                                                        */
94
/*  FUNCTION                                               RELEASE        */
95
/*                                                                        */
96
/*    _gx_display_driver_png_crc_get                      PORTABLE C      */
97
/*                                                           6.1          */
98
/*  AUTHOR                                                                */
99
/*                                                                        */
100
/*    Kenneth Maxwell, Microsoft Corporation                              */
101
/*                                                                        */
102
/*  DESCRIPTION                                                           */
103
/*                                                                        */
104
/*    This function calculates Cyclic Redundancy Check of a pecified      */
105
/*    data stream.                                                        */
106
/*                                                                        */
107
/*  INPUT                                                                 */
108
/*                                                                        */
109
/*    png                                   PNG control block             */
110
/*    crc                                   Generated crc value           */
111
/*    len                                   Data length                   */
112
/*                                                                        */
113
/*  OUTPUT                                                                */
114
/*                                                                        */
115
/*    None                                                                */
116
/*                                                                        */
117
/*  CALLS                                                                 */
118
/*                                                                        */
119
/*    None                                                                */
120
/*                                                                        */
121
/*  CALLED BY                                                             */
122
/*                                                                        */
123
/*    _gx_image_reader_png_decode                                         */
124
/*    _gx_image_reader_png_bits_get                                       */
125
/*                                                                        */
126
/**************************************************************************/
127
4274
static VOID _gx_image_reader_png_crc_get(GX_PNG *png, UINT *crc, UINT len)
128
{
129
UINT      n;
130
4274
GX_UBYTE *buf = png -> gx_png_data + png -> gx_png_data_index;
131
4274
UINT      crc_cal = (*crc);
132
133
15393491
    for (n = 0; n < len; n++)
134
    {
135
15389217
        crc_cal = png -> gx_png_crc_table[(crc_cal ^ buf[n]) & 0xff] ^ (crc_cal >> 8);
136
    }
137
138
4274
    (*crc) = crc_cal ^ 0xffffffff;
139
4274
}
140
141
/**************************************************************************/
142
/*                                                                        */
143
/*  FUNCTION                                               RELEASE        */
144
/*                                                                        */
145
/*    _gx_image_reader_png_4bytes_read                    PORTABLE C      */
146
/*                                                           6.1          */
147
/*  AUTHOR                                                                */
148
/*                                                                        */
149
/*    Kenneth Maxwell, Microsoft Corporation                              */
150
/*                                                                        */
151
/*  DESCRIPTION                                                           */
152
/*                                                                        */
153
/*    This function reads 4 bytes and packed it as an INT value.          */
154
/*                                                                        */
155
/*  INPUT                                                                 */
156
/*                                                                        */
157
/*    png                                   PNG control block             */
158
/*    value                                 Retrieved INT value           */
159
/*                                                                        */
160
/*  OUTPUT                                                                */
161
/*                                                                        */
162
/*    None                                                                */
163
/*                                                                        */
164
/*  CALLS                                                                 */
165
/*                                                                        */
166
/*    None                                                                */
167
/*                                                                        */
168
/*  CALLED BY                                                             */
169
/*                                                                        */
170
/*    _gx_image_reader_png_decode                                         */
171
/*    _gx_image_reader_png_bits_get                                       */
172
/*    _gx_image_reader_png_IHDR_chunk_read                                */
173
/*    _gx_image_reader_png_gAMA_chunk_read                                */
174
/*                                                                        */
175
/**************************************************************************/
176
9786
static VOID _gx_image_reader_png_4bytes_read(GX_PNG *png, INT *value)
177
{
178
INT get_value;
179
180
9786
    get_value = (png -> gx_png_data[png -> gx_png_data_index] << 24);
181
9786
    png -> gx_png_data_index++;
182
183
9786
    get_value |= (png -> gx_png_data[png -> gx_png_data_index] << 16);
184
9786
    png -> gx_png_data_index++;
185
186
9786
    get_value |= (png -> gx_png_data[png -> gx_png_data_index] << 8);
187
9786
    png -> gx_png_data_index++;
188
189
9786
    get_value |= png -> gx_png_data[png -> gx_png_data_index];
190
9786
    png -> gx_png_data_index++;
191
192
9786
    (*value) = get_value;
193
9786
}
194
195
/**************************************************************************/
196
/*                                                                        */
197
/*  FUNCTION                                               RELEASE        */
198
/*                                                                        */
199
/*    _gx_image_reader_png_chunk_type_read                PORTABLE C      */
200
/*                                                           6.1          */
201
/*  AUTHOR                                                                */
202
/*                                                                        */
203
/*    Kenneth Maxwell, Microsoft Corporation                              */
204
/*                                                                        */
205
/*  DESCRIPTION                                                           */
206
/*                                                                        */
207
/*    This function reads the type information of a chunk.                */
208
/*                                                                        */
209
/*  INPUT                                                                 */
210
/*                                                                        */
211
/*    png                                   PNG control block             */
212
/*    chunk_type                            Retrieved chunk type info     */
213
/*                                                                        */
214
/*  OUTPUT                                                                */
215
/*                                                                        */
216
/*    None                                                                */
217
/*                                                                        */
218
/*  CALLS                                                                 */
219
/*                                                                        */
220
/*    None                                                                */
221
/*                                                                        */
222
/*  CALLED BY                                                             */
223
/*                                                                        */
224
/*    _gx_image_reader_png_bits_get                                       */
225
/*    _gx_image_reader_png_decode                                         */
226
/*                                                                        */
227
/**************************************************************************/
228
4274
static VOID _gx_image_reader_png_chunk_type_read(GX_PNG *png, CHAR *chunk_type)
229
{
230
4274
    chunk_type[0] = (CHAR)png -> gx_png_data[png -> gx_png_data_index++];
231
4274
    chunk_type[1] = (CHAR)png -> gx_png_data[png -> gx_png_data_index++];
232
4274
    chunk_type[2] = (CHAR)png -> gx_png_data[png -> gx_png_data_index++];
233
4274
    chunk_type[3] = (CHAR)png -> gx_png_data[png -> gx_png_data_index++];
234
4274
}
235
236
/**************************************************************************/
237
/*                                                                        */
238
/*  FUNCTION                                               RELEASE        */
239
/*                                                                        */
240
/*    _gx_image_reader_png_bits_get                       PORTABLE C      */
241
/*                                                           6.1          */
242
/*  AUTHOR                                                                */
243
/*                                                                        */
244
/*    Kenneth Maxwell, Microsoft Corporation                              */
245
/*                                                                        */
246
/*  DESCRIPTION                                                           */
247
/*                                                                        */
248
/*    This function Extract a specified number of bits from PNG data      */
249
/*    stream and advance the read pointer of the PNG data stream.         */
250
/*                                                                        */
251
/*  INPUT                                                                 */
252
/*                                                                        */
253
/*    png                                   PNG control block             */
254
/*    num_of_bits                           number of bits to retrieve    */
255
/*    return_value                          Retrieved bits data           */
256
/*                                                                        */
257
/*  OUTPUT                                                                */
258
/*                                                                        */
259
/*    None                                                                */
260
/*                                                                        */
261
/*  CALLS                                                                 */
262
/*                                                                        */
263
/*    _gx_image_reader_png_4bytes_read      Read 4 bytes and pack it to a */
264
/*                                            INT type value              */
265
/*    _gx_image_reader_png_crc_get          Calculate crc value with      */
266
/*                                            specified data              */
267
/*    _gx_image_reader_png_chunk_type_read  Read type information         */
268
/*                                                                        */
269
/*  CALLED BY                                                             */
270
/*                                                                        */
271
/*    _gx_image_reader_png_clen_huffman_read                              */
272
/*    _gx_image_reader_png_ll_huffman_read                                */
273
/*    _gx_image_reader_png_huffcode_decode                                */
274
/*    _gx_image_reader_png_IDAT_chunk_read                                */
275
/*                                                                        */
276
/**************************************************************************/
277
19950045
static UINT _gx_image_reader_png_bits_get(GX_PNG *png, UINT num_of_bits, UINT *return_value)
278
{
279
GX_UBYTE get_byte;
280
INT      checksum;
281
CHAR     chunk_type[4];
282
19950045
INT      index = png -> gx_png_trunk_end_index;
283
284
55020373
    while (_bit_count < num_of_bits)
285
    {
286
15120296
        if (png -> gx_png_data_index >= png -> gx_png_data_size)
287
        {
288
1
            return GX_FAILURE;
289
        }
290
291
15120295
        get_byte = png -> gx_png_data[png -> gx_png_data_index++];
292
293
15120295
        _bit_buffer |= (UINT)(get_byte << (UINT)_bit_count);
294
15120295
        _bit_count += 8;
295
296
15120295
        if (png -> gx_png_data_index >= index)
297
        {
298
            /* data_len*/
299
700
            _gx_image_reader_png_4bytes_read(png, &checksum);
300
301
700
            if (png -> gx_png_trunk_crc != (UINT)checksum)
302
            {
303
12
                return GX_FAILURE;
304
            }
305
306
688
            _gx_image_reader_png_4bytes_read(png, &index);
307
308
688
            png -> gx_png_trunk_crc = 0xffffffff;
309
310
688
            _gx_image_reader_png_crc_get(png, &png -> gx_png_trunk_crc, (UINT)(4 + index));
311
312
688
            _gx_image_reader_png_chunk_type_read(png, chunk_type);
313
314
688
            if (strncmp(chunk_type, "IDAT", 4) == 0)
315
            {
316
687
                index += png -> gx_png_data_index;
317
687
                png -> gx_png_trunk_end_index = index;
318
            }
319
        }
320
    }
321
322
19950032
    (*return_value) = _bit_buffer;
323
324
19950032
    return GX_SUCCESS;
325
}
326
327
/**************************************************************************/
328
/*                                                                        */
329
/*  FUNCTION                                               RELEASE        */
330
/*                                                                        */
331
/*    _gx_image_reader_png_bits_revert                    PORTABLE C      */
332
/*                                                           6.1          */
333
/*  AUTHOR                                                                */
334
/*                                                                        */
335
/*    Kenneth Maxwell, Microsoft Corporation                              */
336
/*                                                                        */
337
/*  DESCRIPTION                                                           */
338
/*                                                                        */
339
/*    This function reorders bits stream in opposite order.               */
340
/*                                                                        */
341
/*  INPUT                                                                 */
342
/*                                                                        */
343
/*    bits                                  Variable contain bits stream  */
344
/*    bits_len                              The number of bits to revert  */
345
/*                                                                        */
346
/*  OUTPUT                                                                */
347
/*                                                                        */
348
/*    None                                                                */
349
/*                                                                        */
350
/*  CALLS                                                                 */
351
/*                                                                        */
352
/*    None                                                                */
353
/*                                                                        */
354
/*  CALLED BY                                                             */
355
/*                                                                        */
356
/*    _gx_image_reader_png_dynamic_huffman_code_find                      */
357
/*    _gx_image_reader_png_fixed_ll_huffman_code_find                     */
358
/*    _gx_image_reader_png_huffcode_decode                                */
359
/*                                                                        */
360
/**************************************************************************/
361
43287405
static void _gx_image_reader_png_bits_revert(UINT *bits, UINT bits_len)
362
{
363
43287405
UINT reverted = 0;
364
UINT i;
365
366
245522840
    for (i = 0; i < bits_len; i++)
367
    {
368
202235435
        reverted |= ((*bits) & 0x1) << (bits_len - i - 1);
369
202235435
        (*bits) >>= 1;
370
    }
371
372
43287405
    (*bits) = reverted;
373
43287405
}
374
375
/**************************************************************************/
376
/*                                                                        */
377
/*  FUNCTION                                               RELEASE        */
378
/*                                                                        */
379
/*    _gx_image_reader_png_bits_skip                      PORTABLE C      */
380
/*                                                           6.1          */
381
/*  AUTHOR                                                                */
382
/*                                                                        */
383
/*    Kenneth Maxwell, Microsoft Corporation                              */
384
/*                                                                        */
385
/*  DESCRIPTION                                                           */
386
/*                                                                        */
387
/*    This function skips bits from tempory PNG data buffer.              */
388
/*                                                                        */
389
/*  INPUT                                                                 */
390
/*                                                                        */
391
/*    num_of_skip_bits                      The number of bits to skip    */
392
/*                                                                        */
393
/*  OUTPUT                                                                */
394
/*                                                                        */
395
/*    None                                                                */
396
/*                                                                        */
397
/*  CALLS                                                                 */
398
/*                                                                        */
399
/*    None                                                                */
400
/*                                                                        */
401
/*  CALLED BY                                                             */
402
/*                                                                        */
403
/*    _gx_image_reader_png_clen_huffman_read                              */
404
/*    _gx_image_reader_png_huffcode_decode                                */
405
/*    _gx_image_reader_png_tRNS_chunk_read                                */
406
/*    _gx_image_reader_png_IDAT_chunk_read                                */
407
/*                                                                        */
408
/**************************************************************************/
409
19950650
static VOID _gx_image_reader_png_bits_skip(UINT num_of_skip_bits)
410
{
411
19950650
    _bit_buffer >>= num_of_skip_bits;
412
413
19950650
    _bit_count -= num_of_skip_bits;
414
19950650
}
415
416
/**************************************************************************/
417
/*                                                                        */
418
/*  FUNCTION                                               RELEASE        */
419
/*                                                                        */
420
/*    _gx_image_reader_png_IHDR_chunk_read                PORTABLE C      */
421
/*                                                           6.2.0        */
422
/*  AUTHOR                                                                */
423
/*                                                                        */
424
/*    Kenneth Maxwell, Microsoft Corporation                              */
425
/*                                                                        */
426
/*  DESCRIPTION                                                           */
427
/*                                                                        */
428
/*    This function reads in IHDR chunk information.                      */
429
/*                                                                        */
430
/*  INPUT                                                                 */
431
/*                                                                        */
432
/*    png                                   PNG control block             */
433
/*                                                                        */
434
/*  OUTPUT                                                                */
435
/*                                                                        */
436
/*    status                                Completion status             */
437
/*                                                                        */
438
/*  CALLS                                                                 */
439
/*                                                                        */
440
/*    _gx_display_driver_png_4bytes_read    Read 4 bytes and pack it to a */
441
/*                                            INT type value              */
442
/*                                                                        */
443
/*  CALLED BY                                                             */
444
/*                                                                        */
445
/*    _gx_image_reader_png_decode                                         */
446
/*                                                                        */
447
/**************************************************************************/
448
661
static UINT _gx_image_reader_png_IHDR_chunk_read(GX_PNG *png)
449
{
450
    /* The IHDR chunk contains:
451
        Width: 4 bytes
452
        Height: 4 bytes
453
        Bit depth: 1 byte
454
        Color type: 1 byte
455
        Compression method: 1 byte
456
        Filter method: 1 byte
457
        Interlace method: 1 byte */
458
459
661
    if (png -> gx_png_data_index + 13 > png -> gx_png_trunk_end_index)
460
    {
461
1
        return GX_INVALID_SIZE;
462
    }
463
464
660
    _gx_image_reader_png_4bytes_read(png, &png -> gx_png_width);
465
660
    _gx_image_reader_png_4bytes_read(png, &png -> gx_png_height);
466
467
    /* Limited max png width to 14 bits. */
468

660
    if ((png -> gx_png_width < 0) || (png -> gx_png_width > GX_MAX_PIXELMAP_RESOLUTION))
469
    {
470
2
        return GX_INVALID_WIDTH;
471
    }
472
473
    /* Limited max png height to 14 bits. */
474

658
    if ((png -> gx_png_height < 0) || (png -> gx_png_height > GX_MAX_PIXELMAP_RESOLUTION))
475
    {
476
1
        return GX_INVALID_HEIGHT;
477
    }
478
479
    /* Bits per sample or per palette index, valid values are 1, 2 ,4, 8, 16. */
480
657
    png -> gx_png_bit_depth = png -> gx_png_data[png -> gx_png_data_index++];
481
482
657
    switch (png -> gx_png_bit_depth)
483
    {
484
656
    case 1:
485
    case 2:
486
    case 4:
487
    case 8:
488
    case 16:
489
656
        break;
490
491
1
    default:
492
1
        return GX_INVALID_FORMAT;
493
    }
494
495
    /* 0 gray sample
496
       2 RGB tripple
497
       3 palette index
498
       4 gray sample followed by an alpha sample
499
       6 RGB triple followed by an alpha sample */
500
656
    png -> gx_png_color_type = png -> gx_png_data[png -> gx_png_data_index++];
501
502

656
    switch (png -> gx_png_color_type)
503
    {
504
147
    case 0:
505
    /* Each pixel is agrayscale sample. */
506
    case 3:
507
        /* Each pixel is a palette index, a PLTE chunk must appear. */
508
147
        png -> gx_png_bpp = png -> gx_png_bit_depth;
509
147
        break;
510
178
    case 2:
511
        /* Each pixel is an RGB triple. */
512
178
        png -> gx_png_bpp = (GX_UBYTE)(png -> gx_png_bit_depth * 3);
513
178
        break;
514
515
13
    case 4:
516
        /* Each pixel is a grayscale sample, followed by an alpha sample. */
517
13
        png -> gx_png_bpp = (GX_UBYTE)(png -> gx_png_bit_depth * 2);
518
13
        break;
519
317
    case 6:
520
        /* Each pixel is an R,G,B triple, followed by an alpha sample. */
521
317
        png -> gx_png_bpp = (GX_UBYTE)(png -> gx_png_bit_depth * 4);
522
317
        break;
523
524
1
    default:
525
1
        return GX_FAILURE;
526
    }
527
528
    /* At present, only method 0 is defined. */
529
655
    png -> gx_png_compression_method = png -> gx_png_data[png -> gx_png_data_index++];
530
531
    /* At present, only method 0 is defined. */
532
655
    png -> gx_png_filter_method = png -> gx_png_data[png -> gx_png_data_index++];
533
534

655
    if ((png -> gx_png_compression_method != 0) || (png -> gx_png_filter_method != 0))
535
    {
536
        /* Invalid value. */
537
2
        return GX_FAILURE;
538
    }
539
540
    /* 0 no interlace
541
       1 Adam7 interlace */
542
653
    png -> gx_png_interlace_method = png -> gx_png_data[png -> gx_png_data_index++];
543
544
653
    return GX_SUCCESS;
545
}
546
547
/**************************************************************************/
548
/*                                                                        */
549
/*  FUNCTION                                               RELEASE        */
550
/*                                                                        */
551
/*    _gx_image_reader_png_dynamic_huffman_code_find      PORTABLE C      */
552
/*                                                           6.1          */
553
/*  AUTHOR                                                                */
554
/*                                                                        */
555
/*    Kenneth Maxwell, Microsoft Corporation                              */
556
/*                                                                        */
557
/*  DESCRIPTION                                                           */
558
/*                                                                        */
559
/*    This function retrieves code value from dynamic huffman table.      */
560
/*                                                                        */
561
/*  INPUT                                                                 */
562
/*                                                                        */
563
/*    png                                   PNG control block             */
564
/*    huffman_bits_count                    Array records codes number for*/
565
/*                                          every code len                */
566
/*    scan_buffer                           Buffer to search from         */
567
/*    bit_len                               Retrieved Huffman Code Length */
568
/*    code_value                            Retrieved Huffman Code        */
569
/*                                                                        */
570
/*  OUTPUT                                                                */
571
/*                                                                        */
572
/*    Status code                                                         */
573
/*                                                                        */
574
/*  CALLS                                                                 */
575
/*                                                                        */
576
/*    _gx_image_reader_png_bits_revert      Reorder bits stream in        */
577
/*                                            opposite order              */
578
/*                                                                        */
579
/*  CALLED BY                                                             */
580
/*                                                                        */
581
/*    _gx_image_reader_png_huffcode_decode                                */
582
/*    _gx_image_reader_png_ll_huffman_read                                */
583
/*                                                                        */
584
/**************************************************************************/
585
14684099
static UINT _gx_image_reader_png_dynamic_huffman_code_find(INT  *huffman_table,
586
                                                           UINT  *huffman_bits_count,
587
                                                           UINT   scan_buffer,
588
                                                           UINT  *bit_len,
589
                                                           UINT *code_value)
590
{
591
UINT i_bit;
592
UINT bit_count;
593
UINT code;
594
14684099
UINT code_cal = 0;
595
14684099
UINT code_index = 0;
596
597
73050056
    for (i_bit = 1; i_bit < 16; i_bit++)
598
    {
599
73050035
        bit_count = huffman_bits_count[i_bit] - huffman_bits_count[i_bit - 1];
600
601
73050035
        if (bit_count)
602
        {
603
43269969
            code = (scan_buffer) << (32 - i_bit);
604
43269969
            code = (code) >> (32 - i_bit);
605
606
43269969
            _gx_image_reader_png_bits_revert(&code, i_bit);
607
608
43269969
            if (code <= code_cal + bit_count - 1)
609
            {
610
14684078
                *bit_len = i_bit;
611
14684078
                *code_value = (UINT)huffman_table[code_index + code - code_cal];
612
613
14684078
                return GX_SUCCESS;
614
            }
615
            else
616
            {
617
28585891
                code_index += bit_count;
618
28585891
                code_cal += bit_count;
619
            }
620
        }
621
622
58365957
        code_cal <<= 1;
623
    }
624
625
21
    return GX_NOT_FOUND;
626
}
627
628
/**************************************************************************/
629
/*                                                                        */
630
/*  FUNCTION                                               RELEASE        */
631
/*                                                                        */
632
/*    _gx_image_reader_png_fixed_ll_huffman_code_find     PORTABLE C      */
633
/*                                                           6.1          */
634
/*  AUTHOR                                                                */
635
/*                                                                        */
636
/*    Kenneth Maxwell, Microsoft Corporation                              */
637
/*                                                                        */
638
/*  DESCRIPTION                                                           */
639
/*                                                                        */
640
/*    This function retrieves code value from fixed huffman table.        */
641
/*                                                                        */
642
/*  INPUT                                                                 */
643
/*                                                                        */
644
/*    scan_buffer                           Buffer that contains Huffman  */
645
/*                                          code                          */
646
/*    bit_len                               Retrieved Huffman Code length */
647
/*    code_value                            Retrieved code value of the   */
648
/*                                          matched Huffman Code          */
649
/*                                                                        */
650
/*  OUTPUT                                                                */
651
/*                                                                        */
652
/*    status                                Completion status             */
653
/*                                                                        */
654
/*  CALLS                                                                 */
655
/*                                                                        */
656
/*    _gx_image_reader_png_bits_revert      Reorder bits stream in        */
657
/*                                            opposite order              */
658
/*                                                                        */
659
/*  CALLED BY                                                             */
660
/*                                                                        */
661
/*    _gx_image_reader_png_huffcode_decode                                */
662
/*                                                                        */
663
/**************************************************************************/
664
8151
static UINT _gx_image_reader_png_fixed_ll_huffman_code_find(UINT scan_buffer,
665
                                                            UINT *bit_len,
666
                                                            UINT *code_value)
667
{
668
UINT i_bit;
669
UINT code;
670
671
16781
    for (i_bit = 7; i_bit <= 9; i_bit++)
672
    {
673
15646
        code = scan_buffer << (32 - i_bit);
674
15646
        code = code >> (32 - i_bit);
675
676
15646
        _gx_image_reader_png_bits_revert(&code, i_bit);
677
678
15646
        if (i_bit == 7)
679
        {
680
8151
            if (code <= 0x17)
681
            {
682
1791
                *bit_len = 7;
683
1791
                *code_value = 256 + code;
684
1791
                break;
685
            }
686
        }
687
7495
        else if (i_bit == 8)
688
        {
689
6360
            if (code <= 0xbf)
690
            {
691
                /* code >= 0x30. */
692
5114
                *bit_len = 8;
693
5114
                *code_value = code - 0x30;
694
5114
                break;
695
            }
696
1246
            else if (code <= 0xc7)
697
            {
698
                /* code >= 0xc0. */
699
111
                *bit_len = 8;
700
111
                *code_value = 280 + code - 0xc0;
701
111
                break;
702
            }
703
        }
704
        else
705
        {
706
            /* code >= 0x190 && code <= 0x1ff. */
707
1135
            *bit_len = 9;
708
1135
            *code_value = 144 + code - 0x190;
709
        }
710
    }
711
712
8151
    return GX_SUCCESS;
713
}
714
715
/**************************************************************************/
716
/*                                                                        */
717
/*  FUNCTION                                               RELEASE        */
718
/*                                                                        */
719
/*    _gx_image_reader_png_clen_huffman_read              PORTABLE C      */
720
/*                                                           6.1          */
721
/*  AUTHOR                                                                */
722
/*                                                                        */
723
/*    Kenneth Maxwell, Microsoft Corporation                              */
724
/*                                                                        */
725
/*  DESCRIPTION                                                           */
726
/*                                                                        */
727
/*    This function reads code length huffman table.                      */
728
/*                                                                        */
729
/*  INPUT                                                                 */
730
/*                                                                        */
731
/*    png                                   PNG control block             */
732
/*    hclen                                 The number of "length" codes  */
733
/*                                                                        */
734
/*  OUTPUT                                                                */
735
/*                                                                        */
736
/*    None                                                                */
737
/*                                                                        */
738
/*  CALLS                                                                 */
739
/*                                                                        */
740
/*    _gx_image_reader_png_bits_get         Extract bits from PNG data    */
741
/*                                            stream                      */
742
/*    _gx_image_reader_png_bits_skip        Skip bits from PNG data stream*/
743
/*                                                                        */
744
/*  CALLED BY                                                             */
745
/*                                                                        */
746
/*    _gx_image_reader_png_IDAT_chunk_read                                */
747
/*                                                                        */
748
/**************************************************************************/
749
1018
static UINT _gx_image_reader_png_clen_huffman_read(GX_PNG *png, UINT hclen)
750
{
751
752
1018
INT  code_value[19] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
753
1018
INT  code_len[19] = {0};
754
UINT len;
755
UINT i;
756
INT  pos[16];
757
758
17631
    for (i = 0; i < hclen; i++)
759
    {
760
16614
        if (_gx_image_reader_png_bits_get(png, 3, &len) != GX_SUCCESS)
761
        {
762
1
            return GX_FAILURE;
763
        }
764
16613
        _gx_image_reader_png_bits_skip(3);
765
16613
        len &= 0x7;
766
767
        /* record code len for code len alphabet */
768
16613
        code_len[code_value[i]] = (INT)len;
769
770
        /* record codes number for every code len */
771
16613
        if (len)
772
        {
773
13493
            png -> gx_png_huffman_clen_bits_count[len]++;
774
        }
775
    }
776
777
16272
    for (i = 1; i < 16; i++)
778
    {
779
15255
        png -> gx_png_huffman_clen_bits_count[i] += png -> gx_png_huffman_clen_bits_count[i - 1];
780
    }
781
782
1017
    memset(pos, -1, 16 * sizeof(INT));
783
784
20340
    for (i = 0; i < 19; i++)
785
    {
786
19323
        if (code_len[i])
787
        {
788
13492
            if (pos[code_len[i]] == -1)
789
            {
790
4941
                pos[code_len[i]] = png -> gx_png_huffman_clen_bits_count[code_len[i] - 1];
791
            }
792
13492
            png -> gx_png_huffman_clen_table[pos[code_len[i]]++] = (INT)i;
793
        }
794
    }
795
796
1017
    return GX_SUCCESS;
797
}
798
799
/**************************************************************************/
800
/*                                                                        */
801
/*  FUNCTION                                               RELEASE        */
802
/*                                                                        */
803
/*    _gx_image_reader_png_ll_huffman_read                PORTABLE C      */
804
/*                                                           6.2.0        */
805
/*  AUTHOR                                                                */
806
/*                                                                        */
807
/*    Kenneth Maxwell, Microsoft Corporation                              */
808
/*                                                                        */
809
/*  DESCRIPTION                                                           */
810
/*                                                                        */
811
/*    This function reads in literal and length huffman table.            */
812
/*                                                                        */
813
/*  INPUT                                                                 */
814
/*                                                                        */
815
/*    png                                   PNG control block.            */
816
/*    hlit                                  The number of "literal" codes */
817
/*    hdist                                 The number of "distance" codes*/
818
/*                                                                        */
819
/*  OUTPUT                                                                */
820
/*                                                                        */
821
/*    None                                                                */
822
/*                                                                        */
823
/*  CALLS                                                                 */
824
/*                                                                        */
825
/*    _gx_image_reader_png_bits_get         Extract bits from PNG data    */
826
/*                                            stream                      */
827
/*    _gx_image_reader_png_bits_skip        Skip bits from PNG data stream*/
828
/*    _gx_image_reader_png_dynamic_huffman_code_find                      */
829
/*                                          Retrieve code value from      */
830
/*                                            dynamic huffman table       */
831
/*                                                                        */
832
/*  CALLED BY                                                             */
833
/*                                                                        */
834
/*    _gx_image_reader_png_IDAT_chunk_read                                */
835
/*                                                                        */
836
/**************************************************************************/
837
1017
static UINT _gx_image_reader_png_ll_huffman_read(GX_PNG *png, UINT hlit, UINT hdist)
838
{
839
UINT scan_buffer;
840
UINT bit_len;
841
UINT code_value;
842
UINT repeat;
843
UINT i;
844
1017
UINT count = 0;
845
INT  pos[16];
846
INT  index;
847
848
1017
    memset(png -> gx_png_huffman_lit_code_len, 0, sizeof(INT) * GX_PNG_HUFFMAN_LIT_CODE_LEN_TABLE_SIZE);
849
1017
    memset(png -> gx_png_huffman_dist_code_len, 0, sizeof(INT) * GX_PNG_HUFFMAN_DIST_CODE_LEN_TABLE_SIZE);
850
851
238594
    for (i = 0; i < hlit + hdist;)
852
    {
853
237583
        count++;
854
237583
        if (_gx_image_reader_png_bits_get(png, 16, &scan_buffer) != GX_SUCCESS)
855
        {
856
1
            return GX_FAILURE;
857
        }
858
859
237582
        if (_gx_image_reader_png_dynamic_huffman_code_find(png -> gx_png_huffman_clen_table,
860
237582
                                                           (UINT *)png -> gx_png_huffman_clen_bits_count,
861
                                                           scan_buffer,
862
                                                           &bit_len,
863
                                                           &code_value) == 0)
864
        {
865
237578
            _gx_image_reader_png_bits_skip(bit_len);
866
867
237578
            if (code_value <= 15)
868
            {
869
                /* Represent code lengths of 0-15 */
870
221291
                if (i < hlit)
871
                {
872
202460
                    png -> gx_png_huffman_lit_code_len[i] = (INT)code_value;
873
874
202460
                    png -> gx_png_huffman_lit_bits_count[code_value]++;
875
                }
876
                else
877
                {
878
18831
                    png -> gx_png_huffman_dist_code_len[i - hlit] = (INT)code_value;
879
18831
                    png -> gx_png_huffman_dist_bits_count[code_value]++;
880
                }
881
882
221291
                i++;
883
            }
884
            else
885
            {
886
16287
                if (code_value == 16)
887
                {
888
                    /* repeat previous */
889
                    /* 2 bits repeat length*/
890
10127
                    _gx_image_reader_png_bits_get(png, 2, &repeat);
891
10127
                    _gx_image_reader_png_bits_skip(2);
892
10127
                    repeat &= 0x3;
893
10127
                    repeat += 3;
894
895
10127
                    if (i < 1)
896
                    {
897
1
                        return GX_FALSE;
898
                    }
899
10126
                    else if ((i - 1) < hlit)
900
                    {
901
8191
                        code_value = (UINT)png -> gx_png_huffman_lit_code_len[i - 1];
902
                    }
903
                    else
904
                    {
905
1935
                        code_value = (UINT)png -> gx_png_huffman_dist_code_len[i - 1 - hlit];
906
                    }
907
908
10126
                    if (i < hlit)
909
                    {
910
8191
                        png -> gx_png_huffman_lit_bits_count[code_value] += (INT)repeat;
911
912
41370
                        while (repeat--)
913
                        {
914
33179
                            png -> gx_png_huffman_lit_code_len[i++] = (INT)code_value;
915
                        }
916
                    }
917
                    else
918
                    {
919
1935
                        png -> gx_png_huffman_dist_bits_count[code_value] += (INT)repeat;
920
921
9793
                        while (repeat--)
922
                        {
923
7858
                            png -> gx_png_huffman_dist_code_len[i - hlit] = (INT)code_value;
924
7858
                            i++;
925
                        }
926
                    }
927
                }
928
                else
929
                {
930
6160
                    if (code_value == 17)
931
                    {
932
                        /* repeat 0 */
933
                        /* 3 bits repeat length */
934
5593
                        _gx_image_reader_png_bits_get(png, 3, &repeat);
935
5593
                        _gx_image_reader_png_bits_skip(3);
936
5593
                        repeat &= 0x7;
937
5593
                        repeat += 3;
938
                    }
939
                    else
940
                    {
941
                        /* code_value = 18. */
942
                        /* repeat 0*/
943
                        /* 7 bits repeat length */
944
567
                        _gx_image_reader_png_bits_get(png, 7, &repeat);
945
567
                        _gx_image_reader_png_bits_skip(7);
946
567
                        repeat &= 0x7f;
947
567
                        repeat += 11;
948
                    }
949
950
6160
                    if (i < hlit)
951
                    {
952
5972
                        memset(png -> gx_png_huffman_lit_code_len + i, 0, repeat * sizeof(INT));
953
                    }
954
                    else
955
                    {
956
188
                        memset(png -> gx_png_huffman_dist_code_len + i - hlit, 0, repeat * sizeof(INT));
957
                    }
958
959
6160
                    i += repeat;
960
                }
961
            }
962
        }
963
        else
964
        {
965
            /*error*/
966
4
            return GX_FAILURE;
967
        }
968
    }
969
970
1011
    png -> gx_png_huffman_lit_bits_count[0] = 0;
971
1011
    png -> gx_png_huffman_dist_bits_count[0] = 0;
972
973
16176
    for (i = 2; i <= 16; i++)
974
    {
975
15165
        png -> gx_png_huffman_lit_bits_count[i] += png -> gx_png_huffman_lit_bits_count[i - 1];
976
15165
        png -> gx_png_huffman_dist_bits_count[i] += png -> gx_png_huffman_dist_bits_count[i - 1];
977
    }
978
979
1011
    memset(pos, -1, 16 * sizeof(INT));
980
981
286378
    for (i = 0; i < hlit; i++)
982
    {
983
285367
        index = png -> gx_png_huffman_lit_code_len[i];
984
285367
        if (index)
985
        {
986
206147
            if (pos[index] == -1)
987
            {
988
10074
                pos[index] = png -> gx_png_huffman_lit_bits_count[index - 1];
989
            }
990
206147
            png -> gx_png_huffman_lit_table[pos[index]++] = (INT)i;
991
        }
992
    }
993
994
1011
    memset(pos, -1, 16 * sizeof(INT));
995
996
28582
    for (i = 0; i < hdist; i++)
997
    {
998
27572
        index = png -> gx_png_huffman_dist_code_len[i];
999
27572
        if (index)
1000
        {
1001
25320
            if (pos[index] == -1)
1002
            {
1003
6642
                pos[index] = png -> gx_png_huffman_dist_bits_count[index - 1];
1004
            }
1005
1006
25320
            if (pos[index] >= GX_PNG_HUFFMAN_DIST_TABLE_SIZE)
1007
            {
1008
                /* Invalid data. */
1009
1
                return GX_FAILURE;
1010
            }
1011
1012
25319
            png -> gx_png_huffman_dist_table[pos[index]++] = (INT)i;
1013
        }
1014
    }
1015
1016
1010
    return GX_SUCCESS;
1017
}
1018
1019
/**************************************************************************/
1020
/*                                                                        */
1021
/*  FUNCTION                                               RELEASE        */
1022
/*                                                                        */
1023
/*    _gx_image_reader_png_huffcode_decode                PORTABLE C      */
1024
/*                                                           6.1          */
1025
/*  AUTHOR                                                                */
1026
/*                                                                        */
1027
/*    Kenneth Maxwell, Microsoft Corporation                              */
1028
/*                                                                        */
1029
/*  DESCRIPTION                                                           */
1030
/*                                                                        */
1031
/*    This function decodes the Huffman codes.                            */
1032
/*                                                                        */
1033
/*  INPUT                                                                 */
1034
/*                                                                        */
1035
/*    png                                   PNG control block.            */
1036
/*    dynamic                               True, use dynamic huff table  */
1037
/*                                          False, use fixed huff table   */
1038
/*    decoded_data_size                     Expected decoded data size    */
1039
/*                                                                        */
1040
/*  OUTPUT                                                                */
1041
/*                                                                        */
1042
/*    None                                                                */
1043
/*                                                                        */
1044
/*  CALLS                                                                 */
1045
/*                                                                        */
1046
/*    _gx_image_reader_png_bits_get         Extract bits from PNG data    */
1047
/*                                            stream                      */
1048
/*    _gx_image_reader_png_bits_skip        Skip bits from PNG data stream*/
1049
/*    _gx_image_reader_png_dynamic_huffman_code_find                      */
1050
/*                                          Retrieve code value from      */
1051
/*                                            dynamic huffman table       */
1052
/*    _gx_image_reader_png_fixed_ll_huffman_code_find                     */
1053
/*                                          Retrieve code value from      */
1054
/*                                            fixed huffman table         */
1055
/*                                                                        */
1056
/*  CALLED BY                                                             */
1057
/*                                                                        */
1058
/*    _gx_image_reader_png_IDAT_chunk_read                                */
1059
/*                                                                        */
1060
/**************************************************************************/
1061
1126
static UINT _gx_image_reader_png_huffcode_decode(GX_PNG *png, GX_BOOL dynamic, UINT decoded_data_size)
1062
{
1063
UINT scan_buffer;
1064
1126
UINT bit_len = 0;
1065
1126
UINT code_value = 300;
1066
UINT length;
1067
UINT distance;
1068
UINT extra_bits;
1069
UINT copy_len;
1070
1071
    while (1)
1072
    {
1073
9600917
        if (_gx_image_reader_png_bits_get(png, 16, &scan_buffer) != GX_SUCCESS)
1074
        {
1075
4
            return GX_FAILURE;
1076
        }
1077
1078
        /* Decode literal/length value from input stream */
1079
9600913
        if (dynamic)
1080
        {
1081
9592762
            _gx_image_reader_png_dynamic_huffman_code_find(png -> gx_png_huffman_lit_table,
1082
9592762
                                                           (UINT *)png -> gx_png_huffman_lit_bits_count,
1083
                                                           scan_buffer,
1084
                                                           &bit_len,
1085
                                                           &code_value);
1086
        }
1087
        else
1088
        {
1089
8151
            _gx_image_reader_png_fixed_ll_huffman_code_find(scan_buffer, &bit_len, &code_value);
1090
        }
1091
1092
9600913
        _gx_image_reader_png_bits_skip(bit_len);
1093
1094
9600913
        if (code_value < 256)
1095
        {
1096
4744250
            if ((UINT)(png -> gx_png_decoded_data_len + 1) > decoded_data_size)
1097
            {
1098
                /* Decoded data size exceed allocated buffer size. */
1099
1
                return GX_FAILURE;
1100
            }
1101
1102
4744249
            png -> gx_png_decoded_data[png -> gx_png_decoded_data_len++] = (GX_UBYTE)code_value;
1103
        }
1104
4856663
        else if (code_value == 256)
1105
        {
1106
            /* End of the block */
1107
1116
            break;
1108
        }
1109
        else
1110
        {
1111
4855547
            if (code_value < 265)
1112
            {
1113
                /* 0 extra bits */
1114
4349963
                length = 3 + code_value - 257;
1115
            }
1116
505584
            else if (code_value < 285)
1117
            {
1118
474693
                extra_bits = 1 + (code_value - 265) / 4;
1119
474693
                _gx_image_reader_png_bits_get(png, extra_bits, &length);
1120
474693
                _gx_image_reader_png_bits_skip(extra_bits);
1121
474693
                length <<= (32 - extra_bits);
1122
474693
                length >>= (32 - extra_bits);
1123
1124
474693
                length += 3u + (1u << (extra_bits + 2)) + ((1u << extra_bits) * ((code_value - 265) & 0x3));
1125
            }
1126
30891
            else if (code_value == 285)
1127
            {
1128
                /* 0 extra bits */
1129
30889
                length = 258;
1130
            }
1131
            else
1132
            {
1133
                /* This should not happen. */
1134
2
                return GX_FAILURE;
1135
            }
1136
1137
4855545
            if (dynamic)
1138
            {
1139
4853755
                _gx_image_reader_png_bits_get(png, 16, &scan_buffer);
1140
1141
                /*decode distance from input stream */
1142
4853755
                _gx_image_reader_png_dynamic_huffman_code_find(png -> gx_png_huffman_dist_table,
1143
4853755
                                                               (UINT *)png -> gx_png_huffman_dist_bits_count,
1144
                                                               scan_buffer,
1145
                                                               &bit_len,
1146
                                                               &code_value);
1147
1148
4853755
                _gx_image_reader_png_bits_skip(bit_len);
1149
            }
1150
            else
1151
            {
1152
                /* Decodes 5-bits distance codes. */
1153
1790
                _gx_image_reader_png_bits_get(png, 5, &scan_buffer);
1154
1790
                _gx_image_reader_png_bits_skip(5);
1155
1790
                code_value = scan_buffer & 0x1f;
1156
1790
                _gx_image_reader_png_bits_revert(&code_value, 5);
1157
            }
1158
1159
4855545
            if (code_value < 4)
1160
            {
1161
112633
                distance = 1 + code_value;
1162
            }
1163
4742912
            else if (code_value < 30)
1164
            {
1165
4742911
                extra_bits = 1 + (code_value - 4) / 2;
1166
1167
4742911
                _gx_image_reader_png_bits_get(png, extra_bits, &distance);
1168
4742911
                _gx_image_reader_png_bits_skip(extra_bits);
1169
1170
4742911
                distance <<= (32 - extra_bits);
1171
4742911
                distance >>= (32 - extra_bits);
1172
1173
4742911
                distance += 1u + (1u << (extra_bits + 1)) + (1u << extra_bits) * ((code_value - 4) & 0x1);
1174
            }
1175
            else
1176
            {
1177
                /* This should not happen. */
1178
1
                return GX_FALSE;
1179
            }
1180
1181
            /* move backwards distance bytes in the output stream, and copy
1182
               length bytes from this position to the output stream. */
1183
1184
14626075
            while (length)
1185
            {
1186
9770533
                if (length > distance)
1187
                {
1188
4914989
                    copy_len = distance;
1189
4914989
                    length -= distance;
1190
                }
1191
                else
1192
                {
1193
4855544
                    copy_len = length;
1194
4855544
                    length = 0;
1195
                }
1196
1197
9770533
                if ((distance > (UINT)png -> gx_png_decoded_data_len) ||
1198
9770532
                    ((UINT)png -> gx_png_decoded_data_len + copy_len > decoded_data_size))
1199
                {
1200
1201
                    /* Distance exceed current decoded data length or copied length exceed remaining buffer size. */
1202
2
                    return GX_FAILURE;
1203
                }
1204
1205
9770531
                memcpy(png -> gx_png_decoded_data + png -> gx_png_decoded_data_len, /* Use case of memcpy is verified. */
1206
9770531
                       png -> gx_png_decoded_data + png -> gx_png_decoded_data_len - distance,
1207
                       copy_len * sizeof(GX_UBYTE));
1208
9770531
                png -> gx_png_decoded_data_len += (INT)copy_len;
1209
            }
1210
        }
1211
    }
1212
1213
1116
    return GX_SUCCESS;
1214
}
1215
1216
/**************************************************************************/
1217
/*                                                                        */
1218
/*  FUNCTION                                               RELEASE        */
1219
/*                                                                        */
1220
/*    _gx_image_reader_png_tRNS_chunk_read                PORTABLE C      */
1221
/*                                                           6.1          */
1222
/*  AUTHOR                                                                */
1223
/*                                                                        */
1224
/*    Kenneth Maxwell, Microsoft Corporation                              */
1225
/*                                                                        */
1226
/*  DESCRIPTION                                                           */
1227
/*                                                                        */
1228
/*    This function reads in the tRNS chunk information.                  */
1229
/*                                                                        */
1230
/*  INPUT                                                                 */
1231
/*                                                                        */
1232
/*    png                                   PNG control block.            */
1233
/*                                                                        */
1234
/*  OUTPUT                                                                */
1235
/*                                                                        */
1236
/*    status                                Completion status             */
1237
/*                                                                        */
1238
/*  CALLS                                                                 */
1239
/*                                                                        */
1240
/*    _gx_system_memory_allocator           Application defined memory    */
1241
/*                                            allocation function         */
1242
/*                                                                        */
1243
/*  CALLED BY                                                             */
1244
/*                                                                        */
1245
/*    _gx_image_reader_png_decode                                         */
1246
/*                                                                        */
1247
/**************************************************************************/
1248
55
static UINT _gx_image_reader_png_tRNS_chunk_read(GX_PNG *png)
1249
{
1250
INT index;
1251
1252

55
    if ((png -> gx_png_color_type == 4) || (png -> gx_png_color_type == 6))
1253
    {
1254
        /* tRNS is prohibited for the other color types. */
1255
2
        return GX_FAILURE;
1256
    }
1257
1258
53
    if (png -> gx_png_color_type == 3)
1259
    {
1260
        /* Contains a series of one-byte alpha values.  */
1261
17
        png -> gx_png_trans_num = png -> gx_png_trunk_end_index - png -> gx_png_data_index;
1262
1263
        /* For color type 3, tRNS can contain fewer values than there are palette entries. */
1264
17
        if (png -> gx_png_trans_num > 256)
1265
        {
1266
1
            return GX_INVALID_VALUE;
1267
        }
1268
    }
1269
    else
1270
    {
1271
        /* For color type 0, the tRNS chunk contains a single two-bytes gray level value.
1272
           For color type 2, the tRNS chunk contains a single two-bytes RGB color value. */
1273
36
        png -> gx_png_trans_num = (png -> gx_png_trunk_end_index - png -> gx_png_data_index) >> 1;
1274
1275
36
        if (png -> gx_png_trans_num > 3)
1276
        {
1277
1
            return GX_INVALID_VALUE;
1278
        }
1279
    }
1280
1281
    /* Then trans num is no bigger than 256, multiplication will not overflow. */
1282
51
    png -> gx_png_trans = (GX_COLOR *)_gx_system_memory_allocator((ULONG)png -> gx_png_trans_num * sizeof(GX_COLOR));
1283
1284
51
    if (png -> gx_png_trans == GX_NULL)
1285
    {
1286
1
        return GX_SYSTEM_MEMORY_ERROR;
1287
    }
1288
1289
140
    for (index = 0; index < png -> gx_png_trans_num; index++)
1290
    {
1291
90
        png -> gx_png_trans[index] = png -> gx_png_data[png -> gx_png_data_index++];
1292
1293
90
        if (png -> gx_png_color_type != 3)
1294
        {
1295
74
            png -> gx_png_trans[index] <<= 8;
1296
74
            png -> gx_png_trans[index] |= png -> gx_png_data[png -> gx_png_data_index++];
1297
        }
1298
    }
1299
1300
50
    return GX_SUCCESS;
1301
}
1302
1303
/**************************************************************************/
1304
/*                                                                        */
1305
/*  FUNCTION                                               RELEASE        */
1306
/*                                                                        */
1307
/*    _gx_image_reader_png_IDAT_chunk_read                PORTABLE C      */
1308
/*                                                           6.1          */
1309
/*  AUTHOR                                                                */
1310
/*                                                                        */
1311
/*    Kenneth Maxwell, Microsoft Corporation                              */
1312
/*                                                                        */
1313
/*  DESCRIPTION                                                           */
1314
/*                                                                        */
1315
/*    This function reads in the IDAT chunk information and start         */
1316
/*    decoding.                                                           */
1317
/*                                                                        */
1318
/*  INPUT                                                                 */
1319
/*                                                                        */
1320
/*    png                                   PNG control block.            */
1321
/*                                                                        */
1322
/*  OUTPUT                                                                */
1323
/*                                                                        */
1324
/*    status                                Completion status             */
1325
/*                                                                        */
1326
/*  CALLS                                                                 */
1327
/*                                                                        */
1328
/*    _gx_image_reader_png_bits_get         Extract bits from PNG data    */
1329
/*                                            stream                      */
1330
/*    _gx_image_reader_png_bits_skip        Skip bits from PNG data stream*/
1331
/*    _gx_image_reader_png_clen_huffman_read                              */
1332
/*                                          Read code length huffman table*/
1333
/*    _gx_image_reader_png_ll_huffman_read  Read literal and length       */
1334
/*                                            huffman table               */
1335
/*    _gx_image_reader_png_huffcode_decode  Decode huffman codes          */
1336
/*                                                                        */
1337
/*  CALLED BY                                                             */
1338
/*                                                                        */
1339
/*    _gx_image_reader_png_decode                                         */
1340
/*                                                                        */
1341
/**************************************************************************/
1342
644
static UINT _gx_image_reader_png_IDAT_chunk_read(GX_PNG *png)
1343
{
1344
/*zlib format
1345
   +---+---+
1346
   |CMF|FLG|
1347
   +---+---+
1348
   if FLG.FDICT set
1349
   +---+---+---+---+
1350
   |     DTCTID    |
1351
   +---+---+---+---+
1352
   +=====================+---+---+---+---+
1353
   |...compressed data...| 32bit checksum|
1354
   +=====================+---+---+---+---+
1355
*/
1356
UINT CMF;
1357
UINT FLG;
1358
INT  compress_method;
1359
INT  window_size;
1360
INT  fdict;
1361
UINT header;
1362
INT  hlit;
1363
INT  hdist;
1364
INT  hclen;
1365
UINT alloc_size;
1366
INT  len;
1367
INT  nlen;
1368
1369
644
    if (_gx_image_reader_png_bits_get(png, 8, &CMF) != GX_SUCCESS)
1370
    {
1371
2
        return GX_FAILURE;
1372
    }
1373
1374
642
    _gx_image_reader_png_bits_skip(8);
1375
1376
642
    if (_gx_image_reader_png_bits_get(png, 8, &FLG) != GX_SUCCESS)
1377
    {
1378
1
        return GX_FAILURE;
1379
    }
1380
1381
641
    _gx_image_reader_png_bits_skip(8);
1382
1383
641
    compress_method = CMF & 0x0f;
1384
641
    window_size = 2 << (((CMF & 0xf0) >> 4) + 8);
1385
641
    fdict = FLG & 0x20;
1386
1387

641
    if ((fdict != 0) ||
1388
639
        (window_size > 65536) ||
1389
        (compress_method != 8))
1390
    {
1391
4
        return GX_FAILURE;
1392
    }
1393
1394
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
1395
       overflow cannot occur. */
1396
637
    alloc_size = (UINT)(png -> gx_png_height * ((png -> gx_png_width * png -> gx_png_bpp + 7) / 8));
1397
637
    alloc_size = alloc_size + (UINT)png -> gx_png_height;
1398
637
    png -> gx_png_decoded_data = (GX_UBYTE *)_gx_system_memory_allocator(alloc_size);
1399
637
    png -> gx_png_decoded_data_len = 0;
1400
1401
637
    if (png -> gx_png_decoded_data == GX_NULL)
1402
    {
1403
2
        return GX_SYSTEM_MEMORY_ERROR;
1404
    }
1405
1406
    do
1407
    {
1408
        /* The header of one block */
1409
1150
        if (_gx_image_reader_png_bits_get(png, 8, &header) != GX_SUCCESS)
1410
        {
1411
1
            return GX_FAILURE;
1412
        }
1413
1414
1149
        if ((header & 0x6) == 0x00)
1415
        {
1416
13
            _gx_image_reader_png_bits_skip(3);
1417
1418
            /* no compression */
1419
13
            _gx_image_reader_png_bits_skip(_bit_count & 0x7);
1420
13
            if (_bit_count)
1421
            {
1422
1
                png -> gx_png_data_index -= (INT)(_bit_count / 8);
1423
1
                _gx_image_reader_png_bits_skip(_bit_count);
1424
            }
1425
1426
            /* 4 = 2 bytes len + 2 bytes nlen. */
1427
13
            if (png -> gx_png_data_index + 4 > png -> gx_png_data_size)
1428
            {
1429
1
                return GX_INVALID_SIZE;
1430
            }
1431
1432
            /* Read "LEN".  */
1433
12
            len = png -> gx_png_data[png -> gx_png_data_index];
1434
12
            png -> gx_png_data_index++;
1435
12
            len |= (png -> gx_png_data[png -> gx_png_data_index] << 8);
1436
12
            png -> gx_png_data_index++;
1437
1438
            /* Read "NLEN".  */
1439
12
            nlen = png -> gx_png_data[png -> gx_png_data_index];
1440
12
            png -> gx_png_data_index++;
1441
12
            nlen |= (png -> gx_png_data[png -> gx_png_data_index] << 8);
1442
12
            png -> gx_png_data_index++;
1443
1444
12
            if (len + nlen != 65535)
1445
            {
1446
                /* NLEN is not one's complement of LEN. */
1447
4
                return GX_FAILURE;
1448
            }
1449
1450
            /* Read data to outbuffer directly */
1451
8
            if (len)
1452
            {
1453
7
                if ((UINT)(png -> gx_png_decoded_data_len + len) > alloc_size)
1454
                {
1455
                    /* Copied size exceed remaining buffer size. */
1456
1
                    return GX_FAILURE;
1457
                }
1458
1459
6
                if (png -> gx_png_data_index + len > png -> gx_png_data_size)
1460
                {
1461
1
                    return GX_INVALID_SIZE;
1462
                }
1463
1464
5
                memcpy(png -> gx_png_decoded_data + png -> gx_png_decoded_data_len, png -> gx_png_data + png -> gx_png_data_index, (UINT)len); /* Use case of memcpy is verified. */
1465
5
                png -> gx_png_data_index += len;
1466
5
                png -> gx_png_decoded_data_len += len;
1467
            }
1468
        }
1469
1136
        else if ((header & 0x6) == 0x2)
1470
        {
1471
115
            _gx_image_reader_png_bits_skip(3);
1472
1473
            /* compressed with fixed Huffman codes */
1474
115
            if (_gx_image_reader_png_huffcode_decode(png, GX_FALSE, alloc_size) != GX_SUCCESS)
1475
            {
1476
3
                return GX_FAILURE;
1477
            }
1478
        }
1479
1021
        else if ((header & 0x6) == 0x4)
1480
        {
1481
            /* compressed with dynamic Huffman codes */
1482
1020
            _gx_image_reader_png_bits_skip(3);
1483
1484
            /* # of Literal/Length codes */
1485
1020
            _gx_image_reader_png_bits_get(png, 5, (unsigned int *)&hlit);
1486
1487
1020
            _gx_image_reader_png_bits_skip(5);
1488
1020
            hlit = (hlit & 0x1f) + 257;
1489
1490
            /* # of Distance codes */
1491
1020
            if (_gx_image_reader_png_bits_get(png, 5, (unsigned int *)&hdist) != GX_SUCCESS)
1492
            {
1493
1
                return GX_FAILURE;
1494
            }
1495
1019
            _gx_image_reader_png_bits_skip(5);
1496
1019
            hdist = (hdist & 0x1f) + 1;
1497
1498
            /* # of Code Length codes */
1499
1019
            if (_gx_image_reader_png_bits_get(png, 4, (unsigned int *)&hclen) != GX_SUCCESS)
1500
            {
1501
1
                return GX_FAILURE;
1502
            }
1503
1018
            _gx_image_reader_png_bits_skip(4);
1504
1018
            hclen = (hclen & 0xf) + 4;
1505
1506
1018
            memset(png -> gx_png_huffman_clen_bits_count, 0, 17 * sizeof(INT));
1507
1018
            memset(png -> gx_png_huffman_clen_table, 0, 20 * sizeof(INT));
1508
1018
            memset(png -> gx_png_huffman_lit_bits_count, 0, 17 * sizeof(INT));
1509
1018
            memset(png -> gx_png_huffman_lit_table, 0, GX_PNG_HUFFMAN_LIT_TABLE_SIZE * sizeof(int));
1510
1018
            memset(png -> gx_png_huffman_dist_bits_count, 0, 17 * sizeof(INT));
1511
1018
            memset(png -> gx_png_huffman_dist_table, 0, 30 * sizeof(INT));
1512
1513
1018
            if (_gx_image_reader_png_clen_huffman_read(png, (UINT)hclen) != GX_SUCCESS)
1514
            {
1515
1
                return GX_FAILURE;
1516
            }
1517
1518
1017
            if (_gx_image_reader_png_ll_huffman_read(png, (UINT)hlit, (UINT)hdist) != GX_SUCCESS)
1519
            {
1520
6
                return GX_FAILURE;
1521
            }
1522
1523
1011
            if (_gx_image_reader_png_huffcode_decode(png, GX_TRUE, alloc_size) != GX_SUCCESS)
1524
            {
1525
6
                return GX_FAILURE;
1526
            }
1527
        }
1528
        else
1529
        {
1530
            /* error */
1531
1
            return GX_FAILURE;
1532
        }
1533
1123
    } while ((header & 0x1) != 0x1);
1534
1535
    /* Skip checksum */
1536
608
    png -> gx_png_data_index = png -> gx_png_trunk_end_index;
1537
608
    _gx_image_reader_png_bits_skip(_bit_count);
1538
1539
608
    if (alloc_size != (UINT)png -> gx_png_decoded_data_len)
1540
    {
1541
        /* Decoded data size doesn't match prediction. */
1542
4
        return GX_FAILURE;
1543
    }
1544
1545
604
    return GX_SUCCESS;
1546
}
1547
1548
/**************************************************************************/
1549
/*                                                                        */
1550
/*  FUNCTION                                               RELEASE        */
1551
/*                                                                        */
1552
/*    _gx_image_reader_png_gAMA_chunk_read                PORTABLE C      */
1553
/*                                                           6.1          */
1554
/*  AUTHOR                                                                */
1555
/*                                                                        */
1556
/*    Kenneth Maxwell, Microsoft Corporation                              */
1557
/*                                                                        */
1558
/*  DESCRIPTION                                                           */
1559
/*                                                                        */
1560
/*    This function reads in the gAMA chunk information.                  */
1561
/*                                                                        */
1562
/*  INPUT                                                                 */
1563
/*                                                                        */
1564
/*    png                                   PNG control block.            */
1565
/*                                                                        */
1566
/*  OUTPUT                                                                */
1567
/*                                                                        */
1568
/*    status                                Completion status             */
1569
/*                                                                        */
1570
/*  CALLS                                                                 */
1571
/*                                                                        */
1572
/*    _gx_image_reader_png_4bytes_read      Read 4 bytes and pact it to   */
1573
/*                                            an INT value                */
1574
/*                                                                        */
1575
/*  CALLED BY                                                             */
1576
/*                                                                        */
1577
/*    _gx_image_reader_png_decode                                         */
1578
/*                                                                        */
1579
/**************************************************************************/
1580
565
static UINT _gx_image_reader_png_gAMA_chunk_read(GX_PNG *png)
1581
{
1582
565
    if (png -> gx_png_data_index + 4 > png -> gx_png_trunk_end_index)
1583
    {
1584
1
        return GX_INVALID_SIZE;
1585
    }
1586
1587
    /* Specifies the gamma of the camera that produced the image. */
1588
1589
    /* A gamma of 0.45 would be stored as teh integer 45000. */
1590
564
    _gx_image_reader_png_4bytes_read(png, &png -> gx_png_gamma);
1591
1592
564
    return GX_SUCCESS;
1593
}
1594
1595
/**************************************************************************/
1596
/*                                                                        */
1597
/*  FUNCTION                                               RELEASE        */
1598
/*                                                                        */
1599
/*    _gx_image_reader_png_PLTE_chunk_read                PORTABLE C      */
1600
/*                                                           6.1          */
1601
/*  AUTHOR                                                                */
1602
/*                                                                        */
1603
/*    Kenneth Maxwell, Microsoft Corporation                              */
1604
/*                                                                        */
1605
/*  DESCRIPTION                                                           */
1606
/*                                                                        */
1607
/*    This function reads in the PLTE chunk information.                  */
1608
/*                                                                        */
1609
/*  INPUT                                                                 */
1610
/*                                                                        */
1611
/*    png                                   PNG control block.            */
1612
/*                                                                        */
1613
/*  OUTPUT                                                                */
1614
/*                                                                        */
1615
/*    status                                Completion status             */
1616
/*                                                                        */
1617
/*  CALLS                                                                 */
1618
/*                                                                        */
1619
/*    None                                                                */
1620
/*                                                                        */
1621
/*  CALLED BY                                                             */
1622
/*                                                                        */
1623
/*    _gx_image_reader_png_decode                                         */
1624
/*                                                                        */
1625
/**************************************************************************/
1626
66
static UINT _gx_image_reader_png_PLTE_chunk_read(GX_PNG *png)
1627
{
1628
INT      index;
1629
GX_UBYTE red;
1630
GX_UBYTE green;
1631
GX_UBYTE blue;
1632
1633
66
    png -> gx_png_palette_table_size = (png -> gx_png_trunk_end_index - png -> gx_png_data_index) / 3;
1634
1635
    /* The PLTE chunk contains from 1 to 256 palette entries. */
1636
66
    if (png -> gx_png_palette_table_size > 256)
1637
    {
1638
1
        return GX_INVALID_VALUE;
1639
    }
1640
1641
8862
    for (index = 0; index < png -> gx_png_palette_table_size; index++)
1642
    {
1643
8797
        red = png -> gx_png_data[png -> gx_png_data_index++];
1644
8797
        green = png -> gx_png_data[png -> gx_png_data_index++];
1645
8797
        blue = png -> gx_png_data[png -> gx_png_data_index++];
1646
1647
8797
        png -> gx_png_palette_table[index] = (GX_COLOR)((red << 16) | (green << 8) | blue);
1648
    }
1649
1650
65
    return GX_SUCCESS;
1651
}
1652
1653
/**************************************************************************/
1654
/*                                                                        */
1655
/*  FUNCTION                                               RELEASE        */
1656
/*                                                                        */
1657
/*    _gx_image_reader_png_paeth_predictor                PORTABLE C      */
1658
/*                                                           6.1.8        */
1659
/*  AUTHOR                                                                */
1660
/*                                                                        */
1661
/*    Kenneth Maxwell, Microsoft Corporation                              */
1662
/*                                                                        */
1663
/*  DESCRIPTION                                                           */
1664
/*                                                                        */
1665
/*    This function performs Paeth filter algorithm.                      */
1666
/*                                                                        */
1667
/*  INPUT                                                                 */
1668
/*                                                                        */
1669
/*    a                                     Byte of left pixel.           */
1670
/*    b                                     Byte of above pixel.          */
1671
/*    c                                     Byte of upper left pixel.     */
1672
/*                                                                        */
1673
/*  OUTPUT                                                                */
1674
/*                                                                        */
1675
/*    status                                The nearest of a, b, c.       */
1676
/*                                                                        */
1677
/*  CALLS                                                                 */
1678
/*                                                                        */
1679
/*    None                                                                */
1680
/*                                                                        */
1681
/*  CALLED BY                                                             */
1682
/*                                                                        */
1683
/*    _gx_image_reader_png_unfilter                                       */
1684
/*                                                                        */
1685
/**************************************************************************/
1686
17536220
static GX_UBYTE _gx_image_reader_png_paeth_predictor(GX_UBYTE a, GX_UBYTE b, GX_UBYTE c)
1687
{
1688
INT p;
1689
INT pa, pb, pc;
1690
1691
17536220
    p = a + b - c;
1692
17536220
    pa = GX_ABS(p - a);
1693
17536220
    pb = GX_ABS(p - b);
1694
17536220
    pc = GX_ABS(p - c);
1695
1696
    /*return nearest of a, b, c */
1697
1698

17536220
    if ((pa <= pb) && (pa <= pc))
1699
    {
1700
12176556
        return a;
1701
    }
1702
5359664
    else if (pb <= pc)
1703
    {
1704
4272738
        return b;
1705
    }
1706
    else
1707
    {
1708
1086926
        return c;
1709
    }
1710
}
1711
1712
/**************************************************************************/
1713
/*                                                                        */
1714
/*  FUNCTION                                               RELEASE        */
1715
/*                                                                        */
1716
/*    _gx_image_reader_png_unfilter                       PORTABLE C      */
1717
/*                                                           6.2.0        */
1718
/*  AUTHOR                                                                */
1719
/*                                                                        */
1720
/*    Kenneth Maxwell, Microsoft Corporation                              */
1721
/*                                                                        */
1722
/*  DESCRIPTION                                                           */
1723
/*                                                                        */
1724
/*    This function reverts the effect of filter.                         */
1725
/*                                                                        */
1726
/*  INPUT                                                                 */
1727
/*                                                                        */
1728
/*    png                                   PNG control block.            */
1729
/*                                                                        */
1730
/*  OUTPUT                                                                */
1731
/*                                                                        */
1732
/*    None                                                                */
1733
/*                                                                        */
1734
/*  CALLS                                                                 */
1735
/*                                                                        */
1736
/*    memmove                                                             */
1737
/*    _gx_image_reader_png_paeth_predictor  Perform Paeth filter algorithm*/
1738
/*                                                                        */
1739
/*  CALLED BY                                                             */
1740
/*                                                                        */
1741
/*    _gx_image_reader_png_decode                                         */
1742
/*                                                                        */
1743
/**************************************************************************/
1744
605
static UINT _gx_image_reader_png_unfilter(GX_PNG *png)
1745
{
1746
INT filter_type;
1747
INT byte_width;
1748
INT pos;
1749
605
INT bpp = png -> gx_png_bpp;
1750
INT x;
1751
INT y;
1752
1753
605
    if (png -> gx_png_decoded_data == GX_NULL)
1754
    {
1755
        /* This happens when IDAT chunk is missing. */
1756
1
        return GX_FAILURE;
1757
    }
1758
1759
604
    byte_width = (png -> gx_png_width * bpp + 7) >> 3;
1760
604
    bpp = (bpp + 7) >> 3;
1761
1762
76766
    for (y = 0; y < png -> gx_png_height; y++)
1763
    {
1764
76164
        filter_type = png -> gx_png_decoded_data[y * byte_width + y];
1765
1766
76164
        pos = y * byte_width;
1767
76164
        memmove(png -> gx_png_decoded_data + pos, png -> gx_png_decoded_data + pos + y + 1, (UINT)byte_width);
1768
1769

76164
        switch (filter_type)
1770
        {
1771
2595
        case 0:
1772
2595
            break;
1773
19998
        case 1:
1774
            /* sub(x) + raw(x-bpp)*/
1775
15937009
            for (x = bpp; x < byte_width; x++)
1776
            {
1777
15917011
                png -> gx_png_decoded_data[pos + x] = (GX_UBYTE)(png -> gx_png_decoded_data[pos + x] + png -> gx_png_decoded_data[pos + x - bpp]);
1778
            }
1779
19998
            break;
1780
26536
        case 2:
1781
            /*up(x) + prior(x)*/
1782
26536
            if (y == 0)
1783
            {
1784
4
                break;
1785
            }
1786
1787
20764736
            for (x = 0; x < byte_width; x++)
1788
            {
1789
20738204
                png -> gx_png_decoded_data[pos + x] = (GX_UBYTE)(png -> gx_png_decoded_data[pos + x] + png -> gx_png_decoded_data[pos + x - byte_width]);
1790
            }
1791
26532
            break;
1792
1090
        case 3:
1793
            /* average(x) + floor((raw(x-bpp)+prior(x))/2 */
1794
1090
            if (y == 0)
1795
            {
1796
376
                for (x = bpp; x < byte_width; x++)
1797
                {
1798
372
                    png -> gx_png_decoded_data[pos + x] = (GX_UBYTE)(png -> gx_png_decoded_data[pos + x] + (png -> gx_png_decoded_data[pos + x - bpp] >> 1));
1799
                }
1800
            }
1801
            else
1802
            {
1803
4813
                for (x = 0; x < bpp; x++)
1804
                {
1805
3727
                    png -> gx_png_decoded_data[pos + x] = (GX_UBYTE)(png -> gx_png_decoded_data[pos + x] + (png -> gx_png_decoded_data[pos + x - byte_width] >> 1));
1806
                }
1807
1808
830655
                for (x = bpp; x < byte_width; x++)
1809
                {
1810
829569
                    png -> gx_png_decoded_data[pos + x] = (GX_UBYTE)(png -> gx_png_decoded_data[pos + x] + ((png -> gx_png_decoded_data[pos + x - bpp] +
1811
829569
                                                                                                             png -> gx_png_decoded_data[pos + x - byte_width]) >> 1));
1812
                }
1813
            }
1814
1090
            break;
1815
25943
        case 4:
1816
            /* paeth(x) + paethpredictor(raw(x-bpp), prior(x), prior(x-bpp)) */
1817
25943
            if (y == 0)
1818
            {
1819
376
                for (x = bpp; x < byte_width; x++)
1820
                {
1821
372
                    png -> gx_png_decoded_data[pos + x] = (GX_UBYTE)(png -> gx_png_decoded_data[pos + x] + png -> gx_png_decoded_data[pos + x - bpp]);
1822
                }
1823
            }
1824
            else
1825
            {
1826
128535
                for (x = 0; x < bpp; x++)
1827
                {
1828
102596
                    png -> gx_png_decoded_data[pos + x] = (GX_UBYTE)(png -> gx_png_decoded_data[pos + x] + png -> gx_png_decoded_data[pos + x - byte_width]);
1829
                }
1830
1831
17562159
                for (x = bpp; x < byte_width; x++)
1832
                {
1833
17536220
                    png -> gx_png_decoded_data[pos + x] = (GX_UBYTE)(png -> gx_png_decoded_data[pos + x] + _gx_image_reader_png_paeth_predictor(png -> gx_png_decoded_data[pos + x - bpp],
1834
17536220
                                                                                                                                                png -> gx_png_decoded_data[pos + x - byte_width],
1835
17536220
                                                                                                                                                png -> gx_png_decoded_data[pos + x - byte_width - bpp]));
1836
                }
1837
            }
1838
25943
            break;
1839
2
        default:
1840
2
            return GX_FAILURE;
1841
        }
1842
    }
1843
1844
602
    png -> gx_png_decoded_data_len -= png -> gx_png_height;
1845
1846
602
    return GX_SUCCESS;
1847
}
1848
1849
/**************************************************************************/
1850
/*                                                                        */
1851
/*  FUNCTION                                               RELEASE        */
1852
/*                                                                        */
1853
/*    _gx_image_reader_png_decode                         PORTABLE C      */
1854
/*                                                           6.2.0        */
1855
/*  AUTHOR                                                                */
1856
/*                                                                        */
1857
/*    Kenneth Maxwell, Microsoft Corporation                              */
1858
/*                                                                        */
1859
/*  DESCRIPTION                                                           */
1860
/*                                                                        */
1861
/*    This function decode a PNG format image.                            */
1862
/*                                                                        */
1863
/*  INPUT                                                                 */
1864
/*                                                                        */
1865
/*    inmap                                 Input pixelmap                */
1866
/*    outmap                                Output pixelmap               */
1867
/*                                                                        */
1868
/*  OUTPUT                                                                */
1869
/*                                                                        */
1870
/*    status                                Completion status             */
1871
/*                                                                        */
1872
/*  CALLS                                                                 */
1873
/*                                                                        */
1874
/*    strncmp                                                             */
1875
/*    _gx_system_memory_allocator           Application defined memory    */
1876
/*                                            allocation function         */
1877
/*    _gx_system_memory_free                Application defined memory    */
1878
/*                                            free function               */
1879
/*    _gx_image_reader_png_crc_table_make   Create a crc table            */
1880
/*    _gx_image_reader_png_crc_get          Calculate crc value of        */
1881
/*                                            specified data              */
1882
/*    _gx_image_reader_png_4bytes_read      Read 4 bytes and pack it to   */
1883
/*                                            INT type value              */
1884
/*    _gx_image_reader_png_chunk_type_read  Read chunk type information   */
1885
/*    _gx_image_reader_png_IDAT_chunk_read  Read IDAT chunk information   */
1886
/*                                            and start decoding          */
1887
/*    _gx_image_reader_png_IHDR_chunk_read  Read IHDR chunk information   */
1888
/*    _gx_image_reader_png_gAMA_chunk_read  Read gAMA chunk information   */
1889
/*    _gx_image_reader_png_PLTE_chunk_read  Read PLTE chunk information   */
1890
/*    _gx_image_reader_png_tRNS_chunk_read  Read tRNS chunk information   */
1891
/*    _gx_image_reader_png_unfilter         Revert effect of filter       */
1892
/*                                                                        */
1893
/*  CALLED BY                                                             */
1894
/*                                                                        */
1895
/*    _gx_image_reader_image_decode                                       */
1896
/*                                                                        */
1897
/**************************************************************************/
1898
677
UINT _gx_image_reader_png_decode(GX_CONST GX_UBYTE *read_data, ULONG data_size, GX_PIXELMAP *outmap)
1899
{
1900
677
UINT    status = GX_SUCCESS;
1901
GX_PNG  png;
1902
INT     data_len;
1903
CHAR    chunk_type[4];
1904
INT     checksum;
1905
677
GX_BOOL idat_done = GX_FALSE;
1906
INT    *scratch_buffer;
1907
677
INT     scratch_index = 0;
1908
677
GX_BOOL decoded_done = GX_FALSE;
1909
1910
677
    if (data_size < 8)
1911
    {
1912
1
        return GX_INVALID_SIZE;
1913
    }
1914
1915
676
    if ((read_data[0] == 137) &&
1916
675
        (read_data[1] == 80) &&
1917
674
        (read_data[2] == 78) &&
1918
673
        (read_data[3] == 71) &&
1919
672
        (read_data[4] == 13) &&
1920
671
        (read_data[5] == 10) &&
1921
670
        (read_data[6] == 26) &&
1922
669
        (read_data[7] == 10))
1923
    {
1924
668
        if (!_gx_system_memory_allocator)
1925
        {
1926
1
            return GX_SYSTEM_MEMORY_ERROR;
1927
        }
1928
1929
667
        memset(&png, 0, sizeof(GX_PNG));
1930
667
        scratch_buffer = (INT *)_gx_system_memory_allocator(GX_PNG_SCRATCH_BUFFER_SIZE * sizeof(ULONG));
1931
1932
667
        if (scratch_buffer == GX_NULL)
1933
        {
1934
1
            return GX_SYSTEM_MEMORY_ERROR;
1935
        }
1936
1937
666
        png.gx_png_crc_table = (UINT *)scratch_buffer;
1938
666
        scratch_index += GX_PNG_CRC_TABLE_SIZE;
1939
666
        png.gx_png_huffman_lit_table = scratch_buffer + scratch_index;
1940
666
        scratch_index += GX_PNG_HUFFMAN_LIT_TABLE_SIZE;
1941
666
        png.gx_png_huffman_lit_code_len = scratch_buffer + scratch_index;
1942
666
        scratch_index += GX_PNG_HUFFMAN_LIT_CODE_LEN_TABLE_SIZE;
1943
666
        png.gx_png_huffman_dist_code_len = scratch_buffer + scratch_index;
1944
666
        scratch_index += GX_PNG_HUFFMAN_DIST_CODE_LEN_TABLE_SIZE;
1945
666
        png.gx_png_palette_table = (GX_COLOR *)scratch_buffer + scratch_index;
1946
1947
666
        png.gx_png_data = (GX_UBYTE *)read_data;
1948
666
        png.gx_png_data_size = (INT)data_size;
1949
666
        png.gx_png_data_index = 8;
1950
1951
666
        _gx_image_reader_png_crc_table_make(&png);
1952
1953
666
        _bit_buffer = 0;
1954
666
        _bit_count = 0;
1955
1956
3589
        while (png.gx_png_data_index < png.gx_png_data_size - 4)
1957
        {
1958
            /* data_len*/
1959
3588
            _gx_image_reader_png_4bytes_read(&png, &data_len);
1960
1961
3588
            png.gx_png_trunk_crc = 0xffffffff;
1962
1963
3588
            if ((data_len < 0) ||
1964
3587
                (data_len > png.gx_png_data_size - png.gx_png_data_index - 4))
1965
            {
1966
2
                status = GX_INVALID_SIZE;
1967
2
                break;
1968
            }
1969
1970
            /* Calculate checksum of the chunk data.  */
1971
3586
            _gx_image_reader_png_crc_get(&png, &png.gx_png_trunk_crc, (UINT)(4 + data_len));
1972
1973
            /* Read chunk type.  */
1974
3586
            _gx_image_reader_png_chunk_type_read(&png, chunk_type);
1975
1976
3586
            png.gx_png_trunk_end_index = png.gx_png_data_index + data_len;
1977
1978

3586
            if ((strncmp(chunk_type, "IDAT", 4) == 0) && (!idat_done))
1979
            {
1980
644
                idat_done = GX_TRUE;
1981
1982
644
                status = _gx_image_reader_png_IDAT_chunk_read(&png);
1983
            }
1984
2942
            else if (strncmp(chunk_type, "IHDR", 4) == 0)
1985
            {
1986
661
                status = _gx_image_reader_png_IHDR_chunk_read(&png);
1987
            }
1988
2281
            else if (strncmp(chunk_type, "gAMA", 4) == 0)
1989
            {
1990
565
                status = _gx_image_reader_png_gAMA_chunk_read(&png);
1991
            }
1992
1716
            else if (strncmp(chunk_type, "PLTE", 4) == 0)
1993
            {
1994
66
                status = _gx_image_reader_png_PLTE_chunk_read(&png);
1995
            }
1996

1650
            else if ((strncmp(chunk_type, "tRNS", 4) == 0) && (png.gx_png_trans == GX_NULL))
1997
            {
1998
                /* Read transparent information. */
1999
55
                status = _gx_image_reader_png_tRNS_chunk_read(&png);
2000
            }
2001
1595
            else if (strncmp(chunk_type, "IEND", 4) == GX_SUCCESS)
2002
            {
2003
                /* End */
2004
605
                decoded_done = GX_TRUE;
2005
605
                break;
2006
            }
2007
            else
2008
            {
2009
                /* Ignore chunk */
2010
990
                png.gx_png_data_index += data_len;
2011
            }
2012
2013
2981
            if (status != GX_SUCCESS)
2014
            {
2015
55
                break;
2016
            }
2017
2018
2926
            _gx_image_reader_png_4bytes_read(&png, &checksum);
2019
2020
2926
            if (checksum != (INT)png.gx_png_trunk_crc)
2021
            {
2022
3
                status = GX_FAILURE;
2023
3
                break;
2024
            }
2025
        }
2026
2027

666
        if(status == GX_SUCCESS && (!decoded_done))
2028
        {
2029
1
            status = GX_FAILURE;
2030
        }
2031
2032
666
        if (status == GX_SUCCESS)
2033
        {
2034
            /* revert filter */
2035
605
            status = _gx_image_reader_png_unfilter(&png);
2036
        }
2037
2038
666
        if (status == GX_SUCCESS)
2039
        {
2040
602
            outmap -> gx_pixelmap_data = png.gx_png_decoded_data;
2041
602
            outmap -> gx_pixelmap_data_size = (ULONG)png.gx_png_decoded_data_len;
2042
602
            outmap -> gx_pixelmap_width = (GX_VALUE)png.gx_png_width;
2043
602
            outmap -> gx_pixelmap_height = (GX_VALUE)png.gx_png_height;
2044
602
            outmap -> gx_pixelmap_flags = GX_PIXELMAP_RAW_FORMAT;
2045
2046
602
            if (png.gx_png_trans_num)
2047
            {
2048
49
                outmap -> gx_pixelmap_flags |= GX_PIXELMAP_ALPHA;
2049
49
                outmap -> gx_pixelmap_transparent_color = (ULONG)png.gx_png_trans;
2050
            }
2051
2052

602
            switch (png.gx_png_color_type)
2053
            {
2054
312
            case 6:
2055
                /* Each pixel is an RGB triple, followed by an alpha sample. */
2056
312
                if (png.gx_png_bit_depth == 8)
2057
                {
2058
308
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_32BPP;
2059
                }
2060
                else
2061
                {
2062
                    /* Bit depth = 16. */
2063
4
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_64BPP;
2064
                }
2065
312
                outmap -> gx_pixelmap_flags |= GX_PIXELMAP_ALPHA;
2066
312
                break;
2067
12
            case 4:
2068
                /* Each pixel is a grayscale sample followed by an alpha sample. */
2069
12
                if (png.gx_png_bit_depth == 8)
2070
                {
2071
8
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_16BPP_GRAY_ALPHA;
2072
                }
2073
                else
2074
                {
2075
                    /* Bit depth = 16. */
2076
4
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_32BPP_GRAY_ALPHA;
2077
                }
2078
12
                outmap -> gx_pixelmap_flags |= GX_PIXELMAP_ALPHA;
2079
12
                break;
2080
53
            case 3:
2081
                /* Each pixel is a palette index */
2082

53
                switch (png.gx_png_bit_depth)
2083
                {
2084
6
                case 1:
2085
6
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_1BPP;
2086
6
                    break;
2087
6
                case 2:
2088
6
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_2BPP;
2089
6
                    break;
2090
10
                case 4:
2091
10
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_4BPP;
2092
10
                    break;
2093
31
                default:
2094
                    /* Bit depth = 8. */
2095
31
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_8BPP;
2096
31
                    break;
2097
                }
2098
2099
                /* Palette table size is no bigger than 256, aux data size will not overflow. */
2100
53
                outmap -> gx_pixelmap_aux_data_size = (ULONG)(png.gx_png_palette_table_size) * sizeof(GX_COLOR);
2101
53
                outmap -> gx_pixelmap_aux_data = (GX_UBYTE *)_gx_system_memory_allocator(outmap -> gx_pixelmap_aux_data_size);
2102
2103
53
                if (!outmap -> gx_pixelmap_aux_data)
2104
                {
2105
1
                    return GX_SYSTEM_MEMORY_ERROR;
2106
                }
2107
2108
52
                memcpy((GX_UBYTE *)outmap -> gx_pixelmap_aux_data, png.gx_png_palette_table, outmap -> gx_pixelmap_aux_data_size); /* Use case of memcpy is verified. */
2109
52
                break;
2110
172
            case 2:
2111
                /* Each pixel is an RGB triple. */
2112
172
                if (png.gx_png_bit_depth == 8)
2113
                {
2114
138
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_24BPP;
2115
                }
2116
                else
2117
                {
2118
                    /* Bit depth = 16. */
2119
34
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_48BPP;
2120
                }
2121
172
                break;
2122
53
            default:
2123
                /* Each pixel is a grayscale sample. */
2124

53
                switch (png.gx_png_bit_depth)
2125
                {
2126
16
                case 16:
2127
16
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_16BPP_GRAY;
2128
16
                    break;
2129
16
                case 8:
2130
16
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_8BPP;
2131
16
                    break;
2132
8
                case 4:
2133
8
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_4BPP;
2134
8
                    break;
2135
6
                case 2:
2136
6
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_2BPP;
2137
6
                    break;
2138
7
                default:
2139
                    /* Bit depth = 1. */
2140
7
                    outmap -> gx_pixelmap_format = GX_IMAGE_FORMAT_1BPP;
2141
7
                    break;
2142
                }
2143
53
                break;
2144
            }
2145
        }
2146
2147
665
        if (status != GX_SUCCESS)
2148
        {
2149
64
            if (png.gx_png_decoded_data)
2150
            {
2151
33
                _gx_system_memory_free(png.gx_png_decoded_data);
2152
            }
2153
2154
64
            if (png.gx_png_trans)
2155
            {
2156
1
                _gx_system_memory_free(png.gx_png_trans);
2157
            }
2158
        }
2159
2160
        /* Free scratch buffer. */
2161
665
        _gx_system_memory_free(scratch_buffer);
2162
    }
2163
    else
2164
    {
2165
8
        return GX_FAILURE;
2166
    }
2167
2168
665
    return status;
2169
}
2170
#endif
2171