GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_utility_4bpp_pixelmap_resize.c Lines: 103 103 100.0 %
Date: 2024-12-05 08:52:37 Branches: 28 28 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
#define GX_SOURCE_CODE
21
22
23
/* Include necessary system files.  */
24
25
#include "gx_api.h"
26
#include "gx_utility.h"
27
#include "gx_system.h"
28
29
/**************************************************************************/
30
/*                                                                        */
31
/*  FUNCTION                                               RELEASE        */
32
/*                                                                        */
33
/*    _gx_utility_4bpp_pixelmap_raw_resize                PORTABLE C      */
34
/*                                                           6.1.7        */
35
/*  AUTHOR                                                                */
36
/*                                                                        */
37
/*    Kenneth Maxwell, Microsoft Corporation                              */
38
/*                                                                        */
39
/*  DESCRIPTION                                                           */
40
/*                                                                        */
41
/*    4bpp pixelmap resize function that handles uncompress, with or      */
42
/*    transparent channel.                                                */
43
/*                                                                        */
44
/*  INPUT                                                                 */
45
/*                                                                        */
46
/*    src                                   The source pixelmap           */
47
/*    destination                           The resized pixelmap to be    */
48
/*                                            returned                    */
49
/*    width                                 New width                     */
50
/*    height                                New height                    */
51
/*                                                                        */
52
/*  OUTPUT                                                                */
53
/*                                                                        */
54
/*    status                                Completion status             */
55
/*                                                                        */
56
/*  CALLS                                                                 */
57
/*                                                                        */
58
/*    _gx_system_memory_allocator           Memory Allocation routine     */
59
/*                                                                        */
60
/*  CALLED BY                                                             */
61
/*                                                                        */
62
/*    _gx_utility_4bpp_pixelmap_resize                                    */
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
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
72
/*                                            removed unused variable     */
73
/*                                            assignment,                 */
74
/*                                            resulting in version 6.1.7  */
75
/*                                                                        */
76
/**************************************************************************/
77
103
static UINT _gx_utility_4bpp_pixelmap_raw_resize(GX_PIXELMAP *src, GX_PIXELMAP *destination, INT width, INT height)
78
{
79
/* The pixelmap resize function is implemented from nearest neighbor
80
   image scaling algorithm.  */
81
82
GX_UBYTE *get;
83
GX_UBYTE *put;
84
GX_UBYTE *putrow;
85
GX_UBYTE  putmask;
86
INT       putstride;
87
INT       getstride;
88
GX_UBYTE  pixel;
89
INT       xradio;
90
INT       yradio;
91
INT       x;
92
INT       y;
93
INT       xx;
94
INT       yy;
95
96
    /* Calculate scale ratio and enlarge it by 256 times to keep precision.  */
97
103
    xradio = ((src -> gx_pixelmap_width) << 8) / width;
98
103
    yradio = ((src -> gx_pixelmap_height) << 8) / height;
99
100
103
    putstride = (width + 1) >> 1;
101
103
    getstride = (src -> gx_pixelmap_width + 1) >> 1;
102
103
    /* Fill property values into destination pixelmap structure. */
104
103
    destination -> gx_pixelmap_flags = src -> gx_pixelmap_flags;
105
103
    destination -> gx_pixelmap_format = src -> gx_pixelmap_format;
106
103
    destination -> gx_pixelmap_transparent_color = src -> gx_pixelmap_transparent_color;
107
103
    destination -> gx_pixelmap_version_major = src -> gx_pixelmap_version_major;
108
103
    destination -> gx_pixelmap_version_minor = src -> gx_pixelmap_version_minor;
109
110
103
    destination -> gx_pixelmap_height = (GX_VALUE)height;
111
103
    destination -> gx_pixelmap_width = (GX_VALUE)width;
112
113
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
114
       overflow cannot occur. */
115
103
    destination -> gx_pixelmap_data_size = (UINT)(height * putstride) * sizeof(GX_UBYTE);
116
117
    /* Allocate memory to load pixelmap data. */
118
103
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
119
120
103
    if (destination -> gx_pixelmap_data == GX_NULL)
121
    {
122
2
        return GX_SYSTEM_MEMORY_ERROR;
123
    }
124
125
101
    putrow = (GX_UBYTE *)destination -> gx_pixelmap_data;
126
127
    /* Loop through destination's pixel and fill each pixel with the nearest neighbor.  */
128
12220
    for (y = 0; y < height; y++)
129
    {
130
12119
        put = putrow;
131
12119
        putmask = 0xf0;
132
2800199
        for (x = 0; x < width; x++)
133
        {
134
2788080
            xx = (xradio * x) >> 8;
135
2788080
            yy = (yradio * y) >> 8;
136
137
2788080
            get = (GX_UBYTE *)src -> gx_pixelmap_data;
138
2788080
            get += yy * getstride;
139
2788080
            get += xx >> 1;
140
2788080
            if (xx & 1)
141
            {
142
1325484
                pixel = *get & 0x0f;
143
            }
144
            else
145
            {
146
1462596
                pixel = *get >> 4;
147
            }
148
2788080
            pixel |= (GX_UBYTE)(pixel << 4);
149
150
2788080
            *put &= (GX_UBYTE)(~putmask);
151
2788080
            *put |= putmask & pixel;
152
153
2788080
            putmask >>= 4;
154
2788080
            if (putmask == 0)
155
            {
156
1394040
                put++;
157
1394040
                putmask = 0xf0;
158
            }
159
        }
160
12119
        putrow += putstride;
161
    }
162
163
101
    return GX_SUCCESS;
164
}
165
/**************************************************************************/
166
/*                                                                        */
167
/*  FUNCTION                                               RELEASE        */
168
/*                                                                        */
169
/*    _gx_utility_4bpp_pixelmap_transparent_resize        PORTABLE C      */
170
/*                                                           6.1          */
171
/*  AUTHOR                                                                */
172
/*                                                                        */
173
/*    Kenneth Maxwell, Microsoft Corporation                              */
174
/*                                                                        */
175
/*  DESCRIPTION                                                           */
176
/*                                                                        */
177
/*    4bpp pixelmap resize function that handles uncompress, with or      */
178
/*    transparent channel.                                                */
179
/*                                                                        */
180
/*  INPUT                                                                 */
181
/*                                                                        */
182
/*    src                                   The source pixelmap           */
183
/*    destination                           The resized pixelmap to be    */
184
/*                                            returned                    */
185
/*    width                                 New width                     */
186
/*    height                                New height                    */
187
/*                                                                        */
188
/*  OUTPUT                                                                */
189
/*                                                                        */
190
/*    status                                Completion status             */
191
/*                                                                        */
192
/*  CALLS                                                                 */
193
/*                                                                        */
194
/*    _gx_system_memory_allocator           Memory Allocation routine     */
195
/*                                                                        */
196
/*  CALLED BY                                                             */
197
/*                                                                        */
198
/*    GUIX Internal Code                                                  */
199
/*                                                                        */
200
/*  RELEASE HISTORY                                                       */
201
/*                                                                        */
202
/*    DATE              NAME                      DESCRIPTION             */
203
/*                                                                        */
204
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
205
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
206
/*                                            resulting in version 6.1    */
207
/*                                                                        */
208
/**************************************************************************/
209
339
static UINT _gx_utility_4bpp_pixelmap_transparent_resize(GX_PIXELMAP *src, GX_PIXELMAP *destination, INT width, INT height)
210
{
211
/* The pixelmap resize function is implemented from nearest neighbor
212
   image scaling algorithm.  */
213
GX_UBYTE *get;
214
GX_UBYTE *getaux;
215
GX_UBYTE *put;
216
GX_UBYTE *putrow;
217
GX_UBYTE *putaux;
218
GX_UBYTE *putauxrow;
219
GX_UBYTE  putmask;
220
INT       putstride;
221
INT       putauxstride;
222
INT       getstride;
223
INT       getauxstride;
224
GX_UBYTE  transmask;
225
GX_UBYTE  putauxmask;
226
GX_UBYTE  pixel;
227
INT       xradio;
228
INT       yradio;
229
INT       x;
230
INT       y;
231
INT       xx;
232
INT       yy;
233
234
    /* Calculate scale ratio and enlarge it by 256 times to keep precision.  */
235
339
    xradio = ((src -> gx_pixelmap_width) << 8) / width;
236
339
    yradio = ((src -> gx_pixelmap_height) << 8) / height;
237
238
339
    putstride = (width + 1) >> 1;
239
339
    putauxstride = (width + 7) >> 3;
240
339
    getstride = (src -> gx_pixelmap_width + 1) >> 1;
241
339
    getauxstride = (src -> gx_pixelmap_width + 7) >> 3;
242
243
    /* Fill property values into destination pixelmap structure. */
244
339
    destination -> gx_pixelmap_flags = src -> gx_pixelmap_flags;
245
339
    destination -> gx_pixelmap_format = src -> gx_pixelmap_format;
246
339
    destination -> gx_pixelmap_transparent_color = src -> gx_pixelmap_transparent_color;
247
339
    destination -> gx_pixelmap_version_major = src -> gx_pixelmap_version_major;
248
339
    destination -> gx_pixelmap_version_minor = src -> gx_pixelmap_version_minor;
249
250
339
    destination -> gx_pixelmap_height = (GX_VALUE)height;
251
339
    destination -> gx_pixelmap_width = (GX_VALUE)width;
252
253
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
254
       overflow cannot occur. */
255
339
    destination -> gx_pixelmap_data_size = (UINT)(height * putstride) * sizeof(GX_UBYTE);
256
257
    /* Allocate memory to load pixelmap data. */
258
339
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
259
260
339
    if (destination -> gx_pixelmap_data == GX_NULL)
261
    {
262
3
        return GX_SYSTEM_MEMORY_ERROR;
263
    }
264
265
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
266
       overflow cannot occur. */
267
336
    destination -> gx_pixelmap_aux_data_size = (UINT)(height * putauxstride) * sizeof(GX_UBYTE);
268
336
    destination -> gx_pixelmap_aux_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_aux_data_size);
269
270
336
    if (destination -> gx_pixelmap_aux_data == GX_NULL)
271
    {
272
3
        _gx_system_memory_free((void *)destination -> gx_pixelmap_data);
273
3
        return GX_SYSTEM_MEMORY_ERROR;
274
    }
275
276
333
    putrow = (GX_UBYTE *)destination -> gx_pixelmap_data;
277
333
    putauxrow = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
278
279
    /* Loop through destination's pixel and fill each pixel with the nearest neighbor.  */
280
75616
    for (y = 0; y < height; y++)
281
    {
282
75283
        put = putrow;
283
75283
        putaux = putauxrow;
284
75283
        putmask = 0xf0;
285
75283
        putauxmask = 0x80;
286
14331263
        for (x = 0; x < width; x++)
287
        {
288
14255980
            xx = (xradio * x) >> 8;
289
14255980
            yy = (yradio * y) >> 8;
290
291
            /* set bits first. */
292
14255980
            *put &= (GX_UBYTE)(~putmask);
293
14255980
            getaux = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
294
14255980
            getaux += yy * getauxstride;
295
14255980
            getaux += xx >> 3;
296
297
14255980
            transmask = (GX_UBYTE)(0x80 >> (xx & 0x07));
298
14255980
            if (transmask & (*getaux))
299
            {
300
                /* set tranparent aux bit first. */
301
5022450
                *putaux |= putauxmask;
302
            }
303
            else
304
            {
305
9233530
                *putaux &= (GX_UBYTE)(~putauxmask);
306
307
                /* get pixel data */
308
9233530
                get = (GX_UBYTE *)src -> gx_pixelmap_data;
309
9233530
                get += yy * getstride;
310
9233530
                get += xx >> 1;
311
9233530
                if (xx & 1)
312
                {
313
4587633
                    pixel = *get & 0x0f;
314
                }
315
                else
316
                {
317
4645897
                    pixel = *get >> 4;
318
                }
319
9233530
                pixel |= (GX_UBYTE)(pixel << 4);
320
9233530
                *put |= putmask & pixel;
321
            }
322
14255980
            putauxmask >>= 1;
323
14255980
            if (putauxmask == 0)
324
            {
325
1761169
                putauxmask = 0x80;
326
1761169
                putaux++;
327
            }
328
329
14255980
            putmask >>= 4;
330
14255980
            if (putmask == 0)
331
            {
332
7127831
                put++;
333
7127831
                putmask = 0xf0;
334
            }
335
        }
336
75283
        putrow += putstride;
337
75283
        putauxrow += putauxstride;
338
    }
339
340
333
    return GX_SUCCESS;
341
}
342
/**************************************************************************/
343
/*                                                                        */
344
/*  FUNCTION                                               RELEASE        */
345
/*                                                                        */
346
/*    _gx_utility_4bpp_pixelmap_resize                    PORTABLE C      */
347
/*                                                           6.1          */
348
/*  AUTHOR                                                                */
349
/*                                                                        */
350
/*    Kenneth Maxwell, Microsoft Corporation                              */
351
/*                                                                        */
352
/*  DESCRIPTION                                                           */
353
/*                                                                        */
354
/*    4bpp pixelmap resize function that handles uncompress, with or      */
355
/*    without transparent channel.                                        */
356
/*                                                                        */
357
/*  INPUT                                                                 */
358
/*                                                                        */
359
/*    src                                   The source pixelmap           */
360
/*    destination                           The resized pixelmap to be    */
361
/*                                            returned                    */
362
/*    width                                 New width                     */
363
/*    height                                New height                    */
364
/*                                                                        */
365
/*  OUTPUT                                                                */
366
/*                                                                        */
367
/*    status                                Completion status             */
368
/*                                                                        */
369
/*  CALLS                                                                 */
370
/*                                                                        */
371
/*    _gx_utility_4bpp_pixelmap_transparent_resize                        */
372
/*                                          Real pixelmap resize routine  */
373
/*    _gx_utility_4bpp_pixelmap_raw_resize  Real pixelmap resize routine  */
374
/*                                                                        */
375
/*  CALLED BY                                                             */
376
/*                                                                        */
377
/*    GUIX Internal Code                                                  */
378
/*                                                                        */
379
/*  RELEASE HISTORY                                                       */
380
/*                                                                        */
381
/*    DATE              NAME                      DESCRIPTION             */
382
/*                                                                        */
383
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
384
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
385
/*                                            resulting in version 6.1    */
386
/*                                                                        */
387
/**************************************************************************/
388
442
UINT _gx_utility_4bpp_pixelmap_resize(GX_PIXELMAP *src, GX_PIXELMAP *destination, INT width, INT height)
389
{
390
UINT status;
391
392
442
    if (src -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
393
    {
394
        /* transparent, no compression */
395
339
        status = _gx_utility_4bpp_pixelmap_transparent_resize(src, destination, width, height);
396
    }
397
    else
398
    {
399
        /* no compression or alpha */
400
103
        status = _gx_utility_4bpp_pixelmap_raw_resize(src, destination, width, height);
401
    }
402
403
442
    return status;
404
}
405