about summary refs log tree commit diff
path: root/converter/pgm/lispmtopgm.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/pgm/lispmtopgm.c')
-rw-r--r--converter/pgm/lispmtopgm.c258
1 files changed, 136 insertions, 122 deletions
diff --git a/converter/pgm/lispmtopgm.c b/converter/pgm/lispmtopgm.c
index 40dd3fb4..29f280f3 100644
--- a/converter/pgm/lispmtopgm.c
+++ b/converter/pgm/lispmtopgm.c
@@ -16,6 +16,8 @@
 **   this doesn't matter if you're using only single plane images.
 */
 
+#include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -24,149 +26,161 @@
 
 #define LISPM_MAGIC  "This is a BitMap file"
 
-static void getinit ARGS(( FILE* file, short* colsP, short* rowsP, short* depthP, short* padrightP ));
-static int depth_to_word_size ARGS(( int depth ));
-static unsigned int getval ARGS(( FILE* file ));
-
-int
-main( argc, argv )
-    int argc;
-    char* argv[];
-    {
-    FILE* ifp;
-    gray* grayrow;
-    register gray* gP;
-    short rows, cols, padright, row, col;
-    short depth;
-    int maxval;
 
 
-    pgm_init( &argc, argv );
-
-    if ( argc > 2 )
-	pm_usage( "[lispmfile]" );
+static long item, bitmask;
+static unsigned int bitsperitem, maxbitsperitem, bitshift;
 
-    if ( argc == 2 )
-        ifp = pm_openr( argv[1] );
-    else
-	ifp = stdin;
-
-    getinit( ifp, &cols, &rows, &depth, &padright );
-    maxval = 1 << depth;
-
-    if ( maxval > PGM_OVERALLMAXVAL )
-        pm_error( "depth (%d bits) is too large", depth);
-
-    pgm_writepgminit( stdout, cols, rows, (gray) maxval, 0 );
-    grayrow = pgm_allocrow( ( cols + 7 ) / 8 * 8 );
-
-    for ( row = 0; row < rows; ++row )
-	{
-        for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
-	    *gP = getval( ifp );
-	pgm_writepgmrow( stdout, grayrow, cols, (gray) maxval, 0 );
-	}
-    pm_close( ifp );
-    pm_close( stdout );
-    exit( 0 );
+static unsigned int
+wordSizeFmDepth(unsigned int const depth) {
+/*----------------------------------------------------------------------------
+  Lispm architecture specific - if a bitmap is written out with a depth of 5,
+  it really has a depth of 8, and is stored that way in the file.
+-----------------------------------------------------------------------------*/
+    if (depth==0 || depth==1) return  1;
+    else if (depth ==  2)     return  2;
+    else if (depth <=  4)     return  4;
+    else if (depth <=  8)     return  8;
+    else if (depth <= 16)     return 16;
+    else if (depth <= 32)     return 32;
+    else {
+        pm_error("depth was %u, which is not in the range 1-32.", depth);
+        assert(false);
     }
+}
+
 
-static long item, bitmask;
-static unsigned int bitsperitem, maxbitsperitem, bitshift;
 
 static void
-getinit( file, colsP, rowsP, depthP, padrightP )
-    FILE* file;
-    short* colsP;
-    short* rowsP;
-    short* padrightP;
-    short* depthP;
-    {
-    short cols_32;
+getinit(FILE *         const ifP,
+        unsigned int * const colsP,
+        unsigned int * const rowsP,
+        unsigned int * const depthP,
+        unsigned int * const padrightP) {
+
+    short cols, rows, cols32;
     char magic[sizeof(LISPM_MAGIC)];
-    int i;
+    unsigned int i;
+
+    for (i = 0; i < sizeof(magic)-1; ++i)
+        magic[i] = getc(ifP);
 
-    for ( i = 0; i < sizeof(magic)-1; ++i )
-        magic[i] = getc( file );
     magic[i]='\0';
+
     if (!streq(LISPM_MAGIC, magic))
-        pm_error( "bad id string in Lispm file" );
-    
-    if ( pm_readlittleshort( file, colsP ) == -1 )
-        pm_error( "EOF / read error" );
-    if ( pm_readlittleshort( file, rowsP ) == -1 )
-        pm_error( "EOF / read error" );
-    if ( pm_readlittleshort( file, &cols_32 ) == -1 )
-        pm_error( "EOF / read error" );
-    *depthP = getc( file );
-    
-    if ( *depthP == 0 )
-	*depthP = 1;	/* very old file */
-    
-    *padrightP = ( ( *colsP + 31 ) / 32 ) * 32 - *colsP;
-    
-    if ( *colsP != (cols_32 - *padrightP) ) {
-/*    pm_message( "inconsistent input: Width and Width(mod32) fields don't agree" );  */
-/*    *padrightP = cols_32 - *colsP;   */ /*    hmmmm....   */
-      /* This is a dilemma.  Usually the output is rounded up to mod32, but not always.
-       * For the Lispm code to not round up, the array size must be the same size as the
-       * portion being written - that is, the array itself must be an odd size, not just
-       * the selected portion.  Since arrays that are odd sizes can't be handed to bitblt,
-       * such arrays are probably not image data - so punt on it for now.
-       *
-       * Also, the lispm code for saving bitmaps has a bug, in that if you are writing a
-       * bitmap which is not mod32 across, the file may be up to 7 bits too short!  They
-       * round down instead of up.
-       *
-       * The code in 'pgmtolispm.c' always rounds up to mod32, which is totally reasonable.
-       */
-      }
-    bitsperitem = 0;
-    maxbitsperitem = depth_to_word_size( *depthP );
-    bitmask = ( 1 << maxbitsperitem ) - 1;		/* for depth=3, mask=00000111 */
+        pm_error("bad id string in Lispm file");
+
+    pm_readlittleshort(ifP, &cols);
+    pm_readlittleshort(ifP, &rows);
+    pm_readlittleshort(ifP, &cols32);
+
+    *colsP = cols;
+    *rowsP = rows;
+
+    *depthP = getc(ifP);
+
+    if (*depthP == 0)
+        *depthP = 1;    /* very old file */
 
-    for ( i = 0; i < 9; ++i )
-	getc( file );	/* discard bytes reserved for future use */
+    assert(*colsP < UINT_MAX - 31);
+
+    *padrightP = ROUNDUP(*colsP, 32) - *colsP;
+
+# if 0
+    if (*colsP != (cols32 - *padrightP)) {
+        pm_message("inconsistent input: "
+                   "Width and Width(mod32) fields don't agree" );
+        *padrightP = cols32 - *colsP;   /*    hmmmm....   */
+
+        /* This is a dilemma.  Usually the output is rounded up to mod32, but
+           not always.  For the Lispm code to not round up, the array size
+           must be the same size as the portion being written - that is, the
+           array itself must be an odd size, not just the selected portion.
+           Since arrays that are odd sizes can't be handed to bitblt, such
+           arrays are probably not image data - so punt on it for now.
+
+           Also, the lispm code for saving bitmaps has a bug, in that if you
+           are writing a bitmap which is not mod32 across, the file may be up
+           to 7 bits too short!  They round down instead of up.
+
+            The code in 'pgmtolispm.c' always rounds up to mod32, which is
+            totally reasonable.
+       */
     }
+#endif
+    bitsperitem = 0;
+    maxbitsperitem = wordSizeFmDepth(*depthP);
+    bitmask = (1 << maxbitsperitem) - 1;     /* for depth=3, mask=00000111 */
 
-static int
-depth_to_word_size (depth)	
-     int depth;			
-     /* Lispm architecture specific - if a bitmap is written    */
-     /* out with a depth of 5, it really has a depth of 8, and  */
-     /* is stored that way in the file.			   */
-{				
-    if (depth==0 || depth==1)	return ( 1);
-    else if (depth ==  2)	return ( 2);
-    else if (depth <=  4)	return ( 4);
-    else if (depth <=  8)	return ( 8);
-    else if (depth <= 16)	return (16);
-    else if (depth <= 32)	return (32);
-    else {
-      pm_error( "depth was %d, which is not in the range 1-32.", depth );
-      /* Should never reach here */
-      return(-1);
-  }
+    for (i = 0; i < 9; ++i)
+        getc(ifP);   /* discard bytes reserved for future use */
 }
 
 
 
 static unsigned int
-getval( file )
-    FILE* file;
-    {
+getval(FILE * const ifP) {
+
     unsigned int b;
 
-    if ( bitsperitem == 0 )
-	{
-	if ( pm_readlittlelong( file, &item ) == -1 )
-	    pm_error( "EOF / read error" );
-	bitsperitem = 32;
-	bitshift = 0;
-	item = ~item;
-	}
-    b = ( ( item >> bitshift ) & bitmask );
+    if (bitsperitem == 0) {
+        pm_readlittlelong(ifP, &item);
+        bitsperitem = 32;
+        bitshift = 0;
+        item = ~item;
+    }
+    b           = ((item >> bitshift ) & bitmask);
     bitsperitem = bitsperitem - maxbitsperitem;
-    bitshift = bitshift + maxbitsperitem;
+    bitshift    = bitshift + maxbitsperitem;
     return b;
+}
+
+
+
+int
+main(int argc, const char ** argv) {
+
+    FILE * ifP;
+    gray * grayrow;
+    unsigned int rows, cols, depth, padright;
+    unsigned int row;
+    gray maxval;
+
+
+    pm_proginit(&argc, argv);
+
+    if (argc-1 > 1)
+        pm_error("Too many arguments.  The only possible argument is the "
+                 "input file name");
+
+    if (argc-1 == 1)
+        ifP = pm_openr(argv[1]);
+    else
+        ifP = stdin;
+
+    getinit(ifP, &cols, &rows, &depth, &padright);
+
+    if (depth > 16)
+        pm_error("Invalid depth (%u bits).  Maximum is 15", depth);
+
+    maxval = (1 << depth);
+
+    pgm_writepgminit(stdout, cols, rows, maxval, 0);
+
+    grayrow = pgm_allocrow(ROUNDUP(cols, 8));
+
+    for (row = 0; row < rows; ++row) {
+        unsigned int col;
+
+        for (col = 0; col < cols; ++col)
+            grayrow[col] = getval(ifP);
+
+        pgm_writepgmrow(stdout, grayrow, cols, maxval, 0);
     }
+    pm_close(ifP);
+    pm_close(stdout);
+    exit(0);
+}
+
+
+