aboutsummaryrefslogtreecommitdiff
path: root/toys/pending/compress.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/pending/compress.c')
-rw-r--r--toys/pending/compress.c189
1 files changed, 32 insertions, 157 deletions
diff --git a/toys/pending/compress.c b/toys/pending/compress.c
index 48cec494..bb4af46c 100644
--- a/toys/pending/compress.c
+++ b/toys/pending/compress.c
@@ -5,8 +5,7 @@
* The inflate/deflate code lives here, so the various things that use it
* either live here or call these commands to pipe data through them.
*
- * Divergence from posix: replace obsolete/patented "compress" with mutiplexer.
- * (gzip already replaces "uncompress".)
+ * Divergence from posix: replace obsolete "compress" with mutiplexer.
*
* See RFCs 1950 (zlib), 1951 (deflate), and 1952 (gzip)
* LSB 4.1 has gzip, gunzip, and zcat
@@ -15,10 +14,8 @@
// Accept many different kinds of command line argument.
// Leave Lrg at end so flag values line up.
-USE_COMPRESS(NEWTOY(compress, "zcd9lrg[-cd][!zgLr]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_COMPRESS(NEWTOY(gzip, USE_GZIP_D("d")"19dcflqStvgLRz[!gLRz]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_DECOMPRESS(NEWTOY(zcat, 0, TOYFLAG_USR|TOYFLAG_BIN))
-USE_DECOMPRESS(NEWTOY(gunzip, "cflqStv", TOYFLAG_USR|TOYFLAG_BIN))
+USE_COMPRESS(NEWTOY(compress, "zcd9Lrg[-cd][!zgLr]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_COMPRESS(NEWTOY(zcat, "aLrg[!aLrg]", TOYFLAG_USR|TOYFLAG_BIN))
//zip unzip gzip gunzip zcat
@@ -26,114 +23,38 @@ config COMPRESS
bool "compress"
default n
help
- usage: compress [-zgLR19] [FILE]
-
- Compress or decompress file (or stdin) using "deflate" algorithm.
-
- -1 min compression
- -9 max compression (default)
- -g gzip (default)
- -L zlib
- -R raw
- -z zip
-
-config GZIP
- bool "gzip"
- default y
- depends on COMPRESS
- help
- usage: gzip [-19cfqStvzgLR] [FILE...]
-
- Compess (deflate) file(s). With no files, compress stdin to stdout.
-
- On successful decompression, compressed files are replaced with the
- uncompressed version. The input file is removed and replaced with
- a new file without the .gz extension (with same ownership/permissions).
-
- -1 Minimal compression (fastest)
- -9 Max compression (default)
- -c cat to stdout (act as zcat)
- -f force (if output file exists, input is tty, unrecognized extension)
- -q quiet (no warnings)
- -S specify exension (default .*)
- -t test compressed file(s)
- -v verbose (like -l, but compress files)
-
- Compression type:
- -g gzip (default) -L zlib -R raw -z zip
-
-config GZIP_D
- bool
- default y
- depends on GZIP && DECOMPRESS
- help
- usage: gzip [-d]
-
- -d decompress (act as gunzip)
-
-config DECOMPRESS
- bool "decompress"
- default n
- help
usage: compress [-zglrcd9] [FILE]
Compress or decompress file (or stdin) using "deflate" algorithm.
- -c compress with -g gzip (default) -l zlib -r raw -z zip
+ -c compress with -g gzip (default) -L zlib -r raw -z zip
-d decompress (autodetects type)
-
config ZCAT
bool "zcat"
- default y
- depends on DECOMPRESS
+ default n
+ depends on COMPRESS
help
usage: zcat [FILE...]
Decompress deflated file(s) to stdout
-
-config GUNZIP
- bool "gunzip"
- default y
- depends on DECOMPRESS
- help
- usage: gunzip [-cflqStv] [FILE...]
-
- Decompess (deflate) file(s). With no files, compress stdin to stdout.
-
- On successful decompression, compressed files are replaced with the
- uncompressed version. The input file is removed and replaced with
- a new file without the .gz extension (with same ownership/permissions).
-
- -c cat to stdout (act as zcat)
- -f force (output file exists, input is tty, unrecognized extension)
- -l list compressed/uncompressed/ratio/name for each input file.
- -q quiet (no warnings)
- -S specify exension (default .*)
- -t test compressed file(s)
- -v verbose (like -l, but decompress files)
*/
#define FOR_compress
#include "toys.h"
GLOBALS(
- // Huffman codes: base offset and extra bits tables (length and distance)
+ // base offset and extra bits tables (length and distance)
char lenbits[29], distbits[30];
unsigned short lenbase[29], distbase[30];
void *fixdisthuff, *fixlithuff;
- // CRC
void (*crcfunc)(char *data, int len);
- unsigned crc;
-
- // Compressed data buffer
- char *data;
- unsigned pos, len;
- int fd;
+ unsigned crc, len;
- // Tables only used for deflation
- unsigned short *head, *chain;
+ char *outbuf;
+ unsigned outlen;
+ int outfd;
)
// little endian bit buffer
@@ -204,12 +125,12 @@ unsigned bitbuf_get(struct bitbuf *bb, int bits)
return result;
}
-static void data_crc(char sym)
+static void outbuf_crc(char sym)
{
- TT.data[TT.pos++ & 32767] = sym;
+ TT.outbuf[TT.outlen++ & 32767] = sym;
- if (!(TT.pos & 32767)) {
- xwrite(TT.fd, TT.data, 32768);
+ if (!(TT.outlen & 32767)) {
+ xwrite(TT.outfd, TT.outbuf, 32768);
if (TT.crcfunc) TT.crcfunc(0, 32768);
}
}
@@ -225,7 +146,7 @@ struct huff {
// Create simple huffman tree from array of bit lengths.
-// The symbols in the huffman trees are sorted (first by bit length
+// The symbols in deflate's huffman trees are sorted (first by bit length
// of the code to reach them, then by symbol number). This means that given
// the bit length of each symbol, we can construct a unique tree.
static void len2huff(struct huff *huff, char bitlen[], int len)
@@ -264,33 +185,6 @@ static unsigned huff_and_puff(struct bitbuf *bb, struct huff *huff)
return huff->symbol[start + offset];
}
-// For deflate, TT.len = input read, TT.pos = input consumed
-static void deflate(struct bitbuf *bb)
-{
- char *data = TT.data;
- int len, end = 0;
-
- TT.crc = ~0;
-
- // Read next half-window of data if we haven't hit EOF yet.
-read_more:
- len = readall(TT.fd, data + (TT.len & 32768), 32768);
-fprintf(stderr, "read %d@%d\n", len, TT.pos);
- if (len < 0) perror_exit("read"); // todo: add filename
- if (len != 32768) end++;
- TT.len += len;
-
- // repeat until spanked
- while (TT.pos != TT.len) {
- unsigned pos = TT.pos & 65535;
-
- if (!(pos & 32767) && !end) goto read_more;
-
- TT.pos++;
- }
-fprintf(stderr, "numberwang %d\n", TT.pos);
-}
-
// Decompress deflated data from bitbuf to filehandle.
static void inflate(struct bitbuf *bb)
{
@@ -322,7 +216,7 @@ static void inflate(struct bitbuf *bb)
// dump bytes until done or end of current bitbuf contents
if (bblen > len) bblen = len;
pos = bblen;
- while (pos--) data_crc(*(p++));
+ while (pos--) outbuf_crc(*(p++));
bitbuf_skip(bb, bblen << 3);
len -= bblen;
}
@@ -382,7 +276,7 @@ static void inflate(struct bitbuf *bb)
int sym = huff_and_puff(bb, lithuff);
// Literal?
- if (sym < 256) data_crc(sym);
+ if (sym < 256) outbuf_crc(sym);
// Copy range?
else if (sym > 256) {
@@ -392,9 +286,9 @@ static void inflate(struct bitbuf *bb)
len = TT.lenbase[sym] + bitbuf_get(bb, TT.lenbits[sym]);
sym = huff_and_puff(bb, disthuff);
dist = TT.distbase[sym] + bitbuf_get(bb, TT.distbits[sym]);
- sym = TT.pos & 32767;
+ sym = TT.outlen & 32767;
- while (len--) data_crc(TT.data[(TT.pos-dist) & 32767]);
+ while (len--) outbuf_crc(TT.outbuf[(TT.outlen-dist) & 32767]);
// End of block
} else break;
@@ -405,25 +299,18 @@ static void inflate(struct bitbuf *bb)
if (final) break;
}
- if (TT.pos & 32767) {
- xwrite(TT.fd, TT.data, TT.pos & 32767);
- if (TT.crcfunc) TT.crcfunc(0, TT.pos & 32767);
+ if (TT.outlen & 32767) {
+ xwrite(TT.outfd, TT.outbuf, TT.outlen & 32767);
+ if (TT.crcfunc) TT.crcfunc(0, TT.outlen & 32767);
}
}
-static void init_deflate(int compress)
+static void init_deflate(void)
{
- int i, n = 1, size = 32768;
+ int i, n = 1;
// Ye olde deflate window
- TT.data = xmalloc(32768*(compress+1));
- if (compress) {
- TT.head = (unsigned short *)(TT.data+65536);
- TT.chain = TT.head +
-
-HASH_SIZE = 1 << 15;
-
- }
+ TT.outbuf = xmalloc(32768);
// Calculate lenbits, lenbase, distbits, distbase
*TT.lenbase = 3;
@@ -478,22 +365,17 @@ void gzip_crc(char *data, int len)
unsigned crc, *crc_table = (unsigned *)(toybuf+sizeof(toybuf)-1024);
crc = TT.crc;
- for (i=0; i<len; i++) crc = crc_table[(crc^TT.data[i])&0xff] ^ (crc>>8);
+ for (i=0; i<len; i++) crc = crc_table[(crc^TT.outbuf[i])&0xff] ^ (crc>>8);
TT.crc = crc;
TT.len += len;
}
-static void do_compress(int fd, char *name)
-{
- xwrite(1, "\x1f\x8b\x08\0\0\0\0\0\x02\xff", 10);
-}
-
static void do_zcat(int fd, char *name)
{
struct bitbuf *bb = bitbuf_init(fd, sizeof(toybuf));
if (!is_gzip(bb)) error_exit("not gzip");
- TT.fd = 1;
+ TT.outfd = 1;
// Use last 1k of toybuf for little endian crc table
crc_init((unsigned *)(toybuf+sizeof(toybuf)-1024), 1);
@@ -516,20 +398,13 @@ void compress_main(void)
zcat_main();
}
-#define CLEANUP_compress
-#define FOR_zcat
-#include "generated/flags.h"
+//#define CLEANUP_compress
+//#define FOR_zcat
+//#include "generated/flags.h"
void zcat_main(void)
{
- init_deflate(0);
+ init_deflate();
loopfiles(toys.optargs, do_zcat);
}
-
-//void gunzip_main(void)
-//{
-// init_deflate(0);
-//
-// loopfiles(toys.optargs, do_zcat);
-//}