GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_utility_8bpp_pixelmap_resize.c Lines: 161 161 100.0 %
Date: 2024-12-05 08:52:37 Branches: 44 44 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
#define REDVAL_332(_c)   (((_c) >> 5) & 0x07)
30
#define GREENVAL_332(_c) (((_c) >> 2) & 0x07)
31
#define BLUEVAL_332(_c)  ((_c) & 0x03)
32
33
#define ASSEMBLECOLOR_332(_r, _g, _b)        \
34
    ((((_r) & 0x07) << 5)                  | \
35
     (((_g) & 0x07) << 2)                  | \
36
     ((_b) & 0x03))
37
38
39
/**************************************************************************/
40
/*                                                                        */
41
/*  FUNCTION                                               RELEASE        */
42
/*                                                                        */
43
/*    _gx_utility_8bpp_pixelmap_raw_resize                PORTABLE C      */
44
/*                                                           6.1.7        */
45
/*  AUTHOR                                                                */
46
/*                                                                        */
47
/*    Kenneth Maxwell, Microsoft Corporation                              */
48
/*                                                                        */
49
/*  DESCRIPTION                                                           */
50
/*                                                                        */
51
/*    Internal helper function that resize 8bpp format uncompressed       */
52
/*    pixelmap with or without transparent channel.                       */
53
/*                                                                        */
54
/*  INPUT                                                                 */
55
/*                                                                        */
56
/*    src                                   The source pixelmap           */
57
/*    destination                           The resized pixelmap to be    */
58
/*                                            returned                    */
59
/*    width                                 New width                     */
60
/*    height                                New height                    */
61
/*                                                                        */
62
/*  OUTPUT                                                                */
63
/*                                                                        */
64
/*    status                                Completion status             */
65
/*                                                                        */
66
/*  CALLS                                                                 */
67
/*                                                                        */
68
/*    _gx_system_memory_allocator           Application defined memory    */
69
/*                                            allocation function         */
70
/*                                                                        */
71
/*  CALLED BY                                                             */
72
/*                                                                        */
73
/*    GUIX Internal Code                                                  */
74
/*                                                                        */
75
/*  RELEASE HISTORY                                                       */
76
/*                                                                        */
77
/*    DATE              NAME                      DESCRIPTION             */
78
/*                                                                        */
79
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
80
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
81
/*                                            resulting in version 6.1    */
82
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
83
/*                                            removed unused variable     */
84
/*                                            assignment,                 */
85
/*                                            resulting in version 6.1.7  */
86
/*                                                                        */
87
/**************************************************************************/
88
539
static UINT _gx_utility_8bpp_pixelmap_raw_resize(GX_PIXELMAP *src, GX_PIXELMAP *destination, INT width, INT height)
89
{
90
/* The pixelmap resize function is implemented from nearest neighbor
91
   image scaling algorithm.  */
92
93
GX_UBYTE *get;
94
GX_UBYTE *put;
95
INT       xradio;
96
INT       yradio;
97
INT       x;
98
INT       y;
99
INT       xx;
100
INT       yy;
101
102
    /* Calculate scale ratio and enlarge it by 256 times to keep precision.  */
103
539
    xradio = ((src -> gx_pixelmap_width) << 8) / width;
104
539
    yradio = ((src -> gx_pixelmap_height) << 8) / height;
105
106
    /* Fill property values into destination pixelmap structure. */
107
539
    destination -> gx_pixelmap_flags = src -> gx_pixelmap_flags;
108
539
    destination -> gx_pixelmap_format = src -> gx_pixelmap_format;
109
539
    destination -> gx_pixelmap_transparent_color = src -> gx_pixelmap_transparent_color;
110
539
    destination -> gx_pixelmap_version_major = src -> gx_pixelmap_version_major;
111
539
    destination -> gx_pixelmap_version_minor = src -> gx_pixelmap_version_minor;
112
113
539
    destination -> gx_pixelmap_height = (GX_VALUE)height;
114
539
    destination -> gx_pixelmap_width = (GX_VALUE)width;
115
116
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
117
       overflow cannot occur. */
118
539
    destination -> gx_pixelmap_data_size = (UINT)(height * width) * sizeof(GX_UBYTE);
119
120
    /* Allocate memory to load pixelmap data. */
121
539
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
122
123
539
    if (destination -> gx_pixelmap_data == GX_NULL)
124
    {
125
2
        return GX_SYSTEM_MEMORY_ERROR;
126
    }
127
128
537
    put = (GX_UBYTE *)destination -> gx_pixelmap_data;
129
130
    /* Loop through destination's pixel and fill each pixel with the nearest neighbor.  */
131
100323
    for (y = 0; y < height; y++)
132
    {
133
16008791
        for (x = 0; x < width; x++)
134
        {
135
15909005
            xx = (xradio * x) >> 8;
136
15909005
            yy = (yradio * y) >> 8;
137
138
15909005
            get = (GX_UBYTE *)src -> gx_pixelmap_data;
139
15909005
            get += yy * src -> gx_pixelmap_width;
140
15909005
            get += xx;
141
142
15909005
            *put++ = *get;
143
        }
144
    }
145
146
537
    return GX_SUCCESS;
147
}
148
149
/**************************************************************************/
150
/*                                                                        */
151
/*  FUNCTION                                               RELEASE        */
152
/*                                                                        */
153
/*    _gx_utility_8bpp_pixelmap_alpha_resize              PORTABLE C      */
154
/*                                                           6.1.7        */
155
/*  AUTHOR                                                                */
156
/*                                                                        */
157
/*    Kenneth Maxwell, Microsoft Corporation                              */
158
/*                                                                        */
159
/*  DESCRIPTION                                                           */
160
/*                                                                        */
161
/*    Internal helper function that resize an 8bpp format uncompressed    */
162
/*    pixelmap with transparent channel.                                  */
163
/*                                                                        */
164
/*  INPUT                                                                 */
165
/*                                                                        */
166
/*    src                                   The source pixelmap           */
167
/*    destination                           The resized pixelmap to be    */
168
/*                                            returned                    */
169
/*    width                                 New width                     */
170
/*    height                                New height                    */
171
/*                                                                        */
172
/*  OUTPUT                                                                */
173
/*                                                                        */
174
/*    status                                Completion status             */
175
/*                                                                        */
176
/*  CALLS                                                                 */
177
/*                                                                        */
178
/*    _gx_system_memory_allocator           Application defined memory    */
179
/*                                            allocation function         */
180
/*                                                                        */
181
/*  CALLED BY                                                             */
182
/*                                                                        */
183
/*    GUIX Internal Code                                                  */
184
/*                                                                        */
185
/*  RELEASE HISTORY                                                       */
186
/*                                                                        */
187
/*    DATE              NAME                      DESCRIPTION             */
188
/*                                                                        */
189
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
190
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
191
/*                                            resulting in version 6.1    */
192
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
193
/*                                            removed unused variable     */
194
/*                                            assignment,                 */
195
/*                                            resulting in version 6.1.7  */
196
/*                                                                        */
197
/**************************************************************************/
198
108
static UINT _gx_utility_8bpp_pixelmap_alpha_resize(GX_PIXELMAP *src, GX_PIXELMAP *destination, INT width, INT height)
199
{
200
/* The pixelmap resize function is implemented from bilinear interpolation
201
   image scaling algorithm.  */
202
GX_UBYTE *get;
203
GX_UBYTE *put;
204
GX_UBYTE *getalpha;
205
GX_UBYTE *putalpha;
206
INT       xdiff;
207
INT       ydiff;
208
INT       xradio;
209
INT       yradio;
210
INT       x;
211
INT       y;
212
INT       xx;
213
INT       yy;
214
GX_UBYTE  neighbor_pixels[2][2];
215
GX_COLOR  alpha[4];
216
GX_COLOR  red;
217
GX_COLOR  green;
218
GX_COLOR  blue;
219
220
    /* Calculate scale ratio and enlarge it by 256 times to keep precision.  */
221
108
    xradio = ((src -> gx_pixelmap_width) << 8) / width;
222
108
    yradio = ((src -> gx_pixelmap_height) << 8) / height;
223
224
    /* Fill property values into destination pixelmap structure. */
225
108
    destination -> gx_pixelmap_flags = src -> gx_pixelmap_flags;
226
108
    destination -> gx_pixelmap_format = src -> gx_pixelmap_format;
227
228
108
    destination -> gx_pixelmap_height = (GX_VALUE)height;
229
108
    destination -> gx_pixelmap_width = (GX_VALUE)width;
230
231
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
232
       overflow cannot occur. */
233
108
    destination -> gx_pixelmap_data_size = (UINT)(height * width) * sizeof(GX_UBYTE);
234
235
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
236
       overflow cannot occur. */
237
108
    destination -> gx_pixelmap_aux_data_size = (UINT)(height * width) * sizeof(GX_UBYTE);
238
239
    /* Allocate memory to load pixelmap data. */
240
108
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
241
242
108
    if (destination -> gx_pixelmap_data == GX_NULL)
243
    {
244
1
        return GX_SYSTEM_MEMORY_ERROR;
245
    }
246
247
107
    destination -> gx_pixelmap_aux_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_aux_data_size);
248
249
107
    if (destination -> gx_pixelmap_aux_data == GX_NULL)
250
    {
251
1
        _gx_system_memory_free((void *)destination -> gx_pixelmap_data);
252
1
        return GX_SYSTEM_MEMORY_ERROR;
253
    }
254
255
106
    put = (GX_UBYTE *)destination -> gx_pixelmap_data;
256
106
    putalpha = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
257
258
    /* Loop through destination's pixel and fill each pixel with
259
       the interpolation of 4 nearest neighboring pixels.*/
260
15309
    for (y = 0; y < height; y++)
261
    {
262
2648183
        for (x = 0; x < width; x++)
263
        {
264
            /* Find the original source pixel that the destination pixel conrespond to. */
265
2632980
            xx = (xradio * x) >> 8;
266
2632980
            yy = (yradio * y) >> 8;
267
268
            /* The coordinates of the original source pixel are truncate value,
269
               calucate their distance between the mathematical coordinates. */
270
2632980
            xdiff = (xradio * x) & 0xff;
271
2632980
            ydiff = (yradio * y) & 0xff;
272
273
2632980
            get = (GX_UBYTE *)src -> gx_pixelmap_data;
274
2632980
            get += yy * src -> gx_pixelmap_width;
275
2632980
            get += xx;
276
277
2632980
            getalpha = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
278
2632980
            getalpha += yy * src -> gx_pixelmap_width;
279
2632980
            getalpha += xx;
280
281
282
            /* Calculate 4 nearest neighboring pixels around the mathematical point of original pixel. */
283
2632980
            neighbor_pixels[0][0] = *get;
284
2632980
            alpha[0] = *getalpha;
285
286

2632980
            if ((xx < src -> gx_pixelmap_width - 1) && (yy < src -> gx_pixelmap_height - 1))
287
            {
288
2626839
                neighbor_pixels[0][1] = *(get + 1);
289
2626839
                neighbor_pixels[1][0] = *(get + src -> gx_pixelmap_width);
290
2626839
                neighbor_pixels[1][1] = *(get + src -> gx_pixelmap_width + 1);
291
292
2626839
                alpha[1] = *(getalpha + 1);
293
2626839
                alpha[2] = *(getalpha + src -> gx_pixelmap_width);
294
2626839
                alpha[3] = *(getalpha + src -> gx_pixelmap_width + 1);
295
            }
296
            else
297
            {
298
299
6141
                if ((xx == src -> gx_pixelmap_width - 1) &&
300
2007
                    (yy == src -> gx_pixelmap_height - 1))
301
                {
302
                    /* Handle right bottom corder pixel.  */
303
6
                    neighbor_pixels[0][1] = neighbor_pixels[0][0];
304
6
                    neighbor_pixels[1][0] = neighbor_pixels[0][0];
305
6
                    neighbor_pixels[1][1] = neighbor_pixels[0][0];
306
307
6
                    alpha[1] = alpha[0];
308
6
                    alpha[2] = alpha[0];
309
6
                    alpha[3] = alpha[0];
310
                }
311
6135
                else if (xx == src -> gx_pixelmap_width - 1)
312
                {
313
                    /* Handle pixels in right edge.  */
314
2001
                    neighbor_pixels[0][1] = neighbor_pixels[0][0];
315
2001
                    neighbor_pixels[1][0] = *(get + src -> gx_pixelmap_width);
316
2001
                    neighbor_pixels[1][1] = neighbor_pixels[1][0];
317
318
2001
                    alpha[1] = alpha[0];
319
2001
                    alpha[2] = *(getalpha + src -> gx_pixelmap_width);
320
2001
                    alpha[3] = alpha[2];
321
                }
322
                else
323
                {
324
                    /* Handle pixels in bottom edge.  */
325
4134
                    neighbor_pixels[0][1] = *(get + 1);
326
4134
                    neighbor_pixels[1][0] = neighbor_pixels[0][0];
327
4134
                    neighbor_pixels[1][1] = neighbor_pixels[0][1];
328
329
4134
                    alpha[1] = *(getalpha + 1);
330
4134
                    alpha[2] = alpha[0];
331
4134
                    alpha[3] = alpha[1];
332
                }
333
            }
334
335
            /* Calulate pixel values by interpolating 4 neighboring pixels. */
336
2632980
            red = (REDVAL_332(neighbor_pixels[0][0]) * (alpha[0]) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
337
2632980
                   REDVAL_332(neighbor_pixels[0][1]) * (alpha[1]) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
338
2632980
                   REDVAL_332(neighbor_pixels[1][0]) * (alpha[2]) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
339
2632980
                   REDVAL_332(neighbor_pixels[1][1]) * (alpha[3]) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
340
341
2632980
            green = (GREENVAL_332(neighbor_pixels[0][0]) * (alpha[0]) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
342
2632980
                     GREENVAL_332(neighbor_pixels[0][1]) * (alpha[1]) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
343
2632980
                     GREENVAL_332(neighbor_pixels[1][0]) * (alpha[2]) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
344
2632980
                     GREENVAL_332(neighbor_pixels[1][1]) * (alpha[3]) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
345
346
2632980
            blue = (BLUEVAL_332(neighbor_pixels[0][0]) * (alpha[0]) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
347
2632980
                    BLUEVAL_332(neighbor_pixels[0][1]) * (alpha[1]) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
348
2632980
                    BLUEVAL_332(neighbor_pixels[1][0]) * (alpha[2]) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
349
2632980
                    BLUEVAL_332(neighbor_pixels[1][1]) * (alpha[3]) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
350
351
2632980
            alpha[0] = ((alpha[0]) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
352
2632980
                        (alpha[1]) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
353
2632980
                        (alpha[2]) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
354
2632980
                        (alpha[3]) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
355
356
2632980
            if (alpha[0])
357
            {
358
1161470
                red /= alpha[0];
359
1161470
                green /= alpha[0];
360
1161470
                blue /= alpha[0];
361
            }
362
363
2632980
            alpha[0] = alpha[0] > 255 ? 255 : alpha[0];
364
2632980
            red = red > 7 ? 7 : red;
365
2632980
            green = green > 7 ? 7 : green;
366
2632980
            blue = blue > 3 ? 3 : blue;
367
368
2632980
            *put++ = (GX_UBYTE)ASSEMBLECOLOR_332(red, green, blue);
369
2632980
            *putalpha++ = (GX_UBYTE)alpha[0];
370
        }
371
    }
372
373
106
    return GX_SUCCESS;
374
}
375
/**************************************************************************/
376
/*                                                                        */
377
/*  FUNCTION                                               RELEASE        */
378
/*                                                                        */
379
/*    _gx_utility_8bpp_pixelmap_resize                    PORTABLE C      */
380
/*                                                           6.1          */
381
/*  AUTHOR                                                                */
382
/*                                                                        */
383
/*    Kenneth Maxwell, Microsoft Corporation                              */
384
/*                                                                        */
385
/*  DESCRIPTION                                                           */
386
/*                                                                        */
387
/*    This function resize an 8bpp format uncompressed pixelmap with or   */
388
/*    without transparent channel.                                        */
389
/*                                                                        */
390
/*  INPUT                                                                 */
391
/*                                                                        */
392
/*    src                                   The source pixelmap           */
393
/*    destination                           The resized pixelmap to be    */
394
/*                                            returned                    */
395
/*    width                                 New width                     */
396
/*    height                                New height                    */
397
/*                                                                        */
398
/*  OUTPUT                                                                */
399
/*                                                                        */
400
/*    status                                Completion status             */
401
/*                                                                        */
402
/*  CALLS                                                                 */
403
/*                                                                        */
404
/*     _gx_system_memory_allocator          Application defined memory    */
405
/*                                            allocation function         */
406
/*                                                                        */
407
/*  CALLED BY                                                             */
408
/*                                                                        */
409
/*    GUIX Internal Code                                                  */
410
/*                                                                        */
411
/*  RELEASE HISTORY                                                       */
412
/*                                                                        */
413
/*    DATE              NAME                      DESCRIPTION             */
414
/*                                                                        */
415
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
416
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
417
/*                                            resulting in version 6.1    */
418
/*                                                                        */
419
/**************************************************************************/
420
647
UINT _gx_utility_8bpp_pixelmap_resize(GX_PIXELMAP *src, GX_PIXELMAP *destination, INT width, INT height)
421
{
422
UINT status;
423
424
647
    if (src -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
425
    {
426
        /* alpha, no compression */
427
108
        status = _gx_utility_8bpp_pixelmap_alpha_resize(src, destination, width, height);
428
    }
429
    else
430
    {
431
        /* no compression or transparent channel */
432
539
        status = _gx_utility_8bpp_pixelmap_raw_resize(src, destination, width, height);
433
    }
434
435
647
    return status;
436
}
437
438
/**************************************************************************/
439
/*                                                                        */
440
/*  FUNCTION                                               RELEASE        */
441
/*                                                                        */
442
/*    _gx_utility_8bit_alphamap_resize                    PORTABLE C      */
443
/*                                                           6.1.7        */
444
/*  AUTHOR                                                                */
445
/*                                                                        */
446
/*    Kenneth Maxwell, Microsoft Corporation                              */
447
/*                                                                        */
448
/*  DESCRIPTION                                                           */
449
/*                                                                        */
450
/*    This function resize an 8bit uncompressed alphamap.                 */
451
/*                                                                        */
452
/*  INPUT                                                                 */
453
/*                                                                        */
454
/*    src                                   The source pixelmap           */
455
/*    destination                           The resized pixelmap to be    */
456
/*                                            returned                    */
457
/*    width                                 New width                     */
458
/*    height                                New height                    */
459
/*                                                                        */
460
/*  OUTPUT                                                                */
461
/*                                                                        */
462
/*    status                                Completion status             */
463
/*                                                                        */
464
/*  CALLS                                                                 */
465
/*                                                                        */
466
/*    _gx_system_memory_allocator           Application defined memory    */
467
/*                                            allocation function         */
468
/*                                                                        */
469
/*  CALLED BY                                                             */
470
/*                                                                        */
471
/*    GUIX Internal Code                                                  */
472
/*                                                                        */
473
/*  RELEASE HISTORY                                                       */
474
/*                                                                        */
475
/*    DATE              NAME                      DESCRIPTION             */
476
/*                                                                        */
477
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
478
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
479
/*                                            resulting in version 6.1    */
480
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
481
/*                                            removed unused variable     */
482
/*                                            assignment,                 */
483
/*                                            resulting in version 6.1.7  */
484
/*                                                                        */
485
/**************************************************************************/
486
3885
UINT _gx_utility_8bit_alphamap_resize(GX_PIXELMAP *src, GX_PIXELMAP *destination, INT width, INT height)
487
{
488
/* The pixelmap resize function is implemented from bilinear interpolation
489
   image scaling algorithm.  */
490
491
GX_UBYTE *get;
492
GX_UBYTE *put;
493
INT       xdiff;
494
INT       ydiff;
495
INT       xradio;
496
INT       yradio;
497
INT       x;
498
INT       y;
499
INT       xx;
500
INT       yy;
501
3885
GX_UBYTE  neighbor_pixels[2][2] = {{0, 0}, {0, 0}};
502
INT       alpha;
503
504
    /* Calculate scale ratio and enlarge it by 256 times to keep precision.  */
505
3885
    xradio = ((src -> gx_pixelmap_width) << 8) / width;
506
3885
    yradio = ((src -> gx_pixelmap_height) << 8) / height;
507
508
    /* Fill property values into destination pixelmap structure. */
509
3885
    destination -> gx_pixelmap_flags = src -> gx_pixelmap_flags;
510
3885
    destination -> gx_pixelmap_format = src -> gx_pixelmap_format;
511
512
3885
    destination -> gx_pixelmap_height = (GX_VALUE)height;
513
3885
    destination -> gx_pixelmap_width = (GX_VALUE)width;
514
515
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
516
       overflow cannot occur. */
517
3885
    destination -> gx_pixelmap_data_size = (UINT)(height * width) * sizeof(GX_COLOR);
518
519
    /* Allocate memory to load pixelmap data. */
520
3885
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
521
522
3885
    if (destination -> gx_pixelmap_data == GX_NULL)
523
    {
524
2
        return GX_SYSTEM_MEMORY_ERROR;
525
    }
526
527
3883
    put = (GX_UBYTE *)destination -> gx_pixelmap_data;
528
529
    /* Loop through destination's pixel and fill each pixel with
530
       the interpolation of 4 nearest neighboring pixels.*/
531
91320
    for (y = 0; y < height; y++)
532
    {
533
4805866
        for (x = 0; x < width; x++)
534
        {
535
            /* Find the original source pixel that the destination pixel conrespond to. */
536
4718429
            xx = (xradio * x) >> 8;
537
4718429
            yy = (yradio * y) >> 8;
538
539
            /* The coordinates of the original source pixel are truncate value,
540
               calucate their distance between the mathematical coordinates. */
541
4718429
            xdiff = xradio * x - (xx << 8);
542
4718429
            ydiff = yradio * y - (yy << 8);
543
544
4718429
            get = (GX_UBYTE *)src -> gx_pixelmap_data;
545
4718429
            get += yy * src -> gx_pixelmap_width;
546
4718429
            get += xx;
547
548
            /* Calculate 4 nearest neighboring pixels around the mathematical point of original pixel. */
549
4718429
            neighbor_pixels[0][0] = *get;
550
551

4718429
            if ((xx < src -> gx_pixelmap_width - 1) && (yy < src -> gx_pixelmap_height - 1))
552
            {
553
4691188
                neighbor_pixels[0][1] = *(get + 1);
554
4691188
                neighbor_pixels[1][0] = *(get + src -> gx_pixelmap_width);
555
4691188
                neighbor_pixels[1][1] = *(get + src -> gx_pixelmap_width + 1);
556
            }
557
            else
558
            {
559
560
27241
                if ((xx == src -> gx_pixelmap_width - 1) &&
561
9197
                    (yy == src -> gx_pixelmap_height - 1))
562
                {
563
                    /* Hanle pixels in right bottom corner. */
564
36
                    neighbor_pixels[0][1] = neighbor_pixels[0][0];
565
36
                    neighbor_pixels[1][0] = neighbor_pixels[0][0];
566
36
                    neighbor_pixels[1][1] = neighbor_pixels[0][0];
567
                }
568
27205
                else if (xx == src -> gx_pixelmap_width - 1)
569
                {
570
                    /* Handle pixels in right edge. */
571
9161
                    neighbor_pixels[0][1] = neighbor_pixels[0][0];
572
9161
                    neighbor_pixels[1][0] = *(get + src -> gx_pixelmap_width);
573
9161
                    neighbor_pixels[1][1] = neighbor_pixels[1][0];
574
                }
575
                else
576
                {
577
                    /* Handle pixels in bottom edge.  */
578
18044
                    neighbor_pixels[0][1] = *(get + 1);
579
18044
                    neighbor_pixels[1][0] = neighbor_pixels[0][0];
580
18044
                    neighbor_pixels[1][1] = neighbor_pixels[0][1];
581
                }
582
            }
583
584
            /* Calulate alpha values by interpolating 4 neighboring pixels. */
585
4718429
            alpha = (INT)(((neighbor_pixels[0][0]) * (256 - (ULONG)xdiff) * (256 - (ULONG)ydiff) + \
586
4718429
                           (neighbor_pixels[0][1]) * (ULONG)xdiff * (256 - (ULONG)ydiff) +         \
587
4718429
                           (neighbor_pixels[1][0]) * (ULONG)ydiff * (256 - (ULONG)xdiff) +         \
588
4718429
                           (neighbor_pixels[1][1]) * (ULONG)xdiff * (ULONG)ydiff) >> 16);
589
590
4718429
            *put++ = (GX_UBYTE)alpha;
591
        }
592
    }
593
594
3883
    return GX_SUCCESS;
595
}
596