⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imptool.cpp

📁 一个解压程序,只要设定了解压路径和解压文件的种类,就可以随意解压
💻 CPP
📖 第 1 页 / 共 2 页
字号:
       treemtf[0]=treenum;
      }
     codes=0;
     continue;
    }
   codes++;
   hcode=getbits(BWTTBITS)&(BWTTSIZE-1);
   code=ttable[treenum][hcode];
   if(code<0)
    {
     if(code==-MAX_NCODES)return -3;
     hcode=getbits(MAXCODELEN)>>BWTTBITS;
     code=-code;
     do
      {
       code=hdchain[treenum][code][hcode&1];
       hcode>>=1;
      }
     while(code>0);
     if(code==-MAX_NCODES)return -3;
     code=-code;
    }
   USEDBITS(hclengths[treenum][code]);
   if(code<2)
    {
     rpt=rptbase<<code;
     if(dest+rpt>output_end)rpt=output_end-dest;
     i=mtf[0];
     count[i+1]+=rpt;
     while(rpt--)*dest++=i;
     rptbase<<=1;
    }
   else if(code<257)
    {
     i=mtf[--code];
     *dest++=i;
     for(;code;code--)mtf[code]=mtf[code-1];
     mtf[0]=i;
     count[i+1]++;
     rptbase=1;
    }
   else
    {
     start=dest-output;
     dest++;
     rptbase=1;
    }
  }
 count[0]=1;
 for(i=1;i<256;i++)count[i]+=count[i-1];
 links=new unsigned long[exsize+1];
 for(link=0;link<=exsize;link++)
   if(link!=start)links[link]=(output[link]<<24)|count[output[link]]++;
 links[start]=0;
 for(link=0,dest=output_end-2;dest>=output;dest--)
  {
   link=links[link&0xFFFFFF];
   *dest=(link>>24)+rc;
  }
 delete [] links;
 return 0;
}

int CImpTool::expand_lz(unsigned char *output, int start, int exsize, int mm)
{
 unsigned long huffcodes[MAX_NCODES];
 int llcode_table[LLTTSIZE],distcode_table[3][DTTSIZE];
 int llcode_chain[NLLCODES][2],distcode_chain[3][NDCODES][2];
 unsigned long dist_base[NDCODES-6],dist_mask[NDCODES-6];
 unsigned char dist_extra[NDCODES-6],len_base[NLLCODES-268],len_mask[NLLCODES-268],
   len_extra[NLLCODES-268];
 unsigned char *dest,*output_end;
 int i,j,treenum,code,num_dist_trees,dist_split,numcodes,numtrees;
 unsigned long len;
 unsigned long hcode,dist,last_dist,last_dist2;
 unsigned char *code_lengths,*codelen_src;

 if(mm)g_mmptr=0;
 num_dist_trees=getbits(2)&3;
 USEDBITS(2);
 if(!num_dist_trees)return -3;
 dist_split=num_dist_trees>2;
 numcodes=NLLCODES+NDCODES+ND2CODES;
 if(dist_split)numcodes+=ND3CODES;
 dest=output+start;
 output_end=dest+exsize;
 numtrees=getbits(6);
 USEDBITS(6);
 numtrees&=63;
 if(numtrees)code_lengths=new unsigned char[numcodes*numtrees];
 else code_lengths=new unsigned char[MIN_LZ_CODES];

 i=load_hcodes(code_lengths,numcodes,numtrees,start+exsize);
 if(i<0){delete [] code_lengths;return i;}
 for(i=2,len=11,code=0; code<NLLCODES-268; i<<=1)
   for(j=code+4; code<j; len+=i)len_base[code++]=(unsigned char)len;
 for(i=1,code=0; code<NLLCODES-268; i++)
   for(j=code+4; code<j; code++)len_extra[code]=i;
 for(code=0,len=1; code<NLLCODES-268; len=(len<<1)+1)
   for(j=code+4; code<j; code++)len_mask[code]=(unsigned char)len;
 for(hcode=2,dist=5,code=0; code<NDCODES-6; hcode<<=1)
  {
   dist_base[code]=dist; dist+=hcode;
   dist_base[code+1]=dist; dist+=hcode;
   code+=2;
  }
 for(i=1,code=0; code<NDCODES-6; i++,code+=2)
   dist_extra[code]=dist_extra[code+1]=i;
 for(code=0,dist=1; code<NDCODES-6; dist=(dist<<1)+1,code+=2)
   dist_mask[code]=dist_mask[code+1]=dist;
 codelen_src=code_lengths-numcodes;
 last_dist=0;last_dist2=0;
 code=256;
 numtrees+=!numtrees;
 while(dest<output_end)
  {
   if(code==256)
    {
     if(!numtrees)break;
     numtrees--;
     codelen_src+=numcodes;
     make_codes(huffcodes,codelen_src,NLLCODES);
     make_decode_tables(llcode_table,llcode_chain,huffcodes,codelen_src,LLTTBITS,NLLCODES);
     codelen_src+=NLLCODES;
     for(i=0;i<num_dist_trees;i++)
      {
       make_codes(huffcodes,codelen_src,g_ncodes[i]);
       make_decode_tables(distcode_table[i],distcode_chain[i],huffcodes,codelen_src,DTTBITS,g_ncodes[i]);
       codelen_src+=g_ncodes[i];
      }
     codelen_src-=numcodes;
     code=0;
    }
   code=llcode_table[getbits(LLTTBITS)&(LLTTSIZE-1)];
   if(code<0)
    {
     if(code==-MAX_NCODES)break;
     hcode=getbits(MAXCODELEN)>>LLTTBITS;
     code=-code;
     do
      {
       code=llcode_chain[code][hcode&1];
       hcode>>=1;
      }
     while(code>0);
     if(code==-MAX_NCODES)break;
     code=-code;
    }
   USEDBITS(codelen_src[code]);
   if(code<256)*dest++=code;
   else if(code>256)
    {
     if(code<266)len=code-255;
     else if(code<LONGMATCHCODE)
      {
       len=getbits(5);
       USEDBITS(len_extra[code-266]);
       len=(len&len_mask[code-266])+len_base[code-266];
      }
     else if(code==LONGMATCHCODE)
      {
       len=(getbits(LONGMATCHBITS)&LONGMATCHMASK)+259;
       USEDBITS(LONGMATCHBITS);
      }
     else
      {
       len=getbits(3)&7;
       USEDBITS(3);
       g_mmlist[g_mmptr++]=(dest-output)|(len<<24);
       continue;
      }
     treenum=(len==2)+((dist_split&(len==3))<<1);
     code=distcode_table[treenum][getbits(DTTBITS)&(DTTSIZE-1)];
     if(code<0)
      {
       if(code==-MAX_NCODES)break;
       hcode=getbits(MAXCODELEN)>>DTTBITS;
       code=-code;
       do
        {
         code=distcode_chain[treenum][code][hcode&1];
         hcode>>=1;
        }
       while(code>0);
       if(code==-MAX_NCODES)break;
       code=-code;
      }
     USEDBITS(codelen_src[code+g_ncoffset[treenum]]);
     if(!code)dist=last_dist;
     else if(code==1)
      {
       dist=last_dist2;
       last_dist2=last_dist;
       last_dist=dist;
      }
     else
      {
       if(code<6)dist=code-1;
       else
        {
         dist=getbits(18);
         USEDBITS(dist_extra[code-6]);
         dist=(dist&dist_mask[code-6])+dist_base[code-6];
         last_dist2=last_dist;
         last_dist=dist;
        }
      }
     if(dist<=(unsigned long)(dest-output))
       while(len-- && dest<output_end)*dest=dest[-(signed)dist],dest++;
    }
  }
 delete [] code_lengths;
 if(mm)reverse_mm(output,start+exsize);
 return dest-output-start;
}

int CImpTool::load_hcodes(unsigned char *hclengths, int ncodes, int ntrees, int exsize)
{
 int i,j,dzrpt,zrpt,len,hcode,code;
 unsigned char hlclens[NLENCODES];
 unsigned char *hcldest,*hclend,*hclrpt;
 unsigned long huffcodes[NLENCODES];
 int ttable[HCTTSIZE];
 int hdchain[NLENCODES][2];

 if(!ntrees){load_fixed_codes(hclengths,exsize);return 0;}
 memset(hlclens,0,NLENCODES);
 for(i=0,j=1;i<NLENCODES;)
  {
   code=getbits(5)&31;
   USEDBITS(5);
   if(code<2)
    {i+=j<<code;
     j<<=1;}
   else
    {if(code>MAXCODELEN+1)return -3;
     hlclens[i++]=code-1;
     j=1;}
  }
 make_codes(huffcodes,hlclens,NLENCODES);
 make_decode_tables(ttable,hdchain,huffcodes,hlclens,HCTTBITS,NLENCODES);
 hcldest=hclengths;
 hclend=hclengths+ncodes*ntrees;
 hclrpt=hclengths+ncodes;
 len=0;dzrpt=1;zrpt=1;
 while(hcldest<hclend)
  {
   code=ttable[getbits(HCTTBITS)&(HCTTSIZE-1)];
   if(code<0)
    {
     if(code==-MAX_NCODES)return -3;
     hcode=getbits(MAXCODELEN)>>HCTTBITS;
     code=-code;
     do
      {
       code=hdchain[code][hcode&1];
       hcode>>=1;
      }
     while(code>0);
     if(code==-MAX_NCODES)return -3;
     code=-code;
    }
   USEDBITS(hlclens[code]);
   if(code>=DZRUN)
    {
     code=dzrpt<<(code-DZRUN);
     while(code-- && hcldest<hclend)
      {
       if(hcldest>=hclrpt && hcldest[-ncodes])len=hcldest[-ncodes];
       *hcldest++=len;
      }
     dzrpt<<=1;
     zrpt=1;
    }
   else if(code>=ZRUN)
    {
     code=zrpt<<(code-ZRUN);
     while(code-- && hcldest<hclend)*hcldest++=0;
     zrpt<<=1;
     dzrpt=1;
    }
   else
    {
     if(hcldest>=hclrpt && hcldest[-ncodes])len=code+hcldest[-ncodes];
     else len+=code;
     if(len>MAXCODELEN)len-=MAXCODELEN+1;
     *hcldest++=len;
     dzrpt=1;zrpt=1;
    }
  }
 for(hcldest=hclengths;hcldest<hclend;hcldest++)if(*hcldest>MAXCODELEN)return -3;
 return 0;
}

void CImpTool::reverse_mm(unsigned char *block,int bsize)
{
 int m,d;
 unsigned char *src,*end;
 
 for(m=0;m<g_mmptr;m++)
  {
   d=-(signed)(g_mmlist[m]>>24);
   if(!d)continue;
   src=block+(g_mmlist[m]&0xFFFFFF);
   end=block+bsize;
   if(m<g_mmptr-1)end=block+(g_mmlist[m+1]&0xFFFFFF);
   while(src<end)*src+=src[d],src++;
  }
}

void CImpTool::redo_mm(unsigned long overlap)
{
 int mmptr,d;
 unsigned char *start,*src,*end;
 
 start=g_blockbuffer+g_blockstart-overlap;
 if(start<g_blockbuffer)start=g_blockbuffer;
 for(mmptr=g_mmptr-1;mmptr>=0;mmptr--)
  {
   d=-(signed)(g_mmlist[mmptr]>>24);
   if(!d)continue;
   end=g_blockbuffer+(g_mmlist[mmptr]&0xFFFFFF);
   if(end<start)end=start;
   src=g_blockbuffer+g_blockstart;
   if(mmptr<g_mmptr-1)src=g_blockbuffer+(g_mmlist[mmptr+1]&0xFFFFFF);
   for(src--;src>=end;src--)*src-=src[d];
   if(end<=start)break;
  }
}


void CImpTool::make_codes(unsigned long *huffcodes,unsigned char *hclengths,int ncodes)
{
 unsigned long i,j,k,l,count[MAXCODELEN+1],nextcode[MAXCODELEN+1];

 memset(count,0,sizeof(count));
 for(i=0;i<(unsigned)ncodes;i++)count[hclengths[i]]++;
 count[0]=0;
 for(i=1,k=0;i<=MAXCODELEN;i++)
  {
   k=(k+count[i-1])<<1;
   nextcode[i]=k;
  }
 for(i=0;i<(unsigned)ncodes;i++)
  {
   j=hclengths[i];
   if(j)
    {
     l=0;
     k=nextcode[j]++;
     for(;j>0;j--)
      {
       l<<=1;
       l+=k&1;
       k>>=1;
      }
     huffcodes[i]=l;
    }
  }
}

int CImpTool::make_decode_tables(int *ttable, int hdchain[][2], unsigned long *huffcodes,unsigned char *hclengths, int ttbits, int ncodes)
{
 int hdnode,hdndest,i,ttsize;
 unsigned long base,n,hcode;

 ttsize=1<<ttbits;
 if(hdchain)for(i=0;i<ncodes;i++)hdchain[i][0]=hdchain[i][1]=-MAX_NCODES;
 for(i=0;i<ttsize;i++)ttable[i]=-MAX_NCODES;
 hdndest=1;
 for(i=0;i<ncodes;i++)if(hclengths[i])
  {
   base=1<<hclengths[i];
   n=huffcodes[i];
   if(base<=(unsigned)ttsize)
    {
     while(n<(unsigned)ttsize) /*n should be less than ttsize but it might be invalid*/
      {
       ttable[n]=i;
       n+=base;
      }
    }
   else if(hdchain)
    {
     base=hclengths[i]-ttbits-1;
     n&=ttsize-1;
     hcode=huffcodes[i]>>ttbits;
     if(ttable[n]==-MAX_NCODES)
      {
       ttable[n]=-hdndest;
       hdnode=hdndest++;
      }
     else
      {
       hdnode=-ttable[n];
       while(hdchain[hdnode][hcode&1]>=0)
        {
         hdnode=hdchain[hdnode][hcode&1];
         hcode>>=1;
         base--;
        }
      }
     while(base--)
      {
       if(hdndest==ncodes)return -3;
       hdchain[hdnode][hcode&1]=hdndest;
       hdnode=hdndest++;
       hcode>>=1;
      }
     hdchain[hdnode][hcode&1]=-i;
    }
  }
 return 0;
}

void CImpTool::load_fixed_codes(unsigned char *hclens,int exsize)
{
 memset(hclens,8,244);
 memset(hclens+244,9,17);
 hclens[256]=0;
 memset(hclens+261,10,5);
 memset(hclens+266,11,NLLCODES-266);
 if(exsize<=8192)
  {memset(hclens+NLLCODES,4,4);
   memset(hclens+NLLCODES+4,5,24);
   memset(hclens+NLLCODES+28,0,NDCODES-28);}
 else
  {memset(hclens+NLLCODES,5,22);
   memset(hclens+NLLCODES+22,6,NDCODES-22);}
 memset(hclens+NLLCODES+NDCODES,4,ND2CODES);
 hclens[NLLCODES+NDCODES]=3;
 hclens[NLLCODES+NDCODES+1]=3;
}



int CImpTool::e8ut_crc_write(FILE *outfile,unsigned char *block,int size,unsigned long e8offset,unsigned long srcsize,int last)
{
 int i,w;
 unsigned char *src,*src2,*end;

 if(g_e8extra)
  {
   i=sizeof(g_e8buf)-g_e8extra;
   memcpy(g_e8buf+g_e8extra,block,i>size ? size : i);
   if(i>size)block=g_e8buf,size+=g_e8extra,e8offset-=g_e8extra;
   else
    {
     if(g_e8t==2)i=e8ut_crc_wr16(outfile,g_e8buf,g_e8extra,e8offset-g_e8extra);
     else i=e8ut_crc_wr32(outfile,g_e8buf,g_e8extra,e8offset-g_e8extra,srcsize);
     if(i<0)return i;
     block+=i;
     e8offset+=i;
     size-=i;
    }
  }
 if(g_e8t==2)i=e8ut_crc_wr16(outfile,block,size-g_e8t,e8offset);
 else i=e8ut_crc_wr32(outfile,block,size-g_e8t,e8offset,srcsize);
 if(i<0)return i;
 end=block+size;
 src=end-g_e8t+i;
 src2=src;
 while(src2<end && (*src2!=0xE8 || last))g_crc=crctbl[(unsigned char)g_crc^*src2++]^(g_crc>>8);
 if(src2>src)
  {
   w=fwrite(src,1,src2-src,outfile);
   if(w<src2-src)return -3;
  }
 g_e8extra=end-src2;
 if(g_e8extra)memmove(g_e8buf,src2,g_e8extra);
 return 0;
}

int CImpTool::e8ut_crc_wr16(FILE *outfile,unsigned char *block,int size,unsigned long e8offset)
{
 unsigned char buffer[16384];
 int w;
 unsigned int u;
 unsigned char *src,*end,*dest;
 unsigned char c;

 src=block;
 end=block+size;
 dest=buffer;
 while(src<end)
  {
   if(end-src>sizeof(buffer)-3)end=src+sizeof(buffer)-3;
   while(src<end)
    {
     c=*dest++=*src++;
     g_crc=crctbl[(unsigned char)g_crc^c]^(g_crc>>8);
     if(c==0xE8)
      {
       u=(src[0]+(src[1]<<8))-(unsigned short)(e8offset+(src-block));
       *dest=(unsigned char)u;
       dest[1]=(unsigned char)(u>>8);
       src+=2;
       g_crc=crctbl[(unsigned char)g_crc^*dest++]^(g_crc>>8);
       g_crc=crctbl[(unsigned char)g_crc^*dest++]^(g_crc>>8);
      }
    }
   w=fwrite(buffer,1,dest-buffer,outfile);
   dest=buffer;
   end=block+size;
  }
 return src-end;
}

int CImpTool::e8ut_crc_wr32(FILE *outfile,unsigned char *block,int size,unsigned long e8offset,unsigned long srcsize)
{
 unsigned char buffer[16384];
 int i,j,w;
 unsigned char *src,*end,*end2,*dest;
 unsigned char c;

 src=block;
 end=block+size;
 dest=buffer;
 if(end-src>sizeof(buffer)-5)end=src+sizeof(buffer)-5;
 while(src<end)
  {
   if(end-src>sizeof(buffer)-5)end=src+sizeof(buffer)-5;
   while(src<end)
    {
     c=*dest++=*src++;
     g_crc=crctbl[(unsigned char)g_crc^c]^(g_crc>>8);
     if(c==0xE8)
      {
       i=src[0]+(src[1]<<8)+(src[2]<<16)+(src[3]<<24);
	   j=e8offset+(src-block);
       if(i<0 && i>=-j)i=srcsize-i-j-1;
       else if((unsigned int)i<(unsigned int)srcsize)i-=j;
       src+=4;
       for(end2=dest+4;dest<end2;dest++,i>>=8)
        {
         *dest=(unsigned char)i;
         g_crc=crctbl[(unsigned char)g_crc^*dest]^(g_crc>>8);
        }
      }
    }
   w=fwrite(buffer,1,dest-buffer,outfile);
   dest=buffer;
   end=block+size;
  }
 return src-end;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -