diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:08:28 -0700 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:08:28 -0700 |
commit | 6b834a58bdef976383cff6e2a83f353e668a9cf1 (patch) | |
tree | 5527def57f9d6eac4f3e709c10b9fd89905f2445 /inffast.c | |
parent | bdde4e09d21edff02ea5093b7f6eccbf166b272f (diff) | |
download | zlib-6b834a58bdef976383cff6e2a83f353e668a9cf1.tar.gz zlib-6b834a58bdef976383cff6e2a83f353e668a9cf1.tar.bz2 zlib-6b834a58bdef976383cff6e2a83f353e668a9cf1.zip |
zlib 0.93v0.93
Diffstat (limited to 'inffast.c')
-rw-r--r-- | inffast.c | 155 |
1 files changed, 82 insertions, 73 deletions
@@ -17,10 +17,6 @@ struct inflate_codes_state {int dummy;}; /* for buggy compilers */ | |||
17 | #define bits word.what.Bits | 17 | #define bits word.what.Bits |
18 | 18 | ||
19 | /* macros for bit input with no checking and for returning unused bytes */ | 19 | /* macros for bit input with no checking and for returning unused bytes */ |
20 | #ifdef DEBUG | ||
21 | # undef NEXTBYTE | ||
22 | # define NEXTBYTE (n--?0:fprintf(stderr,"inffast underrun\n"),*p++) | ||
23 | #endif | ||
24 | #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} | 20 | #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} |
25 | #define UNGRAB {n+=(c=k>>3);p-=c;k&=7;} | 21 | #define UNGRAB {n+=(c=k>>3);p-=c;k&=7;} |
26 | 22 | ||
@@ -36,7 +32,7 @@ struct inflate_blocks_state *s; | |||
36 | z_stream *z; | 32 | z_stream *z; |
37 | { | 33 | { |
38 | inflate_huft *t; /* temporary pointer */ | 34 | inflate_huft *t; /* temporary pointer */ |
39 | int e; /* extra bits or operation */ | 35 | uInt e; /* extra bits or operation */ |
40 | uLong b; /* bit buffer */ | 36 | uLong b; /* bit buffer */ |
41 | uInt k; /* bits in bit buffer */ | 37 | uInt k; /* bits in bit buffer */ |
42 | Byte *p; /* input data pointer */ | 38 | Byte *p; /* input data pointer */ |
@@ -52,7 +48,7 @@ z_stream *z; | |||
52 | /* load input, output, bit values */ | 48 | /* load input, output, bit values */ |
53 | LOAD | 49 | LOAD |
54 | 50 | ||
55 | /* initialize masks in registers */ | 51 | /* initialize masks */ |
56 | ml = inflate_mask[bl]; | 52 | ml = inflate_mask[bl]; |
57 | md = inflate_mask[bd]; | 53 | md = inflate_mask[bd]; |
58 | 54 | ||
@@ -60,93 +56,106 @@ z_stream *z; | |||
60 | do { /* assume called with m >= 258 && n >= 10 */ | 56 | do { /* assume called with m >= 258 && n >= 10 */ |
61 | /* get literal/length code */ | 57 | /* get literal/length code */ |
62 | GRABBITS(20) /* max bits for literal/length code */ | 58 | GRABBITS(20) /* max bits for literal/length code */ |
63 | if ((e = (t = tl + ((uInt)b & ml))->exop) < 0) | 59 | if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) |
64 | do { | ||
65 | if (e == -128) | ||
66 | { | ||
67 | z->msg = "invalid literal/length code"; | ||
68 | UNGRAB | ||
69 | UPDATE | ||
70 | return Z_DATA_ERROR; | ||
71 | } | ||
72 | DUMPBITS(t->bits) | ||
73 | e = -e; | ||
74 | if (e & 64) /* end of block */ | ||
75 | { | ||
76 | Tracevv((stderr, "inflate: * end of block\n")); | ||
77 | UNGRAB | ||
78 | UPDATE | ||
79 | return Z_STREAM_END; | ||
80 | } | ||
81 | } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0); | ||
82 | DUMPBITS(t->bits) | ||
83 | |||
84 | /* process literal or length (end of block already trapped) */ | ||
85 | if (e & 16) /* then it's a literal */ | ||
86 | { | 60 | { |
61 | DUMPBITS(t->bits) | ||
87 | Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? | 62 | Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? |
88 | "inflate: * literal '%c'\n" : | 63 | "inflate: * literal '%c'\n" : |
89 | "inflate: * literal 0x%02x\n", t->base)); | 64 | "inflate: * literal 0x%02x\n", t->base)); |
90 | *q++ = (Byte)t->base; | 65 | *q++ = (Byte)t->base; |
91 | m--; | 66 | m--; |
67 | continue; | ||
92 | } | 68 | } |
93 | else /* it's a length */ | 69 | do { |
94 | { | 70 | DUMPBITS(t->bits) |
95 | /* get length of block to copy (already have extra bits) */ | 71 | if (e & 16) |
96 | c = t->base + ((uInt)b & inflate_mask[e]); | 72 | { |
97 | DUMPBITS(e); | 73 | /* get extra bits for length */ |
98 | Tracevv((stderr, "inflate: * length %u\n", c)); | 74 | e &= 15; |
75 | c = t->base + ((uInt)b & inflate_mask[e]); | ||
76 | DUMPBITS(e) | ||
77 | Tracevv((stderr, "inflate: * length %u\n", c)); | ||
99 | 78 | ||
100 | /* decode distance base of block to copy */ | 79 | /* decode distance base of block to copy */ |
101 | GRABBITS(15); /* max bits for distance code */ | 80 | GRABBITS(15); /* max bits for distance code */ |
102 | if ((e = (t = td + ((uInt)b & md))->exop) < 0) | 81 | e = (t = td + ((uInt)b & md))->exop; |
103 | do { | 82 | do { |
104 | if (e == -128) | 83 | DUMPBITS(t->bits) |
84 | if (e & 16) | ||
85 | { | ||
86 | /* get extra bits to add to distance base */ | ||
87 | e &= 15; | ||
88 | GRABBITS(e) /* get extra bits (up to 13) */ | ||
89 | d = t->base + ((uInt)b & inflate_mask[e]); | ||
90 | DUMPBITS(e) | ||
91 | Tracevv((stderr, "inflate: * distance %u\n", d)); | ||
92 | |||
93 | /* do the copy */ | ||
94 | m -= c; | ||
95 | if ((uInt)(q - s->window) >= d) /* offset before dest */ | ||
96 | { /* just copy */ | ||
97 | r = q - d; | ||
98 | *q++ = *r++; c--; /* minimum count is three, */ | ||
99 | *q++ = *r++; c--; /* so unroll loop a little */ | ||
100 | } | ||
101 | else /* else offset after destination */ | ||
102 | { | ||
103 | e = d - (q - s->window); /* bytes from offset to end */ | ||
104 | r = s->end - e; /* pointer to offset */ | ||
105 | if (c > e) /* if source crosses, */ | ||
106 | { | ||
107 | c -= e; /* copy to end of window */ | ||
108 | do { | ||
109 | *q++ = *r++; | ||
110 | } while (--e); | ||
111 | r = s->window; /* copy rest from start of window */ | ||
112 | } | ||
113 | } | ||
114 | do { /* copy all or what's left */ | ||
115 | *q++ = *r++; | ||
116 | } while (--c); | ||
117 | break; | ||
118 | } | ||
119 | else if ((e & 64) == 0) | ||
120 | e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; | ||
121 | else | ||
105 | { | 122 | { |
106 | z->msg = "invalid distance code"; | 123 | z->msg = "invalid distance code"; |
107 | UNGRAB | 124 | UNGRAB |
108 | UPDATE | 125 | UPDATE |
109 | return Z_DATA_ERROR; | 126 | return Z_DATA_ERROR; |
110 | } | 127 | } |
111 | DUMPBITS(t->bits) | 128 | } while (1); |
112 | e = -e; | 129 | break; |
113 | } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0); | ||
114 | DUMPBITS(t->bits) | ||
115 | |||
116 | /* get extra bits to add to distance base */ | ||
117 | GRABBITS((uInt)e) /* get extra bits (up to 13) */ | ||
118 | d = t->base + ((uInt)b & inflate_mask[e]); | ||
119 | DUMPBITS(e) | ||
120 | Tracevv((stderr, "inflate: * distance %u\n", d)); | ||
121 | |||
122 | /* do the copy */ | ||
123 | m -= c; | ||
124 | if ((uInt)(q - s->window) >= d) /* if offset before destination, */ | ||
125 | { /* just copy */ | ||
126 | r = q - d; | ||
127 | *q++ = *r++; c--; /* minimum count is three, */ | ||
128 | *q++ = *r++; c--; /* so unroll loop a little */ | ||
129 | do { | ||
130 | *q++ = *r++; | ||
131 | } while (--c); | ||
132 | } | 130 | } |
133 | else /* else offset after destination */ | 131 | if ((e & 64) == 0) |
134 | { | 132 | { |
135 | e = d - (q - s->window); /* bytes from offset to end */ | 133 | if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) |
136 | r = s->end - e; /* pointer to offset */ | ||
137 | if (c > (uInt)e) /* if source crosses, */ | ||
138 | { | 134 | { |
139 | c -= e; /* copy to end of window */ | 135 | DUMPBITS(t->bits) |
140 | do { | 136 | Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? |
141 | *q++ = *r++; | 137 | "inflate: * literal '%c'\n" : |
142 | } while (--e); | 138 | "inflate: * literal 0x%02x\n", t->base)); |
143 | r = s->window; /* copy rest from start of window */ | 139 | *q++ = (Byte)t->base; |
140 | m--; | ||
141 | break; | ||
144 | } | 142 | } |
145 | do { /* copy all or what's left */ | ||
146 | *q++ = *r++; | ||
147 | } while (--c); | ||
148 | } | 143 | } |
149 | } | 144 | else if (e & 32) |
145 | { | ||
146 | Tracevv((stderr, "inflate: * end of block\n")); | ||
147 | UNGRAB | ||
148 | UPDATE | ||
149 | return Z_STREAM_END; | ||
150 | } | ||
151 | else | ||
152 | { | ||
153 | z->msg = "invalid literal/length code"; | ||
154 | UNGRAB | ||
155 | UPDATE | ||
156 | return Z_DATA_ERROR; | ||
157 | } | ||
158 | } while (1); | ||
150 | } while (m >= 258 && n >= 10); | 159 | } while (m >= 258 && n >= 10); |
151 | 160 | ||
152 | /* not enough input or output--restore pointers and return */ | 161 | /* not enough input or output--restore pointers and return */ |