📄 imptool.cpp
字号:
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 + -