GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_utility_4444argb_pixelmap_resize.c Lines: 68 68 100.0 %
Date: 2026-03-06 19:21:09 Branches: 18 18 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
/**   Utility (Utility)                                                   */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define ALPHAVAL(_c)   (GX_UBYTE)(((_c) >> 12) & 0xf)
23
#define REDVAL(_c)     (GX_UBYTE)(((_c) >> 8) & 0xf)
24
#define GREENVAL(_c)   (GX_UBYTE)(((_c) >> 4) & 0xf)
25
#define BLUEVAL(_c)    (GX_UBYTE)(((_c)) & 0xf)
26
27
#define ASSEMBLECOLOR(_a, _r, _g, _b)              \
28
      (USHORT)((((_a) & 0xf) << 12)              | \
29
               (((_r) & 0xf) << 8)               | \
30
               (((_g) & 0xf) << 4)               | \
31
               ((_b) & 0xf))
32
33
#define BYTE_RANGE(_c) _c > 15 ? 15 : _c
34
35
#define GX_SOURCE_CODE
36
37
38
/* Include necessary system files.  */
39
40
#include "gx_api.h"
41
#include "gx_utility.h"
42
#include "gx_system.h"
43
44
/**************************************************************************/
45
/*                                                                        */
46
/*  FUNCTION                                               RELEASE        */
47
/*                                                                        */
48
/*    _gx_utility_4444argb_pixelmap_resize                PORTABLE C      */
49
/*                                                           6.1.7        */
50
/*  AUTHOR                                                                */
51
/*                                                                        */
52
/*    Kenneth Maxwell, Microsoft Corporation                              */
53
/*                                                                        */
54
/*  DESCRIPTION                                                           */
55
/*                                                                        */
56
/*    4444argb pixelmap resize function that handles uncompress,          */
57
/*    with alpha channel.                                                 */
58
/*                                                                        */
59
/*  INPUT                                                                 */
60
/*                                                                        */
61
/*    src                                   The source pixelmap           */
62
/*    destination                           The resized pixelmap to be    */
63
/*                                            returned                    */
64
/*    width                                 New width                     */
65
/*    height                                New height                    */
66
/*                                                                        */
67
/*  OUTPUT                                                                */
68
/*                                                                        */
69
/*    status                                Completion status             */
70
/*                                                                        */
71
/*  CALLS                                                                 */
72
/*                                                                        */
73
/*                                                                        */
74
/*  CALLED BY                                                             */
75
/*                                                                        */
76
/*    GUIX Internal Code                                                  */
77
/*                                                                        */
78
/**************************************************************************/
79
204
UINT _gx_utility_4444argb_pixelmap_resize(GX_PIXELMAP *src, GX_PIXELMAP *destination, INT width, INT height)
80
{
81
USHORT  *get;
82
USHORT  *put;
83
INT      xdiff;
84
INT      ydiff;
85
INT      xradio;
86
INT      yradio;
87
INT      x;
88
INT      y;
89
INT      xx;
90
INT      yy;
91
USHORT   neighbor_pixels[2][2];
92
GX_COLOR alpha[4];
93
GX_COLOR red;
94
GX_COLOR green;
95
GX_COLOR blue;
96
97
    /* Calculate scale ratio and enlarge it by 256 times to keep precision.  */
98
204
    xradio = ((src -> gx_pixelmap_width) << 8) / width;
99
204
    yradio = ((src -> gx_pixelmap_height) << 8) / height;
100
101
    /* Fill property values into destination pixelmap structure. */
102
204
    destination -> gx_pixelmap_flags = src -> gx_pixelmap_flags;
103
204
    destination -> gx_pixelmap_format = src -> gx_pixelmap_format;
104
105
204
    destination -> gx_pixelmap_height = (GX_VALUE)height;
106
204
    destination -> gx_pixelmap_width = (GX_VALUE)width;
107
108
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
109
       overflow cannot occur. */
110
204
    destination -> gx_pixelmap_data_size = (UINT)(height * width) * sizeof(USHORT);
111
112
    /* Allocate memory to load pixelmap data. */
113
204
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
114
115
204
    if (destination -> gx_pixelmap_data == GX_NULL)
116
    {
117
2
        return GX_SYSTEM_MEMORY_ERROR;
118
    }
119
120
202
    put = (USHORT *)destination -> gx_pixelmap_data;
121
122
26379
    for (y = 0; y < height; y++)
123
    {
124
5173247
        for (x = 0; x < width; x++)
125
        {
126
5147070
            xx = (xradio * x) >> 8;
127
5147070
            yy = (yradio * y) >> 8;
128
129
            /* The coordinates of the original source pixel are truncate value,
130
               calucate their distance between the mathematical coordinates. */
131
5147070
            xdiff = (xradio * x) & 0xff;
132
5147070
            ydiff = (yradio * y) & 0xff;
133
134
5147070
            get = (USHORT *)src -> gx_pixelmap_data;
135
5147070
            get += yy * src -> gx_pixelmap_width;
136
5147070
            get += xx;
137
138
5147070
            neighbor_pixels[0][0] = *get;
139
140

5147070
            if ((xx < src -> gx_pixelmap_width - 1) && (yy < src -> gx_pixelmap_height - 1))
141
            {
142
5136490
                neighbor_pixels[0][1] = *(get + 1);
143
5136490
                neighbor_pixels[1][0] = *(get + src -> gx_pixelmap_width);
144
5136490
                neighbor_pixels[1][1] = *(get + src -> gx_pixelmap_width + 1);
145
            }
146
            else
147
            {
148
10580
                if ((xx == src -> gx_pixelmap_width - 1) &&
149
2604
                    (yy == src -> gx_pixelmap_height - 1))
150
                {
151
                    /* Handle right bottom corder pixel.  */
152
4
                    neighbor_pixels[0][1] = neighbor_pixels[0][0];
153
4
                    neighbor_pixels[1][0] = neighbor_pixels[0][0];
154
4
                    neighbor_pixels[1][1] = neighbor_pixels[0][0];
155
                }
156
10576
                else if (xx == src -> gx_pixelmap_width - 1)
157
                {
158
                    /* Handle pixels in right edge.  */
159
2600
                    neighbor_pixels[0][1] = neighbor_pixels[0][0];
160
2600
                    neighbor_pixels[1][0] = *(get + src -> gx_pixelmap_width);
161
2600
                    neighbor_pixels[1][1] = neighbor_pixels[1][0];
162
                }
163
                else
164
                {
165
                    /* Handle pixels in bottom edge.  */
166
7976
                    neighbor_pixels[0][1] = *(get + 1);
167
7976
                    neighbor_pixels[1][0] = neighbor_pixels[0][0];
168
7976
                    neighbor_pixels[1][1] = neighbor_pixels[0][1];
169
                }
170
            }
171
5147070
            alpha[0] = ALPHAVAL(neighbor_pixels[0][0]);
172
5147070
            alpha[1] = ALPHAVAL(neighbor_pixels[0][1]);
173
5147070
            alpha[2] = ALPHAVAL(neighbor_pixels[1][0]);
174
5147070
            alpha[3] = ALPHAVAL(neighbor_pixels[1][1]);
175
176
            /* Calulate pixel values by interpolating 4 neighboring pixels. */
177
5147070
            red = (REDVAL(neighbor_pixels[0][0]) * (alpha[0]) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
178
5147070
                   REDVAL(neighbor_pixels[0][1]) * (alpha[1]) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
179
5147070
                   REDVAL(neighbor_pixels[1][0]) * (alpha[2]) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
180
5147070
                   REDVAL(neighbor_pixels[1][1]) * (alpha[3]) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
181
182
5147070
            green = (GREENVAL(neighbor_pixels[0][0]) * (alpha[0]) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
183
5147070
                     GREENVAL(neighbor_pixels[0][1]) * (alpha[1]) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
184
5147070
                     GREENVAL(neighbor_pixels[1][0]) * (alpha[2]) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
185
5147070
                     GREENVAL(neighbor_pixels[1][1]) * (alpha[3]) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
186
187
5147070
            blue = (BLUEVAL(neighbor_pixels[0][0]) * (alpha[0]) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
188
5147070
                    BLUEVAL(neighbor_pixels[0][1]) * (alpha[1]) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
189
5147070
                    BLUEVAL(neighbor_pixels[1][0]) * (alpha[2]) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
190
5147070
                    BLUEVAL(neighbor_pixels[1][1]) * (alpha[3]) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
191
192
5147070
            alpha[0] = ((alpha[0]) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
193
5147070
                        (alpha[1]) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
194
5147070
                        (alpha[2]) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
195
5147070
                        (alpha[3]) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
196
197
5147070
            if (alpha[0])
198
            {
199
3731634
                red /= alpha[0];
200
3731634
                green /= alpha[0];
201
3731634
                blue /= alpha[0];
202
            }
203
204
5147070
            alpha[0] = BYTE_RANGE(alpha[0]);
205
5147070
            red = BYTE_RANGE(red);
206
5147070
            green = BYTE_RANGE(green);
207
5147070
            blue = BYTE_RANGE(blue);
208
209
5147070
            *put++ = ASSEMBLECOLOR(alpha[0], red, green, blue);
210
        }
211
    }
212
213
202
    return GX_SUCCESS;
214
}
215