summaryrefslogtreecommitdiff
path: root/inffast.c
diff options
context:
space:
mode:
Diffstat (limited to 'inffast.c')
-rw-r--r--inffast.c155
1 files changed, 82 insertions, 73 deletions
diff --git a/inffast.c b/inffast.c
index 2fd707e..49ed1df 100644
--- a/inffast.c
+++ b/inffast.c
@@ -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;
36z_stream *z; 32z_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 */