Home | History | Annotate | Download | only in tools
      1 #include "compiler.h"
      2 
      3 enum {
      4 	MODE_GEN_INFO,
      5 	MODE_GEN_DATA
      6 };
      7 
      8 typedef struct bitmap_s {		/* bitmap description */
      9 	uint16_t width;
     10 	uint16_t height;
     11 	uint8_t	palette[256*3];
     12 	uint8_t	*data;
     13 } bitmap_t;
     14 
     15 #define DEFAULT_CMAP_SIZE	16	/* size of default color map	*/
     16 
     17 void usage(const char *prog)
     18 {
     19 	fprintf(stderr, "Usage: %s [--gen-info|--gen-data] file\n", prog);
     20 }
     21 
     22 /*
     23  * Neutralize little endians.
     24  */
     25 uint16_t le_short(uint16_t x)
     26 {
     27     uint16_t val;
     28     uint8_t *p = (uint8_t *)(&x);
     29 
     30     val =  (*p++ & 0xff) << 0;
     31     val |= (*p & 0xff) << 8;
     32 
     33     return val;
     34 }
     35 
     36 void skip_bytes (FILE *fp, int n)
     37 {
     38 	while (n-- > 0)
     39 		fgetc (fp);
     40 }
     41 
     42 __attribute__ ((__noreturn__))
     43 int error (char * msg, FILE *fp)
     44 {
     45 	fprintf (stderr, "ERROR: %s\n", msg);
     46 
     47 	fclose (fp);
     48 
     49 	exit (EXIT_FAILURE);
     50 }
     51 
     52 void gen_info(bitmap_t *b, uint16_t n_colors)
     53 {
     54 	printf("/*\n"
     55 		" * Automatically generated by \"tools/bmp_logo\"\n"
     56 		" *\n"
     57 		" * DO NOT EDIT\n"
     58 		" *\n"
     59 		" */\n\n\n"
     60 		"#ifndef __BMP_LOGO_H__\n"
     61 		"#define __BMP_LOGO_H__\n\n"
     62 		"#define BMP_LOGO_WIDTH\t\t%d\n"
     63 		"#define BMP_LOGO_HEIGHT\t\t%d\n"
     64 		"#define BMP_LOGO_COLORS\t\t%d\n"
     65 		"#define BMP_LOGO_OFFSET\t\t%d\n\n"
     66 		"extern unsigned short bmp_logo_palette[];\n"
     67 		"extern unsigned char bmp_logo_bitmap[];\n\n"
     68 		"#endif /* __BMP_LOGO_H__ */\n",
     69 		b->width, b->height, n_colors,
     70 		DEFAULT_CMAP_SIZE);
     71 }
     72 
     73 int main (int argc, char *argv[])
     74 {
     75 	int	mode, i, x;
     76 	FILE	*fp;
     77 	bitmap_t bmp;
     78 	bitmap_t *b = &bmp;
     79 	uint16_t data_offset, n_colors, hdr_size;
     80 
     81 	if (argc < 3) {
     82 		usage(argv[0]);
     83 		exit (EXIT_FAILURE);
     84 	}
     85 
     86 	if (!strcmp(argv[1], "--gen-info"))
     87 		mode = MODE_GEN_INFO;
     88 	else if (!strcmp(argv[1], "--gen-data"))
     89 		mode = MODE_GEN_DATA;
     90 	else {
     91 		usage(argv[0]);
     92 		exit(EXIT_FAILURE);
     93 	}
     94 
     95 	fp = fopen(argv[2], "rb");
     96 	if (!fp) {
     97 		perror(argv[2]);
     98 		exit (EXIT_FAILURE);
     99 	}
    100 
    101 	if (fgetc (fp) != 'B' || fgetc (fp) != 'M')
    102 		error ("Input file is not a bitmap", fp);
    103 
    104 	/*
    105 	 * read width and height of the image, and the number of colors used;
    106 	 * ignore the rest
    107 	 */
    108 	skip_bytes (fp, 8);
    109 	if (fread (&data_offset, sizeof (uint16_t), 1, fp) != 1)
    110 		error ("Couldn't read bitmap data offset", fp);
    111 	skip_bytes(fp, 2);
    112 	if (fread(&hdr_size,   sizeof(uint16_t), 1, fp) != 1)
    113 		error("Couldn't read bitmap header size", fp);
    114 	if (hdr_size < 40)
    115 		error("Invalid bitmap header", fp);
    116 	skip_bytes(fp, 2);
    117 	if (fread (&b->width,   sizeof (uint16_t), 1, fp) != 1)
    118 		error ("Couldn't read bitmap width", fp);
    119 	skip_bytes (fp, 2);
    120 	if (fread (&b->height,  sizeof (uint16_t), 1, fp) != 1)
    121 		error ("Couldn't read bitmap height", fp);
    122 	skip_bytes (fp, 22);
    123 	if (fread (&n_colors, sizeof (uint16_t), 1, fp) != 1)
    124 		error ("Couldn't read bitmap colors", fp);
    125 	skip_bytes(fp, hdr_size - 34);
    126 
    127 	/*
    128 	 * Repair endianess.
    129 	 */
    130 	data_offset = le_short(data_offset);
    131 	b->width = le_short(b->width);
    132 	b->height = le_short(b->height);
    133 	n_colors = le_short(n_colors);
    134 
    135 	/* assume we are working with an 8-bit file */
    136 	if ((n_colors == 0) || (n_colors > 256 - DEFAULT_CMAP_SIZE)) {
    137 		/* reserve DEFAULT_CMAP_SIZE color map entries for default map */
    138 		n_colors = 256 - DEFAULT_CMAP_SIZE;
    139 	}
    140 
    141 	if (mode == MODE_GEN_INFO) {
    142 		gen_info(b, n_colors);
    143 		goto out;
    144 	}
    145 
    146 	printf("/*\n"
    147 		" * Automatically generated by \"tools/bmp_logo\"\n"
    148 		" *\n"
    149 		" * DO NOT EDIT\n"
    150 		" *\n"
    151 		" */\n\n\n"
    152 		"#ifndef __BMP_LOGO_DATA_H__\n"
    153 		"#define __BMP_LOGO_DATA_H__\n\n");
    154 
    155 	/* allocate memory */
    156 	if ((b->data = (uint8_t *)malloc(b->width * b->height)) == NULL)
    157 		error ("Error allocating memory for file", fp);
    158 
    159 	/* read and print the palette information */
    160 	printf("unsigned short bmp_logo_palette[] = {\n");
    161 
    162 	for (i=0; i<n_colors; ++i) {
    163 		b->palette[(int)(i*3+2)] = fgetc(fp);
    164 		b->palette[(int)(i*3+1)] = fgetc(fp);
    165 		b->palette[(int)(i*3+0)] = fgetc(fp);
    166 		x=fgetc(fp);
    167 
    168 		printf ("%s0x0%X%X%X,%s",
    169 			((i%8) == 0) ? "\t" : "  ",
    170 			(b->palette[(int)(i*3+0)] >> 4) & 0x0F,
    171 			(b->palette[(int)(i*3+1)] >> 4) & 0x0F,
    172 			(b->palette[(int)(i*3+2)] >> 4) & 0x0F,
    173 			((i%8) == 7) ? "\n" : ""
    174 		);
    175 	}
    176 
    177 	/* seek to offset indicated by file header */
    178 	fseek(fp, (long)data_offset, SEEK_SET);
    179 
    180 	/* read the bitmap; leave room for default color map */
    181 	printf ("\n");
    182 	printf ("};\n");
    183 	printf ("\n");
    184 	printf("unsigned char bmp_logo_bitmap[] = {\n");
    185 	for (i=(b->height-1)*b->width; i>=0; i-=b->width) {
    186 		for (x = 0; x < b->width; x++) {
    187 			b->data[i + x] = (uint8_t) fgetc(fp)
    188 						+ DEFAULT_CMAP_SIZE;
    189 		}
    190 	}
    191 
    192 	for (i=0; i<(b->height*b->width); ++i) {
    193 		if ((i%8) == 0)
    194 			putchar ('\t');
    195 		printf ("0x%02X,%c",
    196 			b->data[i],
    197 			((i%8) == 7) ? '\n' : ' '
    198 		);
    199 	}
    200 	printf ("\n"
    201 		"};\n\n"
    202 		"#endif /* __BMP_LOGO_DATA_H__ */\n"
    203 	);
    204 
    205 out:
    206 	fclose(fp);
    207 	return 0;
    208 }
    209