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