Mercurial > hg > dmlib
view tools/data2inc.c @ 2208:90ec1ec89c56
Revamp the palette handling in lib64gfx somewhat, add helper functions to
lib64util for handling external palette file options and add support for
specifying one of the "internal" palettes or external (.act) palette file to
gfxconv and 64vw.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 14 Jun 2019 05:01:12 +0300 |
parents | e3f0eaf23f4f |
children | d76b0c92769d |
line wrap: on
line source
/* * data2inc - Convert binary data to "C"-source or XA-compatible include file * Programmed and designed by Matti 'ccr' Hamalainen * (C) Copyright 2003,2009-2012 Tecnic Software productions (TNSP) * * Please read file 'COPYING' for information on license and distribution. */ #include "dmtool.h" #include "dmlib.h" #include "dmargs.h" #include "dmmutex.h" #define RA_LINEBUF (16) enum { FMT_AUTO = 0, FMT_C, FMT_ASM }; char *optInFilename = NULL, *optOutFilename = NULL, *optObjName = "default_object", *optDataType = NULL, *optAddLine = NULL; int optIndentation = -1; int optFormat = FMT_AUTO; BOOL optHexMode = FALSE, optQuiet = FALSE, optExtraData = FALSE, optFormatting = TRUE; void (*writeHeader) (FILE *, char *) = NULL; void (*writeDecl) (FILE *, unsigned int, char *) = NULL; void (*writeData) (FILE *, Uint8 *, unsigned int) = NULL; void (*writeFooter) (FILE *, unsigned int, char *) = NULL; static const DMOptArg optList[] = { { 0, '?', "help", "Show this help", OPT_NONE }, { 4, 'A', "format-asm", "Output in XA-compatible asm", OPT_NONE }, { 5, 'C', "format-c", "Output in ANSI C", OPT_NONE }, { 1, 'n', "name", "Set object name", OPT_ARGREQ }, { 2, 't', "type", "Set datatype (unsigned char/byte)", OPT_ARGREQ }, { 3, 'a', "add-line", "Add this line to start of file", OPT_ARGREQ }, { 6, 'x', "hexadecimal", "Use hexadecimal output", OPT_NONE }, { 7, 'q', "quiet", "Do not add comments", OPT_NONE }, { 8, 'f', "no-formatting", "Disable additional output formatting", OPT_NONE }, { 9, 'i', "indentation", "Set indentation (negative value = tab)", OPT_ARGREQ }, { 10, 'e', "extra-data", "Add object end labels and size in asm output", OPT_NONE }, }; static const int optListN = sizeof(optList) / sizeof(optList[0]); void argShowHelp() { dmPrintBanner(stdout, dmProgName, "[options] [sourcefile] [destfile]"); dmArgsPrintHelp(stdout, optList, optListN, 0); printf( "\n" "To convert a data file to a C structure using 'Uint8' as type:\n" "$ data2inc -C -n variable_name -t Uint8 input.bin output.h\n" "\n" ); } BOOL argHandleOpt(const int optN, char *optArg, char *currArg) { switch (optN) { case 0: argShowHelp(); exit(0); break; case 1: optObjName = optArg; break; case 2: optDataType = optArg; break; case 3: optAddLine = optArg; break; case 4: optFormat = FMT_ASM; break; case 5: optFormat = FMT_C; break; case 6: optHexMode = TRUE; break; case 7: optQuiet = TRUE; break; case 8: optFormatting = FALSE; break; case 9: optIndentation = atoi(optArg); break; case 10: optExtraData = TRUE; break; default: dmErrorMsg("Unimplemented option argument '%s'.\n", currArg); return FALSE; } return TRUE; } BOOL argHandleFile(char * currArg) { if (!optInFilename) optInFilename = currArg; else if (!optOutFilename) optOutFilename = currArg; else dmErrorMsg("Source and destination filenames already specified, extraneous argument '%s'.\n", currArg); return TRUE; } /* Assembler include data output functions */ void writeHeader_ASM(FILE * f, char *name) { if (name) fprintf(f, "; '%s'", name); else fprintf(f, "; Generated"); fprintf(f, " by %s v%s\n", dmProgName, dmProgVersion); } void writeDecl_ASM(FILE * f, unsigned int len, char *name) { if (optExtraData) fprintf(f, "%s_size = %u\n", name, len); fprintf(f, "%s:\n", name); } void writeData_ASM(FILE * f, Uint8 * buf, unsigned int len) { fprintf(f, "%s ", optDataType); for (unsigned int i = 0; i < len; i++) { if (optFormatting) { if (optHexMode) fprintf(f, "$%.2x", buf[i]); else fprintf(f, "%3d", buf[i]); } else { if (optHexMode) fprintf(f, "$%x", buf[i]); else fprintf(f, "%d", buf[i]); } if (i < len - 1) fprintf(f, ","); } } void writeFooter_ASM(FILE * f, unsigned int len, char *name) { (void) len; if (optExtraData) fprintf(f, "%s_end: \n", name); else fprintf(f, "\n"); } /* ANSI-C include data output functions */ void writeHeader_C(FILE * f, char *name) { if (name) fprintf(f, "/* '%s' generated", name); else fprintf(f, "/* Generated"); fprintf(f, " by %s v%s\n" " */\n", dmProgName, dmProgVersion); } void writeDecl_C(FILE * f, unsigned int len, char *name) { fprintf(f, "%s %s[%u] = {\n", optDataType, name, len); printf("extern %s %s[%u];\n", optDataType, name, len); } void writeData_C(FILE * f, Uint8 * buf, unsigned int len) { unsigned int i; for (i = 0; i < len; i++) { if (optFormatting) { if (optHexMode) fprintf(f, "0x%.2x", buf[i]); else fprintf(f, "%3d", buf[i]); } else { if (optHexMode) fprintf(f, "0x%x", buf[i]); else fprintf(f, "%d", buf[i]); } fprintf(f, ","); } } void writeFooter_C(FILE * f, unsigned int len, char *name) { (void) len; (void) name; fprintf(f, "};\n"); } off_t dmGetFileSize(FILE *f) { off_t len, pos = ftello(f); fseeko(f, 0, SEEK_END); len = ftello(f); fseeko(f, pos, SEEK_SET); return len; } int main(int argc, char *argv[]) { FILE *sfile = NULL, *dfile = NULL; off_t inSize; Uint8 inBuf[RA_LINEBUF]; int tmpRes; /* Initialize */ dmInitProg("data2inc", "Data to include converter", "0.6", NULL, NULL); dmVerbosity = 0; /* Parse arguments */ if (!dmArgsProcess(argc, argv, optList, optListN, argHandleOpt, argHandleFile, OPTH_BAILOUT)) exit(1); /* Determine output type, if not specified */ if (optFormat == FMT_AUTO) { char *dext; if (optOutFilename == NULL) { dmErrorMsg("Output format not specified and no output filename given (try --help)\n"); exit(1); } /* Check filename extension */ dext = strrchr(optOutFilename, '.'); if (dext) { dext++; if (!strcasecmp(dext, "c") || !strcasecmp(dext, "h") || !strcasecmp(dext, "cc") || !strcasecmp(dext, "cpp") || !strcasecmp(dext, "hpp") || !strcasecmp(dext, "c++")) optFormat = FMT_C; else optFormat = FMT_ASM; } else optFormat = FMT_ASM; } /* Set functions */ switch (optFormat) { case FMT_ASM: if (!optDataType) optDataType = ".byte"; writeHeader = writeHeader_ASM; writeDecl = writeDecl_ASM; writeData = writeData_ASM; writeFooter = writeFooter_ASM; break; case FMT_C: if (!optDataType) optDataType = "unsigned char"; writeHeader = writeHeader_C; writeDecl = writeDecl_C; writeData = writeData_C; writeFooter = writeFooter_C; break; case FMT_AUTO: default: dmErrorMsg("Internal error, FMT_AUTO at output function init.\n"); exit(2); } /* Open the files */ if (optInFilename == NULL) sfile = stdin; else if ((sfile = fopen(optInFilename, "rb")) == NULL) { tmpRes = dmGetErrno(); dmErrorMsg("Error opening input file '%s'. (%s)\n", optInFilename, dmErrorStr(tmpRes)); exit(3); } if (optOutFilename == NULL) dfile = stdout; else if ((dfile = fopen(optOutFilename, "wa")) == NULL) { tmpRes = dmGetErrno(); dmErrorMsg("Error creating output file '%s'. (%s)\n", optOutFilename, dmErrorStr(tmpRes)); exit(4); } /* Get sourcefile size */ inSize = dmGetFileSize(sfile); /* Output header */ if (!optQuiet) writeHeader(dfile, optOutFilename); if (optAddLine) fprintf(dfile, "%s\n", optAddLine); /* Output declaration */ writeDecl(dfile, inSize, optObjName); /* Output data */ while (!feof(sfile)) { tmpRes = fread(inBuf, sizeof(Uint8), RA_LINEBUF, sfile); if (tmpRes > 0) { if (optIndentation < 0) fprintf(dfile, "\t"); else if (optIndentation > 0) { int i; for (i = 0; i < optIndentation; i++) fputs(" ", dfile); } writeData(dfile, inBuf, tmpRes); fprintf(dfile, "\n"); } } /* Output footer */ writeFooter(dfile, inSize, optObjName); /* Exit */ fclose(sfile); fclose(dfile); return 0; }