[comp.sources.misc] v05i044: portable bitmap routines

jef@helios.ee.lbl.gov (Jef Poskanzer) (11/09/88)

Posting-number: Volume 5, Issue 44
Submitted-by: "Jef Poskanzer" <jef@helios.ee.lbl.gov>
Archive-name: pbm3/Part4

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	pbmtomacp.1
#	pbmtox10wd.c
#	pbmtox10wd.1
#	pbmtoxwd.c
#	pbmtoxwd.1
#	brushtopbm.c
#	brushtopbm.1
#	libpbm1.c
#	libpbm2.c
#	libpbm3.c
#	libpbm4.c
#	libpbm5.c
#	giftopbm.c
#	giftopbm.1
# This archive created: Mon Oct 31 18:33:38 1988
# By:	Jef Poskanzer (Paratheo-Anametamystikhood Of Eris Esoteric, Ada Lovelace Cabal)
export PATH; PATH=/bin:$PATH
echo shar: extracting "'pbmtomacp.1'" '(1091 characters)'
if test -f 'pbmtomacp.1'
then
	echo shar: will not over-write existing file "'pbmtomacp.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pbmtomacp.1'
X.TH pbmtomacp 1 "31 August 1988"
X.SH NAME
Xpbmtomacp - convert portable bitmap into MacPaint
X.SH SYNOPSIS
Xpbmtomacp [-l left] [-r right] [-b bottom] [-t top] [pbmfile]
X.SH DESCRIPTION
XReads a portable bitmap as input.
XIf no input-file is given, standard input is assumed.
XProduces a MacPaint file as output.
X.LP
XLeft, right,bottom & top let you define a square into the pbm file,
Xthat must be converted.
XDefault is the whole file.
XIf the file is too large for a MacPaint-file, the bitmap is cut to fit
Xfrom ( left, top ).
X.SH BUGS
XThe source code contains comments in a language other than English.
X.SH "SEE ALSO"
Xmacptopbm(1), pbm(5)
X.SH AUTHOR
XCopyright (C) 1988 by Douwe van der Schaaf.
XUSENET: ..!mcvax!uvapsy!vdschaaf
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 1091 -ne "`wc -c < 'pbmtomacp.1'`"
then
	echo shar: error transmitting "'pbmtomacp.1'" '(should have been 1091 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'pbmtox10wd.c'" '(2873 characters)'
if test -f 'pbmtox10wd.c'
then
	echo shar: will not over-write existing file "'pbmtox10wd.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pbmtox10wd.c'
X/* pbmtox10wd.c - read a portable bitmap and produce an X10 window dump
X**
X** Copyright (C) 1988 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#ifdef	OS_SYSV
X#include <string.h>
X#else	OS_SYSV
X#include <strings.h>
X#endif	OS_SYSV
X#include "pbm.h"
X#include "x10wd.h"
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    bit **bits;
X    int rows, cols, padright, row, col;
X    char name[100], *cp;
X
X    if ( argc > 2 )
X	{
X	fprintf( stderr, "usage:  %s [pbmfile]\n", argv[0] );
X	exit( 1 );
X	}
X
X    if ( argc == 2 )
X	{
X        ifd = fopen( argv[1], "r" );
X        if ( ifd == NULL )
X	    {
X	    fprintf( stderr, "%s: can't open.\n", argv[1] );
X	    exit( 1 );
X	    }
X	strcpy( name, argv[1] );
X
X#ifdef	OS_SYSV
X	if ( ( cp = strchr( name, '.' ) ) != 0 )
X#else	OS_SYSV
X	if ( ( cp = index( name, '.' ) ) != 0 )
X#endif	OS_SYSV
X	    *cp = '\0';
X	}
X    else
X	{
X	ifd = stdin;
X	strcpy( name, "noname" );
X	}
X
X    bits = pbm_readpbm( ifd, &cols, &rows );
X
X    if ( ifd != stdin )
X	fclose( ifd );
X    
X    /* Compute padding to round cols up to the nearest multiple of 16. */
X    padright = ( ( cols + 15 ) / 16 ) * 16 - cols;
X
X    putinit( cols, rows, name );
X    for ( row = 0; row < rows; row++ )
X	{
X        for ( col = 0; col < cols; col++ )
X	    putbit( bits[row][col] );
X	for ( col = 0; col < padright; col++ )
X	    putbit( 0 );
X        }
X    putrest( );
X
X    exit( 0 );
X    }
X
X
Xshort item;
Xint bitsperitem, bitshift;
X
X
Xputinit( cols, rows, name )
Xint cols, rows;
Xchar *name;
X    {
X    X10WDFileHeader h10;
X
X    h10.header_size = sizeof(h10) + (strlen(name) + 1) * sizeof(char);
X    h10.file_version = X10WD_FILE_VERSION;
X    h10.display_type = -1;		/* random number */
X    h10.display_planes = 1;
X    h10.pixmap_format = XYFormat;
X    h10.pixmap_width = cols;
X    h10.pixmap_height = rows;
X    h10.window_width = cols;
X    h10.window_height = rows;
X    h10.window_x = 0;			/* arbitrary */
X    h10.window_y = 0;			/* likewise */
X    h10.window_bdrwidth = 0;
X    h10.window_ncolors = 0;
X
X    fwrite( &h10, sizeof(h10), 1, stdout );
X    fwrite( name, sizeof(char), strlen(name) + 1, stdout );
X
X    item = 0;
X    bitsperitem = 0;
X    bitshift = 0;
X    }
X
Xputbit( b )
Xbit b;
X    {
X    if ( bitsperitem == 16 )
X	putitem( );
X    bitsperitem++;
X    if ( ! b )
X	item += 1 << bitshift;
X    bitshift++;
X    }
X
Xputrest( )
X    {
X    if ( bitsperitem > 0 )
X	putitem( );
X    }
X
Xputitem( )
X    {
X    fwrite( &item, sizeof(item), 1, stdout );
X    item = 0;
X    bitsperitem = 0;
X    bitshift = 0;
X    }
SHAR_EOF
if test 2873 -ne "`wc -c < 'pbmtox10wd.c'`"
then
	echo shar: error transmitting "'pbmtox10wd.c'" '(should have been 2873 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'pbmtox10wd.1'" '(691 characters)'
if test -f 'pbmtox10wd.1'
then
	echo shar: will not over-write existing file "'pbmtox10wd.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pbmtox10wd.1'
X.TH pbmtox10wd 1 "31 August 1988"
X.SH NAME
Xpbmtox10wd - convert portable bitmaps into X10 window dumps
X.SH SYNOPSIS
Xpbmtox10wd [pbmfile]
X.SH DESCRIPTION
XReads a portable bitmap as input.
XProduces an X10 window dump as output.
X.SH "SEE ALSO"
Xpbmtoxwd(1), xwdtopbm(1), pbm(5)
X.SH AUTHOR
XCopyright (C) 1988 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 691 -ne "`wc -c < 'pbmtox10wd.1'`"
then
	echo shar: error transmitting "'pbmtox10wd.1'" '(should have been 691 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'pbmtoxwd.c'" '(3517 characters)'
if test -f 'pbmtoxwd.c'
then
	echo shar: will not over-write existing file "'pbmtoxwd.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pbmtoxwd.c'
X/* pbmtoxwd.c - read a portable bitmap and produce an X11 window dump
X**
X** Copyright (C) 1988 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#ifdef	OS_SYSV
X#include <string.h>
X#else	OS_SYSV
X#include <strings.h>
X#endif	OS_SYSV
X#include "pbm.h"
X#include "x11wd.h"
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    bit **bits;
X    int rows, cols, padright, row, col;
X    char name[100], *cp;
X
X    if ( argc > 2 )
X	{
X	fprintf( stderr, "usage:  %s [pbmfile]\n", argv[0] );
X	exit( 1 );
X	}
X
X    if ( argc == 2 )
X	{
X        ifd = fopen( argv[1], "r" );
X        if ( ifd == NULL )
X	    {
X	    fprintf( stderr, "%s: can't open.\n", argv[1] );
X	    exit( 1 );
X	    }
X	strcpy( name, argv[1] );
X
X#ifdef	OS_SYSV
X	if ( ( cp = strchr( name, '.' ) ) != 0 )
X#else	OS_SYSV
X	if ( ( cp = index( name, '.' ) ) != 0 )
X#endif	OS_SYSV
X	    *cp = '\0';
X	}
X    else
X	{
X	ifd = stdin;
X	strcpy( name, "noname" );
X	}
X
X    bits = pbm_readpbm( ifd, &cols, &rows );
X
X    if ( ifd != stdin )
X	fclose( ifd );
X    
X    /* Compute padding to round cols up to the nearest multiple of 32. */
X    padright = ( ( cols + 31 ) / 32 ) * 32 - cols;
X
X    putinit( cols, rows, name );
X    for ( row = 0; row < rows; row++ )
X	{
X        for ( col = 0; col < cols; col++ )
X	    putbit( bits[row][col] );
X	for ( col = 0; col < padright; col++ )
X	    putbit( 0 );
X        }
X    putrest( );
X
X    exit( 0 );
X    }
X
X
Xlong item;
Xint bitsperitem, bitshift;
X
X
Xputinit( cols, rows, name )
Xint cols, rows;
Xchar *name;
X    {
X    X11WDFileHeader h11;
X    X11XColor color;
X
X    h11.header_size = sizeof(h11) + (strlen(name) + 1) * sizeof(char);
X    h11.file_version = X11WD_FILE_VERSION;
X    h11.pixmap_format = ZPixmap;
X    h11.pixmap_depth = 1;
X    h11.pixmap_width = cols;
X    h11.pixmap_height = rows;
X    h11.xoffset = 0;
X    h11.byte_order = MSBFirst;
X    h11.bitmap_unit = 32;
X    h11.bitmap_bit_order = MSBFirst;
X    h11.bitmap_pad = 32;
X    h11.bits_per_pixel = 1;
X    h11.bytes_per_line = ( ( cols + 31 ) / 32 ) * 4;
X    h11.visual_class = 0;
X    h11.red_mask = 0;
X    h11.green_mask = 0;
X    h11.blue_mask = 0;
X    h11.bits_per_rgb = 1;
X    h11.colormap_entries = 2;
X    h11.ncolors = 2;
X    h11.window_width = cols;
X    h11.window_height = rows;
X    h11.window_x = 0;			/* arbitrary */
X    h11.window_y = 0;			/* arbitrary */
X    h11.window_bdrwidth = 0;
X    fwrite( &h11, sizeof(h11), 1, stdout );
X
X    fwrite( name, sizeof(char), strlen(name) + 1, stdout );
X
X    color.pixel = 0;
X    color.red = 65535;
X    color.green = 65535;
X    color.blue = 65535;
X    color.flags = 7;
X    color.pad = 0;
X    fwrite( &color, sizeof(color), 1, stdout );
X    color.pixel = 1;
X    color.red = 0;
X    color.green = 0;
X    color.blue = 0;
X    fwrite( &color, sizeof(color), 1, stdout );
X
X    item = 0;
X    bitsperitem = 0;
X    bitshift = 31;
X    }
X
Xputbit( b )
Xbit b;
X    {
X    if ( bitsperitem == 32 )
X	putitem( );
X    bitsperitem++;
X    if ( b )
X	item += 1 << bitshift;
X    bitshift--;
X    }
X
Xputrest( )
X    {
X    if ( bitsperitem > 0 )
X	putitem( );
X    }
X
Xputitem( )
X    {
X    fwrite( &item, sizeof(item), 1, stdout );
X    item = 0;
X    bitsperitem = 0;
X    bitshift = 31;
X    }
SHAR_EOF
if test 3517 -ne "`wc -c < 'pbmtoxwd.c'`"
then
	echo shar: error transmitting "'pbmtoxwd.c'" '(should have been 3517 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'pbmtoxwd.1'" '(742 characters)'
if test -f 'pbmtoxwd.1'
then
	echo shar: will not over-write existing file "'pbmtoxwd.1'"
else
sed 's/^X//' << \SHAR_EOF > 'pbmtoxwd.1'
X.TH pbmtoxwd 1 "31 August 1988"
X.SH NAME
Xpbmtoxwd - convert portable bitmaps into X11 window dumps
X.SH SYNOPSIS
Xpbmtoxwd [pbmfile]
X.SH DESCRIPTION
XReads a portable bitmap as input.
XProduces an X11 window dump as output.
XThis window dump can be displayed using the xwud tool.
X.SH "SEE ALSO"
Xpbmtox10wd(1), xwdtopbm(1), pbm(5)
X.SH AUTHOR
XCopyright (C) 1988 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 742 -ne "`wc -c < 'pbmtoxwd.1'`"
then
	echo shar: error transmitting "'pbmtoxwd.1'" '(should have been 742 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'brushtopbm.c'" '(2333 characters)'
if test -f 'brushtopbm.c'
then
	echo shar: will not over-write existing file "'brushtopbm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'brushtopbm.c'
X/* brushtopbm.c - read a doodle brush file and write a portable bitmap
X**
X** Copyright (C) 1988 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pbm.h"
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X    {
X    FILE *ifd;
X    bit **bits, getbit();
X    int rows, cols, padright, row, col;
X
X    if ( argc > 2 )
X	{
X	fprintf( stderr, "usage:  %s [brushfile]\n", argv[0] );
X	exit( 1 );
X	}
X
X    if ( argc == 2 )
X	{
X        ifd = fopen( argv[1], "r" );
X        if ( ifd == NULL )
X	    {
X	    fprintf( stderr, "%s: can't open.\n", argv[1] );
X	    exit( 1 );
X	    }
X	}
X    else
X	ifd = stdin;
X
X    getinit( ifd, &cols, &rows );
X
X    bits = pbm_allocarray( cols, rows );
X
X    /* Compute padding to round cols up to the next multiple of 16. */
X    padright = ( ( cols + 15 ) / 16 ) * 16 - cols;
X
X    for ( row = 0; row < rows; row++ )
X	{
X	/* Get data. */
X        for ( col = 0; col < cols; col++ )
X	    bits[row][col] = getbit( ifd );
X	/* Discard line padding. */
X        for ( col = 0; col < padright; col++ )
X	    (void) getbit( ifd );
X	}
X
X    if ( ifd != stdin )
X	fclose( ifd );
X    
X    pbm_writepbm( stdout, bits, cols, rows );
X
X    exit( 0 );
X    }
X
X
Xint item, bitsperitem, bitshift;
X
Xgetinit( file, colp, rowp )
XFILE *file;
Xint *colp, *rowp;
X    {
X    int i;
X
X    if ( getc( file ) != 1 )
X	{
X	fprintf( stderr, "Bad magic number 1.\n" );
X	exit( 1 );
X	}
X    if ( getc( file ) != 0 )
X	{
X	fprintf( stderr, "Bad magic number 2.\n" );
X	exit( 1 );
X	}
X    *colp = getc( file ) << 8;
X    *colp += getc( file );
X    *rowp = getc( file ) << 8;
X    *rowp += getc( file );
X    bitsperitem = 8;
X
X    /* Junk rest of header. */
X    for ( i = 0; i < 10; i++ )  /* 10 is just a guess at the header size */
X	(void) getc( file );
X    }
X
Xbit
Xgetbit( file )
XFILE *file;
X    {
X    bit b;
X
X    if ( bitsperitem == 8 )
X	{
X	item = getc( file );
X	bitsperitem = 0;
X	bitshift = 7;
X	}
X    bitsperitem++;
X    b = 1 - ( ( item >> bitshift) & 1 );
X    bitshift--;
X    return b;
X    }
SHAR_EOF
if test 2333 -ne "`wc -c < 'brushtopbm.c'`"
then
	echo shar: error transmitting "'brushtopbm.c'" '(should have been 2333 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'brushtopbm.1'" '(729 characters)'
if test -f 'brushtopbm.1'
then
	echo shar: will not over-write existing file "'brushtopbm.1'"
else
sed 's/^X//' << \SHAR_EOF > 'brushtopbm.1'
X.TH brushtopbm 1 "28 August 1988"
X.SH NAME
Xbrushtopbm - convert doodle brush files into portable bitmaps
X.SH SYNOPSIS
Xbrushtopbm [brushfile]
X.SH DESCRIPTION
XReads a Xerox doodle brush file as input.
XProduces a portable bitmap as output.
X.LP
XNote that there is currently no pbmtobrush tool.
X.SH "SEE ALSO"
Xpbm(5)
X.SH AUTHOR
XCopyright (C) 1988 by Jef Poskanzer.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted, provided
Xthat the above copyright notice appear in all copies and that both that
Xcopyright notice and this permission notice appear in supporting
Xdocumentation.  This software is provided "as is" without express or
Ximplied warranty.
SHAR_EOF
if test 729 -ne "`wc -c < 'brushtopbm.1'`"
then
	echo shar: error transmitting "'brushtopbm.1'" '(should have been 729 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'libpbm1.c'" '(789 characters)'
if test -f 'libpbm1.c'
then
	echo shar: will not over-write existing file "'libpbm1.c'"
else
sed 's/^X//' << \SHAR_EOF > 'libpbm1.c'
X/* libpbm1.c - pbm utility library part 1
X**
X** Copyright (C) 1988 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pbm.h"
X#include "libpbm.h"
X
X
Xbit **
Xpbm_allocarray( cols, rows )
Xint cols, rows;
X    {
X    bit **bits;
X    int i;
X
X    bits = (bit **) malloc( rows * sizeof( bit *) );
X    for ( i = 0; i < rows; i++ )
X	{
X	bits[i] = (bit *) malloc( cols * sizeof( bit ) );
X	}
X
X    return bits;
X    }
SHAR_EOF
if test 789 -ne "`wc -c < 'libpbm1.c'`"
then
	echo shar: error transmitting "'libpbm1.c'" '(should have been 789 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'libpbm2.c'" '(2492 characters)'
if test -f 'libpbm2.c'
then
	echo shar: will not over-write existing file "'libpbm2.c'"
else
sed 's/^X//' << \SHAR_EOF > 'libpbm2.c'
X/* libpbm2.c - pbm utility library part 2
X**
X** Copyright (C) 1988 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pbm.h"
X#include "libpbm.h"
X
X
Xstatic char
Xpbm_getc( file )
XFILE *file;
X    {
X    int ich;
X    char ch;
X
X    ich = getc( file );
X    if ( ich == NULL )
X	{
X	fprintf( stderr, "Premature EOF.\n" );
X	exit( 1 );
X	}
X    ch = (char) ich;
X    
X    if ( ch == '#' )
X	{
X	do
X	    {
X	    ich = getc( file );
X	    if ( ich == NULL )
X		{
X		fprintf( stderr, "Premature EOF.\n" );
X		exit( 1 );
X		}
X	    ch = (char) ich;
X	    }
X	while ( ch != '\n' );
X	}
X
X    return ch;
X    }
X
Xstatic int
Xpbm_getint( file )
XFILE *file;
X    {
X    char ch;
X    int i;
X
X    do
X	{
X	ch = pbm_getc( file );
X	}
X    while ( ch == ' ' || ch == '\t' || ch == '\n' );
X
X    if ( ch < '0' || ch > '9' )
X	{
X	fprintf( stderr, "Junk in file where an integer should be!\n" );
X	exit( 1 );
X	}
X
X    i = 0;
X    do
X	{
X	i = i * 10 + ch - '0';
X	ch = pbm_getc( file );
X        }
X    while ( ch >= '0' && ch <= '9' );
X
X    return i;
X    }
X
Xstatic bit
Xpbm_getbit( file )
XFILE *file;
X    {
X    char ch;
X
X    do
X	{
X	ch = pbm_getc( file );
X	}
X    while ( ch == ' ' || ch == '\t' || ch == '\n' );
X
X    if ( ch != '0' && ch != '1' )
X	{
X	fprintf( stderr, "Junk in file where bits should be!\n" );
X	exit( 1 );
X	}
X
X    return ( ch == '1' ) ? 1 : 0;
X    }
X
X
Xbit **
Xpbm_readpbm( file, colsP, rowsP )
XFILE *file;
Xint *colsP, *rowsP;
X    {
X    int ich1, ich2;
X    bit **bits;
X    int row, col;
X
X    /* Check for magic number. */
X    ich1 = getc( file );
X    if ( ich1 == NULL )
X	{
X	fprintf( stderr, "Premature EOF.\n" );
X	exit( 1 );
X	}
X    ich2 = getc( file );
X    if ( ich2 == NULL )
X	{
X	fprintf( stderr, "Premature EOF.\n" );
X	exit( 1 );
X	}
X    if ( ich1 != PBM_MAGIC1 || ich2 != PBM_MAGIC2 )
X	{
X	fprintf( stderr, "Bad magic number - not a pbm file.\n" );
X	exit( 1 );
X	}
X
X    /* Read size. */
X    *colsP = pbm_getint( file );
X    *rowsP = pbm_getint( file );
X
X    bits = pbm_allocarray( *colsP, *rowsP );
X
X    for ( row = 0; row < *rowsP; row++ )
X        for ( col = 0; col < *colsP; col++ )
X	    bits[row][col] = pbm_getbit( file );
X
X    return bits;
X    }
SHAR_EOF
if test 2492 -ne "`wc -c < 'libpbm2.c'`"
then
	echo shar: error transmitting "'libpbm2.c'" '(should have been 2492 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'libpbm3.c'" '(1018 characters)'
if test -f 'libpbm3.c'
then
	echo shar: will not over-write existing file "'libpbm3.c'"
else
sed 's/^X//' << \SHAR_EOF > 'libpbm3.c'
X/* libpbm3.c - pbm utility library part 3
X**
X** Copyright (C) 1988 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pbm.h"
X#include "libpbm.h"
X
X
Xpbm_writepbm( file, bits, cols, rows )
XFILE *file;
Xbit **bits;
Xint cols, rows;
X    {
X    int row, col, linecount;
X
X    fprintf( file, "%c%c\n%d %d\n", PBM_MAGIC1, PBM_MAGIC2, cols, rows );
X
X    for ( row = 0; row < rows; row++ )
X	{
X	linecount = 0;
X        for ( col = 0; col < cols; col++ )
X	    {
X	    if ( linecount >= 70 )
X		{
X		putc( '\n', file );
X		linecount = 0;
X		}
X	    putc( bits[row][col] ? '1' : '0', file );
X	    linecount++;
X	    }
X	putc( '\n', file );
X        }
X    }
SHAR_EOF
if test 1018 -ne "`wc -c < 'libpbm3.c'`"
then
	echo shar: error transmitting "'libpbm3.c'" '(should have been 1018 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'libpbm4.c'" '(2929 characters)'
if test -f 'libpbm4.c'
then
	echo shar: will not over-write existing file "'libpbm4.c'"
else
sed 's/^X//' << \SHAR_EOF > 'libpbm4.c'
X/* libpbm4.c - pbm utility library part 4
X**
X** Copyright (C) 1988 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pbm.h"
X#include "libpbm.h"
X
X
Xstatic int version, item, bitsinitem, bitshift;
Xstatic int bitspercount, count, repeatbits, repeatindex;
Xstatic bit repeat, repeatbuf[MAX_REPEATBITS];
Xstatic FILE *cbm_file;
X
X
Xstatic
Xcbm_getinit( file, colsP, rowsP )
XFILE *file;
Xint *colsP, *rowsP;
X    {
X    int magic2;
X
X    if ( getc( file ) != CBM_MAGIC1 )
X	{
X	fprintf( stderr, "Bad first magic number.\n" );
X	exit( 1 );
X	}
X    if ( ( magic2 = getc( file ) ) != OCBM_MAGIC2 && magic2 != NCBM_MAGIC2 )
X	{
X	fprintf( stderr, "Bad second magic number.\n" );
X	exit( 1 );
X	}
X
X    if ( magic2 == OCBM_MAGIC2 )
X	version = VERSION_OLDCBM;
X    else
X	{
X	version = getc( file );
X	switch ( version )
X	    {
X	    case VERSION_RUNLEN:
X	    bitspercount = getc( file );
X	    repeatbits = getc( file );
X	    count = 0;
X	    break;
X
X	    default:
X	    fprintf( stderr, "Unknown cbm version %d.\n", version );
X	    exit( 1 );
X	    }
X	}
X
X    *colsP = getc( file ) << 8;
X    *colsP += getc( file );
X    *rowsP = getc( file ) << 8;
X    *rowsP += getc( file );
X
X    bitsinitem = 8;
X    cbm_file = file;
X    }
X
Xstatic bit
Xcbm_getbit( )
X    {
X    bit b;
X
X    if ( bitsinitem == 8 )
X	{
X	item = getc( cbm_file );
X	bitsinitem = 0;
X	bitshift = 7;
X	}
X    bitsinitem++;
X    b = ( item >> bitshift) & 1;
X    bitshift--;
X    return b;
X    }
X
Xstatic bit
Xcbm_getrlbit( )
X    {
X    int i;
X
X    if ( count == 0 )
X	{
X	repeat = cbm_getbit( );
X
X	for ( i = 0; i < bitspercount; i++ )
X	    count = ( count << 1 ) + cbm_getbit( );
X	if ( count == 0 )
X	    {
X	    fprintf( stderr, "Error - zero count in cbm file.\n" );
X	    exit( 1 );
X	    }
X
X	if ( repeat )
X	    {
X	    for ( i = 0; i < repeatbits; i++ )
X		repeatbuf[i] = cbm_getbit( );
X	    repeatindex = repeatbits - 1;
X	    }
X	}
X
X    count--;
X    if ( repeat )
X	{
X	repeatindex = ( repeatindex + 1 ) % repeatbits;
X	return repeatbuf[repeatindex];
X	}
X    else
X	return cbm_getbit( );
X    }
X
Xbit **
Xpbm_readcbm( file, colsP, rowsP )
XFILE *file;
Xint *colsP, *rowsP;
X    {
X    bit **bits;
X    int row, col;
X
X    cbm_getinit( file, colsP, rowsP );
X
X    bits = pbm_allocarray( *colsP, *rowsP );
X
X    switch ( version )
X	{
X	case VERSION_OLDCBM:
X	for ( row = 0; row < *rowsP; row++ )
X	    for ( col = 0; col < *colsP; col++ )
X		bits[row][col] = cbm_getbit( );
X	break;
X
X	case VERSION_RUNLEN:
X	for ( row = 0; row < *rowsP; row++ )
X	    for ( col = 0; col < *colsP; col++ )
X		bits[row][col] = cbm_getrlbit( );
X	break;
X	}
X
X    return bits;
X    }
SHAR_EOF
if test 2929 -ne "`wc -c < 'libpbm4.c'`"
then
	echo shar: error transmitting "'libpbm4.c'" '(should have been 2929 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'libpbm5.c'" '(4574 characters)'
if test -f 'libpbm5.c'
then
	echo shar: will not over-write existing file "'libpbm5.c'"
else
sed 's/^X//' << \SHAR_EOF > 'libpbm5.c'
X/* libpbm5.c - pbm utility library part 5
X**
X** Copyright (C) 1988 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation.  This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include "pbm.h"
X#include "libpbm.h"
X
X
Xstatic int item, bitsinitem, bitshift;
Xstatic int bitspercount, count, maxcount, repeatbits, repeatcount, repeatindex;
Xstatic bit repeat, bitbuf[MAX_MAXCOUNT], repeatbuf[MAX_REPEATBITS];
Xstatic FILE *cbm_file;
X
X
Xstatic
Xcbm_putinit( cols, rows, file )
Xint cols, rows;
XFILE *file;
X    {
X    putc( (char) CBM_MAGIC1, file );
X    putc( (char) NCBM_MAGIC2, file );
X
X    putc( (char) VERSION_RUNLEN, file );
X
X    bitspercount = DEFAULT_BITSPERCOUNT;
X    maxcount = ( 1 << bitspercount ) - 1;
X    putc( (char) bitspercount, file );
X
X    repeatbits = DEFAULT_REPEATBITS;
X    putc( (char) repeatbits, file );
X
X    putc( (char) ( ( cols >> 8 ) & 0xff ), file );
X    putc( (char) ( cols & 0xff ), file );
X    putc( (char) ( ( rows >> 8 ) & 0xff ), file );
X    putc( (char) ( rows & 0xff ), file );
X
X    /* Initialize statics for run-length encoding. */
X    repeat = 1;
X    count = 0;
X    repeatindex = 0;
X
X    /* Initialize statics for bit-to-byte encoding. */
X    bitsinitem = 0;
X    item = 0;
X    bitshift = 7;
X    cbm_file = file;
X    }
X
Xstatic
Xcbm_putitem( )
X    {
X    putc( (char) item, cbm_file );
X    bitsinitem = 0;
X    item = 0;
X    bitshift = 7;
X    }
X
Xstatic
Xcbm_putbit( b )
Xbit b;
X    {
X    if ( bitsinitem == 8 )
X	cbm_putitem( );
X    bitsinitem++;
X    if ( b )
X	item += 1 << bitshift;
X    bitshift--;
X    }
X
Xstatic
Xcbm_putrest( )
X    {
X    if ( bitsinitem > 0 )
X	cbm_putitem( );
X    }
X
Xstatic
Xcbm_putrlbuffer( )
X    {
X    int i;
X
X    cbm_putbit( repeat );
X
X    for ( i = bitspercount - 1; i >= 0; i-- )
X	if ( count & ( 1 << i ) )
X	    cbm_putbit( 1 );
X	else
X	    cbm_putbit( 0 );
X
X    if ( repeat )
X	for ( i = 0; i < repeatbits; i++ )
X	    cbm_putbit( repeatbuf[i] );
X    else
X	for ( i = 0; i < count; i++ )
X	    cbm_putbit( bitbuf[i] );
X
X    repeat = 1;
X    count = 0;
X    }
X
Xstatic
Xcbm_putrlbit( b )
Xbit b;
X    {
X    int i;
X
X    if ( count == maxcount )
X	{
X	cbm_putrlbuffer( );
X	repeatindex = 0;
X	}
X
X    if ( repeat && count < repeatbits )
X	{ /* Still initializing a repeat buf. */
X	bitbuf[count] = repeatbuf[repeatindex] = b;
X	count++;
X	repeatindex = ( repeatindex + 1 ) % repeatbits;
X	}
X    else if ( repeat )
X	{ /* Repeating - watch for end of run. */
X	if ( b == repeatbuf[repeatindex] )
X	    { /* Run continues. */
X	    bitbuf[count] = b;
X	    count++;
X	    repeatindex = ( repeatindex + 1 ) % repeatbits;
X	    }
X	else
X	    { /* Run ended - is it long enough to dump? */
X	    if ( count > bitspercount + 1 )
X		{ /* Yes, dump a repeat-mode buffer and start a new one. */
X		cbm_putrlbuffer( );
X		repeatindex = 0;
X		bitbuf[count] = repeatbuf[repeatindex] = b;
X		count++;
X		repeatindex++;
X		}
X	    else
X		{ /* Not long enough - convert to non-repeat mode. */
X		repeat = 0;
X		bitbuf[count] = b;
X		count++;
X		for ( i = 0; i < repeatbits; i++ )
X		    repeatbuf[i] = bitbuf[count - repeatbits + i];
X		repeatcount = repeatbits;
X		repeatindex = 0;
X		}
X	    }
X	}
X    else
X	{ /* Not repeating - watch for a run worth repeating. */
X	if ( b == repeatbuf[repeatindex] )
X	    { /* Possible run continues. */
X	    repeatcount++;
X	    repeatindex = ( repeatindex + 1 ) % repeatbits;
X	    if ( repeatcount > 2 + 2 * bitspercount + repeatbits )
X		{ /* Long enough - dump non-repeat part and start repeat. */
X		count = count - ( repeatcount - 1 );
X		cbm_putrlbuffer( );
X		count = repeatcount;
X		/* ??? */
X		}
X	    else
X		{ /* Not long enough yet - continue as non-repeat buf. */
X		bitbuf[count] = b;
X		count++;
X		}
X	    }
X	else
X	    { /* Broken run. */
X	    bitbuf[count] = b;
X	    count++;
X	    for ( i = 0; i < repeatbits; i++ )
X		repeatbuf[i] = bitbuf[count - repeatbits + i];
X	    repeatcount = repeatbits;
X	    repeatindex = 0;
X	    }
X	}
X    }
X
Xstatic
Xcbm_putrlrest( )
X    {
X    if ( count > 0 )
X	cbm_putrlbuffer( );
X    cbm_putrest( );
X    }
X
X
Xpbm_writecbm( file, bits, cols, rows )
XFILE *file;
Xbit **bits;
Xint cols, rows;
X    {
X    int row, col, linecount;
X
X    cbm_putinit( cols, rows, file );
X
X    for ( row = 0; row < rows; row++ )
X        for ( col = 0; col < cols; col++ )
X	    cbm_putrlbit( bits[row][col] );
X
X    cbm_putrlrest( );
X    }
SHAR_EOF
if test 4574 -ne "`wc -c < 'libpbm5.c'`"
then
	echo shar: error transmitting "'libpbm5.c'" '(should have been 4574 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'giftopbm.c'" '(13188 characters)'
if test -f 'giftopbm.c'
then
	echo shar: will not over-write existing file "'giftopbm.c'"
else
sed 's/^X//' << \SHAR_EOF > 'giftopbm.c'
X/*-
X * gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
X *
X * Copyright (c) 1988 by Patrick J. Naughton
X *
X * Author: Patrick J. Naughton
X * naughton@wind.sun.com
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation.
X *
X * This file is provided AS IS with no warranties of any kind.  The author
X * shall have no liability with respect to the infringement of copyrights,
X * trade secrets or any patents by this file or any part thereof.  In no
X * event will the author be liable for any lost revenue or profits or
X * other special, indirect and consequential damages.
X *
X * Comments and additions should be sent to the author:
X *
X *                     Patrick J. Naughton
X *                     Sun Microsystems, Inc.
X *                     2550 Garcia Ave, MS 14-40
X *                     Mountain View, CA 94043
X *                     (415) 336-1080
X *
X * Revision History:
X * 28-Aug-88: Modified by Jef Poskanzer to output PBM instead of Sun raster.
X * 27-Jul-88: Updated to use libpixrect to fix 386i byteswapping problems.
X * 11-Apr-88: Converted to C and changed to write Sun rasterfiles.
X * 19-Jan-88: GIFSLOW.PAS posted to comp.graphics by Jim Briebel,
X *            a Turbo Pascal 4.0 program to painfully slowly display
X *            GIF images on an EGA equipped IBM-PC.
X *
X * Description:
X *   This program takes a Compuserve "Graphics Interchange Format" or "GIF"
X * file as input and writes a file known as a Sun rasterfile.  This datafile
X * can be loaded by the NeWS "readcanvas" operator and is of the same format
X * as the files in /usr/NeWS/smi/*.  Under X11R2 there is a program called
X * xraster to display these files.
X *
X * Portability:
X *   To make this program convert to some image format other than PBM
X * format simply seach for the tag "PBMS:" in the source and
X * replace these simple mechanisms with the appropriate ones for the
X * other output format.  I have marked all (six) PBM Specific pieces
X * of code with this comment.
X *
X * SS: compile with "cc -o gif2ras -O gif2ras.c -lpixrect"
X * PBMS: compile with "cc -o giftopbm -O giftopbm.c libpbm.a
X */
X
X#include <stdio.h>
X#ifdef notdefSS
X#include <pixrect/pixrect_hs.h> /* SS: main Pixrect header file */
X#endif notdefSS
X#include <sys/types.h>
X#include "pbm.h"		/* PBMS: main PBM header file */
X
Xtypedef int boolean;
X#define True (1)
X#define False (0)
X
X#define NEXTSHORT (*ptr++ + (0x100 * *ptr++))
X#define NEXTBYTE (*ptr++)
X#define IMAGESEP 0x2c
X#define INTERLACEMASK 0x40
X#define COLORMAPMASK 0x80
X
Xint BitOffset = 0,		/* Bit Offset of next code */
X    XC = 0, YC = 0,		/* Output X and Y coords of current pixel */
X    Pass = 0,			/* Used by output routine if interlaced pic */
X    OutCount = 0,		/* Decompressor output 'stack count' */
X    RWidth, RHeight,		/* screen dimensions */
X    Width, Height,		/* image dimensions */
X    LeftOfs, TopOfs,		/* image offset */
X    BitsPerPixel,		/* Bits per pixel, read from GIF header */
X    ColorMapSize,		/* number of colors */
X    CodeSize,			/* Code size, read from GIF header */
X    InitCodeSize,		/* Starting code size, used during Clear */
X    Code,			/* Value returned by ReadCode */
X    MaxCode,			/* limiting value for current code size */
X    ClearCode,			/* GIF clear code */
X    EOFCode,			/* GIF end-of-information code */
X    CurCode, OldCode, InCode,	/* Decompressor variables */
X    FirstFree,			/* First free code, generated per GIF spec */
X    FreeCode,			/* Decompressor, next free slot in hash table */
X    FinChar,			/* Decompressor variable */
X    BitMask,			/* AND mask for data size */
X    ReadMask;			/* Code AND mask for current code size */
X
Xboolean Interlace, HasColormap;
X
X#ifdef notdefSS
X/* SS: defined in pixrect/pixrect_hs.h */
XPixrect *Output;		/* The Sun Pixrect */
Xcolormap_t Colormap;		/* The Pixrect Colormap */
Xu_char *Image;			/* The result array */
X#endif notdefSS
X/* PBMS: defined in pbm.h */
Xbit **bits;			/* The PBM bit array */
X
Xu_char *RawGIF;			/* The heap array to hold it, raw */
Xu_char *Raster;			/* The raster data stream, unblocked */
X
X    /* The hash table used by the decompressor */
Xint Prefix[4096];
Xint Suffix[4096];
X
X    /* An output array used by the decompressor */
Xint OutCode[1025];
X
X    /* The color map, read from the GIF header */
Xu_char Red[256], Green[256], Blue[256];
X
Xchar *id = "GIF87a";
X
Xchar *pname;			/* program name (used for error messages) */
X 
Xvoid
Xerror(s1, s2)
Xchar *s1, *s2;
X{
X    fprintf(stderr, s1, pname, s2);
X    exit(1);
X}
X
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
XFILE *fp;
Xchar *infname = argv[1];
Xchar *outfname = argv[2];
Xint filesize;
Xregister u_char ch, ch1;
Xregister u_char *ptr, *ptr1;
Xregister int i;
X
X    setbuf(stderr, NULL);
X    pname = argv[0];
X
X    if (argc < 3)
X	error("usage: %s GIFfile rasterfile\n", NULL);
X
X    if (!(fp = fopen(infname, "r")))
X	error("%s: %s not found.\n", infname);
X
X    /* find the size of the file */
X
X    fseek(fp, 0L, 2);
X    filesize = ftell(fp);
X    fseek(fp, 0L, 0);
X
X    if (!(ptr = RawGIF = (u_char *) malloc(filesize)))
X	error("%s: not enough memory to read gif file.\n", NULL);
X
X    if (!(Raster = (u_char *) malloc(filesize)))
X	error("%s: not enough memory to read gif file.\n", NULL);
X
X    fread(ptr, filesize, 1, fp);
X
X    if (strncmp(ptr, id, 6))
X	error("%s: %s is not a GIF file.\n", infname);
X    ptr += 6;
X
X/* Get variables from the GIF screen descriptor */
X
X    RWidth = NEXTSHORT;		/* screen dimensions... not used. */
X    RHeight = NEXTSHORT;
X
X    ch = NEXTBYTE;
X    HasColormap = ((ch & COLORMAPMASK) ? True : False);
X
X    BitsPerPixel = (ch & 7) + 1;
X    ColorMapSize = 1 << BitsPerPixel;
X    BitMask = ColorMapSize - 1;
X
X    ch = NEXTBYTE;		/* background color... not used. */
X
X    if (NEXTBYTE)		/* supposed to be NULL */
X	error("%s: %s is a corrupt GIF file.\n", infname);
X
X/* Read in global colormap. */
X
X    if (HasColormap) {
X	fprintf(stderr, "%s is %d bits per pixel, (%d colors).\n",
X		infname, BitsPerPixel, ColorMapSize);
X	for (i = 0; i < ColorMapSize; i++) {
X	    Red[i] = NEXTBYTE;
X	    Green[i] = NEXTBYTE;
X	    Blue[i] = NEXTBYTE;
X	}
X
X#ifdef notdefSS
X/* SS: Fill in the Pixrect colormap struct */
X	Colormap.type = RMT_EQUAL_RGB;
X	Colormap.length = ColorMapSize;
X	Colormap.map[0] = Red;
X	Colormap.map[1] = Green;
X	Colormap.map[2] = Blue;
X#endif notdefSS
X	/* PBMS: PBM only handles bitmaps.  Reject any pixmaps here. */
X	if (BitsPerPixel != 1)
X	    error("%s: %s has more than one bit per pixel - it's not a bitmap.\n", infname);
X    }
X    else error("%s: %s does not have a colormap.\n", infname);
X
X
X/* Check for image seperator */
X
X    if (NEXTBYTE != IMAGESEP)
X	error("%s: %s is a corrupt GIF file.\n", infname);
X
X/* Now read in values from the image descriptor */
X
X    LeftOfs = NEXTSHORT;
X    TopOfs = NEXTSHORT;
X    Width = NEXTSHORT;
X    Height = NEXTSHORT;
X    Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False);
X
X    fprintf(stderr, "Reading a %d by %d %sinterlaced image...",
X        Width, Height, (Interlace) ? "" : "non-");
X    
X
X/* Note that I ignore the possible existence of a local color map.
X * I'm told there aren't many files around that use them, and the spec
X * says it's defined for future use.  This could lead to an error
X * reading some files. 
X */
X
X/* Start reading the raster data. First we get the intial code size
X * and compute decompressor constant values, based on this code size.
X */
X
X    CodeSize = NEXTBYTE;
X    ClearCode = (1 << CodeSize);
X    EOFCode = ClearCode + 1;
X    FreeCode = FirstFree = ClearCode + 2;
X
X/* The GIF spec has it that the code size is the code size used to
X * compute the above values is the code size given in the file, but the
X * code size used in compression/decompression is the code size given in
X * the file plus one. (thus the ++).
X */
X
X    CodeSize++;
X    InitCodeSize = CodeSize;
X    MaxCode = (1 << CodeSize);
X    ReadMask = MaxCode - 1;
X
X/* Read the raster data.  Here we just transpose it from the GIF array
X * to the Raster array, turning it from a series of blocks into one long
X * data stream, which makes life much easier for ReadCode().
X */
X
X    ptr1 = Raster;
X    do {
X	ch = ch1 = NEXTBYTE;
X	while (ch--) *ptr1++ = NEXTBYTE;
X    } while(ch1);
X
X    free(RawGIF);		/* We're done with the raw data now... */
X
X    fprintf(stderr, "done.\n");
X    fprintf(stderr, "Decompressing...");
X
X
X#ifdef notdefSS
X/* SS: Allocate the Sun Pixrect and make "Image" point to the image data. */
X    Output = mem_create(Width, Height, 8);
X    if (Output == (Pixrect *) NULL)
X	error("%s: not enough memory for output data.\n", NULL);
X    Image = (u_char *) mpr_d(Output)->md_image;
X#endif notdefSS
X/* PBMS: Allocate the PBM bit array. */
X    bits = pbm_allocarray(Width, Height);
X
X
X/* Decompress the file, continuing until you see the GIF EOF code.
X * One obvious enhancement is to add checking for corrupt files here.
X */
X
X    Code = ReadCode();
X    while (Code != EOFCode) {
X
X/* Clear code sets everything back to its initial value, then reads the
X * immediately subsequent code as uncompressed data.
X */
X
X	if (Code == ClearCode) {
X	    CodeSize = InitCodeSize;
X	    MaxCode = (1 << CodeSize);
X	    ReadMask = MaxCode - 1;
X	    FreeCode = FirstFree;
X	    CurCode = OldCode = Code = ReadCode();
X	    FinChar = CurCode & BitMask;
X	    AddToPixel(FinChar);
X	}
X	else {
X
X/* If not a clear code, then must be data: save same as CurCode and InCode */
X
X	    CurCode = InCode = Code;
X
X/* If greater or equal to FreeCode, not in the hash table yet;
X * repeat the last character decoded
X */
X
X	    if (CurCode >= FreeCode) {
X		CurCode = OldCode;
X		OutCode[OutCount++] = FinChar;
X	    }
X
X/* Unless this code is raw data, pursue the chain pointed to by CurCode
X * through the hash table to its end; each code in the chain puts its
X * associated output code on the output queue.
X */
X
X	    while (CurCode > BitMask) {
X		OutCode[OutCount++] = Suffix[CurCode];
X		CurCode = Prefix[CurCode];
X	    } 
X
X/* The last code in the chain is treated as raw data. */
X
X	    FinChar = CurCode & BitMask;
X	    OutCode[OutCount++] = FinChar;
X
X/* Now we put the data out to the Output routine.
X * It's been stacked LIFO, so deal with it that way...
X */
X
X	    for (i = OutCount - 1; i >= 0; i--)
X		AddToPixel(OutCode[i]);
X	    OutCount = 0;
X
X/* Build the hash table on-the-fly. No table is stored in the file. */
X
X	    Prefix[FreeCode] = OldCode;
X	    Suffix[FreeCode] = FinChar;
X	    OldCode = InCode;
X
X/* Point to the next slot in the table.  If we exceed the current
X * MaxCode value, increment the code size unless it's already 12.  If it
X * is, do nothing: the next code decompressed better be CLEAR
X */
X
X	    FreeCode++;
X	    if (FreeCode >= MaxCode) {
X		if (CodeSize < 12) {
X		    CodeSize++;
X		    MaxCode *= 2;
X		    ReadMask = (1 << CodeSize) - 1;
X		}
X	    }
X	}
X	Code = ReadCode();
X    }
X
X    free(Raster);
X
X    fprintf(stderr, "done.\n");
X
X    if (!(fp = fopen(outfname, "w")))
X	error("%s: can't create %s.\n", outfname);
X
X#ifdef notdefSS
X/* SS: Pixrect Rasterfile output code. */
X    fprintf(stderr, "Writing Sun Rasterfile: %s...", outfname);
X    if (pr_dump(Output, fp, &Colormap, RT_STANDARD, 0) == PIX_ERR)
X	error("%s: error writing Sun Rasterfile: %s\n", outfname);
X#endif notdefSS
X/* PBMS: PBM output code. */
X    pbm_writepbm(stdout, bits, Width, Height);
X
X    fclose(fp);
X
X    fprintf(stderr, "done.\n");
X}
X
X
X/* Fetch the next code from the raster data stream.  The codes can be
X * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
X * maintain our location in the Raster array as a BIT Offset.  We compute
X * the byte Offset into the raster array by dividing this by 8, pick up
X * three bytes, compute the bit Offset into our 24-bit chunk, shift to
X * bring the desired code to the bottom, then mask it off and return it. 
X */
XReadCode()
X{
Xint RawCode, ByteOffset;
X
X    ByteOffset = BitOffset / 8;
X    RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
X    if (CodeSize >= 8)
X	RawCode += (0x10000 * Raster[ByteOffset + 2]);
X    RawCode >>= (BitOffset % 8);
X    BitOffset += CodeSize;
X    return(RawCode & ReadMask);
X}
X
X
XAddToPixel(Index)
Xu_char Index;
X{
X#ifdef notdefSS
X    *(Image + YC * Width + XC) = Index;
X#endif notdefSS
X/* PBMS: Store a pixel. */
X    bits[YC][XC] = Index;
X
X/* Update the X-coordinate, and if it overflows, update the Y-coordinate */
X
X    if (++XC == Width) {
X
X/* If a non-interlaced picture, just increment YC to the next scan line. 
X * If it's interlaced, deal with the interlace as described in the GIF
X * spec.  Put the decoded scan line out to the screen if we haven't gone
X * past the bottom of it
X */
X
X	XC = 0;
X	if (!Interlace) YC++;
X	else {
X	    switch (Pass) {
X		case 0:
X		    YC += 8;
X		    if (YC >= Height) {
X			Pass++;
X			YC = 4;
X		    }
X		break;
X		case 1:
X		    YC += 8;
X		    if (YC >= Height) {
X			Pass++;
X			YC = 2;
X		    }
X		break;
X		case 2:
X		    YC += 4;
X		    if (YC >= Height) {
X			Pass++;
X			YC = 1;
X		    }
X		break;
X		case 3:
X		    YC += 2;
X		break;
X		default:
X		break;
X	    }
X	}
X    }
X}
SHAR_EOF
if test 13188 -ne "`wc -c < 'giftopbm.c'`"
then
	echo shar: error transmitting "'giftopbm.c'" '(should have been 13188 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'giftopbm.1'" '(952 characters)'
if test -f 'giftopbm.1'
then
	echo shar: will not over-write existing file "'giftopbm.1'"
else
sed 's/^X//' << \SHAR_EOF > 'giftopbm.1'
X.TH giftopbm 1 "29 August 1988"
X.SH NAME
Xgiftopbm - convert GIF files into portable bitmaps
X.SH SYNOPSIS
Xgiftopbm [giffile]
X.SH DESCRIPTION
XReads a GIF file as input.
XProduces a portable bitmap as output.
X.LP
XNote that there is currently no pbmtogif tool.
X.LP
XAlso note that, since PBM only supports monochrome, this tool is
Xuseless for 99% of the GIF files out there.
X.SH BUGS
XThis tool has not been tested in its PBM form AT ALL.
XHowever, in the original gif2ras form, it worked fine.
X.SH "SEE ALSO"
Xpbm(5)
X.SH AUTHOR
XTrivial modifications to produce PBM by Jef Poskanzer.  Otherwise:
X
XCopyright (c) 1988 by Patrick J. Naughton
X(naughton@wind.sun.com)
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted,
Xprovided that the above copyright notice appear in all copies and that
Xboth that copyright notice and this permission notice appear in
Xsupporting documentation. 
SHAR_EOF
if test 952 -ne "`wc -c < 'giftopbm.1'`"
then
	echo shar: error transmitting "'giftopbm.1'" '(should have been 952 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0