forked from backup/30dayMakeOS
650 lines
15 KiB
C
650 lines
15 KiB
C
#include <stdio.h> /* NULL */
|
||
#include <stdlib.h> /* malloc, free */
|
||
#include <setjmp.h>
|
||
|
||
typedef unsigned char UCHAR;
|
||
typedef unsigned int UINT32;
|
||
typedef UINT32 tek_TPRB;
|
||
|
||
static int tek_decode1(int siz, UCHAR *p, UCHAR *q);
|
||
static int tek_decode2(int siz, UCHAR *p, UCHAR *q);
|
||
static int tek_decode5(int siz, UCHAR *p, UCHAR *q);
|
||
|
||
static unsigned int tek_getnum_s7s(UCHAR **pp)
|
||
{
|
||
unsigned int s = 0;
|
||
UCHAR *p = *pp;
|
||
do {
|
||
s = s << 7 | *p++;
|
||
} while ((s & 1) == 0);
|
||
s >>= 1;
|
||
*pp = p;
|
||
return s;
|
||
}
|
||
|
||
int autodecomp(int siz0, UCHAR *p0, int siz)
|
||
{
|
||
unsigned char *b = p0, *c, *c0;
|
||
int s, i, e = 0;
|
||
if ((*(int *) &b[0x08] == 0x5341534f) && (*(int *) &b[0x0c] == 0x504d434b)) {
|
||
if (*(int *) &b[0x04] == 0x00000001) {
|
||
unsigned int t = *(int *) &b[0x00];
|
||
e |= 1;
|
||
if (0xffffff83 <= t && t <= 0xffffff89) {
|
||
c = &b[0x10];
|
||
s = tek_getnum_s7s(&c);
|
||
if (s + siz - 0x10 <= siz0) {
|
||
c0 = c = b + siz0 - siz;
|
||
for (i = siz - 1; i >= 0x10; i--)
|
||
c[i] = b[i];
|
||
c += 0x10;
|
||
tek_getnum_s7s(&c);
|
||
if (t == 0xffffff83)
|
||
e = tek_decode1(siz, c0, b);
|
||
if (t == 0xffffff85)
|
||
e = tek_decode2(siz, c0, b);
|
||
if (t == 0xffffff89)
|
||
e = tek_decode5(siz, c0, b);
|
||
siz = s;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (e)
|
||
siz |= -1;
|
||
return siz;
|
||
}
|
||
|
||
static int tek_lzrestore_stk1(int srcsiz, UCHAR *src, int outsiz, UCHAR *q)
|
||
{
|
||
int by, lz, cp, ds;
|
||
UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q;
|
||
do {
|
||
if ((by = (lz = *s7ptr++) & 0x0f) == 0)
|
||
by = tek_getnum_s7s(&s7ptr);
|
||
if ((lz >>= 4) == 0)
|
||
lz = tek_getnum_s7s(&s7ptr);
|
||
do {
|
||
*q++ = *s7ptr++;
|
||
} while (--by);
|
||
if (q >= q1)
|
||
break;
|
||
do {
|
||
ds = (cp = *s7ptr++) & 0x0f;
|
||
if ((ds & 1) == 0) {
|
||
do {
|
||
ds = ds << 7 | *s7ptr++;
|
||
} while ((ds & 1) == 0);
|
||
}
|
||
ds = ~(ds >> 1);
|
||
if ((cp >>= 4) == 0) {
|
||
do {
|
||
cp = cp << 7 | *s7ptr++;
|
||
} while ((cp & 1) == 0);
|
||
cp >>= 1;
|
||
}
|
||
cp++;
|
||
if (q + ds < q0)
|
||
goto err;
|
||
if (q + cp > q1)
|
||
cp = q1 - q;
|
||
do {
|
||
*q = *(q + ds);
|
||
q++;
|
||
} while (--cp);
|
||
} while (--lz);
|
||
} while (q < q1);
|
||
return 0;
|
||
err:
|
||
return 1;
|
||
}
|
||
|
||
static int tek_decode1(int siz, UCHAR *p, UCHAR *q)
|
||
{
|
||
int dsiz, hed, bsiz;
|
||
UCHAR *p1 = p + siz;
|
||
p += 16;
|
||
if ((dsiz = tek_getnum_s7s(&p)) > 0) {
|
||
hed = tek_getnum_s7s(&p);
|
||
bsiz = 1 << (((hed >> 1) & 0x0f) + 8);
|
||
if (dsiz > bsiz || (hed & 0x21) != 0x01)
|
||
return 1;
|
||
if (hed & 0x40)
|
||
tek_getnum_s7s(&p);
|
||
if (tek_getnum_s7s(&p) != 0)
|
||
return 1;
|
||
return tek_lzrestore_stk1(p1 - p, p, dsiz, q);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
static unsigned int tek_getnum_s7(UCHAR **pp)
|
||
{
|
||
unsigned int s = 0, b = 0, a = 1;
|
||
UCHAR *p = *pp;
|
||
for (;;) {
|
||
s = s << 7 | *p++;
|
||
if (s & 1)
|
||
break;
|
||
a <<= 7;
|
||
b += a;
|
||
}
|
||
s >>= 1;
|
||
*pp = p;
|
||
return s + b;
|
||
}
|
||
|
||
static int tek_lzrestore_stk2(int srcsiz, UCHAR *src, int outsiz, UCHAR *q)
|
||
{
|
||
int cp, ds, repdis[4], i, j;
|
||
UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q, bylz, cbylz;
|
||
for (j = 0; j < 4; j++)
|
||
repdis[j] = -1 - j;
|
||
bylz = cbylz = 0;
|
||
if (outsiz) {
|
||
if (tek_getnum_s7s(&s7ptr))
|
||
return 1;
|
||
do {
|
||
j = 0;
|
||
do {
|
||
j++;
|
||
if (j >= 17) {
|
||
j += tek_getnum_s7s(&s7ptr);
|
||
break;
|
||
}
|
||
if (cbylz == 0) {
|
||
cbylz = 8;
|
||
bylz = *s7ptr++;
|
||
}
|
||
cbylz--;
|
||
i = bylz & 1;
|
||
bylz >>= 1;
|
||
} while (i == 0);
|
||
do {
|
||
*q++ = *s7ptr++;
|
||
} while (--j);
|
||
if (q >= q1)
|
||
break;
|
||
|
||
j = 0;
|
||
do {
|
||
j++;
|
||
if (j >= 17) {
|
||
j += tek_getnum_s7s(&s7ptr);
|
||
break;
|
||
}
|
||
if (cbylz == 0) {
|
||
cbylz = 8;
|
||
bylz = *s7ptr++;
|
||
}
|
||
cbylz--;
|
||
i = bylz & 1;
|
||
bylz >>= 1;
|
||
} while (i == 0);
|
||
do {
|
||
i = *s7ptr++;
|
||
cp = i >> 4;
|
||
i &= 0x0f;
|
||
if ((i & 1) == 0)
|
||
i |= (tek_getnum_s7(&s7ptr) + 1) << 4;
|
||
i >>= 1;
|
||
ds = ~(i - 6);
|
||
if (i < 4)
|
||
ds = repdis[i];
|
||
if (i == 4)
|
||
ds = repdis[0] - tek_getnum_s7(&s7ptr) - 1;
|
||
if (i == 5)
|
||
ds = repdis[0] + tek_getnum_s7(&s7ptr) + 1;
|
||
if (cp == 0)
|
||
cp = tek_getnum_s7(&s7ptr) + 16;
|
||
cp++;
|
||
if (i > 0) {
|
||
if (i > 1) {
|
||
if (i > 2)
|
||
repdis[3] = repdis[2];
|
||
repdis[2] = repdis[1];
|
||
}
|
||
repdis[1] = repdis[0];
|
||
repdis[0] = ds;
|
||
}
|
||
if (q + ds < q0)
|
||
goto err;
|
||
if (q + cp > q1)
|
||
cp = q1 - q;
|
||
do {
|
||
*q = *(q + ds);
|
||
q++;
|
||
} while (--cp);
|
||
} while (--j);
|
||
} while (q < q1);
|
||
}
|
||
return 0;
|
||
err:
|
||
return 1;
|
||
}
|
||
|
||
static int tek_decode2(int siz, UCHAR *p, UCHAR *q)
|
||
{
|
||
UCHAR *p1 = p + siz;
|
||
int dsiz, hed, bsiz, st = 0;
|
||
p += 16;
|
||
if ((dsiz = tek_getnum_s7s(&p)) > 0) {
|
||
hed = tek_getnum_s7s(&p);
|
||
bsiz = 1 << (((hed >> 1) & 0x0f) + 8);
|
||
if (dsiz > bsiz || (hed & 0x21) != 0x01)
|
||
return 1;
|
||
if (hed & 0x40)
|
||
tek_getnum_s7s(&p);
|
||
st = tek_lzrestore_stk2(p1 - p, p, dsiz, q);
|
||
}
|
||
return st;
|
||
}
|
||
|
||
static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags);
|
||
|
||
static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf)
|
||
{
|
||
int wrksiz, lc, lp, pb, flags, *work, prop0, fl;
|
||
|
||
if ((fl = (prop0 = *src) & 0x0f) == 0x01) /* 0001 */
|
||
flags |= -1;
|
||
else if (fl == 0x05)
|
||
flags = -2;
|
||
else if (fl == 0x09)
|
||
flags &= 0;
|
||
else
|
||
return 1;
|
||
src++;
|
||
prop0 >>= 4;
|
||
if (prop0 == 0)
|
||
prop0 = *src++;
|
||
else {
|
||
static UCHAR prop0_table[] = { 0x5d, 0x00 }, prop1_table[] = { 0x00 };
|
||
if (flags == -1) {
|
||
if (prop0 >= 3)
|
||
return 1;
|
||
prop0 = prop0_table[prop0 - 1];
|
||
} else {
|
||
if (prop0 >= 2)
|
||
return 1;
|
||
prop0 = prop1_table[prop0 - 1];
|
||
}
|
||
}
|
||
lp = prop0 / (9 * 5);
|
||
prop0 %= 9 * 5;
|
||
pb = prop0 / 9;
|
||
lc = prop0 % 9;
|
||
if (flags == 0) /* tek5:z2 */
|
||
flags = *src++;
|
||
if (flags == -1) { /* stk5 */
|
||
wrksiz = lp;
|
||
lp = pb;
|
||
pb = wrksiz;
|
||
}
|
||
wrksiz = 0x180 * sizeof (UINT32) + (0x840 + (0x300 << (lc + lp))) * sizeof (tek_TPRB);
|
||
work = malloc(wrksiz);
|
||
if (work == NULL)
|
||
return -1;
|
||
flags = tek_decmain5(work, src, outsiz, outbuf, lc, pb, lp, flags);
|
||
free(work);
|
||
return flags;
|
||
}
|
||
|
||
struct tek_STR_BITMODEL {
|
||
UCHAR t, m, s, dmy;
|
||
UINT32 prb0, prb1, tmsk, ntm, lt, lt0, dmy4;
|
||
};
|
||
|
||
struct tek_STR_PRB {
|
||
struct tek_STR_PRB_PB {
|
||
struct tek_STR_PRB_PBST {
|
||
tek_TPRB mch, rep0l1;
|
||
} st[12];
|
||
tek_TPRB lenlow[2][8], lenmid[2][8];
|
||
} pb[16];
|
||
struct tek_STR_PRB_ST {
|
||
tek_TPRB rep, repg0, repg1, repg2;
|
||
} st[12];
|
||
tek_TPRB lensel[2][2], lenhigh[2][256], pslot[4][64], algn[64];
|
||
tek_TPRB spdis[2][2+4+8+16+32], lenext[2+4+8+16+32];
|
||
tek_TPRB repg3, fchgprm[2 * 32], tbmt[16], tbmm[16], fchglt;
|
||
tek_TPRB lit[1];
|
||
};
|
||
|
||
struct tek_STR_RNGDEC {
|
||
UCHAR *p;
|
||
UINT32 range, code, rmsk;
|
||
jmp_buf errjmp;
|
||
struct tek_STR_BITMODEL bm[32], *ptbm[16];
|
||
struct tek_STR_PRB probs;
|
||
};
|
||
|
||
static void tek_setbm5(struct tek_STR_BITMODEL *bm, int t, int m)
|
||
{
|
||
bm->t = t;
|
||
bm->m = m;
|
||
bm->prb1 = -1 << (m + t);
|
||
bm->prb0 = ~bm->prb1;
|
||
bm->prb1 |= 1 << t;
|
||
bm->tmsk = (-1 << t) & 0xffff;
|
||
bm->prb0 &= bm->tmsk;
|
||
bm->prb1 &= bm->tmsk;
|
||
bm->ntm = ~bm->tmsk;
|
||
return;
|
||
}
|
||
|
||
static int tek_rdget0(struct tek_STR_RNGDEC *rd, int n, int i)
|
||
{
|
||
do {
|
||
while (rd->range < (UINT32) (1 << 24)) {
|
||
rd->range <<= 8;
|
||
rd->code = rd->code << 8 | *rd->p++;
|
||
}
|
||
rd->range >>= 1;
|
||
i += i;
|
||
if (rd->code >= rd->range) {
|
||
rd->code -= rd->range;
|
||
i |= 1;
|
||
}
|
||
} while (--n);
|
||
return ~i;
|
||
}
|
||
|
||
static int tek_rdget1(struct tek_STR_RNGDEC *rd, tek_TPRB *prob0, int n, int j, struct tek_STR_BITMODEL *bm)
|
||
{
|
||
UINT32 p, i, *prob, nm = n >> 4;
|
||
n &= 0x0f;
|
||
prob0 -= j;
|
||
do {
|
||
p = *(prob = prob0 + j);
|
||
if (bm->lt > 0) {
|
||
if (--bm->lt == 0) {
|
||
if (tek_rdget1(rd, &rd->probs.fchglt, 0x71, 0, &rd->bm[3]) == 0) {
|
||
err:
|
||
longjmp(rd->errjmp, 1);
|
||
}
|
||
i = bm - rd->bm;
|
||
if ((bm->s = tek_rdget1(rd, &rd->probs.fchgprm[i * 2 + bm->s], 0x71, 0, &rd->bm[1])) == 0) {
|
||
i = tek_rdget1(rd, rd->probs.tbmt, 0x74, 1, &rd->bm[2]) & 15;
|
||
if (i == 15)
|
||
goto err;
|
||
tek_setbm5(bm, i, ((tek_rdget1(rd, rd->probs.tbmm, 0x74, 1, &rd->bm[2]) - 1) & 15) + 1);
|
||
}
|
||
bm->lt = bm->lt0;
|
||
}
|
||
if (p < bm->prb0) {
|
||
p = bm->prb0;
|
||
goto fixprob;
|
||
}
|
||
if (p > bm->prb1) {
|
||
p = bm->prb1;
|
||
goto fixprob;
|
||
}
|
||
if (p & bm->ntm) {
|
||
p &= bm->tmsk;
|
||
fixprob:
|
||
*prob = p;
|
||
}
|
||
}
|
||
|
||
while (rd->range < (UINT32) (1 << 24)) {
|
||
rd->range <<= 8;
|
||
rd->code = rd->code << 8 | *rd->p++;
|
||
}
|
||
j += j;
|
||
i = ((unsigned long long) (rd->range & rd->rmsk) * p) >> 16;
|
||
if (rd->code < i) {
|
||
j |= 1;
|
||
rd->range = i;
|
||
*prob += ((0x10000 - p) >> bm->m) & bm->tmsk;
|
||
} else {
|
||
rd->range -= i;
|
||
rd->code -= i;
|
||
*prob -= (p >> bm->m) & bm->tmsk;
|
||
}
|
||
--n;
|
||
if ((n & nm) == 0)
|
||
bm++;
|
||
} while (n);
|
||
return j;
|
||
}
|
||
|
||
static UINT32 tek_revbit(UINT32 data, int len)
|
||
{
|
||
UINT32 rev = 0;
|
||
do {
|
||
rev += rev + (data & 1);
|
||
data >>= 1;
|
||
} while (--len);
|
||
return rev;
|
||
}
|
||
|
||
static int tek_getlen5(struct tek_STR_RNGDEC *rd, int m, int s_pos, int stk)
|
||
{
|
||
int i;
|
||
if (tek_rdget1(rd, &rd->probs.lensel[m][0], 0x71, 0, rd->ptbm[3]) ^ stk) /* low */
|
||
i = tek_rdget1(rd, rd->probs.pb[s_pos].lenlow[m], 0x73, 1, rd->ptbm[4]) & 7;
|
||
else if (tek_rdget1(rd, &rd->probs.lensel[m][1], 0x71, 0, rd->ptbm[3]) ^ stk) /* mid */
|
||
i = tek_rdget1(rd, rd->probs.pb[s_pos].lenmid[m], 0x73, 1, rd->ptbm[5]);
|
||
else {
|
||
/* high */
|
||
i = tek_rdget1(rd, rd->probs.lenhigh[m], 0x78, 1, rd->ptbm[6]) - (256 + 256 - 8);
|
||
if (i > 0) {
|
||
if (i < 6 && stk == 0)
|
||
i = tek_rdget1(rd, &rd->probs.lenext[(1 << i) - 2], i | 0x70, 1, rd->ptbm[7]) - 1;
|
||
else
|
||
i = tek_rdget0(rd, i, ~1) - 1;
|
||
i = tek_rdget0(rd, i, ~1) - 1;
|
||
}
|
||
i += 256 - 8 + 16;
|
||
}
|
||
return i;
|
||
}
|
||
|
||
static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags)
|
||
{
|
||
static int state_table[] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
|
||
int i, j, k, pmch, rep[4], s, pos, m_pos = (1 << pb) - 1, m_lp = (1 << lp) - 1;
|
||
int stk = (flags == -1), lcr = 8 - lc, s_pos, lit0cntmsk = 0x78;
|
||
UINT32 *lit1;
|
||
struct tek_STR_RNGDEC *rd = (struct tek_STR_RNGDEC *) work;
|
||
struct tek_STR_PRB *prb = &rd->probs;
|
||
|
||
rd->p = &src[4];
|
||
rd->range |= -1;
|
||
rd->code = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3];
|
||
for (i = 0; i < 4; i++)
|
||
rep[i] = ~i;
|
||
if (setjmp(rd->errjmp))
|
||
goto err;
|
||
for (i = sizeof (struct tek_STR_PRB) / sizeof (tek_TPRB) + (0x300 << (lc + lp)) - 2; i >= 0; i--)
|
||
((tek_TPRB *) prb)[i] = 1 << 15;
|
||
for (i = 0; i < 32; i++) {
|
||
rd->bm[i].lt = (i >= 4);
|
||
rd->bm[i].lt0 = (i < 24) ? 16 * 1024 : 8 * 1024;
|
||
rd->bm[i].s &= 0;
|
||
rd->bm[i].t = rd->bm[i].m = 5;
|
||
}
|
||
lit1 = prb->lit + ((256 << (lc + lp)) - 2);
|
||
if (stk) {
|
||
rd->rmsk = -1 << 11;
|
||
for (i = 0; i < 32; i++)
|
||
rd->bm[i].lt = 0;
|
||
for (i = 0; i < 14; i++)
|
||
rd->ptbm[i] = &rd->bm[0];
|
||
} else {
|
||
UCHAR pt[14];
|
||
static UCHAR pt1[14] = {
|
||
8, 8, 8, 8, 8, 8, 8, 8,
|
||
8, 8, 18, 18, 18, 8
|
||
};
|
||
static UCHAR pt2[14] = {
|
||
8, 8, 10, 11, 12, 12, 14, 15,
|
||
16, 16, 18, 18, 20, 21
|
||
};
|
||
/*
|
||
0- 7:mch, mch, lit1, lensel, lenlow, lenmid, lenhigh, lenext
|
||
8-15:pslot, pslot, sdis, sdis, align, rep-repg2
|
||
*/
|
||
rd->rmsk |= -1;
|
||
rd->bm[1].t = 5; rd->bm[1].m = 3; /* for fchgprm */
|
||
rd->bm[2].t = 9; rd->bm[2].m = 2; /* for tbmt, tbmm */
|
||
if (flags & 0x40) { /* lt-flag */
|
||
rd->bm[3].t = 0; rd->bm[3].m = 1;
|
||
prb->fchglt = 0xffff;
|
||
}
|
||
rd->bm[22].t = 0; rd->bm[22].m = 1;
|
||
prb->repg3 = 0xffff;
|
||
if (flags == -2) { /* z1 */
|
||
rd->bm[22].lt = 0;
|
||
for (i = 0; i < 14; i++)
|
||
pt[i] = pt1[i];
|
||
} else {
|
||
for (i = 0; i < 14; i++)
|
||
pt[i] = pt2[i];
|
||
lit0cntmsk = (7 >> (flags & 3)) << 4 | 8;
|
||
pt[ 1] = 8 + ((flags & 0x04) != 0); /* mch */
|
||
pt[ 5] = 12 + ((flags & 0x08) != 0); /* llm */
|
||
pt[ 9] = 16 + ((flags & 0x10) != 0); /* pst */
|
||
pt[11] = 18 + ((flags & 0x20) != 0); /* sds */
|
||
}
|
||
for (i = 0; i < 14; i++)
|
||
rd->ptbm[i] = &rd->bm[pt[i]];
|
||
}
|
||
for (i = 0; i < 32; i++)
|
||
tek_setbm5(&rd->bm[i], rd->bm[i].t, rd->bm[i].m);
|
||
|
||
if ((tek_rdget1(rd, &prb->pb[0].st[0].mch, 0x71, 0, rd->ptbm[0]) ^ stk) == 0)
|
||
goto err;
|
||
*q++ = tek_rdget1(rd, prb->lit, lit0cntmsk, 1, &rd->bm[24]) & 0xff;
|
||
pmch &= 0; s &= 0; pos = 1;
|
||
while (pos < osiz) {
|
||
s_pos = pos & m_pos;
|
||
if (tek_rdget1(rd, &prb->pb[s_pos].st[s].mch, 0x71, 0, rd->ptbm[s > 0]) ^ stk) {
|
||
i = (q[-1] >> lcr | (pos & m_lp) << lc) << 8;
|
||
s = state_table[s];
|
||
if (pmch == 0)
|
||
*q = tek_rdget1(rd, &prb->lit[i], lit0cntmsk, 1, &rd->bm[24]) & 0xff;
|
||
else {
|
||
struct tek_STR_BITMODEL *bm = &rd->bm[24];
|
||
j = 1; /* lit1‚Íʼn‚©‚ç2‚ðŒ¸‚¶‚Ä‚ ‚é */
|
||
k = 8;
|
||
pmch = q[rep[0]];
|
||
do {
|
||
j += j + tek_rdget1(rd, &lit1[(i + j) << 1 | pmch >> 7], 0x71, 0, rd->ptbm[2]);
|
||
k--;
|
||
if ((k & (lit0cntmsk >> 4)) == 0)
|
||
bm++;
|
||
if ((((pmch >> 7) ^ j) & 1) != 0 && k != 0) {
|
||
j = tek_rdget1(rd, &prb->lit[i + j - 1], k | (lit0cntmsk & 0x70), j, bm);
|
||
break;
|
||
}
|
||
pmch <<= 1;
|
||
} while (k);
|
||
*q = j & 0xff;
|
||
pmch &= 0;
|
||
}
|
||
pos++;
|
||
q++;
|
||
} else { /* lz */
|
||
pmch |= 1;
|
||
if (tek_rdget1(rd, &prb->st[s].rep, 0x71, 0, rd->ptbm[13]) ^ stk) { /* len/dis */
|
||
rep[3] = rep[2];
|
||
rep[2] = rep[1];
|
||
rep[1] = rep[0];
|
||
j = i = tek_getlen5(rd, 0, s_pos, stk);
|
||
s = s < 7 ? 7 : 10;
|
||
if (j >= 4)
|
||
j = 3;
|
||
rep[0] = j = tek_rdget1(rd, prb->pslot[j], 0x76, 1, rd->ptbm[8 + (j == 3)]) & 0x3f;
|
||
if (j >= 4) {
|
||
k = (j >> 1) - 1; /* k = [1, 30] */
|
||
rep[0] = (2 | (j & 1)) << k;
|
||
if (j < 14) /* k < 6 */
|
||
rep[0] |= tek_revbit(tek_rdget1(rd, &prb->spdis[j & 1][(1 << k) - 2], k | 0x70, 1, rd->ptbm[10 + (k >= 4)]), k);
|
||
else {
|
||
if (stk == 0) {
|
||
if (k -= 6)
|
||
rep[0] |= tek_rdget0(rd, k, ~0) << 6;
|
||
rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x76, 1, rd->ptbm[12]), 6);
|
||
} else {
|
||
rep[0] |= tek_rdget0(rd, k - 4, ~0) << 4;
|
||
rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x74, 1, rd->ptbm[12]), 4);
|
||
}
|
||
}
|
||
}
|
||
rep[0] = ~rep[0];
|
||
} else { /* repeat-dis */
|
||
if (tek_rdget1(rd, &prb->st[s].repg0, 0x71, 0, rd->ptbm[13]) ^ stk) { /* rep0 */
|
||
i |= -1;
|
||
if (tek_rdget1(rd, &prb->pb[s_pos].st[s].rep0l1, 0x71, 0, rd->ptbm[13]) == 0) {
|
||
s = s < 7 ? 9 : 11;
|
||
goto skip;
|
||
}
|
||
} else {
|
||
if (tek_rdget1(rd, &prb->st[s].repg1, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep1 */
|
||
i = rep[1];
|
||
else {
|
||
if (tek_rdget1(rd, &prb->st[s].repg2, 0x71, 0, rd->ptbm[13]) ^ stk) /* rep2 */
|
||
i = rep[2];
|
||
else {
|
||
if (stk == 0) {
|
||
if (tek_rdget1(rd, &prb->repg3, 0x71, 0, &rd->bm[22]) == 0)
|
||
goto err;
|
||
}
|
||
i = rep[3]; /* rep3 */
|
||
rep[3] = rep[2];
|
||
}
|
||
rep[2] = rep[1];
|
||
}
|
||
rep[1] = rep[0];
|
||
rep[0] = i;
|
||
}
|
||
i = tek_getlen5(rd, 1, s_pos, stk);
|
||
s = s < 7 ? 8 : 11;
|
||
}
|
||
skip:
|
||
i += 2;
|
||
if (pos + rep[0] < 0)
|
||
goto err;
|
||
if (pos + i > osiz)
|
||
i = osiz - pos;
|
||
pos += i;
|
||
do {
|
||
*q = q[rep[0]];
|
||
q++;
|
||
} while (--i);
|
||
}
|
||
}
|
||
return 0;
|
||
err:
|
||
return 1;
|
||
}
|
||
|
||
int tek_decode5(int siz, UCHAR *p, UCHAR *q)
|
||
{
|
||
UCHAR *p1 = p + siz;
|
||
int dsiz, hed, bsiz, st = 0;
|
||
p += 16;
|
||
if ((dsiz = tek_getnum_s7s(&p)) > 0) {
|
||
hed = tek_getnum_s7s(&p);
|
||
if ((hed & 1) == 0)
|
||
st = tek_lzrestore_tek5(p1 - p + 1, p - 1, dsiz, q);
|
||
else {
|
||
bsiz = 1 << (((hed >> 1) & 0x0f) + 8);
|
||
if (hed & 0x20)
|
||
return 1;
|
||
if (bsiz == 256)
|
||
st = tek_lzrestore_tek5(p1 - p, p, dsiz, q);
|
||
else {
|
||
if (dsiz > bsiz)
|
||
return 1;
|
||
if (hed & 0x40)
|
||
tek_getnum_s7s(&p);
|
||
st = tek_lzrestore_tek5(p1 - p, p, dsiz, q);
|
||
}
|
||
}
|
||
}
|
||
return st;
|
||
}
|