GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_utility_565rgb_pixelmap_rotate.c Lines: 389 389 100.0 %
Date: 2026-03-06 19:21:09 Branches: 164 164 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 REDVAL(_c)   (GX_UBYTE)(((_c) >> 11) & 0x1f)
23
#define GREENVAL(_c) (GX_UBYTE)(((_c) >> 5) & 0x3f)
24
#define BLUEVAL(_c)  (GX_UBYTE)(((_c)) & 0x1f)
25
26
#define ASSEMBLECOLOR(_r, _g, _b)            \
27
    (USHORT)((((_r) & 0x1f) << 11)         | \
28
             (((_g) & 0x3f) << 5)          | \
29
             ((_b) & 0x1f))
30
31
#define GX_SOURCE_CODE
32
33
34
/* Include necessary system files.  */
35
36
#include "gx_api.h"
37
#include "gx_display.h"
38
#include "gx_context.h"
39
#include "gx_utility.h"
40
#include "gx_system.h"
41
42
/**************************************************************************/
43
/*                                                                        */
44
/*  FUNCTION                                               RELEASE        */
45
/*                                                                        */
46
/*    _gx_utility_565rgb_pixelmap_raw_rotate              PORTABLE C      */
47
/*                                                           6.1          */
48
/*  AUTHOR                                                                */
49
/*                                                                        */
50
/*    Kenneth Maxwell, Microsoft Corporation                              */
51
/*                                                                        */
52
/*  DESCRIPTION                                                           */
53
/*                                                                        */
54
/*    Internal helper function that rotate an uncompressed pixelmap       */
55
/*    without alpha.                                                      */
56
/*                                                                        */
57
/*  INPUT                                                                 */
58
/*                                                                        */
59
/*    src                                   The pixelmap to be rotated    */
60
/*    angle                                 The angle to be rotated       */
61
/*    destination                           The rotated bitmap to be      */
62
/*                                            returned                    */
63
/*    rot_cx                                X coordinate of rotation      */
64
/*                                            center                      */
65
/*    rot_cy                                Y coordinate of rotation      */
66
/*                                            center                      */
67
/*                                                                        */
68
/*  OUTPUT                                                                */
69
/*                                                                        */
70
/*    status                                Completion status             */
71
/*                                                                        */
72
/*  CALLS                                                                 */
73
/*                                                                        */
74
/*    _gx_system_memory_allocator           Memory Allocation routine     */
75
/*    _gx_utility_math_cos                  Compute the cosine value      */
76
/*    _gx_utility_math_sin                  Compute the sine value        */
77
/*                                                                        */
78
/*  CALLED BY                                                             */
79
/*                                                                        */
80
/*    GUIX Internal Code                                                  */
81
/*                                                                        */
82
/**************************************************************************/
83
1158
static UINT _gx_utility_565rgb_pixelmap_raw_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
84
{
85
USHORT   *put;
86
USHORT   *get;
87
GX_UBYTE *putalpha;
88
INT       srcxres;
89
INT       srcyres;
90
INT       cosv;
91
INT       sinv;
92
USHORT    red, green, blue;
93
INT       idxminx, idxmaxx, idxmaxy;
94
INT      *mx;
95
INT      *my;
96
INT       xres;
97
INT       yres;
98
INT       width, height;
99
INT       x, y;
100
INT       xx, yy;
101
USHORT    a, b, c, d;
102
INT       alpha;
103
INT       xdiff, ydiff;
104
105
1158
    mx = _gx_system_scratchpad;
106
1158
    my = mx + 4;
107
108
1158
    mx[0] = mx[3] = -1;
109
1158
    mx[1] = mx[2] = 1;
110
111
1158
    my[0] = my[1] = 1;
112
1158
    my[2] = my[3] = -1;
113
114
1158
    idxminx = (angle / 90) & 0x3;
115
1158
    idxmaxx = (idxminx + 2) & 0x3;
116
1158
    idxmaxy = (idxminx + 1) & 0x3;
117
118
    /* Calculate the source x and y center. */
119
1158
    srcxres = src -> gx_pixelmap_width >> 1;
120
1158
    srcyres = src -> gx_pixelmap_height >> 1;
121
122
1158
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
123
1158
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
124
125
1158
    xres = mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv;
126
1158
    yres = my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv;
127
128
1158
    xres = GX_FIXED_VAL_TO_INT(xres);
129
1158
    yres = GX_FIXED_VAL_TO_INT(yres);
130
131
    /* Calculate destination width and height. */
132
1158
    width = (xres << 1);
133
1158
    height = (yres << 1);
134
135
    /* Calculate the new rotation axis. */
136

1158
    if (rot_cx && rot_cy)
137
    {
138
1148
        x = ((*rot_cx) - srcxres) * cosv - ((*rot_cy) - srcyres) * sinv;
139
1148
        y = ((*rot_cy) - srcyres) * cosv + ((*rot_cx) - srcxres) * sinv;
140
141
1148
        srcxres = (INT)*rot_cx;
142
1148
        srcyres = (INT)*rot_cy;
143
144
1148
        x = GX_FIXED_VAL_TO_INT(x) + xres;
145
1148
        y = GX_FIXED_VAL_TO_INT(y) + yres;
146
147
1148
        *rot_cx = x;
148
1148
        *rot_cy = y;
149
150
1148
        xres = *rot_cx;
151
1148
        yres = *rot_cy;
152
    }
153
154
1158
    destination -> gx_pixelmap_height = (GX_VALUE)height;
155
1158
    destination -> gx_pixelmap_width  = (GX_VALUE)width;
156
1158
    destination -> gx_pixelmap_flags |= GX_PIXELMAP_ALPHA;
157
158
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
159
       overflow cannot occur. */
160
1158
    destination -> gx_pixelmap_data_size = (UINT)(height * width) * sizeof(USHORT);
161
1158
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
162
163
1158
    if (destination -> gx_pixelmap_data == GX_NULL)
164
    {
165
3
        return GX_SYSTEM_MEMORY_ERROR;
166
    }
167
168
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
169
       overflow cannot occur. */
170
1155
    destination -> gx_pixelmap_aux_data_size = (UINT)(height * width) * sizeof(GX_UBYTE);
171
1155
    destination -> gx_pixelmap_aux_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_aux_data_size);
172
173
1155
    if (destination -> gx_pixelmap_aux_data == GX_NULL)
174
    {
175
1
        _gx_system_memory_free((VOID *)destination -> gx_pixelmap_aux_data);
176
177
1
        return GX_SYSTEM_MEMORY_ERROR;
178
    }
179
180
1154
    put = (USHORT *)destination -> gx_pixelmap_data;
181
1154
    putalpha = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
182
183
    /* Loop through the destination's pixels.  */
184
274926
    for (y = 0; y < height; y++)
185
    {
186
64482308
        for (x = 0; x < width; x++)
187
        {
188
64208536
            xx = (x - xres) * cosv + (y - yres) * sinv;
189
64208536
            yy = (y - yres) * cosv - (x - xres) * sinv;
190
191
64208536
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
192
64208536
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
193
194
64208536
            xx = GX_FIXED_VAL_TO_INT(xx) + srcxres;
195
64208536
            yy = GX_FIXED_VAL_TO_INT(yy) + srcyres;
196
197

64208536
            if ((xx >= -1) && (xx < src -> gx_pixelmap_width) &&
198
41285400
                (yy >= -1) && (yy < src -> gx_pixelmap_height))
199
            {
200

35476776
                if ((xx >= 0) && (xx < src -> gx_pixelmap_width - 1) &&
201
34815902
                    (yy >= 0) && (yy < src -> gx_pixelmap_height - 1))
202
                {
203
34628706
                    get = (USHORT *)src -> gx_pixelmap_data;
204
34628706
                    get += yy * src -> gx_pixelmap_width;
205
34628706
                    get += xx;
206
207
34628706
                    a = *get;
208
34628706
                    b = *(get + 1);
209
34628706
                    c = *(get + src -> gx_pixelmap_width);
210
34628706
                    d = *(get + src -> gx_pixelmap_width + 1);
211
212
34628706
                    alpha = 0xff;
213
                }
214
                else
215
                {
216
848070
                    get = (USHORT *)src -> gx_pixelmap_data;
217
218
848070
                    a = 0;
219
848070
                    b = 0;
220
848070
                    c = 0;
221
848070
                    d = 0;
222
848070
                    alpha = 0;
223
224
848070
                    if (xx == -1)
225
                    {
226
                        /* handle left edge.  */
227
237450
                        if (yy >= 0)
228
                        {
229
236380
                            b = *(get + yy * src -> gx_pixelmap_width);
230
236380
                            alpha += xdiff * (256 - ydiff);
231
                        }
232
233
237450
                        if (yy < src -> gx_pixelmap_height - 1)
234
                        {
235
236290
                            d = *(get + (yy + 1) * src -> gx_pixelmap_width);
236
236290
                            alpha += xdiff * ydiff;
237
                        }
238
                    }
239
610620
                    else if (yy == -1)
240
                    {
241
                        /* handle top edge.  */
242
187296
                        c = *(get + xx);
243
187296
                        alpha += ydiff * (256 - xdiff);
244
245
187296
                        if (xx < src -> gx_pixelmap_width - 1)
246
                        {
247
186134
                            d = *(get + xx + 1);
248
186134
                            alpha += xdiff * ydiff;
249
                        }
250
                    }
251
423324
                    else if (xx == src -> gx_pixelmap_width - 1)
252
                    {
253
                        /* handle right edget. */
254
236128
                        a = *(get + yy * src -> gx_pixelmap_width + xx);
255
236128
                        alpha += (256 - xdiff) * (256 - ydiff);
256
257
236128
                        if (yy < src -> gx_pixelmap_height - 1)
258
                        {
259
234962
                            c = *(get + (yy + 1) * src -> gx_pixelmap_width + xx);
260
234962
                            alpha += ydiff * (256 - xdiff);
261
                        }
262
                    }
263
                    else
264
                    {
265
                        /* handle bottom edge. */
266
187196
                        a = *(get + yy * src -> gx_pixelmap_width + xx);
267
187196
                        alpha += (256 - xdiff) * (256 - ydiff);
268
269
187196
                        b = *(get + yy * src -> gx_pixelmap_width + xx + 1);
270
187196
                        alpha += xdiff * (256 - ydiff);
271
                    }
272
273
848070
                    alpha >>= 8;
274
                }
275
276
35476776
                red = (USHORT)((REDVAL(a) * (256 - xdiff) * (256 - ydiff) + \
277
35476776
                                REDVAL(b) * xdiff * (256 - ydiff) +         \
278
35476776
                                REDVAL(c) * ydiff * (256 - xdiff) +         \
279
35476776
                                REDVAL(d) * xdiff * ydiff) >> 16);
280
281
35476776
                green = (USHORT)((GREENVAL(a) * (256 - xdiff) * (256 - ydiff) + \
282
35476776
                                  GREENVAL(b) * xdiff * (256 - ydiff) +         \
283
35476776
                                  GREENVAL(c) * ydiff * (256 - xdiff) +         \
284
35476776
                                  GREENVAL(d) * xdiff * ydiff) >> 16);
285
286
35476776
                blue = (USHORT)((BLUEVAL(a) * (256 - xdiff) * (256 - ydiff) + \
287
35476776
                                 BLUEVAL(b) * xdiff * (256 - ydiff) +         \
288
35476776
                                 BLUEVAL(c) * ydiff * (256 - xdiff) +         \
289
35476776
                                 BLUEVAL(d) * xdiff * ydiff) >> 16);
290
291

35476776
                if (alpha && (alpha < 0xff))
292
                {
293
840762
                    red   = (USHORT)((red << 8) / alpha);
294
840762
                    green = (USHORT)((green << 8) / alpha);
295
840762
                    blue  = (USHORT)((blue << 8) / alpha);
296
                }
297
298
35476776
                red = red > 31 ? 31 : red;
299
35476776
                green = green > 63 ? 63 : green;
300
35476776
                blue = blue > 31 ? 31 : blue;
301
35476776
                alpha = alpha > 255 ? 255 : alpha;
302
303
35476776
                *put++ = ASSEMBLECOLOR(red, green, blue);
304
35476776
                *putalpha++ = (GX_UBYTE)alpha;
305
            }
306
            else
307
            {
308
28731760
                put++;
309
28731760
                *putalpha++ = 0;
310
            }
311
        }
312
    }
313
314
1154
    return GX_SUCCESS;
315
}
316
317
/**************************************************************************/
318
/*                                                                        */
319
/*  FUNCTION                                               RELEASE        */
320
/*                                                                        */
321
/*    _gx_utility_565rgb_pixelmap_alpha_rotate            PORTABLE C      */
322
/*                                                           6.1          */
323
/*  AUTHOR                                                                */
324
/*                                                                        */
325
/*    Kenneth Maxwell, Microsoft Corporation                              */
326
/*                                                                        */
327
/*  DESCRIPTION                                                           */
328
/*                                                                        */
329
/*    Internal helper function that rotate an uncompressed pixelmap       */
330
/*      with alpha.                                                       */
331
/*                                                                        */
332
/*  INPUT                                                                 */
333
/*                                                                        */
334
/*    src                                   The pixelmap to be rotated    */
335
/*    angle                                 The angle to be rotated       */
336
/*    destination                           The rotated bitmap to be      */
337
/*                                            returned                    */
338
/*    rot_cx                                X coordinate of rotation      */
339
/*                                            center                      */
340
/*    rot_cy                                Y coordinate of rotation      */
341
/*                                            center                      */
342
/*                                                                        */
343
/*  OUTPUT                                                                */
344
/*                                                                        */
345
/*    status                                Completion status             */
346
/*                                                                        */
347
/*  CALLS                                                                 */
348
/*                                                                        */
349
/*    _gx_system_memory_allocator           Memory Allocation routine     */
350
/*    _gx_utility_math_cos                  Compute the cosine value      */
351
/*    _gx_utility_math_sin                  Compute the sine value        */
352
/*                                                                        */
353
/*  CALLED BY                                                             */
354
/*                                                                        */
355
/*    GUIX Internal Code                                                  */
356
/*                                                                        */
357
/**************************************************************************/
358
1192
static UINT _gx_utility_565rgb_pixelmap_alpha_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
359
{
360
USHORT   *put;
361
USHORT   *get;
362
GX_UBYTE *putalpha;
363
GX_UBYTE *getalpha;
364
INT       srcxres;
365
INT       srcyres;
366
INT       cosv;
367
INT       sinv;
368
USHORT    red, green, blue;
369
INT       idxminx, idxmaxx, idxmaxy;
370
INT      *mx;
371
INT      *my;
372
INT       xres;
373
INT       yres;
374
INT       width, height;
375
INT       x, y;
376
INT       xx, yy;
377
USHORT    a, b, c, d;
378
USHORT    alpha[4];
379
INT       xdiff, ydiff;
380
381
1192
    mx = _gx_system_scratchpad;
382
1192
    my = mx + 4;
383
384
1192
    mx[0] = mx[3] = -1;
385
1192
    mx[1] = mx[2] = 1;
386
387
1192
    my[0] = my[1] = 1;
388
1192
    my[2] = my[3] = -1;
389
390
1192
    idxminx = (angle / 90) & 0x3;
391
1192
    idxmaxx = (idxminx + 2) & 0x3;
392
1192
    idxmaxy = (idxminx + 1) & 0x3;
393
394
    /* Calculate the source x and y center. */
395
1192
    srcxres = src -> gx_pixelmap_width >> 1;
396
1192
    srcyres = src -> gx_pixelmap_height >> 1;
397
398
1192
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
399
1192
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
400
401
1192
    xres = mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv;
402
1192
    yres = my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv;
403
404
1192
    xres = GX_FIXED_VAL_TO_INT(xres);
405
1192
    yres = GX_FIXED_VAL_TO_INT(yres);
406
407
408
    /* Calculate destination width and height. */
409
1192
    width = (xres << 1);
410
1192
    height = (yres << 1);
411
412
    /* Calculate the new rotation axis. */
413

1192
    if (rot_cx && rot_cy)
414
    {
415
1178
        x = ((*rot_cx) - srcxres) * cosv - ((*rot_cy) - srcyres) * sinv;
416
1178
        y = ((*rot_cy) - srcyres) * cosv + ((*rot_cx) - srcxres) * sinv;
417
418
1178
        srcxres = *rot_cx;
419
1178
        srcyres = *rot_cy;
420
421
1178
        x = GX_FIXED_VAL_TO_INT(x) + xres;
422
1178
        y = GX_FIXED_VAL_TO_INT(y) + yres;
423
424
1178
        *rot_cx = x;
425
1178
        *rot_cy = y;
426
427
1178
        xres = *rot_cx;
428
1178
        yres = *rot_cy;
429
    }
430
431
1192
    destination -> gx_pixelmap_height = (GX_VALUE)height;
432
1192
    destination -> gx_pixelmap_width = (GX_VALUE)width;
433
1192
    destination -> gx_pixelmap_flags |= GX_PIXELMAP_ALPHA;
434
435
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
436
       overflow cannot occur. */
437
1192
    destination -> gx_pixelmap_data_size = (UINT)(height * width) * sizeof(USHORT);
438
1192
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
439
440
1192
    if (destination -> gx_pixelmap_data == GX_NULL)
441
    {
442
7
        return GX_SYSTEM_MEMORY_ERROR;
443
    }
444
445
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
446
       overflow cannot occur. */
447
1185
    destination -> gx_pixelmap_aux_data_size = (UINT)(height * width) * sizeof(GX_UBYTE);
448
1185
    destination -> gx_pixelmap_aux_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_aux_data_size);
449
450
1185
    if (destination -> gx_pixelmap_aux_data == GX_NULL)
451
    {
452
2
        _gx_system_memory_free((VOID *)destination -> gx_pixelmap_data);
453
454
2
        return GX_SYSTEM_MEMORY_ERROR;
455
    }
456
457
1183
    put = (USHORT *)destination -> gx_pixelmap_data;
458
1183
    putalpha = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
459
460
    /* Loop through the destination's pixels.  */
461
347363
    for (y = 0; y < height; y++)
462
    {
463
103073484
        for (x = 0; x < width; x++)
464
        {
465
102727304
            xx = (x - xres) * cosv + (y - yres) * sinv;
466
102727304
            yy = (y - yres) * cosv - (x - xres) * sinv;
467
468
102727304
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
469
102727304
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
470
471
102727304
            xx = GX_FIXED_VAL_TO_INT(xx);
472
102727304
            yy = GX_FIXED_VAL_TO_INT(yy);
473
474
102727304
            xx += srcxres;
475
102727304
            yy += srcyres;
476
477

102727304
            if ((xx >= -1) && (xx < src -> gx_pixelmap_width) &&
478
72643059
                (yy >= -1) && (yy < src -> gx_pixelmap_height))
479
            {
480
481

61119518
                if ((xx >= 0) && (xx < src -> gx_pixelmap_width - 1) &&
482
60326793
                    (yy >= 0) && (yy < src -> gx_pixelmap_height - 1))
483
                {
484
60044104
                    get = (USHORT *)src -> gx_pixelmap_data;
485
60044104
                    get += yy * src -> gx_pixelmap_width;
486
60044104
                    get += xx;
487
488
60044104
                    getalpha = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
489
60044104
                    getalpha += yy * src -> gx_pixelmap_width;
490
60044104
                    getalpha += xx;
491
492
60044104
                    a = *get;
493
60044104
                    alpha[0] = *getalpha;
494
495
60044104
                    b = *(get + 1);
496
60044104
                    alpha[1] = *(getalpha + 1);
497
498
60044104
                    c = *(get + src -> gx_pixelmap_width);
499
60044104
                    alpha[2] = *(getalpha + src -> gx_pixelmap_width);
500
501
60044104
                    d = *(get + src -> gx_pixelmap_width + 1);
502
60044104
                    alpha[3] = *(getalpha + src -> gx_pixelmap_width + 1);
503
                }
504
                else
505
                {
506
1075414
                    get = (USHORT *)src -> gx_pixelmap_data;
507
1075414
                    getalpha = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
508
509
1075414
                    a = 0;
510
1075414
                    b = 0;
511
1075414
                    c = 0;
512
1075414
                    d = 0;
513
514
1075414
                    if (xx == -1)
515
                    {
516
                        /* handle left edge.  */
517
254854
                        if (yy >= 0)
518
                        {
519
253909
                            b = *(get + yy * src -> gx_pixelmap_width);
520
253909
                            alpha[1] = *(getalpha + yy * src -> gx_pixelmap_width);
521
                        }
522
523
254854
                        if (yy < src -> gx_pixelmap_height - 1)
524
                        {
525
253897
                            d = *(get + (yy + 1) * src -> gx_pixelmap_width);
526
253897
                            alpha[3] = *(getalpha + (yy + 1) * src -> gx_pixelmap_width);
527
                        }
528
                    }
529
820560
                    else if (yy == -1)
530
                    {
531
                        /* handle top edge.  */
532
283585
                        c = *(get + xx);
533
283585
                        alpha[2] = *(getalpha + xx);
534
535
283585
                        if (xx < src -> gx_pixelmap_width - 1)
536
                        {
537
282634
                            d = *(get + xx + 1);
538
282634
                            alpha[3] = *(getalpha + xx + 1);
539
                        }
540
                    }
541
536975
                    else if (xx == src -> gx_pixelmap_width - 1)
542
                    {
543
                        /* handle right edget. */
544
254286
                        a = *(get + yy * src -> gx_pixelmap_width + xx);
545
254286
                        alpha[0] = *(getalpha + yy * src -> gx_pixelmap_width + xx);
546
547
254286
                        if (yy < src -> gx_pixelmap_height - 1)
548
                        {
549
253358
                            c = *(get + (yy + 1) * src -> gx_pixelmap_width + xx);
550
253358
                            alpha[2] = *(getalpha + (yy + 1) * src -> gx_pixelmap_width + xx);
551
                        }
552
                    }
553
                    else
554
                    {
555
                        /* handle bottom edge. */
556
282689
                        a = *(get + yy * src -> gx_pixelmap_width + xx);
557
282689
                        alpha[0] = *(getalpha + yy * src -> gx_pixelmap_width + xx);
558
559
282689
                        b = *(get + yy * src -> gx_pixelmap_width + xx + 1);
560
282689
                        alpha[1] = *(getalpha + yy * src -> gx_pixelmap_width + xx + 1);
561
                    }
562
563
1075414
                    if (!a)
564
                    {
565
540802
                        alpha[0] = 0;
566
                    }
567
568
1075414
                    if (!b)
569
                    {
570
540908
                        alpha[1] = 0;
571
                    }
572
573
1075414
                    if (!c)
574
                    {
575
541046
                        alpha[2] = 0;
576
                    }
577
578
1075414
                    if (!d)
579
                    {
580
541158
                        alpha[3] = 0;
581
                    }
582
                }
583
584
61119518
                red = (USHORT)((REDVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) + \
585
61119518
                                REDVAL(b) * alpha[1] * xdiff * (256 - ydiff) +         \
586
61119518
                                REDVAL(c) * alpha[2] * ydiff * (256 - xdiff) +         \
587
61119518
                                REDVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
588
589
61119518
                green = (USHORT)((GREENVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) + \
590
61119518
                                  GREENVAL(b) * alpha[1] * xdiff * (256 - ydiff) +         \
591
61119518
                                  GREENVAL(c) * alpha[2] * ydiff * (256 - xdiff) +         \
592
61119518
                                  GREENVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
593
594
61119518
                blue = (USHORT)((BLUEVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) + \
595
61119518
                                 BLUEVAL(b) * alpha[1] * xdiff * (256 - ydiff) +         \
596
61119518
                                 BLUEVAL(c) * alpha[2] * ydiff * (256 - xdiff) +         \
597
61119518
                                 BLUEVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
598
599
61119518
                alpha[0] = (USHORT)((alpha[0] * (256 - xdiff) * (256 - ydiff) + \
600
61119518
                                     alpha[1] * xdiff * (256 - ydiff) +         \
601
61119518
                                     alpha[2] * ydiff * (256 - xdiff) +         \
602
61119518
                                     alpha[3] * xdiff * ydiff) >> 16);
603
604
61119518
                if (alpha[0])
605
                {
606
43340538
                    red /= alpha[0];
607
43340538
                    green /=  alpha[0];
608
43340538
                    blue /= alpha[0];
609
                }
610
611
61119518
                red = red > 31 ? 31 : red;
612
61119518
                green = green > 63 ? 63 : green;
613
61119518
                blue = blue > 31 ? 31 : blue;
614
615
61119518
                *put++ = ASSEMBLECOLOR(red, green, blue);
616
61119518
                *putalpha++ = (GX_UBYTE)alpha[0];
617
            }
618
            else
619
            {
620
41607786
                put++;
621
41607786
                *putalpha++ = 0;
622
            }
623
        }
624
    }
625
626
1183
    return GX_SUCCESS;
627
}
628
629
/**************************************************************************/
630
/*                                                                        */
631
/*  FUNCTION                                               RELEASE        */
632
/*                                                                        */
633
/*    _gx_utility_565rgb_pixelmap_simple_raw_rotate       PORTABLE C      */
634
/*                                                           6.1          */
635
/*  AUTHOR                                                                */
636
/*                                                                        */
637
/*    Kenneth Maxwell, Microsoft Corporation                              */
638
/*                                                                        */
639
/*  DESCRIPTION                                                           */
640
/*                                                                        */
641
/*    Internal helper function that handles 90, 180 and 270 degree        */
642
/*    rotation of an uncompressed pixelmap wihout alpha.                  */
643
/*                                                                        */
644
/*  INPUT                                                                 */
645
/*                                                                        */
646
/*    src                                   The pixelmap to be rotated    */
647
/*    angle                                 The angle to be rotated       */
648
/*    destination                           The rotated bitmap to be      */
649
/*                                            returned                    */
650
/*    rot_cx                                X coordinate of rotation      */
651
/*                                            center                      */
652
/*    rot_cy                                Y coordinate of rotation      */
653
/*                                            center                      */
654
/*                                                                        */
655
/*  OUTPUT                                                                */
656
/*                                                                        */
657
/*    status                                Completion status             */
658
/*                                                                        */
659
/*  CALLS                                                                 */
660
/*                                                                        */
661
/*    _gx_system_memory_allocator           Memory Allocation routine     */
662
/*                                                                        */
663
/*  CALLED BY                                                             */
664
/*                                                                        */
665
/*    GUIX Internal Code                                                  */
666
/*                                                                        */
667
/**************************************************************************/
668
33
static UINT _gx_utility_565rgb_pixelmap_simple_raw_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
669
{
670
USHORT *put;
671
USHORT *get;
672
INT     width, height;
673
INT     x, y;
674
675
33
    width = 0;
676
33
    height = 0;
677
678
33
    destination -> gx_pixelmap_aux_data = GX_NULL;
679
680
33
    width = src -> gx_pixelmap_height;
681
33
    height = src -> gx_pixelmap_width;
682
683
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
684
       overflow cannot occur. */
685
33
    destination -> gx_pixelmap_data_size = (UINT)(width * height) * sizeof(USHORT);
686
33
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
687
688
33
    if (destination -> gx_pixelmap_data == GX_NULL)
689
    {
690
12
        return GX_SYSTEM_MEMORY_ERROR;
691
    }
692
693
21
    if (angle == 90)
694
    {
695
7
        put = (USHORT *)destination -> gx_pixelmap_data;
696
697
1459
        for (y = 0; y < height; y++)
698
        {
699
213132
            for (x = 0; x < width; x++)
700
            {
701
211680
                get = (USHORT *)src -> gx_pixelmap_data;
702
211680
                get += (width - 1 - x) * height;
703
211680
                get += y;
704
705
211680
                *put++ = *get;
706
            }
707
        }
708
709

7
        if (rot_cx && rot_cy)
710
        {
711
5
            x = *rot_cx;
712
5
            y = *rot_cy;
713
714
5
            *rot_cx = (width - 1 - y);
715
5
            *rot_cy = x;
716
        }
717
    }
718
14
    else if (angle == 180)
719
    {
720
7
        GX_SWAP_VALS(width, height);
721
722
7
        put = (USHORT *)destination -> gx_pixelmap_data;
723
724
1117
        for (y = 0; y < height; y++)
725
        {
726
212790
            for (x = 0; x < width; x++)
727
            {
728
211680
                get = (USHORT *)src -> gx_pixelmap_data;
729
211680
                get += (height - 1 - y) * width;
730
211680
                get += width - 1 - x;
731
732
211680
                *put++ = *get;
733
            }
734
        }
735
736

7
        if (rot_cx && rot_cy)
737
        {
738
5
            x = *rot_cx;
739
5
            y = *rot_cy;
740
741
5
            *rot_cx = (width - 1 - x);
742
5
            *rot_cy = (height - 1 - y);
743
        }
744
    }
745
    else
746
    {
747
        /* angle = 270. */
748
7
        put = (USHORT *)destination -> gx_pixelmap_data;
749
750
1459
        for (y = 0; y < height; y++)
751
        {
752
213132
            for (x = 0; x < width; x++)
753
            {
754
211680
                get = (USHORT *)src -> gx_pixelmap_data;
755
211680
                get += x * height;
756
211680
                get += height - 1 - y;
757
758
211680
                *put++ = *get;
759
            }
760
        }
761
762

7
        if (rot_cx && rot_cy)
763
        {
764
5
            x = *rot_cx;
765
5
            y = *rot_cy;
766
767
5
            *rot_cx = y;
768
5
            *rot_cy = (height - 1 - x);
769
        }
770
    }
771
772
21
    destination -> gx_pixelmap_height = (GX_VALUE)height;
773
21
    destination -> gx_pixelmap_width = (GX_VALUE)width;
774
775
21
    return GX_SUCCESS;
776
}
777
778
/**************************************************************************/
779
/*                                                                        */
780
/*  FUNCTION                                               RELEASE        */
781
/*                                                                        */
782
/*    _gx_utility_565rgb_pixelmap_simple_alpha_rotate     PORTABLE C      */
783
/*                                                           6.1          */
784
/*  AUTHOR                                                                */
785
/*                                                                        */
786
/*    Kenneth Maxwell, Microsoft Corporation                              */
787
/*                                                                        */
788
/*  DESCRIPTION                                                           */
789
/*                                                                        */
790
/*    Internal helper function that handles 90, 180 and 270 degree        */
791
/*    rotation of an uncompressed pixelmap wih alpha.                     */
792
/*                                                                        */
793
/*  INPUT                                                                 */
794
/*                                                                        */
795
/*    src                                   The pixelmap to be rotated    */
796
/*    angle                                 The angle to be rotated       */
797
/*    destination                           The rotated bitmap to be      */
798
/*                                            returned                    */
799
/*    rot_cx                                X coordinate of rotation      */
800
/*                                            center                      */
801
/*    rot_cy                                Y coordinate of rotation      */
802
/*                                            center                      */
803
/*                                                                        */
804
/*  OUTPUT                                                                */
805
/*                                                                        */
806
/*    None                                                                */
807
/*                                                                        */
808
/*  CALLS                                                                 */
809
/*                                                                        */
810
/*    _gx_system_memory_allocator           Memory Allocation routine     */
811
/*                                                                        */
812
/*  CALLED BY                                                             */
813
/*                                                                        */
814
/*    GUIX Internal Code                                                  */
815
/*                                                                        */
816
/**************************************************************************/
817
63
static UINT _gx_utility_565rgb_pixelmap_simple_alpha_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
818
{
819
USHORT   *put;
820
GX_UBYTE *putalpha;
821
USHORT   *get;
822
GX_UBYTE *getalpha;
823
INT       width, height;
824
INT       x, y;
825
826
63
    width = src -> gx_pixelmap_height;
827
63
    height = src -> gx_pixelmap_width;
828
829
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
830
       overflow cannot occur. */
831
63
    destination -> gx_pixelmap_data_size = (UINT)(width * height) * sizeof(USHORT);
832
63
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
833
834
63
    if (destination -> gx_pixelmap_data == GX_NULL)
835
    {
836
12
        return GX_SYSTEM_MEMORY_ERROR;
837
    }
838
839
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
840
       overflow cannot occur. */
841
51
    destination -> gx_pixelmap_aux_data_size = (UINT)(width * height) * sizeof(GX_UBYTE);
842
51
    destination -> gx_pixelmap_aux_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_aux_data_size);
843
844
51
    if (destination -> gx_pixelmap_aux_data == GX_NULL)
845
    {
846
6
        _gx_system_memory_free((VOID *)destination -> gx_pixelmap_data);
847
6
        return GX_SYSTEM_MEMORY_ERROR;
848
    }
849
850
45
    if (angle == 90)
851
    {
852
17
        put = (USHORT *)destination -> gx_pixelmap_data;
853
17
        putalpha = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
854
855
2979
        for (y = 0; y < height; y++)
856
        {
857
587639
            for (x = 0; x < width; x++)
858
            {
859
584677
                get = (USHORT *)src -> gx_pixelmap_data;
860
584677
                get += (width - 1 - x) * height;
861
584677
                get += y;
862
863
584677
                getalpha = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
864
584677
                getalpha += (width - 1 - x) * height;
865
584677
                getalpha += y;
866
867
584677
                *put++ = *get;
868
584677
                *putalpha++ = *getalpha;
869
            }
870
        }
871
872

17
        if (rot_cx && rot_cy)
873
        {
874
11
            x = *rot_cx;
875
11
            y = *rot_cy;
876
877
            /* Get new rotation point. */
878
11
            *rot_cx = (width - 1 - y);
879
11
            *rot_cy = x;
880
        }
881
    }
882
28
    else if (angle == 180)
883
    {
884
14
        GX_SWAP_VALS(width, height);
885
886
14
        put = (USHORT *)destination -> gx_pixelmap_data;
887
14
        putalpha = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
888
889
2636
        for (y = 0; y < height; y++)
890
        {
891
506839
            for (x = 0; x < width; x++)
892
            {
893
504217
                get = (USHORT *)src -> gx_pixelmap_data;
894
504217
                get += (height - 1 - y) * width;
895
504217
                get += width - 1 - x;
896
897
504217
                getalpha = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
898
504217
                getalpha += (height - 1 - y) * width;
899
504217
                getalpha += width - 1 - x;
900
901
504217
                *put++ = *get;
902
504217
                *putalpha++ = *getalpha;
903
            }
904
        }
905
906

14
        if (rot_cx && rot_cy)
907
        {
908
8
            x = *rot_cx;
909
8
            y = *rot_cy;
910
911
            /* Get new rotation point. */
912
8
            *rot_cx = (width - 1 - x);
913
8
            *rot_cy = (height - 1 - y);
914
        }
915
    }
916
    else
917
    {
918
        /* angle = 270. */
919
14
        put = (USHORT *)destination -> gx_pixelmap_data;
920
14
        putalpha = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
921
922
2498
        for (y = 0; y < height; y++)
923
        {
924
506701
            for (x = 0; x < width; x++)
925
            {
926
504217
                get = (USHORT *)src -> gx_pixelmap_data;
927
504217
                get += x * height;
928
504217
                get += height - 1 - y;
929
930
504217
                getalpha = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
931
504217
                getalpha += x * height;
932
504217
                getalpha += height - 1 - y;
933
934
504217
                *put++ = *get;
935
504217
                *putalpha++ = *getalpha;
936
            }
937
        }
938
939

14
        if (rot_cx && rot_cy)
940
        {
941
8
            x = *rot_cx;
942
8
            y = *rot_cy;
943
944
            /* Get new rotation point. */
945
8
            *rot_cx = y;
946
8
            *rot_cy = (height - 1 - x);
947
        }
948
    }
949
950
45
    destination -> gx_pixelmap_height = (GX_VALUE)height;
951
45
    destination -> gx_pixelmap_width = (GX_VALUE)width;
952
953
45
    return GX_SUCCESS;
954
}
955
956
957
/**************************************************************************/
958
/*                                                                        */
959
/*  FUNCTION                                               RELEASE        */
960
/*                                                                        */
961
/*    _gx_utility_565rgb_pixelmap_rotate                  PORTABLE C      */
962
/*                                                           6.1          */
963
/*  AUTHOR                                                                */
964
/*                                                                        */
965
/*    Kenneth Maxwell, Microsoft Corporation                              */
966
/*                                                                        */
967
/*  DESCRIPTION                                                           */
968
/*                                                                        */
969
/*    This function rotates 565rgb format uncompressed pixelmap with or   */
970
/*    without alpha channel.                                              */
971
/*                                                                        */
972
/*  INPUT                                                                 */
973
/*                                                                        */
974
/*    src                                   The pixelmap to be rotated    */
975
/*    angle                                 The angle to be rotated       */
976
/*    destination                           The rotated bitmap to be      */
977
/*                                            returned                    */
978
/*    rot_cx                                X coordinate of rotation      */
979
/*                                            center                      */
980
/*    rot_cy                                Y coordinate of rotation      */
981
/*                                            center                      */
982
/*                                                                        */
983
/*  OUTPUT                                                                */
984
/*                                                                        */
985
/*    status                                Completion status             */
986
/*                                                                        */
987
/*  CALLS                                                                 */
988
/*                                                                        */
989
/*     _gx_utility_565rgb_pixelmap_raw_rotate                             */
990
/*                                          Rotate 565rgb format pixelmap */
991
/*                                            without alpha channel       */
992
/*     _gx_utility_565rgb_pixelmap_alpha_rotate                           */
993
/*                                          Rotate 565rgb format pixelmap */
994
/*                                            with alpha channel          */
995
/*                                                                        */
996
/*  CALLED BY                                                             */
997
/*                                                                        */
998
/*    GUIX Internal Code                                                  */
999
/*                                                                        */
1000
/**************************************************************************/
1001
2350
UINT _gx_utility_565rgb_pixelmap_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
1002
{
1003
UINT status;
1004
1005
2350
    if (src -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
1006
    {
1007
        /* alpha, no compression */
1008
1192
        status = _gx_utility_565rgb_pixelmap_alpha_rotate(src, angle, destination, rot_cx, rot_cy);
1009
    }
1010
    else
1011
    {
1012
        /* no compression or alpha */
1013
1158
        status = _gx_utility_565rgb_pixelmap_raw_rotate(src, angle, destination, rot_cx, rot_cy);
1014
    }
1015
1016
2350
    return status;
1017
}
1018
1019
1020
/**************************************************************************/
1021
/*                                                                        */
1022
/*  FUNCTION                                               RELEASE        */
1023
/*                                                                        */
1024
/*    _gx_utility_565rgb_pixelmap_simple_rotate           PORTABLE C      */
1025
/*                                                           6.1          */
1026
/*  AUTHOR                                                                */
1027
/*                                                                        */
1028
/*    Kenneth Maxwell, Microsoft Corporation                              */
1029
/*                                                                        */
1030
/*  DESCRIPTION                                                           */
1031
/*                                                                        */
1032
/*    This function rotates 565rgb format uncompressed pixelmap with      */
1033
/*    simple rotation angle 90, 180 or 270 degree.                        */
1034
/*                                                                        */
1035
/*  INPUT                                                                 */
1036
/*                                                                        */
1037
/*    src                                   The pixelmap to be rotated    */
1038
/*    angle                                 The angle to be rotated       */
1039
/*    destination                           The rotated bitmap to be      */
1040
/*                                            returned                    */
1041
/*    rot_cx                                X coordinate of rotation      */
1042
/*                                            center                      */
1043
/*    rot_cy                                Y coordinate of rotation      */
1044
/*                                            center                      */
1045
/*                                                                        */
1046
/*  OUTPUT                                                                */
1047
/*                                                                        */
1048
/*    status                                Completion status             */
1049
/*                                                                        */
1050
/*  CALLS                                                                 */
1051
/*                                                                        */
1052
/*     _gx_utility_565rgb_pixelmap_simple_raw_rotate                      */
1053
/*                                          Rotate 565rgb format pixelmap */
1054
/*                                            without alpha channel       */
1055
/*     _gx_utility_565rgb_pixelmap_simple_alpha_rotate                    */
1056
/*                                          Rotate 565rgb format pixelmap */
1057
/*                                            with alpha channel          */
1058
/*                                                                        */
1059
/*  CALLED BY                                                             */
1060
/*                                                                        */
1061
/*    GUIX Internal Code                                                  */
1062
/*                                                                        */
1063
/**************************************************************************/
1064
96
UINT _gx_utility_565rgb_pixelmap_simple_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
1065
{
1066
UINT status;
1067
1068
96
    if (src -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
1069
    {
1070
        /* alpha, no compression */
1071
63
        status = _gx_utility_565rgb_pixelmap_simple_alpha_rotate(src, angle, destination, rot_cx, rot_cy);
1072
    }
1073
    else
1074
    {
1075
        /* no compression or alpha */
1076
33
        status = _gx_utility_565rgb_pixelmap_simple_raw_rotate(src, angle, destination, rot_cx, rot_cy);
1077
    }
1078
1079
96
    return status;
1080
}
1081