diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
commit | 1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch) | |
tree | 64c8c96cf54d8718847339a403e5e67b922e8c3f /converter/pgm/lispmtopgm.c | |
download | netpbm-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.c | 172 |
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; + } |