1#include "compiler.h" 2 3enum { 4 MODE_GEN_INFO, 5 MODE_GEN_DATA, 6 MODE_GEN_BMP 7}; 8 9typedef 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 18void 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 */ 27uint16_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 38void skip_bytes (FILE *fp, int n) 39{ 40 while (n-- > 0) 41 fgetc (fp); 42} 43 44__attribute__ ((__noreturn__)) 45int error (char * msg, FILE *fp) 46{ 47 fprintf (stderr, "ERROR: %s\n", msg); 48 49 fclose (fp); 50 51 exit (EXIT_FAILURE); 52} 53 54void 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 75int 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 225out: 226 fclose(fp); 227 return 0; 228} 229