about summary refs log tree commit diff
path: root/converter/pbm/pbmtoxbm.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/pbm/pbmtoxbm.c')
-rw-r--r--converter/pbm/pbmtoxbm.c153
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);