├── README.md ├── bth └── main.c /README.md: -------------------------------------------------------------------------------- 1 | # ByteToHeader 2 | 3 | Simple C tool to generate a C header file with an array of bytes of given file. Useful for storing resources in memory without relying on a file. 4 | 5 | Usage: 6 | ``` 7 | ./bth my_file my_file.h my_file_array(optional) 8 | ``` 9 | Output: 10 | ```c 11 | #pragma once 12 | 13 | // This file was auto-generated. 14 | 15 | unsigned char my_file_array[0xSIZE] = { 16 | // ... 17 | }; 18 | -------------------------------------------------------------------------------- /bth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypervisor/ByteToHeader/5fd571cf964759d6aa67bd83282621162ae224f1/bth -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // 6 | // Change this if you want more/less bytes per line. 7 | // 8 | 9 | #define MAX_BYTES_PER_LINE 8 10 | 11 | int main(int argc, char **argv) 12 | { 13 | FILE *fp; // File pointer 14 | long len; // File length (in bytes) 15 | char *buf; // Pointer to file buffer 16 | clock_t start, end; // Start and end times 17 | double diff, dtime; // Difference between start & end and time of execution 18 | 19 | if (argc < 3) { 20 | printf("Incorrect usage!\n"); 21 | return 1; 22 | } 23 | 24 | start = clock(); 25 | 26 | // 27 | // Read file to buffer. 28 | // 29 | 30 | fp = fopen(argv[1], "rb"); 31 | if (!fp) { 32 | printf("Failed to open file \"%s\"!\n", argv[1]); 33 | return 1; 34 | } 35 | 36 | fseek(fp, 0, SEEK_END); 37 | len = ftell(fp); 38 | fseek(fp, 0, SEEK_SET); 39 | 40 | buf = malloc(len); 41 | fread(buf, 1, len, fp); 42 | fclose(fp); 43 | 44 | // 45 | // Create file to write to. 46 | // 47 | 48 | fp = fopen(argv[2], "w"); 49 | if (!fp) { 50 | printf("Failed to open file \"%s\"!\n", argv[2]); 51 | return 1; 52 | } 53 | 54 | long lines; // We only want to print x amount of bytes per line 55 | char *arrname; // Name of array, if argument used 56 | 57 | lines = len / MAX_BYTES_PER_LINE; 58 | 59 | if (argc > 3) { 60 | arrname = argv[3]; 61 | } else { 62 | arrname = "bFileArray"; 63 | } 64 | 65 | printf("File size: 0x%lX\n", len); 66 | 67 | // 68 | // Now we print the bytes, first print the standard header stuff. 69 | // Then we loop through each line and print MAX_BYTES_PER_LINE per line. 70 | // This code is somewhat obscure and there are definitely better ways 71 | // to do this, but it is insignificant. 72 | // 73 | 74 | fprintf(fp, "#pragma once\n\n// This file was auto-generated.\n\nunsigned char %s[0x%lX] = {\n ", arrname, len); 75 | 76 | for (long i = 0; i < lines; ++i) { 77 | const char last_line = i == lines - 1; 78 | for (unsigned h = 0; h < MAX_BYTES_PER_LINE; ++h) { 79 | const char last_byte = h == MAX_BYTES_PER_LINE - 1; 80 | const long cur_byte = h + i * MAX_BYTES_PER_LINE; 81 | fprintf(fp, "0x%02X", buf[cur_byte]); 82 | if (last_line && last_byte) 83 | goto done; 84 | fprintf(fp, ", "); 85 | if (!last_line && last_byte) 86 | fprintf(fp, "\n "); 87 | } 88 | } 89 | 90 | done: 91 | fprintf(fp, "\n};"); 92 | 93 | end = clock(); 94 | diff = (double)end - start; 95 | dtime = diff / CLOCKS_PER_SEC; 96 | 97 | free(buf); 98 | fclose(fp); 99 | 100 | printf("Done! (%fs)\n", dtime); 101 | 102 | return 0; 103 | } --------------------------------------------------------------------------------