1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 /*********************************************************************
21 * Converts BMP files to Rockbox bitmap format
23 * 1999-05-03 Linus Nielsen Feltzing
25 **********************************************/
32 #include <sys/types.h>
39 #define STRUCT_PACKED __attribute__((packed))
42 #pragma pack (push, 2)
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 */
67 unsigned char rgbBlue
;
68 unsigned char rgbGreen
;
70 unsigned char rgbReserved
;
74 short readshort(void* value
)
76 unsigned char* bytes
= (unsigned char*) value
;
77 return bytes
[0] | (bytes
[1] << 8);
80 int readlong(void* value
)
82 unsigned char* bytes
= (unsigned char*) value
;
83 return bytes
[0] | (bytes
[1] << 8) | (bytes
[2] << 16) | (bytes
[3] << 24);
86 /*********************************************************************
89 * Reads a 8bit BMP file and puts the data in a 1-pixel-per-byte
90 * array. Returns 0 on success.
92 *********************************************************************/
93 int read_bmp_file(char* filename
,
94 int *get_width
, /* in pixels */
95 int *get_height
, /* in pixels */
99 struct RGBQUAD palette
[2]; /* two colors only */
101 unsigned int bitmap_width
, bitmap_height
;
105 int fd
= open(filename
, O_RDONLY
);
107 unsigned int row
, col
;
115 debugf("error - can't open '%s'\n", filename
);
120 if(read(fd
, &fh
, sizeof(struct Fileheader
)) !=
121 sizeof(struct Fileheader
))
123 debugf("error - can't Read Fileheader Stucture\n");
128 /* Exit if more than 8 bits */
129 depth
= readshort(&fh
.BitCount
);
132 debugf("error - Bitmap uses more than 8 bit depth, got %d\n",
138 /* Exit if too wide */
139 if(readlong(&fh
.Width
) > 112)
141 debugf("error - Bitmap is too wide (%d pixels, max is 112)\n",
142 readlong(&fh
.Width
));
147 /* Exit if too high */
148 if(readlong(&fh
.Height
) > 64)
150 debugf("error - Bitmap is too high (%d pixels, max is 64)\n",
151 readlong(&fh
.Height
));
158 if(read(fd
, &palette
[l
],sizeof(struct RGBQUAD
)) !=
159 sizeof(struct RGBQUAD
))
161 debugf("error - Can't read bitmap's color palette\n");
167 /* pass the other palettes */
168 lseek(fd
, 254*sizeof(struct RGBQUAD
), SEEK_CUR
);
171 /* Try to guess the foreground and background colors.
172 We assume that the foreground color is the darkest. */
173 if(((int)palette
[0].rgbRed
+
174 (int)palette
[0].rgbGreen
+
175 (int)palette
[0].rgbBlue
) >
176 ((int)palette
[1].rgbRed
+
177 (int)palette
[1].rgbGreen
+
178 (int)palette
[1].rgbBlue
))
187 width
= readlong(&fh
.Width
);
190 PaddedWidth
= ((width
+3)&(~0x3)); /* aligned 4-bytes boundaries */
192 PaddedWidth
= ((width
+31)&(~0x1f))/8;
194 size
= PaddedWidth
*readlong(&fh
.Height
);
196 bmp
= (unsigned char *)malloc(size
);
197 *bitmap
= (unsigned char *)malloc(size
);
201 debugf("error - Out of memory\n");
207 if(read(fd
, (unsigned char*)bmp
,(long)size
) != size
) {
208 debugf("error - Can't read image\n");
214 bitmap_height
= readlong(&fh
.Height
);
215 bitmap_width
= readlong(&fh
.Width
);
217 *get_width
= bitmap_width
;
218 *get_height
= bitmap_height
;
222 /* Now convert the bitmap into an array with 1 byte per pixel,
223 exactly the size of the image */
224 for(row
= 0;row
< bitmap_height
;row
++) {
225 for(col
= 0;col
< bitmap_width
;col
++) {
226 if(bmp
[(bitmap_height
-1 -row
) * PaddedWidth
+ col
]) {
227 (*bitmap
)[ (row
/8) * bitmap_width
+ col
] &=
231 (*bitmap
)[ (row
/8) * bitmap_width
+ col
] |=
241 /* monocrome BMP conversion uses 8 pixels per byte */
242 for(row
= 0; row
< bitmap_height
; row
++) {
245 for(col
= 0;col
< bitmap_width
;col
++) {
246 if((bmp
[(bitmap_height
- row
- 1) * PaddedWidth
+ byte
] &
248 (*bitmap
)[(row
/8) * bitmap_width
+ col
] &=
252 (*bitmap
)[(row
/8) * bitmap_width
+ col
] |=
270 return 0; /* success */
273 /*********************************************************************
274 ** generate_c_source()
276 ** Outputs a C source code with the bitmap in an array, accompanied by
278 **********************************************************************/
279 void generate_c_source(char *id
, int width
, int height
, unsigned char *bitmap
)
282 unsigned int i
, a
, eline
;
290 "#define BMPHEIGHT_%s %d"
291 "\n#define BMPWIDTH_%s %d"
292 "\nconst unsigned char %s[] = {\n",
293 id
, height
, id
, width
, id
);
295 for(i
=0, eline
=0; i
< height
; i
+=8, eline
++) {
296 for (a
=0; a
<width
; a
++)
297 fprintf(f
, "0x%02x,%c", bitmap
[eline
*width
+ a
],
303 fprintf(f
, "\n};\n");
307 /*********************************************************************
310 ** Outputs an ascii picture of the bitmap
311 **********************************************************************/
312 void generate_ascii(int width
, int height
, unsigned char *bitmap
)
315 unsigned int i
, eline
;
319 /* for screen output debugging */
320 for(i
=0, eline
=0; i
< height
; i
+=8, eline
++) {
322 for(y
=0; y
<8 && (i
+y
< height
); y
++) {
323 for(x
=0; x
< width
; x
++) {
325 if(bitmap
[eline
*width
+ x
] & (1<<y
)) {
336 void print_usage(void)
338 printf("Usage: %s [-i <id>] [-a] <bitmap file>\n"
339 "\t-i <id> Bitmap name (default is filename without extension)\n"
340 "\t-a Show ascii picture of bitmap\n",
342 printf("build date: " __DATE__
"\n\n");
345 int main(int argc
, char **argv
)
347 char *bmp_filename
= NULL
;
355 for(i
= 1;i
< argc
;i
++)
357 if(argv
[i
][0] == '-')
378 case 'a': /* Assembly */
392 bmp_filename
= argv
[i
];
410 char *ptr
=strrchr(bmp_filename
, '/');
416 for (i
= 0; id
[i
]; i
++)
421 if (read_bmp_file(bmp_filename
, &width
, &height
, &bitmap
))
425 generate_ascii(width
, height
, bitmap
);
427 generate_c_source(id
, width
, height
, bitmap
);