bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression) { // Read file FILE* f = fopen(filename, "rb"); if (!f) return false; int data_sz; if (fseek(f, 0, SEEK_END) || (data_sz = (int)ftell(f)) == -1 || fseek(f, 0, SEEK_SET)) { fclose(f); return false; } char* data = new char[data_sz+4]; if (fread(data, 1, data_sz, f) != (size_t)data_sz) { fclose(f); delete[] data; return false; } memset((void *)(((char*)data) + data_sz), 0, 4); fclose(f); // Compress int maxlen = data_sz + 512 + (data_sz >> 2) + sizeof(int); // total guess char* compressed = use_compression ? new char[maxlen] : data; int compressed_sz = use_compression ? stb_compress((stb_uchar*)compressed, (stb_uchar*)data, data_sz) : data_sz; if (use_compression) memset(compressed + compressed_sz, 0, maxlen - compressed_sz); // Output as Base85 encoded FILE* out = stdout; fprintf(out, "// File: '%s' (%d bytes)\n", filename, (int)data_sz); fprintf(out, "// Exported using binary_to_compressed_c.cpp\n"); const char* compressed_str = use_compression ? "compressed_" : ""; if (use_base85_encoding) { fprintf(out, "static const char %s_%sdata_base85[%d+1] =\n \"", symbol, compressed_str, (int)((compressed_sz+3)/4)*5); int column = 0; for (int i = 0; i < compressed_sz; i += 4) { unsigned int d = *(unsigned int*)(compressed + i); fprintf(out, "%c%c%c%c%c", Encode85Byte(d), Encode85Byte(d/85), Encode85Byte(d/7225), Encode85Byte(d/614125), Encode85Byte(d/52200625)); if ((i % 112) == 112-4) fprintf(out, "\"\n \""); } fprintf(out, "\";\n\n"); } else { fprintf(out, "static const unsigned int %s_%ssize = %d;\n", symbol, compressed_str, (int)compressed_sz); fprintf(out, "static const unsigned int %s_%sdata[%d/4] =\n{", symbol, compressed_str, (int)((compressed_sz+3)/4)*4); int column = 0; for (int i = 0; i < compressed_sz; i += 4) { unsigned int d = *(unsigned int*)(compressed + i); if ((column++ % 12) == 0) fprintf(out, "\n 0x%08x, ", d); else fprintf(out, "0x%08x, ", d); } fprintf(out, "\n};\n\n"); } // Cleanup delete[] data; if (use_compression) delete[] compressed; return true; }
bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression) { // Read file FILE* f = fopen(filename, "rb"); if (!f) return false; int data_sz; if (fseek(f, 0, SEEK_END) || (data_sz = (int)ftell(f)) == -1 || fseek(f, 0, SEEK_SET)) { fclose(f); return false; } char* data = new char[data_sz+4]; if (fread(data, 1, data_sz, f) != (size_t)data_sz) { fclose(f); delete[] data; return false; } memset((void *)(((char*)data) + data_sz), 0, 4); fclose(f); // Compress int maxlen = data_sz + 512 + (data_sz >> 2) + sizeof(int); // total guess char* compressed = use_compression ? new char[maxlen] : data; int compressed_sz = use_compression ? stb_compress((stb_uchar*)compressed, (stb_uchar*)data, data_sz) : data_sz; if (use_compression) memset(compressed + compressed_sz, 0, maxlen - compressed_sz); // Output as Base85 encoded FILE* out = stdout; fprintf(out, "// File: '%s' (%d bytes)\n", filename, (int)data_sz); fprintf(out, "// Exported using binary_to_compressed_c.cpp\n"); const char* compressed_str = use_compression ? "compressed_" : ""; if (use_base85_encoding) { fprintf(out, "static const char %s_%sdata_base85[%d+1] =\n \"", symbol, compressed_str, (int)((compressed_sz+3)/4)*5); char prev_c = 0; for (int src_i = 0; src_i < compressed_sz; src_i += 4) { // This is made a little more complicated by the fact that ??X sequences are interpreted as trigraphs by old C/C++ compilers. So we need to escape pairs of ??. unsigned int d = *(unsigned int*)(compressed + src_i); for (unsigned int n5 = 0; n5 < 5; n5++, d /= 85) { char c = Encode85Byte(d); fprintf(out, (c == '?' && prev_c == '?') ? "\\%c" : "%c", c); prev_c = c; } if ((src_i % 112) == 112-4) fprintf(out, "\"\n \""); } fprintf(out, "\";\n\n"); } else { fprintf(out, "static const unsigned int %s_%ssize = %d;\n", symbol, compressed_str, (int)compressed_sz); fprintf(out, "static const unsigned int %s_%sdata[%d/4] =\n{", symbol, compressed_str, (int)((compressed_sz+3)/4)*4); int column = 0; for (int i = 0; i < compressed_sz; i += 4) { unsigned int d = *(unsigned int*)(compressed + i); if ((column++ % 12) == 0) fprintf(out, "\n 0x%08x, ", d); else fprintf(out, "0x%08x, ", d); } fprintf(out, "\n};\n\n"); } // Cleanup delete[] data; if (use_compression) delete[] compressed; return true; }