/*
 * tngp/bin2h.c
 *
 * Copyright (C) 2021 bzt
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * @brief Small utility to convert binary to C header, because MacOSX does not support ld -b binary!
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "zlib.c"

int main(int argc, char **argv)
{
    FILE *f, *c, *h = NULL;
    unsigned long int size, len;
    unsigned char *buff = NULL, *buff2 = NULL;
    char p[255], *fn;
    int i, file = 1, comp = 0;

    if(argc < 2){
        printf("bin2h <bin file> [bin file2...]\r\n");
        exit(1);
    }

    if(!strcmp(argv[1], "-o")) {
        c = fopen(argv[2], "w"); if(!c) { fprintf(stderr, "bin2h: unable to open %s\r\n", argv[2]); return 1; }
        file = 3; comp = 0;
    } else {
        c = fopen("data.c", "w"); if(!c) { fprintf(stderr, "bin2h: unable to open data.c\r\n"); return 1; }
        h = fopen("data.h", "w"); if(!h) { fprintf(stderr, "bin2h: unable to open data.h\r\n"); return 1; }
        fprintf(h, "/* generated by bin2h, do not edit */\n\n");
    }
    fprintf(c, "/* generated by bin2h, do not edit */\n\n");
    for(; file < argc; file++){
        size = 0;
        f = fopen(argv[file],"rb");
        if(f) {
            fseek(f, 0, SEEK_END);
            size = ftell(f);
            fseek(f, 0, SEEK_SET);
            buff = (unsigned char*)malloc(size);
            if(!buff) {
                fprintf(stderr, "bin2h: memory allocation error\r\n");
                exit(2);
            }
            fread(buff, size, 1, f);
            fclose(f);
            fn = strrchr(argv[file], '/');
            if(!fn) fn = strrchr(argv[file], '\\');
            if(!fn) fn = argv[file]; else fn++;
            for(i = 0; fn[i]; i++)
                p[i] = fn[i] == '.' || fn[i] <= ' ' ? '_' : fn[i];
            p[i] = 0;
            if(comp && size > 16 && buff[0] != 0x1F && buff[1] != 0x8B) {
                len = compressBound(size);
                buff2 = (unsigned char*)malloc(len);
                if(!buff2) {
                    fprintf(stderr, "bin2h: memory allocation error\r\n");
                    exit(2);
                }
                compress2(buff2, &len, buff, size, 9);
                free(buff); buff = buff2;
            } else len = size;
            if(h) fprintf(h, "#define sizeof_%s %ld\nextern unsigned char binary_%s[%ld];\n", p, size, p, len);
            fprintf(c, "unsigned char binary_%s[%ld] = { ", p, len);
            for(i = 0; i < len; i++)
                fprintf(c,"%s%d", i?",":"", buff[i]);
            fprintf(c," };\n");
            free(buff);
            buff = NULL;
        } else
            fprintf(stderr, "bin2h: unable to open input file: %s\r\n", argv[file]);
    }
    if(h) fclose(h);
    fclose(c);
}
