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 -