about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2015-05-19 02:31:58 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2015-05-19 02:31:58 +0000
commit3403204f2e3feb6ac39148d2a5fe4257037af752 (patch)
tree25ab81deb7a3b47bfeb7bfc0f901e4867208d450
parentefbb99fa388a388696c6f49fa7a491d93199045b (diff)
downloadnetpbm-mirror-3403204f2e3feb6ac39148d2a5fe4257037af752.tar.gz
netpbm-mirror-3403204f2e3feb6ac39148d2a5fe4257037af752.tar.xz
netpbm-mirror-3403204f2e3feb6ac39148d2a5fe4257037af752.zip
cleanup
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@2497 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--converter/pbm/atktopbm.c425
1 files changed, 207 insertions, 218 deletions
diff --git a/converter/pbm/atktopbm.c b/converter/pbm/atktopbm.c
index 62664999..807e4f4a 100644
--- a/converter/pbm/atktopbm.c
+++ b/converter/pbm/atktopbm.c
@@ -61,17 +61,24 @@
 */
 
 /* macros to generate case entries for switch statement */
-#define case1(v) case v
-#define case4(v) case v: case (v)+1: case (v)+2: case(v)+3
-#define case6(v) case4(v): case ((v)+4): case ((v)+5)
-#define case8(v) case4(v): case4((v)+4)
+#define CASE1(v) case v
+#define CASE4(v) case v: case (v)+1: case (v)+2: case(v)+3
+#define CASE6(v) CASE4(v): case ((v)+4): case ((v)+5)
+#define CASE8(v) CASE4(v): CASE4((v)+4)
+
+
 
 static long
-ReadRow(FILE * const file, unsigned char * const row, long const length) {
+ReadRow(FILE *          const file,
+        unsigned char * const row,
+        long            const length) {
 /*----------------------------------------------------------------------------
   'file' is where to get them from.
   'row' is where to put bytes.
   'length' is how many bytes in row must be filled.
+  
+  Return the delimiter that marks the end of the row, or EOF if EOF marks
+  the end of the row, or NUL in some cases.
 -----------------------------------------------------------------------------*/
     /* Each input character is processed by the central loop.  There are 
     ** some input codes which require two or three characters for
@@ -80,18 +87,23 @@ ReadRow(FILE * const file, unsigned char * const row, long const length) {
     ** to the Ready state whenever a character unacceptable to the
     ** current state is read.
     */
-    enum stateCode {
-        Ready,      /* any input code is allowed */
-        HexDigitPending,    /* have seen the first of a hex digit pair */
-        RepeatPending,  /* repeat code has been seen:
-                   must be followed by two hex digits */
-        RepeatAndDigit};    /* have seen repeat code and its first
-                   following digit */
-    enum stateCode InputState;  /* current state */
-    register int c;     /* the current input character */
-    register long repeatcount = 0;  /* current repeat value */
-    register long hexval;   /* current hex value */
-    long pendinghex = 0;    /* the first of a pair of hex characters */
+    enum StateCode {
+        Ready,
+            /* any input code is allowed */
+        HexDigitPending,
+            /* have seen the first of a hex digit pair */
+        RepeatPending,
+            /* repeat code has been seen: must be followed by two hex digits
+             */
+        RepeatAndDigit
+            /* have seen repeat code and its first following digit */
+    };
+    
+    enum StateCode InputState;  /* current state */
+    int c;     /* the current input character */
+    long repeatcount;  /* current repeat value */
+    long hexval;   /* current hex value */
+    long pendinghex;    /* the first of a pair of hex characters */
     int lengthRemaining;
     unsigned char * cursor;
     
@@ -101,262 +113,239 @@ ReadRow(FILE * const file, unsigned char * const row, long const length) {
     ** zero, we ungetc the byte.
     */
 
-    lengthRemaining = length;
-    cursor = row;
+    repeatcount = 0;  /* initial value */
+    pendinghex = 0;  /* initial value */
+
+    lengthRemaining = length;  /* initial value */
+    cursor = row;  /* initial value */
+    InputState = Ready;  /* initial value */
 
-    InputState = Ready;
     while ((c=getc(file)) != EOF) switch (c) {
 
-    case8(0x0):
-    case8(0x8):
-    case8(0x10):
-    case8(0x18):
-    case1(' '):
-        /* control characters and space are legal and ignored */
-        break;
-    case1(0x40):    /* '@' */
-    case1(0x5B):    /* '[' */
-    case4(0x5D):    /*  ']'  '^'  '_'  '`' */
-    case4(0x7D):    /* '}'  '~'  DEL  0x80 */
-    default:        /* all above 0x80 */
-        /* error code:  Ignored at present.  Reset InputState. */
-        InputState = Ready;
-        break;
-
-    case1(0x7B):    /* '{' */
-    case1(0x5C):    /* '\\' */
-        /* illegal end of line:  exit anyway */
-        ungetc(c, file);    /* retain terminator in stream */
-        /* DROP THROUGH */
-    case1(0x7C):    /* '|' */
-        /* legal end of row: may have to pad  */
-        while (lengthRemaining-- > 0)
-            *cursor++ = WHITEBYTE;
-        return c;
+        CASE8(0x0):
+        CASE8(0x8):
+        CASE8(0x10):
+        CASE8(0x18):
+        CASE1(' '):
+            /* control characters and space are legal and ignored */
+            break;
+        CASE1(0x40):    /* '@' */
+        CASE1(0x5B):    /* '[' */
+        CASE4(0x5D):    /*  ']'  '^'  '_'  '`' */
+        CASE4(0x7D):    /* '}'  '~'  DEL  0x80 */
+        default:        /* all above 0x80 */
+            /* error code:  Ignored at present.  Reset InputState. */
+            InputState = Ready;
+            break;
+
+        CASE1(0x7B):    /* '{' */
+        CASE1(0x5C):    /* '\\' */
+            /* illegal end of line:  exit anyway */
+            ungetc(c, file);    /* retain terminator in stream */
+            /* DROP THROUGH */
+        CASE1(0x7C):    /* '|' */
+            /* legal end of row: may have to pad  */
+            while (lengthRemaining-- > 0)
+                *cursor++ = WHITEBYTE;
+            return c;
     
-    case1(0x21):
-    case6(0x22):
-    case8(0x28):
-        /* punctuation characters: repeat byte given by two
-        ** succeeding hex chars
-        */
-        if (lengthRemaining <= 0) {
-            ungetc(c, file);
-            return('\0');
-        }
-        repeatcount = c - OTHERZERO;
-        InputState = RepeatPending;
-        break;
-
-    case8(0x30):
-    case8(0x38):
-        /* digit (or following punctuation)  -  hex digit */
-        hexval = c - 0x30;
-        goto hexdigit;
-    case6(0x41):
-        /* A ... F    -  hex digit */
-        hexval = c - (0x41 - 0xA);
-        goto hexdigit;
-    case6(0x61):
-        /* a ... f  - hex digit */
-        hexval = c - (0x61 - 0xA);
-        goto hexdigit;
-
-    case8(0x67):
-    case8(0x6F):
-    case4(0x77):
-        /* g ... z   -   multiple WHITE bytes */
-        if (lengthRemaining <= 0) {
-            ungetc(c, file);
-            return('\0');
-        }
-        repeatcount = c - WHITEZERO;
-        hexval = WHITEBYTE;
-        goto store;
-    case8(0x47):
-    case8(0x4F):
-    case4(0x57):
-        /* G ... Z   -   multiple BLACK bytes */
-        if (lengthRemaining <= 0) {
-            ungetc(c, file);
-            return('\0');
-        }
-        repeatcount = c - BLACKZERO;
-        hexval = BLACKBYTE;
-        goto store;
-
-hexdigit:
-        /* process a hex digit.  Use InputState to determine
-            what to do with it. */
-        if (lengthRemaining <= 0) {
-            ungetc(c, file);
-            return('\0');
-        }
-        switch(InputState) {
-        case Ready:
-            InputState = HexDigitPending;
-            pendinghex = hexval << 4;
+        CASE1(0x21):
+        CASE6(0x22):
+        CASE8(0x28):
+            /* punctuation characters: repeat byte given by two
+            ** succeeding hex chars
+            */
+            if (lengthRemaining <= 0) {
+                ungetc(c, file);
+                return('\0');
+            }
+            repeatcount = c - OTHERZERO;
+            InputState = RepeatPending;
             break;
-        case HexDigitPending:
-            hexval |= pendinghex;
-            repeatcount = 1;
+
+        CASE8(0x30):
+        CASE8(0x38):
+            /* digit (or following punctuation)  -  hex digit */
+            hexval = c - 0x30;
+            goto hexdigit;
+        CASE6(0x41):
+            /* A ... F    -  hex digit */
+            hexval = c - (0x41 - 0xA);
+            goto hexdigit;
+        CASE6(0x61):
+            /* a ... f  - hex digit */
+            hexval = c - (0x61 - 0xA);
+            goto hexdigit;
+
+        CASE8(0x67):
+        CASE8(0x6F):
+        CASE4(0x77):
+            /* g ... z   -   multiple WHITE bytes */
+            if (lengthRemaining <= 0) {
+                ungetc(c, file);
+                return('\0');
+            }
+            repeatcount = c - WHITEZERO;
+            hexval = WHITEBYTE;
             goto store;
-        case RepeatPending:
-            InputState = RepeatAndDigit;
-            pendinghex = hexval << 4;
-            break;
-        case RepeatAndDigit:
-            hexval |= pendinghex;
+        CASE8(0x47):
+        CASE8(0x4F):
+        CASE4(0x57):
+            /* G ... Z   -   multiple BLACK bytes */
+            if (lengthRemaining <= 0) {
+                ungetc(c, file);
+                return('\0');
+            }
+            repeatcount = c - BLACKZERO;
+            hexval = BLACKBYTE;
             goto store;
-        }
-        break;
-
-store:
-        /* generate byte(s) into the output row 
-            Use repeatcount, depending on state.  */
-        if (lengthRemaining < repeatcount) 
-            /* reduce repeat count if it would exceed
-                available space */
-            repeatcount = lengthRemaining;
-        lengthRemaining -= repeatcount;  /* do this before repeatcount-- */
-        while (repeatcount-- > 0)
+
+        hexdigit:
+            /* process a hex digit.  Use InputState to determine
+               what to do with it. */
+            if (lengthRemaining <= 0) {
+                ungetc(c, file);
+                return('\0');
+            }
+            switch(InputState) {
+            case Ready:
+                InputState = HexDigitPending;
+                pendinghex = hexval << 4;
+                break;
+            case HexDigitPending:
+                hexval |= pendinghex;
+                repeatcount = 1;
+                goto store;
+            case RepeatPending:
+                InputState = RepeatAndDigit;
+                pendinghex = hexval << 4;
+                break;
+            case RepeatAndDigit:
+                hexval |= pendinghex;
+                goto store;
+            }
+            break;
+
+        store:
+            /* generate byte(s) into the output row 
+               Use repeatcount, depending on state.  */
+            if (lengthRemaining < repeatcount) 
+                /* reduce repeat count if it would exceed
+                   available space */
+                repeatcount = lengthRemaining;
+            lengthRemaining -= repeatcount;  /* do this before repeatcount-- */
+            while (repeatcount-- > 0)
                 *cursor++ = hexval;
-        InputState = Ready;
-        break;
+            InputState = Ready;
+            break;
 
-    } /* end of while( - )switch( - ) */
+        } /* end of while( - )switch( - ) */
     return EOF;
 }
 
 
 
-#undef case1
-#undef case4
-#undef case6
-#undef case8
+#undef CASE1
+#undef CASE4
+#undef CASE6
+#undef CASE8
 
 
 
 static void
-ReadATKRaster(FILE * const file, 
-              int * const rwidth, 
-              int * const rheight, 
-              unsigned char ** const destaddrP) {
+ReadATKRaster(FILE * const ifP) {
 
-    int row, rowlen;  /* count rows;  byte length of row */
+    int row;  /* count rows;  byte length of row */
     int version;
     char keyword[6];
     int discardid;
     int objectid;     /* id read for the incoming pixel image */
     long tc;            /* temp */
     int width, height;      /* dimensions of image */
+    bit * bitrow;
 
-    if (fscanf(file, "\\begindata{raster,%d", &discardid) != 1
-                || getc(file) != '}' || getc(file) != '\n')
-      pm_error ("input file not Andrew raster object");
+    if (fscanf(ifP, "\\begindata{raster,%d", &discardid) != 1
+        || getc(ifP) != '}' || getc(ifP) != '\n')
+        pm_error ("input file not Andrew raster object");
 
-    fscanf(file, " %d ", &version);
+    fscanf(ifP, " %d ", &version);
     if (version < 2) 
-      pm_error ("version too old to parse");
+        pm_error ("version too old to parse");
 
     {
         unsigned int options;
         long xscale, yscale;
         long xoffset, yoffset, subwidth, subheight;
         /* ignore all these features: */
-        fscanf(file, " %u %ld %ld %ld %ld %ld %ld",  
+        fscanf(ifP, " %u %ld %ld %ld %ld %ld %ld",  
                &options, &xscale, &yscale, &xoffset, 
                &yoffset, &subwidth, &subheight);
     }
     /* scan to end of line in case this is actually something beyond V2 */
-    while (((tc=getc(file)) != '\n') && (tc != '\\') && (tc != EOF)) {}
+    while (((tc=getc(ifP)) != '\n') && (tc != '\\') && (tc != EOF)) {}
 
     /* read the keyword */
-    fscanf(file, " %5s", keyword);
+    fscanf(ifP, " %5s", keyword);
     if (!streq(keyword, "bits"))
-      pm_error ("keyword is not 'bits'!");
+        pm_error ("keyword is not 'bits'!");
 
-    fscanf(file, " %d %d %d ", &objectid, &width, &height);
+    fscanf(ifP, " %d %d %d ", &objectid, &width, &height);
 
     if (width < 1 || height < 1 || width > 1000000 || height > 1000000) 
-      pm_error ("bad width or height");
-
-    *rwidth = width;
-    *rheight = height;
-    rowlen = (width + 7) / 8;
-    MALLOCARRAY(*destaddrP, height * rowlen);
-    if (destaddrP == NULL)
-        pm_error("Unable to allocate %u bytes for the input image.",
-                 height * rowlen);
-    for (row = 0;   row < height;   row++)
-      {
-        long c;
-
-        c = ReadRow(file, *destaddrP + (row * rowlen), rowlen);
-        if (c != '|')
-          {
-        if (c == EOF)
-          pm_error ("premature EOF");
-        else
-          pm_error ("bad format");
-        break;
-          }
-      }
-    while (! feof(file) && getc(file) != '\\') {};  /* scan for \enddata */
-    if (fscanf(file, "enddata{raster,%d", &discardid) != 1
-        || getc(file) != '}' || getc(file) != '\n')
-      pm_error ("missing end-of-object marker");
-}
+        pm_error("bad width or height");
 
+    pbm_writepbminit(stdout, width, height, 0);
+    bitrow = pbm_allocrow_packed(width);
 
+    for (row = 0;   row < height; ++row) {
+        unsigned int const rowlen = (width + 7) / 8;
+        long const nextChar = ReadRow(ifP, bitrow, rowlen);
 
-int
-main(int argc, char **argv) {
+        switch (nextChar) {
+        case '|': 
+            pbm_writepbmrow_packed(stdout, bitrow, width, 0);
+            break;
+        case EOF:
+            pm_error("premature EOF");
+            break;
+        default:
+            pm_error("bad format");
+        }
+    }
 
-    FILE *ifp;
-    register bit *bitrow, *bP;
-    int rows, cols, row, col, charcount;
-    unsigned char *data, mask;
+    pbm_freerow_packed(bitrow);
 
+    while (! feof(ifP) && getc(ifP) != '\\') {};  /* scan for \enddata */
 
-    pbm_init ( &argc, argv );
+    if (fscanf(ifP, "enddata{raster,%d", &discardid) != 1
+        || getc(ifP) != '}' || getc(ifP) != '\n')
+        pm_error("missing end-of-object marker");
+}
 
-    if ( argc > 2 )
-        pm_usage( "[raster obj]" );
-    
-    if ( argc == 2 )
-        ifp = pm_openr( argv[1] );
-    else
-        ifp = stdin;
 
-    ReadATKRaster( ifp, &cols, &rows, &data );
 
-    pm_close( ifp );
+int
+main(int argc, const char ** argv) {
 
-    pbm_writepbminit( stdout, cols, rows, 0 );
-    bitrow = pbm_allocrow( cols );
+    FILE * ifP;
 
-    for ( row = 0; row < rows; ++row )
-    {
-        charcount = 0;
-        mask = 0x80;
-        for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
-        {
-            if ( charcount >= 8 )
-            {
-                ++data;
-                charcount = 0;
-                mask = 0x80;
-            }
-            *bP = ( *data & mask ) ? PBM_BLACK : PBM_WHITE;
-            ++charcount;
-            mask >>= 1;
-        }
-        ++data;
-        pbm_writepbmrow( stdout, bitrow, cols, 0 );
+    pm_proginit(&argc, argv);
+
+    if (argc-1 < 1)
+        ifP = stdin;
+    else {
+        ifP = pm_openr(argv[1]);
+
+        if (argc-1 > 1)
+            pm_error("Too many arguments.  The only possible argument is "
+                     "the input file name");
     }
 
-    pm_close( stdout );
-    exit( 0 );
-}
+    ReadATKRaster(ifP);
+
+    pm_close(ifP);
 
+    pm_close(stdout);
+
+    return 0;
+}