diff options
Diffstat (limited to 'converter/pbm/pbmtoxbm.c')
-rw-r--r-- | converter/pbm/pbmtoxbm.c | 153 |
1 files changed, 84 insertions, 69 deletions
diff --git a/converter/pbm/pbmtoxbm.c b/converter/pbm/pbmtoxbm.c index ecb72b30..a452d6fa 100644 --- a/converter/pbm/pbmtoxbm.c +++ b/converter/pbm/pbmtoxbm.c @@ -10,10 +10,10 @@ ** implied warranty. */ -/* 2006.10 (afu) +/* 2006.10 (afu) Changed bitrow from plain to raw, read function from pbm_readpbmrow() to pbm_readpbmrow_packed(). Retired bitwise transformation functions. - + Output function putitem rewritten to handle both X10 and X11. Added -name option. There is no check for the string thus given. @@ -35,7 +35,7 @@ #include "nstring.h" -enum xbmVersion { X10, X11 }; +enum XbmVersion { X10, X11 }; struct CmdlineInfo { /* All the information the user supplied in the command line, @@ -43,16 +43,16 @@ struct CmdlineInfo { */ const char * inputFileName; const char * name; - enum xbmVersion xbmVersion; + enum XbmVersion xbmVersion; }; static void -parseCommandLine(int argc, +parseCommandLine(int argc, const char ** argv, struct CmdlineInfo *cmdlineP ) { /*---------------------------------------------------------------------------- Parse program command line described in Unix standard form by argc - and argv. Return the information in the options as *cmdlineP. + and argv. Return the information in the options as *cmdlineP. If command line is internally inconsistent (invalid options, etc.), issue error message to stderr and abort program. @@ -61,8 +61,6 @@ parseCommandLine(int argc, was passed to us as the argv array. We also trash *argv. -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to pm_optParseOptions3 on how to parse our options. */ - optStruct3 opt; unsigned int option_def_index; unsigned int x10, x11, nameSpec; @@ -78,7 +76,7 @@ parseCommandLine(int argc, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (!nameSpec) @@ -96,19 +94,19 @@ parseCommandLine(int argc, pm_error("Image name '%s' contains invalid character (%c).", cmdlineP->name, cmdlineP->name[i]); } - + if (x10 && x11) pm_error("You can't specify both -x10 and -x11"); else if (x10) cmdlineP->xbmVersion = X10; - else + else cmdlineP->xbmVersion = X11; - - if (argc-1 < 1) + + if (argc-1 < 1) cmdlineP->inputFileName = "-"; else { cmdlineP->inputFileName = argv[1]; - + if (argc-1 > 1) pm_error("Program takes zero or one argument (filename). You " "specified %u", argc-1); @@ -141,22 +139,22 @@ generateName(char const filenameArg[], /* indices into the input and output buffers */ /* Start just after the rightmost slash, or at beginning if no slash */ - if (strrchr(filenameArg, '/') == 0) + if (strrchr(filenameArg, '/') == 0) argIndex = 0; else argIndex = strrchr(filenameArg, '/') - filenameArg + 1; - if (filenameArg[argIndex] == '\0') + if (filenameArg[argIndex] == '\0') *nameP = strdup("noname"); else { char * name; nameIndex = 0; /* Start at beginning of name buffer */ name = malloc(strlen(filenameArg)); - - while (filenameArg[argIndex] != '\0' + + while (filenameArg[argIndex] != '\0' && filenameArg[argIndex] != '.') { const char filenameChar = filenameArg[argIndex++]; - name[nameIndex++] = + name[nameIndex++] = ISALNUM(filenameChar) ? filenameChar : '_'; } name[nameIndex] = '\0'; @@ -167,37 +165,46 @@ generateName(char const filenameArg[], -static unsigned short int itemBuff[22]; -static int itemCnt; /* takes values 0 to 15 (x11) or 21 (x10) */ -static enum xbmVersion itemVersion; +typedef struct { + unsigned short int buff[22]; + int cnt; /* takes values 0 to 15 (x11) or 21 (x10) */ + enum XbmVersion version; +} ItemWriter; + +static ItemWriter itemWriter; static void putitemX10(unsigned char const item) { - if (itemCnt == 22) { + if (itemWriter.cnt == 22) { /* Buffer is full. Write out one line. */ int rc; rc = printf(" 0x%02x%02x,0x%02x%02x,0x%02x%02x,0x%02x%02x," "0x%02x%02x,0x%02x%02x,0x%02x%02x,0x%02x%02x," "0x%02x%02x,0x%02x%02x,0x%02x%02x,\n", - itemBuff[ 1], itemBuff[ 0], itemBuff[ 3], itemBuff[ 2], - itemBuff[ 5], itemBuff[ 4], itemBuff[ 7], itemBuff[ 6], - itemBuff[ 9], itemBuff[ 8], itemBuff[11], itemBuff[10], - itemBuff[13], itemBuff[12], itemBuff[15], itemBuff[14], - itemBuff[17], itemBuff[16], itemBuff[19], itemBuff[18], - itemBuff[21], itemBuff[20] + itemWriter.buff[ 1], itemWriter.buff[ 0], + itemWriter.buff[ 3], itemWriter.buff[ 2], + itemWriter.buff[ 5], itemWriter.buff[ 4], + itemWriter.buff[ 7], itemWriter.buff[ 6], + itemWriter.buff[ 9], itemWriter.buff[ 8], + itemWriter.buff[11], itemWriter.buff[10], + itemWriter.buff[13], itemWriter.buff[12], + itemWriter.buff[15], itemWriter.buff[14], + itemWriter.buff[17], itemWriter.buff[16], + itemWriter.buff[19], itemWriter.buff[18], + itemWriter.buff[21], itemWriter.buff[20] ); - if (rc < 0) + if (rc < 0) pm_error("Error writing X10 bitmap raster item. " "printf() failed with errno %d (%s)", errno, strerror(errno)); - - itemCnt = 0; + + itemWriter.cnt = 0; } - itemBuff[itemCnt++] = bitreverse[item]; + itemWriter.buff[itemWriter.cnt++] = bitreverse[item]; } @@ -205,26 +212,30 @@ putitemX10(unsigned char const item) { static void putitemX11(unsigned char const item) { - if (itemCnt == 15 ) { + if (itemWriter.cnt == 15 ) { /* Buffer is full. Write out one line. */ int rc; rc = printf(" 0x%02x,0x%02x,0x%02x,0x%02x," "0x%02x,0x%02x,0x%02x,0x%02x," "0x%02x,0x%02x,0x%02x,0x%02x," "0x%02x,0x%02x,0x%02x,\n", - itemBuff[0], itemBuff[1], itemBuff[2], itemBuff[3], - itemBuff[4], itemBuff[5], itemBuff[6], itemBuff[7], - itemBuff[8], itemBuff[9], itemBuff[10],itemBuff[11], - itemBuff[12],itemBuff[13],itemBuff[14] + itemWriter.buff[ 0], itemWriter.buff[ 1], + itemWriter.buff[ 2], itemWriter.buff[ 3], + itemWriter.buff[ 4], itemWriter.buff[ 5], + itemWriter.buff[ 6], itemWriter.buff[ 7], + itemWriter.buff[ 8], itemWriter.buff[ 9], + itemWriter.buff[10], itemWriter.buff[11], + itemWriter.buff[12], itemWriter.buff[13], + itemWriter.buff[14] ); - if (rc < 0) + if (rc < 0) pm_error("Error writing X11 bitmap raster item. " "printf() failed with errno %d (%s)", errno, strerror(errno)); - - itemCnt = 0; + + itemWriter.cnt = 0; } - itemBuff[itemCnt++] = bitreverse[item]; + itemWriter.buff[itemWriter.cnt++] = bitreverse[item]; } @@ -232,7 +243,7 @@ putitemX11(unsigned char const item) { static void putitem(unsigned char const item) { - switch (itemVersion) { + switch (itemWriter.version) { case X10: putitemX10(item); break; case X11: putitemX11(item); break; } @@ -245,19 +256,19 @@ puttermX10(void) { unsigned int i; - assert(itemCnt % 2 == 0); + assert(itemWriter.cnt % 2 == 0); - for (i = 0; i < itemCnt; i += 2) { + for (i = 0; i < itemWriter.cnt; i += 2) { int rc; - assert(i + 1 < itemCnt); + assert(i + 1 < itemWriter.cnt); rc = printf("%s0x%02x%02x%s", (i == 0) ? " " : "", - itemBuff[i+1], - itemBuff[i], - (i + 2 >= itemCnt) ? "" : ","); - if (rc < 0) + itemWriter.buff[i+1], + itemWriter.buff[i], + (i + 2 >= itemWriter.cnt) ? "" : ","); + if (rc < 0) pm_error("Error writing Item %u at end of X10 bitmap raster. " "printf() failed with errno %d (%s)", i, errno, strerror(errno)); @@ -271,15 +282,15 @@ puttermX11(void) { unsigned int i; - for (i = 0; i < itemCnt; ++i) { + for (i = 0; i < itemWriter.cnt; ++i) { int rc; rc = printf("%s0x%02x%s", (i == 0) ? " " : "", - itemBuff[i], - (i + 1 >= itemCnt) ? "" : ","); + itemWriter.buff[i], + (i + 1 >= itemWriter.cnt) ? "" : ","); - if (rc < 0) + if (rc < 0) pm_error("Error writing Item %u at end of X11 bitmap raster. " "printf() failed with errno %d (%s)", i, errno, strerror(errno)); @@ -289,10 +300,10 @@ puttermX11(void) { static void -putinit(enum xbmVersion const xbmVersion) { +putinit(enum XbmVersion const xbmVersion) { - itemCnt = 0; - itemVersion = xbmVersion; + itemWriter.cnt = 0; + itemWriter.version = xbmVersion; } @@ -300,7 +311,7 @@ putinit(enum xbmVersion const xbmVersion) { static void putterm(void) { - switch (itemVersion) { + switch (itemWriter.version) { case X10: puttermX10(); break; case X11: puttermX11(); break; } @@ -310,7 +321,7 @@ putterm(void) { rc = printf("};\n"); - if (rc < 0) + if (rc < 0) pm_error("Error writing end of X11 bitmap raster. " "printf() failed with errno %d (%s)", errno, strerror(errno)); @@ -320,7 +331,7 @@ putterm(void) { static void -writeXbmHeader(enum xbmVersion const xbmVersion, +writeXbmHeader(enum XbmVersion const xbmVersion, const char * const name, unsigned int const width, unsigned int const height, @@ -341,11 +352,11 @@ convertRaster(FILE * const ifP, unsigned int const rows, int const format, FILE * const ofP, - enum xbmVersion const xbmVersion) { - - unsigned int const bitsPerUnit = xbmVersion == X10 ? 16 : 8; + enum XbmVersion const xbmVersion) { + + unsigned int const bitsPerUnit = xbmVersion == X10 ? 16 : 8; unsigned int const padright = ROUNDUP(cols, bitsPerUnit) - cols; - /* Amount of padding to round cols up to the nearest multiple of + /* Amount of padding to round cols up to the nearest multiple of 8 (if x11) or 16 (if x10). */ unsigned int const bitrowBytes = (cols + padright) / 8; @@ -353,10 +364,14 @@ convertRaster(FILE * const ifP, unsigned char * bitrow; unsigned int row; + if (cols > UINT_MAX - bitsPerUnit) + pm_error("Image is too wide (%u columns) for computations", + cols); + putinit(xbmVersion); bitrow = pbm_allocrow_packed(cols + padright); - + for (row = 0; row < rows; ++row) { unsigned int i; @@ -382,7 +397,7 @@ int main(int argc, const char ** argv) { - struct CmdlineInfo cmdline; + struct CmdlineInfo cmdline; FILE * ifP; int rows, cols, format; const char * name; @@ -390,15 +405,15 @@ main(int argc, pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); - if (cmdline.name == NULL) + if (cmdline.name == NULL) generateName(cmdline.inputFileName, &name); else name = strdup(cmdline.name); ifP = pm_openr(cmdline.inputFileName); - + pbm_readpbminit(ifP, &cols, &rows, &format); - + writeXbmHeader(cmdline.xbmVersion, name, cols, rows, stdout); convertRaster(ifP, cols, rows, format, stdout, cmdline.xbmVersion); |