3 * @author Shinichiro Nakamura
\r
4 * @brief BMPファイルを少ないメモリでI/Oできるモジュールの実装。
\r
8 * ===============================================================
\r
11 * ===============================================================
\r
12 * Copyright (c) 2010-2011 Shinichiro Nakamura
\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
23 * The above copyright notice and this permission notice shall be
\r
24 * included in all copies or substantial portions of the Software.
\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
37 #include "bmplowio.h"
\r
39 static int fread_uint32_t(
\r
41 int (*func_getc)(void)) {
\r
44 for (i = 0; i < 4; i++) {
\r
45 int c = func_getc();
\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
58 static int fread_uint16_t(
\r
60 int (*func_getc)(void)) {
\r
63 for (i = 0; i < 2; i++) {
\r
64 int c = func_getc();
\r
70 *data = ((((uint16_t)temp[0]) << 0) & 0x00ff)
\r
71 | ((((uint16_t)temp[1]) << 8) & 0xff00) ;
\r
75 static int fwrite_uint32_t(
\r
77 int (*func_putc)(uint8_t c)) {
\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
92 static int fwrite_uint16_t(
\r
94 int (*func_putc)(uint8_t c)) {
\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
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
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
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
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
157 int bmplowio_palette_write(
\r
158 int (*func_putc)(uint8_t c),
\r
159 const bmp_rgbquad_t *rgbquad,
\r
162 const bmp_rgbquad_t *p = rgbquad;
\r
163 for (i = 0; i < n; i++) {
\r
165 func_putc(p->green);
\r
166 func_putc(p->blue);
\r
167 func_putc(p->reserved);
\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
179 * @todo 書き込みが必要になったら対応する。
\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
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
209 int bmplowio_palette_read(
\r
210 int (*func_getc)(void),
\r
211 bmp_rgbquad_t *rgbquad,
\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
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
236 for (y = 0; y < infohead->biHeight; y++) {
\r
237 for (x = 0; x < infohead->biWidth; x++) {
\r
238 if (infohead->biBitCount == 24) {
\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
249 for (i = 0; i < p; i++) {
\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
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
272 if (biBitCount == 32) {
\r
273 bmp_frame_bytesize = biWidth * 4 * biHeight;
\r
276 if (biBitCount == 24) {
\r
277 bmp_frame_bytesize =
\r
278 ((biWidth * 3 + 3) / 4) * 4 * biHeight;
\r
281 if (biBitCount == 8) {
\r
282 bmp_frame_bytesize =
\r
283 ((biWidth + 3) / 4) * 4 * biHeight;
\r
286 if (biBitCount == 4) {
\r
287 bmp_frame_bytesize =
\r
288 ((biWidth / 2 + 3) / 4) * 4 * biHeight;
\r
291 if (biBitCount == 2) {
\r
292 bmp_frame_bytesize =
\r
293 ((biWidth / 4 + 3) / 4) * 4 * biHeight;
\r
296 if (biBitCount == 1) {
\r
297 bmp_frame_bytesize =
\r
298 ((biWidth / 8 + 3) / 4) * 4 * biHeight;
\r
301 return bmp_frame_bytesize;
\r