2 * Basic BMP data process and Raw picture data handle functions.
3 * Could be used to adjust pixel data format, get infomation, etc.
5 * Copyright (C) 2011 Wayne Xia <xiawenc@cn.ibm.com>
7 * This work is licensed under the terms of the GNU LGPLv3.
12 #define bmp_load4byte(addr) (*(u32 *)(addr))
13 #define bmp_load2byte(addr) (*(u16 *)(addr))
15 typedef struct tagBITMAPFILEHEADER {
21 } BITMAPFILEHEADER, tagBITMAPFILEHEADER;
23 typedef struct tagBITMAPINFOHEADER {
31 u8 biXPelsPerMeter[4];
32 u8 biYPelsPerMeter[4];
35 } BITMAPINFOHEADER, tagBITMAPINFOHEADER;
37 typedef struct tagRGBQUAD {
42 } RGBQUAD, tagRGBQUAD;
44 /* flat picture data adjusting function
46 * switch the vertical line sequence
47 * arrange horizontal pixel data, add extra space in the dest buffer
50 static void raw_data_format_adjust_24bpp(u8 *src, u8 *dest, int width,
51 int height, int bytes_per_line_dest)
53 int bytes_per_line_src = 3 * width;
55 for (i = 0 ; i < height ; i++) {
56 memcpy(dest + i * bytes_per_line_dest,
57 src + (height - 1 - i) * bytes_per_line_src, bytes_per_line_src);
61 struct bmp_decdata *bmp_alloc(void)
63 struct bmp_decdata *bmp = malloc_tmphigh(sizeof(*bmp));
67 int bmp_decode(struct bmp_decdata *bmp, unsigned char *data, int data_size)
72 u16 bmp_filehead = bmp_load2byte(data + 0);
73 if (bmp_filehead != 0x4d42)
75 u32 bmp_recordsize = bmp_load4byte(data + 2);
76 if (bmp_recordsize != data_size)
78 u32 bmp_dataoffset = bmp_load4byte(data + 10);
79 bmp->datap = (unsigned char *)data + bmp_dataoffset;
80 bmp->width = bmp_load4byte(data + 18);
81 bmp->height = bmp_load4byte(data + 22);
82 bmp->bpp = bmp_load2byte(data + 28);
86 void bmp_get_size(struct bmp_decdata *bmp, int *width, int *height)
89 *height = bmp->height;
93 int bmp_show(struct bmp_decdata *bmp, unsigned char *pic, int width
94 , int height, int depth, int bytes_per_line_dest)
96 if (bmp->datap == pic)
98 /* now only support 24bpp bmp file */
99 if ((depth == 24) && (bmp->bpp == 24)) {
100 raw_data_format_adjust_24bpp(bmp->datap, pic, width, height,
101 bytes_per_line_dest);