summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMats Lidell <matsl@rockbox.org>2002-08-16 14:02:48 +0000
committerMats Lidell <matsl@rockbox.org>2002-08-16 14:02:48 +0000
commit8a700fe39ca776470650c723598a9bb2f5e15911 (patch)
tree1549779e63b6bda745b5ecdb60bfa09d8e1263f5
parent2f4435cc7c96e68c1123fd6645eead0af6fed9d5 (diff)
downloadrockbox-8a700fe39ca776470650c723598a9bb2f5e15911.tar.gz
rockbox-8a700fe39ca776470650c723598a9bb2f5e15911.zip
Created.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1781 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--tools/bmp2rb.c374
1 files changed, 374 insertions, 0 deletions
diff --git a/tools/bmp2rb.c b/tools/bmp2rb.c
new file mode 100644
index 0000000000..5eec2cbdb7
--- /dev/null
+++ b/tools/bmp2rb.c
@@ -0,0 +1,374 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19/*********************************************************************
20 *
21 * Converts BMP files to Rockbox bitmap format
22 *
23 * 1999-05-03 Linus Nielsen Feltzing
24 *
25 **********************************************/
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <stdbool.h>
31
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <fcntl.h>
35
36#define debugf printf
37
38#ifdef __GNUC__
39#define STRUCT_PACKED __attribute__((packed))
40#else
41#define STRUCT_PACKED
42#pragma pack (push, 2)
43#endif
44
45struct Fileheader
46{
47 unsigned short Type; /* signature - 'BM' */
48 unsigned long Size; /* file size in bytes */
49 unsigned short Reserved1; /* 0 */
50 unsigned short Reserved2; /* 0 */
51 unsigned long OffBits; /* offset to bitmap */
52 unsigned long StructSize; /* size of this struct (40) */
53 unsigned long Width; /* bmap width in pixels */
54 unsigned long Height; /* bmap height in pixels */
55 unsigned short Planes; /* num planes - always 1 */
56 unsigned short BitCount; /* bits per pixel */
57 unsigned long Compression; /* compression flag */
58 unsigned long SizeImage; /* image size in bytes */
59 long XPelsPerMeter; /* horz resolution */
60 long YPelsPerMeter; /* vert resolution */
61 unsigned long ClrUsed; /* 0 -> color table size */
62 unsigned long ClrImportant; /* important color count */
63} STRUCT_PACKED;
64
65struct RGBQUAD
66{
67 unsigned char rgbBlue;
68 unsigned char rgbGreen;
69 unsigned char rgbRed;
70 unsigned char rgbReserved;
71} STRUCT_PACKED;
72
73#ifdef LITTLE_ENDIAN
74#define readshort(x) x
75#define readlong(x) x
76#else
77
78#define readshort(x) (((x&0xff00)>>8)|((x&0x00ff)<<8))
79#define readlong(x) (((x&0xff000000)>>24)| \
80 ((x&0x00ff0000)>>8) | \
81 ((x&0x0000ff00)<<8) | \
82 ((x&0x000000ff)<<24))
83#endif
84
85/*********************************************************************
86 * read_bmp_file()
87 *
88 * Reads a 8bit BMP file and puts the data in a 1-pixel-per-byte
89 * array. Returns 0 on success.
90 *
91 *********************************************************************/
92int read_bmp_file(char* filename,
93 int *get_width, /* in pixels */
94 int *get_height, /* in pixels */
95 char **bitmap)
96{
97 struct Fileheader fh;
98 struct RGBQUAD palette[2]; /* two colors only */
99
100 unsigned int bitmap_width, bitmap_height;
101
102 long PaddedWidth;
103 int background;
104 int fd = open(filename, O_RDONLY);
105 long size;
106 unsigned int row, col;
107 int l;
108 unsigned char *bmp;
109 int width;
110
111 if(fd == -1)
112 {
113 debugf("error - can't open '%s'\n", filename);
114 return 1;
115 }
116 else
117 {
118 if(read(fd, &fh, sizeof(struct Fileheader)) !=
119 sizeof(struct Fileheader))
120 {
121 debugf("error - can't Read Fileheader Stucture\n");
122 close(fd);
123 return 2;
124 }
125
126 /* Exit if not monochrome */
127 if(readshort(fh.BitCount) > 8)
128 {
129 debugf("error - Bitmap must be less than 8, got %d\n",
130 readshort(fh.BitCount));
131 close(fd);
132 return 2;
133 }
134
135 /* Exit if too wide */
136 if(readlong(fh.Width) > 112)
137 {
138 debugf("error - Bitmap is too wide (%d pixels, max is 112)\n",
139 readlong(fh.Width));
140 close(fd);
141 return 3;
142 }
143 debugf("Bitmap is %d pixels wide\n", readlong(fh.Width));
144
145 /* Exit if too high */
146 if(readlong(fh.Height) > 64)
147 {
148 debugf("error - Bitmap is too high (%d pixels, max is 64)\n",
149 readlong(fh.Height));
150 close(fd);
151 return 4;
152 }
153 debugf("Bitmap is %d pixels heigh\n", readlong(fh.Height));
154
155 for(l=0;l < 2;l++)
156 {
157 if(read(fd, &palette[l],sizeof(struct RGBQUAD)) !=
158 sizeof(struct RGBQUAD))
159 {
160 debugf("error - Can't read bitmap's color palette\n");
161 close(fd);
162 return 5;
163 }
164 }
165 /* pass the other palettes */
166 lseek(fd, 254*sizeof(struct RGBQUAD), SEEK_CUR);
167
168 /* Try to guess the foreground and background colors.
169 We assume that the foreground color is the darkest. */
170 if(((int)palette[0].rgbRed +
171 (int)palette[0].rgbGreen +
172 (int)palette[0].rgbBlue) >
173 ((int)palette[1].rgbRed +
174 (int)palette[1].rgbGreen +
175 (int)palette[1].rgbBlue))
176 {
177 background = 0;
178 }
179 else
180 {
181 background = 1;
182 }
183
184 width = readlong(fh.Width);
185 PaddedWidth = ((width+3)&(~0x3));
186 size = PaddedWidth*readlong(fh.Height);
187
188 bmp = (unsigned char *)malloc(size);
189 *bitmap = (unsigned char *)malloc(size);
190
191 if(bmp == NULL)
192 {
193 debugf("error - Out of memory\n");
194 close(fd);
195 return 6;
196 }
197 else
198 {
199 if(read(fd, (unsigned char*)bmp,(long)size) != size) {
200 debugf("error - Can't read image\n");
201 close(fd);
202 return 7;
203 }
204 }
205
206 bitmap_height = readlong(fh.Height);
207 bitmap_width = readlong(fh.Width);
208
209 *get_width = bitmap_width;
210 *get_height = bitmap_height;
211
212 /* Now convert the bitmap into an array with 1 byte per pixel,
213 exactly the size of the image */
214
215 for(row = 0;row < bitmap_height;row++) {
216 for(col = 0;col < bitmap_width;col++) {
217 if(bmp[(bitmap_height-1 -row) * PaddedWidth + col]) {
218 (*bitmap)[ (row/8) * bitmap_width + col ] &= ~ (1<<(row&7));
219 }
220 else {
221 (*bitmap)[ (row/8) * bitmap_width + col ] |= 1<<(row&7);
222 }
223 }
224 }
225
226 free(bmp);
227
228 }
229 close(fd);
230 return 0; /* success */
231}
232
233/*********************************************************************
234** generate_c_source()
235**
236** Outputs a C source code with the bitmap in an array, accompanied by
237** some #define's
238**********************************************************************/
239void generate_c_source(char *id, int width, int height, unsigned char *bitmap)
240{
241 FILE *f;
242 unsigned int i, a, eline;
243
244 f = stdout;
245
246 fprintf(f, "\nconst unsigned char %s[] = {\n", id);
247
248 for(i=0, eline=0; i< height; i+=8, eline++) {
249 for (a=0; a<width; a++) fprintf(f, "0x%02x, ", bitmap[eline*width + a]);
250 fprintf(f, "\n");
251 }
252
253
254 fprintf(f, "\n};");
255}
256
257
258/*********************************************************************
259** generate_ascii()
260**
261** Outputs an ascii picture of the bitmap
262**********************************************************************/
263void generate_ascii(int width, int height, unsigned char *bitmap)
264{
265 FILE *f;
266 unsigned int i, eline;
267
268 f = stdout;
269
270 /* for screen output debugging */
271 for(i=0, eline=0; i< height; i+=8, eline++) {
272 unsigned int x, y;
273 for(y=0; y<8 && (i+y < height); y++) {
274 for(x=0; x < width; x++) {
275
276 if(bitmap[eline*width + x] & (1<<y)) {
277 fprintf(f, "*");
278 }
279 else
280 fprintf(f, " ");
281 }
282 fprintf(f, "\n");
283 }
284 }
285}
286
287void print_usage(void)
288{
289 printf("Usage: %s [-i <id>] [-a] <bitmap file>\n"
290 "\t-i <id> Bitmap name (default is filename without extension)\n"
291 "\t-a Show ascii picture of bitmap\n",
292 APPLICATION_NAME);
293 printf("build date: " __DATE__ "\n\n");
294}
295
296int main(int argc, char **argv)
297{
298 char *bmp_filename = NULL;
299 char *id = NULL;
300 int i;
301 int height, width;
302 int ascii = false;
303 char* bitmap = NULL;
304
305
306 for(i = 1;i < argc;i++)
307 {
308 if(argv[i][0] == '-')
309 {
310 switch(argv[i][1])
311 {
312 case 'i': /* ID */
313 if(argv[i][2])
314 {
315 id = &argv[i][2];
316 }
317 else if(argc > i+1)
318 {
319 id = argv[i+1];
320 i++;
321 }
322 else
323 {
324 print_usage();
325 exit(1);
326 }
327 break;
328
329 case 'a': /* Assembly */
330 ascii = true;
331 break;
332
333 default:
334 print_usage();
335 exit(1);
336 break;
337 }
338 }
339 else
340 {
341 if(!bmp_filename)
342 {
343 bmp_filename = argv[i];
344 }
345 else
346 {
347 print_usage();
348 exit(1);
349 }
350 }
351 }
352
353 if (!bmp_filename)
354 {
355 print_usage();
356 exit(1);
357 }
358
359 if (!id)
360 {
361 id = strdup(bmp_filename);
362 for (i = 0; id[i]; i++) if (id[i] == '.') id[i] = '\0';
363 }
364
365 if (read_bmp_file(bmp_filename, &width, &height, &bitmap))
366 return 0;
367
368 if (ascii)
369 generate_ascii(width, height, bitmap);
370 else
371 generate_c_source(id, width, height, bitmap);
372
373 return 0;
374}