GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_image_reader_start.c Lines: 137 137 100.0 %
Date: 2026-03-06 19:21:09 Branches: 77 77 100.0 %

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
/**   Image Reader Management (Image Reader)                              */
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
#if defined(GX_SOFTWARE_DECODER_SUPPORT)
33
34
/**************************************************************************/
35
/*                                                                        */
36
/*  FUNCTION                                               RELEASE        */
37
/*                                                                        */
38
/*    _gx_image_reader_rgb2gray                           PORTABLE C      */
39
/*                                                           6.1          */
40
/*  AUTHOR                                                                */
41
/*                                                                        */
42
/*    Kenneth Maxwell, Microsoft Corporation                              */
43
/*                                                                        */
44
/*  DESCRIPTION                                                           */
45
/*                                                                        */
46
/*    This function converts RGB value to grayscale.                      */
47
/*                                                                        */
48
/*  INPUT                                                                 */
49
/*                                                                        */
50
/*    pixel                                 RGB value                     */
51
/*    gray                                  Grayscale value to return     */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    None                                                                */
56
/*                                                                        */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    None                                                                */
60
/*                                                                        */
61
/*  CALLED BY                                                             */
62
/*                                                                        */
63
/*    GUIX Internal Code                                                  */
64
/*                                                                        */
65
/**************************************************************************/
66
2358022
VOID _gx_image_reader_rgb2gray(GX_PIXEL *pixel, GX_UBYTE *gray)
67
{
68
2358022
    (*gray) = (GX_UBYTE)((pixel -> gx_pixel_red * 299 +
69
2358022
                          pixel -> gx_pixel_green * 587 +
70
2358022
                          pixel -> gx_pixel_blue * 114) / 1000);
71
2358022
}
72
73
/**************************************************************************/
74
/*                                                                        */
75
/*  FUNCTION                                               RELEASE        */
76
/*                                                                        */
77
/*    _gx_image_reader_gray_threshold_calculate           PORTABLE C      */
78
/*                                                           6.1          */
79
/*  AUTHOR                                                                */
80
/*                                                                        */
81
/*    Kenneth Maxwell, Microsoft Corporation                              */
82
/*                                                                        */
83
/*  DESCRIPTION                                                           */
84
/*                                                                        */
85
/*    This function calcualtes thredshold value used to create monochrome */
86
/*    pixlemap.                                                           */
87
/*                                                                        */
88
/*  INPUT                                                                 */
89
/*                                                                        */
90
/*    image_reader                          Image reader control block    */
91
/*                                                                        */
92
/*  OUTPUT                                                                */
93
/*                                                                        */
94
/*    None                                                                */
95
/*                                                                        */
96
/*  CALLS                                                                 */
97
/*                                                                        */
98
/*    [gx_image_reader_pixel_read]          Pixel read callback           */
99
/*    _gx_image_reader_rgb2gray             Conver RGB value to grayscale */
100
/*                                                                        */
101
/*  CALLED BY                                                             */
102
/*                                                                        */
103
/*    _gx_image_reader_start                                              */
104
/*                                                                        */
105
/**************************************************************************/
106
26
static VOID _gx_image_reader_gray_threshold_calculate(GX_IMAGE_READER *image_reader)
107
{
108
26
INT      threshold = 0;
109
INT      xval;
110
INT      yval;
111
26
INT      count = 0;
112
GX_PIXEL pixel;
113
GX_UBYTE gray;
114
115
4666
    for (yval = 0; yval < (INT)image_reader -> gx_image_reader_image_height; yval++)
116
    {
117
873399
        for (xval = 0; xval < (INT)image_reader -> gx_image_reader_image_width; xval++)
118
        {
119
868759
            image_reader -> gx_image_reader_pixel_read(image_reader, xval, &pixel);
120
121
868759
            if (pixel.gx_pixel_alpha > 128)
122
            {
123
                /* Convert RGB value to grayscale. */
124
694186
                _gx_image_reader_rgb2gray(&pixel, &gray);
125
694186
                threshold += gray;
126
694186
                count++;
127
            }
128
        }
129
130
4640
        image_reader -> gx_image_reader_getdata += image_reader -> gx_image_reader_input_stride;
131
    }
132
133
26
    if (count)
134
    {
135
25
        image_reader -> gx_image_reader_mono_shreshold = (GX_UBYTE)(threshold / count);
136
    }
137
138
26
    if (image_reader -> gx_image_reader_mono_shreshold == 0)
139
    {
140
        /* All opaque pixels are black. */
141
1
        image_reader -> gx_image_reader_mono_shreshold = 255;
142
    }
143
25
    else if (image_reader -> gx_image_reader_mono_shreshold == 255)
144
    {
145
        /* All opqaute pixels are white. */
146
1
        image_reader -> gx_image_reader_mono_shreshold = 0;
147
    }
148
26
}
149
150
151
/**************************************************************************/
152
/*                                                                        */
153
/*  FUNCTION                                               RELEASE        */
154
/*                                                                        */
155
/*    _gx_image_reader_pixelmap_info_set                  PORTABLE C      */
156
/*                                                           6.1          */
157
/*  AUTHOR                                                                */
158
/*                                                                        */
159
/*    Kenneth Maxwell, Microsoft Corporation                              */
160
/*                                                                        */
161
/*  DESCRIPTION                                                           */
162
/*                                                                        */
163
/*    This function prepares for image converting.                        */
164
/*                                                                        */
165
/*  INPUT                                                                 */
166
/*                                                                        */
167
/*    image_reader                          Image reader control block    */
168
/*    outmap                                Pointer to a pixelmap that is */
169
/*                                            used to loading converted   */
170
/*                                            image                       */
171
/*                                                                        */
172
/*  OUTPUT                                                                */
173
/*                                                                        */
174
/*    Completion status                                                   */
175
/*                                                                        */
176
/*  CALLS                                                                 */
177
/*                                                                        */
178
/*    None                                                                */
179
/*                                                                        */
180
/*  CALLED BY                                                             */
181
/*                                                                        */
182
/*    _gx_image_reader_start                                              */
183
/*                                                                        */
184
/**************************************************************************/
185
817
static UINT _gx_image_reader_pixelmap_info_set(GX_IMAGE_READER *image_reader, GX_PIXELMAP *outmap)
186
{
187
817
    outmap -> gx_pixelmap_width = (GX_VALUE)image_reader -> gx_image_reader_image_width;
188
817
    outmap -> gx_pixelmap_height = (GX_VALUE)image_reader -> gx_image_reader_image_height;
189
817
    outmap -> gx_pixelmap_data_size = 0;
190
817
    outmap -> gx_pixelmap_aux_data_size = 0;
191
817
    outmap -> gx_pixelmap_format = image_reader -> gx_image_reader_color_format;
192
193
    /* Set alpha flag.  */
194
817
    if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA)
195
    {
196
325
        switch (outmap -> gx_pixelmap_format)
197
        {
198
25
        case GX_COLOR_FORMAT_8BIT_PALETTE:
199
        case GX_COLOR_FORMAT_4BIT_GRAY:
200
        case GX_COLOR_FORMAT_MONOCHROME:
201
25
            outmap -> gx_pixelmap_flags = GX_PIXELMAP_TRANSPARENT;
202
25
            outmap -> gx_pixelmap_transparent_color = GX_TRANSPARENT_COLOR;
203
25
            break;
204
205
300
        default:
206
300
            outmap -> gx_pixelmap_flags = GX_PIXELMAP_ALPHA;
207
300
            break;
208
        }
209
    }
210
211
    /* Calculate pixelmap data size, which will be used for memory allocation lator. Max width and height is limited to 14 bits,
212
       so overflow cannot occur. */
213

817
    switch (outmap -> gx_pixelmap_format)
214
    {
215
305
    case GX_COLOR_FORMAT_565RGB:
216
    case GX_COLOR_FORMAT_1555XRGB:
217
305
        outmap -> gx_pixelmap_data_size = (ULONG)(outmap -> gx_pixelmap_width * outmap -> gx_pixelmap_height * (INT)sizeof(USHORT));
218
219
305
        if (outmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
220
        {
221
149
            outmap -> gx_pixelmap_aux_data_size = (ULONG)(outmap -> gx_pixelmap_width * outmap -> gx_pixelmap_height);
222
        }
223
305
        break;
224
225
19
    case GX_COLOR_FORMAT_4444ARGB:
226
19
        outmap -> gx_pixelmap_data_size = (ULONG)(outmap -> gx_pixelmap_width * outmap -> gx_pixelmap_height * (INT)sizeof(USHORT));
227
19
        break;
228
229
277
    case GX_COLOR_FORMAT_32ARGB:
230
    case GX_COLOR_FORMAT_24XRGB:
231
277
        outmap -> gx_pixelmap_data_size = (ULONG)(outmap -> gx_pixelmap_width * outmap -> gx_pixelmap_height * (INT)sizeof(GX_COLOR));
232
277
        image_reader -> gx_image_reader_mode = (GX_UBYTE)(image_reader -> gx_image_reader_mode & (~GX_IMAGE_READER_MODE_DITHER));
233
277
        break;
234
235
166
    case GX_COLOR_FORMAT_8BIT_ALPHAMAP:
236
    case GX_COLOR_FORMAT_8BIT_PALETTE:
237
166
        outmap -> gx_pixelmap_data_size = (ULONG)(outmap -> gx_pixelmap_width * outmap -> gx_pixelmap_height);
238
166
        break;
239
240
23
    case GX_COLOR_FORMAT_4BIT_GRAY:
241
23
        outmap -> gx_pixelmap_data_size = (ULONG)(((outmap -> gx_pixelmap_width + 1) >> 1) * outmap -> gx_pixelmap_height);
242
23
        if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA)
243
        {
244
7
            outmap -> gx_pixelmap_aux_data_size = (ULONG)(((outmap -> gx_pixelmap_width + 7) >> 3) * outmap -> gx_pixelmap_height);
245
        }
246
23
        break;
247
248
26
    case GX_COLOR_FORMAT_MONOCHROME:
249
26
        if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_ALPHA)
250
        {
251
10
            outmap -> gx_pixelmap_data_size = (ULONG)(((outmap -> gx_pixelmap_width + 3) >> 2) * outmap -> gx_pixelmap_height);
252
        }
253
        else
254
        {
255
16
            outmap -> gx_pixelmap_data_size = (ULONG)(((outmap -> gx_pixelmap_width + 7) >> 3) * outmap -> gx_pixelmap_height);
256
        }
257
26
        break;
258
259
1
    default:
260
1
        return GX_NOT_SUPPORTED;
261
    }
262
263
816
    return GX_SUCCESS;
264
}
265
266
/**************************************************************************/
267
/*                                                                        */
268
/*  FUNCTION                                               RELEASE        */
269
/*                                                                        */
270
/*    _gx_image_reader_start                              PORTABLE C      */
271
/*                                                           6.3.0        */
272
/*  AUTHOR                                                                */
273
/*                                                                        */
274
/*    Kenneth Maxwell, Microsoft Corporation                              */
275
/*                                                                        */
276
/*  DESCRIPTION                                                           */
277
/*                                                                        */
278
/*    This function converts pixelmap to a specified color format.        */
279
/*                                                                        */
280
/*  INPUT                                                                 */
281
/*                                                                        */
282
/*    image_reader                          Image reader control block    */
283
/*    outmap                                Output pixelmap               */
284
/*                                                                        */
285
/*  OUTPUT                                                                */
286
/*                                                                        */
287
/*    None                                                                */
288
/*                                                                        */
289
/*  CALLS                                                                 */
290
/*                                                                        */
291
/*    memcpy                                                              */
292
/*    memset                                                              */
293
/*    _gx_system_memory_allocator           Application defined memory    */
294
/*                                            allocation function         */
295
/*    _gx_system_memory_free                Application defined memory    */
296
/*                                            free function               */
297
/*    _gx_image_reader_image_decode         Decode specified image        */
298
/*    _gx_image_reader_pixel_read_callback_set                            */
299
/*                                          Set pixel read callback       */
300
/*    _gx_image_reader_pixel_write_callback_set                           */
301
/*                                          Set pixel write callback      */
302
/*    _gx_image_reader_dither               Process dither algorithm      */
303
/*    _gx_image_reader_rle_encode           Compress image with RLE       */
304
/*                                            algorithm                   */
305
/*    _gx_image_reader_raw_convert          Convert raw format map to     */
306
/*                                            specified format            */
307
/*                                                                        */
308
/*  CALLED BY                                                             */
309
/*                                                                        */
310
/*    Application Code                                                    */
311
/*                                                                        */
312
/**************************************************************************/
313
973
UINT _gx_image_reader_start(GX_IMAGE_READER *image_reader, GX_PIXELMAP *outmap)
314
{
315
UINT        status;
316
GX_PIXELMAP srcmap;
317
GX_PIXELMAP tempmap;
318
UINT        compressed_data_size;
319
UINT        compressed_aux_size;
320
UINT        raw_size;
321
GX_BOOL     do_compress;
322
323
973
    memset(outmap, 0, sizeof(GX_PIXELMAP));
324
973
    memset(&srcmap, 0, sizeof(GX_PIXELMAP));
325
326
973
    if (!_gx_system_memory_allocator)
327
    {
328
147
        return GX_SYSTEM_MEMORY_ERROR;
329
    }
330
331
    /* Decode input image to raw format. */
332
826
    status = _gx_image_reader_image_decode(image_reader, &srcmap);
333
334
826
    if (status == GX_SUCCESS)
335
    {
336
        /* Set output pixelmap information. */
337
817
        image_reader -> gx_image_reader_image_width = (UINT)srcmap.gx_pixelmap_width;
338
817
        image_reader -> gx_image_reader_image_height = (UINT)srcmap.gx_pixelmap_height;
339
340
817
        status = _gx_image_reader_pixelmap_info_set(image_reader, outmap);
341
    }
342
343
826
    if (image_reader -> gx_image_reader_mode & GX_IMAGE_READER_MODE_COMPRESS)
344
    {
345
205
        do_compress = GX_TRUE;
346
    }
347
    else
348
    {
349
621
        do_compress = GX_FALSE;
350
    }
351
352

826
    if((image_reader -> gx_image_reader_image_type == GX_IMAGE_TYPE_JPG && srcmap.gx_pixelmap_format == GX_IMAGE_FORMAT_24BPP) ||
353
658
       (image_reader -> gx_image_reader_image_type == GX_IMAGE_TYPE_PNG))
354
    {
355
356
772
        if (status == GX_SUCCESS)
357
        {
358
768
            if (image_reader -> gx_image_reader_color_format == GX_COLOR_FORMAT_MONOCHROME)
359
            {
360
26
                status = _gx_image_reader_pixel_read_callback_set(image_reader, &srcmap);
361
26
                _gx_image_reader_gray_threshold_calculate(image_reader);
362
            }
363
        }
364
365
772
        image_reader -> gx_image_reader_mode = (GX_UBYTE)(image_reader -> gx_image_reader_mode & (~GX_IMAGE_READER_MODE_COMPRESS));
366
367
        /* Color Space Convert.  */
368
772
        if (status == GX_SUCCESS)
369
        {
370
768
            tempmap = *outmap;
371
372
768
            status = _gx_image_reader_pixel_read_callback_set(image_reader, &srcmap);
373
        }
374
375
772
        if (status == GX_SUCCESS)
376
        {
377
768
            status = _gx_image_reader_pixel_write_callback_set(image_reader, &tempmap);
378
        }
379
380
772
        if (status == GX_SUCCESS)
381
        {
382
765
            status = _gx_image_reader_colorspace_convert(image_reader, &tempmap);
383
384
765
            _gx_system_memory_free((VOID *)srcmap.gx_pixelmap_data);
385
386
765
            if (srcmap.gx_pixelmap_aux_data)
387
            {
388
52
                _gx_system_memory_free((VOID *)srcmap.gx_pixelmap_aux_data);
389
            }
390
391
765
            srcmap = tempmap;
392
        }
393
    }
394
395
    /* Compare compressed size and raw size. */
396
826
    if (do_compress)
397
    {
398
205
        image_reader -> gx_image_reader_mode |= GX_IMAGE_READER_MODE_COMPRESS;
399
400
        /* Seet pixel read and write callback.  */
401
205
        if (status == GX_SUCCESS)
402
        {
403
197
            status = _gx_image_reader_pixel_read_callback_set(image_reader, &srcmap);
404
        }
405
406
205
        if (status == GX_SUCCESS)
407
        {
408
197
            tempmap = *outmap;
409
197
            tempmap.gx_pixelmap_data_size = 0;
410
197
            tempmap.gx_pixelmap_aux_data_size = 0;
411
197
            tempmap.gx_pixelmap_flags |= GX_PIXELMAP_COMPRESSED;
412
413
197
            status = _gx_image_reader_pixel_write_callback_set(image_reader, &tempmap);
414
        }
415
416
        /* Calculate the storage size that needed for rle encode. */
417
205
        if (status == GX_SUCCESS)
418
        {
419
197
            _gx_image_reader_rle_encode_size_get(image_reader, &compressed_data_size, &compressed_aux_size);
420
421
197
            raw_size = outmap -> gx_pixelmap_aux_data_size + outmap -> gx_pixelmap_data_size;
422
423
            /* Test wheather the encoded data size is smaller that raw size.  */
424
197
            if (compressed_aux_size + compressed_data_size < raw_size)
425
            {
426
184
                outmap -> gx_pixelmap_data_size = compressed_data_size;
427
184
                outmap -> gx_pixelmap_aux_data_size = compressed_aux_size;
428
184
                outmap -> gx_pixelmap_flags |= GX_PIXELMAP_COMPRESSED;
429
430
184
                _gx_image_reader_pixel_read_callback_set(image_reader, &srcmap);
431
432
184
                status = _gx_image_reader_pixel_write_callback_set(image_reader, outmap);
433
434
184
                if (status == GX_SUCCESS)
435
                {
436
183
                    status = _gx_image_reader_rle_encode(image_reader, outmap);
437
                }
438
            }
439
            else
440
            {
441
13
                *outmap = srcmap;
442
13
                memset(&srcmap, 0, sizeof(GX_PIXELMAP));
443
            }
444
        }
445
    }
446
    else
447
    {
448
621
        *outmap = srcmap;
449
621
        memset(&srcmap, 0, sizeof(GX_PIXELMAP));
450
    }
451
452
    /* Release memory that used to load decoded pixelmap data. */
453
826
    if (srcmap.gx_pixelmap_data)
454
    {
455
186
        _gx_system_memory_free((VOID *)srcmap.gx_pixelmap_data);
456
    }
457
458
826
    if (srcmap.gx_pixelmap_aux_data)
459
    {
460
17
        _gx_system_memory_free((VOID *)srcmap.gx_pixelmap_aux_data);
461
    }
462
463
826
    if (image_reader -> gx_image_reader_png_trans)
464
    {
465
49
        _gx_system_memory_free((VOID *)image_reader -> gx_image_reader_png_trans);
466
    }
467
468
826
    if (status != GX_SUCCESS)
469
    {
470
17
        if (outmap -> gx_pixelmap_data)
471
        {
472
5
            _gx_system_memory_free((VOID *)outmap -> gx_pixelmap_data);
473
5
            outmap -> gx_pixelmap_data = GX_NULL;
474
        }
475
476
17
        if (outmap -> gx_pixelmap_aux_data)
477
        {
478
1
            _gx_system_memory_free((VOID *)outmap -> gx_pixelmap_aux_data);
479
1
            outmap -> gx_pixelmap_aux_data = GX_NULL;
480
        }
481
    }
482
483
826
    return status;
484
}
485
#endif
486