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 }