📄 fdi.c
字号:
/* exit if end of block */
if(e == 15)
break;
/* get length of block to copy */
ZIPNEEDBITS(e)
n = t->v.n + ((cab_ULONG)b & Zipmask[e]);
ZIPDUMPBITS(e);
/* decode distance of block to copy */
ZIPNEEDBITS((cab_ULONG)bd)
if ((e = (t = td + ((cab_ULONG)b & md))->e) > 16)
do {
if (e == 99)
return 1;
ZIPDUMPBITS(t->b)
e -= 16;
ZIPNEEDBITS(e)
} while ((e = (t = t->v.t + ((cab_ULONG)b & Zipmask[e]))->e) > 16);
ZIPDUMPBITS(t->b)
ZIPNEEDBITS(e)
d = w - t->v.n - ((cab_ULONG)b & Zipmask[e]);
ZIPDUMPBITS(e)
do
{
n -= (e = (e = ZIPWSIZE - ((d &= ZIPWSIZE-1) > w ? d : w)) > n ?n:e);
do
{
CAB(outbuf)[w++] = CAB(outbuf)[d++];
} while (--e);
} while (n);
}
}
/* restore the globals from the locals */
ZIP(window_posn) = w; /* restore global window pointer */
ZIP(bb) = b; /* restore global bit buffer */
ZIP(bk) = k;
/* done */
return 0;
}
/***********************************************************
* Zipinflate_stored (internal)
*/
static cab_LONG fdi_Zipinflate_stored(fdi_decomp_state *decomp_state)
/* "decompress" an inflated type 0 (stored) block. */
{
cab_ULONG n; /* number of bytes in block */
cab_ULONG w; /* current window position */
register cab_ULONG b; /* bit buffer */
register cab_ULONG k; /* number of bits in bit buffer */
/* make local copies of globals */
b = ZIP(bb); /* initialize bit buffer */
k = ZIP(bk);
w = ZIP(window_posn); /* initialize window position */
/* go to byte boundary */
n = k & 7;
ZIPDUMPBITS(n);
/* get the length and its complement */
ZIPNEEDBITS(16)
n = ((cab_ULONG)b & 0xffff);
ZIPDUMPBITS(16)
ZIPNEEDBITS(16)
if (n != (cab_ULONG)((~b) & 0xffff))
return 1; /* error in compressed data */
ZIPDUMPBITS(16)
/* read and output the compressed data */
while(n--)
{
ZIPNEEDBITS(8)
CAB(outbuf)[w++] = (cab_UBYTE)b;
ZIPDUMPBITS(8)
}
/* restore the globals from the locals */
ZIP(window_posn) = w; /* restore global window pointer */
ZIP(bb) = b; /* restore global bit buffer */
ZIP(bk) = k;
return 0;
}
/******************************************************
* fdi_Zipinflate_fixed (internal)
*/
static cab_LONG fdi_Zipinflate_fixed(fdi_decomp_state *decomp_state)
{
struct Ziphuft *fixed_tl;
struct Ziphuft *fixed_td;
cab_LONG fixed_bl, fixed_bd;
cab_LONG i; /* temporary variable */
cab_ULONG *l;
l = ZIP(ll);
/* literal table */
for(i = 0; i < 144; i++)
l[i] = 8;
for(; i < 256; i++)
l[i] = 9;
for(; i < 280; i++)
l[i] = 7;
for(; i < 288; i++) /* make a complete, but wrong code set */
l[i] = 8;
fixed_bl = 7;
if((i = fdi_Ziphuft_build(l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl, decomp_state)))
return i;
/* distance table */
for(i = 0; i < 30; i++) /* make an incomplete code set */
l[i] = 5;
fixed_bd = 5;
if((i = fdi_Ziphuft_build(l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd, decomp_state)) > 1)
{
fdi_Ziphuft_free(CAB(hfdi), fixed_tl);
return i;
}
/* decompress until an end-of-block code */
i = fdi_Zipinflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd, decomp_state);
fdi_Ziphuft_free(CAB(hfdi), fixed_td);
fdi_Ziphuft_free(CAB(hfdi), fixed_tl);
return i;
}
/**************************************************************
* fdi_Zipinflate_dynamic (internal)
*/
static cab_LONG fdi_Zipinflate_dynamic(fdi_decomp_state *decomp_state)
/* decompress an inflated type 2 (dynamic Huffman codes) block. */
{
cab_LONG i; /* temporary variables */
cab_ULONG j;
cab_ULONG *ll;
cab_ULONG l; /* last length */
cab_ULONG m; /* mask for bit lengths table */
cab_ULONG n; /* number of lengths to get */
struct Ziphuft *tl; /* literal/length code table */
struct Ziphuft *td; /* distance code table */
cab_LONG bl; /* lookup bits for tl */
cab_LONG bd; /* lookup bits for td */
cab_ULONG nb; /* number of bit length codes */
cab_ULONG nl; /* number of literal/length codes */
cab_ULONG nd; /* number of distance codes */
register cab_ULONG b; /* bit buffer */
register cab_ULONG k; /* number of bits in bit buffer */
/* make local bit buffer */
b = ZIP(bb);
k = ZIP(bk);
ll = ZIP(ll);
/* read in table lengths */
ZIPNEEDBITS(5)
nl = 257 + ((cab_ULONG)b & 0x1f); /* number of literal/length codes */
ZIPDUMPBITS(5)
ZIPNEEDBITS(5)
nd = 1 + ((cab_ULONG)b & 0x1f); /* number of distance codes */
ZIPDUMPBITS(5)
ZIPNEEDBITS(4)
nb = 4 + ((cab_ULONG)b & 0xf); /* number of bit length codes */
ZIPDUMPBITS(4)
if(nl > 288 || nd > 32)
return 1; /* bad lengths */
/* read in bit-length-code lengths */
for(j = 0; j < nb; j++)
{
ZIPNEEDBITS(3)
ll[Zipborder[j]] = (cab_ULONG)b & 7;
ZIPDUMPBITS(3)
}
for(; j < 19; j++)
ll[Zipborder[j]] = 0;
/* build decoding table for trees--single level, 7 bit lookup */
bl = 7;
if((i = fdi_Ziphuft_build(ll, 19, 19, NULL, NULL, &tl, &bl, decomp_state)) != 0)
{
if(i == 1)
fdi_Ziphuft_free(CAB(hfdi), tl);
return i; /* incomplete code set */
}
/* read in literal and distance code lengths */
n = nl + nd;
m = Zipmask[bl];
i = l = 0;
while((cab_ULONG)i < n)
{
ZIPNEEDBITS((cab_ULONG)bl)
j = (td = tl + ((cab_ULONG)b & m))->b;
ZIPDUMPBITS(j)
j = td->v.n;
if (j < 16) /* length of code in bits (0..15) */
ll[i++] = l = j; /* save last length in l */
else if (j == 16) /* repeat last length 3 to 6 times */
{
ZIPNEEDBITS(2)
j = 3 + ((cab_ULONG)b & 3);
ZIPDUMPBITS(2)
if((cab_ULONG)i + j > n)
return 1;
while (j--)
ll[i++] = l;
}
else if (j == 17) /* 3 to 10 zero length codes */
{
ZIPNEEDBITS(3)
j = 3 + ((cab_ULONG)b & 7);
ZIPDUMPBITS(3)
if ((cab_ULONG)i + j > n)
return 1;
while (j--)
ll[i++] = 0;
l = 0;
}
else /* j == 18: 11 to 138 zero length codes */
{
ZIPNEEDBITS(7)
j = 11 + ((cab_ULONG)b & 0x7f);
ZIPDUMPBITS(7)
if ((cab_ULONG)i + j > n)
return 1;
while (j--)
ll[i++] = 0;
l = 0;
}
}
/* free decoding table for trees */
fdi_Ziphuft_free(CAB(hfdi), tl);
/* restore the global bit buffer */
ZIP(bb) = b;
ZIP(bk) = k;
/* build the decoding tables for literal/length and distance codes */
bl = ZIPLBITS;
if((i = fdi_Ziphuft_build(ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl, decomp_state)) != 0)
{
if(i == 1)
fdi_Ziphuft_free(CAB(hfdi), tl);
return i; /* incomplete code set */
}
bd = ZIPDBITS;
fdi_Ziphuft_build(ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd, decomp_state);
/* decompress until an end-of-block code */
if(fdi_Zipinflate_codes(tl, td, bl, bd, decomp_state))
return 1;
/* free the decoding tables, return */
fdi_Ziphuft_free(CAB(hfdi), tl);
fdi_Ziphuft_free(CAB(hfdi), td);
return 0;
}
/*****************************************************
* fdi_Zipinflate_block (internal)
*/
static cab_LONG fdi_Zipinflate_block(cab_LONG *e, fdi_decomp_state *decomp_state) /* e == last block flag */
{ /* decompress an inflated block */
cab_ULONG t; /* block type */
register cab_ULONG b; /* bit buffer */
register cab_ULONG k; /* number of bits in bit buffer */
/* make local bit buffer */
b = ZIP(bb);
k = ZIP(bk);
/* read in last block bit */
ZIPNEEDBITS(1)
*e = (cab_LONG)b & 1;
ZIPDUMPBITS(1)
/* read in block type */
ZIPNEEDBITS(2)
t = (cab_ULONG)b & 3;
ZIPDUMPBITS(2)
/* restore the global bit buffer */
ZIP(bb) = b;
ZIP(bk) = k;
/* inflate that block type */
if(t == 2)
return fdi_Zipinflate_dynamic(decomp_state);
if(t == 0)
return fdi_Zipinflate_stored(decomp_state);
if(t == 1)
return fdi_Zipinflate_fixed(decomp_state);
/* bad block type */
return 2;
}
/****************************************************
* ZIPfdi_decomp(internal)
*/
static int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
{
cab_LONG e; /* last block flag */
TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
ZIP(inpos) = CAB(inbuf);
ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0;
if(outlen > ZIPWSIZE)
return DECR_DATAFORMAT;
/* CK = Chris Kirmse, official Microsoft purloiner */
if(ZIP(inpos)[0] != 0x43 || ZIP(inpos)[1] != 0x4B)
return DECR_ILLEGALDATA;
ZIP(inpos) += 2;
do {
if(fdi_Zipinflate_block(&e, decomp_state))
return DECR_ILLEGALDATA;
} while(!e);
/* return success */
return DECR_OK;
}
/*******************************************************************
* QTMfdi_decomp(internal)
*/
static int QTMfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
{
cab_UBYTE *inpos = CAB(inbuf);
cab_UBYTE *window = QTM(window);
cab_UBYTE *runsrc, *rundest;
cab_ULONG window_posn = QTM(window_posn);
cab_ULONG window_size = QTM(window_size);
/* used by bitstream macros */
register int bitsleft, bitrun, bitsneed;
register cab_ULONG bitbuf;
/* used by GET_SYMBOL */
cab_ULONG range;
cab_UWORD symf;
int i;
int extra, togo = outlen, match_length = 0, copy_length;
cab_UBYTE selector, sym;
cab_ULONG match_offset = 0;
cab_UWORD H = 0xFFFF, L = 0, C;
TRACE("(inlen == %d, outlen == %d)\n", inlen, outlen);
/* read initial value of C */
Q_INIT_BITSTREAM;
Q_READ_BITS(C, 16);
/* apply 2^x-1 mask */
window_posn &= window_size - 1;
/* runs can't straddle the window wraparound */
if ((window_posn + togo) > window_size) {
TRACE("straddled run\n");
return DECR_DATAFORMAT;
}
while (togo > 0) {
GET_SYMBOL(model7, selector);
switch (selector) {
case 0:
GET_SYMBOL(model00, sym); window[window_posn++] = sym; togo--;
break;
case 1:
GET_SYMBOL(model40, sym); window[window_posn++] = sym; togo--;
break;
case 2:
GET_SYMBOL(model80, sym); window[window_posn++] = sym; togo--;
break;
case 3:
GET_SYMBOL(modelC0, sym); window[window_posn++] = sym; togo--;
break;
case 4:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -