📄 ziptool.cpp
字号:
suffix_of[code] = code;
}
// 偦偺懠傕傠傕傠
oldcode = GetCode();
if( bits_eof )
return;
finchar = oldcode;
BYTE f=finchar;
zipwrite( &f,1 );
stackp = 8192;
while( left>0 && !bits_eof )
{
// code 傪堦屄庢傝弌偡
code = GetCode();
if( bits_eof )
break;
// clear!
while( code == 256 )
{
switch( GetCode() )
{
case 1:
codesize++;
if( codesize == 13 )
maxcode = (1 << codesize);
else
maxcode = (1 << codesize) - 1;
break;
case 2: // partial_clear !!
{
int pr,cd;
for( cd=257; cd<free_ent; cd++ )
prefix_of[cd] |= 0x8000;
for( cd=257; cd<free_ent; cd++)
{
pr = prefix_of[cd] & 0x7fff;
if( pr >= 257 )
prefix_of[pr] &= 0x7fff;
}
for( cd=257; cd<free_ent; cd++ )
if( (prefix_of[cd] & 0x8000) != 0 )
prefix_of[cd] = -1;
cd = 257;
while( (cd < (1<<13)) && (prefix_of[cd] != -1) )
cd++;
free_ent = cd;
}
break;
}
code = GetCode();
if( bits_eof )
break;
}
if( bits_eof )
break;
// 摿庩側応崌( KwKwK )
incode = code;
if( prefix_of[code] == -1 )
{
stack[--stackp] = finchar;
code = oldcode;
}
// 帿彂偐傜僗僞僢僋傊
while( code >= 257 )
{
stack[--stackp] = suffix_of[code];
code = prefix_of[code];
}
finchar = suffix_of[code];
stack[--stackp] = finchar;
// 僗僞僢僋偐傜弌椡
left -= (8192-stackp);
zipwrite( stack+stackp, (8192-stackp) );
stackp = 8192;
// 怴偟偄僄儞僩儕傪捛壛
code = free_ent;
if( code < (1<<13) )
{
prefix_of[code] = oldcode;
suffix_of[code] = finchar;
do
code++;
while( (code < (1<<13)) && (prefix_of[code] != -1) );
free_ent = code;
}
// 慜偺傪妎偊偰偲偔
oldcode = incode;
}
#undef GetCode
}
////////////////////////////////////////////////////////////////
// Reduce 丗 lz77 + 曄側晞崋壔(^^; PkZip 0.x
////////////////////////////////////////////////////////////////
void CZipTool::LoadFollowers( BYTE* Slen, BYTE followers[][64] )
{
for( int x=255; x>=0; x-- )
{
Slen[x] = getbits(6);
for( int i=0; i<Slen[x]; i++ )
followers[x][i] = getbits(8);
}
}
void CZipTool::Unreduce( DWORD usz, DWORD csz, int factor )
{
unsigned char* outbuf = CTool::common_buf;
unsigned char* outpos=outbuf;
memset( outbuf,0,0x4000 );
int left = (signed)usz;
#define RED_FLUSH() zipwrite(outbuf,outpos-outbuf), outpos=outbuf;
#define RED_OUTC(c) {(*outpos++)=c; left--; if(outpos-outbuf==0x4000) RED_FLUSH();}
//--------------------------------------------------------------------//
static const int Length_table[] = {0, 0x7f, 0x3f, 0x1f, 0x0f};
static const int D_shift[] = {0, 0x07, 0x06, 0x05, 0x04};
static const int D_mask[] = {0, 0x01, 0x03, 0x07, 0x0f};
static const int B_table[] = {
8, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8};
initbits();
BYTE followers[256][64];
BYTE Slen[256];
LoadFollowers( Slen, followers );
int l_stage = 0;
int l_char = 0;
int ch, V, Len;
while( !bits_eof && left>0 )
{
if( Slen[l_char] == 0 )
ch = getbits(8);
else
{
if( getbits(1) )
ch = getbits(8);
else
{
int bitsneeded = B_table[ Slen[l_char] ];
ch = followers[ l_char ][ getbits(bitsneeded) ];
}
}
// Repeater Decode
switch( l_stage )
{
case 0:
if( ch == 0x90 )// hit傪帵偡僼儔僌側傜丄師偺僗僥乕僕傊
l_stage++;
else // 偦偺傑傑弌椡
RED_OUTC( ch )
break;
case 1:
if( ch == 0x00 )// hit僼儔僌傪偦偺傑傑弌椡
{
RED_OUTC(0x90)
l_stage = 0;
}
else // 挿偝傪庢摼( 儊僜僢僪埶懚 )
{
V = ch;
Len = V & Length_table[factor];
if( Len == Length_table[factor] )
l_stage = 2;
else
l_stage = 3;
}
break;
case 2: // 挿偝傪捛壛庢摼
Len += ch;
l_stage++;
break;
case 3: // 儅僢僠偟偨晹暘傪弌椡( 儊僜僢僪埶懚 )
{
int i = Len+3;
int offset = (((V>>D_shift[factor]) & D_mask[factor]) << 8) + ch + 1;
int op = (((outpos-outbuf)-offset) & 0x3fff);
while( i-- )
{
RED_OUTC( outbuf[op++] );
op &= 0x3fff;
}
l_stage = 0;
}
break;
}
l_char = ch;
}
RED_FLUSH();
#undef RED_FLUSH
#undef RED_OUTC
}
////////////////////////////////////////////////////////////////
// Implode 丗 lz77 + shanon-fano ? PkZip 1.x
////////////////////////////////////////////////////////////////
void CZipTool::Explode( DWORD usz, DWORD csz, bool _8k, bool littree )
{
unsigned char* outbuf = CTool::common_buf;
unsigned char* outpos=outbuf;
memset( outbuf,0,0x4000 );
int left = (signed)usz;
#define EXP_FLUSH() zipwrite(outbuf,outpos-outbuf), outpos=outbuf;
#define EXP_OUTC(c) {(*outpos++)=c; left--; if(outpos-outbuf==0x4000) EXP_FLUSH();}
//--------------------------------------------------------------------//
BYTE ch;
initbits();
int dict_bits = ( _8k ? 7 : 6);
int min_match_len = (littree ? 3 : 2);
sf_tree lit_tree;
sf_tree length_tree;
sf_tree distance_tree;
// 栘傪儘乕僪
if( littree )
LoadTree( &lit_tree, 256 );
LoadTree( &length_tree, 64 );
LoadTree( &distance_tree, 64 );
// 僨乕僞張棟
while( !bits_eof && left>0 )
{
if( getbits(1) ) // 晛捠偺暥帤僨乕僞
{
if( littree )
ch = ReadTree( &lit_tree );
else
ch = getbits(8);
EXP_OUTC( ch );
}
else // 僗儔僀僪帿彂偵儅僢僠偟偰傞僨乕僞
{
// 嫍棧
int Distance = getbits(dict_bits);
Distance |= ( ReadTree(&distance_tree) << dict_bits );
// 挿偝
int Length = ReadTree( &length_tree );
if( Length == 63 )
Length += getbits(8);
Length += min_match_len;
// 弌椡
int op = (((outpos-outbuf)-(Distance+1)) & 0x3fff);
while( Length-- )
{
EXP_OUTC( outbuf[op++] );
op &= 0x3fff;
}
}
}
EXP_FLUSH();
#undef EXP_OUTC
#undef EXP_FLUSH
}
static void SortLengths( sf_tree* tree )
{
int gap,a,b;
sf_entry t;
bool noswaps;
gap = tree->entries >> 1;
do
{
do
{
noswaps = true;
for( int x=0; x<=(tree->entries - 1)-gap; x++ )
{
a = tree->entry[x].BitLength;
b = tree->entry[x + gap].BitLength;
if( (a>b) || ((a==b) && (tree->entry[x].Value > tree->entry[x + gap].Value)) )
{
t = tree->entry[x];
tree->entry[x] = tree->entry[x + gap];
tree->entry[x + gap] = t;
noswaps = false;
}
}
} while (!noswaps);
gap >>= 1;
} while( gap > 0 );
}
void CZipTool::ReadLengths( sf_tree* tree )
{
int treeBytes,i,num,len;
treeBytes = getbits(8) + 1;
i = 0;
tree->MaxLength = 0;
while( treeBytes-- )
{
len = getbits(4)+1;
num = getbits(4)+1;
while( num-- )
{
if( len > tree->MaxLength )
tree->MaxLength = len;
tree->entry[i].BitLength = len;
tree->entry[i].Value = i;
i++;
}
}
}
static void GenerateTrees( sf_tree* tree )
{
WORD Code = 0;
int CodeIncrement = 0, LastBitLength = 0;
int i = tree->entries - 1; // either 255 or 63
while( i >= 0 )
{
Code += CodeIncrement;
if( tree->entry[i].BitLength != LastBitLength )
{
LastBitLength = tree->entry[i].BitLength;
CodeIncrement = 1 << (16 - LastBitLength);
}
tree->entry[i].Code = Code;
i--;
}
}
static void ReverseBits( sf_tree* tree )
{
for( int i=0; i<=tree->entries-1; i++ )
{
WORD o = tree->entry[i].Code,
v = 0,
mask = 0x0001,
revb = 0x8000;
for( int b=0; b!=16; b++ )
{
if( (o&mask) != 0 )
v = v | revb;
revb = (revb >> 1);
mask = (mask << 1);
}
tree->entry[i].Code = v;
}
}
void CZipTool::LoadTree( sf_tree* tree, int treesize )
{
tree->entries = treesize;
ReadLengths( tree );
SortLengths( tree );
GenerateTrees( tree );
ReverseBits( tree );
}
int CZipTool::ReadTree( sf_tree* tree )
{
int bits=0, cur=0, b;
WORD cv=0;
while( true )
{
b = getbits(1);
cv = cv | (b << bits);
bits++;
while( tree->entry[cur].BitLength < bits )
{
cur++;
if( cur >= tree->entries )
return -1;
}
while( tree->entry[cur].BitLength == bits )
{
if( tree->entry[cur].Code == cv )
return tree->entry[cur].Value;
cur++;
if( cur >= tree->entries )
return -1;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -