GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_utility_canvas_to_bmp.c Lines: 261 261 100.0 %
Date: 2024-12-05 08:52:37 Branches: 95 95 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
/**   Text Input Management (Single Line Text Input)                      */
18
/**                                                                       */
19
/**************************************************************************/
20
21
/* Include necessary system files.  */
22
#define GX_SOURCE_CODE
23
24
#include "gx_api.h"
25
#include "gx_utility.h"
26
27
#define BI_RGB       0L
28
#define BI_BITFIELDS 3L
29
30
#define DATA_OFFSET  54
31
typedef struct bitmap_file_header_struct
32
{
33
    USHORT filetype;
34
    UINT   filesize;
35
    UINT   reserved;
36
    UINT   offset;
37
} bitmap_file_header;
38
39
typedef struct bmp_info_struct
40
{
41
    UINT   bi_Size;
42
    INT    bi_Width;
43
    INT    bi_Height;
44
    USHORT bi_Planes;
45
    USHORT bi_BitCount;
46
    UINT   bi_Compression;
47
    UINT   bi_SizeImage;
48
    UINT   bi_XPelsPerMeter;
49
    UINT   bi_YPelsPerMeter;
50
    UINT   bi_ClrUsed;
51
    UINT   bi_ClrImportant;
52
} bmp_info;
53
54
55
/**************************************************************************/
56
/*                                                                        */
57
/*  FUNCTION                                               RELEASE        */
58
/*                                                                        */
59
/*    _gx_utility_write_bitmap_header                     PORTABLE C      */
60
/*                                                           6.1          */
61
/*  AUTHOR                                                                */
62
/*                                                                        */
63
/*    Kenneth Maxwell, Microsoft Corporation                              */
64
/*                                                                        */
65
/*  DESCRIPTION                                                           */
66
/*                                                                        */
67
/*    This function create bitmap header and write it to bmp file.        */
68
/*                                                                        */
69
/*  INPUT                                                                 */
70
/*                                                                        */
71
/*    canvas                                Canvas control block          */
72
/*    rectangle                             Rectangle specification       */
73
/*    write_data                            Write data callback function  */
74
/*                                                                        */
75
/*  OUTPUT                                                                */
76
/*                                                                        */
77
/*    status                                Completion status             */
78
/*                                                                        */
79
/*  CALLS                                                                 */
80
/*                                                                        */
81
/*    None                                                                */
82
/*                                                                        */
83
/*  CALLED BY                                                             */
84
/*                                                                        */
85
/*    _gx_utility_canvas_to_bmp                                           */
86
/*                                                                        */
87
/*  RELEASE HISTORY                                                       */
88
/*                                                                        */
89
/*    DATE              NAME                      DESCRIPTION             */
90
/*                                                                        */
91
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
92
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
93
/*                                            resulting in version 6.1    */
94
/*                                                                        */
95
/**************************************************************************/
96
21
static UINT _gx_utility_write_bitmap_header(GX_CANVAS *canvas, GX_RECTANGLE *rect, UINT (*write_data)(GX_UBYTE *byte_data, UINT data_count))
97
{
98
bitmap_file_header bmp_fheader;
99
bmp_info           b_info;
100
GX_COLOR           color;
101
GX_COLOR          *palette;
102
INT                count;
103
INT                r;
104
INT                g;
105
INT                b;
106
INT                red;
107
INT                green;
108
INT                blue;
109
110
21
    memset(&bmp_fheader, 0, sizeof(bitmap_file_header));
111
21
    memset(&b_info, 0, sizeof(bmp_info));
112
21
    bmp_fheader.filetype = 0x4d42; /* "MB" */
113
21
    bmp_fheader.reserved = 0;
114
115
    /* calculate data offset */
116
21
    bmp_fheader.offset = DATA_OFFSET;
117
118
    /* set common datas for bmp info. */
119
21
    b_info.bi_Width = rect -> gx_rectangle_right - rect -> gx_rectangle_left + 1;
120
21
    b_info.bi_Height = rect -> gx_rectangle_bottom - rect -> gx_rectangle_top + 1;
121
21
    b_info.bi_Size = sizeof(bmp_info);
122
21
    b_info.bi_Planes = 1;
123
21
    b_info.bi_Compression = BI_RGB;
124
21
    b_info.bi_XPelsPerMeter = 0;
125
21
    b_info.bi_YPelsPerMeter = 0;
126
21
    b_info.bi_ClrUsed = 0;
127
21
    b_info.bi_ClrImportant = 0;
128
129

21
    switch (canvas -> gx_canvas_display -> gx_display_color_format)
130
    {
131
2
    case GX_COLOR_FORMAT_32ARGB:
132
    case GX_COLOR_FORMAT_24XRGB:
133
2
        b_info.bi_BitCount = 32;
134
2
        b_info.bi_SizeImage = (UINT)((b_info.bi_Width << 2) * b_info.bi_Height);
135
2
        break;
136
137
6
    case GX_COLOR_FORMAT_1555XRGB:
138
    case GX_COLOR_FORMAT_4444ARGB:
139
    case GX_COLOR_FORMAT_565RGB:
140
6
        b_info.bi_BitCount = 16;
141
6
        b_info.bi_SizeImage = (UINT)((((UINT)(b_info.bi_Width + 1) & 0xfffffffe) << 1) * (UINT)b_info.bi_Height);
142
6
        b_info.bi_ClrUsed = 3;
143
6
        b_info.bi_ClrImportant = 3;
144
6
        b_info.bi_Compression = BI_BITFIELDS;
145
        /* Three color entries in palette */
146
6
        bmp_fheader.offset += 3 * sizeof(GX_COLOR);
147
6
        break;
148
149
4
    case GX_COLOR_FORMAT_8BIT_PALETTE:
150
4
        if ((canvas -> gx_canvas_display -> gx_display_palette == GX_NULL) ||
151
3
            (canvas -> gx_canvas_display -> gx_display_palette_size == 0))
152
        {
153
2
            return GX_FAILURE;
154
        }
155
2
        b_info.bi_BitCount = 8;
156
2
        b_info.bi_SizeImage = (UINT)(((UINT)(b_info.bi_Width + 3) & 0xfffffffc) * (UINT)b_info.bi_Height);
157
2
        b_info.bi_ClrUsed = canvas -> gx_canvas_display -> gx_display_palette_size;
158
2
        b_info.bi_ClrImportant = canvas -> gx_canvas_display -> gx_display_palette_size;
159
2
        bmp_fheader.offset += canvas -> gx_canvas_display -> gx_display_palette_size * sizeof(GX_COLOR);
160
2
        break;
161
162
2
    case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
163
2
        b_info.bi_BitCount = 8;
164
2
        b_info.bi_SizeImage = (UINT)(((UINT)(b_info.bi_Width + 3) & 0xfffffffc) * (UINT)b_info.bi_Height);
165
        /* Palette for 332rgb is default to 256. */
166
2
        b_info.bi_ClrImportant = 256;
167
2
        b_info.bi_ClrUsed = 256;
168
2
        bmp_fheader.offset += 256 * sizeof(GX_COLOR);
169
2
        break;
170
171
3
    case GX_COLOR_FORMAT_4BIT_GRAY:
172
3
        b_info.bi_BitCount = 4;
173
3
        b_info.bi_SizeImage = (UINT)((((UINT)(b_info.bi_Width + 7) & 0xfffffff8) >> 1) * (UINT)b_info.bi_Height);
174
3
        b_info.bi_ClrUsed = 16;
175
3
        b_info.bi_ClrImportant = 16;
176
3
        bmp_fheader.offset += 16 * sizeof(GX_COLOR);
177
3
        break;
178
179
3
    case GX_COLOR_FORMAT_MONOCHROME:
180
3
        b_info.bi_BitCount = 1;
181
3
        b_info.bi_SizeImage = (UINT)((((UINT)(b_info.bi_Width + 63) & 0xffffffc0) >> 3) * (UINT)b_info.bi_Height);
182
3
        b_info.bi_ClrUsed = 2;
183
3
        b_info.bi_ClrImportant = 2;
184
3
        bmp_fheader.offset += 2 * sizeof(GX_COLOR);
185
3
        break;
186
187
1
    default:
188
1
        break;
189
    }
190
191
    /* total file size */
192
19
    bmp_fheader.filesize = bmp_fheader.offset + b_info.bi_SizeImage;
193
194
    /* write bmp file header */
195
19
    write_data((GX_UBYTE *)&bmp_fheader.filetype, sizeof(USHORT));
196
19
    write_data((GX_UBYTE *)&bmp_fheader.filesize, sizeof(UINT));
197
19
    write_data((GX_UBYTE *)&bmp_fheader.reserved, sizeof(UINT));
198
19
    write_data((GX_UBYTE *)&bmp_fheader.offset, sizeof(UINT));
199
200
    /* height value is negtive means we can write image data from top to bottom. */
201
19
    b_info.bi_Height = -b_info.bi_Height;
202
    /* write bmp info */
203
19
    write_data((GX_UBYTE *)&b_info, sizeof(bmp_info));
204
205
    /* I don't want to add a matrix with 256 to store the palette.
206
       so let's write the palette by colors.*/
207


19
    switch (canvas -> gx_canvas_display -> gx_display_color_format)
208
    {
209
2
    case GX_COLOR_FORMAT_565RGB:
210
2
        color = 0x0000f800;
211
2
        write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
212
2
        color = 0x000007e0;
213
2
        write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
214
2
        color = 0x0000001f;
215
2
        write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
216
2
        break;
217
218
2
    case GX_COLOR_FORMAT_1555XRGB:
219
2
        color = 0x00007c00;
220
2
        write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
221
2
        color = 0x000003e0;
222
2
        write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
223
2
        color = 0x0000001f;
224
2
        write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
225
2
        break;
226
227
2
    case GX_COLOR_FORMAT_4444ARGB:
228
2
        color = 0x00000f00;
229
2
        write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
230
2
        color = 0x000000f0;
231
2
        write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
232
2
        color = 0x0000000f;
233
2
        write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
234
2
        break;
235
236
2
    case GX_COLOR_FORMAT_8BIT_PALETTE:
237
2
        palette = canvas -> gx_canvas_display -> gx_display_palette;
238
2
        count = (INT)(canvas -> gx_canvas_display -> gx_display_palette_size);
239
514
        while (count)
240
        {
241
512
            write_data((GX_UBYTE *)palette, sizeof(GX_COLOR));
242
512
            palette++;
243
512
            count--;
244
        }
245
2
        break;
246
247
2
    case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
248
18
        for (r = 0; r < 8; r++)
249
        {
250
16
            red = r << 21;
251
16
            if (red & 0x200000)
252
            {
253
8
                red |= 0x1f0000;
254
            }
255
144
            for (g = 0; g < 8; g++)
256
            {
257
128
                green = g << 13;
258
128
                if (green & 0x2000)
259
                {
260
64
                    green |= 0x1f00;
261
                }
262
640
                for (b = 0; b < 4; b++)
263
                {
264
512
                    blue = b << 6;
265
512
                    if (blue & 0x40)
266
                    {
267
256
                        blue |= 0x3f;
268
                    }
269
512
                    color = (GX_COLOR)(red | green | blue);
270
512
                    write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
271
                }
272
            }
273
        }
274
2
        break;
275
276
3
    case GX_COLOR_FORMAT_4BIT_GRAY:
277
51
        for (r = 0; r <= 0xff; r += 0x11)
278
        {
279
48
            color = (GX_COLOR)((GX_COLOR)((r << 16) | (r << 8) | r) | 0xff000000);
280
48
            write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
281
        }
282
3
        break;
283
284
3
    case GX_COLOR_FORMAT_MONOCHROME:
285
3
        color = 0xff000000;
286
3
        write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
287
3
        color = 0xffffffff;
288
3
        write_data((GX_UBYTE *)&color, sizeof(GX_COLOR));
289
3
        break;
290
291
3
    default:
292
3
        break;
293
    }
294
295
19
    return GX_SUCCESS;
296
}
297
298
/**************************************************************************/
299
/*                                                                        */
300
/*  FUNCTION                                               RELEASE        */
301
/*                                                                        */
302
/*    _gx_utility_write_bitmap_data_32bpp                 PORTABLE C      */
303
/*                                                           6.1          */
304
/*  AUTHOR                                                                */
305
/*                                                                        */
306
/*    Kenneth Maxwell, Microsoft Corporation                              */
307
/*                                                                        */
308
/*  DESCRIPTION                                                           */
309
/*                                                                        */
310
/*    This function read canvas memory data and write it to bmp file.     */
311
/*                                                                        */
312
/*  INPUT                                                                 */
313
/*                                                                        */
314
/*    canvas                                Canvas control block          */
315
/*    rectangle                             Rectangle specification       */
316
/*    write_data                            Write data callback function  */
317
/*                                                                        */
318
/*  OUTPUT                                                                */
319
/*                                                                        */
320
/*    None                                                                */
321
/*                                                                        */
322
/*  CALLS                                                                 */
323
/*                                                                        */
324
/*    None                                                                */
325
/*                                                                        */
326
/*  CALLED BY                                                             */
327
/*                                                                        */
328
/*    _gx_utility_canvas_to_bmp                                           */
329
/*                                                                        */
330
/*  RELEASE HISTORY                                                       */
331
/*                                                                        */
332
/*    DATE              NAME                      DESCRIPTION             */
333
/*                                                                        */
334
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
335
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
336
/*                                            resulting in version 6.1    */
337
/*                                                                        */
338
/**************************************************************************/
339
2
static void _gx_utility_write_bitmap_data_32bpp(GX_CANVAS *canvas, GX_RECTANGLE *rect, UINT (*write_data)(GX_UBYTE *byte_data, UINT data_count))
340
{
341
GX_COLOR *get;
342
GX_COLOR *get_row;
343
INT       x;
344
INT       y;
345
346
2
    get_row = (GX_COLOR *)(canvas -> gx_canvas_memory);
347
2
    get_row += canvas -> gx_canvas_x_resolution * rect -> gx_rectangle_top;
348
2
    get_row += rect -> gx_rectangle_left;
349
350
658
    for (y = rect -> gx_rectangle_top; y <= rect -> gx_rectangle_bottom; y++)
351
    {
352
656
        get = get_row;
353
284140
        for (x = rect -> gx_rectangle_left; x <= rect -> gx_rectangle_right; x++)
354
        {
355
283484
            write_data((GX_UBYTE *)get, sizeof(GX_COLOR));
356
283484
            get++;
357
        }
358
656
        get_row += canvas -> gx_canvas_x_resolution;
359
    }
360
2
}
361
362
/**************************************************************************/
363
/*                                                                        */
364
/*  FUNCTION                                               RELEASE        */
365
/*                                                                        */
366
/*    _gx_utility_write_bitmap_data_16bpp                 PORTABLE C      */
367
/*                                                           6.1          */
368
/*  AUTHOR                                                                */
369
/*                                                                        */
370
/*    Kenneth Maxwell, Microsoft Corporation                              */
371
/*                                                                        */
372
/*  DESCRIPTION                                                           */
373
/*                                                                        */
374
/*    This function read canvas memory data and write it to bmp file.     */
375
/*                                                                        */
376
/*  INPUT                                                                 */
377
/*                                                                        */
378
/*    canvas                                Canvas control block          */
379
/*    rectangle                             Rectangle specification       */
380
/*    write_data                            Write data callback function  */
381
/*                                                                        */
382
/*  OUTPUT                                                                */
383
/*                                                                        */
384
/*    None                                                                */
385
/*                                                                        */
386
/*  CALLS                                                                 */
387
/*                                                                        */
388
/*    None                                                                */
389
/*                                                                        */
390
/*  CALLED BY                                                             */
391
/*                                                                        */
392
/*    _gx_utility_canvas_to_bmp                                           */
393
/*                                                                        */
394
/*  RELEASE HISTORY                                                       */
395
/*                                                                        */
396
/*    DATE              NAME                      DESCRIPTION             */
397
/*                                                                        */
398
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
399
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
400
/*                                            resulting in version 6.1    */
401
/*                                                                        */
402
/**************************************************************************/
403
6
static void _gx_utility_write_bitmap_data_16bpp(GX_CANVAS *canvas, GX_RECTANGLE *rect, UINT (*write_data)(GX_UBYTE *byte_data, UINT data_count))
404
{
405
USHORT *get;
406
USHORT *get_row;
407
INT     x;
408
INT     y;
409
INT     width;
410
411
6
    get_row = (USHORT *)(canvas -> gx_canvas_memory);
412
6
    get_row += canvas -> gx_canvas_x_resolution * rect -> gx_rectangle_top;
413
6
    get_row += rect -> gx_rectangle_left;
414
6
    width = rect -> gx_rectangle_right - rect -> gx_rectangle_left + 1;
415
416
1974
    for (y = rect -> gx_rectangle_top; y <= rect -> gx_rectangle_bottom; y++)
417
    {
418
1968
        get = get_row;
419
852420
        for (x = 0; x < width; x++)
420
        {
421
850452
            write_data((GX_UBYTE *)get, sizeof(USHORT));
422
850452
            get++;
423
        }
424
1968
        if (width & 1)
425
        {
426
            /* Fix data to 4 bytes aligned. */
427
708
            write_data((GX_UBYTE *)get, sizeof(USHORT));
428
        }
429
1968
        get_row += canvas -> gx_canvas_x_resolution;
430
    }
431
6
}
432
433
/**************************************************************************/
434
/*                                                                        */
435
/*  FUNCTION                                               RELEASE        */
436
/*                                                                        */
437
/*    _gx_utility_write_bitmap_data_8bpp                  PORTABLE C      */
438
/*                                                           6.1          */
439
/*  AUTHOR                                                                */
440
/*                                                                        */
441
/*    Kenneth Maxwell, Microsoft Corporation                              */
442
/*                                                                        */
443
/*  DESCRIPTION                                                           */
444
/*                                                                        */
445
/*    This function read canvas memory data and write it to bmp file.     */
446
/*                                                                        */
447
/*  INPUT                                                                 */
448
/*                                                                        */
449
/*    canvas                                Canvas control block          */
450
/*    rectangle                             Rectangle specification       */
451
/*    write_data                            Write data callback function  */
452
/*                                                                        */
453
/*  OUTPUT                                                                */
454
/*                                                                        */
455
/*    None                                                                */
456
/*                                                                        */
457
/*  CALLS                                                                 */
458
/*                                                                        */
459
/*    None                                                                */
460
/*                                                                        */
461
/*  CALLED BY                                                             */
462
/*                                                                        */
463
/*    _gx_utility_canvas_to_bmp                                           */
464
/*                                                                        */
465
/*  RELEASE HISTORY                                                       */
466
/*                                                                        */
467
/*    DATE              NAME                      DESCRIPTION             */
468
/*                                                                        */
469
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
470
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
471
/*                                            resulting in version 6.1    */
472
/*                                                                        */
473
/**************************************************************************/
474
4
static void _gx_utility_write_bitmap_data_8bpp(GX_CANVAS *canvas, GX_RECTANGLE *rect, UINT (*write_data)(GX_UBYTE *byte_data, UINT data_count))
475
{
476
GX_UBYTE *get;
477
GX_UBYTE *get_row;
478
INT       x;
479
INT       y;
480
INT       width;
481
INT       fixed_count;
482
483
4
    get_row = (GX_UBYTE *)(canvas -> gx_canvas_memory);
484
4
    get_row += canvas -> gx_canvas_x_resolution * rect -> gx_rectangle_top;
485
4
    get_row += rect -> gx_rectangle_left;
486
4
    width = rect -> gx_rectangle_right - rect -> gx_rectangle_left + 1;
487
4
    fixed_count = width & 3;
488
4
    if (fixed_count)
489
    {
490
2
        fixed_count = 4 - fixed_count;
491
    }
492
493
1316
    for (y = rect -> gx_rectangle_top; y <= rect -> gx_rectangle_bottom; y++)
494
    {
495
1312
        get = get_row;
496
568280
        for (x = 0; x < width; x++)
497
        {
498
566968
            write_data((GX_UBYTE *)get, sizeof(GX_UBYTE));
499
566968
            get++;
500
        }
501
502
        /* Fix data to 4 bytes aligned. */
503
2728
        for (x = 0; x < fixed_count; x++)
504
        {
505
1416
            write_data((GX_UBYTE *)get, sizeof(GX_UBYTE));
506
        }
507
1312
        get_row += canvas -> gx_canvas_x_resolution;
508
    }
509
4
}
510
511
/**************************************************************************/
512
/*                                                                        */
513
/*  FUNCTION                                               RELEASE        */
514
/*                                                                        */
515
/*    _gx_utility_write_bitmap_data_4bpp                  PORTABLE C      */
516
/*                                                           6.1          */
517
/*  AUTHOR                                                                */
518
/*                                                                        */
519
/*    Kenneth Maxwell, Microsoft Corporation                              */
520
/*                                                                        */
521
/*  DESCRIPTION                                                           */
522
/*                                                                        */
523
/*    This function read canvas memory data and write it to bmp file.     */
524
/*                                                                        */
525
/*  INPUT                                                                 */
526
/*                                                                        */
527
/*    canvas                                Canvas control block          */
528
/*    rectangle                             Rectangle specification       */
529
/*    write_data                            Write data callback function  */
530
/*                                                                        */
531
/*  OUTPUT                                                                */
532
/*                                                                        */
533
/*    None                                                                */
534
/*                                                                        */
535
/*  CALLS                                                                 */
536
/*                                                                        */
537
/*    None                                                                */
538
/*                                                                        */
539
/*  CALLED BY                                                             */
540
/*                                                                        */
541
/*    _gx_utility_canvas_to_bmp                                           */
542
/*                                                                        */
543
/*  RELEASE HISTORY                                                       */
544
/*                                                                        */
545
/*    DATE              NAME                      DESCRIPTION             */
546
/*                                                                        */
547
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
548
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
549
/*                                            resulting in version 6.1    */
550
/*                                                                        */
551
/**************************************************************************/
552
3
static void _gx_utility_write_bitmap_data_4bpp(GX_CANVAS *canvas, GX_RECTANGLE *rect, UINT (*write_data)(GX_UBYTE *byte_data, UINT data_count))
553
{
554
GX_UBYTE *get;
555
GX_UBYTE *get_row;
556
3
GX_UBYTE  color = 0;
557
INT       x;
558
INT       y;
559
INT       fixed_count;
560
INT       row_count;
561
562
3
    get_row = (GX_UBYTE *)(canvas -> gx_canvas_memory);
563
3
    get_row += ((canvas -> gx_canvas_x_resolution + 1) >> 1) * rect -> gx_rectangle_top;
564
3
    get_row += rect -> gx_rectangle_left >> 1;
565
3
    row_count = rect -> gx_rectangle_right - rect -> gx_rectangle_left + 1;
566
3
    row_count = (row_count + 1) >> 1;
567
3
    fixed_count = row_count & 3;
568
3
    if (fixed_count)
569
    {
570
2
        fixed_count = 4 - fixed_count;
571
    }
572
573
3
    if (rect -> gx_rectangle_left & 1)
574
    {
575
        /* If start pixel is not at the first bit of byte. We need to make it aligned. */
576
842
        for (y = rect -> gx_rectangle_top; y <= rect -> gx_rectangle_bottom; y++)
577
        {
578
840
            get = get_row;
579
243600
            for (x = 0; x < row_count; x++)
580
            {
581
242760
                color = (GX_UBYTE)((*get & 0x0f) << 4);
582
242760
                get++;
583
242760
                color |= (*get & 0xf0) >> 4;
584
585
242760
                write_data((GX_UBYTE *)&color, sizeof(GX_UBYTE));
586
            }
587
588
            /* Fix data to 4 bytes aligned. */
589
1680
            for (x = 0; x < fixed_count; x++)
590
            {
591
840
                write_data((GX_UBYTE *)&color, sizeof(GX_UBYTE));
592
            }
593
594
840
            get_row += (canvas -> gx_canvas_x_resolution + 1) >> 1;
595
        }
596
    }
597
    else
598
    {
599
237
        for (y = rect -> gx_rectangle_top; y <= rect -> gx_rectangle_bottom; y++)
600
        {
601
236
            get = get_row;
602
20296
            for (x = 0; x < row_count; x++)
603
            {
604
20060
                write_data((GX_UBYTE *)get, sizeof(GX_UBYTE));
605
20060
                get++;
606
            }
607
608
            /* Fix data to 4 bytes aligned. */
609
944
            for (x = 0; x < fixed_count; x++)
610
            {
611
708
                write_data((GX_UBYTE *)&color, sizeof(GX_UBYTE));
612
            }
613
236
            get_row += (canvas -> gx_canvas_x_resolution + 1) >> 1;
614
        }
615
    }
616
3
}
617
618
/**************************************************************************/
619
/*                                                                        */
620
/*  FUNCTION                                               RELEASE        */
621
/*                                                                        */
622
/*    _gx_utility_write_bitmap_data_monochrome            PORTABLE C      */
623
/*                                                           6.1          */
624
/*  AUTHOR                                                                */
625
/*                                                                        */
626
/*    Kenneth Maxwell, Microsoft Corporation                              */
627
/*                                                                        */
628
/*  DESCRIPTION                                                           */
629
/*                                                                        */
630
/*    This function read canvas memory data and write it to bmp file.     */
631
/*                                                                        */
632
/*  INPUT                                                                 */
633
/*                                                                        */
634
/*    canvas                                Canvas control block          */
635
/*    rectangle                             Rectangle specification       */
636
/*    write_data                            Write data callback function  */
637
/*                                                                        */
638
/*  OUTPUT                                                                */
639
/*                                                                        */
640
/*    None                                                                */
641
/*                                                                        */
642
/*  CALLS                                                                 */
643
/*                                                                        */
644
/*    None                                                                */
645
/*                                                                        */
646
/*  CALLED BY                                                             */
647
/*                                                                        */
648
/*    _gx_utility_canvas_to_bmp                                           */
649
/*                                                                        */
650
/*  RELEASE HISTORY                                                       */
651
/*                                                                        */
652
/*    DATE              NAME                      DESCRIPTION             */
653
/*                                                                        */
654
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
655
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
656
/*                                            resulting in version 6.1    */
657
/*                                                                        */
658
/**************************************************************************/
659
3
static void _gx_utility_write_bitmap_data_monochrome(GX_CANVAS *canvas, GX_RECTANGLE *rect, UINT (*write_data)(GX_UBYTE *byte_data, UINT data_count))
660
{
661
GX_UBYTE *get;
662
GX_UBYTE *get_row;
663
INT       x;
664
INT       y;
665
INT       row_count;
666
INT       fixed_count;
667
INT       bits_in_first_byte;
668
3
GX_UBYTE  color = 0;
669
670
3
    get_row = (GX_UBYTE *)(canvas -> gx_canvas_memory);
671
3
    get_row += ((canvas -> gx_canvas_x_resolution + 7) >> 3) * rect -> gx_rectangle_top;
672
3
    get_row += rect -> gx_rectangle_left >> 3;
673
3
    row_count = rect -> gx_rectangle_right - rect -> gx_rectangle_left + 1;
674
3
    row_count = (row_count + 7) >> 3;
675
3
    bits_in_first_byte = rect -> gx_rectangle_left & 7;
676
3
    fixed_count = row_count & 3;
677
3
    if (fixed_count)
678
    {
679
2
        fixed_count = 4 - fixed_count;
680
    }
681
682
3
    if (bits_in_first_byte)
683
    {
684
2
        bits_in_first_byte = 8 - (rect -> gx_rectangle_left & 7);
685
686
        /* If start pixel is not at the first bit of byte. We need to make it aligned. */
687
842
        for (y = rect -> gx_rectangle_top; y <= rect -> gx_rectangle_bottom; y++)
688
        {
689
840
            get = get_row;
690
61740
            for (x = 0; x < row_count; x++)
691
            {
692
60900
                color = (GX_UBYTE)((*get) << (8 - bits_in_first_byte));
693
60900
                get++;
694
60900
                color = (GX_UBYTE)(color | ((*get) >> bits_in_first_byte));
695
696
60900
                write_data((GX_UBYTE *)&color, sizeof(GX_UBYTE));
697
            }
698
699
            /* Fix data to 4 bytes aligned. */
700
2100
            for (x = 0; x < fixed_count; x++)
701
            {
702
1260
                write_data((GX_UBYTE *)&color, sizeof(GX_UBYTE));
703
            }
704
705
840
            get_row += (canvas -> gx_canvas_x_resolution + 7) >> 3;
706
        }
707
    }
708
    else
709
    {
710
237
        for (y = rect -> gx_rectangle_top; y <= rect -> gx_rectangle_bottom; y++)
711
        {
712
236
            get = get_row;
713
5428
            for (x = 0; x < row_count; x++)
714
            {
715
5192
                write_data((GX_UBYTE *)get, sizeof(GX_UBYTE));
716
5192
                get++;
717
            }
718
719
            /* Fix data to 4 bytes aligned. */
720
708
            for (x = 0; x < fixed_count; x++)
721
            {
722
472
                write_data((GX_UBYTE *)&color, sizeof(GX_UBYTE));
723
            }
724
725
236
            get_row += (canvas -> gx_canvas_x_resolution + 7) >> 3;
726
        }
727
    }
728
3
}
729
730
/**************************************************************************/
731
/*                                                                        */
732
/*  FUNCTION                                               RELEASE        */
733
/*                                                                        */
734
/*    _gx_utility_canvas_to_bmp                           PORTABLE C      */
735
/*                                                           6.1          */
736
/*  AUTHOR                                                                */
737
/*                                                                        */
738
/*    Kenneth Maxwell, Microsoft Corporation                              */
739
/*                                                                        */
740
/*  DESCRIPTION                                                           */
741
/*                                                                        */
742
/*    Covert canvas memory data to bmp file.                              */
743
/*                                                                        */
744
/*  INPUT                                                                 */
745
/*                                                                        */
746
/*    canvas                                Canvas control block          */
747
/*    rectangle                             Rectangle specification       */
748
/*    write_data                            Write data callback function  */
749
/*                                                                        */
750
/*  OUTPUT                                                                */
751
/*                                                                        */
752
/*    status                                Completion status             */
753
/*                                                                        */
754
/*  CALLS                                                                 */
755
/*                                                                        */
756
/*    _gx_utility_rectangle_define          Define a rectangle            */
757
/*    _gx_utility_rectangle_inside_detect   Detect rect inside of another */
758
/*    _gx_utility_write_bitmap_header       Create bmp file header        */
759
/*    _gx_utility_write_bitmap_data_monochrome                            */
760
/*    _gx_utility_write_bitmap_data_4bpp                                  */
761
/*    _gx_utility_write_bitmap_data_8bpp                                  */
762
/*    _gx_utility_write_bitmap_data_16bpp                                 */
763
/*    _gx_utility_write_bitmap_data_32bpp   Above functions read canvas   */
764
/*                                            memory and write data to    */
765
/*                                            file.                       */
766
/*                                                                        */
767
/*  CALLED BY                                                             */
768
/*                                                                        */
769
/*    _gxe_utility_canvas_to_bmp            Error checking function       */
770
/*                                                                        */
771
/*  RELEASE HISTORY                                                       */
772
/*                                                                        */
773
/*    DATE              NAME                      DESCRIPTION             */
774
/*                                                                        */
775
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
776
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
777
/*                                            resulting in version 6.1    */
778
/*                                                                        */
779
/**************************************************************************/
780
22
UINT _gx_utility_canvas_to_bmp(GX_CANVAS *canvas, GX_RECTANGLE *rect, UINT (*write_data)(GX_UBYTE *byte_data, UINT data_count))
781
{
782
UINT         status;
783
UINT         pixelmap_format;
784
GX_RECTANGLE canvas_size;
785
786
22
    _gx_utility_rectangle_define(&canvas_size, 0, 0, (GX_VALUE)(canvas -> gx_canvas_x_resolution - 1), (GX_VALUE)(canvas -> gx_canvas_y_resolution - 1));
787
788
22
    if (!_gx_utility_rectangle_inside_detect(&canvas_size, rect))
789
    {
790
1
        return GX_INVALID_SIZE;
791
    }
792
793
    /* write bmp file header. */
794
21
    status = _gx_utility_write_bitmap_header(canvas, rect, write_data);
795
796
21
    if (status == GX_SUCCESS)
797
    {
798
        /* write bmp image data*/
799
19
        pixelmap_format = canvas -> gx_canvas_display -> gx_display_color_format;
800
801

19
        switch (pixelmap_format)
802
        {
803
3
        case GX_COLOR_FORMAT_MONOCHROME:
804
3
            _gx_utility_write_bitmap_data_monochrome(canvas, rect, write_data);
805
3
            break;
806
807
808
3
        case GX_COLOR_FORMAT_4BIT_GRAY:
809
3
            _gx_utility_write_bitmap_data_4bpp(canvas, rect, write_data);
810
3
            break;
811
812
4
        case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
813
        case GX_COLOR_FORMAT_8BIT_PALETTE:
814
4
            _gx_utility_write_bitmap_data_8bpp(canvas, rect, write_data);
815
4
            break;
816
817
6
        case GX_COLOR_FORMAT_1555XRGB:
818
        case GX_COLOR_FORMAT_4444ARGB:
819
        case GX_COLOR_FORMAT_565RGB:
820
6
            _gx_utility_write_bitmap_data_16bpp(canvas, rect, write_data);
821
6
            break;
822
823
2
        case GX_COLOR_FORMAT_24XRGB:
824
        case GX_COLOR_FORMAT_32ARGB:
825
2
            _gx_utility_write_bitmap_data_32bpp(canvas, rect, write_data);
826
2
            break;
827
828
1
        case GX_COLOR_FORMAT_2BIT_GRAY: /* Not support now. */
829
        default:
830
1
            return GX_NOT_SUPPORTED;
831
        }
832
    }
833
834
20
    return status;
835
}
836