diff options
author | Richard Purdie <rpurdie@rpsys.net> | 2006-06-22 17:47:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-22 18:05:58 -0400 |
commit | 4f3865fb57a04db7cca068fed1c15badc064a302 (patch) | |
tree | 4c923c72b6ac9b633c87cc73b55a75c7cfd0f044 /lib/zlib_inflate/infutil.h | |
parent | 4f1bcaf094ccc512c23e10104c05a6f8e5b7a9e4 (diff) |
[PATCH] zlib_inflate: Upgrade library code to a recent version
Upgrade the zlib_inflate implementation in the kernel from a patched
version 1.1.3/4 to a patched 1.2.3.
The code in the kernel is about seven years old and I noticed that the
external zlib library's inflate performance was significantly faster (~50%)
than the code in the kernel on ARM (and faster again on x86_32).
For comparison the newer deflate code is 20% slower on ARM and 50% slower
on x86_32 but gives an approx 1% compression ratio improvement. I don't
consider this to be an improvement for kernel use so have no plans to
change the zlib_deflate code.
Various changes have been made to the zlib code in the kernel, the most
significant being the extra functions/flush option used by ppp_deflate.
This update reimplements the features PPP needs to ensure it continues to
work.
This code has been tested on ARM under both JFFS2 (with zlib compression
enabled) and ppp_deflate and on x86_32. JFFS2 sees an approx. 10% real
world file read speed improvement.
This patch also removes ZLIB_VERSION as it no longer has a correct value.
We don't need version checks anyway as the kernel's module handling will
take care of that for us. This removal is also more in keeping with the
zlib author's wishes (http://www.zlib.net/zlib_faq.html#faq24) and I've
added something to the zlib.h header to note its a modified version.
Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Acked-by: Joern Engel <joern@wh.fh-wedel.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'lib/zlib_inflate/infutil.h')
-rw-r--r-- | lib/zlib_inflate/infutil.h | 176 |
1 files changed, 2 insertions, 174 deletions
diff --git a/lib/zlib_inflate/infutil.h b/lib/zlib_inflate/infutil.h index a15875fc5f72..eb1a9007bd86 100644 --- a/lib/zlib_inflate/infutil.h +++ b/lib/zlib_inflate/infutil.h | |||
@@ -11,184 +11,12 @@ | |||
11 | #ifndef _INFUTIL_H | 11 | #ifndef _INFUTIL_H |
12 | #define _INFUTIL_H | 12 | #define _INFUTIL_H |
13 | 13 | ||
14 | #include <linux/zconf.h> | 14 | #include <linux/zlib.h> |
15 | #include "inftrees.h" | ||
16 | #include "infcodes.h" | ||
17 | |||
18 | typedef enum { | ||
19 | TYPE, /* get type bits (3, including end bit) */ | ||
20 | LENS, /* get lengths for stored */ | ||
21 | STORED, /* processing stored block */ | ||
22 | TABLE, /* get table lengths */ | ||
23 | BTREE, /* get bit lengths tree for a dynamic block */ | ||
24 | DTREE, /* get length, distance trees for a dynamic block */ | ||
25 | CODES, /* processing fixed or dynamic block */ | ||
26 | DRY, /* output remaining window bytes */ | ||
27 | B_DONE, /* finished last block, done */ | ||
28 | B_BAD} /* got a data error--stuck here */ | ||
29 | inflate_block_mode; | ||
30 | |||
31 | /* inflate blocks semi-private state */ | ||
32 | struct inflate_blocks_state { | ||
33 | |||
34 | /* mode */ | ||
35 | inflate_block_mode mode; /* current inflate_block mode */ | ||
36 | |||
37 | /* mode dependent information */ | ||
38 | union { | ||
39 | uInt left; /* if STORED, bytes left to copy */ | ||
40 | struct { | ||
41 | uInt table; /* table lengths (14 bits) */ | ||
42 | uInt index; /* index into blens (or border) */ | ||
43 | uInt *blens; /* bit lengths of codes */ | ||
44 | uInt bb; /* bit length tree depth */ | ||
45 | inflate_huft *tb; /* bit length decoding tree */ | ||
46 | } trees; /* if DTREE, decoding info for trees */ | ||
47 | struct { | ||
48 | inflate_codes_statef | ||
49 | *codes; | ||
50 | } decode; /* if CODES, current state */ | ||
51 | } sub; /* submode */ | ||
52 | uInt last; /* true if this block is the last block */ | ||
53 | |||
54 | /* mode independent information */ | ||
55 | uInt bitk; /* bits in bit buffer */ | ||
56 | uLong bitb; /* bit buffer */ | ||
57 | inflate_huft *hufts; /* single malloc for tree space */ | ||
58 | Byte *window; /* sliding window */ | ||
59 | Byte *end; /* one byte after sliding window */ | ||
60 | Byte *read; /* window read pointer */ | ||
61 | Byte *write; /* window write pointer */ | ||
62 | check_func checkfn; /* check function */ | ||
63 | uLong check; /* check on output */ | ||
64 | |||
65 | }; | ||
66 | |||
67 | |||
68 | /* defines for inflate input/output */ | ||
69 | /* update pointers and return */ | ||
70 | #define UPDBITS {s->bitb=b;s->bitk=k;} | ||
71 | #define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} | ||
72 | #define UPDOUT {s->write=q;} | ||
73 | #define UPDATE {UPDBITS UPDIN UPDOUT} | ||
74 | #define LEAVE {UPDATE return zlib_inflate_flush(s,z,r);} | ||
75 | /* get bytes and bits */ | ||
76 | #define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} | ||
77 | #define NEEDBYTE {if(n)r=Z_OK;else LEAVE} | ||
78 | #define NEXTBYTE (n--,*p++) | ||
79 | #define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} | ||
80 | #define DUMPBITS(j) {b>>=(j);k-=(j);} | ||
81 | /* output bytes */ | ||
82 | #define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q) | ||
83 | #define LOADOUT {q=s->write;m=(uInt)WAVAIL;} | ||
84 | #define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} | ||
85 | #define FLUSH {UPDOUT r=zlib_inflate_flush(s,z,r); LOADOUT} | ||
86 | #define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} | ||
87 | #define OUTBYTE(a) {*q++=(Byte)(a);m--;} | ||
88 | /* load local pointers */ | ||
89 | #define LOAD {LOADIN LOADOUT} | ||
90 | |||
91 | /* masks for lower bits (size given to avoid silly warnings with Visual C++) */ | ||
92 | extern uInt zlib_inflate_mask[17]; | ||
93 | |||
94 | /* copy as much as possible from the sliding window to the output area */ | ||
95 | extern int zlib_inflate_flush ( | ||
96 | inflate_blocks_statef *, | ||
97 | z_streamp , | ||
98 | int); | ||
99 | |||
100 | /* inflate private state */ | ||
101 | typedef enum { | ||
102 | METHOD, /* waiting for method byte */ | ||
103 | FLAG, /* waiting for flag byte */ | ||
104 | DICT4, /* four dictionary check bytes to go */ | ||
105 | DICT3, /* three dictionary check bytes to go */ | ||
106 | DICT2, /* two dictionary check bytes to go */ | ||
107 | DICT1, /* one dictionary check byte to go */ | ||
108 | DICT0, /* waiting for inflateSetDictionary */ | ||
109 | BLOCKS, /* decompressing blocks */ | ||
110 | CHECK4, /* four check bytes to go */ | ||
111 | CHECK3, /* three check bytes to go */ | ||
112 | CHECK2, /* two check bytes to go */ | ||
113 | CHECK1, /* one check byte to go */ | ||
114 | I_DONE, /* finished check, done */ | ||
115 | I_BAD} /* got an error--stay here */ | ||
116 | inflate_mode; | ||
117 | |||
118 | struct internal_state { | ||
119 | |||
120 | /* mode */ | ||
121 | inflate_mode mode; /* current inflate mode */ | ||
122 | |||
123 | /* mode dependent information */ | ||
124 | union { | ||
125 | uInt method; /* if FLAGS, method byte */ | ||
126 | struct { | ||
127 | uLong was; /* computed check value */ | ||
128 | uLong need; /* stream check value */ | ||
129 | } check; /* if CHECK, check values to compare */ | ||
130 | uInt marker; /* if BAD, inflateSync's marker bytes count */ | ||
131 | } sub; /* submode */ | ||
132 | |||
133 | /* mode independent information */ | ||
134 | int nowrap; /* flag for no wrapper */ | ||
135 | uInt wbits; /* log2(window size) (8..15, defaults to 15) */ | ||
136 | inflate_blocks_statef | ||
137 | *blocks; /* current inflate_blocks state */ | ||
138 | |||
139 | }; | ||
140 | |||
141 | /* inflate codes private state */ | ||
142 | typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ | ||
143 | START, /* x: set up for LEN */ | ||
144 | LEN, /* i: get length/literal/eob next */ | ||
145 | LENEXT, /* i: getting length extra (have base) */ | ||
146 | DIST, /* i: get distance next */ | ||
147 | DISTEXT, /* i: getting distance extra */ | ||
148 | COPY, /* o: copying bytes in window, waiting for space */ | ||
149 | LIT, /* o: got literal, waiting for output space */ | ||
150 | WASH, /* o: got eob, possibly still output waiting */ | ||
151 | END, /* x: got eob and all data flushed */ | ||
152 | BADCODE} /* x: got error */ | ||
153 | inflate_codes_mode; | ||
154 | |||
155 | struct inflate_codes_state { | ||
156 | |||
157 | /* mode */ | ||
158 | inflate_codes_mode mode; /* current inflate_codes mode */ | ||
159 | |||
160 | /* mode dependent information */ | ||
161 | uInt len; | ||
162 | union { | ||
163 | struct { | ||
164 | inflate_huft *tree; /* pointer into tree */ | ||
165 | uInt need; /* bits needed */ | ||
166 | } code; /* if LEN or DIST, where in tree */ | ||
167 | uInt lit; /* if LIT, literal */ | ||
168 | struct { | ||
169 | uInt get; /* bits to get for extra */ | ||
170 | uInt dist; /* distance back to copy from */ | ||
171 | } copy; /* if EXT or COPY, where and how much */ | ||
172 | } sub; /* submode */ | ||
173 | |||
174 | /* mode independent information */ | ||
175 | Byte lbits; /* ltree bits decoded per branch */ | ||
176 | Byte dbits; /* dtree bits decoder per branch */ | ||
177 | inflate_huft *ltree; /* literal/length/eob tree */ | ||
178 | inflate_huft *dtree; /* distance tree */ | ||
179 | |||
180 | }; | ||
181 | 15 | ||
182 | /* memory allocation for inflation */ | 16 | /* memory allocation for inflation */ |
183 | 17 | ||
184 | struct inflate_workspace { | 18 | struct inflate_workspace { |
185 | inflate_codes_statef working_state; | 19 | struct inflate_state inflate_state; |
186 | struct inflate_blocks_state working_blocks_state; | ||
187 | struct internal_state internal_state; | ||
188 | unsigned int tree_work_area_1[19]; | ||
189 | unsigned int tree_work_area_2[288]; | ||
190 | unsigned working_blens[258 + 0x1f + 0x1f]; | ||
191 | inflate_huft working_hufts[MANY]; | ||
192 | unsigned char working_window[1 << MAX_WBITS]; | 20 | unsigned char working_window[1 << MAX_WBITS]; |
193 | }; | 21 | }; |
194 | 22 | ||