about summary refs log tree commit diff
path: root/converter/pgm/pgmtolispm.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2010-03-27 19:22:22 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2010-03-27 19:22:22 +0000
commit4c233fcfb54b386fcd96f71deb1e88e10d635825 (patch)
tree8cd7f623d29368a59905ccc108e5151bc28d2e62 /converter/pgm/pgmtolispm.c
parent3a54a339a59e83834ea18d88cab7104fd9d8b9ca (diff)
downloadnetpbm-mirror-4c233fcfb54b386fcd96f71deb1e88e10d635825.tar.gz
netpbm-mirror-4c233fcfb54b386fcd96f71deb1e88e10d635825.tar.xz
netpbm-mirror-4c233fcfb54b386fcd96f71deb1e88e10d635825.zip
Release 10.50.00 - copied from trunk
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@1162 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/pgm/pgmtolispm.c')
-rw-r--r--converter/pgm/pgmtolispm.c224
1 files changed, 131 insertions, 93 deletions
diff --git a/converter/pgm/pgmtolispm.c b/converter/pgm/pgmtolispm.c
index abb85494..7d931fb3 100644
--- a/converter/pgm/pgmtolispm.c
+++ b/converter/pgm/pgmtolispm.c
@@ -14,129 +14,167 @@
 **   usually a color image; but a color map is not written in the file, so we
 **   treat this as a graymap instead.  To convert a color image to Lispm 
 **   format, you must convert it to a pgm, and hand-edit a color map...  Ick.
+**
+** Feb 2010 afu
+** Added dimension check to prevent short int from overflowing
+** Changed code style (ANSI-style function definitions, etc.)
 */
 
-#include <stdio.h>
+#include "pm.h"
 #include "pgm.h"
 
 #define LISPM_MAGIC  "This is a BitMap file"
+#define INT16MAX 32767
 
-static void putinit ARGS(( int cols, int rows, int depth ));
-static int depth_to_word_size ARGS(( int depth ));
-static void putval ARGS(( gray b ));
-static void putrest ARGS(( void ));
-static void putitem ARGS(( void ));
 
-int
-main( argc, argv )
-    int argc;
-    char* argv[];
-    {
-    FILE* ifp;
-    gray *grayrow;
-    register gray* gP;
-    int rows, cols, depth, format, padright, row, col;
-    gray maxval;
+static unsigned int item;
+static unsigned int bitsperitem, maxbitsperitem, bitshift;
 
+static unsigned int
+depth_to_word_size(unsigned int const depth) {
 
-    pgm_init( &argc, argv );
+    /* 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 ( argc > 2 )
-	pm_usage( "[pgmfile]" );
-    if ( argc == 2 )
-	ifp = pm_openr( argv[1] );
-    else
-	ifp = stdin;
+    unsigned int const wordSize = 
+        depth ==  1 ?  1 :
+        depth ==  2 ?  2 :
+        depth <=  4 ?  4 :
+        depth <=  8 ?  8 :
+        depth <= 16 ? 16 :
+        depth <= 32 ? 32 :
+        0;
 
-    pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
-    grayrow = pgm_allocrow( cols );
-    depth = pm_maxvaltobits( maxval );
+    if (wordSize == 0)
+        pm_error("depth was %u, which is not in the range 1-32", depth);
 
-    /* Compute padding to round cols up to the nearest multiple of 32. */
-    padright = ( ( cols + 31 ) / 32 ) * 32 - cols;
+    return wordSize;
+}
 
-    putinit( cols, rows, depth );
-    for ( row = 0; row < rows; ++row )
-	{
-	pgm_readpgmrow( ifp, grayrow, cols, maxval, format );
-        for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
-	    putval( *gP );
-	for ( col = 0; col < padright; ++col )
-	    putval( 0 );
-        }
 
-    pm_close( ifp );
 
-    putrest( );
+static void
+putinit(unsigned int const cols,
+        unsigned int const rows,
+        unsigned int const depth) {
 
-    exit( 0 );
-    }
+    unsigned int const cols32 = ((cols + 31 ) / 32) * 32;
 
-static unsigned int item;
-static unsigned int bitsperitem, maxbitsperitem, bitshift;
+    unsigned int i;
 
-static void
-putinit( cols, rows, depth )
-    int cols, rows, depth;
-    {
-    int i;
-    int cols32 = ( ( cols + 31 ) / 32 ) * 32;	/* Lispms are able to write bit files that are not mod32 wide, but we   */
-						/* don't.  This should be ok, since bit arrays which are not mod32 wide */
-    printf(LISPM_MAGIC);			/* are pretty useless on a lispm (can't hand them to bitblt).		*/
-    pm_writelittleshort( stdout, cols );
-    pm_writelittleshort( stdout, rows );
-    pm_writelittleshort( stdout, cols32 );
+    /* Lispms are able to write bit files that are not mod32 wide, but we   */
+    /* don't.  This should be ok, since bit arrays which are not mod32 wide */
+    /* are pretty useless on a lispm (can't hand them to bitblt).           */
+
+    if (rows > INT16MAX || cols > INT16MAX || cols32 > INT16MAX)
+        pm_error("Input image is too large.");
+
+    printf(LISPM_MAGIC);
+
+    pm_writelittleshort(stdout, cols);
+    pm_writelittleshort(stdout, rows);
+    pm_writelittleshort(stdout, cols32);
     putchar(depth & 0xFF);
 
-    for ( i = 0; i < 9; ++i )
-	putchar( 0 );	/* pad bytes */
+    for (i = 0; i < 9; ++i)
+        putchar(0);   /* pad bytes */
 
-    item = 0;
-    bitsperitem = 0;
-    maxbitsperitem = depth_to_word_size( depth );
-    bitshift = 0;
-    }
+    item           = 0;
+    bitsperitem    = 0;
+    maxbitsperitem = depth_to_word_size(depth);
+    bitshift       = 0;
+}
 
-static int
-depth_to_word_size (depth)	/* Lispm architecture specific - if a bitmap is written    */
-  int depth;			/* 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 );
-      return(-1);  /* Should never reach here */
-  }
+
+
+static void
+putitem(void) {
+
+    pm_writelittlelong(stdout, ~item);
+
+    item        = 0;
+    bitsperitem = 0;
+    bitshift    = 0;
 }
 
 
 
 static void
-putval( gray b )
-    {
-    if ( bitsperitem == 32 )
-	putitem( );
-    item = item | ( b << bitshift );
+putval(gray const b) {
+
+    if (bitsperitem == 32)
+        putitem();
+
+    item        = item | (b << bitshift);
     bitsperitem = bitsperitem + maxbitsperitem;
-    bitshift = bitshift + maxbitsperitem;
-    }
+    bitshift    = bitshift + maxbitsperitem;
+}
+
+
 
 static void
-putrest( )
-    {
-    if ( bitsperitem > 0 )
-	putitem( );
+putrest(void) {
+
+    if (bitsperitem > 0)
+        putitem();
+}
+
+
+
+int
+main(int argc, const char * argv[]) {
+
+    FILE * ifP;
+    gray * grayrow;
+    int rows;
+    int cols;
+    unsigned int depth;
+    int format;
+    unsigned int padright;
+    unsigned int row;
+    gray maxval;
+    const char * inputFile;
+
+    pm_proginit(&argc, argv);
+
+    if (argc-1 < 1)
+        inputFile = "-";
+    else {
+        inputFile = argv[1];
+
+        if (argc-1 > 2)
+            pm_error("Too many arguments.  The only argument is the optional "
+                     "input file name");
     }
 
-static void
-putitem( )
-    {
-    pm_writelittlelong( stdout, ~item );
-    item = 0;
-    bitsperitem = 0;
-    bitshift = 0;
+    ifP = pm_openr(inputFile);
+
+    pgm_readpgminit(ifP, &cols, &rows, &maxval, &format);
+
+    grayrow = pgm_allocrow(cols);
+    depth = pm_maxvaltobits(maxval);
+
+    /* Compute padding to round cols up to the nearest multiple of 32. */
+    padright = ((cols + 31) / 32) * 32 - cols;
+
+    putinit(cols, rows, depth);
+
+    for (row = 0; row < rows; ++row) {
+        unsigned int col;
+
+        pgm_readpgmrow(ifP, grayrow, cols, maxval, format);
+
+        for (col = 0; col < cols; ++col)
+            putval(grayrow[col]);
+
+        for (col = 0; col < padright; ++col)
+            putval(0);
     }
+
+    pm_close(ifP);
+
+    putrest();
+
+    return 0;
+}