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
);
108 unsigned int row
, col
;
117 debugf("error - can't open '%s'\n", filename
);
122 if(read(fd
, &fh
, sizeof(struct Fileheader
)) !=
123 sizeof(struct Fileheader
))
125 debugf("error - can't Read Fileheader Stucture\n");
130 /* Exit if more than 8 bits */
131 depth
= readshort(&fh
.BitCount
);
134 debugf("error - Bitmap uses more than 8 bit depth, got %d\n",
140 /* Exit if too wide */
141 if(readlong(&fh
.Width
) > 160)
143 debugf("error - Bitmap is too wide for iRiver models (%d pixels, max is 160)\n",
144 readlong(&fh
.Width
));
147 if(readlong(&fh
.Width
) > 112)
149 debugf("info - Bitmap is too wide for Archos models (%d pixels, max is 112)\n",
150 readlong(&fh
.Width
));
153 /* Exit if too high */
154 if(readlong(&fh
.Height
) > 128)
156 debugf("error - Bitmap is too high for iRiver models (%d pixels, max is 128)\n",
157 readlong(&fh
.Height
));
160 if(readlong(&fh
.Height
) > 64)
162 debugf("info - Bitmap is too high for Archos models (%d pixels, max is 64)\n",
163 readlong(&fh
.Height
));
168 if(read(fd
, &palette
[l
],sizeof(struct RGBQUAD
)) !=
169 sizeof(struct RGBQUAD
))
171 debugf("error - Can't read bitmap's color palette\n");
177 /* pass the other palettes */
178 lseek(fd
, 254*sizeof(struct RGBQUAD
), SEEK_CUR
);
181 /* Try to guess the foreground and background colors.
182 We assume that the foreground color is the darkest. */
183 if(((int)palette
[0].rgbRed
+
184 (int)palette
[0].rgbGreen
+
185 (int)palette
[0].rgbBlue
) >
186 ((int)palette
[1].rgbRed
+
187 (int)palette
[1].rgbGreen
+
188 (int)palette
[1].rgbBlue
))
197 width
= readlong(&fh
.Width
);
200 PaddedWidth
= ((width
+3)&(~0x3)); /* aligned 4-bytes boundaries */
202 PaddedWidth
= ((width
+31)&(~0x1f))/8;
204 height
= readlong(&fh
.Height
);
206 allocsize
= size
= PaddedWidth
*height
; /* read this many bytes */
207 bmp
= (unsigned char *)malloc(size
);
210 /* not even 8 bytes, add up to a full 8 pixels boundary */
211 height
+= 8-(height
%8);
212 allocsize
= PaddedWidth
*height
; /* bytes to alloc */
215 *bitmap
= (unsigned char *)malloc(allocsize
);
219 debugf("error - Out of memory\n");
225 if(read(fd
, (unsigned char*)bmp
,(long)size
) != size
) {
226 debugf("error - Can't read image\n");
232 bitmap_height
= readlong(&fh
.Height
);
233 bitmap_width
= readlong(&fh
.Width
);
235 *get_width
= bitmap_width
;
236 *get_height
= bitmap_height
;
240 /* Now convert the bitmap into an array with 1 byte per pixel,
241 exactly the size of the image */
242 for(row
= 0;row
< bitmap_height
;row
++) {
243 for(col
= 0;col
< bitmap_width
;col
++) {
244 if(bmp
[(bitmap_height
-1 -row
) * PaddedWidth
+ col
]) {
245 (*bitmap
)[ (row
/8) * bitmap_width
+ col
] &=
249 (*bitmap
)[ (row
/8) * bitmap_width
+ col
] |=
259 /* monocrome BMP conversion uses 8 pixels per byte */
260 for(row
= 0; row
< bitmap_height
; row
++) {
263 for(col
= 0;col
< bitmap_width
;col
++) {
264 if((bmp
[(bitmap_height
- row
- 1) * PaddedWidth
+ byte
] &
266 (*bitmap
)[(row
/8) * bitmap_width
+ col
] &=
270 (*bitmap
)[(row
/8) * bitmap_width
+ col
] |=
288 return 0; /* success */
291 /*********************************************************************
292 ** generate_c_source()
294 ** Outputs a C source code with the bitmap in an array, accompanied by
296 **********************************************************************/
297 void generate_c_source(char *id
, int width
, int height
, unsigned char *bitmap
)
300 unsigned int i
, a
, eline
;
308 "#define BMPHEIGHT_%s %d"
309 "\n#define BMPWIDTH_%s %d"
310 "\nconst unsigned char %s[] = {\n",
311 id
, height
, id
, width
, id
);
313 for(i
=0, eline
=0; i
< height
; i
+=8, eline
++) {
314 for (a
=0; a
<width
; a
++)
315 fprintf(f
, "0x%02x,%c", bitmap
[eline
*width
+ a
],
321 fprintf(f
, "\n};\n");
325 /*********************************************************************
328 ** Outputs an ascii picture of the bitmap
329 **********************************************************************/
330 void generate_ascii(int width
, int height
, unsigned char *bitmap
)
333 unsigned int i
, eline
;
337 /* for screen output debugging */
338 for(i
=0, eline
=0; i
< height
; i
+=8, eline
++) {
340 for(y
=0; y
<8 && (i
+y
< height
); y
++) {
341 for(x
=0; x
< width
; x
++) {
343 if(bitmap
[eline
*width
+ x
] & (1<<y
)) {
354 void print_usage(void)
356 printf("Usage: %s [-i <id>] [-a] <bitmap file>\n"
357 "\t-i <id> Bitmap name (default is filename without extension)\n"
358 "\t-a Show ascii picture of bitmap\n",
360 printf("build date: " __DATE__
"\n\n");
363 int main(int argc
, char **argv
)
365 char *bmp_filename
= NULL
;
373 for(i
= 1;i
< argc
;i
++)
375 if(argv
[i
][0] == '-')
396 case 'a': /* Assembly */
410 bmp_filename
= argv
[i
];
428 char *ptr
=strrchr(bmp_filename
, '/');
434 for (i
= 0; id
[i
]; i
++)
439 if (read_bmp_file(bmp_filename
, &width
, &height
, &bitmap
))
443 generate_ascii(width
, height
, bitmap
);
445 generate_c_source(id
, width
, height
, bitmap
);