bmp_logo.c 4.6 KB

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