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

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

19908456
            if ((xx >= -1) && (xx < src -> gx_pixelmap_width) &&
196
14512884
                (yy >= -1) && (yy < src -> gx_pixelmap_height))
197
            {
198

11004532
                if ((xx >= 0) && (xx < src -> gx_pixelmap_width - 1) &&
199
10827830
                    (yy >= 0) && (yy < src -> gx_pixelmap_height - 1))
200
                {
201
10741590
                    get = (GX_UBYTE *)src -> gx_pixelmap_data;
202
10741590
                    get += yy * src -> gx_pixelmap_width;
203
10741590
                    get += xx;
204
205
10741590
                    a = *get;
206
10741590
                    b = *(get + 1);
207
10741590
                    c = *(get + src -> gx_pixelmap_width);
208
10741590
                    d = *(get + src -> gx_pixelmap_width + 1);
209
210
10741590
                    alpha = 0xff;
211
                }
212
                else
213
                {
214
262942
                    get = (GX_UBYTE *)src -> gx_pixelmap_data;
215
216
262942
                    a = 0;
217
262942
                    b = 0;
218
262942
                    c = 0;
219
262942
                    d = 0;
220
262942
                    alpha = 0;
221
222
262942
                    if (xx == -1)
223
                    {
224
                        /* handle left edge.  */
225
45698
                        if (yy >= 0)
226
                        {
227
45388
                            b = *(get + yy * src -> gx_pixelmap_width);
228
45388
                            alpha += xdiff * (256 - ydiff);
229
                        }
230
231
45698
                        if (yy < src -> gx_pixelmap_height - 1)
232
                        {
233
45354
                            d = *(get + (yy + 1) * src -> gx_pixelmap_width);
234
45354
                            alpha += xdiff * ydiff;
235
                        }
236
                    }
237
217244
                    else if (yy == -1)
238
                    {
239
                        /* handle top edge.  */
240
85892
                        c = *(get + xx);
241
85892
                        alpha += ydiff * (256 - xdiff);
242
243
85892
                        if (xx < src -> gx_pixelmap_width - 1)
244
                        {
245
85534
                            d = *(get + xx + 1);
246
85534
                            alpha += xdiff * ydiff;
247
                        }
248
                    }
249
131352
                    else if (xx == src -> gx_pixelmap_width - 1)
250
                    {
251
                        /* handle right edget. */
252
45112
                        a = *(get + yy * src -> gx_pixelmap_width + xx);
253
45112
                        alpha += (256 - xdiff) * (256 - ydiff);
254
255
45112
                        if (yy < src -> gx_pixelmap_height - 1)
256
                        {
257
44746
                            c = *(get + (yy + 1) * src -> gx_pixelmap_width + xx);
258
44746
                            alpha += ydiff * (256 - xdiff);
259
                        }
260
                    }
261
                    else
262
                    {
263
                        /* handle bottom edge. */
264
86240
                        a = *(get + yy * src -> gx_pixelmap_width + xx);
265
86240
                        alpha += (256 - xdiff) * (256 - ydiff);
266
267
86240
                        b = *(get + yy * src -> gx_pixelmap_width + xx + 1);
268
86240
                        alpha += xdiff * (256 - ydiff);
269
                    }
270
271
262942
                    alpha >>= 8;
272
                }
273
274
11004532
                red = (USHORT)((REDVAL_332(a) * (256 - xdiff) * (256 - ydiff) + \
275
11004532
                                REDVAL_332(b) * xdiff * (256 - ydiff) +         \
276
11004532
                                REDVAL_332(c) * ydiff * (256 - xdiff) +         \
277
11004532
                                REDVAL_332(d) * xdiff * ydiff) >> 16);
278
279
11004532
                green = (USHORT)((GREENVAL_332(a) * (256 - xdiff) * (256 - ydiff) + \
280
11004532
                                  GREENVAL_332(b) * xdiff * (256 - ydiff) +         \
281
11004532
                                  GREENVAL_332(c) * ydiff * (256 - xdiff) +         \
282
11004532
                                  GREENVAL_332(d) * xdiff * ydiff) >> 16);
283
284
11004532
                blue = (USHORT)((BLUEVAL_332(a) * (256 - xdiff) * (256 - ydiff) + \
285
11004532
                                 BLUEVAL_332(b) * xdiff * (256 - ydiff) +         \
286
11004532
                                 BLUEVAL_332(c) * ydiff * (256 - xdiff) +         \
287
11004532
                                 BLUEVAL_332(d) * xdiff * ydiff) >> 16);
288
289

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

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

31809736
            if ((xx >= -1) && (xx < src -> gx_pixelmap_width) &&
472
21188595
                (yy >= -1) && (yy < src -> gx_pixelmap_height))
473
            {
474
475

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

3
        if (rot_cx && rot_cy)
706
        {
707
1
            x = *rot_cx;
708
1
            y = *rot_cy;
709
710
1
            *rot_cx = (width - 1 - y);
711
1
            *rot_cy = x;
712
        }
713
    }
714
6
    else if (angle == 180)
715
    {
716
3
        put = (GX_UBYTE *)destination -> gx_pixelmap_data;
717
718
381
        for (y = 0; y < height; y++)
719
        {
720
91098
            for (x = 0; x < width; x++)
721
            {
722
90720
                get = (GX_UBYTE *)src -> gx_pixelmap_data;
723
90720
                get += (height - 1 - y) * width;
724
90720
                get += width - 1 - x;
725
726
90720
                *put++ = *get;
727
            }
728
        }
729
730

3
        if (rot_cx && rot_cy)
731
        {
732
1
            x = *rot_cx;
733
1
            y = *rot_cy;
734
735
1
            *rot_cx = (width - 1 - x);
736
1
            *rot_cy = (height - 1 - y);
737
        }
738
    }
739
    else
740
    {
741
        /* angle = 270. */
742
3
        GX_SWAP_VALS(width, height);
743
744
3
        put = (GX_UBYTE *)destination -> gx_pixelmap_data;
745
746
723
        for (y = 0; y < height; y++)
747
        {
748
91440
            for (x = 0; x < width; x++)
749
            {
750
90720
                get = (GX_UBYTE *)src -> gx_pixelmap_data;
751
90720
                get += x * height;
752
90720
                get += height - 1 - y;
753
754
90720
                *put++ = *get;
755
            }
756
        }
757
758

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

7
        if (rot_cx && rot_cy)
873
        {
874
1
            x = *rot_cx;
875
1
            y = *rot_cy;
876
877
            /* Get new rotation point. */
878
1
            *rot_cx = width - 1 - y;
879
1
            *rot_cy = x;
880
        }
881
    }
882
14
    else if (angle == 180)
883
    {
884
1404
        for (y = 0; y < height; y++)
885
        {
886
264872
            for (x = 0; x < width; x++)
887
            {
888
263475
                get = (GX_UBYTE *)src -> gx_pixelmap_data;
889
263475
                get += (height - 1 - y) * width;
890
263475
                get += width - 1 - x;
891
892
263475
                getalpha = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
893
263475
                getalpha += (height - 1 - y) * width;
894
263475
                getalpha += width - 1 - x;
895
896
263475
                *put++ = *get;
897
263475
                *putalpha++ = *getalpha;
898
            }
899
        }
900
901

7
        if (rot_cx && rot_cy)
902
        {
903
1
            x = *rot_cx;
904
1
            y = *rot_cy;
905
906
            /* Get new rotation point. */
907
1
            *rot_cx = width - 1 - x;
908
1
            *rot_cy = height - 1 - y;
909
        }
910
    }
911
    else
912
    {
913
        /* angle = 270. */
914
7
        GX_SWAP_VALS(width, height);
915
916
1312
        for (y = 0; y < height; y++)
917
        {
918
264780
            for (x = 0; x < width; x++)
919
            {
920
263475
                get = (GX_UBYTE *)src -> gx_pixelmap_data;
921
263475
                get += x * height;
922
263475
                get += height - 1 - y;
923
924
263475
                getalpha = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
925
263475
                getalpha += x * height;
926
263475
                getalpha += height - 1 - y;
927
928
263475
                *put++ = *get;
929
263475
                *putalpha++ = *getalpha;
930
            }
931
        }
932
933

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