GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_image_reader_start.c Lines: 137 137 100.0 %
Date: 2024-12-05 08:52:37 Branches: 77 77 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** GUIX Component                                                        */
16
/**                                                                       */
17
/**   Image Reader Management (Image Reader)                              */
18
/**                                                                       */
19
/**************************************************************************/
20
21
#define GX_SOURCE_CODE
22
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_system.h"
28
#include "gx_utility.h"
29
#include "gx_image_reader.h"
30
31
#if defined(GX_SOFTWARE_DECODER_SUPPORT)
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _gx_image_reader_rgb2gray                           PORTABLE C      */
38
/*                                                           6.1          */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function converts RGB value to grayscale.                      */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    pixel                                 RGB value                     */
50
/*    gray                                  Grayscale value to return     */
51
/*                                                                        */
52
/*  OUTPUT                                                                */
53
/*                                                                        */
54
/*    None                                                                */
55
/*                                                                        */
56
/*  CALLS                                                                 */
57
/*                                                                        */
58
/*    None                                                                */
59
/*                                                                        */
60
/*  CALLED BY                                                             */
61
/*                                                                        */
62
/*    GUIX Internal Code                                                  */
63
/*                                                                        */
64
/*  RELEASE HISTORY                                                       */
65
/*                                                                        */
66
/*    DATE              NAME                      DESCRIPTION             */
67
/*                                                                        */
68
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
69
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
70
/*                                            resulting in version 6.1    */
71
/*                                                                        */
72
/**************************************************************************/
73
2358022
VOID _gx_image_reader_rgb2gray(GX_PIXEL *pixel, GX_UBYTE *gray)
74
{
75
2358022
    (*gray) = (GX_UBYTE)((pixel -> gx_pixel_red * 299 +
76
2358022
                          pixel -> gx_pixel_green * 587 +
77
2358022
                          pixel -> gx_pixel_blue * 114) / 1000);
78
2358022
}
79
80
/**************************************************************************/
81
/*                                                                        */
82
/*  FUNCTION                                               RELEASE        */
83
/*                                                                        */
84
/*    _gx_image_reader_gray_threshold_calculate           PORTABLE C      */
85
/*                                                           6.1          */
86
/*  AUTHOR                                                                */
87
/*                                                                        */
88
/*    Kenneth Maxwell, Microsoft Corporation                              */
89
/*                                                                        */
90
/*  DESCRIPTION                                                           */
91
/*                                                                        */
92
/*    This function calcualtes thredshold value used to create monochrome */
93
/*    pixlemap.                                                           */
94
/*                                                                        */
95
/*  INPUT                                                                 */
96
/*                                                                        */
97
/*    image_reader                          Image reader control block    */
98
/*                                                                        */
99
/*  OUTPUT                                                                */
100
/*                                                                        */
101
/*    None                                                                */
102
/*                                                                        */
103
/*  CALLS                                                                 */
104
/*                                                                        */
105
/*    [gx_image_reader_pixel_read]          Pixel read callback           */
106
/*    _gx_image_reader_rgb2gray             Conver RGB value to grayscale */
107
/*                                                                        */
108
/*  CALLED BY                                                             */
109
/*                                                                        */
110
/*    _gx_image_reader_start                                              */
111
/*                                                                        */
112
/*  RELEASE HISTORY                                                       */
113
/*                                                                        */
114
/*    DATE              NAME                      DESCRIPTION             */
115
/*                                                                        */
116
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
117
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
118
/*                                            resulting in version 6.1    */
119
/*                                                                        */
120
/**************************************************************************/
121
26
static VOID _gx_image_reader_gray_threshold_calculate(GX_IMAGE_READER *image_reader)
122
{
123
26
INT      threshold = 0;
124
INT      xval;
125
INT      yval;
126
26
INT      count = 0;
127
GX_PIXEL pixel;
128
GX_UBYTE gray;
129
130
4666
    for (yval = 0; yval < (INT)image_reader -> gx_image_reader_image_height; yval++)
131
    {
132
873399
        for (xval = 0; xval < (INT)image_reader -> gx_image_reader_image_width; xval++)
133
        {
134
868759
            image_reader -> gx_image_reader_pixel_read(image_reader, xval, &pixel);
135
136
868759
            if (pixel.gx_pixel_alpha > 128)
137
            {
138
                /* Convert RGB value to grayscale. */
139
694186
                _gx_image_reader_rgb2gray(&pixel, &gray);
140
694186
                threshold += gray;
141
694186
                count++;
142
            }
143
        }
144
145
4640
        image_reader -> gx_image_reader_getdata += image_reader -> gx_image_reader_input_stride;
146
    }
147
148
26
    if (count)
149
    {
150
25
        image_reader -> gx_image_reader_mono_shreshold = (GX_UBYTE)(threshold / count);
151
    }
152
153
26
    if (image_reader -> gx_image_reader_mono_shreshold == 0)
154
    {
155
        /* All opaque pixels are black. */
156
1
        image_reader -> gx_image_reader_mono_shreshold = 255;
157
    }
158
25
    else if (image_reader -> gx_image_reader_mono_shreshold == 255)
159
    {
160
        /* All opqaute pixels are white. */
161
1
        image_reader -> gx_image_reader_mono_shreshold = 0;
162
    }
163
26
}
164
165
166
/**************************************************************************/
167
/*                                                                        */
168
/*  FUNCTION                                               RELEASE        */
169
/*                                                                        */
170
/*    _gx_image_reader_pixelmap_info_set                  PORTABLE C      */
171
/*                                                           6.1          */
172
/*  AUTHOR                                                                */
173
/*                                                                        */
174
/*    Kenneth Maxwell, Microsoft Corporation                              */
175
/*                                                                        */
176
/*  DESCRIPTION                                                           */
177
/*                                                                        */
178
/*    This function prepares for image converting.                        */
179
/*                                                                        */
180
/*  INPUT                                                                 */
181
/*                                                                        */
182
/*    image_reader                          Image reader control block    */
183
/*    outmap                                Pointer to a pixelmap that is */
184
/*                                            used to loading converted   */
185
/*                                            image                       */
186
/*                                                                        */
187
/*  OUTPUT                                                                */
188
/*                                                                        */
189
/*    Completion status                                                   */
190
/*                                                                        */
191
/*  CALLS                                                                 */
192
/*                                                                        */
193
/*    None                                                                */
194
/*                                                                        */
195
/*  CALLED BY                                                             */
196
/*                                                                        */
197
/*    _gx_image_reader_start                                              */
198
/*                                                                        */
199
/*  RELEASE HISTORY                                                       */
200
/*                                                                        */
201
/*    DATE              NAME                      DESCRIPTION             */
202
/*                                                                        */
203
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
204
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
205
/*                                            resulting in version 6.1    */
206
/*                                                                        */
207
/**************************************************************************/
208
817
static UINT _gx_image_reader_pixelmap_info_set(GX_IMAGE_READER *image_reader, GX_PIXELMAP *outmap)
209
{
210
817
    outmap -> gx_pixelmap_width = (GX_VALUE)image_reader -> gx_image_reader_image_width;
211
817
    outmap -> gx_pixelmap_height = (GX_VALUE)image_reader -> gx_image_reader_image_height;
212
817
    outmap -> gx_pixelmap_data_size = 0;
213
817
    outmap -> gx_pixelmap_aux_data_size = 0;
214
817
    outmap -> gx_pixelmap_format = image_reader -> gx_image_reader_color_format;
215
216
    /* Set alpha flag.  */
217
817
    if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA)
218
    {
219
325
        switch (outmap -> gx_pixelmap_format)
220
        {
221
25
        case GX_COLOR_FORMAT_8BIT_PALETTE:
222
        case GX_COLOR_FORMAT_4BIT_GRAY:
223
        case GX_COLOR_FORMAT_MONOCHROME:
224
25
            outmap -> gx_pixelmap_flags = GX_PIXELMAP_TRANSPARENT;
225
25
            outmap -> gx_pixelmap_transparent_color = GX_TRANSPARENT_COLOR;
226
25
            break;
227
228
300
        default:
229
300
            outmap -> gx_pixelmap_flags = GX_PIXELMAP_ALPHA;
230
300
            break;
231
        }
232
    }
233
234
    /* Calculate pixelmap data size, which will be used for memory allocation lator. Max width and height is limited to 14 bits,
235
       so overflow cannot occur. */
236

817
    switch (outmap -> gx_pixelmap_format)
237
    {
238
305
    case GX_COLOR_FORMAT_565RGB:
239
    case GX_COLOR_FORMAT_1555XRGB:
240
305
        outmap -> gx_pixelmap_data_size = (ULONG)(outmap -> gx_pixelmap_width * outmap -> gx_pixelmap_height * (INT)sizeof(USHORT));
241
242
305
        if (outmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
243
        {
244
149
            outmap -> gx_pixelmap_aux_data_size = (ULONG)(outmap -> gx_pixelmap_width * outmap -> gx_pixelmap_height);
245
        }
246
305
        break;
247
248
19
    case GX_COLOR_FORMAT_4444ARGB:
249
19
        outmap -> gx_pixelmap_data_size = (ULONG)(outmap -> gx_pixelmap_width * outmap -> gx_pixelmap_height * (INT)sizeof(USHORT));
250
19
        break;
251
252
277
    case GX_COLOR_FORMAT_32ARGB:
253
    case GX_COLOR_FORMAT_24XRGB:
254
277
        outmap -> gx_pixelmap_data_size = (ULONG)(outmap -> gx_pixelmap_width * outmap -> gx_pixelmap_height * (INT)sizeof(GX_COLOR));
255
277
        image_reader -> gx_image_reader_mode = (GX_UBYTE)(image_reader -> gx_image_reader_mode & (~GX_IMAGE_READER_MODE_DITHER));
256
277
        break;
257
258
166
    case GX_COLOR_FORMAT_8BIT_ALPHAMAP:
259
    case GX_COLOR_FORMAT_8BIT_PALETTE:
260
166
        outmap -> gx_pixelmap_data_size = (ULONG)(outmap -> gx_pixelmap_width * outmap -> gx_pixelmap_height);
261
166
        break;
262
263
23
    case GX_COLOR_FORMAT_4BIT_GRAY:
264
23
        outmap -> gx_pixelmap_data_size = (ULONG)(((outmap -> gx_pixelmap_width + 1) >> 1) * outmap -> gx_pixelmap_height);
265
23
        if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA)
266
        {
267
7
            outmap -> gx_pixelmap_aux_data_size = (ULONG)(((outmap -> gx_pixelmap_width + 7) >> 3) * outmap -> gx_pixelmap_height);
268
        }
269
23
        break;
270
271
26
    case GX_COLOR_FORMAT_MONOCHROME:
272
26
        if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA)
273
        {
274
10
            outmap -> gx_pixelmap_data_size = (ULONG)(((outmap -> gx_pixelmap_width + 3) >> 2) * outmap -> gx_pixelmap_height);
275
        }
276
        else
277
        {
278
16
            outmap -> gx_pixelmap_data_size = (ULONG)(((outmap -> gx_pixelmap_width + 7) >> 3) * outmap -> gx_pixelmap_height);
279
        }
280
26
        break;
281
282
1
    default:
283
1
        return GX_NOT_SUPPORTED;
284
    }
285
286
816
    return GX_SUCCESS;
287
}
288
289
/**************************************************************************/
290
/*                                                                        */
291
/*  FUNCTION                                               RELEASE        */
292
/*                                                                        */
293
/*    _gx_image_reader_start                              PORTABLE C      */
294
/*                                                           6.3.0        */
295
/*  AUTHOR                                                                */
296
/*                                                                        */
297
/*    Kenneth Maxwell, Microsoft Corporation                              */
298
/*                                                                        */
299
/*  DESCRIPTION                                                           */
300
/*                                                                        */
301
/*    This function converts pixelmap to a specified color format.        */
302
/*                                                                        */
303
/*  INPUT                                                                 */
304
/*                                                                        */
305
/*    image_reader                          Image reader control block    */
306
/*    outmap                                Output pixelmap               */
307
/*                                                                        */
308
/*  OUTPUT                                                                */
309
/*                                                                        */
310
/*    None                                                                */
311
/*                                                                        */
312
/*  CALLS                                                                 */
313
/*                                                                        */
314
/*    memcpy                                                              */
315
/*    memset                                                              */
316
/*    _gx_system_memory_allocator           Application defined memory    */
317
/*                                            allocation function         */
318
/*    _gx_system_memory_free                Application defined memory    */
319
/*                                            free function               */
320
/*    _gx_image_reader_image_decode         Decode specified image        */
321
/*    _gx_image_reader_pixel_read_callback_set                            */
322
/*                                          Set pixel read callback       */
323
/*    _gx_image_reader_pixel_write_callback_set                           */
324
/*                                          Set pixel write callback      */
325
/*    _gx_image_reader_dither               Process dither algorithm      */
326
/*    _gx_image_reader_rle_encode           Compress image with RLE       */
327
/*                                            algorithm                   */
328
/*    _gx_image_reader_raw_convert          Convert raw format map to     */
329
/*                                            specified format            */
330
/*                                                                        */
331
/*  CALLED BY                                                             */
332
/*                                                                        */
333
/*    Application Code                                                    */
334
/*                                                                        */
335
/*  RELEASE HISTORY                                                       */
336
/*                                                                        */
337
/*    DATE              NAME                      DESCRIPTION             */
338
/*                                                                        */
339
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
340
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
341
/*                                            resulting in version 6.1    */
342
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
343
/*                                            improved logic,             */
344
/*                                            resulting in version 6.3.0  */
345
/*                                                                        */
346
/**************************************************************************/
347
973
UINT _gx_image_reader_start(GX_IMAGE_READER *image_reader, GX_PIXELMAP *outmap)
348
{
349
UINT        status;
350
GX_PIXELMAP srcmap;
351
GX_PIXELMAP tempmap;
352
UINT        compressed_data_size;
353
UINT        compressed_aux_size;
354
UINT        raw_size;
355
GX_BOOL     do_compress;
356
357
973
    memset(outmap, 0, sizeof(GX_PIXELMAP));
358
973
    memset(&srcmap, 0, sizeof(GX_PIXELMAP));
359
360
973
    if (!_gx_system_memory_allocator)
361
    {
362
147
        return GX_SYSTEM_MEMORY_ERROR;
363
    }
364
365
    /* Decode input image to raw format. */
366
826
    status = _gx_image_reader_image_decode(image_reader, &srcmap);
367
368
826
    if (status == GX_SUCCESS)
369
    {
370
        /* Set output pixelmap information. */
371
817
        image_reader -> gx_image_reader_image_width = (UINT)srcmap.gx_pixelmap_width;
372
817
        image_reader -> gx_image_reader_image_height = (UINT)srcmap.gx_pixelmap_height;
373
374
817
        status = _gx_image_reader_pixelmap_info_set(image_reader, outmap);
375
    }
376
377
826
    if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_COMPRESS)
378
    {
379
205
        do_compress = GX_TRUE;
380
    }
381
    else
382
    {
383
621
        do_compress = GX_FALSE;
384
    }
385
386

826
    if((image_reader -> gx_image_reader_image_type == GX_IMAGE_TYPE_JPG && srcmap.gx_pixelmap_format == GX_IMAGE_FORMAT_24BPP) ||
387
658
       (image_reader -> gx_image_reader_image_type == GX_IMAGE_TYPE_PNG))
388
    {
389
390
772
        if (status == GX_SUCCESS)
391
        {
392
768
            if (image_reader -> gx_image_reader_color_format == GX_COLOR_FORMAT_MONOCHROME)
393
            {
394
26
                status = _gx_image_reader_pixel_read_callback_set(image_reader, &srcmap);
395
26
                _gx_image_reader_gray_threshold_calculate(image_reader);
396
            }
397
        }
398
399
772
        image_reader -> gx_image_reader_mode = (GX_UBYTE)(image_reader -> gx_image_reader_mode & (~GX_IMAGE_READER_MODE_COMPRESS));
400
401
        /* Color Space Convert.  */
402
772
        if (status == GX_SUCCESS)
403
        {
404
768
            tempmap = *outmap;
405
406
768
            status = _gx_image_reader_pixel_read_callback_set(image_reader, &srcmap);
407
        }
408
409
772
        if (status == GX_SUCCESS)
410
        {
411
768
            status = _gx_image_reader_pixel_write_callback_set(image_reader, &tempmap);
412
        }
413
414
772
        if (status == GX_SUCCESS)
415
        {
416
765
            status = _gx_image_reader_colorspace_convert(image_reader, &tempmap);
417
418
765
            _gx_system_memory_free((VOID *)srcmap.gx_pixelmap_data);
419
420
765
            if (srcmap.gx_pixelmap_aux_data)
421
            {
422
52
                _gx_system_memory_free((VOID *)srcmap.gx_pixelmap_aux_data);
423
            }
424
425
765
            srcmap = tempmap;
426
        }
427
    }
428
429
    /* Compare compressed size and raw size. */
430
826
    if (do_compress)
431
    {
432
205
        image_reader -> gx_image_reader_mode |= GX_IMAGE_READER_MODE_COMPRESS;
433
434
        /* Seet pixel read and write callback.  */
435
205
        if (status == GX_SUCCESS)
436
        {
437
197
            status = _gx_image_reader_pixel_read_callback_set(image_reader, &srcmap);
438
        }
439
440
205
        if (status == GX_SUCCESS)
441
        {
442
197
            tempmap = *outmap;
443
197
            tempmap.gx_pixelmap_data_size = 0;
444
197
            tempmap.gx_pixelmap_aux_data_size = 0;
445
197
            tempmap.gx_pixelmap_flags |= GX_PIXELMAP_COMPRESSED;
446
447
197
            status = _gx_image_reader_pixel_write_callback_set(image_reader, &tempmap);
448
        }
449
450
        /* Calculate the storage size that needed for rle encode. */
451
205
        if (status == GX_SUCCESS)
452
        {
453
197
            _gx_image_reader_rle_encode_size_get(image_reader, &compressed_data_size, &compressed_aux_size);
454
455
197
            raw_size = outmap -> gx_pixelmap_aux_data_size + outmap -> gx_pixelmap_data_size;
456
457
            /* Test wheather the encoded data size is smaller that raw size.  */
458
197
            if (compressed_aux_size + compressed_data_size < raw_size)
459
            {
460
184
                outmap -> gx_pixelmap_data_size = compressed_data_size;
461
184
                outmap -> gx_pixelmap_aux_data_size = compressed_aux_size;
462
184
                outmap -> gx_pixelmap_flags |= GX_PIXELMAP_COMPRESSED;
463
464
184
                _gx_image_reader_pixel_read_callback_set(image_reader, &srcmap);
465
466
184
                status = _gx_image_reader_pixel_write_callback_set(image_reader, outmap);
467
468
184
                if (status == GX_SUCCESS)
469
                {
470
183
                    status = _gx_image_reader_rle_encode(image_reader, outmap);
471
                }
472
            }
473
            else
474
            {
475
13
                *outmap = srcmap;
476
13
                memset(&srcmap, 0, sizeof(GX_PIXELMAP));
477
            }
478
        }
479
    }
480
    else
481
    {
482
621
        *outmap = srcmap;
483
621
        memset(&srcmap, 0, sizeof(GX_PIXELMAP));
484
    }
485
486
    /* Release memory that used to load decoded pixelmap data. */
487
826
    if (srcmap.gx_pixelmap_data)
488
    {
489
186
        _gx_system_memory_free((VOID *)srcmap.gx_pixelmap_data);
490
    }
491
492
826
    if (srcmap.gx_pixelmap_aux_data)
493
    {
494
17
        _gx_system_memory_free((VOID *)srcmap.gx_pixelmap_aux_data);
495
    }
496
497
826
    if (image_reader -> gx_image_reader_png_trans)
498
    {
499
49
        _gx_system_memory_free((VOID *)image_reader -> gx_image_reader_png_trans);
500
    }
501
502
826
    if (status != GX_SUCCESS)
503
    {
504
17
        if (outmap -> gx_pixelmap_data)
505
        {
506
5
            _gx_system_memory_free((VOID *)outmap -> gx_pixelmap_data);
507
5
            outmap -> gx_pixelmap_data = GX_NULL;
508
        }
509
510
17
        if (outmap -> gx_pixelmap_aux_data)
511
        {
512
1
            _gx_system_memory_free((VOID *)outmap -> gx_pixelmap_aux_data);
513
1
            outmap -> gx_pixelmap_aux_data = GX_NULL;
514
        }
515
    }
516
517
826
    return status;
518
}
519
#endif
520