00001
00002
00003
00004
00005
00006 #include "zutil.h"
00007 #include "inftrees.h"
00008 #include "infblock.h"
00009 #include "infcodes.h"
00010 #include "infutil.h"
00011 #include "inffast.h"
00012
00013 struct inflate_codes_state {int dummy;};
00014
00015
00016 #define exop word.what.Exop
00017 #define bits word.what.Bits
00018
00019
00020 #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
00021 #define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
00022
00023
00024
00025
00026
00027
00028 int inflate_fast(bl, bd, tl, td, s, z)
00029 uInt bl, bd;
00030 inflate_huft *tl;
00031 inflate_huft *td;
00032 inflate_blocks_statef *s;
00033 z_streamp z;
00034 {
00035 inflate_huft *t;
00036 uInt e;
00037 uLong b;
00038 uInt k;
00039 Bytef *p;
00040 uInt n;
00041 Bytef *q;
00042 uInt m;
00043 uInt ml;
00044 uInt md;
00045 uInt c;
00046 uInt d;
00047 Bytef *r;
00048
00049
00050 LOAD
00051
00052
00053 ml = inflate_mask[bl];
00054 md = inflate_mask[bd];
00055
00056
00057 do {
00058
00059 GRABBITS(20)
00060 if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
00061 {
00062 DUMPBITS(t->bits)
00063 Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
00064 "inflate: * literal '%c'\n" :
00065 "inflate: * literal 0x%02x\n", t->base));
00066 *q++ = (Byte)t->base;
00067 m--;
00068 continue;
00069 }
00070 do {
00071 DUMPBITS(t->bits)
00072 if (e & 16)
00073 {
00074
00075 e &= 15;
00076 c = t->base + ((uInt)b & inflate_mask[e]);
00077 DUMPBITS(e)
00078 Tracevv((stderr, "inflate: * length %u\n", c));
00079
00080
00081 GRABBITS(15);
00082 e = (t = td + ((uInt)b & md))->exop;
00083 do {
00084 DUMPBITS(t->bits)
00085 if (e & 16)
00086 {
00087
00088 e &= 15;
00089 GRABBITS(e)
00090 d = t->base + ((uInt)b & inflate_mask[e]);
00091 DUMPBITS(e)
00092 Tracevv((stderr, "inflate: * distance %u\n", d));
00093
00094
00095 m -= c;
00096 r = q - d;
00097 if (r < s->window)
00098 {
00099 do {
00100 r += s->end - s->window;
00101 } while (r < s->window);
00102 e = s->end - r;
00103 if (c > e)
00104 {
00105 c -= e;
00106 do {
00107 *q++ = *r++;
00108 } while (--e);
00109 r = s->window;
00110 do {
00111 *q++ = *r++;
00112 } while (--c);
00113 }
00114 else
00115 {
00116 *q++ = *r++; c--;
00117 *q++ = *r++; c--;
00118 do {
00119 *q++ = *r++;
00120 } while (--c);
00121 }
00122 }
00123 else
00124 {
00125 *q++ = *r++; c--;
00126 *q++ = *r++; c--;
00127 do {
00128 *q++ = *r++;
00129 } while (--c);
00130 }
00131 break;
00132 }
00133 else if ((e & 64) == 0)
00134 {
00135 t += t->base;
00136 e = (t += ((uInt)b & inflate_mask[e]))->exop;
00137 }
00138 else
00139 {
00140 z->msg = (char*)"invalid distance code";
00141 UNGRAB
00142 UPDATE
00143 return Z_DATA_ERROR;
00144 }
00145 } while (1);
00146 break;
00147 }
00148 if ((e & 64) == 0)
00149 {
00150 t += t->base;
00151 if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
00152 {
00153 DUMPBITS(t->bits)
00154 Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
00155 "inflate: * literal '%c'\n" :
00156 "inflate: * literal 0x%02x\n", t->base));
00157 *q++ = (Byte)t->base;
00158 m--;
00159 break;
00160 }
00161 }
00162 else if (e & 32)
00163 {
00164 Tracevv((stderr, "inflate: * end of block\n"));
00165 UNGRAB
00166 UPDATE
00167 return Z_STREAM_END;
00168 }
00169 else
00170 {
00171 z->msg = (char*)"invalid literal/length code";
00172 UNGRAB
00173 UPDATE
00174 return Z_DATA_ERROR;
00175 }
00176 } while (1);
00177 } while (m >= 258 && n >= 10);
00178
00179
00180 UNGRAB
00181 UPDATE
00182 return Z_OK;
00183 }