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/pbm/pbmtogem.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/pbm/pbmtogem.c')
-rw-r--r-- | converter/pbm/pbmtogem.c | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/converter/pbm/pbmtogem.c b/converter/pbm/pbmtogem.c new file mode 100644 index 00000000..59f2b9cf --- /dev/null +++ b/converter/pbm/pbmtogem.c @@ -0,0 +1,252 @@ +/* pbmtogem.c - read a portable bitmap and produce a GEM .img file +** +** Author: David Beckemeyer (bdt!david) +** +** Much of the code for this program was taken from other +** pbmto* programs. I just modified the code to produce +** a .img header and generate .img "Bit Strings". +** +** Thanks to Diomidis D. Spinellis for the .img header format. +** +** Copyright (C) 1988 by David Beckemeyer (bdt!david) and Jef Poskanzer. +** +** Modified by Johann Haider to produce Atari ST compatible files +** +** 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. +*/ +/* +* 92/07/11 jh +* +* Changes made to this program: +* changed header length to count words to conform with Atari ST documentation +* removed rounding of the imagewidth to the next word boundary +* removed arbitrary limit to imagewidth +* changed pattern length to 1 to simplify locating of compressable parts +* in real world images +* add solid run and pattern run compression +* +* Deficiencies: +* Compression of repeated scanlines not added +* +* Johann Haider (jh@fortec.tuwien.ac.at) +* +* 94/01/31 Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de) +* Changed to remove architecture dependencies +* Added compression of repeated scanlines +*/ + +#include <stdio.h> +#include <string.h> +#include "pbm.h" + +#define SOLID_0 0 +#define SOLID_1 0xff +#define MINRUN 4 +#define putsolid(v,c) putc((v&0x80)|c, stdout) +#define putpattern(v,c) putc(0, stdout);putc(c, stdout);putc(v, stdout) + +static void putinit ARGS ((int rows, int cols)); +static void putbit ARGS(( bit b )); +static void putitem ARGS(( void )); +static void putrow ARGS(( void )); +static void flushrow ARGS ((void)); +static void putstring ARGS((register unsigned char *p, register int n)); + +int +main( argc, argv ) + int argc; + char* argv[]; + { + FILE* ifp; + bit* bitrow; + register bit* bP; + int rows, cols, format, row, col; + + pbm_init( &argc, argv ); + + if ( argc > 2 ) + pm_usage( "[pbmfile]" ); + + if ( argc == 2 ) + ifp = pm_openr( argv[1] ); + else + ifp = stdin; + + pbm_readpbminit( ifp, &cols, &rows, &format ); + + bitrow = pbm_allocrow( cols ); + + putinit (rows, cols); + for ( row = 0; row < rows; ++row ) + { +#ifdef DEBUG + fprintf (stderr, "row %d\n", row); +#endif + pbm_readpbmrow( ifp, bitrow, cols, format ); + for ( col = 0, bP = bitrow; col < cols; ++col, ++bP ) + putbit( *bP ); + putrow( ); + } + flushrow (); + + pm_close( ifp ); + + + exit( 0 ); + } + +static short item; +static int outcol, outmax; +static short bitsperitem, bitshift; +static short linerepeat; +static unsigned char *outrow, *lastrow; + +static void +putinit (rows, cols) + int rows, cols; +{ + if (pm_writebigshort (stdout, (short) 1) == -1 /* Image file version */ + || pm_writebigshort (stdout, (short) 8) == -1 /* Header length */ + || pm_writebigshort (stdout, (short) 1) == -1 /* Number of planes */ + || pm_writebigshort (stdout, (short) 1) == -1 /* Pattern length */ + || pm_writebigshort (stdout, (short) 372) == -1 /* Pixel width */ + || pm_writebigshort (stdout, (short) 372) == -1 /* Pixel height */ + || pm_writebigshort (stdout, (short) cols) == -1 + || pm_writebigshort (stdout, (short) rows) == -1) + pm_error ("write error"); + item = 0; + bitsperitem = 0; + bitshift = 7; + outcol = 0; + outmax = (cols + 7) / 8; + outrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char)); + lastrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char)); + linerepeat = -1; +} + +#if __STDC__ +static void +putbit( bit b ) +#else /*__STDC__*/ +static void +putbit( b ) + bit b; +#endif /*__STDC__*/ + { + if ( bitsperitem == 8 ) + putitem( ); + ++bitsperitem; + if ( b == PBM_BLACK ) + item += 1 << bitshift; + --bitshift; + } + +static void +putitem( ) + { + outrow[outcol++] = item; + item = 0; + bitsperitem = 0; + bitshift = 7; + } + +static void +putstring (p, n) +register unsigned char *p; +register int n; +{ +#ifdef DEBUG + fprintf (stderr, "Bitstring, length: %d, pos %d\n", n, outcol); +#endif + (void) putc((char) 0x80, stdout); /* a Bit string */ + (void) putc(n, stdout); /* count */ + fwrite( p, n, 1, stdout ); +} + +static void +putrow( ) +{ + if (bitsperitem > 0) + putitem (); + outcol = 0; + if (linerepeat == -1 || linerepeat == 255 + || memcmp (outrow, lastrow, outmax) != 0) + { + unsigned char *temp; + if (linerepeat != -1) /* Unless first line */ + flushrow (); + /* Swap the pointers */ + temp = outrow; outrow = lastrow; lastrow = temp; + linerepeat = 1; + } + else + /* Repeated line */ + linerepeat++; +} + +static void +flushrow( ) + { + register unsigned char *outp, *p, *q; + register int count; + int col = outmax; + + if (linerepeat > 1) + { + /* Put out line repeat count */ + fwrite ("\0\0\377", 3, 1, stdout); + putchar (linerepeat); + } + for (outp = p = lastrow; col > 0;) + { + for (q = p, count=0; (count < col) && (*q == *p); q++,count++); + if (count > MINRUN) + { + if (p > outp) + { + putstring (outp, p-outp); + outp = p; + } + col -= count; + switch (*p) + { + case SOLID_0: +#ifdef DEBUG +/* if (outcol > 0) */ + fprintf (stderr, "Solid run 0, length: %d\n", count); +#endif + putsolid (SOLID_0, count); + break; + + case SOLID_1: +#ifdef DEBUG + fprintf (stderr, "Solid run 1, length: %d, pos %d\n", count, outcol); +#endif + putsolid (SOLID_1, count); + break; + default: +#ifdef DEBUG + fprintf (stderr, "Pattern run, length: %d\n", count); +#endif + putpattern (*p, count); + break; + } + outp = p = q; + } + else + { + p++; + col--; + } + } + if (p > outp) + putstring (outp, p-outp); + if (ferror (stdout)) + pm_error ("write error"); +} + |