diff options
Diffstat (limited to 'converter/pgm/pgmtolispm.c')
-rw-r--r-- | converter/pgm/pgmtolispm.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/converter/pgm/pgmtolispm.c b/converter/pgm/pgmtolispm.c new file mode 100644 index 00000000..02f2fd1e --- /dev/null +++ b/converter/pgm/pgmtolispm.c @@ -0,0 +1,148 @@ +/* pgmtolispm.c - read a pgm and write a file acceptable to the +** tv:read-bit-array-file function of TI Explorer and Symbolics Lisp Machines. +** +** 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. To convert a color image to Lispm +** format, you must convert it to a pgm, and hand-edit a color map... Ick. +*/ + +#include <stdio.h> +#include "pgm.h" + +#define LISPM_MAGIC "This is a BitMap file" + +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; + + + pgm_init( &argc, argv ); + + if ( argc > 2 ) + pm_usage( "[pgmfile]" ); + if ( argc == 2 ) + ifp = pm_openr( argv[1] ); + else + ifp = stdin; + + 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 ) + { + 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( ); + + exit( 0 ); + } + +static unsigned int item; +static unsigned int bitsperitem, maxbitsperitem, bitshift; + +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 ); + putchar(depth & 0xFF); + + for ( i = 0; i < 9; ++i ) + putchar( 0 ); /* pad bytes */ + + 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 */ + } +} + + + +#if __STDC__ +static void +putval( gray b ) +#else /*__STDC__*/ +static void +putval( b ) +gray b; +#endif /*__STDC__*/ + { + if ( bitsperitem == 32 ) + putitem( ); + item = item | ( b << bitshift ); + bitsperitem = bitsperitem + maxbitsperitem; + bitshift = bitshift + maxbitsperitem; + } + +static void +putrest( ) + { + if ( bitsperitem > 0 ) + putitem( ); + } + +static void +putitem( ) + { + pm_writelittlelong( stdout, ~item ); + item = 0; + bitsperitem = 0; + bitshift = 0; + } |