3 static unsigned int tek_getnum_s7s(UCHAR **pp);
6 static int tek_lzrestore_stk1(int srcsiz, UCHAR *src, int outsiz, UCHAR *q);
7 static int tek_decode1(int siz, UCHAR *p, UCHAR *q);
8 static unsigned int tek_getnum_s7(UCHAR **pp);
9 static int tek_lzrestore_stk2(int srcsiz, UCHAR *src, int outsiz, UCHAR *q);
10 static int tek_decode2(int siz, UCHAR *p, UCHAR *q);
12 static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf);
13 static void tek_setbm5(struct tek_STR_BITMODEL *bm, int t, int m);
14 static int tek_rdget0(struct tek_STR_RNGDEC *rd, int n, int i);
15 static int tek_rdget1(struct tek_STR_RNGDEC *rd, tek_TPRB *prob0, int n, int j, struct tek_STR_BITMODEL *bm);
16 static UINT32 tek_revbit(UINT32 data, int len);
17 static int tek_getlen5(struct tek_STR_RNGDEC *rd, int m, int s_pos, int stk);
18 static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags);
19 static int tek_decode5(int siz, UCHAR *p, UCHAR *q);
21 static unsigned int tek_getnum_s7s(UCHAR **pp)
23 /* 下駄がないので中身をいじりやすい */
29 } while ((s & 1) == 0);
37 int tek_getsize(unsigned char *p)
39 static char header[15] = {
40 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x41, 0x53, 0x4b, 0x43, 0x4d, 0x50
43 if (memcmp(p + 1, header, 15) == 0 && (*p == 0x83 || *p == 0x85 || *p == 0x89)) {
45 size = tek_getnum_s7s(&p);
48 } /* (註)memcmpはstrncmpの仲間で、文字列中に0があっても指定された15文字まで比較する関数 */
52 int tek_decomp(unsigned char *p, unsigned char *q, int size)
57 err = tek_decode1(size, p, q);
58 } else if (*p == 0x85) {
59 err = tek_decode2(size, p, q);
60 } else if (*p == 0x89) {
61 err = tek_decode5(size, p, q);
65 err = tek_decode5(size, p, q);
70 printf("tek_decomp() serious error, err: %d\n", err);
78 static int tek_lzrestore_stk1(int srcsiz, UCHAR *src, int outsiz, UCHAR *q)
81 UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q;
83 if ((by = (lz = *s7ptr++) & 0x0f) == 0)
84 by = tek_getnum_s7s(&s7ptr);
86 lz = tek_getnum_s7s(&s7ptr);
93 ds = (cp = *s7ptr++) & 0x0f;
96 ds = ds << 7 | *s7ptr++;
97 } while ((ds & 1) == 0);
100 if ((cp >>= 4) == 0) {
102 cp = cp << 7 | *s7ptr++;
103 } while ((cp & 1) == 0);
105 } /* 0がこないことをあてにする */
122 static int tek_decode1(int siz, UCHAR *p, UCHAR *q)
127 if ((dsiz = tek_getnum_s7s(&p)) > 0) {
128 hed = tek_getnum_s7s(&p);
129 bsiz = 1 << (((hed >> 1) & 0x0f) + 8);
130 if (dsiz > bsiz || (hed & 0x21) != 0x01)
133 tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */
134 if (tek_getnum_s7s(&p) != 0)
135 return 1; /* 補助バッファ使用 */
136 return tek_lzrestore_stk1(p1 - p, p, dsiz, q);
141 static unsigned int tek_getnum_s7(UCHAR **pp)
142 /* これは必ずbig-endian */
144 unsigned int s = 0, b = 0, a = 1;
158 static int tek_lzrestore_stk2(int srcsiz, UCHAR *src, int outsiz, UCHAR *q)
160 int cp, ds, repdis[4], i, j;
161 UCHAR *q1 = q + outsiz, *s7ptr = src, *q0 = q, bylz, cbylz;
162 for (j = 0; j < 4; j++)
166 if (tek_getnum_s7s(&s7ptr))
174 j += tek_getnum_s7s(&s7ptr);
196 j += tek_getnum_s7s(&s7ptr);
212 i |= (tek_getnum_s7(&s7ptr) + 1) << 4;
218 ds = repdis[0] - tek_getnum_s7(&s7ptr) - 1;
220 ds = repdis[0] + tek_getnum_s7(&s7ptr) + 1;
222 cp = tek_getnum_s7(&s7ptr) + 16;
227 repdis[3] = repdis[2];
228 repdis[2] = repdis[1];
230 repdis[1] = repdis[0];
249 static int tek_decode2(int siz, UCHAR *p, UCHAR *q)
252 int dsiz, hed, bsiz, st = 0;
254 if ((dsiz = tek_getnum_s7s(&p)) > 0) {
255 hed = tek_getnum_s7s(&p);
256 bsiz = 1 << (((hed >> 1) & 0x0f) + 8);
257 if (dsiz > bsiz || (hed & 0x21) != 0x01)
260 tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */
261 st = tek_lzrestore_stk2(p1 - p, p, dsiz, q);
268 static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf)
270 int wrksiz, lc, lp, pb, flags = 0, *work, prop0, fl;
272 if ((fl = (prop0 = *src) & 0x0f) == 0x01) /* 0001 */
285 static UCHAR prop0_table[] = { 0x5d, 0x00 }, prop1_table[] = { 0x00 };
289 prop0 = prop0_table[prop0 - 1];
293 prop0 = prop1_table[prop0 - 1];
296 lp = prop0 / (9 * 5);
300 if (flags == 0) /* tek5:z2 */
302 if (flags == -1) { /* stk5 */
307 wrksiz = 0x180 * sizeof (UINT32) + (0x840 + (0x300 << (lc + lp))) * sizeof (tek_TPRB); /* 最低15KB, lc+lp=3なら、36KB */
308 work = (int *) malloc(wrksiz);
311 flags = tek_decmain5(work, src, outsiz, outbuf, lc, pb, lp, flags);
316 static void tek_setbm5(struct tek_STR_BITMODEL *bm, int t, int m)
320 bm->prb1 = -1 << (m + t);
321 bm->prb0 = ~bm->prb1;
323 bm->tmsk = (-1 << t) & 0xffff;
324 bm->prb0 &= bm->tmsk;
325 bm->prb1 &= bm->tmsk;
330 static int tek_rdget0(struct tek_STR_RNGDEC *rd, int n, int i)
333 while (rd->range < (UINT32) (1 << 24)) {
335 rd->code = rd->code << 8 | *rd->p++;
339 if (rd->code >= rd->range) {
340 rd->code -= rd->range;
347 static int tek_rdget1(struct tek_STR_RNGDEC *rd, tek_TPRB *prob0, int n, int j, struct tek_STR_BITMODEL *bm)
349 UINT32 p, i, *prob, nm = n >> 4;
353 p = *(prob = prob0 + j);
357 if (tek_rdget1(rd, &rd->probs.fchglt, 0x71, 0, &rd->bm[3]) == 0) {
358 /* 寿命変更はまだサポートしてない */
359 printf("Fatal: Life change is not supported. in tek_rdget1\n");
360 printf(" rd->range: %lu, rd->code: %lu, rd->rmsk: %lu\n", rd->range, rd->code, rd->rmsk);
362 longjmp(rd->errjmp, 1);
365 if ((bm->s = tek_rdget1(rd, &rd->probs.fchgprm[i * 2 + bm->s], 0x71, 0, &rd->bm[1])) == 0) {
366 i = tek_rdget1(rd, rd->probs.tbmt, 0x74, 1, &rd->bm[2]) & 15;
371 tek_setbm5(bm, i, ((tek_rdget1(rd, rd->probs.tbmm, 0x74, 1, &rd->bm[2]) - 1) & 15) + 1);
390 while (rd->range < (UINT32) (1 << 24)) {
392 rd->code = rd->code << 8 | *rd->p++;
395 i = (UINT32)((rd->range & rd->rmsk) * p) >> 16;
399 *prob += ((0x10000 - p) >> bm->m) & bm->tmsk;
403 *prob -= (p >> bm->m) & bm->tmsk;
412 static UINT32 tek_revbit(UINT32 data, int len)
416 rev += rev + (data & 1);
422 static int tek_getlen5(struct tek_STR_RNGDEC *rd, int m, int s_pos, int stk)
425 if (tek_rdget1(rd, &rd->probs.lensel[m][0], 0x71, 0, rd->ptbm[3]) ^ stk) /* low */
426 i = tek_rdget1(rd, rd->probs.pb[s_pos].lenlow[m], 0x73, 1, rd->ptbm[4]) & 7;
427 else if (tek_rdget1(rd, &rd->probs.lensel[m][1], 0x71, 0, rd->ptbm[3]) ^ stk) /* mid */
428 i = tek_rdget1(rd, rd->probs.pb[s_pos].lenmid[m], 0x73, 1, rd->ptbm[5]);
431 i = tek_rdget1(rd, rd->probs.lenhigh[m], 0x78, 1, rd->ptbm[6]) - (256 + 256 - 8);
433 if (i < 6 && stk == 0)
434 i = tek_rdget1(rd, &rd->probs.lenext[(1 << i) - 2], i | 0x70, 1, rd->ptbm[7]) - 1;
436 i = tek_rdget0(rd, i, ~1) - 1;
437 i = tek_rdget0(rd, i, ~1) - 1;
444 static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp, int flags)
446 static int state_table[] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
447 int i, j, k, pmch, rep[4], s, pos, m_pos = (1 << pb) - 1, m_lp = (1 << lp) - 1;
448 int stk = (flags == -1), lcr = 8 - lc, s_pos, lit0cntmsk = 0x78;
450 struct tek_STR_RNGDEC *rd = (struct tek_STR_RNGDEC *) work;
451 struct tek_STR_PRB *prb = &rd->probs;
455 rd->code = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3];
456 for (i = 0; i < 4; i++)
458 if (setjmp(rd->errjmp)) // tek_rdget1() 内でエラーが発生したときに飛んでくる
463 for (i = sizeof (struct tek_STR_PRB) / sizeof (tek_TPRB)+(0x300 << (lc + lp)) - 2; i >= 0; i--)
465 ((tek_TPRB *) prb)[i] = 1 << 15;
467 for (i = 0; i < 32; i++) {
468 rd->bm[i].lt = (i >= 4); /* 0..3は寿命なし */
469 rd->bm[i].lt0 = (i < 24) ? 16 * 1024 : 8 * 1024;
471 rd->bm[i].t = rd->bm[i].m = 5;
473 lit1 = prb->lit + ((256 << (lc + lp)) - 2);
476 for (i = 0; i < 32; i++)
478 rd->bm[i].lt = 0; /* 全て寿命なし */
480 for (i = 0; i < 14; i++)
482 rd->ptbm[i] = &rd->bm[0];
486 static UCHAR pt1[14] = {
487 8, 8, 8, 8, 8, 8, 8, 8,
490 static UCHAR pt2[14] = {
491 8, 8, 10, 11, 12, 12, 14, 15,
492 16, 16, 18, 18, 20, 21
495 0- 7:mch, mch, lit1, lensel, lenlow, lenmid, lenhigh, lenext
496 8-15:pslot, pslot, sdis, sdis, align, rep-repg2
499 rd->bm[1].t = 5; rd->bm[1].m = 3; /* for fchgprm */
500 rd->bm[2].t = 9; rd->bm[2].m = 2; /* for tbmt, tbmm */
501 if (flags & 0x40) { /* lt-flag */
502 rd->bm[3].t = 0; rd->bm[3].m = 1;
503 prb->fchglt = 0xffff;
505 rd->bm[22].t = 0; rd->bm[22].m = 1;
507 if (flags == -2) { /* z1 */
508 rd->bm[22].lt = 0; /* repg3のltを0に */
509 for (i = 0; i < 14; i++)
514 for (i = 0; i < 14; i++)
518 lit0cntmsk = (7 >> (flags & 3)) << 4 | 8;
519 pt[ 1] = 8 + ((flags & 0x04) != 0); /* mch */
520 pt[ 5] = 12 + ((flags & 0x08) != 0); /* llm */
521 pt[ 9] = 16 + ((flags & 0x10) != 0); /* pst */
522 pt[11] = 18 + ((flags & 0x20) != 0); /* sds */
524 for (i = 0; i < 14; i++)
526 rd->ptbm[i] = &rd->bm[pt[i]];
529 for (i = 0; i < 32; i++)
531 tek_setbm5(&rd->bm[i], rd->bm[i].t, rd->bm[i].m);
534 if ((tek_rdget1(rd, &prb->pb[0].st[0].mch, 0x71, 0, rd->ptbm[0]) ^ stk) == 0)
539 *q++ = tek_rdget1(rd, prb->lit, lit0cntmsk, 1, &rd->bm[24]) & 0xff;
540 pmch &= 0; s &= 0; pos = 1;
543 if (tek_rdget1(rd, &prb->pb[s_pos].st[s].mch, 0x71, 0, rd->ptbm[s > 0]) ^ stk) { /* 非lz */
544 i = (q[-1] >> lcr | (pos & m_lp) << lc) << 8;
548 *q = tek_rdget1(rd, &prb->lit[i], lit0cntmsk, 1, &rd->bm[24]) & 0xff;
551 struct tek_STR_BITMODEL *bm = &rd->bm[24];
552 j = 1; /* lit1は最初から2を減じてある */
556 j += j + tek_rdget1(rd, &lit1[(i + j) << 1 | pmch >> 7], 0x71, 0, rd->ptbm[2]);
558 if ((k & (lit0cntmsk >> 4)) == 0)
562 if ((((pmch >> 7) ^ j) & 1) != 0 && k != 0) {
563 j = tek_rdget1(rd, &prb->lit[i + j - 1], k | (lit0cntmsk & 0x70), j, bm);
575 if (tek_rdget1(rd, &prb->st[s].rep, 0x71, 0, rd->ptbm[13]) ^ stk) { /* len/dis */
579 j = i = tek_getlen5(rd, 0, s_pos, stk);
582 rep[0] = j = tek_rdget1(rd, prb->pslot[j], 0x76, 1, rd->ptbm[8 + (j == 3)]) & 0x3f;
584 k = (j >> 1) - 1; /* k = [1, 30] */
585 rep[0] = (2 | (j & 1)) << k;
586 if (j < 14){ /* k < 6 */
587 rep[0] |= tek_revbit(tek_rdget1(rd, &prb->spdis[j & 1][(1 << k) - 2], k | 0x70, 1, rd->ptbm[10 + (k >= 4)]), k);
591 rep[0] |= tek_rdget0(rd, k, ~0) << 6;
592 rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x76, 1, rd->ptbm[12]), 6);
594 rep[0] |= tek_rdget0(rd, k - 4, ~0) << 4;
595 rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 0x74, 1, rd->ptbm[12]), 4);
600 } else { /* repeat-dis */
601 if (tek_rdget1(rd, &prb->st[s].repg0, 0x71, 0, rd->ptbm[13]) ^ stk) { /* rep0 */
603 if (tek_rdget1(rd, &prb->pb[s_pos].st[s].rep0l1, 0x71, 0, rd->ptbm[13]) == 0) {
608 if (tek_rdget1(rd, &prb->st[s].repg1, 0x71, 0, rd->ptbm[13]) ^ stk){ /* rep1 */
611 if (tek_rdget1(rd, &prb->st[s].repg2, 0x71, 0, rd->ptbm[13]) ^ stk){ /* rep2 */
615 if (tek_rdget1(rd, &prb->repg3, 0x71, 0, &rd->bm[22]) == 0)
621 i = rep[3]; /* rep3 */
629 i = tek_getlen5(rd, 1, s_pos, stk);
634 if (pos + rep[0] < 0)
639 if (pos + i > osiz) i = osiz - pos;
652 static int tek_decode5(int siz, UCHAR *p, UCHAR *q)
655 int dsiz, hed, bsiz, st = 0;
657 if ((dsiz = tek_getnum_s7s(&p)) > 0) {
658 hed = tek_getnum_s7s(&p);
661 st = tek_lzrestore_tek5(p1 - p + 1, p - 1, dsiz, q);
662 printf("tek_lzrestore_tek5(%d, %d, %d, %d)\n", p1 - p + 1, p - 1, dsiz, q);
665 bsiz = 1 << (((hed >> 1) & 0x0f) + 8);
669 st = tek_lzrestore_tek5(p1 - p, p, dsiz, q);
674 tek_getnum_s7s(&p); /* オプション情報へのポインタを読み飛ばす */
675 st = tek_lzrestore_tek5(p1 - p, p, dsiz, q);