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 if ((uInt)(q - s->window) >= d)
00097 {
00098 r = q - d;
00099 *q++ = *r++; c--;
00100 *q++ = *r++; c--;
00101 }
00102 else
00103 {
00104 e = d - (uInt)(q - s->window);
00105 r = s->end - e;
00106 if (c > e)
00107 {
00108 c -= e;
00109 do {
00110 *q++ = *r++;
00111 } while (--e);
00112 r = s->window;
00113 }
00114 }
00115 do {
00116 *q++ = *r++;
00117 } while (--c);
00118 break;
00119 }
00120 else if ((e & 64) == 0)
00121 {
00122 t += t->base;
00123 e = (t += ((uInt)b & inflate_mask[e]))->exop;
00124 }
00125 else
00126 {
00127 z->msg = (char*)"invalid distance code";
00128 UNGRAB
00129 UPDATE
00130 return Z_DATA_ERROR;
00131 }
00132 } while (1);
00133 break;
00134 }
00135 if ((e & 64) == 0)
00136 {
00137 t += t->base;
00138 if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
00139 {
00140 DUMPBITS(t->bits)
00141 Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
00142 "inflate: * literal '%c'\n" :
00143 "inflate: * literal 0x%02x\n", t->base));
00144 *q++ = (Byte)t->base;
00145 m--;
00146 break;
00147 }
00148 }
00149 else if (e & 32)
00150 {
00151 Tracevv((stderr, "inflate: * end of block\n"));
00152 UNGRAB
00153 UPDATE
00154 return Z_STREAM_END;
00155 }
00156 else
00157 {
00158 z->msg = (char*)"invalid literal/length code";
00159 UNGRAB
00160 UPDATE
00161 return Z_DATA_ERROR;
00162 }
00163 } while (1);
00164 } while (m >= 258 && n >= 10);
00165
00166
00167 UNGRAB
00168 UPDATE
00169 return Z_OK;
00170 }