delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/06/19/13:01:26

Xref: news-dnh.mv.net comp.os.msdos.djgpp:446
Path: news-dnh.mv.net!mv!news.sprintlink.net!cs.utexas.edu!convex!not-for-mail
From: rosenkra AT convex DOT com (William Rosenkranz)
Newsgroups: comp.os.msdos.djgpp
Subject: zlib(3x) library (part01/01)
Date: 19 Jun 1995 00:16:52 -0500
Organization: Engineering, Convex Computer Corporation, Richardson, Tx USA
Lines: 1627
Nntp-Posting-Host: convex1.convex.com
Summary: stdio on compressed files
Keywords: unix compress stdio uncompress
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Dj-Gateway: from newsgroup comp.os.msdos.djgpp

zlib part01/01

zlib for atari ST (and MSDOS)
-----------------------------

[ excerpt from readme file ]

note: if you do not have or use compress, this is probably not for you...

zlib would be helpful with pagers like less. it would allow them to read
compressed files if they can't already do this. it is read only (will
not compress, just uncompress).

this was posted to alt.sources circa nov 1990. i thought it would be
useful so i ported it to TOS. it provides a stdio-like stream interface
for reading compressed files. the args are similar to "normal" stdio. i
ported it to TOS (Alcyon). it should work fine with sozobon, gcc, minix(?)
and whatever, though i have not tested it with these.

what it does: it provides a READ ONLY stream interface for compressed
files, i.e. those compressed which unix compress (of which there is, of
course, a TOS version). up to 16-bit compress is supported.
no support for "zfputc" or "zfputs" or "zprintf" is provided here. still,
this is very useful indeed. currently it might be limited to compressed
text files, at least with alcyon, though that will probably not be the
case with gcc. i also runs fine under unix.

included are:

	zfopen		open a compressed (or normal) file
	zfclose		closes compressed stream
	zfgetc		get a single char from stream (does cr-lf translation)
	zfgets		get a single line from stream
	zfeof		test for EOF on stream
	zfilter		for working with stdin

this library will handle 16-bit compressed files. it has been tested with
16-bit compress 4.3 for the atari ST:

	compress 4.3 88/12/26 08:00:00 don
	Options: Unix MAXBITS = 16

i have included an executable for zcat (the test program). see makefile
for how to run it. all included in this post are alcyon-compatible libraries
and aln index file (zlib.ndx). zlib.out is log of atari doindex command for
aln random libraries.

enjoy...

-bill rosenkranz
rosenkra AT convex DOT com

------------------------------ cut here ------------------------------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by William Rosenkranz <rosenkra AT det_hp> on Mon Jun 19 00:59:17 1995
#
# This archive contains:
#	zlib	
#
# Error checking via sum(1) will be performed.

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

if sum -r </dev/null >/dev/null 2>&1
then
	sumopt='-r'
else
	sumopt=''
fi

echo mkdir - zlib
mkdir zlib

echo x - zlib/ascii
cat >zlib/ascii <<'@EOF'
#ifndef _ZLIB_H
#define _ZLIB_H 1

#include <proto.h>			/* for _PROTO macro... */

#ifdef ALCYON
# ifndef void
#  define void		int
# endif
#endif

#ifdef MSDOS
# define PC_HUGE	huge		/* Microsoft C and contemptibles */
#else
# define PC_HUGE
#endif

#define ZEXT		".Z"		/* "normal" compressed file ext */

#ifdef __arm
# undef ZEXT
# define ZEXT		"-z"
#endif

#define Z_BITS		16
#define Z_MAXBUF	256

/*
 *	the major data structure, ZFILE
 */
typedef struct zfiletype
{
	FILE	       *file;
	int		flags;
	int     	n_bits;		/* number of bits/code */
	int     	maxbits;	/* user settable max # bits/code */
	long    	maxcode;	/* maximum code, given n_bits */
	long    	free_ent;	/* first unused entry */
	int     	block_compress;
	int     	clear_flg;

	long    	stackp;
	long    	finchar;
	long    	code,
	        	oldcode,
	        	incode;
	int     	offset,
	        	size;
	unsigned char   buf[Z_BITS];	/* Passed to getcode */
	unsigned char PC_HUGE *tab_suffixof;
					/* There is a flag bit to say whether */
	long PC_HUGE   *tab_prefixof;	/* these have been allocated.         */
	int     	init;

	int     	bufput,
	        	bufget,
	        	bufend;
	unsigned char   buff[Z_MAXBUF];
	int     	c1,
	        	c2;
	int     	zeof;

} ZFILE;


/*
 *	fcn prototypes...
 */
ZFILE  *zfopen _PROTO((char *fileptr, char *how));
void    zfclose _PROTO((ZFILE *z));
ZFILE  *zfilter _PROTO((FILE *f));
int     zfgetc _PROTO((ZFILE *z));
int     zfeof _PROTO((ZFILE *z));
char   *zfgets _PROTO((char *line, int len, ZFILE *zfp));

#endif /*_ZLIB_H*/
@EOF
set `sum $sumopt <zlib/ascii`; if test $1 -ne 16934
then
	echo ERROR: zlib/ascii checksum is $1 should be 16934
fi

chmod 644 zlib/ascii

echo x - zlib/readme.1st
cat >zlib/readme.1st <<'@EOF'

this is a replacement for stdio functions fopen, fclose, fgetc, fgets
that will read (and decompress) files compressed with the unix
compress program (.Z suffix). it is known to run under both unix and
with gcc on the atari ST.

it could be incorporated into a pager (like less). this would be
especially helpful with manpages that tend to eat up a fair amount
of space. compress usually will compress files to 40-50% of their
original size. note that if file system fragment sizes are 8kb,
and your files are all smaller than this, this would not be a win
since the file would still eat up 8kb of space, even if it was 1
byte in size.

anyway, i ported this to unix and the atari ST. it was originally
written for DOS, so it should report back.

-bill rosenkranz
rosenkra AT convex DOT com
@EOF
set `sum $sumopt <zlib/readme.1st`; if test $1 -ne 49785
then
	echo ERROR: zlib/readme.1st checksum is $1 should be 49785
fi

chmod 644 zlib/readme.1st

echo x - zlib/makefile
cat >zlib/makefile <<'@EOF'
# makefile for zlib as a library
#
# date:    Sat Nov 17 14:27:48 1990
# version: 1.0
#
SECT		= 3
SUBSECT		= x
LIBTARG		= zlib
A		=.a
MANPAGE		= zlib.$(SECT)$(SUBSECT)
MANSRC		= zlib.man
H_FILE		= zlib.h
HEADERS		= zdef.h
OBJS		= zfopen.o zfclose.o zfgets.o zfeof.o zfilter.o zfgetc.o
SRCS		= zfopen.c zfclose.c zfgets.c zfeof.c zfilter.c zfgetc.c
OTHERS		= readme $(MANSRC) makefile $(H_FILE) $(HEADERS)

CC		= cc -Aa
OPT		= -O
CFLAGS		= $(OPT)
LDFLAGS		=
LIBS		=

#SLASH		=\\
#LIBDIR		= c:\usr\lib
#MANTOP		= c:\usr\man
#MANDIR		= $(MANTOP)$(SLASH)man$(SECT)
#CATDIR		= $(MANTOP)$(SLASH)cat$(SECT)
#INCDIR		= c:\usr\include
SLASH		=/
LIBDIR		= /mnt/rosenkra/lib
MANTOP		= /mnt/rosenkra/man
MANDIR		= $(MANTOP)$(SLASH)man$(SECT)
CATDIR		= $(MANTOP)$(SLASH)cat$(SECT)
INCDIR		= /mnt/rosenkra/include

TEST		= testzcat
EXE		=#.ttp

ZEXT		=.Z

INST_LIB	= cp -p
INST_H		= cp -p
INST_MAN	= cp -p

RM		= rm -f
RANLIB		= ranlib


# directions...
#
directions:
		@echo type "make initial" to built $(LIBTARG) the first time
		@echo type "make all" to built $(LIBTARG)
		@echo type "make install" to built/install $(LIBTARG)
		@echo type "make test" to make test for $(LIBTARG)
		@echo type "make runtest" to test $(LIBTARG)
		@echo type "make clean" to remove objects
		@echo type "make clobber" to remove objects and $(LIBTARG)


# main library target (during development)...
#
all:		$(LIBTARG)$(A)

$(LIBTARG)$(A):	$(OBJS)
		$(AR) rv $@ $?
		$(RANLIB) $(LIBTARG)$(A)


# main target the first time...
#
initial:	$(OBJS)
		$(AR) rv $(LIBTARG)$(A) $(OBJS)
		$(RANLIB) $(LIBTARG)$(A)


# manpage
#
manpage:	$(MANPAGE)

$(MANPAGE):	$(MANSRC)
		nroff -man $(MANSRC)|ul -t dumb|cat -s >$(MANPAGE)



# install lib, header, and manpage...
#
install:	install_lib install_h install_man

install_lib:	# $(LIBTARG)$(A)
		$(INST_LIB) $(LIBTARG)$(A) $(LIBDIR)$(SLASH)$(LIBTARG)$(A)
		$(RANLIB) $(LIBDIR)$(SLASH)$(LIBTARG)$(A)
		touch install_lib

install_man:
		$(INST_MAN) $(MANSRC) $(MANDIR)$(SLASH)$(MANPAGE)
		$(INST_MAN) $(MANPAGE) $(CATDIR)$(SLASH)$(MANPAGE)
		touch install_man

install_h:
		$(INST_H) $(H_FILE) $(INCDIR)$(SLASH)$(H_FILE)
		touch install_h



# make a test program for the lib...
#
test:		$(LIBTARG)$(A) $(TEST).o
		$(CC) $(LDFLAGS) -o $(TEST) $(TEST).o $(LIBTARG)$(A) $(LIBS)
		@echo done making $(LIBTARG) test program.
		@echo execute with "make runtest".

runtest:
		@echo test ascii text file: ascii
		$(TEST)$(EXE) ascii >ascii.out
		cmp ascii ascii.out
#		rm ascii.out
		@echo test compressed file: asciic.z
		cp ascii asciic
		compress asciic
		$(TEST)$(EXE) asciic >asciic.out
		cmp ascii asciic.out
#		rm asciic$(ZEXT) asciic.out
		@echo test completed.

# others...
#
clean:
		$(RM) *.o errs core

clobber:	clean
		$(RM) $(LIBTARG)$(A)




# dependencies...
#
$(HEADERS):	$(H_FILE)
		touch $(HEADERS)

$(OBJS):	$(HEADERS)

$(TEST).o:	$(H_FILE) $(TEST).c
@EOF
set `sum $sumopt <zlib/makefile`; if test $1 -ne 27460
then
	echo ERROR: zlib/makefile checksum is $1 should be 27460
fi

chmod 644 zlib/makefile

echo x - zlib/manifest
cat >zlib/manifest <<'@EOF'
total 59
-rw-------  0 0    1615 Nov 17 04:18 ascii	test file
-rw-------  0 0    3110 Nov 17 15:22 makefile	look here before leaping...
-rw-------  0 0    1116 Nov 17 15:38 manifest	this file
-rw-------  0 0    1335 Nov 17 15:16 readme	look here, too...
-rw-------  0 0     937 Nov 17 15:27 zcat.c	test program
-rwx------  0 0   15800 Nov 17 15:28 zcat.ttp	its executable
-rw-------  0 0    3992 Nov 17 15:27 zdef.h	local header
-rw-------  0 0     497 Nov 17 15:27 zfclose.c	src...
-rw-------  0 0     384 Nov 17 15:27 zfeof.c	"
-rw-------  0 0    6404 Nov 17 15:27 zfgetc.c	"
-rw-------  0 0     736 Nov 17 15:27 zfgets.c	"
-rw-------  0 0    1520 Nov 17 15:27 zfilter.c	"
-rw-------  0 0    2358 Nov 17 15:27 zfopen.c	"
-rw-------  0 0    7628 Nov 17 15:30 zlib	ar68 library (alcyon,aln)
-rw-------  0 0    2552 Nov 17 15:33 zlib.3x	formatted manpage
-rw-------  0 0    1615 Nov 17 15:26 zlib.h	for include your dir
-rw-------  0 0    2527 Nov 17 15:26 zlib.man	nroff manpage
-rw-------  0 0     204 Nov 17 15:31 zlib.ndx	aln index
-rw-------  0 0     606 Nov 17 15:31 zlib.out	doindex output
@EOF
set `sum $sumopt <zlib/manifest`; if test $1 -ne 7375
then
	echo ERROR: zlib/manifest checksum is $1 should be 7375
fi

chmod 644 zlib/manifest

echo x - zlib/readme
cat >zlib/readme <<'@EOF'
zlib for atari ST
-----------------

note: if you do not have or use compress, this is probably not for you...

this was posted to alt.sources circa nov 1990. i thought it would be
useful so i ported it to TOS. it provides a stdio-like stream interface
for reading compressed files. the args are similar to "normal" stdio. i
ported it to TOS (Alcyon). it should work fine with sozobon, gcc, minix(?)
and whatever, though i have not tested it with these.

what it does: it provides a READ ONLY stream interface for compressed
files, i.e. those compressed which unix compress (of which there is, of
course, a TOS version). up to 16-bit compress is supported. to write
compressed files, you can do something like:

	write_to_tmp_file (buf, tmpfilename);
	sprintf (cmd, "compress %s", tmpfilename);
	system (cmd);

no support for "zfputc" or "zfputs" or "zprintf" is provided here. still,
this is very useful indeed. currently it might be limited to compressed
text files, at least with alcyon, though that will probably not be the
case with gcc. i also runs fine under unix.

included are:

	zfopen		open a compressed (or normal) file
	zfclose		closes compressed stream
	zfgetc		get a single char from stream (does cr-lf translation)
	zfgets		get a single line from stream
	zfeof		test for EOF on stream
	zfilter		for working with stdin

note that you MUST zfclose a file to free memory. exit/_exit will not do
this for you (obviously).

i have not tried working with zfilter for reading stdin. this is really
compiler/library/shell dependent since stdin must be read binary (the cr-lf
issue). my environment does not permit this (gulam), at least not to my
knowledge.

zfopen will currently only open compressed ascii files (DOS, TOS). zfgetc
will check for a cr-lf and return only the linefeed. if the file is compressed,
it normally has a .z extension. if not, zfopen will check to see if the file
is in fact compressed. if not, zfgetc/zfgets will still read it using fgetc,
though the read will be slower than using fgetc directly.

i have not tested zfgets but it looks ok, more or less. see original author's
comments in the src.

this library will handle 16-bit compressed files. it has been tested with
16-bit compress 4.3 for the atari ST:

	compress 4.3 88/12/26 08:00:00 don
	Options: Unix MAXBITS = 16

makefile will build a library ("make initial" first time, then "make all"
during development) and a version of zcat for testing ("make test"). to
run the tests, do "make runtest" which uses file "ascii" for the tests.
you will need compress(1) and cmp(1) to test.

i have included an executable for zcat (the test program). see makefile
for how to run it. all included in this post are alcyon-compatible libraries
and aln index file (zlib.ndx). zlib.out is log of atari doindex command for
aln random libraries.

enjoy...

-bill rosenkranz
rosenkra%c1yankee AT convex DOT com

@EOF
set `sum $sumopt <zlib/readme`; if test $1 -ne 47457
then
	echo ERROR: zlib/readme checksum is $1 should be 47457
fi

chmod 644 zlib/readme

echo x - zlib/testzcat.c
cat >zlib/testzcat.c <<'@EOF'
/*
 *	test zlib package. this is more or less zcat
 */

#include "zlib.h"

/* Written so it can be either included or linked in */
/*#include "zlib.c"*/

#ifndef __STDC__
int     main (argc, argv)
int     argc;
char   *argv[];
#else
int     main (int argc, char **argv)
#endif
{
	char   *myname;
	ZFILE  *in;
	int     i,
	        c;

#ifdef ALCYON
	myname = "testzcat";
#else
	myname = argv[0];
#endif

	if (argc == 1)
	{
		in = zfilter (stdin);
		for (c = zfgetc (in); c != EOF; putchar (c), c = zfgetc (in))
			;
		zfclose (in);
	}
	else if (argc > 1)
	{
		for (i = 1; i < argc; i++)
		{
			in = zfopen (argv[i], "r");
			if (in != (ZFILE *) NULL)
			{
				for (c = zfgetc (in); c != EOF;
				putchar (c), c = zfgetc (in))
					;
				zfclose (in);
			}
			else
			{
				fprintf (stderr, "%s: cannot open %s\n",
					myname, argv[i]);
			}
		}
	}

	exit (0);
}
@EOF
set `sum $sumopt <zlib/testzcat.c`; if test $1 -ne 59788
then
	echo ERROR: zlib/testzcat.c checksum is $1 should be 59788
fi

chmod 644 zlib/testzcat.c

echo x - zlib/zdef.h
cat >zlib/zdef.h <<'@EOF'
#undef DEBUG	/*1*/
#undef MONITOR_CRLF

/*
 *	zdef.h
 */

/*
 *	These wondrous debugging macros helped me find the nasty bug which
 *	only manifested itself on msdos -- stackp has to be a long on msdos
 *	because the array it is indexing is 'huge' ...
 */
#ifdef DEBUG
int	debug = 1;
# define TRACT(lev, stmnt)	if (lev <= debug) fprintf(stderr, "%d: %s\n", __LINE__, #stmnt);
# define TRACE(lev, stmnt)	if (lev <= debug) fprintf(stderr, "%d: %s\n", __LINE__, #stmnt); stmnt
# define TRACA(lev, stmnt)	stmnt; if (lev <= debug) fprintf(stderr, "%d: %s\n", __LINE__, #stmnt);
# define TRACL(lev, var)	if (lev <= debug) fprintf(stderr, "%d: %s <- %ld\n", __LINE__, #var, var);
#else
# define TRACT(lev, stmnt)
# define TRACE(lev, stmnt) stmnt
# define TRACA(lev, stmnt) stmnt
# define TRACL(lev, var)
#endif


/* 
 *
 * Originally:
 *
 * compress.c - File compression ala IEEE Computer, June 1984.
 *
 * Authors:    Spencer W. Thomas       (decvax!harpo!utah-cs!utah-gr!thomas)
 *             Jim McKie               (decvax!mcvax!jim)
 *             Steve Davies            (decvax!vax135!petsd!peora!srd)
 *             Ken Turkowski           (decvax!decwrl!turtlevax!ken)
 *             James A. Woods          (decvax!ihnp4!ames!jaw)
 *             Joe Orost               (decvax!vax135!petsd!joe)
 *
 * $Header: zlib.c,v 4.1 90/11/12 14:52:24 gtoal Release $
 *
 * Graham Toal, 3rd September 1988.  My changes released to public domain.
 *                                   Updated Nov 90.
 *
 * The original decompress has been restructured so that data can be
 * fetched on demand a byte at a time.  This lets it be used as a filter
 * for programs which read large data files - you do not need the disk
 * space to decompress the input files first.
 *
 * (Incidentally, programs reading data off floppies will be speeded up
 *  because decompression is always faster than the equivalent amount
 *  of disk I/O).
 *
 * This implementation supplies 'z' versions of fopen, fputc, feof and fclose
 * to be used as direct substitutes for the originals; it would be cleaner
 * and more transparent if the decompress filter were hidden under the
 * real stdio procedures.  An extra call zfilter() is supplied to convert
 * an already-opened stream into a z-stream: see the example at the end
 * of this file.
 *
 * If a file opened by zfopen() was not compressed, the files contents are
 * still recovered correctly at the low expense of an extra procedure call
 * per byte.  This makes the routines more generally usable - they can be
 * left in production programs which can be speeded up in the field by
 * compressing selected input files(*); also, files can be compressed or
 * not selectively depending on whether the compression makes them
 * smaller or not - code accessing the files does not need to know.
 *
 * [(*) reading from a compressed file off floppy disk is faster than
 * reading from an uncompressed file. This probably isn't true of
 * hard disks though.]
 *
 * BUGS: Opening a file "r" will not do CR/LF processing on computers with
 *       this file structure.
 */


#if defined(__unix) && !defined(unix)
#define unix 1
#endif

#include <stdio.h>
#include <string.h>
#ifdef __STDC__
# include <stdlib.h>
#else
# define size_t		int
#endif
#include <ctype.h>

#if defined(MSDOS)
# include <malloc.h>
#elif ! defined(unix) && ! defined(__unix)
extern char    *malloc ();
#endif

#ifndef min
# define min(a,b)	((a>b) ? b : a)
# endif
#define HSIZE		69001L		/* 95% occupancy */

/*
 *	the next two codes should not be changed lightly, as they must not
 *	lie within the contiguous general code space.
 */
#define FIRST		257L		/* first free entry */
#define CLEAR		256L		/* table clear output code */

#define BIT_MASK        0x1f
#define BLOCK_MASK      0x80
#define INIT_BITS       9		/* initial number of bits/code */

#define CHECK_GAP	10000L		/* ratio check interval */

#include "zlib.h"

#define NOT_COMPRESSED	1
#define ALLOCATED	2


/* end of zdef.h */
@EOF
set `sum $sumopt <zlib/zdef.h`; if test $1 -ne 29204
then
	echo ERROR: zlib/zdef.h checksum is $1 should be 29204
fi

chmod 644 zlib/zdef.h

echo x - zlib/zfclose.c
cat >zlib/zfclose.c <<'@EOF'
#include "zdef.h"

/*------------------------------*/
/*	zfclose			*/
/*------------------------------*/
#ifndef __STDC__
void zfclose (z)
ZFILE *z;
#else
void zfclose (ZFILE *z)
#endif
{
	if (z == 0)
	        return;

	if (z->zeof)
	{
		if ((z->flags & ALLOCATED) != 0)
		{
#ifdef MSDOS
			hfree (z->tab_suffixof);
			hfree (z->tab_prefixof);
#else
			free (z->tab_suffixof);
			free (z->tab_prefixof);
#endif
			z->flags &= (~ALLOCATED);
		}
	}
	free (z);
}



@EOF
set `sum $sumopt <zlib/zfclose.c`; if test $1 -ne 31489
then
	echo ERROR: zlib/zfclose.c checksum is $1 should be 31489
fi

chmod 644 zlib/zfclose.c

echo x - zlib/zfeof.c
cat >zlib/zfeof.c <<'@EOF'
#include "zdef.h"

/*------------------------------*/
/*	zfeof			*/
/*------------------------------*/
#ifndef __STDC__
int zfeof (z)
ZFILE *z;
#else
int zfeof (ZFILE *z)
#endif
{
	if ((z->flags & NOT_COMPRESSED) != 0)
	{
		if      (z->c1 != EOF)
		{
			        return ((int) (0 != 0));
		}
		return ((int) feof (z->file));
	}
	return ((int) (z->zeof));
}

@EOF
set `sum $sumopt <zlib/zfeof.c`; if test $1 -ne 26246
then
	echo ERROR: zlib/zfeof.c checksum is $1 should be 26246
fi

chmod 644 zlib/zfeof.c

echo x - zlib/zfgetc.c
cat >zlib/zfgetc.c <<'@EOF'
#include "zdef.h"

#ifdef __STDC__
static void     decompress_more(register ZFILE *z);
static long     getcode(register ZFILE *z);
#else
static void     decompress_more();
static long     getcode();
#endif

#define CR		0x0D
#define LF		0x0A

/*------------------------------*/
/*	zfgetc			*/
/*------------------------------*/
#ifndef __STDC__
int zfgetc (z)
ZFILE *z;
#else
int zfgetc (ZFILE *z)
#endif
{
	int     c;

	/* 
	 *   If buffer empty, and not end-of-file, call decompress_more();
	 *   return next in buffer.  
	 */
again:
	if ((z->flags & NOT_COMPRESSED) != 0)
	{
		if ((c = z->c1) >= 0)
		{
			z->c1 = z->c2;
			z->c2 = EOF;

			return ((int) c);
		}
again2:
		c = fgetc (z->file);
#if defined(ALCYON)
		/*
		 *   see note below...
		 */
		if (c == CR)
			goto again2;
#endif
		return ((int) c);
	}
	if ((z->bufget == z->bufput) && (!z->zeof))
	{
		decompress_more (z);
	}
	z->zeof = (z->bufput == z->bufget);
	if (z->zeof)
	{
		if ((z->flags & ALLOCATED) != 0)
		{
#ifdef MSDOS
			hfree (z->tab_suffixof);
			hfree (z->tab_prefixof);
#else
			free (z->tab_suffixof);
			free (z->tab_prefixof);
#endif
			z->flags &= (~ALLOCATED);
		}
		return ((int) EOF);
	}
	c = z->buff[z->bufget];
	z->bufget++;

#ifdef MONITOR_CRLF
	if (c == CR)
		fprintf (stderr, "\n*** CR IN INPUT ***\n");
	if (c == LF)
		fprintf (stderr, "\n*** LF IN INPUT ***\n");
#endif

#if defined(ALCYON)
	/*
	 *   at least with alcyon, fputc will write a cr-nl if c is nl so
	 *   skip past the cr we read. other libraries may or may not have
	 *   this problem...
	 */
	if (c == CR)
		goto again;
#endif

	return ((int) c);
}



/*------------------------------*/
/*	decompress_more		*/
/*------------------------------*/
#ifndef __STDC__
static void decompress_more (z)
register ZFILE *z;
#else
static void decompress_more (register ZFILE *z)
#endif
{
	z->bufput = 0;
	z->bufget = 0;

	if (z->init != 0)
		goto resume;

	z->init   = 1;
	z->offset = 0;
	z->size   = 0;

#ifdef MSDOS
	z->tab_suffixof =
	    (unsigned char PC_HUGE *) halloc (HSIZE, sizeof (unsigned char));
	z->tab_prefixof =
		(long PC_HUGE *) halloc (HSIZE, sizeof (long));
#else
	z->tab_suffixof =
	    (unsigned char *) malloc ((size_t) HSIZE * sizeof (unsigned char));
	z->tab_prefixof = (long *) malloc ((size_t) HSIZE * sizeof (long));
#endif
	z->flags |= ALLOCATED;

	z->n_bits  = INIT_BITS;
	z->maxcode = ((1L << (z->n_bits)) - 1L);
	for (z->code = 255L; z->code >= 0L; z->code--)
	{
		z->tab_prefixof[z->code] = 0L;
		z->tab_suffixof[z->code] = (unsigned char) z->code;
	}
	z->free_ent = ((z->block_compress) ? FIRST : 256L);

	z->finchar = z->oldcode = getcode (z);
	if (z->oldcode == -1L)
		return;			/* EOF already? */
	if (z->finchar < 0L || z->finchar >= 256L)
		fprintf (stderr, "****\n");
	z->buff[z->bufput] = (char) (z->finchar & 0xff);
	z->bufput++;

	z->stackp = 1L << Z_BITS;	/* The 1L is for DOS huge arrays */

	while ((z->code = getcode (z)) != EOF)
	{
		if ((z->code == CLEAR) && z->block_compress)
		{
			for (z->code = 255; z->code >= 0; z->code--)
				z->tab_prefixof[z->code] = 0;
			z->clear_flg = 1;
			z->free_ent  = FIRST - 1;
			if ((z->code = getcode (z)) == EOF)
				break;	/* O, untimely death! */
		}			/* if */
		z->incode = z->code;
		if (z->code >= z->free_ent)
		{
			z->tab_suffixof[z->stackp] = (unsigned char)z->finchar;
			z->stackp                 += 1L;
			z->code                    = z->oldcode;
		}
		while (z->code >= 256L)
		{
			z->tab_suffixof[z->stackp] = z->tab_suffixof[z->code];
			z->stackp                 += 1L;
			z->code                    = z->tab_prefixof[z->code];
		}
		z->finchar                 = z->tab_suffixof[z->code];
		z->tab_suffixof[z->stackp] = (unsigned char) z->finchar;
		z->stackp                 += 1L;
		do
		{
			long    tmp;

			z->stackp           -= 1L;
			tmp                  = z->tab_suffixof[z->stackp];
			z->buff[z->bufput++] = (unsigned char) (tmp & 255L);
			if (z->bufput == z->bufend)
			{
				/*
				 *   Logically a setjmp/longjump, but this
				 *   is more portable
				 */
				return;

				/*
				 *   jumped to here -- is jumping into a
				 *   loop safe?
				 *   - or should I use jumps for the loop too?
				 */
resume:				;
			}		/* if */

		} while (z->stackp > (1L << Z_BITS));
		/* ^ This is why I changed stackp from a pointer. */
		/* Pointer comparisons can be dubious...          */

		if ((z->code = z->free_ent) < (1L << z->maxbits))
		{
			z->tab_prefixof[z->code] = z->oldcode;
			z->tab_suffixof[z->code] = (unsigned char) z->finchar;
			z->free_ent              = z->code + 1;
		}
		z->oldcode = z->incode;
	}				/* while */
}

static unsigned char    rmask[9] =
{
	0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
};


/*------------------------------*/
/*	getcode			*/
/*------------------------------*/
#ifndef __STDC__
static long getcode (z)
register ZFILE *z;
#else
static long getcode (register ZFILE *z)
#endif
{					/* Should be int!!! */
	register long   code;
	register long   r_off,
	                bits;
	register int    bp;

	bp = 0;
	if (z->clear_flg != 0 || z->offset >= z->size
	|| z->free_ent > z->maxcode)
	{
		if (z->free_ent > z->maxcode)
		{
			z->n_bits++;
			if (z->n_bits == z->maxbits)
			{
				z->maxcode = (1L << z->maxbits);
				/* won't get any bigger now */
			}
			else
			{
				z->maxcode = ((1L << (z->n_bits)) - 1L);
			}
		}
		if (z->clear_flg != 0)
		{
			z->n_bits    = INIT_BITS;
			z->maxcode   = ((1L << (z->n_bits)) - 1L);
			z->clear_flg = 0;
		}
		z->size = fread (z->buf, 1, (size_t) z->n_bits, z->file);
		if (z->size <= 0)
		{
			fclose (z->file);
			return ((long) EOF);	/* end of file */
		}
		z->offset = 0;
		z->size   = (z->size << 3) - (z->n_bits - 1);
	}
	r_off = z->offset;
	bits  = z->n_bits;
	bp    = bp + ((int) r_off >> 3);
	r_off = r_off & 7;
	code  = ((long) z->buf[bp++] >> r_off);
	bits  = bits - 8 + r_off;
	r_off = 8 - r_off;		/* now, offset into code word */
	if (bits >= 8)
	{
		code  = code | ((long) z->buf[bp++] << r_off);
		r_off = r_off + 8;
		bits  = bits - 8;
	}
	code = code
	    | ((long)((long)(z->buf[bp]) & (long)rmask[bits]) << (long)r_off);
	z->offset = z->offset + z->n_bits;

	return ((long) code);
}


@EOF
set `sum $sumopt <zlib/zfgetc.c`; if test $1 -ne 34015
then
	echo ERROR: zlib/zfgetc.c checksum is $1 should be 34015
fi

chmod 644 zlib/zfgetc.c

echo x - zlib/zfgets.c
cat >zlib/zfgets.c <<'@EOF'
#include "zdef.h"

/*------------------------------*/
/*	zfgets			*/
/*------------------------------*/
#ifndef __STDC__
char *zfgets (line, len, zfp)
char   *line;
int     len;
ZFILE  *zfp;
#else
char *zfgets (char *line, int len, ZFILE *zfp)
#endif
{

/*
 *	I *hope* this is what fgets does - I only added it
 *	here when I came across a program that needed it; I'm
 *	including the '\n' in the string.
 */

	int     c,
	        pos = 0;

	for (;;)
	{
		c = zfgetc (zfp);
		if (c == EOF)
			return ((char *) NULL);

		c &= 255;
		line[pos] = (char) c;
		if (pos + 1 == len)	/* Too long! */
			break;
		pos++;
		if (c == '\n')
			break;
	}
	line[pos] = '\0';

	return ((char *) line);
}



@EOF
set `sum $sumopt <zlib/zfgets.c`; if test $1 -ne 49303
then
	echo ERROR: zlib/zfgets.c checksum is $1 should be 49303
fi

chmod 644 zlib/zfgets.c

echo x - zlib/zfilter.c
cat >zlib/zfilter.c <<'@EOF'
#include "zdef.h"

/*------------------------------*/
/*	zfilter			*/
/*------------------------------*/
#ifndef __STDC__
ZFILE *zfilter (f)
FILE   *f;
#else
ZFILE *zfilter (FILE *f)
#endif
{
	register ZFILE *z;

	z = (ZFILE *) malloc (sizeof (ZFILE));
	z->flags          = 0;
	z->maxbits        = Z_BITS;	/* user settable max # bits/code */
	z->free_ent       = 0;		/* first unused entry */
	z->block_compress = BLOCK_MASK;
	z->clear_flg      = 0;
	z->init           = 0;

	z->zeof           = (0 != 0);
	z->c1             = EOF;
	z->c2             = EOF;
	z->bufput         = 0;
	z->bufget         = 0;
	z->bufend         = Z_MAXBUF - 1;

	z->maxbits        = Z_BITS;	/* user settable max # bits/code */

	/*
	 *   Open input file
	 */
	z->file = f;
	if (z->file == (FILE *) NULL)
	{
		free (z);
		z = (ZFILE *) NULL;
	}

	/*
	 *   Check the magic number
	 */
	if (z != (ZFILE *) NULL)
	{
		z->c1 = fgetc (z->file);
		z->c2 = fgetc (z->file);
		if ((z->c1 != 0x1F) || (z->c2 != 0x9D))
		{
			z->flags |= NOT_COMPRESSED;
		}
	}
	if ((z == (ZFILE *) NULL) || ((z->flags & NOT_COMPRESSED) != 0))
		return ((ZFILE *) z);

	z->maxbits        = fgetc (z->file);	/* set -b from file */
	z->block_compress = z->maxbits & BLOCK_MASK;
	z->maxbits       &= BIT_MASK;

	if (z->maxbits > Z_BITS)
	{
		fprintf (stderr,
	"stdin compressed with %d bits; decompress can only handle %d bits\n",
			z->maxbits, Z_BITS);
		exit (0);
	}
	return ((ZFILE *) z);
}



@EOF
set `sum $sumopt <zlib/zfilter.c`; if test $1 -ne 39106
then
	echo ERROR: zlib/zfilter.c checksum is $1 should be 39106
fi

chmod 644 zlib/zfilter.c

echo x - zlib/zfopen.c
cat >zlib/zfopen.c <<'@EOF'
#include "zdef.h"

/*------------------------------*/
/*	zfopen			*/
/*------------------------------*/
#ifndef __STDC__
ZFILE *zfopen (fileptr, how)
char   *fileptr;
char   *how;
#else
ZFILE *zfopen (char *fileptr, char *how)
#endif
{
	ZFILE *z;



	/*
	 *   allocate space for the z structure
	 */
	z = (ZFILE *) malloc (sizeof (ZFILE));
	if (z == (ZFILE *) NULL)
	{
		return ((ZFILE *) z);
	}
	

	/*
	 *   set up the structure...
	 */
	z->flags          = 0;
	z->maxbits        = Z_BITS;	/* user settable max # bits/code */
	z->free_ent       = 0;		/* first unused entry */
	z->block_compress = BLOCK_MASK;
	z->clear_flg      = 0;
	z->init           = 0;

	z->zeof           = (0 != 0);
	z->c1             = EOF;
	z->c2             = EOF;
	z->bufput         = 0;
	z->bufget         = 0;
	z->bufend         = Z_MAXBUF - 1;

	z->maxbits        = Z_BITS;	/* user settable max # bits/code */



	/*
	 *   Open input file
	 */
	if (*how == 'r')
	{
#if defined(ALCYON)
		z->file = fopenb (fileptr, "r");
#elif defined(MSDOS) || defined(atarist)
		z->file = fopen (fileptr, "rb");
#else
		z->file = fopen (fileptr, "r");
#endif
		if (z->file == (FILE *) NULL)
		{
			char    tempfname[256];

			strcpy (tempfname, fileptr);
			strcat (tempfname, ZEXT);
#if defined(ALCYON)
			z->file = fopenb (tempfname, "r");
#elif defined(MSDOS) || defined(atarist)
			z->file = fopen (tempfname, "rb");
#else
			z->file = fopen (tempfname, "r");
#endif
		}
	}
	else
	{
		/*
		 *   No compressed output yet, if ever...
		 *   Compress the file explicitly once it has been written
		 */
#if defined(ALCYON)
		z->file = fopenb (fileptr, how);
#else
		z->file = fopen (fileptr, how);
#endif
		z->flags |= NOT_COMPRESSED;
	}
	if (z->file == (FILE *) NULL)
	{
		free (z);
		z = (ZFILE *) NULL;
	}

	/*
	 *   Check the magic number
	 */
	if ((z != (ZFILE *) NULL)
	&& ((fgetc (z->file) != 0x1F) || (fgetc (z->file) != 0x9D)))
	{
		z->flags |= NOT_COMPRESSED;
		fclose (z->file);
#ifdef ALCYON
		z->file = fopenb (fileptr, how);
#else
		z->file = fopen (fileptr, how);
#endif
		if (z->file == (FILE *) NULL)
		{
			free (z);
			z = (ZFILE *) NULL;
		}
	}
	if ((z == (ZFILE *) NULL) || ((z->flags & NOT_COMPRESSED) != 0))
		return ((ZFILE *) z);

	z->maxbits        = fgetc (z->file);	/* set -b from file */
	z->block_compress = z->maxbits & BLOCK_MASK;
	z->maxbits       &= BIT_MASK;

	if (z->maxbits > Z_BITS)
	{
		fprintf (stderr,
	"%s: compressed with %d bits; decompress can only handle %d bits\n",
			fileptr, z->maxbits, Z_BITS);
		exit (0);
	}

	return ((ZFILE *) z);
}


@EOF
set `sum $sumopt <zlib/zfopen.c`; if test $1 -ne 43246
then
	echo ERROR: zlib/zfopen.c checksum is $1 should be 43246
fi

chmod 644 zlib/zfopen.c

echo x - zlib/zlib.3x
cat >zlib/zlib.3x <<'@EOF'

 ZLIB(3X)                                                           ZLIB(3X)

 NAME
      zlib - stream interface to compress, read only

 SYNOPSIS
      #include <zlib.h>

      ZFILE *zfopen (fileptr, how)
      char *fileptr;
      char *how;

      ZFILE *zfilter (f)
      FILE *f;

      int zfgetc (z)
      ZFILE *z;

      int zfeof (z)
      ZFILE *z;

      void zfclose (z)
      ZFILE *z;

      char *zfgets (line, len, zfp)
      char *line;
      int len;
      ZFILE *zfp;

 DESCRIPTION
      This implementation supplies 'z' versions of fopen(3s), fputc(3s),
      feof(3s), and fclose(3s) to be used as direct substitutes for the
      originals; it would be cleaner and more transparent if the decompress
      filter were hidden under the real stdio procedures.  An extra call
      zfilter(3x) is supplied to convert an already-opened stream into a z-
      stream: see the example at the end of this file.  Note that on the
      Atari or MSDOS, depending on the shell, stdin may have been opened as
      an ASCII stream and hence these routines are useless.  A pre-existion
      stream MUST have been opened as a binary file.

      If a file opened by zfopen() was not compressed, the files contents
      are still recovered correctly at the low expense of an extra procedure
      call per byte.  This makes the routines more generally usable - they
      can be left in production programs which can be speeded up in the
      field by compressing selected input files (see NOTES); also, files can
      be compressed or not selectively depending on whether the compression
      makes them smaller or not - code accessing the files does not need to
      know.

 NOTES
      Reading from a compressed file off floppy disk is faster than reading
      from an uncompressed file.  This probably isn't true of hard disks

                                    - 1 -          Formatted:  June 18, 1995

 ZLIB(3X)                                                           ZLIB(3X)

      though.

      The original decompress has been restructured so that data can be
      fetched on demand a byte at a time.  This lets it be used as a filter
      for programs which read large data files - you do not need the disk
      space to decompress the input files first.

      Incidentally, programs reading data off floppies will be speeded up
      because decompression is always faster than the equivalent amount of
      disk I/O.

 BUGS
      Opening a file "r" will not do CR/LF processing on computers with this
      file structure.

 SEE ALSO
      intro(3S), fopen(3S)

 AUTHOR
      Graham Toal, 3rd September 1988.
      My changes released to public domain.
      Updated Nov 90.

      Modified for Atari ST (Alcyon C and GNU C) by Bill Rosenkranz

                                    - 2 -          Formatted:  June 18, 1995

@EOF
set `sum $sumopt <zlib/zlib.3x`; if test $1 -ne 4287
then
	echo ERROR: zlib/zlib.3x checksum is $1 should be 4287
fi

chmod 644 zlib/zlib.3x

echo x - zlib/zlib.h
cat >zlib/zlib.h <<'@EOF'
#ifndef _ZLIB_H
#define _ZLIB_H 1

/*
 *	header for for zlib (compress file i/o utilities)
 */

#include <stdio.h>

#if defined(MSDOS) && !defined(__GNUC__)
# define PC_HUGE	huge		/* Microsoft C and contemptibles */
#else
# define PC_HUGE
#endif

#if defined(unix) || defined(__unix)
#define ZEXT		".Z"		/* "normal" compressed file ext */
#else
#define ZEXT		"Z"		/* "normal" compressed file ext */
#endif

#ifdef __arm
# undef ZEXT
# define ZEXT		"-z"
#endif

#define Z_BITS		16
#define Z_MAXBUF	256



/*
 *	the major data structure, ZFILE
 */
typedef struct zfiletype
{
	FILE	       *file;
	int		flags;
	int     	n_bits;		/* number of bits/code */
	int     	maxbits;	/* user settable max # bits/code */
	long    	maxcode;	/* maximum code, given n_bits */
	long    	free_ent;	/* first unused entry */
	int     	block_compress;
	int     	clear_flg;

	long    	stackp;
	long    	finchar;
	long    	code,
	        	oldcode,
	        	incode;
	int     	offset,
	        	size;
	unsigned char   buf[Z_BITS];	/* Passed to getcode */
	unsigned char PC_HUGE *tab_suffixof;
					/* There is a flag bit to say whether*/
	long PC_HUGE   *tab_prefixof;	/* these have been allocated.        */
	int     	init;

	int     	bufput,
	        	bufget,
	        	bufend;
	unsigned char   buff[Z_MAXBUF];
	int     	c1,
	        	c2;
	int     	zeof;

} ZFILE;


/*
 *	function prototypes...
 */
#if defined(__STDC__)
ZFILE  *zfopen(char *fileptr, char *how);
void    zfclose(ZFILE *z);
ZFILE  *zfilter(FILE *f);
int     zfgetc(ZFILE *z);
int     zfeof(ZFILE *z);
char   *zfgets(char *line, int len, ZFILE *zfp);
#else
ZFILE  *zfopen();
void    zfclose();
ZFILE  *zfilter();
int     zfgetc();
int     zfeof();
char   *zfgets();
#endif

#endif /*_ZLIB_H*/
@EOF
set `sum $sumopt <zlib/zlib.h`; if test $1 -ne 8775
then
	echo ERROR: zlib/zlib.h checksum is $1 should be 8775
fi

chmod 644 zlib/zlib.h

echo x - zlib/zlib.man
sed 's/^@//' >zlib/zlib.man <<'@EOF'
@.TH ZLIB 3X
@.SH NAME
zlib \- stream interface to compress, read only
@.SH SYNOPSIS
@.B "#include <zlib.h>"
@.sp
@.B "ZFILE *zfopen"
@.BI ( fileptr ,
@.IB how )
@.br
@.B char
@.BI * fileptr ;
@.br
@.B char
@.BI * how ;
@.sp
@.B "ZFILE *zfilter"
@.BI ( f )
@.br
@.B FILE
@.BI * f ;
@.sp
@.B "int zfgetc"
@.BI ( z )
@.br
@.B ZFILE
@.BI * z ;
@.sp
@.B "int zfeof"
@.BI ( z )
@.br
@.B ZFILE
@.BI * z ;
@.sp
@.B "void zfclose"
@.BI ( z )
@.br
@.B ZFILE
@.BI * z ;
@.sp
@.B "char *zfgets"
@.BI ( line ,
@.IB len ,
@.IB zfp )
@.br
@.B char
@.BI * line ;
@.br
@.B int
@.IB len ;
@.br
@.B ZFILE
@.BI * zfp ;
@.sp
@.SH DESCRIPTION
This implementation supplies 'z' versions of
@.BR fopen (3s),
@.BR fputc (3s),
@.BR feof (3s),
and
@.BR fclose (3s)
to be used as direct substitutes for the originals;
it would be cleaner and more transparent if the decompress
filter were hidden under the real stdio procedures.
An extra call
@.BR zfilter (3x)
is supplied to convert an already-opened stream into a z-stream:
see the example at the end of this file.
Note that on the Atari or MSDOS, depending on the shell, stdin may have been
opened as an ASCII stream and hence these routines are useless.
A pre-existion stream MUST have been opened as a binary file.
@.PP
If a file opened by
@.B zfopen()
was not compressed, the files contents are still recovered
correctly at the low expense of an extra procedure call per byte.
This makes the routines more generally usable \- they can be
left in production programs which can be speeded up in the field by
compressing selected input files (see NOTES);
also, files can be compressed or not selectively depending on whether
the compression makes them smaller or not \- code accessing
the files does not need to know.
@.SH NOTES
Reading from a compressed file off floppy disk is faster than
reading from an uncompressed file.
This probably isn't true of hard disks though.
@.PP
The original decompress has been restructured so that data can be
fetched on demand a byte at a time.
This lets it be used as a filter
for programs which read large data files \- you do not need the disk
space to decompress the input files first.
@.PP
Incidentally, programs reading data off floppies will be speeded up
because decompression is always faster than the equivalent amount
of disk I/O.
@.SH BUGS
Opening a file "r" will not do CR/LF processing on computers with
this file structure.
@.SH "SEE ALSO"
intro(3S),
fopen(3S)
@.SH AUTHOR
Graham Toal, 3rd September 1988.
@.br
My changes released to public domain.
@.br
Updated Nov 90.
@.sp
Modified for Atari ST (Alcyon C and GNU C) by Bill Rosenkranz
@EOF
set `sum $sumopt <zlib/zlib.man`; if test $1 -ne 30771
then
	echo ERROR: zlib/zlib.man checksum is $1 should be 30771
fi

chmod 644 zlib/zlib.man

chmod 755 zlib

exit 0

-- 
Bill Rosenkranz            |UUCP: {uunet,texsun}!convex!rosenkra
Convex Computer Corp.      |ARPA: rosenkra AT convex DOT com

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019