GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_utility_canvas_to_bmp.c Lines: 261 261 100.0 %
Date: 2026-03-06 19:21:09 Branches: 95 95 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** GUIX Component                                                        */
17
/**                                                                       */
18
/**   Text Input Management (Single Line Text Input)                      */
19
/**                                                                       */
20
/**************************************************************************/
21
22
/* Include necessary system files.  */
23
#define GX_SOURCE_CODE
24
25
#include "gx_api.h"
26
#include "gx_utility.h"
27
28
#define BI_RGB       0L
29
#define BI_BITFIELDS 3L
30
31
#define DATA_OFFSET  54
32
typedef struct bitmap_file_header_struct
33
{
34
    USHORT filetype;
35
    UINT   filesize;
36
    UINT   reserved;
37
    UINT   offset;
38
} bitmap_file_header;
39
40
typedef struct bmp_info_struct
41
{
42
    UINT   bi_Size;
43
    INT    bi_Width;
44
    INT    bi_Height;
45
    USHORT bi_Planes;
46
    USHORT bi_BitCount;
47
    UINT   bi_Compression;
48
    UINT   bi_SizeImage;
49
    UINT   bi_XPelsPerMeter;
50
    UINT   bi_YPelsPerMeter;
51
    UINT   bi_ClrUsed;
52
    UINT   bi_ClrImportant;
53
} bmp_info;
54
55
56
/**************************************************************************/
57
/*                                                                        */
58
/*  FUNCTION                                               RELEASE        */
59
/*                                                                        */
60
/*    _gx_utility_write_bitmap_header                     PORTABLE C      */
61
/*                                                           6.1          */
62
/*  AUTHOR                                                                */
63
/*                                                                        */
64
/*    Kenneth Maxwell, Microsoft Corporation                              */
65
/*                                                                        */
66
/*  DESCRIPTION                                                           */
67
/*                                                                        */
68
/*    This function create bitmap header and write it to bmp file.        */
69
/*                                                                        */
70
/*  INPUT                                                                 */
71
/*                                                                        */
72
/*    canvas                                Canvas control block          */
73
/*    rectangle                             Rectangle specification       */
74
/*    write_data                            Write data callback function  */
75
/*                                                                        */
76
/*  OUTPUT                                                                */
77
/*                                                                        */
78
/*    status                                Completion status             */
79
/*                                                                        */
80
/*  CALLS                                                                 */
81
/*                                                                        */
82
/*    None                                                                */
83
/*                                                                        */
84
/*  CALLED BY                                                             */
85
/*                                                                        */
86
/*    _gx_utility_canvas_to_bmp                                           */
87
/*                                                                        */
88
/**************************************************************************/
89
21
static UINT _gx_utility_write_bitmap_header(GX_CANVAS *canvas, GX_RECTANGLE *rect, UINT (*write_data)(GX_UBYTE *byte_data, UINT data_count))
90
{
91
bitmap_file_header bmp_fheader;
92
bmp_info           b_info;
93
GX_COLOR           color;
94
GX_COLOR          *palette;
95
INT                count;
96
INT                r;
97
INT                g;
98
INT                b;
99
INT                red;
100
INT                green;
101
INT                blue;
102
103
21
    memset(&bmp_fheader, 0, sizeof(bitmap_file_header));
104
21
    memset(&b_info, 0, sizeof(bmp_info));
105
21
    bmp_fheader.filetype = 0x4d42; /* "MB" */
106
21
    bmp_fheader.reserved = 0;
107
108
    /* calculate data offset */
109
21
    bmp_fheader.offset = DATA_OFFSET;
110
111
    /* set common datas for bmp info. */
112
21
    b_info.bi_Width = rect -> gx_rectangle_right - rect -> gx_rectangle_left + 1;
113
21
    b_info.bi_Height = rect -> gx_rectangle_bottom - rect -> gx_rectangle_top + 1;
114
21
    b_info.bi_Size = sizeof(bmp_info);
115
21
    b_info.bi_Planes = 1;
116
21
    b_info.bi_Compression = BI_RGB;
117
21
    b_info.bi_XPelsPerMeter = 0;
118
21
    b_info.bi_YPelsPerMeter = 0;
119
21
    b_info.bi_ClrUsed = 0;
120
21
    b_info.bi_ClrImportant = 0;
121
122

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


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

19
        switch (pixelmap_format)
747
        {
748
3
        case GX_COLOR_FORMAT_MONOCHROME:
749
3
            _gx_utility_write_bitmap_data_monochrome(canvas, rect, write_data);
750
3
            break;
751
752
753
3
        case GX_COLOR_FORMAT_4BIT_GRAY:
754
3
            _gx_utility_write_bitmap_data_4bpp(canvas, rect, write_data);
755
3
            break;
756
757
4
        case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
758
        case GX_COLOR_FORMAT_8BIT_PALETTE:
759
4
            _gx_utility_write_bitmap_data_8bpp(canvas, rect, write_data);
760
4
            break;
761
762
6
        case GX_COLOR_FORMAT_1555XRGB:
763
        case GX_COLOR_FORMAT_4444ARGB:
764
        case GX_COLOR_FORMAT_565RGB:
765
6
            _gx_utility_write_bitmap_data_16bpp(canvas, rect, write_data);
766
6
            break;
767
768
2
        case GX_COLOR_FORMAT_24XRGB:
769
        case GX_COLOR_FORMAT_32ARGB:
770
2
            _gx_utility_write_bitmap_data_32bpp(canvas, rect, write_data);
771
2
            break;
772
773
1
        case GX_COLOR_FORMAT_2BIT_GRAY: /* Not support now. */
774
        default:
775
1
            return GX_NOT_SUPPORTED;
776
        }
777
    }
778
779
20
    return status;
780
}
781