OSDN Git Service

First commitment for the BlackTank LPC1769.
[blacktank/blacktank.git] / bmplowio.c
1 /**\r
2  * @file bmplowio.c\r
3  * @author Shinichiro Nakamura\r
4  * @brief BMPファイルを少ないメモリでI/Oできるモジュールの実装。\r
5  */\r
6 \r
7 /*\r
8  * ===============================================================\r
9  *  BMP Low I/O Module\r
10  *  Version 0.0.1\r
11  * ===============================================================\r
12  * Copyright (c) 2010-2011 Shinichiro Nakamura\r
13  *\r
14  * Permission is hereby granted, free of charge, to any person\r
15  * obtaining a copy of this software and associated documentation\r
16  * files (the "Software"), to deal in the Software without\r
17  * restriction, including without limitation the rights to use,\r
18  * copy, modify, merge, publish, distribute, sublicense, and/or\r
19  * sell copies of the Software, and to permit persons to whom the\r
20  * Software is furnished to do so, subject to the following\r
21  * conditions:\r
22  *\r
23  * The above copyright notice and this permission notice shall be\r
24  * included in all copies or substantial portions of the Software.\r
25  *\r
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
27  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\r
28  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
29  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\r
30  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r
31  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
32  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\r
33  * OTHER DEALINGS IN THE SOFTWARE.\r
34  * ===============================================================\r
35  */\r
36 \r
37 #include "bmplowio.h"\r
38 \r
39 static int fread_uint32_t(\r
40         uint32_t *data,\r
41         int (*func_getc)(void)) {\r
42     uint8_t temp[4];\r
43     uint8_t i;\r
44     for (i = 0; i < 4; i++) {\r
45         int c = func_getc();\r
46         if (c < 0) {\r
47             return -1;\r
48         }\r
49         temp[i] = c;\r
50     }\r
51     *data = ((((uint32_t)temp[0]) << 0) & 0x000000ff)\r
52         | ((((uint32_t)temp[1]) << 8) & 0x0000ff00)\r
53         | ((((uint32_t)temp[2]) << 16) & 0x00ff0000)\r
54         | ((((uint32_t)temp[3]) << 24) & 0xff000000) ;\r
55     return 0;\r
56 }\r
57 \r
58 static int fread_uint16_t(\r
59         uint16_t *data,\r
60         int (*func_getc)(void)) {\r
61     uint8_t temp[2];\r
62     uint8_t i;\r
63     for (i = 0; i < 2; i++) {\r
64         int c = func_getc();\r
65         if (c < 0) {\r
66             return -1;\r
67         }\r
68         temp[i] = c;\r
69     }\r
70     *data = ((((uint16_t)temp[0]) << 0) & 0x00ff)\r
71         | ((((uint16_t)temp[1]) << 8) & 0xff00) ;\r
72     return 0;\r
73 }\r
74 \r
75 static int fwrite_uint32_t(\r
76         uint32_t data,\r
77         int (*func_putc)(uint8_t c)) {\r
78     uint8_t temp[4];\r
79     uint8_t i;\r
80     temp[0] = ((data) >> 0) & 0x000000ff;\r
81     temp[1] = ((data) >> 8) & 0x000000ff;\r
82     temp[2] = ((data) >> 16) & 0x000000ff;\r
83     temp[3] = ((data) >> 24) & 0x000000ff;\r
84     for (i = 0; i < 4; i++) {\r
85         if (func_putc(temp[i]) < 0) {\r
86             return -1;\r
87         }\r
88     }\r
89     return 0;\r
90 }\r
91 \r
92 static int fwrite_uint16_t(\r
93         uint16_t data,\r
94         int (*func_putc)(uint8_t c)) {\r
95     uint8_t temp[2];\r
96     uint8_t i;\r
97     temp[0] = ((data) >> 0) & 0x00ff;\r
98     temp[1] = ((data) >> 8) & 0x00ff;\r
99     for (i = 0; i < 2; i++) {\r
100         if (func_putc(temp[i]) < 0) {\r
101             return -1;\r
102         }\r
103     }\r
104     return 0;\r
105 }\r
106 \r
107 int bmplowio_header_init(\r
108         bmp_file_t* filehead,\r
109         bmp_info_t *infohead) {\r
110     filehead->bfType = 0;\r
111     filehead->bfType = 0;\r
112     filehead->bfSize = 0;\r
113     filehead->bfReserved1 = 0;\r
114     filehead->bfReserved2 = 0;\r
115     filehead->bfOffBits = 0;\r
116 \r
117     infohead->biSize = 0;\r
118     infohead->biWidth = 0;\r
119     infohead->biHeight = 0;\r
120     infohead->biPlanes = 0;\r
121     infohead->biBitCount = 0;\r
122     infohead->biCompression = 0;\r
123     infohead->biSizeImage = 0;\r
124     infohead->biXPelsPerMeter = 0;\r
125     infohead->biYPelsPerMeter = 0;\r
126     infohead->biClrUsed = 0;\r
127     infohead->biClrImportant = 0;\r
128 \r
129     return 0;\r
130 }\r
131 \r
132 int bmplowio_header_write(\r
133         int (*func_putc)(uint8_t c),\r
134         const bmp_file_t *filehead,\r
135         const bmp_info_t *infohead) {\r
136     fwrite_uint16_t(filehead->bfType, func_putc);\r
137     fwrite_uint32_t(filehead->bfSize, func_putc);\r
138     fwrite_uint16_t(filehead->bfReserved1, func_putc);\r
139     fwrite_uint16_t(filehead->bfReserved2, func_putc);\r
140     fwrite_uint32_t(filehead->bfOffBits, func_putc);\r
141 \r
142     fwrite_uint32_t(infohead->biSize, func_putc);\r
143     fwrite_uint32_t(infohead->biWidth, func_putc);\r
144     fwrite_uint32_t(infohead->biHeight, func_putc);\r
145     fwrite_uint16_t(infohead->biPlanes, func_putc);\r
146     fwrite_uint16_t(infohead->biBitCount, func_putc);\r
147     fwrite_uint32_t(infohead->biCompression, func_putc);\r
148     fwrite_uint32_t(infohead->biSizeImage, func_putc);\r
149     fwrite_uint32_t(infohead->biXPelsPerMeter, func_putc);\r
150     fwrite_uint32_t(infohead->biYPelsPerMeter, func_putc);\r
151     fwrite_uint32_t(infohead->biClrUsed, func_putc);\r
152     fwrite_uint32_t(infohead->biClrImportant, func_putc);\r
153 \r
154     return 0;\r
155 }\r
156 \r
157 int bmplowio_palette_write(\r
158         int (*func_putc)(uint8_t c),\r
159         const bmp_rgbquad_t *rgbquad,\r
160         size_t n) {\r
161     int i;\r
162     const bmp_rgbquad_t *p = rgbquad;\r
163     for (i = 0; i < n; i++) {\r
164         func_putc(p->red);\r
165         func_putc(p->green);\r
166         func_putc(p->blue);\r
167         func_putc(p->reserved);\r
168         p++;\r
169     }\r
170     return 0;\r
171 }\r
172 \r
173 int bmplowio_image_write(\r
174         int (*func_putc)(uint8_t c),\r
175         const bmp_file_t *filehead,\r
176         const bmp_info_t *infohead,\r
177         void(*func)(int x, int y, int *r, int *g, int *b)) {\r
178     /**\r
179      * @todo 書き込みが必要になったら対応する。\r
180      */\r
181     return 0;\r
182 }\r
183 \r
184 int bmplowio_header_read(\r
185         int (*func_getc)(void),\r
186         bmp_file_t *filehead,\r
187         bmp_info_t *infohead) {\r
188     fread_uint16_t(&filehead->bfType, func_getc);\r
189     fread_uint32_t(&filehead->bfSize, func_getc);\r
190     fread_uint16_t(&filehead->bfReserved1, func_getc);\r
191     fread_uint16_t(&filehead->bfReserved2, func_getc);\r
192     fread_uint32_t(&filehead->bfOffBits, func_getc);\r
193 \r
194     fread_uint32_t(&infohead->biSize, func_getc);\r
195     fread_uint32_t(&infohead->biWidth, func_getc);\r
196     fread_uint32_t(&infohead->biHeight, func_getc);\r
197     fread_uint16_t(&infohead->biPlanes, func_getc);\r
198     fread_uint16_t(&infohead->biBitCount, func_getc);\r
199     fread_uint32_t(&infohead->biCompression, func_getc);\r
200     fread_uint32_t(&infohead->biSizeImage, func_getc);\r
201     fread_uint32_t(&infohead->biXPelsPerMeter, func_getc);\r
202     fread_uint32_t(&infohead->biYPelsPerMeter, func_getc);\r
203     fread_uint32_t(&infohead->biClrUsed, func_getc);\r
204     fread_uint32_t(&infohead->biClrImportant, func_getc);\r
205 \r
206     return 0;\r
207 }\r
208 \r
209 int bmplowio_palette_read(\r
210         int (*func_getc)(void),\r
211         bmp_rgbquad_t *rgbquad,\r
212         size_t n) {\r
213     int i;\r
214     bmp_rgbquad_t *p = rgbquad;\r
215     for (i = 0; i < n; i++) {\r
216         p->red = func_getc();\r
217         p->green = func_getc();\r
218         p->blue = func_getc();\r
219         p->reserved = func_getc();\r
220         p++;\r
221     }\r
222     return 0;\r
223 }\r
224 \r
225 int bmplowio_image_read(\r
226         int (*func_getc)(void),\r
227         const bmp_file_t *filehead,\r
228         const bmp_info_t *infohead,\r
229         void(*func)(int x, int y, int r, int g, int b)) {\r
230     const int w = infohead->biWidth;\r
231     const int h = infohead->biHeight;\r
232     const int p = (w * infohead->biBitCount + 31) / 32 * 4\r
233                   - (w * infohead->biBitCount + 7 ) / 8;\r
234     int x, y;\r
235     int i;\r
236     for (y = 0; y < infohead->biHeight; y++) {\r
237         for (x = 0; x < infohead->biWidth; x++) {\r
238             if (infohead->biBitCount == 24) {\r
239                 int a, b, c;\r
240                 a = (uint8_t)func_getc();\r
241                 b = (uint8_t)func_getc();\r
242                 c = (uint8_t)func_getc();\r
243                 if (func != NULL) {\r
244                     func(x, h - y - 1, c, b, a);\r
245                 }\r
246             }\r
247             // TODO\r
248         }\r
249         for (i = 0; i < p; i++) {\r
250             func_getc();\r
251         }\r
252     }\r
253     return 0;\r
254 }\r
255 \r
256 int have_palette(const bmp_info_t *infohead) {\r
257     if ((infohead->biBitCount == 8)\r
258             || (infohead->biBitCount == 4)\r
259             || (infohead->biBitCount == 2)\r
260             || (infohead->biBitCount == 1)) {\r
261         return 1;\r
262     }\r
263     return 0;\r
264 }\r
265 \r
266 int calc_framebytesize(const bmp_info_t *infohead) {\r
267     const int biBitCount = infohead->biBitCount;\r
268     const int biWidth = infohead->biWidth;\r
269     const int biHeight = infohead->biHeight;\r
270     int bmp_frame_bytesize = -1;\r
271 \r
272     if (biBitCount == 32) {\r
273         bmp_frame_bytesize = biWidth * 4 * biHeight;\r
274     }\r
275 \r
276     if (biBitCount == 24) {\r
277         bmp_frame_bytesize =\r
278             ((biWidth * 3 + 3) / 4) * 4 * biHeight;\r
279     }\r
280 \r
281     if (biBitCount == 8) {\r
282         bmp_frame_bytesize =\r
283             ((biWidth     + 3) / 4) * 4 * biHeight;\r
284     }\r
285 \r
286     if (biBitCount == 4) {\r
287         bmp_frame_bytesize =\r
288             ((biWidth / 2 + 3) / 4) * 4 * biHeight;\r
289     }\r
290 \r
291     if (biBitCount == 2) {\r
292         bmp_frame_bytesize =\r
293             ((biWidth / 4 + 3) / 4) * 4 * biHeight;\r
294     }\r
295 \r
296     if (biBitCount == 1) {\r
297         bmp_frame_bytesize =\r
298             ((biWidth / 8 + 3) / 4) * 4 * biHeight;\r
299     }\r
300 \r
301     return bmp_frame_bytesize;\r
302 }\r