merged 2.2 branch
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@7748 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
554
utils/Install/sfxace/uac_dcpr.c
Normal file
554
utils/Install/sfxace/uac_dcpr.c
Normal file
@@ -0,0 +1,554 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* */
|
||||
/* These are the decompression algorithms. */
|
||||
/* Don't change here anything (apart from memory allocation perhaps). */
|
||||
/* Any changes will very likely cause bugs! */
|
||||
/* */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#if defined(AMIGA)
|
||||
#include <string.h> // mem*()
|
||||
#endif
|
||||
#if defined(DOS) || defined(WIN16) || defined(WINNT) || defined(OS2) || defined(UNIX)
|
||||
#if !defined(__CYGWIN__)
|
||||
#include <mem.h> // mem*()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h> // printf()
|
||||
#include <stdlib.h> // malloc()
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "globals.h"
|
||||
#include "portable.h"
|
||||
#include "uac_comm.h"
|
||||
#include "uac_crc.h"
|
||||
#include "uac_dcpr.h"
|
||||
#include "uac_sys.h"
|
||||
#ifdef CRYPT
|
||||
#include "unace_ps.h"
|
||||
#endif /* CRYPT */
|
||||
|
||||
|
||||
//------------------------------ QUICKSORT ---------------------------------//
|
||||
#define xchg_def(v1,v2) {INT dummy;\
|
||||
dummy=v1; \
|
||||
v1=v2; \
|
||||
v2=dummy;}
|
||||
|
||||
void sortrange(INT left, INT right)
|
||||
{
|
||||
INT zl = left,
|
||||
zr = right,
|
||||
hyphen;
|
||||
|
||||
hyphen = sort_freq[right];
|
||||
|
||||
//divides by hyphen the given range into 2 parts
|
||||
do
|
||||
{
|
||||
while (sort_freq[zl] > hyphen)
|
||||
zl++;
|
||||
while (sort_freq[zr] < hyphen)
|
||||
zr--;
|
||||
//found a too small (left side) and
|
||||
//a too big (right side) element-->exchange them
|
||||
if (zl <= zr)
|
||||
{
|
||||
xchg_def(sort_freq[zl], sort_freq[zr]);
|
||||
xchg_def(sort_org[zl], sort_org[zr]);
|
||||
zl++;
|
||||
zr--;
|
||||
}
|
||||
}
|
||||
while (zl < zr);
|
||||
|
||||
//sort partial ranges - when very small, sort directly
|
||||
if (left < zr)
|
||||
{
|
||||
if (left < zr - 1)
|
||||
sortrange(left, zr);
|
||||
else if (sort_freq[left] < sort_freq[zr])
|
||||
{
|
||||
xchg_def(sort_freq[left], sort_freq[zr]);
|
||||
xchg_def(sort_org[left], sort_org[zr]);
|
||||
}
|
||||
}
|
||||
|
||||
if (right > zl)
|
||||
{
|
||||
if (zl < right - 1)
|
||||
sortrange(zl, right);
|
||||
else if (sort_freq[zl] < sort_freq[right])
|
||||
{
|
||||
xchg_def(sort_freq[zl], sort_freq[right]);
|
||||
xchg_def(sort_org[zl], sort_org[right]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void quicksort(INT n)
|
||||
{
|
||||
INT i;
|
||||
|
||||
for (i = n + 1; i--;)
|
||||
sort_org[i] = i;
|
||||
sortrange(0, n);
|
||||
}
|
||||
|
||||
//------------------------------ read bits ---------------------------------//
|
||||
void readdat(void)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
i = (size_rdb - 2) << 2;
|
||||
rpos -= size_rdb - 2;
|
||||
buf_rd[0] = buf_rd[size_rdb - 2];
|
||||
buf_rd[1] = buf_rd[size_rdb - 1];
|
||||
read_adds_blk((CHAR *) & buf_rd[2], i);
|
||||
#ifdef HI_LO_BYTE_ORDER
|
||||
{
|
||||
ULONG *p;
|
||||
i>>=2; // count LONGs not BYTEs
|
||||
p=&buf_rd[2];
|
||||
while (i--)
|
||||
{
|
||||
LONGswap(p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define addbits(bits) \
|
||||
{ \
|
||||
rpos+=(bits_rd+=bits)>>5; \
|
||||
bits_rd&=31; \
|
||||
if (rpos==(size_rdb-2)) readdat(); \
|
||||
code_rd=(buf_rd[rpos] << bits_rd) \
|
||||
+((buf_rd[rpos+1] >> (32-bits_rd))&(!bits_rd-1)); \
|
||||
}
|
||||
|
||||
|
||||
//---------------------- COMMENT DECOMPRESSION -----------------------------//
|
||||
|
||||
#define comm_cpr_hf(a,b) (a+b)
|
||||
|
||||
void dcpr_comm_init(void)
|
||||
{
|
||||
INT i;
|
||||
|
||||
i = comm_cpr_size > size_rdb * sizeof(LONG) ? size_rdb * sizeof(LONG) : comm_cpr_size;
|
||||
if (!f_err)
|
||||
memcpy(buf_rd, comm, i);
|
||||
#ifdef HI_LO_BYTE_ORDER
|
||||
{
|
||||
ULONG *p;
|
||||
i>>=2; // count LONGs not BYTEs
|
||||
p=buf_rd;
|
||||
while (i--)
|
||||
{
|
||||
LONGswap(p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
code_rd = buf_rd[0];
|
||||
rpos = bits_rd = 0;
|
||||
}
|
||||
|
||||
void dcpr_comm(INT comm_size)
|
||||
{
|
||||
SHORT hash[comm_cpr_hf(255, 255) + 1];
|
||||
INT dpos = 0,
|
||||
c,
|
||||
pos = 0,
|
||||
len,
|
||||
hs;
|
||||
|
||||
memset(&hash, 0, sizeof(hash));
|
||||
if (comm_cpr_size)
|
||||
{
|
||||
dcpr_comm_init();
|
||||
len = code_rd >> (32 - 15);
|
||||
addbits(15);
|
||||
if (len >= comm_size)
|
||||
len = comm_size - 1;
|
||||
if (read_wd(maxwd_mn, dcpr_code_mn, dcpr_wd_mn, max_cd_mn))
|
||||
do
|
||||
{
|
||||
if (dpos > 1)
|
||||
{
|
||||
pos = hash[hs = comm_cpr_hf(comm[dpos - 1], comm[dpos - 2])];
|
||||
hash[hs] = dpos;
|
||||
}
|
||||
addbits(dcpr_wd_mn[(c = dcpr_code_mn[code_rd >> (32 - maxwd_mn)])]);
|
||||
if (rpos == size_rdb - 3)
|
||||
rpos = 0;
|
||||
if (c > 255)
|
||||
{
|
||||
c -= 256;
|
||||
c += 2;
|
||||
while (c--)
|
||||
comm[dpos++] = comm[pos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
comm[dpos++] = c;
|
||||
}
|
||||
}
|
||||
while (dpos < len);
|
||||
comm[len] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------- LZW1 DECOMPRESSION -----------------------------//
|
||||
void wrchar(CHAR ch)
|
||||
{
|
||||
dcpr_do++;
|
||||
|
||||
dcpr_text[dcpr_dpos] = ch;
|
||||
dcpr_dpos++;
|
||||
dcpr_dpos &= dcpr_dican;
|
||||
}
|
||||
|
||||
void copystr(LONG d, INT l)
|
||||
{
|
||||
INT mpos;
|
||||
|
||||
dcpr_do += l;
|
||||
|
||||
mpos = dcpr_dpos - d;
|
||||
mpos &= dcpr_dican;
|
||||
|
||||
if ((mpos >= dcpr_dicsiz - maxlength) || (dcpr_dpos >= dcpr_dicsiz - maxlength))
|
||||
{
|
||||
while (l--)
|
||||
{
|
||||
dcpr_text[dcpr_dpos] = dcpr_text[mpos];
|
||||
dcpr_dpos++;
|
||||
dcpr_dpos &= dcpr_dican;
|
||||
mpos++;
|
||||
mpos &= dcpr_dican;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (l--)
|
||||
dcpr_text[dcpr_dpos++] = dcpr_text[mpos++];
|
||||
dcpr_dpos &= dcpr_dican;
|
||||
}
|
||||
}
|
||||
|
||||
void decompress(void)
|
||||
{
|
||||
INT c,
|
||||
lg,
|
||||
i,
|
||||
k;
|
||||
ULONG dist;
|
||||
|
||||
while (dcpr_do < dcpr_do_max)
|
||||
{
|
||||
if (!blocksize)
|
||||
if (!calc_dectabs())
|
||||
return;
|
||||
|
||||
addbits(dcpr_wd_mn[(c = dcpr_code_mn[code_rd >> (32 - maxwd_mn)])]);
|
||||
blocksize--;
|
||||
if (c > 255)
|
||||
{
|
||||
if (c > 259)
|
||||
{
|
||||
if ((c -= 260) > 1)
|
||||
{
|
||||
dist = (code_rd >> (33 - c)) + (1L << (c - 1));
|
||||
addbits(c - 1);
|
||||
}
|
||||
else
|
||||
dist = c;
|
||||
dcpr_olddist[(dcpr_oldnum = (dcpr_oldnum + 1) & 3)] = dist;
|
||||
i = 2;
|
||||
if (dist > maxdis2)
|
||||
{
|
||||
i++;
|
||||
if (dist > maxdis3)
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = dcpr_olddist[(dcpr_oldnum - (c &= 255)) & 3];
|
||||
for (k = c + 1; k--;)
|
||||
dcpr_olddist[(dcpr_oldnum - k) & 3] = dcpr_olddist[(dcpr_oldnum - k + 1) & 3];
|
||||
dcpr_olddist[dcpr_oldnum] = dist;
|
||||
i = 2;
|
||||
if (c > 1)
|
||||
i++;
|
||||
}
|
||||
addbits(dcpr_wd_lg[(lg = dcpr_code_lg[code_rd >> (32 - maxwd_lg)])]);
|
||||
dist++;
|
||||
lg += i;
|
||||
copystr(dist, lg);
|
||||
}
|
||||
else
|
||||
wrchar(c);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------- HUFFMAN ROUTINES ------------------------------//
|
||||
INT makecode(UINT maxwd, UINT size1_t, UCHAR * wd, USHORT * code)
|
||||
{
|
||||
UINT maxc,
|
||||
size2_t,
|
||||
l,
|
||||
c,
|
||||
i,
|
||||
max_make_code;
|
||||
|
||||
memcpy(&sort_freq, wd, (size1_t + 1) * sizeof(CHAR));
|
||||
if (size1_t)
|
||||
quicksort(size1_t);
|
||||
else
|
||||
sort_org[0] = 0;
|
||||
sort_freq[size1_t + 1] = size2_t = c = 0;
|
||||
while (sort_freq[size2_t])
|
||||
size2_t++;
|
||||
if (size2_t < 2)
|
||||
{
|
||||
i = sort_org[0];
|
||||
wd[i] = 1;
|
||||
size2_t += (size2_t == 0);
|
||||
}
|
||||
size2_t--;
|
||||
|
||||
max_make_code = 1 << maxwd;
|
||||
for (i = size2_t + 1; i-- && c < max_make_code;)
|
||||
{
|
||||
maxc = 1 << (maxwd - sort_freq[i]);
|
||||
l = sort_org[i];
|
||||
if (c + maxc > max_make_code)
|
||||
{
|
||||
dcpr_do = dcpr_do_max;
|
||||
return (0);
|
||||
}
|
||||
memset16(&code[c], l, maxc);
|
||||
c += maxc;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
INT read_wd(UINT maxwd, USHORT * code, UCHAR * wd, INT max_el)
|
||||
{
|
||||
UINT c,
|
||||
i,
|
||||
j,
|
||||
num_el,
|
||||
l,
|
||||
uplim,
|
||||
lolim;
|
||||
|
||||
memset(wd, 0, max_el * sizeof(CHAR));
|
||||
memset(code, 0, (1 << maxwd) * sizeof(SHORT));
|
||||
|
||||
num_el = code_rd >> (32 - 9);
|
||||
addbits(9);
|
||||
if (num_el > max_el)
|
||||
num_el = max_el;
|
||||
|
||||
lolim = code_rd >> (32 - 4);
|
||||
addbits(4);
|
||||
uplim = code_rd >> (32 - 4);
|
||||
addbits(4);
|
||||
|
||||
for (i = -1; ++i <= uplim;)
|
||||
{
|
||||
wd_svwd[i] = code_rd >> (32 - 3);
|
||||
addbits(3);
|
||||
}
|
||||
if (!makecode(maxwd_svwd, uplim, wd_svwd, code))
|
||||
return (0);
|
||||
j = 0;
|
||||
while (j <= num_el)
|
||||
{
|
||||
c = code[code_rd >> (32 - maxwd_svwd)];
|
||||
addbits(wd_svwd[c]);
|
||||
if (c < uplim)
|
||||
wd[j++] = c;
|
||||
else
|
||||
{
|
||||
l = (code_rd >> 28) + 4;
|
||||
addbits(4);
|
||||
while (l-- && j <= num_el)
|
||||
wd[j++] = 0;
|
||||
}
|
||||
}
|
||||
if (uplim)
|
||||
for (i = 0; ++i <= num_el;)
|
||||
wd[i] = (wd[i] + wd[i - 1]) % uplim;
|
||||
for (i = -1; ++i <= num_el;)
|
||||
if (wd[i])
|
||||
wd[i] += lolim;
|
||||
|
||||
return (makecode(maxwd, num_el, wd, code));
|
||||
|
||||
}
|
||||
|
||||
INT calc_dectabs(void)
|
||||
{
|
||||
if (!read_wd(maxwd_mn, dcpr_code_mn, dcpr_wd_mn, max_cd_mn)
|
||||
|| !read_wd(maxwd_lg, dcpr_code_lg, dcpr_wd_lg, max_cd_lg))
|
||||
return (0);
|
||||
|
||||
blocksize = code_rd >> (32 - 15);
|
||||
addbits(15);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
//---------------------------- BLOCK ROUTINES ------------------------------//
|
||||
INT decompress_blk(CHAR * buf, UINT len)
|
||||
{
|
||||
LONG old_pos = dcpr_dpos;
|
||||
INT i;
|
||||
|
||||
dcpr_do = 0;
|
||||
if ((dcpr_do_max = len - maxlength) > dcpr_size)
|
||||
dcpr_do_max = dcpr_size;
|
||||
if ((LONG) dcpr_size > 0 && dcpr_do_max)
|
||||
{
|
||||
decompress();
|
||||
if (old_pos + dcpr_do > dcpr_dicsiz)
|
||||
{
|
||||
i = dcpr_dicsiz - old_pos;
|
||||
memcpy(buf, &dcpr_text[old_pos], i);
|
||||
memcpy(&buf[i], dcpr_text, dcpr_do - i);
|
||||
}
|
||||
else
|
||||
memcpy(buf, &dcpr_text[old_pos], dcpr_do);
|
||||
}
|
||||
dcpr_size -= dcpr_do;
|
||||
return (dcpr_do);
|
||||
}
|
||||
|
||||
INT unstore(CHAR * buf, UINT len)
|
||||
{
|
||||
UINT rd = 0,
|
||||
i,
|
||||
pos = 0;
|
||||
|
||||
#ifdef CRYPT
|
||||
len = crypt_len(len - 8); /* because of decryption */
|
||||
#endif /* CRYPT */
|
||||
|
||||
while ((i = read_adds_blk((CHAR *) buf_rd, (INT) ((i = ((len > dcpr_size) ? dcpr_size : len)) > size_rdb ? size_rdb : i))) != 0)
|
||||
{
|
||||
rd += i;
|
||||
len -= i;
|
||||
memcpy(&buf[pos], buf_rd, i);
|
||||
pos += i;
|
||||
}
|
||||
dcpr_size -= rd;
|
||||
for (i = 0; i < rd; i++)
|
||||
{
|
||||
dcpr_text[dcpr_dpos] = buf[i];
|
||||
dcpr_dpos++;
|
||||
dcpr_dpos &= dcpr_dican;
|
||||
}
|
||||
return (INT)rd;
|
||||
}
|
||||
|
||||
INT dcpr_adds_blk(CHAR * buf, UINT len)
|
||||
{
|
||||
INT r;
|
||||
|
||||
switch (fhead.TECH.TYPE)
|
||||
{
|
||||
case TYPE_STORE:
|
||||
r = unstore(buf, len);
|
||||
break;
|
||||
case TYPE_LZW1:
|
||||
r = decompress_blk(buf, len);
|
||||
break;
|
||||
default:
|
||||
error("\nFile compressed with unknown method. Decompression not possible.\n");
|
||||
f_err = ERR_OTHER;
|
||||
r = 0;
|
||||
}
|
||||
rd_crc = getcrc(rd_crc, (UCHAR*)buf, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------- INIT ROUTINES ------------------------------//
|
||||
void dcpr_init(void)
|
||||
{
|
||||
dcpr_frst_file = 1;
|
||||
|
||||
dcpr_dic = 20;
|
||||
while ((dcpr_text = malloc(dcpr_dicsiz = (LONG) 1 << dcpr_dic))==NULL)
|
||||
dcpr_dic--;
|
||||
dcpr_dican = dcpr_dicsiz - 1;
|
||||
}
|
||||
|
||||
void dcpr_init_file(void)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
#ifdef CRYPT
|
||||
|
||||
reset_cryptkey();
|
||||
|
||||
#else /* CRYPT */
|
||||
|
||||
if (head.HEAD_FLAGS & ACE_PASSW)
|
||||
{
|
||||
error("\nFound passworded file. Decryption not supported.\n");
|
||||
f_err = ERR_OTHER;
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* CRYPT */
|
||||
|
||||
rd_crc = CRC_MASK;
|
||||
dcpr_size = fhead.SIZE;
|
||||
if (fhead.TECH.TYPE == TYPE_LZW1)
|
||||
{
|
||||
if ((fhead.TECH.PARM & 15) + 10 > dcpr_dic)
|
||||
{
|
||||
error("\nNot enough memory or dictionary of archive too large.\n");
|
||||
f_err = ERR_MEM;
|
||||
return;
|
||||
}
|
||||
|
||||
i = size_rdb * sizeof(LONG);
|
||||
read_adds_blk((CHAR *) buf_rd, i);
|
||||
#ifdef HI_LO_BYTE_ORDER
|
||||
{
|
||||
ULONG *p;
|
||||
i>>=2; // count LONGs not BYTEs
|
||||
p=buf_rd;
|
||||
while (i--)
|
||||
{
|
||||
LONGswap(p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
code_rd = buf_rd[0];
|
||||
bits_rd = rpos = 0;
|
||||
|
||||
blocksize = 0;
|
||||
}
|
||||
if (!adat.sol || dcpr_frst_file)
|
||||
dcpr_dpos = 0;
|
||||
|
||||
dcpr_oldnum = 0;
|
||||
memset(&dcpr_olddist, 0, sizeof(dcpr_olddist));
|
||||
|
||||
dcpr_frst_file = 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user