GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_utility_4bpp_pixelmap_rotate.c Lines: 321 321 100.0 %
Date: 2024-12-05 08:52:37 Branches: 138 138 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 GX_SOURCE_CODE
22
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_display.h"
28
#include "gx_context.h"
29
#include "gx_utility.h"
30
#include "gx_system.h"
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _gx_utility_4bpp_pixelmap_rotate                    PORTABLE C      */
37
/*                                                           6.1          */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Kenneth Maxwell, Microsoft Corporation                              */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    4bpp pixelmap rotation function that handles uncompress, with or    */
45
/*    without alpha channel.                                              */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    src                                   The pixelmap to be rotated    */
50
/*    angle                                 The angle to be rotated       */
51
/*    destination                           The rotated bitmap to be      */
52
/*                                            returned                    */
53
/*    rot_cx                                X coordinate of rotation      */
54
/*                                            center                      */
55
/*    rot_cy                                Y coordinate of rotation      */
56
/*                                            center                      */
57
/*                                                                        */
58
/*  OUTPUT                                                                */
59
/*                                                                        */
60
/*    None                                                                */
61
/*                                                                        */
62
/*  CALLS                                                                 */
63
/*                                                                        */
64
/*    _gx_system_memory_allocator           Memory Allocation routine     */
65
/*    _gx_utility_math_cos                  Compute the cosine value      */
66
/*    _gx_utility_math_sin                  Compute the sine value        */
67
/*                                                                        */
68
/*  CALLED BY                                                             */
69
/*                                                                        */
70
/*    Application Code                                                    */
71
/*                                                                        */
72
/*  RELEASE HISTORY                                                       */
73
/*                                                                        */
74
/*    DATE              NAME                      DESCRIPTION             */
75
/*                                                                        */
76
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
77
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
78
/*                                            resulting in version 6.1    */
79
/*                                                                        */
80
/**************************************************************************/
81
730
UINT _gx_utility_4bpp_pixelmap_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
82
{
83
GX_UBYTE *putrow;
84
GX_UBYTE *put;
85
GX_UBYTE *get;
86
INT       srcxres;
87
INT       srcyres;
88
INT       cosv;
89
INT       sinv;
90
INT       idxminx, idxmaxx, idxmaxy;
91
730
INT       mx[] = {-1, 1, 1, -1};
92
730
INT       my[] = {1, 1, -1, -1};
93
INT       xres;
94
INT       yres;
95
INT       width, height;
96
INT       x, y;
97
INT       xx, yy;
98
INT       putstride;
99
INT       getstride;
100
INT       putauxstride;
101
INT       getauxstride;
102
GX_UBYTE  putmask;
103
GX_UBYTE  pixel;
104
GX_UBYTE *putaux;
105
GX_UBYTE *putauxrow;
106
GX_UBYTE  putauxmask;
107
GX_UBYTE  transmask;
108
GX_UBYTE *getaux;
109
730
GX_BOOL   draw = GX_TRUE;
110
111
730
    idxminx = (angle / 90) & 0x3;
112
730
    idxmaxx = (idxminx + 2) & 0x3;
113
730
    idxmaxy = (idxminx + 1) & 0x3;
114
115
    /* Calculate the source x and y center. */
116
730
    srcxres = src -> gx_pixelmap_width >> 1;
117
730
    srcyres = src -> gx_pixelmap_height >> 1;
118
119
730
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
120
730
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
121
122
730
    xres = GX_FIXED_VAL_TO_INT((mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
123
730
    yres = GX_FIXED_VAL_TO_INT((my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
124
125
    /* Calculate destination width and height. */
126
730
    width = (xres << 1);
127
730
    height = (yres << 1);
128
129

730
    if (rot_cx && rot_cy)
130
    {
131
        /* Calculate the new rotation axis. */
132
712
        x = ((*rot_cx) - srcxres) * cosv - ((*rot_cy) - srcyres) * sinv;
133
712
        y = ((*rot_cy) - srcyres) * cosv + ((*rot_cx) - srcxres) * sinv;
134
135
712
        x = GX_FIXED_VAL_TO_INT(x) + xres;
136
712
        y = GX_FIXED_VAL_TO_INT(y) + yres;
137
138
712
        srcxres = *rot_cx;
139
712
        srcyres = *rot_cy;
140
141
712
        *rot_cx = x;
142
712
        *rot_cy = y;
143
144
712
        xres = *rot_cx;
145
712
        yres = *rot_cy;
146
    }
147
148
    /* Set width and height of destination pixelmap.  */
149
730
    destination -> gx_pixelmap_width = (GX_VALUE)width;
150
730
    destination -> gx_pixelmap_height = (GX_VALUE)height;
151
730
    destination -> gx_pixelmap_flags |= GX_PIXELMAP_TRANSPARENT;
152
730
    putstride = (width + 1) >> 1;
153
730
    putauxstride = (width + 7) >> 3;
154
730
    getstride = (src -> gx_pixelmap_width + 1) >> 1;
155
730
    getauxstride = 0;
156
157
730
    if (src -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
158
    {
159
362
        getauxstride = (src -> gx_pixelmap_width + 7) >> 3;
160
    }
161
162
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
163
       overflow cannot occur. */
164
730
    destination -> gx_pixelmap_data_size = (UINT)(putstride * height) * sizeof(GX_UBYTE);
165
166
    /* Allocate memory for destination pixelmap to load pixel information.  */
167
730
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
168
169
730
    if (destination -> gx_pixelmap_data == GX_NULL)
170
    {
171
10
        return GX_SYSTEM_MEMORY_ERROR;
172
    }
173
174
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
175
       overflow cannot occur. */
176
720
    destination -> gx_pixelmap_aux_data_size = (UINT)(putauxstride * height) * sizeof(GX_UBYTE);
177
178
    /* Allocate memory for destination pixelmap to load pixel information.  */
179
720
    destination -> gx_pixelmap_aux_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_aux_data_size);
180
181
720
    if (destination -> gx_pixelmap_aux_data == GX_NULL)
182
    {
183
2
        _gx_system_memory_free((void *)destination -> gx_pixelmap_data);
184
2
        return GX_SYSTEM_MEMORY_ERROR;
185
    }
186
187
718
    putrow = (GX_UBYTE *)destination -> gx_pixelmap_data;
188
718
    putauxrow = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
189
190
    /* For every pixel in destination bitmap, find its position in source bitmap,
191
       and set the pixel with the value in source bitmap.  */
192
192374
    for (y = 0; y < height; y++)
193
    {
194
191656
        put = putrow;
195
191656
        putaux = putauxrow;
196
191656
        putmask = 0xf0;
197
191656
        putauxmask = 0x80;
198
199
51909848
        for (x = 0; x < width; x++)
200
        {
201
51718192
            xx = GX_FIXED_VAL_TO_INT((x - xres) * cosv + (y - yres) * sinv);
202
51718192
            yy = GX_FIXED_VAL_TO_INT((y - yres) * cosv - (x - xres) * sinv);
203
204
51718192
            xx += srcxres;
205
51718192
            yy += srcyres;
206
207
51718192
            if (getauxstride)
208
            {
209
31705840
                getaux = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
210
31705840
                getaux += yy * getauxstride;
211
31705840
                getaux += xx >> 3;
212
31705840
                transmask = (GX_UBYTE)(0x80 >> (xx & 0x07));
213
214
31705840
                if (transmask & (*getaux))
215
                {
216
11588464
                    draw = GX_FALSE;
217
                }
218
                else
219
                {
220
20117376
                    draw = GX_TRUE;
221
                }
222
            }
223
224
            /* Set bits first. */
225
51718192
            *put &= (GX_UBYTE)(~putmask);
226


51718192
            if (draw && (xx >= 0) && (xx < src -> gx_pixelmap_width) &&
227
28645067
                (yy >= 0) && (yy < src -> gx_pixelmap_height))
228
            {
229
23948788
                get = (GX_UBYTE *)src -> gx_pixelmap_data;
230
23948788
                get += yy * getstride;
231
23948788
                get += xx >> 1;
232
233
23948788
                if (xx & 1)
234
                {
235
11971964
                    pixel = *get & 0x0f;
236
                }
237
                else
238
                {
239
11976824
                    pixel = (*get & 0xf0) >> 4;
240
                }
241
23948788
                pixel |= (GX_UBYTE)(pixel << 4);
242
                /* set pixel */
243
23948788
                *put |= pixel & putmask;
244
                /* Set transparent info. */
245
23948788
                *putaux &= (GX_UBYTE)(~putauxmask);
246
            }
247
            else
248
            {
249
27769404
                *putaux |= putauxmask;
250
            }
251
252
51718192
            putauxmask >>= 1;
253
51718192
            if (putauxmask == 0)
254
            {
255
6396372
                putaux++;
256
6396372
                putauxmask = 0x80;
257
            }
258
259
51718192
            putmask >>= 4;
260
51718192
            if (putmask == 0)
261
            {
262
25859096
                put++;
263
25859096
                putmask = 0xf0;
264
            }
265
        }
266
191656
        putrow += putstride;
267
191656
        putauxrow += putauxstride;
268
    }
269
270
718
    return GX_SUCCESS;
271
}
272
/**************************************************************************/
273
/*                                                                        */
274
/*  FUNCTION                                               RELEASE        */
275
/*                                                                        */
276
/*    _gx_utility_4bpp_pixelmap_simple_raw_rotate         PORTABLE C      */
277
/*                                                           6.1          */
278
/*  AUTHOR                                                                */
279
/*                                                                        */
280
/*    Kenneth Maxwell, Microsoft Corporation                              */
281
/*                                                                        */
282
/*  DESCRIPTION                                                           */
283
/*                                                                        */
284
/*    Internal helper function that handles 90, 180 and 270 degree        */
285
/*      rotation of an uncompressed pixelmap with or wihout alpha.        */
286
/*                                                                        */
287
/*  INPUT                                                                 */
288
/*                                                                        */
289
/*    src                                   The pixelmap to be rotated    */
290
/*    angle                                 The angle to be rotated       */
291
/*    destination                           The rotated bitmap to be      */
292
/*                                            returned                    */
293
/*    rot_cx                                X coordinate of rotation      */
294
/*                                            center                      */
295
/*    rot_cy                                Y coordinate of rotation      */
296
/*                                            center                      */
297
/*                                                                        */
298
/*  OUTPUT                                                                */
299
/*                                                                        */
300
/*    None                                                                */
301
/*                                                                        */
302
/*  CALLS                                                                 */
303
/*                                                                        */
304
/*    _gx_system_memory_allocator           Memory Allocation routine     */
305
/*                                                                        */
306
/*  CALLED BY                                                             */
307
/*                                                                        */
308
/*   _gx_utility_4bpp_pixelmap_simple_rotate                              */
309
/*                                                                        */
310
/*  RELEASE HISTORY                                                       */
311
/*                                                                        */
312
/*    DATE              NAME                      DESCRIPTION             */
313
/*                                                                        */
314
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
315
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
316
/*                                            resulting in version 6.1    */
317
/*                                                                        */
318
/**************************************************************************/
319
39
static UINT _gx_utility_4bpp_pixelmap_simple_raw_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
320
{
321
GX_UBYTE *put;
322
GX_UBYTE *putrow;
323
GX_UBYTE *get;
324
INT       width, height;
325
INT       x, y;
326
INT       putstride;
327
GX_UBYTE  putmask;
328
GX_UBYTE  pixel;
329
INT       getstride;
330
331
39
    getstride = (src -> gx_pixelmap_width + 1) >> 1;
332
333
39
    width = src -> gx_pixelmap_height;
334
39
    height = src -> gx_pixelmap_width;
335
336
39
    if (angle == 180)
337
    {
338
13
        GX_SWAP_VALS(width, height);
339
    }
340
341
39
    putstride = (width + 1) >> 1;
342
343
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
344
       overflow cannot occur. */
345
39
    destination -> gx_pixelmap_data_size = (UINT)(putstride * height) * sizeof(GX_UBYTE);
346
39
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
347
348
39
    if (destination -> gx_pixelmap_data == GX_NULL)
349
    {
350
12
        return GX_SYSTEM_MEMORY_ERROR;
351
    }
352
353
27
    if (angle == 90)
354
    {
355
9
        putrow = (GX_UBYTE *)destination -> gx_pixelmap_data;
356
357
1929
        for (y = 0; y < height; y++)
358
        {
359
1920
            put = putrow;
360
1920
            putmask = 0xf0;
361
260400
            for (x = 0; x < width; x++)
362
            {
363
258480
                get = (GX_UBYTE *)src -> gx_pixelmap_data;
364
258480
                get += (width - 1 - x) * getstride;
365
258480
                get += y >> 1;
366
367
258480
                if (y & 1)
368
                {
369
129240
                    pixel = *get & 0x0f;
370
                }
371
                else
372
                {
373
129240
                    pixel = (*get & 0xf0) >> 4;
374
                }
375
258480
                pixel |= (GX_UBYTE)(pixel << 4);
376
258480
                *put &= (GX_UBYTE)(~putmask);
377
258480
                *put |= pixel & putmask;
378
379
258480
                putmask >>= 4;
380
258480
                if (putmask == 0)
381
                {
382
128880
                    put++;
383
128880
                    putmask = 0xf0;
384
                }
385
            }
386
1920
            putrow += putstride;
387
        }
388
389

9
        if (rot_cx && rot_cy)
390
        {
391
1
            x = *rot_cx;
392
1
            y = *rot_cy;
393
394
1
            *rot_cx = (width - 1 - y);
395
1
            *rot_cy = x;
396
        }
397
    }
398
18
    else if (angle == 180)
399
    {
400
9
        putrow = (GX_UBYTE *)destination -> gx_pixelmap_data;
401
402
1235
        for (y = 0; y < height; y++)
403
        {
404
1226
            put = putrow;
405
1226
            putmask = 0xf0;
406
259706
            for (x = 0; x < width; x++)
407
            {
408
258480
                get = (GX_UBYTE *)src -> gx_pixelmap_data;
409
258480
                get += (height - 1 - y) * getstride;
410
258480
                get += (width - 1 - x) >> 1;
411
412
258480
                if ((width - 1 - x) & 1)
413
                {
414
129240
                    pixel = *get & 0x0f;
415
                }
416
                else
417
                {
418
129240
                    pixel = (*get & 0xf0) >> 4;
419
                }
420
258480
                pixel |= (GX_UBYTE)(pixel << 4);
421
258480
                *put &= (GX_UBYTE)(~putmask);
422
258480
                *put |= pixel & putmask;
423
424
258480
                putmask >>= 4;
425
258480
                if (putmask == 0)
426
                {
427
129240
                    put++;
428
129240
                    putmask = 0xf0;
429
                }
430
            }
431
1226
            putrow += putstride;
432
        }
433
434

9
        if (rot_cx && rot_cy)
435
        {
436
1
            x = *rot_cx;
437
1
            y = *rot_cy;
438
439
1
            *rot_cx = (width - 1 - x);
440
1
            *rot_cy = (height - 1 - y);
441
        }
442
    }
443
    else
444
    {
445
        /* angle = 270. */
446
9
        putrow = (GX_UBYTE *)destination -> gx_pixelmap_data;
447
448
1929
        for (y = 0; y < height; y++)
449
        {
450
1920
            put = putrow;
451
1920
            putmask = 0xf0;
452
453
260400
            for (x = 0; x < width; x++)
454
            {
455
258480
                get = (GX_UBYTE *)src -> gx_pixelmap_data;
456
258480
                get += x * getstride;
457
258480
                get += (height - 1 - y) >> 1;
458
459
258480
                if ((height - 1 - y) & 1)
460
                {
461
129240
                    pixel = *get & 0x0f;
462
                }
463
                else
464
                {
465
129240
                    pixel = (*get & 0xf0) >> 4;
466
                }
467
258480
                pixel |= (GX_UBYTE)(pixel << 4);
468
258480
                *put &= (GX_UBYTE)(~putmask);
469
258480
                *put |= pixel & putmask;
470
471
258480
                putmask >>= 4;
472
258480
                if (putmask == 0)
473
                {
474
128880
                    put++;
475
128880
                    putmask = 0xf0;
476
                }
477
            }
478
1920
            putrow += putstride;
479
        }
480
481

9
        if (rot_cx && rot_cy)
482
        {
483
1
            x = *rot_cx;
484
1
            y = *rot_cy;
485
486
1
            *rot_cx = y;
487
1
            *rot_cy = (height - 1 - x);
488
        }
489
    }
490
491
27
    destination -> gx_pixelmap_height = (GX_VALUE)height;
492
27
    destination -> gx_pixelmap_width  = (GX_VALUE)width;
493
494
27
    return GX_SUCCESS;
495
}
496
497
/**************************************************************************/
498
/*                                                                        */
499
/*  FUNCTION                                               RELEASE        */
500
/*                                                                        */
501
/*    _gx_utility_4bpp_pixelmap_simple_transparent_rotate PORTABLE C      */
502
/*                                                           6.1          */
503
/*  AUTHOR                                                                */
504
/*                                                                        */
505
/*    Kenneth Maxwell, Microsoft Corporation                              */
506
/*                                                                        */
507
/*  DESCRIPTION                                                           */
508
/*                                                                        */
509
/*    Internal helper function that handles 90, 180 and 270 degree        */
510
/*      rotation of an uncompressed pixelmap with or wihout alpha.        */
511
/*                                                                        */
512
/*  INPUT                                                                 */
513
/*                                                                        */
514
/*    src                                   The pixelmap to be rotated    */
515
/*    angle                                 The angle to be rotated       */
516
/*    destination                           The rotated bitmap to be      */
517
/*                                            returned                    */
518
/*    rot_cx                                X coordinate of rotation      */
519
/*                                            center                      */
520
/*    rot_cy                                Y coordinate of rotation      */
521
/*                                            center                      */
522
/*                                                                        */
523
/*  OUTPUT                                                                */
524
/*                                                                        */
525
/*    None                                                                */
526
/*                                                                        */
527
/*  CALLS                                                                 */
528
/*                                                                        */
529
/*    _gx_system_memory_allocator           Memory Allocation routine     */
530
/*                                                                        */
531
/*  CALLED BY                                                             */
532
/*                                                                        */
533
/*   _gx_utility_4bpp_pixelmap_simple_rotate                              */
534
/*                                                                        */
535
/*  RELEASE HISTORY                                                       */
536
/*                                                                        */
537
/*    DATE              NAME                      DESCRIPTION             */
538
/*                                                                        */
539
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
540
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
541
/*                                            resulting in version 6.1    */
542
/*                                                                        */
543
/**************************************************************************/
544
21
static UINT _gx_utility_4bpp_pixelmap_simple_transparent_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
545
{
546
GX_UBYTE *put;
547
GX_UBYTE *putrow;
548
GX_UBYTE *putaux;
549
GX_UBYTE *putauxrow;
550
GX_UBYTE *get;
551
INT       width, height;
552
INT       x, y;
553
INT       putstride;
554
INT       putauxstride;
555
GX_UBYTE  putmask;
556
GX_UBYTE  pixel;
557
GX_UBYTE  transmask;
558
GX_UBYTE  putauxmask;
559
GX_UBYTE *getaux;
560
INT       getstride;
561
INT       getauxstride;
562
563
21
    getstride = (src -> gx_pixelmap_width + 1) >> 1;
564
21
    getauxstride = (src -> gx_pixelmap_width + 7) >> 3;
565
566
21
    width = src -> gx_pixelmap_height;
567
21
    height = src -> gx_pixelmap_width;
568
569
21
    if (angle == 180)
570
    {
571
7
        GX_SWAP_VALS(width, height);
572
    }
573
574
21
    putstride = (width + 1) >> 1;
575
21
    putauxstride = (width + 7) >> 3;
576
577
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
578
       overflow cannot occur. */
579
21
    destination -> gx_pixelmap_data_size = (UINT)(putstride * height) * sizeof(GX_UBYTE);
580
21
    destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
581
582
21
    if (destination -> gx_pixelmap_data == GX_NULL)
583
    {
584
6
        return GX_SYSTEM_MEMORY_ERROR;
585
    }
586
587
    /* Safe int math is not required here, calling function limits max width, height to 14 bits so
588
       overflow cannot occur. */
589
15
    destination -> gx_pixelmap_aux_data_size = (UINT)(putauxstride * height) * sizeof(GX_UBYTE);
590
15
    destination -> gx_pixelmap_aux_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_aux_data_size);
591
592
15
    if (destination -> gx_pixelmap_aux_data == GX_NULL)
593
    {
594
6
        _gx_system_memory_free((void *)destination -> gx_pixelmap_data);
595
6
        return GX_SYSTEM_MEMORY_ERROR;
596
    }
597
598
9
    if (angle == 90)
599
    {
600
3
        putrow = (GX_UBYTE *)destination -> gx_pixelmap_data;
601
3
        putauxrow = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
602
603
588
        for (y = 0; y < height; y++)
604
        {
605
585
            put = putrow;
606
585
            putaux = putauxrow;
607
585
            putmask = 0xf0;
608
585
            putauxmask = 0x80;
609
156780
            for (x = 0; x < width; x++)
610
            {
611
                /* set bits first. */
612
156195
                *put &= (GX_UBYTE)(~putmask);
613
156195
                getaux = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
614
156195
                getaux += (width - 1 - x) * getauxstride;
615
156195
                getaux += y >> 3;
616
617
156195
                transmask = (GX_UBYTE)(0x80 >> (y & 0x07));
618
156195
                if (transmask & (*getaux))
619
                {
620
                    /* transparent pixel, set destination true */
621
47541
                    *putaux |= putauxmask;
622
                }
623
                else
624
                {
625
                    /* not transparent, set destination bit to 0. */
626
108654
                    *putaux &= (GX_UBYTE)(~putauxmask);
627
628
108654
                    get = (GX_UBYTE *)src -> gx_pixelmap_data;
629
108654
                    get += (width - 1 - x) * getstride;
630
108654
                    get += y >> 1;
631
632
108654
                    if (y & 1)
633
                    {
634
54306
                        pixel = *get & 0x0f;
635
                    }
636
                    else
637
                    {
638
54348
                        pixel = (*get & 0xf0) >> 4;
639
                    }
640
108654
                    pixel |= (GX_UBYTE)(pixel << 4);
641
642
                    /* set data. */
643
108654
                    *put |= pixel & putmask;
644
                }
645
646
156195
                putmask >>= 4;
647
156195
                if (putmask == 0)
648
                {
649
77805
                    put++;
650
77805
                    putmask = 0xf0;
651
                }
652
156195
                putauxmask >>= 1;
653
156195
                if (putauxmask == 0)
654
                {
655
19305
                    putaux++;
656
19305
                    putauxmask = 0x80;
657
                }
658
            }
659
585
            putrow += putstride;
660
585
            putauxrow += putauxstride;
661
        }
662
663

3
        if (rot_cx && rot_cy)
664
        {
665
1
            x = *rot_cx;
666
1
            y = *rot_cy;
667
668
1
            *rot_cx = (width - 1 - y);
669
1
            *rot_cy = x;
670
        }
671
    }
672
6
    else if (angle == 180)
673
    {
674
3
        putrow = (GX_UBYTE *)destination -> gx_pixelmap_data;
675
3
        putauxrow = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
676
677
804
        for (y = 0; y < height; y++)
678
        {
679
801
            put = putrow;
680
801
            putaux = putauxrow;
681
801
            putmask = 0xf0;
682
801
            putauxmask = 0x80;
683
156996
            for (x = 0; x < width; x++)
684
            {
685
                /* set bits first. */
686
156195
                *put &= (GX_UBYTE)(~putmask);
687
156195
                getaux = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
688
156195
                getaux += (height - 1 - y) * getauxstride;
689
156195
                getaux += (width - 1 - x) >> 3;
690
691
156195
                transmask = (GX_UBYTE)(0x80 >> ((width - 1 - x) & 0x07));
692
156195
                if (transmask & (*getaux))
693
                {
694
                    /* transparent pixel, set destination true */
695
47541
                    *putaux |= putauxmask;
696
                }
697
                else
698
                {
699
                    /* not transparent, set destination bit to 0. */
700
108654
                    *putaux &= (GX_UBYTE)(~putauxmask);
701
702
108654
                    get = (GX_UBYTE *)src -> gx_pixelmap_data;
703
108654
                    get += (height - 1 - y) * getstride;
704
108654
                    get += (width - 1 - x) >> 1;
705
706
108654
                    if ((width - 1 - x) & 1)
707
                    {
708
54306
                        pixel = *get & 0x0f;
709
                    }
710
                    else
711
                    {
712
54348
                        pixel = (*get & 0xf0) >> 4;
713
                    }
714
108654
                    pixel |= (GX_UBYTE)(pixel << 4);
715
108654
                    *put |= pixel & putmask;
716
                }
717
156195
                putmask >>= 4;
718
156195
                if (putmask == 0)
719
                {
720
77697
                    put++;
721
77697
                    putmask = 0xf0;
722
                }
723
156195
                putauxmask >>= 1;
724
156195
                if (putauxmask == 0)
725
                {
726
19224
                    putaux++;
727
19224
                    putauxmask = 0x80;
728
                }
729
            }
730
801
            putrow += putstride;
731
801
            putauxrow += putauxstride;
732
        }
733

3
        if (rot_cx && rot_cy)
734
        {
735
1
            x = *rot_cx;
736
1
            y = *rot_cy;
737
738
1
            *rot_cx = (width - 1 - x);
739
1
            *rot_cy = (height - 1 - y);
740
        }
741
    }
742
    else
743
    {
744
        /* angle = 270. */
745
3
        putrow = (GX_UBYTE *)destination -> gx_pixelmap_data;
746
3
        putauxrow = (GX_UBYTE *)destination -> gx_pixelmap_aux_data;
747
748
588
        for (y = 0; y < height; y++)
749
        {
750
585
            put = putrow;
751
585
            putaux = putauxrow;
752
585
            putmask = 0xf0;
753
585
            putauxmask = 0x80;
754
755
156780
            for (x = 0; x < width; x++)
756
            {
757
                /* set bits first. */
758
156195
                *put &= (GX_UBYTE)(~putmask);
759
156195
                getaux = (GX_UBYTE *)src -> gx_pixelmap_aux_data;
760
156195
                getaux += x * getauxstride;
761
156195
                getaux += (height - 1 - y) >> 3;
762
763
156195
                transmask = (GX_UBYTE)(0x80 >> ((height - 1 - y) & 0x07));
764
156195
                if (transmask & (*getaux))
765
                {
766
                    /* transparent pixel, set destination true */
767
47541
                    *putaux |= putauxmask;
768
                }
769
                else
770
                {
771
                    /* not transparent, set destination bit to 0. */
772
108654
                    *putaux &= (GX_UBYTE)(~putauxmask);
773
774
108654
                    get = (GX_UBYTE *)src -> gx_pixelmap_data;
775
108654
                    get += x * getstride;
776
108654
                    get += (height - 1 - y) >> 1;
777
778
108654
                    if ((height - 1 - y) & 1)
779
                    {
780
54306
                        pixel = *get & 0x0f;
781
                    }
782
                    else
783
                    {
784
54348
                        pixel = (*get & 0xf0) >> 4;
785
                    }
786
108654
                    pixel |= (GX_UBYTE)(pixel << 4);
787
108654
                    *put |= pixel & putmask;
788
                }
789
156195
                putmask >>= 4;
790
156195
                if (putmask == 0)
791
                {
792
77805
                    put++;
793
77805
                    putmask = 0xf0;
794
                }
795
156195
                putauxmask >>= 1;
796
156195
                if (putauxmask == 0)
797
                {
798
19305
                    putaux++;
799
19305
                    putauxmask = 0x80;
800
                }
801
            }
802
585
            putrow += putstride;
803
585
            putauxrow += putauxstride;
804
        }
805
806

3
        if (rot_cx && rot_cy)
807
        {
808
1
            x = *rot_cx;
809
1
            y = *rot_cy;
810
811
1
            *rot_cx = y;
812
1
            *rot_cy = (height - 1 - x);
813
        }
814
    }
815
816
9
    destination -> gx_pixelmap_height = (GX_VALUE)height;
817
9
    destination -> gx_pixelmap_width = (GX_VALUE)width;
818
819
9
    return GX_SUCCESS;
820
}
821
/**************************************************************************/
822
/*                                                                        */
823
/*  FUNCTION                                               RELEASE        */
824
/*                                                                        */
825
/*    _gx_utility_4bpp_pixelmap_simple_rotate             PORTABLE C      */
826
/*                                                           6.1          */
827
/*  AUTHOR                                                                */
828
/*                                                                        */
829
/*    Kenneth Maxwell, Microsoft Corporation                              */
830
/*                                                                        */
831
/*  DESCRIPTION                                                           */
832
/*                                                                        */
833
/*    Internal helper function that handles 90, 180 and 270 degree        */
834
/*      rotation of an uncompressed pixelmap with or wihout alpha.        */
835
/*                                                                        */
836
/*  INPUT                                                                 */
837
/*                                                                        */
838
/*    src                                   The pixelmap to be rotated    */
839
/*    angle                                 The angle to be rotated       */
840
/*    destination                           The rotated bitmap to be      */
841
/*                                            returned                    */
842
/*    rot_cx                                X coordinate of rotation      */
843
/*                                            center                      */
844
/*    rot_cy                                Y coordinate of rotation      */
845
/*                                            center                      */
846
/*                                                                        */
847
/*  OUTPUT                                                                */
848
/*                                                                        */
849
/*    None                                                                */
850
/*                                                                        */
851
/*  CALLS                                                                 */
852
/*                                                                        */
853
/*    _gx_utility_4bpp_pixelmap_simple_transparent_rotate                 */
854
/*                                          Real pixelmap rotate function */
855
/*    _gx_utility_4bpp_pixelmap_simple_raw_rotate                         */
856
/*                                          Real pixelmap rotate function */
857
/*                                                                        */
858
/*  CALLED BY                                                             */
859
/*                                                                        */
860
/*    GUIX Internal Code                                                  */
861
/*                                                                        */
862
/*  RELEASE HISTORY                                                       */
863
/*                                                                        */
864
/*    DATE              NAME                      DESCRIPTION             */
865
/*                                                                        */
866
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
867
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
868
/*                                            resulting in version 6.1    */
869
/*                                                                        */
870
/**************************************************************************/
871
60
UINT _gx_utility_4bpp_pixelmap_simple_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
872
{
873
UINT status;
874
875
60
    if (src -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
876
    {
877
        /* with transparent, no compression */
878
21
        status = _gx_utility_4bpp_pixelmap_simple_transparent_rotate(src, angle, destination, rot_cx, rot_cy);
879
    }
880
    else
881
    {
882
        /* no compression or transparent */
883
39
        status = _gx_utility_4bpp_pixelmap_simple_raw_rotate(src, angle, destination, rot_cx, rot_cy);
884
    }
885
886
60
    return status;
887
}
888