22 #define _CRT_SECURE_NO_WARNINGS
33 static bool binary_to_compressed_c(
const char* filename,
const char* symbol,
bool use_base85_encoding,
bool use_compression);
35 int main(
int argc,
char** argv)
39 printf(
"Syntax: %s [-base85] [-nocompress] <inputfile> <symbolname>\n", argv[0]);
44 bool use_base85_encoding =
false;
45 bool use_compression =
true;
46 if (argv[argn][0] ==
'-')
48 if (strcmp(argv[argn],
"-base85") == 0) { use_base85_encoding =
true; argn++; }
49 else if (strcmp(argv[argn],
"-nocompress") == 0) { use_compression =
false; argn++; }
52 fprintf(stderr,
"Unknown argument: '%s'\n", argv[argn]);
59 fprintf(stderr,
"Error opening or reading file: '%s'\n", argv[argn]);
66 return (
x>=
'\\') ?
x+1 :
x;
69 bool binary_to_compressed_c(
const char* filename,
const char* symbol,
bool use_base85_encoding,
bool use_compression)
72 FILE*
f = fopen(filename,
"rb");
75 if (fseek(
f, 0, SEEK_END) || (data_sz = (
int)ftell(
f)) == -1 || fseek(
f, 0, SEEK_SET)) { fclose(
f);
return false; }
76 char*
data =
new char[data_sz+4];
77 if (fread(
data, 1, data_sz,
f) != (
size_t)data_sz) { fclose(
f);
delete[]
data;
return false; }
78 memset((
void*)(((
char*)
data) + data_sz), 0, 4);
82 int maxlen = data_sz + 512 + (data_sz >> 2) +
sizeof(
int);
83 char* compressed = use_compression ?
new char[maxlen] :
data;
86 memset(compressed + compressed_sz, 0, maxlen - compressed_sz);
90 fprintf(out,
"// File: '%s' (%d bytes)\n", filename, (
int)data_sz);
91 fprintf(out,
"// Exported using binary_to_compressed_c.cpp\n");
92 const char* compressed_str = use_compression ?
"compressed_" :
"";
93 if (use_base85_encoding)
95 fprintf(out,
"static const char %s_%sdata_base85[%d+1] =\n \"", symbol, compressed_str, (
int)((compressed_sz+3)/4)*5);
97 for (
int src_i = 0; src_i < compressed_sz; src_i += 4)
100 unsigned int d = *(
unsigned int*)(compressed + src_i);
101 for (
unsigned int n5 = 0; n5 < 5; n5++,
d /= 85)
104 fprintf(out, (c ==
'?' && prev_c ==
'?') ?
"\\%c" :
"%c", c);
107 if ((src_i % 112) == 112-4)
108 fprintf(out,
"\"\n \"");
110 fprintf(out,
"\";\n\n");
114 fprintf(out,
"static const unsigned int %s_%ssize = %d;\n", symbol, compressed_str, (
int)compressed_sz);
115 fprintf(out,
"static const unsigned int %s_%sdata[%d/4] =\n{", symbol, compressed_str, (
int)((compressed_sz+3)/4)*4);
117 for (
int i = 0;
i < compressed_sz;
i += 4)
119 unsigned int d = *(
unsigned int*)(compressed +
i);
120 if ((column++ % 12) == 0)
121 fprintf(out,
"\n 0x%08x, ",
d);
123 fprintf(out,
"0x%08x, ",
d);
125 fprintf(out,
"\n};\n\n");
141 const unsigned long ADLER_MOD = 65521;
142 unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
143 unsigned long blocklen,
i;
145 blocklen = buflen % 5552;
147 for (
i=0;
i + 7 < blocklen;
i += 8) {
148 s1 +=
buffer[0], s2 += s1;
149 s1 +=
buffer[1], s2 += s1;
150 s1 +=
buffer[2], s2 += s1;
151 s1 +=
buffer[3], s2 += s1;
152 s1 +=
buffer[4], s2 += s1;
153 s1 +=
buffer[5], s2 += s1;
154 s1 +=
buffer[6], s2 += s1;
155 s1 +=
buffer[7], s2 += s1;
160 for (;
i < blocklen; ++
i)
161 s1 += *
buffer++, s2 += s1;
163 s1 %= ADLER_MOD, s2 %= ADLER_MOD;
167 return (s2 << 16) + s1;
173 for (
i=0;
i < maxlen; ++
i)
174 if (m1[
i] != m2[
i])
return i;
191 #define stb_out(v) do { if (stb__out) *stb__out++ = (stb_uchar) (v); else stb__write((stb_uchar) (v)); } while (0)
199 while (numlit > 65536) {
206 else if (numlit <= 32)
stb_out (0x000020 + numlit-1);
207 else if (numlit <= 2048)
stb_out2(0x000800 + numlit-1);
221 return ((best > 2 && dist <= 0x00100)
222 || (best > 5 && dist <= 0x04000)
223 || (best > 7 && dist <= 0x80000));
230 #define stb__hc(q,h,c) (((h) << 7) + ((h) >> 25) + q[c])
231 #define stb__hc2(q,h,c,d) (((h) << 14) + ((h) >> 18) + (q[c] << 7) + q[d])
232 #define stb__hc3(q,c,d,e) ((q[c] << 14) + (q[d] << 7) + q[e])
240 int *pending_literals,
250 #define STB__SCRAMBLE(h) (((h) + ((h) >> 16)) & mask)
259 int best = 2, dist=0;
266 #define stb__nc(b,d) ((d) <= window && ((b) > 9 || stb_not_crap(b,d)))
268 #define STB__TRY(t,p) \
269 if (p ? dist != q-t : 1) \
270 if ((m = stb_matchlen(t, q, match_max)) > best) \
271 if (stb__nc(m,q-(t))) \
272 best = m, dist = q - (t)
279 t = chash[h1];
if (t)
STB__TRY(t,0);
285 t = chash[h4];
if (t)
STB__TRY(t,1);
289 chash[h1] = chash[h2] = chash[h3] = chash[h4] = q;
297 }
else if (best > 2 && best <= 0x80 && dist <= 0x100) {
298 outliterals(lit_start, q-lit_start); lit_start = (q += best);
301 }
else if (best > 5 && best <= 0x100 && dist <= 0x4000) {
302 outliterals(lit_start, q-lit_start); lit_start = (q += best);
305 }
else if (best > 7 && best <= 0x100 && dist <= 0x80000) {
306 outliterals(lit_start, q-lit_start); lit_start = (q += best);
309 }
else if (best > 8 && best <= 0x10000 && dist <= 0x80000) {
310 outliterals(lit_start, q-lit_start); lit_start = (q += best);
313 }
else if (best > 9 && dist <= 0x1000000) {
314 if (best > 65536) best = 65536;
315 outliterals(lit_start, q-lit_start); lit_start = (q += best);
335 *pending_literals = (q - lit_start);
348 if (chash ==
NULL)
return 0;