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_system.h"
28 #include "gx_utility.h"
29
30 /**************************************************************************/
31 /* */
32 /* FUNCTION RELEASE */
33 /* */
34 /* _gx_utility_pixelmap_rotation PORTABLE C */
35 /* 6.1.3 */
36 /* AUTHOR */
37 /* */
38 /* Kenneth Maxwell, Microsoft Corporation */
39 /* */
40 /* DESCRIPTION */
41 /* */
42 /* This service rotate a pixelmap. */
43 /* */
44 /* INPUT */
45 /* */
46 /* src The pixelmap to rotate */
47 /* angle The angle to rotate */
48 /* destination Destination buffer for */
49 /* rotated pixelmap. */
50 /* rot_cx X coordinate of rotation */
51 /* center */
52 /* rot_cy Y coordinate of rotation */
53 /* center */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* status Completion status */
58 /* */
59 /* CALLS */
60 /* */
61 /* _gx_utility_32argb_pixelmap_rotate Rotate 32bpp pixelmap */
62 /* _gx_utility_565rgb_pixelmap_rotate Rotate 565rgb pixelmap */
63 /* _gx_utility_4444argb_pixelmap_rotate Rotate 4444argb pixelmap */
64 /* _gx_utility_8bpp_pixelmap_rotate Rotate 8bit palette pixelmap */
65 /* _gx_utility_332rgb_pixelmap_rotate Rotate 332rgb pixelmap */
66 /* _gx_utility_8bit_alphamap_rotate Rotate 8bit alphamap */
67 /* _gx_utility_4bpp_pixelmap_rotate Rotate 4bpp pixelmap */
68 /* _gx_utility_1bpp_pixelmap_rotate Rotate 1bpp pixelmap */
69 /* */
70 /* CALLED BY */
71 /* */
72 /* Application Code */
73 /* GUIX Internal Code */
74 /* */
75 /* RELEASE HISTORY */
76 /* */
77 /* DATE NAME DESCRIPTION */
78 /* */
79 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
80 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
81 /* added 565bgr format support,*/
82 /* resulting in version 6.1 */
83 /* 12-31-2020 Kenneth Maxwell Modified comment(s), added */
84 /* display rotation support, */
85 /* resulting in version 6.1.3 */
86 /* */
87 /**************************************************************************/
_gx_utility_pixelmap_rotate(GX_PIXELMAP * src,INT angle,GX_PIXELMAP * destination,INT * rot_cx,INT * rot_cy)88 UINT _gx_utility_pixelmap_rotate(GX_PIXELMAP *src, INT angle, GX_PIXELMAP *destination, INT *rot_cx, INT *rot_cy)
89 {
90 UINT status = GX_SUCCESS;
91 GX_PIXELMAP rotated_src;
92
93 /* Limit pixelmap width to 14bits. */
94 if (src -> gx_pixelmap_width > GX_MAX_PIXELMAP_RESOLUTION)
95 {
96 return GX_INVALID_WIDTH;
97 }
98
99 /* Limit pixelmap height to 14bits. */
100 if (src -> gx_pixelmap_height > GX_MAX_PIXELMAP_RESOLUTION)
101 {
102 return GX_INVALID_HEIGHT;
103 }
104
105 if ((src -> gx_pixelmap_flags & GX_PIXELMAP_ROTATED_90) ||
106 (src -> gx_pixelmap_flags & GX_PIXELMAP_ROTATED_270))
107 {
108 rotated_src = (*src);
109 GX_SWAP_VALS(rotated_src.gx_pixelmap_width, rotated_src.gx_pixelmap_height);
110 src = &rotated_src;
111
112 if (rot_cx && rot_cy)
113 {
114 GX_SWAP_VALS(*rot_cx, *rot_cy);
115
116 if (src -> gx_pixelmap_flags & GX_PIXELMAP_ROTATED_90)
117 {
118 *rot_cy = src -> gx_pixelmap_height - 1 - (*rot_cy);
119 }
120 else
121 {
122 *rot_cx = src -> gx_pixelmap_width - 1 - (*rot_cx);
123 }
124 }
125 }
126
127 angle = angle % 360;
128
129 if (angle == 0)
130 {
131 return GX_INVALID_VALUE;
132 }
133 else if (angle < 0)
134 {
135 angle += 360;
136 }
137
138 if ((_gx_system_memory_allocator == GX_NULL) || (_gx_system_memory_free == GX_NULL))
139 {
140 return GX_SYSTEM_MEMORY_ERROR;
141 }
142
143 if (src -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
144 {
145 return GX_INVALID_FORMAT;
146 }
147
148 if ((angle % 90) == 0)
149 {
150 _gx_utility_pixelmap_simple_rotate(src, angle, destination, rot_cx, rot_cy);
151 }
152 else
153 {
154 memset(destination, 0, sizeof(GX_PIXELMAP));
155 destination -> gx_pixelmap_format = src -> gx_pixelmap_format;
156 destination -> gx_pixelmap_version_major = src -> gx_pixelmap_version_major;
157 destination -> gx_pixelmap_version_minor = src -> gx_pixelmap_version_major;
158 destination -> gx_pixelmap_flags = src -> gx_pixelmap_flags;
159
160 switch (src -> gx_pixelmap_format)
161 {
162 case GX_COLOR_FORMAT_32ARGB:
163 case GX_COLOR_FORMAT_24XRGB:
164 /* Call 32argb pixelmap rotate. */
165 status = _gx_utility_32argb_pixelmap_rotate(src, angle, destination, rot_cx, rot_cy);
166 break;
167
168 case GX_COLOR_FORMAT_565RGB:
169 case GX_COLOR_FORMAT_565BGR:
170 /* Call 565rgb pixelmap rotate. */
171 status = _gx_utility_565rgb_pixelmap_rotate(src, angle, destination, rot_cx, rot_cy);
172 break;
173
174 case GX_COLOR_FORMAT_1555XRGB:
175 status = _gx_utility_1555xrgb_pixelmap_rotate(src, angle, destination, rot_cx, rot_cy);
176 break;
177
178 case GX_COLOR_FORMAT_4444ARGB:
179 status = _gx_utility_4444argb_pixelmap_rotate(src, angle, destination, rot_cx, rot_cy);
180 break;
181
182 case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
183 status = _gx_utility_332rgb_pixelmap_rotate(src, angle, destination, rot_cx, rot_cy);
184 break;
185
186 case GX_COLOR_FORMAT_8BIT_PALETTE:
187 /* Call 8bpp pixelmap rotate. */
188 status = _gx_utility_8bpp_pixelmap_rotate(src, angle, destination, rot_cx, rot_cy);
189 break;
190
191 case GX_COLOR_FORMAT_8BIT_ALPHAMAP:
192 /* Call 8bit alphamap rotate. */
193 status = _gx_utility_8bit_alphamap_rotate(src, angle, destination, rot_cx, rot_cy);
194 break;
195
196 case GX_COLOR_FORMAT_4BIT_GRAY:
197 status = _gx_utility_4bpp_pixelmap_rotate(src, angle, destination, rot_cx, rot_cy);
198 break;
199
200 case GX_COLOR_FORMAT_MONOCHROME:
201 status = _gx_utility_1bpp_pixelmap_rotate(src, angle, destination, rot_cx, rot_cy);
202 break;
203
204 default:
205 return GX_INVALID_FORMAT;
206 }
207 }
208
209 if ((src -> gx_pixelmap_flags & GX_PIXELMAP_ROTATED_90) ||
210 (src -> gx_pixelmap_flags & GX_PIXELMAP_ROTATED_270))
211 {
212 GX_SWAP_VALS(destination -> gx_pixelmap_width, destination -> gx_pixelmap_height);
213
214 if (rot_cx && rot_cy)
215 {
216 GX_SWAP_VALS(*rot_cx, *rot_cy);
217
218 if (src -> gx_pixelmap_flags & GX_PIXELMAP_ROTATED_90)
219 {
220 *rot_cx = destination -> gx_pixelmap_width - 1 - (*rot_cx);
221 }
222 else
223 {
224 *rot_cy = destination -> gx_pixelmap_height - 1 - (*rot_cy);
225 }
226 }
227 }
228
229 return status;
230 }
231
232