about summary refs log tree commit diff
path: root/converter/pgm/lispmtopgm.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
commit1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch)
tree64c8c96cf54d8718847339a403e5e67b922e8c3f /converter/pgm/lispmtopgm.c
downloadnetpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.gz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.xz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.zip
Create Subversion repository
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/pgm/lispmtopgm.c')
-rw-r--r--converter/pgm/lispmtopgm.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/converter/pgm/lispmtopgm.c b/converter/pgm/lispmtopgm.c
new file mode 100644
index 00000000..7b98ef00
--- /dev/null
+++ b/converter/pgm/lispmtopgm.c
@@ -0,0 +1,172 @@
+/* lispmtopgm.c - read a file written by the tv:write-bit-array-file function
+** of TI Explorer and Symbolics Lisp Machines, and write a PGM.
+**
+** Written by Jamie Zawinski based on code (C) 1988 by Jef Poskanzer.
+**
+** Permission to use, copy, modify, and distribute this software and its
+** documentation for any purpose and without fee is hereby granted, provided
+** that the above copyright notice appear in all copies and that both that
+** copyright notice and this permission notice appear in supporting
+** documentation.  This software is provided "as is" without express or
+** implied warranty.
+**
+**   When one writes a multi-plane bitmap with tv:write-bit-array-file, it is
+**   usually a color image; but a color map is not written in the file, so we
+**   treat this as a graymap instead.  Since the pgm reader can also read pbms,
+**   this doesn't matter if you're using only single plane images.
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "nstring.h"
+#include "pgm.h"
+
+#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]" );
+
+    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 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;
+    char magic[sizeof(LISPM_MAGIC)];
+    int i;
+
+    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 */
+
+    for ( i = 0; i < 9; ++i )
+	getc( file );	/* discard bytes reserved for future use */
+    }
+
+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);
+  }
+}
+
+
+
+static unsigned int
+getval( file )
+    FILE* file;
+    {
+    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 );
+    bitsperitem = bitsperitem - maxbitsperitem;
+    bitshift = bitshift + maxbitsperitem;
+    return b;
+    }