1// bin2c.c
2//
3// convert a binary file into a C source vector
4//
5// THE "BEER-WARE LICENSE" (Revision 3.1415):
6// sandro AT sigala DOT it wrote this file. As long as you retain this notice you can do
7// whatever you want with this stuff. If we meet some day, and you think this stuff is
8// worth it, you can buy me a beer in return. Sandro Sigala
9//
10// syntax: bin2c [-c] [-z] <input_file> <output_file>
11//
12// -c add the "const" keyword to definition
13// -z terminate the array with a zero (useful for embedded C strings)
14//
15// examples:
16// bin2c -c myimage.png myimage_png.cpp
17// bin2c -z sometext.txt sometext_txt.cpp
18
19#include <ctype.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
24#ifndef PATH_MAX
25#define PATH_MAX 1024
26#endif
27
28int useconst = 0;
29int zeroterminated = 0;
30
31int myfgetc(FILE *f)
32{
33 int c = fgetc(f);
34 if (c == EOF && zeroterminated)
35 {
36 zeroterminated = 0;
37 return 0;
38 }
39 return c;
40}
41
42void process(const char *ifname, const char *ofname)
43{
44 FILE *ifile, *ofile;
45 ifile = fopen(ifname, "rb");
46 if (ifile == NULL)
47 {
48 fprintf(stderr, "cannot open %s for reading\n", ifname);
49 exit(1);
50 }
51 ofile = fopen(ofname, "wb");
52 if (ofile == NULL)
53 {
54 fprintf(stderr, "cannot open %s for writing\n", ofname);
55 exit(1);
56 }
57 char buf[PATH_MAX], *p;
58 const char *cp;
59 if ((cp = strrchr(ifname, '/')) != NULL)
60 {
61 ++cp;
62 } else {
63 if ((cp = strrchr(ifname, '\\')) != NULL)
64 ++cp;
65 else
66 cp = ifname;
67 }
68 strcpy(buf, cp);
69 for (p = buf; *p != '\0'; ++p)
70 {
71 if (!isalnum(*p))
72 *p = '_';
73 }
74 fprintf(ofile, "static %sunsigned char %s[] = {\n", useconst ? "const " : "", buf);
75 int c, col = 1;
76 while ((c = myfgetc(ifile)) != EOF)
77 {
78 if (col >= 78 - 6)
79 {
80 fputc('\n', ofile);
81 col = 1;
82 }
83 fprintf(ofile, "0x%.2x, ", c);
84 col += 6;
85 }
86 fprintf(ofile, "\n};\n");
87
88 fclose(ifile);
89 fclose(ofile);
90}
91
92void usage(void)
93{
94 fprintf(stderr, "usage: bin2c [-cz] <input_file> <output_file>\n");
95 exit(1);
96}
97
98int main(int argc, char **argv)
99{
100 while (argc > 3)
101 {
102 if (!strcmp(argv[1], "-c"))
103 {
104 useconst = 1;
105 --argc;
106 ++argv;
107 } else if (!strcmp(argv[1], "-z"))
108 {
109 zeroterminated = 1;
110 --argc;
111 ++argv;
112 } else {
113 usage();
114 }
115 }
116 if (argc != 3)
117 {
118 usage();
119 }
120 process(argv[1], argv[2]);
121 return 0;
122}