GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_utility_1555xrgb_pixelmap_rotate.c Lines: 265 265 100.0 %
Date: 2024-12-05 08:52:37 Branches: 100 100 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** GUIX Component                                                        */
16
/**                                                                       */
17
/**   Utility (Utility)                                                   */
18
/**                                                                       */
19
/**************************************************************************/
20
21
#define REDVAL(_c)   (GX_UBYTE)(((_c) >> 10) & 0x1f)
22
#define GREENVAL(_c) (GX_UBYTE)(((_c) >> 5) & 0x1f)
23
#define BLUEVAL(_c)  (GX_UBYTE)(((_c)) & 0x1f)
24
25
#define ASSEMBLECOLOR(_r, _g, _b)    \
26
    (USHORT)((((_r) & 0x1f) << 10) | \
27
             (((_g) & 0x1f) << 5) |  \
28
             ((_b) & 0x1f))
29
30
#define GX_SOURCE_CODE
31
32
33
/* Include necessary system files.  */
34
35
#include "gx_api.h"
36
#include "gx_display.h"
37
#include "gx_context.h"
38
#include "gx_utility.h"
39
#include "gx_system.h"
40
41
/**************************************************************************/
42
/*                                                                        */
43
/*  FUNCTION                                               RELEASE        */
44
/*                                                                        */
45
/*    _gx_utility_1555xrgb_pixelmap_raw_rotate            PORTABLE C      */
46
/*                                                           6.1          */
47
/*  AUTHOR                                                                */
48
/*                                                                        */
49
/*    Kenneth Maxwell, Microsoft Corporation                              */
50
/*                                                                        */
51
/*  DESCRIPTION                                                           */
52
/*                                                                        */
53
/*    Internal helper function that rotate an 1555xrgb format pixelmap    */
54
/*    without compression, without alpha.                                 */
55
/*                                                                        */
56
/*  INPUT                                                                 */
57
/*                                                                        */
58
/*    src                                   The pixelmap to be rotated    */
59
/*    angle                                 The angle to be rotated       */
60
/*    destination                           The rotated bitmap to be      */
61
/*                                            returned                    */
62
/*    rot_cx                                X coordinate of rotation      */
63
/*                                            center                      */
64
/*    rot_cy                                Y coordinate of rotation      */
65
/*                                            center                      */
66
/*                                                                        */
67
/*  OUTPUT                                                                */
68
/*                                                                        */
69
/*    status                                Completion status             */
70
/*                                                                        */
71
/*  CALLS                                                                 */
72
/*                                                                        */
73
/*    _gx_system_memory_allocator           Memory Allocation routine     */
74
/*    _gx_utility_math_cos                  Compute the cosine value      */
75
/*    _gx_utility_math_sin                  Compute the sine value        */
76
/*                                                                        */
77
/*  CALLED BY                                                             */
78
/*                                                                        */
79
/*    GUIX Internal Code                                                  */
80
/*                                                                        */
81
/*  RELEASE HISTORY                                                       */
82
/*                                                                        */
83
/*    DATE              NAME                      DESCRIPTION             */
84
/*                                                                        */
85
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
86
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
87
/*                                            resulting in version 6.1    */
88
/*                                                                        */
89
/**************************************************************************/
90
360
static UINT _gx_utility_1555xrgb_pixelmap_raw_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
91
{
92
USHORT   *put;
93
USHORT   *get;
94
GX_UBYTE *putalpha;
95
INT       srcxres;
96
INT       srcyres;
97
INT       cosv;
98
INT       sinv;
99
USHORT    red, green, blue;
100
INT       idxminx, idxmaxx, idxmaxy;
101
INT      *mx;
102
INT      *my;
103
INT       xres;
104
INT       yres;
105
INT       width, height;
106
INT       x, y;
107
INT       xx, yy;
108
USHORT    a, b, c, d;
109
INT       alpha;
110
INT       xdiff, ydiff;
111
112
360
    mx = _gx_system_scratchpad;
113
360
    my = mx + 4;
114
115
360
    mx[0] = mx[3] = -1;
116
360
    mx[1] = mx[2] = 1;
117
118
360
    my[0] = my[1] = 1;
119
360
    my[2] = my[3] = -1;
120
121
122
360
    idxminx = (angle / 90) & 0x3;
123
360
    idxmaxx = (idxminx + 2) & 0x3;
124
360
    idxmaxy = (idxminx + 1) & 0x3;
125
126
    /* Calculate the source x and y center. */
127
360
    srcxres = src -> gx_pixelmap_width >> 1;
128
360
    srcyres = src -> gx_pixelmap_height >> 1;
129
130
360
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
131
360
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
132
133
360
    xres = mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv;
134
360
    yres = my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv;
135
136
360
    xres = GX_FIXED_VAL_TO_INT(xres);
137
360
    yres = GX_FIXED_VAL_TO_INT(yres);
138
139
    /* Calculate destination width and height. */
140
360
    width = (xres << 1);
141
360
    height = (yres << 1);
142
143
    /* Calculate the new rotation axis. */
144

360
    if (rot_cx && rot_cy)
145
    {
146
356
        x = ((*rot_cx) - srcxres) * cosv - ((*rot_cy) - srcyres) * sinv;
147
356
        y = ((*rot_cy) - srcyres) * cosv + ((*rot_cx) - srcxres) * sinv;
148
149
356
        srcxres = (INT)*rot_cx;
150
356
        srcyres = (INT)*rot_cy;
151
152
356
        x = GX_FIXED_VAL_TO_INT(x) + xres;
153
356
        y = GX_FIXED_VAL_TO_INT(y) + yres;
154
155
356
        *rot_cx = x;
156
356
        *rot_cy = y;
157
158
356
        xres = *rot_cx;
159
356
        yres = *rot_cy;
160
    }
161
162
360
    destination -> gx_pixelmap_height = (GX_VALUE)height;
163
360
    destination -> gx_pixelmap_width = (GX_VALUE)width;
164
360
    destination -> gx_pixelmap_flags |= GX_PIXELMAP_ALPHA;
165
166
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
167
       overflow cannot occur. */
168
360
    destination -> gx_pixelmap_data_size = (UINT)(height * width) * sizeof(USHORT);
169
360
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
170
171
360
    if (destination -> gx_pixelmap_data == GX_NULL)
172
    {
173
2
        return GX_SYSTEM_MEMORY_ERROR;
174
    }
175
176
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
177
       overflow cannot occur. */
178
358
    destination -> gx_pixelmap_aux_data_size = (UINT)(height * width) * sizeof(GX_UBYTE);
179
358
    destination -> gx_pixelmap_aux_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_aux_data_size);
180
181
358
    if (destination -> gx_pixelmap_aux_data == GX_NULL)
182
    {
183
2
        _gx_system_memory_free((VOID *)destination -> gx_pixelmap_data);
184
185
2
        return GX_SYSTEM_MEMORY_ERROR;
186
    }
187
188
356
    put = (USHORT *)destination -> gx_pixelmap_data;
189
356
    putalpha = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
190
191
    /* Loop through the destination's pixels.  */
192
84748
    for (y = 0; y < height; y++)
193
    {
194
19864616
        for (x = 0; x < width; x++)
195
        {
196
19780224
            xx = (x - xres) * cosv + (y - yres) * sinv;
197
19780224
            yy = (y - yres) * cosv - (x - xres) * sinv;
198
199
19780224
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
200
19780224
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
201
202
19780224
            xx = GX_FIXED_VAL_TO_INT(xx);
203
19780224
            yy = GX_FIXED_VAL_TO_INT(yy);
204
205
19780224
            xx += srcxres;
206
19780224
            yy += srcyres;
207
208

19780224
            if ((xx >= -1) && (xx < src -> gx_pixelmap_width) &&
209
14425200
                (yy >= -1) && (yy < src -> gx_pixelmap_height))
210
            {
211

10943030
                if ((xx >= 0) && (xx < src -> gx_pixelmap_width - 1) &&
212
10767320
                    (yy >= 0) && (yy < src -> gx_pixelmap_height - 1))
213
                {
214
10681560
                    get = (USHORT *)src -> gx_pixelmap_data;
215
10681560
                    get += yy * src -> gx_pixelmap_width;
216
10681560
                    get += xx;
217
218
10681560
                    a = *get;
219
10681560
                    b = *(get + 1);
220
10681560
                    c = *(get + src -> gx_pixelmap_width);
221
10681560
                    d = *(get + src -> gx_pixelmap_width + 1);
222
223
10681560
                    alpha = 0xff;
224
                }
225
                else
226
                {
227
261470
                    get = (USHORT *)src -> gx_pixelmap_data;
228
229
261470
                    a = 0;
230
261470
                    b = 0;
231
261470
                    c = 0;
232
261470
                    d = 0;
233
261470
                    alpha = 0;
234
235
261470
                    if (xx == -1)
236
                    {
237
                        /* handle left edge.  */
238
45442
                        if (yy >= 0)
239
                        {
240
45132
                            b = *(get + yy * src -> gx_pixelmap_width);
241
45132
                            alpha += xdiff * (256 - ydiff);
242
                        }
243
244
45442
                        if (yy < src -> gx_pixelmap_height - 1)
245
                        {
246
45100
                            d = *(get + (yy + 1) * src -> gx_pixelmap_width);
247
45100
                            alpha += xdiff * ydiff;
248
                        }
249
                    }
250
216028
                    else if (yy == -1)
251
                    {
252
                        /* handle top edge.  */
253
85408
                        c = *(get + xx);
254
85408
                        alpha += ydiff * (256 - xdiff);
255
256
85408
                        if (xx < src -> gx_pixelmap_width - 1)
257
                        {
258
85054
                            d = *(get + xx + 1);
259
85054
                            alpha += xdiff * ydiff;
260
                        }
261
                    }
262
130620
                    else if (xx == src -> gx_pixelmap_width - 1)
263
                    {
264
                        /* handle right edget. */
265
44860
                        a = *(get + yy * src -> gx_pixelmap_width + xx);
266
44860
                        alpha += (256 - xdiff) * (256 - ydiff);
267
268
44860
                        if (yy < src -> gx_pixelmap_height - 1)
269
                        {
270
44496
                            c = *(get + (yy + 1) * src -> gx_pixelmap_width + xx);
271
44496
                            alpha += ydiff * (256 - xdiff);
272
                        }
273
                    }
274
                    else
275
                    {
276
                        /* handle bottom edge. */
277
85760
                        a = *(get + yy * src -> gx_pixelmap_width + xx);
278
85760
                        alpha += (256 - xdiff) * (256 - ydiff);
279
280
85760
                        b = *(get + yy * src -> gx_pixelmap_width + xx + 1);
281
85760
                        alpha += xdiff * (256 - ydiff);
282
                    }
283
284
261470
                    alpha >>= 8;
285
                }
286
287
10943030
                red = (USHORT)((REDVAL(a) * (256 - xdiff) * (256 - ydiff) + \
288
10943030
                                REDVAL(b) * xdiff * (256 - ydiff) +         \
289
10943030
                                REDVAL(c) * ydiff * (256 - xdiff) +         \
290
10943030
                                REDVAL(d) * xdiff * ydiff) >> 16);
291
292
10943030
                green = (USHORT)((GREENVAL(a) * (256 - xdiff) * (256 - ydiff) + \
293
10943030
                                  GREENVAL(b) * xdiff * (256 - ydiff) +         \
294
10943030
                                  GREENVAL(c) * ydiff * (256 - xdiff) +         \
295
10943030
                                  GREENVAL(d) * xdiff * ydiff) >> 16);
296
297
10943030
                blue = (USHORT)((BLUEVAL(a) * (256 - xdiff) * (256 - ydiff) + \
298
10943030
                                 BLUEVAL(b) * xdiff * (256 - ydiff) +         \
299
10943030
                                 BLUEVAL(c) * ydiff * (256 - xdiff) +         \
300
10943030
                                 BLUEVAL(d) * xdiff * ydiff) >> 16);
301
302

10943030
                if (alpha && (alpha < 0xff))
303
                {
304
259270
                    red = (USHORT)((red << 8) / alpha);
305
259270
                    green = (USHORT)((green << 8) / alpha);
306
259270
                    blue = (USHORT)((blue << 8) / alpha);
307
                }
308
309
10943030
                red = red > 31 ? 31 : red;
310
10943030
                green = green > 63 ? 63 : green;
311
10943030
                blue = blue > 31 ? 31 : blue;
312
10943030
                alpha = alpha > 255 ? 255 : alpha;
313
314
10943030
                *put++ = ASSEMBLECOLOR(red, green, blue);
315
10943030
                *putalpha++ = (GX_UBYTE)alpha;
316
            }
317
            else
318
            {
319
8837194
                put++;
320
8837194
                *putalpha++ = 0;
321
            }
322
        }
323
    }
324
325
356
    return GX_SUCCESS;
326
}
327
328
/**************************************************************************/
329
/*                                                                        */
330
/*  FUNCTION                                               RELEASE        */
331
/*                                                                        */
332
/*    _gx_utility_1555xrgb_pixelmap_alpha_rotate          PORTABLE C      */
333
/*                                                           6.1          */
334
/*  AUTHOR                                                                */
335
/*                                                                        */
336
/*    Kenneth Maxwell, Microsoft Corporation                              */
337
/*                                                                        */
338
/*  DESCRIPTION                                                           */
339
/*                                                                        */
340
/*    Internal helper function that rotate an 1555xrgb format pixelmap    */
341
/*    without compression, with alpha.                                    */
342
/*                                                                        */
343
/*  INPUT                                                                 */
344
/*                                                                        */
345
/*    src                                   The pixelmap to be rotated    */
346
/*    angle                                 The angle to be rotated       */
347
/*    destination                           The rotated bitmap to be      */
348
/*                                            returned                    */
349
/*    rot_cx                                X coordinate of rotation      */
350
/*                                            center                      */
351
/*    rot_cy                                Y coordinate of rotation      */
352
/*                                            center                      */
353
/*                                                                        */
354
/*  OUTPUT                                                                */
355
/*                                                                        */
356
/*    status                                Completion status             */
357
/*                                                                        */
358
/*  CALLS                                                                 */
359
/*                                                                        */
360
/*    _gx_system_memory_allocator           Memory Allocation routine     */
361
/*    _gx_utility_math_cos                  Compute the cosine value      */
362
/*    _gx_utility_math_sin                  Compute the sine value        */
363
/*                                                                        */
364
/*  CALLED BY                                                             */
365
/*                                                                        */
366
/*    GUIX Internal Code                                                  */
367
/*                                                                        */
368
/*  RELEASE HISTORY                                                       */
369
/*                                                                        */
370
/*    DATE              NAME                      DESCRIPTION             */
371
/*                                                                        */
372
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
373
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
374
/*                                            resulting in version 6.1    */
375
/*                                                                        */
376
/**************************************************************************/
377
628
static UINT _gx_utility_1555xrgb_pixelmap_alpha_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
378
{
379
USHORT   *put;
380
USHORT   *get;
381
GX_UBYTE *putalpha;
382
GX_UBYTE *getalpha;
383
INT       srcxres;
384
INT       srcyres;
385
INT       cosv;
386
INT       sinv;
387
USHORT    red, green, blue;
388
INT       idxminx, idxmaxx, idxmaxy;
389
INT      *mx;
390
INT      *my;
391
INT       xres;
392
INT       yres;
393
INT       width, height;
394
INT       x, y;
395
INT       xx, yy;
396
USHORT    a, b, c, d;
397
USHORT    alpha[4];
398
INT       xdiff, ydiff;
399
400
628
    idxminx = (angle / 90) & 0x3;
401
628
    idxmaxx = (idxminx + 2) & 0x3;
402
628
    idxmaxy = (idxminx + 1) & 0x3;
403
404
628
    mx = _gx_system_scratchpad;
405
628
    my = mx + 4;
406
407
628
    mx[0] = mx[3] = -1;
408
628
    mx[1] = mx[2] = 1;
409
410
628
    my[0] = my[1] = 1;
411
628
    my[2] = my[3] = -1;
412
413
    /* Calculate the source x and y center. */
414
628
    srcxres = src -> gx_pixelmap_width >> 1;
415
628
    srcyres = src -> gx_pixelmap_height >> 1;
416
417
628
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
418
628
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
419
420
628
    xres = mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv;
421
628
    yres = my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv;
422
423
628
    xres = GX_FIXED_VAL_TO_INT(xres);
424
628
    yres = GX_FIXED_VAL_TO_INT(yres);
425
426
    /* Calculate destination width and height. */
427
628
    width = (xres << 1);
428
628
    height = (yres << 1);
429
430
    /* Calculate the new rotation axis. */
431

628
    if (rot_cx && rot_cy)
432
    {
433
624
        x = ((*rot_cx) - srcxres) * cosv - ((*rot_cy) - srcyres) * sinv;
434
624
        y = ((*rot_cy) - srcyres) * cosv + ((*rot_cx) - srcxres) * sinv;
435
436
624
        srcxres = *rot_cx;
437
624
        srcyres = *rot_cy;
438
439
624
        x = GX_FIXED_VAL_TO_INT(x) + xres;
440
624
        y = GX_FIXED_VAL_TO_INT(y) + yres;
441
442
624
        *rot_cx = x;
443
624
        *rot_cy = y;
444
445
624
        xres = *rot_cx;
446
624
        yres = *rot_cy;
447
    }
448
449
628
    destination -> gx_pixelmap_height = (GX_VALUE)height;
450
628
    destination -> gx_pixelmap_width = (GX_VALUE)width;
451
628
    destination -> gx_pixelmap_flags |= GX_PIXELMAP_ALPHA;
452
453
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
454
       overflow cannot occur. */
455
628
    destination -> gx_pixelmap_data_size = (UINT)(height * width) * sizeof(USHORT);
456
628
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
457
458
628
    if (destination -> gx_pixelmap_data == GX_NULL)
459
    {
460
2
        return GX_SYSTEM_MEMORY_ERROR;
461
    }
462
463
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
464
       overflow cannot occur. */
465
626
    destination -> gx_pixelmap_aux_data_size = (UINT)(height * width) * sizeof(GX_UBYTE);
466
626
    destination -> gx_pixelmap_aux_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_aux_data_size);
467
468
626
    if (destination -> gx_pixelmap_aux_data == GX_NULL)
469
    {
470
2
        _gx_system_memory_free((VOID *)destination -> gx_pixelmap_data);
471
472
2
        return GX_SYSTEM_MEMORY_ERROR;
473
    }
474
475
624
    put = (USHORT *)destination -> gx_pixelmap_data;
476
624
    putalpha = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
477
478
    /* Loop through the destination's pixels.  */
479
165808
    for (y = 0; y < height; y++)
480
    {
481
45591232
        for (x = 0; x < width; x++)
482
        {
483
45426048
            xx = (x - xres) * cosv + (y - yres) * sinv;
484
45426048
            yy = (y - yres) * cosv - (x - xres) * sinv;
485
486
45426048
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
487
45426048
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
488
489
45426048
            xx = GX_FIXED_VAL_TO_INT(xx);
490
45426048
            yy = GX_FIXED_VAL_TO_INT(yy);
491
492
45426048
            xx += srcxres;
493
45426048
            yy += srcyres;
494
495

45426048
            if ((xx >= -1) && (xx < src -> gx_pixelmap_width) &&
496
30252029
                (yy >= -1) && (yy < src -> gx_pixelmap_height))
497
            {
498
499

26090648
                if ((xx >= 0) && (xx < src -> gx_pixelmap_width - 1) &&
500
25701980
                    (yy >= 0) && (yy < src -> gx_pixelmap_height - 1))
501
                {
502
25584900
                    get = (USHORT *)src -> gx_pixelmap_data;
503
25584900
                    get += yy * src -> gx_pixelmap_width;
504
25584900
                    get += xx;
505
506
25584900
                    getalpha = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
507
25584900
                    getalpha += yy * src -> gx_pixelmap_width;
508
25584900
                    getalpha += xx;
509
510
25584900
                    a = *get;
511
25584900
                    alpha[0] = *getalpha;
512
513
25584900
                    b = *(get + 1);
514
25584900
                    alpha[1] = *(getalpha + 1);
515
516
25584900
                    c = *(get + src -> gx_pixelmap_width);
517
25584900
                    alpha[2] = *(getalpha + src -> gx_pixelmap_width);
518
519
25584900
                    d = *(get + src -> gx_pixelmap_width + 1);
520
25584900
                    alpha[3] = *(getalpha + src -> gx_pixelmap_width + 1);
521
                }
522
                else
523
                {
524
505748
                    get = (USHORT *)src -> gx_pixelmap_data;
525
505748
                    getalpha = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
526
527
505748
                    a = 0;
528
505748
                    b = 0;
529
505748
                    c = 0;
530
505748
                    d = 0;
531
532
505748
                    if (xx == -1)
533
                    {
534
                        /* handle left edge.  */
535
135504
                        if (yy >= 0)
536
                        {
537
134948
                            b = *(get + yy * src -> gx_pixelmap_width);
538
134948
                            alpha[1] = *(getalpha + yy * src -> gx_pixelmap_width);
539
                        }
540
541
135504
                        if (yy < src -> gx_pixelmap_height - 1)
542
                        {
543
134952
                            d = *(get + (yy + 1) * src -> gx_pixelmap_width);
544
134952
                            alpha[3] = *(getalpha + (yy + 1) * src -> gx_pixelmap_width);
545
                        }
546
                    }
547
370244
                    else if (yy == -1)
548
                    {
549
                        /* handle top edge.  */
550
117716
                        c = *(get + xx);
551
117716
                        alpha[2] = *(getalpha + xx);
552
553
117716
                        if (xx < src -> gx_pixelmap_width - 1)
554
                        {
555
117160
                            d = *(get + xx + 1);
556
117160
                            alpha[3] = *(getalpha + xx + 1);
557
                        }
558
                    }
559
252528
                    else if (xx == src -> gx_pixelmap_width - 1)
560
                    {
561
                        /* handle right edget. */
562
135448
                        a = *(get + yy * src -> gx_pixelmap_width + xx);
563
135448
                        alpha[0] = *(getalpha + yy * src -> gx_pixelmap_width + xx);
564
565
135448
                        if (yy < src -> gx_pixelmap_height - 1)
566
                        {
567
134628
                            c = *(get + (yy + 1) * src -> gx_pixelmap_width + xx);
568
134628
                            alpha[2] = *(getalpha + (yy + 1) * src -> gx_pixelmap_width + xx);
569
                        }
570
                    }
571
                    else
572
                    {
573
                        /* handle bottom edge. */
574
117080
                        a = *(get + yy * src -> gx_pixelmap_width + xx);
575
117080
                        alpha[0] = *(getalpha + yy * src -> gx_pixelmap_width + xx);
576
577
117080
                        b = *(get + yy * src -> gx_pixelmap_width + xx + 1);
578
117080
                        alpha[1] = *(getalpha + yy * src -> gx_pixelmap_width + xx + 1);
579
                    }
580
581
505748
                    if (!a)
582
                    {
583
253220
                        alpha[0] = 0;
584
                    }
585
586
505748
                    if (!b)
587
                    {
588
253720
                        alpha[1] = 0;
589
                    }
590
591
505748
                    if (!c)
592
                    {
593
253404
                        alpha[2] = 0;
594
                    }
595
596
505748
                    if (!d)
597
                    {
598
253636
                        alpha[3] = 0;
599
                    }
600
                }
601
602
26090648
                red = (USHORT)((REDVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) + \
603
26090648
                                REDVAL(b) * alpha[1] * xdiff * (256 - ydiff) +         \
604
26090648
                                REDVAL(c) * alpha[2] * ydiff * (256 - xdiff) +         \
605
26090648
                                REDVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
606
607
26090648
                green = (USHORT)((GREENVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) + \
608
26090648
                                  GREENVAL(b) * alpha[1] * xdiff * (256 - ydiff) +         \
609
26090648
                                  GREENVAL(c) * alpha[2] * ydiff * (256 - xdiff) +         \
610
26090648
                                  GREENVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
611
612
26090648
                blue = (USHORT)((BLUEVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) + \
613
26090648
                                 BLUEVAL(b) * alpha[1] * xdiff * (256 - ydiff) +         \
614
26090648
                                 BLUEVAL(c) * alpha[2] * ydiff * (256 - xdiff) +         \
615
26090648
                                 BLUEVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
616
617
26090648
                alpha[0] = (USHORT)((alpha[0] * (256 - xdiff) * (256 - ydiff) + \
618
26090648
                                     alpha[1] * xdiff * (256 - ydiff) +         \
619
26090648
                                     alpha[2] * ydiff * (256 - xdiff) +         \
620
26090648
                                     alpha[3] * xdiff * ydiff) >> 16);
621
622
26090648
                if (alpha[0])
623
                {
624
16453188
                    red /= alpha[0];
625
16453188
                    green /= alpha[0];
626
16453188
                    blue /= alpha[0];
627
                }
628
629
26090648
                red = red > 31 ? 31 : red;
630
26090648
                green = green > 63 ? 63 : green;
631
26090648
                blue = blue > 31 ? 31 : blue;
632
633
26090648
                *put++ = ASSEMBLECOLOR(red, green, blue);
634
26090648
                *putalpha++ = (GX_UBYTE)alpha[0];
635
            }
636
            else
637
            {
638
19335400
                put++;
639
19335400
                *putalpha++ = 0;
640
            }
641
        }
642
    }
643
644
624
    return GX_SUCCESS;
645
}
646
647
/**************************************************************************/
648
/*                                                                        */
649
/*  FUNCTION                                               RELEASE        */
650
/*                                                                        */
651
/*    _gx_utility_1555xrgb_pixelmap_rotate                PORTABLE C      */
652
/*                                                           6.1          */
653
/*  AUTHOR                                                                */
654
/*                                                                        */
655
/*    Kenneth Maxwell, Microsoft Corporation                              */
656
/*                                                                        */
657
/*  DESCRIPTION                                                           */
658
/*                                                                        */
659
/*    This function rotates an 1555xrgb format uncompressed pixelmap with */
660
/*    or without alpha channel.                                           */
661
/*                                                                        */
662
/*  INPUT                                                                 */
663
/*                                                                        */
664
/*    src                                   The pixelmap to be rotated    */
665
/*    angle                                 The angle to be rotated       */
666
/*    destination                           The rotated bitmap to be      */
667
/*                                            returned                    */
668
/*    rot_cx                                X coordinate of rotation      */
669
/*                                            center                      */
670
/*    rot_cy                                Y coordinate of rotation      */
671
/*                                            center                      */
672
/*                                                                        */
673
/*  OUTPUT                                                                */
674
/*                                                                        */
675
/*    status                                Completion status             */
676
/*                                                                        */
677
/*  CALLS                                                                 */
678
/*                                                                        */
679
/*     _gx_utility_1555xrgb_pixelmap_raw_rotate                           */
680
/*                                          Rotate 1555xrgb format        */
681
/*                                            pixlemap without alpha      */
682
/*     _gx_utility_1555xrgb_pixelmap_alpha_rotate                         */
683
/*                                          Rotate 1555xrgb format        */
684
/*                                            pixelmap with alpha         */
685
/*                                                                        */
686
/*  CALLED BY                                                             */
687
/*                                                                        */
688
/*    GUIX Internal Code                                                  */
689
/*                                                                        */
690
/*  RELEASE HISTORY                                                       */
691
/*                                                                        */
692
/*    DATE              NAME                      DESCRIPTION             */
693
/*                                                                        */
694
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
695
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
696
/*                                            resulting in version 6.1    */
697
/*                                                                        */
698
/**************************************************************************/
699
988
UINT _gx_utility_1555xrgb_pixelmap_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
700
{
701
UINT status;
702
703
988
    if (src -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
704
    {
705
        /* alpha, no compression */
706
628
        status = _gx_utility_1555xrgb_pixelmap_alpha_rotate(src, angle, destination, rot_cx, rot_cy);
707
    }
708
    else
709
    {
710
        /* no compression or alpha */
711
360
        status = _gx_utility_1555xrgb_pixelmap_raw_rotate(src, angle, destination, rot_cx, rot_cy);
712
    }
713
714
988
    return status;
715
}
716