blob: fecc295304b3e9f73d460d577f0c88b100620747 [file] [log] [blame]
Wayne Xia5042ca52011-07-08 11:02:09 +08001/*
2* Basic BMP data process and Raw picture data handle functions.
Stefan Weil6bcacf72015-10-02 08:46:40 +02003* Could be used to adjust pixel data format, get information, etc.
Wayne Xia5042ca52011-07-08 11:02:09 +08004*
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'Connor9dea5902013-09-14 20:23:54 -04009#include "malloc.h" // malloc_tmphigh
Kevin O'Connorfa9c66a2013-09-14 19:10:40 -040010#include "string.h" // memcpy
Kevin O'Connor07cf73b2013-09-15 00:31:17 -040011#include "util.h" // struct bmp_decdata
12
13struct bmp_decdata {
14 struct tagRGBQUAD *quadp;
15 unsigned char *datap;
16 int width;
17 int height;
18 int bpp;
19};
Wayne Xia5042ca52011-07-08 11:02:09 +080020
21#define bmp_load4byte(addr) (*(u32 *)(addr))
22#define bmp_load2byte(addr) (*(u16 *)(addr))
23
24typedef 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
32typedef 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
46typedef 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*/
Joseph Pacheco-Corwin63d69672019-01-29 23:00:00 +000059static void raw_data_format_adjust(u8 *src, u8 *dest, int width,
60 int height, int bytes_per_line_src, int bytes_per_line_dest)
Wayne Xia5042ca52011-07-08 11:02:09 +080061{
Wayne Xia5042ca52011-07-08 11:02:09 +080062 int i;
63 for (i = 0 ; i < height ; i++) {
64 memcpy(dest + i * bytes_per_line_dest,
65 src + (height - 1 - i) * bytes_per_line_src, bytes_per_line_src);
66 }
67}
68
Kevin O'Connor07cf73b2013-09-15 00:31:17 -040069/* allocate decdata struct */
Wayne Xia5042ca52011-07-08 11:02:09 +080070struct bmp_decdata *bmp_alloc(void)
71{
72 struct bmp_decdata *bmp = malloc_tmphigh(sizeof(*bmp));
73 return bmp;
74}
75
Kevin O'Connor07cf73b2013-09-15 00:31:17 -040076/* extract information from bmp file data */
Wayne Xia5042ca52011-07-08 11:02:09 +080077int bmp_decode(struct bmp_decdata *bmp, unsigned char *data, int data_size)
78{
79 if (data_size < 54)
80 return 1;
81
82 u16 bmp_filehead = bmp_load2byte(data + 0);
83 if (bmp_filehead != 0x4d42)
84 return 2;
85 u32 bmp_recordsize = bmp_load4byte(data + 2);
86 if (bmp_recordsize != data_size)
87 return 3;
88 u32 bmp_dataoffset = bmp_load4byte(data + 10);
89 bmp->datap = (unsigned char *)data + bmp_dataoffset;
90 bmp->width = bmp_load4byte(data + 18);
91 bmp->height = bmp_load4byte(data + 22);
92 bmp->bpp = bmp_load2byte(data + 28);
93 return 0;
94}
95
Kevin O'Connor07cf73b2013-09-15 00:31:17 -040096/* get bmp properties */
Joseph Pacheco-Corwin63d69672019-01-29 23:00:00 +000097void bmp_get_info(struct bmp_decdata *bmp, int *width, int *height, int *bpp)
Wayne Xia5042ca52011-07-08 11:02:09 +080098{
99 *width = bmp->width;
100 *height = bmp->height;
Joseph Pacheco-Corwin63d69672019-01-29 23:00:00 +0000101 *bpp = bmp->bpp;
Wayne Xia5042ca52011-07-08 11:02:09 +0800102}
103
Kevin O'Connor07cf73b2013-09-15 00:31:17 -0400104/* flush flat picture data to *pc */
Joseph Pacheco-Corwin63d69672019-01-29 23:00:00 +0000105int bmp_show(struct bmp_decdata *bmp, unsigned char *pic, int width,
106 int height, int depth, int bytes_per_line_dest)
Wayne Xia5042ca52011-07-08 11:02:09 +0800107{
108 if (bmp->datap == pic)
109 return 0;
Joseph Pacheco-Corwin63d69672019-01-29 23:00:00 +0000110 if ((depth == bmp->bpp) && (bmp->bpp%8 == 0)) {
111 raw_data_format_adjust(bmp->datap, pic, width, height,
112 (bmp->bpp/8)*width, bytes_per_line_dest);
Wayne Xia5042ca52011-07-08 11:02:09 +0800113 return 0;
114 }
115 return 1;
116}