annotate lib/bunzip.c @ 56:7794562e2e64

Comment and whitespace changes.
author Rob Landley <rob@landley.net>
date Wed, 17 Jan 2007 13:58:08 -0500
parents 0bb7c679499a
children 034de958ee65
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
1 /* vi: set sw=4 ts=4: */
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
2 /* micro-bunzip, a small, simple bzip2 decompression implementation.
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
3
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
4 Copyright 2003, 2006 by Rob Landley (rob@landley.net).
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
5
54
60a7fb8ddeb4 Add a quick and dirt bzcat (stdin to stdout only for the moment) to test
Rob Landley <rob@landley.net>
parents: 46
diff changeset
6 Based on a close reading (but not the actual code) of the original bzip2
60a7fb8ddeb4 Add a quick and dirt bzcat (stdin to stdout only for the moment) to test
Rob Landley <rob@landley.net>
parents: 46
diff changeset
7 decompression code by Julian R Seward (jseward@acm.org), which also
60a7fb8ddeb4 Add a quick and dirt bzcat (stdin to stdout only for the moment) to test
Rob Landley <rob@landley.net>
parents: 46
diff changeset
8 acknowledges contributions by Mike Burrows, David Wheeler, Peter Fenwick,
60a7fb8ddeb4 Add a quick and dirt bzcat (stdin to stdout only for the moment) to test
Rob Landley <rob@landley.net>
parents: 46
diff changeset
9 Alistair Moffat, Radford Neal, Ian H. Witten, Robert Sedgewick, and
60a7fb8ddeb4 Add a quick and dirt bzcat (stdin to stdout only for the moment) to test
Rob Landley <rob@landley.net>
parents: 46
diff changeset
10 Jon L. Bentley.
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
11 */
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
12
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
13 #include "toys.h"
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
14
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
15 // Constants for huffman coding
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
16 #define MAX_GROUPS 6
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
17 #define GROUP_SIZE 50 /* 64 would have been more efficient */
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
18 #define MAX_HUFCODE_BITS 20 /* Longest huffman code allowed */
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
19 #define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
20 #define SYMBOL_RUNA 0
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
21 #define SYMBOL_RUNB 1
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
22
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
23 // Other housekeeping constants
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
24 #define IOBUF_SIZE 4096
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
25
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
26 // Status return values
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
27 #define RETVAL_OK 0
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
28 #define RETVAL_LAST_BLOCK (-1)
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
29 #define RETVAL_NOT_BZIP_DATA (-2)
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
30 #define RETVAL_UNEXPECTED_INPUT_EOF (-3)
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
31 #define RETVAL_UNEXPECTED_OUTPUT_EOF (-4)
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
32 #define RETVAL_DATA_ERROR (-5)
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
33 #define RETVAL_OUT_OF_MEMORY (-6)
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
34 #define RETVAL_OBSOLETE_INPUT (-7)
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
35
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
36 char *bunzip_errors[]={
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
37 NULL,
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
38 "Bad file checksum",
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
39 "Not bzip data",
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
40 "Unexpected input EOF",
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
41 "Unexpected output EOF",
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
42 "Data error",
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
43 "Out of memory",
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
44 "Obsolete (pre 0.9.5) bzip format not supported."
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
45 };
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
46
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
47 // This is what we know about each huffman coding group
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
48 struct group_data {
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
49 int limit[MAX_HUFCODE_BITS], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS];
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
50 char minLen, maxLen;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
51 };
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
52
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
53 // Structure holding all the housekeeping data, including IO buffers and
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
54 // memory that persists between calls to bunzip
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
55 typedef struct {
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
56
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
57 // For I/O error handling
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
58 jmp_buf jmpbuf;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
59
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
60 // Input stream, input buffer, input bit buffer
46
5a6241f16e95 Remove more warnings.
Rob Landley <rob@landley.net>
parents: 40
diff changeset
61 int in_fd, inbufCount, inbufPos;
5a6241f16e95 Remove more warnings.
Rob Landley <rob@landley.net>
parents: 40
diff changeset
62 char *inbuf;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
63 unsigned int inbufBitCount, inbufBits;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
64
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
65 // Output buffer
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
66 char outbuf[IOBUF_SIZE];
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
67 int outbufPos;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
68
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
69 // The CRC values stored in the block header and calculated from the data
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
70 unsigned int crc32Table[256], headerCRC, dataCRC, totalCRC;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
71
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
72 // Intermediate buffer and its size (in bytes)
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
73 unsigned int *dbuf, dbufSize;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
74
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
75 // State for interrupting output loop
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
76 int writePos, writeRun, writeCount, writeCurrent;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
77
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
78 // These things are a bit too big to go on the stack
46
5a6241f16e95 Remove more warnings.
Rob Landley <rob@landley.net>
parents: 40
diff changeset
79 char selectors[32768]; // nSelectors=15 bits
5a6241f16e95 Remove more warnings.
Rob Landley <rob@landley.net>
parents: 40
diff changeset
80 struct group_data groups[MAX_GROUPS]; // huffman coding tables
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
81 } bunzip_data;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
82
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
83 // Return the next nnn bits of input. All reads from the compressed input
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
84 // are done through this function. All reads are big endian.
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
85 static unsigned int get_bits(bunzip_data *bd, char bits_wanted)
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
86 {
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
87 unsigned int bits = 0;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
88
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
89 // If we need to get more data from the byte buffer, do so. (Loop getting
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
90 // one byte at a time to enforce endianness and avoid unaligned access.)
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
91 while (bd->inbufBitCount < bits_wanted) {
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
92
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
93 // If we need to read more data from file into byte buffer, do so
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
94 if (bd->inbufPos == bd->inbufCount) {
40
d046f8d1401e Trawling through the archives: a broken test, an unnecessary memset, and a
Rob Landley <rob@landley.net>
parents: 39
diff changeset
95 if (0 >= (bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE)))
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
96 longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
97 bd->inbufPos = 0;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
98 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
99
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
100 // Avoid 32-bit overflow (dump bit buffer to top of output)
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
101 if (bd->inbufBitCount>=24) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
102 bits = bd->inbufBits&((1<<bd->inbufBitCount)-1);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
103 bits_wanted -= bd->inbufBitCount;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
104 bits <<= bits_wanted;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
105 bd->inbufBitCount = 0;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
106 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
107
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
108 // Grab next 8 bits of input from buffer.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
109 bd->inbufBits = (bd->inbufBits<<8) | bd->inbuf[bd->inbufPos++];
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
110 bd->inbufBitCount += 8;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
111 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
112
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
113 // Calculate result
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
114 bd->inbufBitCount -= bits_wanted;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
115 bits |= (bd->inbufBits>>bd->inbufBitCount) & ((1<<bits_wanted)-1);
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
116
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
117 return bits;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
118 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
119
56
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
120 // Decompress a block of text to intermediate buffer
54
60a7fb8ddeb4 Add a quick and dirt bzcat (stdin to stdout only for the moment) to test
Rob Landley <rob@landley.net>
parents: 46
diff changeset
121 int read_bunzip_data(bunzip_data *bd)
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
122 {
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
123 struct group_data *hufGroup;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
124 int dbufCount, nextSym, dbufSize, origPtr, groupCount, *base, *limit,
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
125 selector, i, j, k, t, runPos, symCount, symTotal, nSelectors,
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
126 byteCount[256];
46
5a6241f16e95 Remove more warnings.
Rob Landley <rob@landley.net>
parents: 40
diff changeset
127 char uc, mtfSymbol[256], symToByte[256], *selectors;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
128 unsigned int *dbuf;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
129
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
130 // Read in header signature (borrowing mtfSymbol for temp space).
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
131 for (i=0; i<6; i++) mtfSymbol[i] = get_bits(bd,8);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
132 mtfSymbol[6] = 0;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
133
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
134 // Read CRC (which is stored big endian).
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
135 bd->headerCRC = get_bits(bd,32);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
136
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
137 // Is this the last block (with CRC for file)?
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
138 if (!strcmp(mtfSymbol, "\x17\x72\x45\x38\x50\x90"))
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
139 return RETVAL_LAST_BLOCK;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
140
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
141 // If it's not a valid data block, barf.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
142 if (strcmp(mtfSymbol, "\x31\x41\x59\x26\x53\x59"))
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
143 return RETVAL_NOT_BZIP_DATA;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
144
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
145 dbuf = bd->dbuf;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
146 dbufSize = bd->dbufSize;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
147 selectors = bd->selectors;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
148
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
149 // We can add support for blockRandomised if anybody complains.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
150 if (get_bits(bd,1)) return RETVAL_OBSOLETE_INPUT;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
151 if ((origPtr=get_bits(bd,24)) > dbufSize) return RETVAL_DATA_ERROR;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
152
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
153 // mapping table: if some byte values are never used (encoding things
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
154 // like ascii text), the compression code removes the gaps to have fewer
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
155 // symbols to deal with, and writes a sparse bitfield indicating which
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
156 // values were present. We make a translation table to convert the symbols
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
157 // back to the corresponding bytes.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
158 t = get_bits(bd, 16);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
159 symTotal = 0;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
160 for (i=0; i<16; i++) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
161 if (t&(1<<(15-i))) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
162 k = get_bits(bd,16);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
163 for (j=0;j<16;j++)
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
164 if (k&(1<<(15-j))) symToByte[symTotal++] = (16*i)+j;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
165 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
166 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
167
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
168 // How many different huffman coding groups does this block use?
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
169 groupCount = get_bits(bd,3);
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
170 if (groupCount<2 || groupCount>MAX_GROUPS) return RETVAL_DATA_ERROR;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
171
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
172 // nSelectors: Every GROUP_SIZE many symbols we select a new huffman coding
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
173 // group. Read in the group selector list, which is stored as MTF encoded
56
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
174 // bit runs. (MTF = Move To Front. Every time a symbol occurs it's moved
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
175 // to the front of the table, so it has a shorter encoding next time.)
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
176 if (!(nSelectors = get_bits(bd, 15))) return RETVAL_DATA_ERROR;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
177 for (i=0; i<groupCount; i++) mtfSymbol[i] = i;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
178 for (i=0; i<nSelectors; i++) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
179
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
180 // Get next value
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
181 for(j=0;get_bits(bd,1);j++)
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
182 if (j>=groupCount) return RETVAL_DATA_ERROR;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
183
56
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
184 // Decode MTF to get the next selector, and move it to the front.
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
185 uc = mtfSymbol[j];
55
0bb7c679499a Memmove is 11 bytes shorter than the unrolled loop, and Manuel Nova pointed
Rob Landley <rob@landley.net>
parents: 54
diff changeset
186 memmove(mtfSymbol+1, mtfSymbol, j);
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
187 mtfSymbol[0] = selectors[i] = uc;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
188 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
189 // Read the huffman coding tables for each group, which code for symTotal
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
190 // literal symbols, plus two run symbols (RUNA, RUNB)
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
191 symCount = symTotal+2;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
192 for (j=0; j<groupCount; j++) {
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
193 unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1];
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
194 int minLen, maxLen, pp;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
195
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
196 // Read lengths
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
197 t = get_bits(bd, 5);
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
198 for (i = 0; i < symCount; i++) {
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
199 for(;;) {
54
60a7fb8ddeb4 Add a quick and dirt bzcat (stdin to stdout only for the moment) to test
Rob Landley <rob@landley.net>
parents: 46
diff changeset
200 if (MAX_HUFCODE_BITS < (unsigned)t-1) return RETVAL_DATA_ERROR;
55
0bb7c679499a Memmove is 11 bytes shorter than the unrolled loop, and Manuel Nova pointed
Rob Landley <rob@landley.net>
parents: 54
diff changeset
201 if(!get_bits(bd, 1)) break; // Stop yet?
0bb7c679499a Memmove is 11 bytes shorter than the unrolled loop, and Manuel Nova pointed
Rob Landley <rob@landley.net>
parents: 54
diff changeset
202 t += (1 - 2*get_bits(bd, 1)); // bit ? t-- : t++
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
203 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
204 length[i] = t;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
205 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
206
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
207 // Find largest and smallest lengths in this group
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
208 minLen = maxLen = length[0];
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
209 for (i = 1; i < symCount; i++) {
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
210 if(length[i] > maxLen) maxLen = length[i];
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
211 else if(length[i] < minLen) minLen = length[i];
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
212 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
213
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
214 /* Calculate permute[], base[], and limit[] tables from length[].
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
215 *
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
216 * permute[] is the lookup table for converting huffman coded symbols
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
217 * into decoded symbols. base[] is the amount to subtract from the
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
218 * value of a huffman symbol of a given length when using permute[].
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
219 *
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
220 * limit[] indicates the largest numerical value a symbol with a given
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
221 * number of bits can have. It lets us know when to stop reading.
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
222 *
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
223 * To use these, keep reading bits until value <= limit[bitcount] or
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
224 * you've read over 20 bits (error). Then the decoded symbol
56
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
225 * equals permute[hufcode_value - base[hufcode_bitcount]].
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
226 */
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
227 hufGroup = bd->groups+j;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
228 hufGroup->minLen = minLen;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
229 hufGroup->maxLen = maxLen;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
230
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
231 // Note that minLen can't be smaller than 1, so we adjust the base
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
232 // and limit array pointers so we're not always wasting the first
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
233 // entry. We do this again when using them (during symbol decoding).
56
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
234 base = hufGroup->base-1;
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
235 limit = hufGroup->limit-1;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
236
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
237 // Calculate permute[]
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
238 pp = 0;
56
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
239 for (i = minLen; i <= maxLen; i++)
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
240 for (t = 0; t < symCount; t++)
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
241 if (length[t] == i) hufGroup->permute[pp++] = t;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
242
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
243 // Count cumulative symbols coded for at each bit length
56
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
244 for (i = minLen; i <= maxLen; i++) temp[i] = limit[i] = 0;
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
245 for (i = 0; i < symCount; i++) temp[length[i]]++;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
246
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
247 /* Calculate limit[] (the largest symbol-coding value at each bit
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
248 * length, which is (previous limit<<1)+symbols at this level), and
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
249 * base[] (number of symbols to ignore at each bit length, which is
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
250 * limit-cumulative count of symbols coded for already). */
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
251 pp = t = 0;
56
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
252 for (i = minLen; i < maxLen; i++) {
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
253 pp += temp[i];
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
254 limit[i] = pp-1;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
255 pp <<= 1;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
256 base[i+1] = pp-(t+=temp[i]);
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
257 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
258 limit[maxLen] = pp+temp[maxLen]-1;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
259 base[minLen] = 0;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
260 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
261
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
262 // We've finished reading and digesting the block header. Now read this
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
263 // block's huffman coded symbols from the file and undo the huffman coding
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
264 // and run length encoding, saving the result into dbuf[dbufCount++] = uc
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
265
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
266 // Initialize symbol occurrence counters and symbol mtf table
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
267 memset(byteCount, 0, 256*sizeof(int));
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
268 for(i=0; i<256; i++) mtfSymbol[i] = (unsigned char)i;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
269
56
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
270 // Loop through compressed symbols. This is the first "tight inner loop"
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
271 // that needs to be micro-optimized for speed. (This one fills out dbuf[]
7794562e2e64 Comment and whitespace changes.
Rob Landley <rob@landley.net>
parents: 55
diff changeset
272 // linearly, staying in cache more, so isn't as limited by DRAM access.)
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
273 runPos = dbufCount = symCount = selector = 0;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
274 for (;;) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
275
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
276 // Determine which huffman coding group to use.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
277 if (!(symCount--)) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
278 symCount = GROUP_SIZE-1;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
279 if (selector >= nSelectors) return RETVAL_DATA_ERROR;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
280 hufGroup = bd->groups+selectors[selector++];
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
281 base = hufGroup->base-1;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
282 limit = hufGroup->limit-1;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
283 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
284
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
285 // Read next huffman-coded symbol
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
286 i = hufGroup->minLen;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
287 j = get_bits(bd, i);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
288 for (;;) {
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
289 if (i > hufGroup->maxLen) return RETVAL_DATA_ERROR;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
290 if (j <= limit[i]) break;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
291 i++;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
292
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
293 j = (j << 1) | get_bits(bd,1);
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
294 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
295
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
296 // Huffman decode nextSym (with bounds checking)
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
297 j-=base[i];
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
298 if (j < 0 || j >= MAX_SYMBOLS) return RETVAL_DATA_ERROR;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
299 nextSym = hufGroup->permute[j];
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
300
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
301 // If this is a repeated run, loop collecting data
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
302 if (nextSym == SYMBOL_RUNA || nextSym == SYMBOL_RUNB) {
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
303
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
304 // If this is the start of a new run, zero out counter
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
305 if(!runPos) {
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
306 runPos = 1;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
307 t = 0;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
308 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
309
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
310 /* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 at
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
311 each bit position, add 1 or 2 instead. For example,
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
312 1011 is 1<<0 + 1<<1 + 2<<2. 1010 is 2<<0 + 2<<1 + 1<<2.
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
313 You can make any bit pattern that way using 1 less symbol than
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
314 the basic or 0/1 method (except all bits 0, which would use no
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
315 symbols, but a run of length 0 doesn't mean anything in this
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
316 context). Thus space is saved. */
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
317 if (nextSym == SYMBOL_RUNA) t += runPos;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
318 else t += 2*runPos;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
319 runPos <<= 1;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
320 continue;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
321 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
322
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
323 /* When we hit the first non-run symbol after a run, we now know
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
324 how many times to repeat the last literal, so append that many
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
325 copies to our buffer of decoded symbols (dbuf) now. (The last
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
326 literal used is the one at the head of the mtfSymbol array.) */
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
327 if (runPos) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
328 runPos = 0;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
329 if (dbufCount+t >= dbufSize) return RETVAL_DATA_ERROR;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
330
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
331 uc = symToByte[mtfSymbol[0]];
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
332 byteCount[uc] += t;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
333 while (t--) dbuf[dbufCount++] = uc;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
334 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
335
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
336 // Is this the terminating symbol?
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
337 if (nextSym>symTotal) break;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
338
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
339 /* At this point, the symbol we just decoded indicates a new literal
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
340 character. Subtract one to get the position in the MTF array
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
341 at which this literal is currently to be found. (Note that the
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
342 result can't be -1 or 0, because 0 and 1 are RUNA and RUNB.
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
343 Another instance of the first symbol in the mtf array, position 0,
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
344 would have been handled as part of a run.) */
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
345 if (dbufCount>=dbufSize) return RETVAL_DATA_ERROR;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
346 i = nextSym - 1;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
347 uc = mtfSymbol[i];
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
348 memmove(mtfSymbol+1, mtfSymbol, i);
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
349 mtfSymbol[0] = uc;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
350 uc = symToByte[uc];
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
351
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
352 // We have our literal byte. Save it into dbuf.
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
353 byteCount[uc]++;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
354 dbuf[dbufCount++] = (unsigned int)uc;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
355 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
356
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
357 /* At this point, we've finished reading huffman-coded symbols and
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
358 compressed runs from the input stream. There are dbufCount many of
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
359 them in dbuf[]. Now undo the Burrows-Wheeler transform on dbuf.
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
360 See http://marknelson.us/1996/09/01/bwt/
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
361 */
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
362
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
363 // Now we know what dbufCount is, do a better sanity check on origPtr.
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
364 if (origPtr<0 || origPtr>=dbufCount) return RETVAL_DATA_ERROR;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
365
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
366 // Turn byteCount into cumulative occurrence counts of 0 to n-1.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
367 j = 0;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
368 for (i=0;i<256;i++) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
369 k = j+byteCount[i];
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
370 byteCount[i] = j;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
371 j = k;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
372 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
373
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
374 // Figure out what order dbuf would be in if we sorted it.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
375 for (i=0; i<dbufCount; i++) {
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
376 uc = (unsigned char)(dbuf[i] & 0xff);
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
377 dbuf[byteCount[uc]] |= (i << 8);
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
378 byteCount[uc]++;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
379 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
380
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
381 // blockRandomised support would go here.
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
382
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
383 // Using i as position, j as previous character, t as current character,
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
384 // and uc as run count.
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
385 bd->dataCRC = 0xffffffffL;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
386
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
387 /* Decode first byte by hand to initialize "previous" byte. Note that it
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
388 doesn't get output, and if the first three characters are identical
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
389 it doesn't qualify as a run (hence uc=255, which will either wrap
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
390 to 1 or get reset). */
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
391 if (dbufCount) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
392 bd->writePos = dbuf[origPtr];
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
393 bd->writeCurrent = (unsigned char)(bd->writePos&0xff);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
394 bd->writePos >>= 8;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
395 bd->writeRun = -1;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
396 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
397 bd->writeCount = dbufCount;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
398
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
399 return RETVAL_OK;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
400 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
401
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
402 // Flush output buffer to disk
54
60a7fb8ddeb4 Add a quick and dirt bzcat (stdin to stdout only for the moment) to test
Rob Landley <rob@landley.net>
parents: 46
diff changeset
403 void flush_bunzip_outbuf(bunzip_data *bd, int out_fd)
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
404 {
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
405 if (bd->outbufPos) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
406 if (write(out_fd, bd->outbuf, bd->outbufPos) != bd->outbufPos)
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
407 longjmp(bd->jmpbuf,RETVAL_UNEXPECTED_OUTPUT_EOF);
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
408 bd->outbufPos = 0;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
409 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
410 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
411
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
412 // Undo burrows-wheeler transform on intermediate buffer to produce output.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
413 // If !len, write up to len bytes of data to buf. Otherwise write to out_fd.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
414 // Returns len ? bytes written : RETVAL_OK. Notice all errors negative #'s.
54
60a7fb8ddeb4 Add a quick and dirt bzcat (stdin to stdout only for the moment) to test
Rob Landley <rob@landley.net>
parents: 46
diff changeset
415 int write_bunzip_data(bunzip_data *bd, int out_fd, char *outbuf, int len)
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
416 {
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
417 unsigned int *dbuf = bd->dbuf;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
418 int count, pos, current, run, copies, outbyte, previous, gotcount = 0;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
419
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
420 for (;;) {
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
421
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
422 // If last read was short due to end of file, return last block now
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
423 if (bd->writeCount < 0) return bd->writeCount;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
424
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
425 // If we need to refill dbuf, do it.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
426 if (!bd->writeCount) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
427 int i = read_bunzip_data(bd);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
428 if (i) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
429 if (i == RETVAL_LAST_BLOCK) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
430 bd->writeCount = i;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
431 return gotcount;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
432 } else return i;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
433 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
434 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
435
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
436 // Loop generating output
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
437 count = bd->writeCount;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
438 pos = bd->writePos;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
439 current = bd->writeCurrent;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
440 run = bd->writeRun;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
441 while (count) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
442
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
443 // If somebody (like tar) wants a certain number of bytes of
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
444 // data from memory instead of written to a file, humor them.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
445 if (len && bd->outbufPos>=len) goto dataus_interruptus;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
446 count--;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
447
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
448 // Follow sequence vector to undo Burrows-Wheeler transform.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
449 previous = current;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
450 pos = dbuf[pos];
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
451 current = pos&0xff;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
452 pos >>= 8;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
453
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
454 // Whenever we see 3 consecutive copies of the same byte,
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
455 // the 4th is a repeat count
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
456 if (run++ == 3) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
457 copies = current;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
458 outbyte = previous;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
459 current = -1;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
460 } else {
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
461 copies = 1;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
462 outbyte = current;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
463 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
464
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
465 // Output bytes to buffer, flushing to file if necessary
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
466 while (copies--) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
467 if (bd->outbufPos == IOBUF_SIZE) flush_bunzip_outbuf(bd,out_fd);
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
468 bd->outbuf[bd->outbufPos++] = outbyte;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
469 bd->dataCRC = (bd->dataCRC << 8)
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
470 ^ bd->crc32Table[(bd->dataCRC >> 24) ^ outbyte];
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
471 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
472 if (current!=previous) run=0;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
473 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
474
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
475 // Decompression of this block completed successfully
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
476 bd->dataCRC = ~(bd->dataCRC);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
477 bd->totalCRC = ((bd->totalCRC << 1) | (bd->totalCRC >> 31))
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
478 ^ bd->dataCRC;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
479
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
480 // If this block had a CRC error, force file level CRC error.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
481 if (bd->dataCRC != bd->headerCRC) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
482 bd->totalCRC = bd->headerCRC+1;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
483
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
484 return RETVAL_LAST_BLOCK;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
485 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
486 dataus_interruptus:
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
487 bd->writeCount = count;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
488 if (len) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
489 gotcount += bd->outbufPos;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
490 memcpy(outbuf, bd->outbuf, len);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
491
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
492 // If we got enough data, checkpoint loop state and return
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
493 if ((len-=bd->outbufPos)<1) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
494 bd->outbufPos -= len;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
495 if (bd->outbufPos)
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
496 memmove(bd->outbuf, bd->outbuf+len, bd->outbufPos);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
497 bd->writePos = pos;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
498 bd->writeCurrent = current;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
499 bd->writeRun = run;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
500
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
501 return gotcount;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
502 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
503 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
504 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
505 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
506
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
507 // Allocate the structure, read file header. If !len, src_fd contains
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
508 // filehandle to read from. Else inbuf contains data.
54
60a7fb8ddeb4 Add a quick and dirt bzcat (stdin to stdout only for the moment) to test
Rob Landley <rob@landley.net>
parents: 46
diff changeset
509 int start_bunzip(bunzip_data **bdp, int src_fd, char *inbuf, int len)
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
510 {
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
511 bunzip_data *bd;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
512 unsigned int i, j, c;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
513
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
514 // Figure out how much data to allocate.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
515 i = sizeof(bunzip_data);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
516 if (!len) i += IOBUF_SIZE;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
517
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
518 // Allocate bunzip_data. Most fields initialize to zero.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
519 if (!(bd = *bdp = malloc(i))) return RETVAL_OUT_OF_MEMORY;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
520 memset(bd,0,sizeof(bunzip_data));
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
521 if (len) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
522 bd->inbuf = inbuf;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
523 bd->inbufCount = len;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
524 bd->in_fd = -1;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
525 } else {
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
526 bd->inbuf = (char *)(bd+1);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
527 bd->in_fd = src_fd;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
528 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
529
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
530 // Init the CRC32 table (big endian)
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
531 for (i=0; i<256; i++) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
532 c = i<<24;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
533 for (j=8; j; j--)
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
534 c=c&0x80000000 ? (c<<1)^0x04c11db7 : (c<<1);
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
535 bd->crc32Table[i] = c;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
536 }
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
537
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
538 // Setup for I/O error handling via longjmp.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
539 i = setjmp(bd->jmpbuf);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
540 if (i) return i;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
541
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
542 // Ensure that file starts with "BZh".
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
543 for (i=0;i<3;i++)
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
544 if (get_bits(bd,8)!="BZh"[i]) return RETVAL_NOT_BZIP_DATA;
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
545
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
546 // Next byte ascii '1'-'9', indicates block size in units of 100k of
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
547 // uncompressed data. Allocate intermediate buffer for block.
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
548 i = get_bits(bd, 8);
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
549 if (i<'1' || i>'9') return RETVAL_NOT_BZIP_DATA;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
550 bd->dbufSize = 100000*(i-'0');
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
551 if (!(bd->dbuf = malloc(bd->dbufSize * sizeof(int))))
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
552 return RETVAL_OUT_OF_MEMORY;
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
553
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
554 return RETVAL_OK;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
555 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
556
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
557 // Example usage: decompress src_fd to dst_fd. (Stops at end of bzip data,
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
558 // not end of file.)
54
60a7fb8ddeb4 Add a quick and dirt bzcat (stdin to stdout only for the moment) to test
Rob Landley <rob@landley.net>
parents: 46
diff changeset
559 char *bunzipStream(int src_fd, int dst_fd)
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
560 {
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
561 bunzip_data *bd;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
562 int i;
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
563
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
564 if (!(i = start_bunzip(&bd,src_fd,0,0))) {
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
565 i = write_bunzip_data(bd,dst_fd,0,0);
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
566 if (i==RETVAL_LAST_BLOCK && bd->headerCRC==bd->totalCRC) i = RETVAL_OK;
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
567 }
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
568 flush_bunzip_outbuf(bd,dst_fd);
39
00e73c4dea66 More whitespace/cowbell. (And change comment style to //.)
Rob Landley <rob@landley.net>
parents: 37
diff changeset
569 free(bd->dbuf);
37
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
570 free(bd);
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
571 return bunzip_errors[-i];
14d27eab3acf Add my old micro-bunzip library. Needs some cleanup...
Rob Landley <rob@landley.net>
parents:
diff changeset
572 }