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 #define GX_SOURCE_CODE
21
22
23 /* Include necessary system files. */
24
25 #include "gx_api.h"
26 #include "gx_utility.h"
27 #include "gx_system.h"
28
29 /**************************************************************************/
30 /* */
31 /* FUNCTION RELEASE */
32 /* */
33 /* _gx_utility_1bpp_pixelmap_raw_resize PORTABLE C */
34 /* 6.1.7 */
35 /* AUTHOR */
36 /* */
37 /* Kenneth Maxwell, Microsoft Corporation */
38 /* */
39 /* DESCRIPTION */
40 /* */
41 /* 1bpp pixelmap resize function that handles uncompress, without */
42 /* transparent channel. */
43 /* */
44 /* INPUT */
45 /* */
46 /* src The source pixelmap */
47 /* destination The resized pixelmap to be */
48 /* returned */
49 /* width New width */
50 /* height New height */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* status Completion status */
55 /* */
56 /* CALLS */
57 /* */
58 /* _gx_system_memory_allocator Memory Allocation routine */
59 /* */
60 /* CALLED BY */
61 /* */
62 /* _gx_utility_1bpp_pixelmap_resize */
63 /* */
64 /* RELEASE HISTORY */
65 /* */
66 /* DATE NAME DESCRIPTION */
67 /* */
68 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
69 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
70 /* resulting in version 6.1 */
71 /* 06-02-2021 Kenneth Maxwell Modified comment(s), */
72 /* removed unused variable */
73 /* assignment, */
74 /* resulting in version 6.1.7 */
75 /* */
76 /**************************************************************************/
_gx_utility_1bpp_pixelmap_raw_resize(GX_PIXELMAP * src,GX_PIXELMAP * destination,INT width,INT height)77 static UINT _gx_utility_1bpp_pixelmap_raw_resize(GX_PIXELMAP *src, GX_PIXELMAP *destination, INT width, INT height)
78 {
79 /* The pixelmap resize function is implemented from nearest neighbor
80 image scaling algorithm. */
81 GX_UBYTE *get;
82 GX_UBYTE *put;
83 GX_UBYTE *putrow;
84 GX_UBYTE putmask;
85 GX_UBYTE getmask;
86 INT putstride;
87 INT getstride;
88 INT xradio;
89 INT yradio;
90 INT x;
91 INT y;
92 INT xx;
93 INT yy;
94
95 /* Calculate scale ratio and enlarge it by 256 times to keep precision. */
96 xradio = ((src -> gx_pixelmap_width) << 8) / width;
97 yradio = ((src -> gx_pixelmap_height) << 8) / height;
98
99 putstride = (width + 7) >> 3;
100 getstride = (src -> gx_pixelmap_width + 7) >> 3;
101
102 /* Fill property values into destination pixelmap structure. */
103 destination -> gx_pixelmap_flags = src -> gx_pixelmap_flags;
104 destination -> gx_pixelmap_format = src -> gx_pixelmap_format;
105 destination -> gx_pixelmap_transparent_color = src -> gx_pixelmap_transparent_color;
106 destination -> gx_pixelmap_version_major = src -> gx_pixelmap_version_major;
107 destination -> gx_pixelmap_version_minor = src -> gx_pixelmap_version_minor;
108
109 destination -> gx_pixelmap_height = (GX_VALUE)height;
110 destination -> gx_pixelmap_width = (GX_VALUE)width;
111
112 /* Safe int math is not required here, calling function limits max width, height to 14 bits so
113 overflow cannot occur. */
114 destination -> gx_pixelmap_data_size = (UINT)(height * putstride) * sizeof(GX_UBYTE);
115
116 /* Allocate memory to load pixelmap data. */
117 destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
118
119 if (destination -> gx_pixelmap_data == GX_NULL)
120 {
121 return GX_SYSTEM_MEMORY_ERROR;
122 }
123
124 putrow = (GX_UBYTE *)destination -> gx_pixelmap_data;
125
126 /* Loop through destination's pixel and fill each pixel with the nearest neighbor. */
127 for (y = 0; y < height; y++)
128 {
129 put = putrow;
130 putmask = 0x80;
131 for (x = 0; x < width; x++)
132 {
133 xx = (xradio * x) >> 8;
134 yy = (yradio * y) >> 8;
135
136 get = (GX_UBYTE *)src -> gx_pixelmap_data;
137 get += yy * getstride;
138 get += xx >> 3;
139
140 getmask = (GX_UBYTE)(0x80 >> (xx & 0x07));
141
142 if (*get & getmask)
143 {
144 *put |= putmask;
145 }
146 else
147 {
148 *put &= (GX_UBYTE)(~putmask);
149 }
150
151 putmask >>= 1;
152 if (putmask == 0)
153 {
154 put++;
155 putmask = 0x80;
156 }
157 }
158 putrow += putstride;
159 }
160
161 return GX_SUCCESS;
162 }
163 /**************************************************************************/
164 /* */
165 /* FUNCTION RELEASE */
166 /* */
167 /* _gx_utility_1bpp_pixelmap_transparent_resize PORTABLE C */
168 /* 6.1 */
169 /* AUTHOR */
170 /* */
171 /* Kenneth Maxwell, Microsoft Corporation */
172 /* */
173 /* DESCRIPTION */
174 /* */
175 /* 1bpp pixelmap resize function that handles uncompress, with */
176 /* transparent channel. */
177 /* */
178 /* INPUT */
179 /* */
180 /* src The source pixelmap */
181 /* destination The resized pixelmap to be */
182 /* returned */
183 /* width New width */
184 /* height New height */
185 /* */
186 /* OUTPUT */
187 /* */
188 /* status Completion status */
189 /* */
190 /* CALLS */
191 /* */
192 /* _gx_system_memory_allocator Memory Allocation routine */
193 /* */
194 /* CALLED BY */
195 /* */
196 /* _gx_utility_1bpp_pixelmap_resize */
197 /* */
198 /* RELEASE HISTORY */
199 /* */
200 /* DATE NAME DESCRIPTION */
201 /* */
202 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
203 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
204 /* resulting in version 6.1 */
205 /* */
206 /**************************************************************************/
_gx_utility_1bpp_pixelmap_transparent_resize(GX_PIXELMAP * src,GX_PIXELMAP * destination,INT width,INT height)207 static UINT _gx_utility_1bpp_pixelmap_transparent_resize(GX_PIXELMAP *src, GX_PIXELMAP *destination, INT width, INT height)
208 {
209 /* The pixelmap resize function is implemented from nearest neighbor
210 image scaling algorithm. */
211 GX_UBYTE *get;
212 GX_UBYTE *put;
213 GX_UBYTE *putrow;
214 GX_UBYTE putmask;
215 GX_UBYTE puttransmask;
216 INT putstride;
217 INT getstride;
218 GX_UBYTE getmask;
219 GX_UBYTE gettransmask;
220 INT xradio;
221 INT yradio;
222 INT x;
223 INT y;
224 INT xx;
225 INT yy;
226
227 /* Calculate scale ratio and enlarge it by 256 times to keep precision. */
228 xradio = ((src -> gx_pixelmap_width) << 8) / width;
229 yradio = ((src -> gx_pixelmap_height) << 8) / height;
230
231 putstride = (width + 3) >> 2;
232 getstride = (src -> gx_pixelmap_width + 3) >> 2;
233
234 /* Fill property values into destination pixelmap structure. */
235 destination -> gx_pixelmap_flags = src -> gx_pixelmap_flags;
236 destination -> gx_pixelmap_format = src -> gx_pixelmap_format;
237 destination -> gx_pixelmap_transparent_color = src -> gx_pixelmap_transparent_color;
238 destination -> gx_pixelmap_version_major = src -> gx_pixelmap_version_major;
239 destination -> gx_pixelmap_version_minor = src -> gx_pixelmap_version_minor;
240
241 destination -> gx_pixelmap_height = (GX_VALUE)height;
242 destination -> gx_pixelmap_width = (GX_VALUE)width;
243
244 /* Safe int math is not required here, calling function limits max width, height to 14 bits so
245 overflow cannot occur. */
246 destination -> gx_pixelmap_data_size = (UINT)(height * putstride) * sizeof(GX_UBYTE);
247
248 /* Allocate memory to load pixelmap data. */
249 destination -> gx_pixelmap_data = (GX_UBYTE *)_gx_system_memory_allocator(destination -> gx_pixelmap_data_size);
250
251 if (destination -> gx_pixelmap_data == GX_NULL)
252 {
253 return GX_SYSTEM_MEMORY_ERROR;
254 }
255
256 putrow = (GX_UBYTE *)destination -> gx_pixelmap_data;
257
258 /* Loop through destination's pixel and fill each pixel with the nearest neighbor. */
259 for (y = 0; y < height; y++)
260 {
261 put = putrow;
262 putmask = 0x80;
263 puttransmask = 0x40;
264 for (x = 0; x < width; x++)
265 {
266 xx = (xradio * x) >> 8;
267 yy = (yradio * y) >> 8;
268
269 /* set bits first. */
270 *put &= (GX_UBYTE)(~putmask);
271 *put &= (GX_UBYTE)(~puttransmask);
272
273 /* get pixel data */
274 get = (GX_UBYTE *)src -> gx_pixelmap_data;
275 get += yy * getstride;
276 get += xx >> 2;
277
278 gettransmask = (GX_UBYTE)(0x40 >> ((xx & 0x03) << 1));
279 if (*get & gettransmask)
280 {
281 *put |= puttransmask;
282 getmask = (GX_UBYTE)(gettransmask << 1);
283 if (*get & getmask)
284 {
285 *put |= putmask;
286 }
287 }
288
289 putmask >>= 2;
290 puttransmask >>= 2;
291 if (puttransmask == 0)
292 {
293 put++;
294 putmask = 0x80;
295 puttransmask = 0x40;
296 }
297 }
298 putrow += putstride;
299 }
300
301 return GX_SUCCESS;
302 }
303 /**************************************************************************/
304 /* */
305 /* FUNCTION RELEASE */
306 /* */
307 /* _gx_utility_1bpp_pixelmap_resize PORTABLE C */
308 /* 6.1 */
309 /* AUTHOR */
310 /* */
311 /* Kenneth Maxwell, Microsoft Corporation */
312 /* */
313 /* DESCRIPTION */
314 /* */
315 /* 1bpp pixelmap resize function that handles uncompress, with or */
316 /* without transparent channel. */
317 /* */
318 /* INPUT */
319 /* */
320 /* src The source pixelmap */
321 /* destination The resized pixelmap to be */
322 /* returned */
323 /* width New width */
324 /* height New height */
325 /* */
326 /* OUTPUT */
327 /* */
328 /* status Completion status */
329 /* */
330 /* CALLS */
331 /* */
332 /* _gx_utility_1bpp_pixelmap_transparent_resize */
333 /* Real pixelmap resize routine */
334 /* _gx_utility_1bpp_pixelmap_raw_resize Real pixelmap resize routine */
335 /* */
336 /* */
337 /* CALLED BY */
338 /* */
339 /* GUIX Internal Code */
340 /* */
341 /* RELEASE HISTORY */
342 /* */
343 /* DATE NAME DESCRIPTION */
344 /* */
345 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
346 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
347 /* resulting in version 6.1 */
348 /* */
349 /**************************************************************************/
_gx_utility_1bpp_pixelmap_resize(GX_PIXELMAP * src,GX_PIXELMAP * destination,INT width,INT height)350 UINT _gx_utility_1bpp_pixelmap_resize(GX_PIXELMAP *src, GX_PIXELMAP *destination, INT width, INT height)
351 {
352 UINT status;
353
354 if (src -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
355 {
356 /* transparent, no compression */
357 status = _gx_utility_1bpp_pixelmap_transparent_resize(src, destination, width, height);
358 }
359 else
360 {
361 /* no compression or alpha */
362 status = _gx_utility_1bpp_pixelmap_raw_resize(src, destination, width, height);
363 }
364
365 return status;
366 }
367
368