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