blob: 81be306b986b7815d6e2d3cebca08781d497aaab [file] [log] [blame]
Wayne Xia5042ca52011-07-08 11:02:09 +08001/*
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*/
Kevin O'Connorfa9c66a2013-09-14 19:10:40 -04009#include "util.h" // malloc_tmphigh
10#include "bmp.h" // struct bmp_decdata
11#include "string.h" // memcpy
Wayne Xia5042ca52011-07-08 11:02:09 +080012
13#define bmp_load4byte(addr) (*(u32 *)(addr))
14#define bmp_load2byte(addr) (*(u16 *)(addr))
15
16typedef struct tagBITMAPFILEHEADER {
17 u8 bfType[2];
18 u8 bfSize[4];
19 u8 bfReserved1[2];
20 u8 bfReserved2[2];
21 u8 bfOffBits[4];
22} BITMAPFILEHEADER, tagBITMAPFILEHEADER;
23
24typedef struct tagBITMAPINFOHEADER {
25 u8 biSize[4];
26 u8 biWidth[4];
27 u8 biHeight[4];
28 u8 biPlanes[2];
29 u8 biBitCount[2];
30 u8 biCompression[4];
31 u8 biSizeImage[4];
32 u8 biXPelsPerMeter[4];
33 u8 biYPelsPerMeter[4];
34 u8 biClrUsed[4];
35 u8 biClrImportant[4];
36} BITMAPINFOHEADER, tagBITMAPINFOHEADER;
37
38typedef struct tagRGBQUAD {
39 u8 rgbBlue;
40 u8 rgbGreen;
41 u8 rgbRed;
42 u8 rgbReserved;
43} RGBQUAD, tagRGBQUAD;
44
45/* flat picture data adjusting function
46* description:
47* switch the vertical line sequence
48* arrange horizontal pixel data, add extra space in the dest buffer
49* for every line
50*/
51static void raw_data_format_adjust_24bpp(u8 *src, u8 *dest, int width,
52 int height, int bytes_per_line_dest)
53{
54 int bytes_per_line_src = 3 * width;
55 int i;
56 for (i = 0 ; i < height ; i++) {
57 memcpy(dest + i * bytes_per_line_dest,
58 src + (height - 1 - i) * bytes_per_line_src, bytes_per_line_src);
59 }
60}
61
62struct bmp_decdata *bmp_alloc(void)
63{
64 struct bmp_decdata *bmp = malloc_tmphigh(sizeof(*bmp));
65 return bmp;
66}
67
68int bmp_decode(struct bmp_decdata *bmp, unsigned char *data, int data_size)
69{
70 if (data_size < 54)
71 return 1;
72
73 u16 bmp_filehead = bmp_load2byte(data + 0);
74 if (bmp_filehead != 0x4d42)
75 return 2;
76 u32 bmp_recordsize = bmp_load4byte(data + 2);
77 if (bmp_recordsize != data_size)
78 return 3;
79 u32 bmp_dataoffset = bmp_load4byte(data + 10);
80 bmp->datap = (unsigned char *)data + bmp_dataoffset;
81 bmp->width = bmp_load4byte(data + 18);
82 bmp->height = bmp_load4byte(data + 22);
83 bmp->bpp = bmp_load2byte(data + 28);
84 return 0;
85}
86
87void bmp_get_size(struct bmp_decdata *bmp, int *width, int *height)
88{
89 *width = bmp->width;
90 *height = bmp->height;
91}
92
93
94int bmp_show(struct bmp_decdata *bmp, unsigned char *pic, int width
95 , int height, int depth, int bytes_per_line_dest)
96{
97 if (bmp->datap == pic)
98 return 0;
99 /* now only support 24bpp bmp file */
100 if ((depth == 24) && (bmp->bpp == 24)) {
101 raw_data_format_adjust_24bpp(bmp->datap, pic, width, height,
102 bytes_per_line_dest);
103 return 0;
104 }
105 return 1;
106}