Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / seabios / src / bmp.c
1 /*
2 * Basic BMP data process and Raw picture data handle functions.
3 * Could be used to adjust pixel data format, get infomation, etc.
4 *
5 * Copyright (C) 2011 Wayne Xia <xiawenc@cn.ibm.com>
6 *
7 * This work is licensed under the terms of the GNU LGPLv3.
8 */
9 #include "malloc.h" // malloc_tmphigh
10 #include "string.h" // memcpy
11 #include "util.h" // struct bmp_decdata
12
13 struct bmp_decdata {
14     struct tagRGBQUAD *quadp;
15     unsigned char *datap;
16     int width;
17     int height;
18     int bpp;
19 };
20
21 #define bmp_load4byte(addr) (*(u32 *)(addr))
22 #define bmp_load2byte(addr) (*(u16 *)(addr))
23
24 typedef struct tagBITMAPFILEHEADER {
25     u8 bfType[2];
26     u8 bfSize[4];
27     u8 bfReserved1[2];
28     u8 bfReserved2[2];
29     u8 bfOffBits[4];
30 } BITMAPFILEHEADER, tagBITMAPFILEHEADER;
31
32 typedef struct tagBITMAPINFOHEADER {
33     u8 biSize[4];
34     u8 biWidth[4];
35     u8 biHeight[4];
36     u8 biPlanes[2];
37     u8 biBitCount[2];
38     u8 biCompression[4];
39     u8 biSizeImage[4];
40     u8 biXPelsPerMeter[4];
41     u8 biYPelsPerMeter[4];
42     u8 biClrUsed[4];
43     u8 biClrImportant[4];
44 } BITMAPINFOHEADER, tagBITMAPINFOHEADER;
45
46 typedef struct tagRGBQUAD {
47     u8 rgbBlue;
48     u8 rgbGreen;
49     u8 rgbRed;
50     u8 rgbReserved;
51 } RGBQUAD, tagRGBQUAD;
52
53 /* flat picture data adjusting function
54 * description:
55 *   switch the vertical line sequence
56 *   arrange horizontal pixel data, add extra space in the dest buffer
57 *       for every line
58 */
59 static void raw_data_format_adjust_24bpp(u8 *src, u8 *dest, int width,
60                                         int height, int bytes_per_line_dest)
61 {
62     int bytes_per_line_src = 3 * width;
63     int i;
64     for (i = 0 ; i < height ; i++) {
65         memcpy(dest + i * bytes_per_line_dest,
66            src + (height - 1 - i) * bytes_per_line_src, bytes_per_line_src);
67     }
68 }
69
70 /* allocate decdata struct */
71 struct bmp_decdata *bmp_alloc(void)
72 {
73     struct bmp_decdata *bmp = malloc_tmphigh(sizeof(*bmp));
74     return bmp;
75 }
76
77 /* extract information from bmp file data */
78 int bmp_decode(struct bmp_decdata *bmp, unsigned char *data, int data_size)
79 {
80     if (data_size < 54)
81         return 1;
82
83     u16 bmp_filehead = bmp_load2byte(data + 0);
84     if (bmp_filehead != 0x4d42)
85         return 2;
86     u32 bmp_recordsize = bmp_load4byte(data + 2);
87     if (bmp_recordsize != data_size)
88         return 3;
89     u32 bmp_dataoffset = bmp_load4byte(data + 10);
90     bmp->datap = (unsigned char *)data + bmp_dataoffset;
91     bmp->width = bmp_load4byte(data + 18);
92     bmp->height = bmp_load4byte(data + 22);
93     bmp->bpp = bmp_load2byte(data + 28);
94     return 0;
95 }
96
97 /* get bmp properties */
98 void bmp_get_size(struct bmp_decdata *bmp, int *width, int *height)
99 {
100     *width = bmp->width;
101     *height = bmp->height;
102 }
103
104 /* flush flat picture data to *pc */
105 int bmp_show(struct bmp_decdata *bmp, unsigned char *pic, int width
106              , int height, int depth, int bytes_per_line_dest)
107 {
108     if (bmp->datap == pic)
109         return 0;
110     /* now only support 24bpp bmp file */
111     if ((depth == 24) && (bmp->bpp == 24)) {
112         raw_data_format_adjust_24bpp(bmp->datap, pic, width, height,
113                                         bytes_per_line_dest);
114         return 0;
115     }
116     return 1;
117 }