summaryrefslogtreecommitdiff
path: root/sample
diff options
context:
space:
mode:
Diffstat (limited to 'sample')
-rw-r--r--sample/add.c59
-rw-r--r--sample/makecrc.c60
-rw-r--r--sample/sub.c90
-rwxr-xr-xsample/zfile28
-rw-r--r--sample/zread.c55
-rwxr-xr-xsample/ztouch15
6 files changed, 307 insertions, 0 deletions
diff --git a/sample/add.c b/sample/add.c
new file mode 100644
index 0000000..cadbc3a
--- /dev/null
+++ b/sample/add.c
@@ -0,0 +1,59 @@
+/* add.c not copyrighted (n) 1993 by Mark Adler */
+/* version 1.1 11 Jun 1993 */
+
+/* This filter reverses the effect of the sub filter. It requires no
+ arguments, since sub puts the information necessary for extraction
+ in the stream. See sub.c for what the filtering is and what it's
+ good for. */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MAGIC1 'S' /* sub data */
+#define MAGIC2 26 /* ^Z */
+#define MAX_DIST 16384
+
+char a[MAX_DIST]; /* last byte buffer for up to MAX_DIST differences */
+
+int main()
+{
+ int n; /* number of differences */
+ int i; /* difference counter */
+ int c; /* byte from input */
+
+ /* check magic word */
+ if (getchar() != MAGIC1 || getchar() != MAGIC2)
+ {
+ fputs("add: input stream not made by sub\n", stderr);
+ exit(EXIT_FAILURE);
+ }
+
+ /* get number of differences from data */
+ if ((n = getchar()) == EOF || (i = getchar()) == EOF) {
+ fputs("add: unexpected end of file\n", stderr);
+ exit(EXIT_FAILURE);
+ }
+ n += (i<<8);
+ if (n <= 0 || n > MAX_DIST) {
+ fprintf(stderr, "add: incorrect distance %d\n", n);
+ exit(EXIT_FAILURE);
+ }
+
+ /* initialize last byte */
+ i = n;
+ do {
+ a[--i] = 0;
+ } while (i);
+
+ /* read differenced data and restore original */
+ while ((c = getchar()) != EOF)
+ {
+ c = (a[i++] += c) & 0xff; /* restore data, save last byte */
+ putchar(c); /* write original */
+ if (i == n) /* cycle on n differences */
+ i = 0;
+ }
+ exit(EXIT_SUCCESS);
+ return 0; /* avoid warning */
+}
diff --git a/sample/makecrc.c b/sample/makecrc.c
new file mode 100644
index 0000000..8fa2959
--- /dev/null
+++ b/sample/makecrc.c
@@ -0,0 +1,60 @@
+/* Not copyrighted 1990 Mark Adler */
+
+#include <config.h>
+#include <stdio.h>
+
+main()
+/*
+ Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The table is simply the CRC of all possible eight bit values. This is all
+ the information needed to generate CRC's on data a byte at a time for all
+ combinations of CRC register values and incoming bytes. The table is
+ written to stdout as 256 long hexadecimal values in C language format.
+*/
+{
+ unsigned long c; /* crc shift register */
+ unsigned long e; /* polynomial exclusive-or pattern */
+ int i; /* counter for all possible eight bit values */
+ int k; /* byte being shifted into crc apparatus */
+
+ /* terms of polynomial defining this crc (except x^32): */
+ static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* Make exclusive-or pattern from polynomial (0xedb88320) */
+ e = 0;
+ for (i = 0; i < sizeof(p)/sizeof(int); i++)
+ e |= 1L << (31 - p[i]);
+
+ /* Compute and print table of CRC's, five per line */
+ printf(" 0x00000000L");
+ for (i = 1; i < 256; i++)
+ {
+ c = i;
+ /* The idea to initialize the register with the byte instead of
+ * zero was stolen from Haruhiko Okumura's ar002
+ */
+ for (k = 8; k; k--)
+ c = c & 1 ? (c >> 1) ^ e : c >> 1;
+ printf(i % 5 ? ", 0x%08lxL" : ",\n 0x%08lxL", c);
+ }
+ putchar('\n');
+ return 0;
+}
diff --git a/sample/sub.c b/sample/sub.c
new file mode 100644
index 0000000..a06cc9b
--- /dev/null
+++ b/sample/sub.c
@@ -0,0 +1,90 @@
+/* sub.c not copyrighted (n) 1993 by Mark Adler */
+/* version 1.1 11 Jun 1993 */
+
+/* sub is a simple filter to preprocess a data file before compression.
+ It can increase compression for data whose points tend to be close to
+ the last point. The output is the difference of successive bytes of
+ the input. The add filter is used to undo what sub does. This could
+ be used on 8-bit sound or graphics data.
+
+ sub can also take an argument to apply this to interleaved sets of
+ bytes. For example, if the data are 16-bit sound samples, then you
+ can use "sub 2" to take differences on the low-byte stream and the
+ high-byte stream. (This gives nearly the same effect as subtracting
+ the 16-bit values, but avoids the complexities of endianess of the
+ data.) The concept extends to RGB image data (sub 3), 16-bit stereo
+ data (sub 4), floating point data (sub 4 or sub 8), etc.
+
+ add takes no options, since the number of interleaved byte streams
+ is put in the first two bytes of the output stream for add to use
+ (in little-endian format).
+
+ Examples:
+
+ sub < graph.vga | gzip -9 > graph.vga.sgz
+ sub < phone.snd | gzip -9 > phone.snd.sgz
+ sub 2 < audio.snd | gzip -9 > audio.snd.sgz
+ sub 3 < picture.rgb | gzip -9 > picture.rgb.sgz
+ sub 4 < stereo.snd | gzip -9 > stereo.snd.sgz
+ sub 8 < double.data | gzip -9 > double.data.sgz
+
+ To expand, use the reverse operation, as in:
+
+ gunzip < double.data.sgz | add > double.data
+*/
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MAGIC1 'S' /* sub data */
+#define MAGIC2 26 /* ^Z */
+#define MAX_DIST 16384
+
+char a[MAX_DIST]; /* last byte buffer for up to MAX_DIST differences */
+
+int main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int n = 1; /* number of differences */
+ int i; /* difference counter */
+ int c; /* byte from input */
+ int atoi(); /* (avoid including stdlib for portability) */
+
+ /* process arguments */
+ if (argc > 2)
+ {
+ fputs("sub: only one argument needed--# of differences\n", stderr);
+ exit(EXIT_FAILURE);
+ }
+ if (argc > 1)
+ n = atoi(argv[1]);
+
+ if (n < 0) n = -n; /* tolerate "sub -2" */
+ if (n == 0 || n > MAX_DIST) {
+ fputs("sub: incorrect distance\n", stderr);
+ exit(EXIT_FAILURE);
+ }
+
+ /* initialize last byte */
+ i = n;
+ do {
+ a[--i] = 0;
+ } while (i);
+
+ /* write differenced data */
+ putchar(MAGIC1); putchar(MAGIC2); /* magic word for add */
+ putchar(n & 0xff); /* so add knows what to do */
+ putchar((n>>8) & 0xff);
+
+ while ((c = getchar()) != EOF)
+ {
+ putchar((c - a[i]) & 0xff); /* write difference */
+ a[i++] = c; /* save last byte */
+ if (i == n) /* cycle on n differences */
+ i = 0;
+ }
+ exit(EXIT_SUCCESS);
+ return 0; /* avoid warning */
+}
diff --git a/sample/zfile b/sample/zfile
new file mode 100755
index 0000000..6b4514c
--- /dev/null
+++ b/sample/zfile
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+if test $# = 0; then
+ echo 'zfile: file(1) for programs which may be compressed with gzexe'
+ echo usage: `basename $0` files...
+ exit 1
+fi
+
+tmp=/tmp/gz$$
+
+for i do
+ if test ! -f "$i" ; then
+ echo `basename $0`: $i not a file
+ res=1
+ continue
+ fi
+ skip=18
+ if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
+ eval `sed -e 1d -e 2q "$i"`
+ fi
+ if tail +$skip "$i" | gzip --list >/dev/null 2>&1; then
+ tail +$skip "$i" | gzip -cd | dd count=1 >$tmp 2>/dev/null
+ file $tmp | sed "s|^$tmp|$i|"
+ else
+ file "$i"
+ fi
+ rm -f $tmp
+done
diff --git a/sample/zread.c b/sample/zread.c
new file mode 100644
index 0000000..e20de49
--- /dev/null
+++ b/sample/zread.c
@@ -0,0 +1,55 @@
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Trivial example of reading a gzip'ed file or gzip'ed standard input
+ * using stdio functions fread(), getc(), etc... fseek() is not supported.
+ * Modify according to your needs. You can easily construct the symmetric
+ * zwrite program.
+ *
+ * Usage: zread [file[.gz]]
+ * This programs assumes that gzip is somewhere in your path.
+ */
+int main(argc, argv)
+ int argc;
+ char **argv;
+{
+ FILE *infile;
+ char cmd[256];
+ char buf[BUFSIZ];
+ int n;
+
+ if (argc < 1 || argc > 2) {
+ fprintf(stderr, "usage: %s [file[.gz]]\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ strcpy(cmd, "gzip -dc "); /* use "gzip -c" for zwrite */
+ if (argc == 2) {
+ strncat(cmd, argv[1], sizeof(cmd)-strlen(cmd));
+ }
+ infile = popen(cmd, "r"); /* use "w" for zwrite */
+ if (infile == NULL) {
+ fprintf(stderr, "%s: popen('%s', 'r') failed\n", argv[0], cmd);
+ exit(EXIT_FAILURE);
+ }
+ /* Read one byte using getc: */
+ n = getc(infile);
+ if (n == EOF) {
+ pclose(infile);
+ exit(EXIT_SUCCESS);
+ }
+ putchar(n);
+
+ /* Read the rest using fread: */
+ for (;;) {
+ n = fread(buf, 1, BUFSIZ, infile);
+ if (n <= 0) break;
+ fwrite(buf, 1, n, stdout);
+ }
+ if (pclose(infile) != 0) {
+ fprintf(stderr, "%s: pclose failed\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ exit(EXIT_SUCCESS);
+ return 0; /* just to make compiler happy */
+}
diff --git a/sample/ztouch b/sample/ztouch
new file mode 100755
index 0000000..c5d30ad
--- /dev/null
+++ b/sample/ztouch
@@ -0,0 +1,15 @@
+#! /usr/local/bin/perl
+# Set the time stamp of a gzip'ed file from that stored in the file.
+# usage: ztouch files...
+
+foreach $file (@ARGV) {
+ open (FILE, $file);
+ read (FILE, $_, 8);
+ ($magic, $method, $flags, $time) = unpack ("A2C2V", $_);
+ if ($magic eq "\037\213") {
+ utime ($time, $time, $file);
+ }
+ else {
+ warn "$file is not compressed with gzip!\n";
+ }
+}