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