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

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