⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtk5s.cpp

📁 MONA是为数不多的C++语言编写的一个很小的操作系统
💻 CPP
字号:
//#include <setjmp.h>//#include <stdlib.h>		/* malloc *///#include <stdio.h>		/* NULL */#include <monapi/messages.h>#include <monapi/syscall.h>#include "FileServer.h"#include "dtk5s.h"#include "file.h"typedef unsigned int UINT32;typedef unsigned char UCHAR;typedef UINT32 tek_TPRB;int tek_checkformat(int siz, UCHAR *p); /* 揥奐屻偺僒僀僘傪曉偡 */	/* -1:旕osacmp */	/* -2:osacmp偩偑懳墳偱偒側偄 */int tek_decode(int siz, UCHAR *p, UCHAR *q); /* 惉岟偟偨傜0 */	/* 惓偺抣偼僼僅乕儅僢僩偺堎忢丒枹懳墳丄晧偺抣偼儊儌儕晄懌 */static unsigned int tek_getnum_s7s(UCHAR **pp);static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf);static int tek_decmain5(int *work, UCHAR *src, int osiz, UCHAR *q, int lc, int pb, int lp);int tek_checkformat(int siz, UCHAR *p){	static UCHAR header[] = "\xff\xff\xff\x01\x00\x00\x00" "OSASKCMP";	int i;	if (siz < 17)		return -1;	for (i = 0; i < 15; i++) {		if (p[i + 1] != header[i])			return -1;	}	if (p[0] != 0x89)		return -2;	p += 16;	return tek_getnum_s7s(&p);}int tek_decode(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;}static unsigned int tek_getnum_s7s(UCHAR **pp)/* 偙傟偼昁偢big-endian *//* 壓懯偑側偄偺偱拞恎傪偄偠傝傗偡偄 */{	unsigned int s = 0;	UCHAR *p = *pp;	do {		s = s << 7 | *p++;	} while ((s & 1) == 0);	s >>= 1;	*pp = p;	return s;}static int tek_lzrestore_tek5(int srcsiz, UCHAR *src, int outsiz, UCHAR *outbuf){	int wrksiz, lc, lp, pb, *work, prop0, fl;	if ((fl = (prop0 = *src) & 0x0f) != 0x01) /* 0001 */		return 1;	src++;	prop0 >>= 4;	if (prop0 == 0)		prop0 = *src++;	else {		static UCHAR prop0_table[] = { 0x5d, 0x00 };		if (prop0 >= 3)			return 1;		prop0 = prop0_table[prop0 - 1];	}	pb = prop0 / (9 * 5);	prop0 %= 9 * 5;	lp = prop0 / 9;	lc = prop0 % 9;	wrksiz = (0x800 + (0x300 << (lc + lp))) * sizeof (tek_TPRB); /* 嵟掅11KB, lc+lp=3側傜丄32KB */	work = (int *)malloc(wrksiz);	if (work == NULL)		return -1;	return tek_decmain5(work, src, outsiz, outbuf, lc, pb, lp);}struct tek_STR_RNGDEC {	UCHAR *p;	UINT32 range, code;};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[16];	tek_TPRB spdis[2][2+4+8+16+32];	tek_TPRB lit[1];};struct tek_STR_WORK5 {	struct tek_STR_RNGDEC rd;	struct tek_STR_PRB prb;};static int tek_rdget0(struct tek_STR_RNGDEC *rd, int n, int i){	do {		if (rd->range < (UINT32) (1 << 24))			goto shift;shift1:		rd->range >>= 1;		i += i;		if (rd->code >= rd->range) {			rd->code -= rd->range;			i |= 1;		}	} while (--n);	return ~i;shift:	do {		rd->range <<= 8;		rd->code = rd->code << 8 | *rd->p++;	} while (rd->range < (UINT32) (1 << 24));	goto shift1;}static int tek_rdget1(struct tek_STR_RNGDEC *rd, UINT32 *prob0, int n, int j){	UINT32 i, *prob;	prob0 -= j;	do {		prob = prob0 + j;		if (rd->range < (UINT32) (1 << 24))			goto shift;shift1:		j += j;		i = (rd->range >> 11) * *prob;		if (rd->code < i) {			j |= 1;			rd->range = i;			*prob += (0x800 - *prob) >> 5;		} else {			rd->range -= i;			rd->code -= i;			*prob -= *prob >> 5;		}	} while (--n);	return j;shift:	do {		rd->range <<= 8;		rd->code = rd->code << 8 | *rd->p++;	} while (rd->range < (UINT32) (1 << 24));	goto shift1;}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, struct tek_STR_PRB *prb, int m, int s_pos){	int i;	if (tek_rdget1(rd, &prb->lensel[m][0], 1, 0) == 0) /* low */		i = tek_rdget1(rd, prb->pb[s_pos].lenlow[m], 3, 1) & 7;	else if (tek_rdget1(rd, &prb->lensel[m][1], 1, 0) == 0) /* mid */		i = tek_rdget1(rd, prb->pb[s_pos].lenmid[m], 3, 1);	else {		/* high */		i = tek_rdget1(rd, prb->lenhigh[m], 8, 1) - (256 + 256 - 8);		if (i > 0) {			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){	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 lcr = 8 - lc, s_pos;	UINT32 *lit1;	struct tek_STR_PRB *prb = &((struct tek_STR_WORK5 *) work)->prb;	struct tek_STR_RNGDEC *rd = &((struct tek_STR_WORK5 *) work)->rd;	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;	for (i = sizeof (struct tek_STR_PRB) / sizeof (UINT32) + (0x300 << (lc + lp)) - 2; i >= 0; i--)		((UINT32 *) prb)[i] = 1 << 10;	lit1 = prb->lit + ((256 << (lc + lp)) - 2);	if (tek_rdget1(rd, &prb->pb[0].st[0].mch, 1, 0))		goto err;	*q++ = tek_rdget1(rd, prb->lit, 8, 1) & 0xff;	pmch &= 0; s &= 0; pos = 1;	do {		s_pos = pos & m_pos;		if (tek_rdget1(rd, &prb->pb[s_pos].st[s].mch, 1, 0) == 0) { /* 旕lz */			i = (q[-1] >> lcr | (pos & m_lp) << lc) << 8;			s = state_table[s];			if (pmch == 0)				*q = tek_rdget1(rd, &prb->lit[i], 8, 1) & 0xff;			else {				j = 1; /* lit1偼嵟弶偐傜2傪尭偠偰偁傞 */				k = 8;				pmch = q[rep[0]];				do {					j += j + tek_rdget1(rd, &lit1[(i + j) << 1 | pmch >> 7], 1, 0);					k--;					if ((((pmch >> 7) ^ j) & 1) != 0 && k != 0) {						j = tek_rdget1(rd, &prb->lit[i + j - 1], k, j);						break;					}					pmch <<= 1;				} while (k);				*q = j & 0xff;				pmch &= 0;			}			pos++;			q++;		} else { /* lz */			pmch |= 1;			if (tek_rdget1(rd, &prb->st[s].rep, 1, 0) == 0) { /* len/dis */				rep[3] = rep[2];				rep[2] = rep[1];				rep[1] = rep[0];				j = i = tek_getlen5(rd, prb, 0, s_pos);				s = s < 7 ? 7 : 10;				if (j >= 4)					j = 3;				rep[0] = j = tek_rdget1(rd, prb->pslot[j], 6, 1) & 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, 1), k);					else {						rep[0] |= tek_rdget0(rd, k - 4, ~0) << 4;						rep[0] |= tek_revbit(tek_rdget1(rd, prb->algn, 4, 1), 4);					}				}				rep[0] = ~rep[0];			} else { /* repeat-dis */				if (tek_rdget1(rd, &prb->st[s].repg0, 1, 0) == 0) { /* rep0 */					i |= -1;					if (tek_rdget1(rd, &prb->pb[s_pos].st[s].rep0l1, 1, 0) == 0) {						s = s < 7 ? 9 : 11;						goto skip;					}				} else {					if (tek_rdget1(rd, &prb->st[s].repg1, 1, 0) == 0) /* rep1 */						i = rep[1];					else {						if (tek_rdget1(rd, &prb->st[s].repg2, 1, 0) == 0) /* rep2 */							i = rep[2];						else {							i = rep[3]; /* rep3 */							rep[3] = rep[2];						}						rep[2] = rep[1];					}					rep[1] = rep[0];					rep[0] = i;				}				i = tek_getlen5(rd, prb, 1, s_pos);				s = s < 7 ? 8 : 11;			}skip:			i += 2;			if (pos + rep[0] < 0)				goto err;			pos += i;			if (pos > osiz)				goto err;			do {				*q = q[rep[0]];				q++;			} while (--i);		}	} while (pos < osiz);	return 0;err:	return 1;}int64_t GetST5DecompressedSize(monapi_cmemoryinfo* mi){	int64_t ret = 0;	ret = tek_checkformat(mi->Size, (UCHAR*)mi->Data);	return ret;}monapi_cmemoryinfo* ST5Decompress(monapi_cmemoryinfo* mi){	int64_t size = GetST5DecompressedSize(mi);	if (size < 0) return NULL;		// if size >= 4GB abort...	if ((size >> 32) > 0) return NULL;		monapi_cmemoryinfo* ret = new monapi_cmemoryinfo();	if (!monapi_cmemoryinfo_create(ret, (dword)(size + 1), 0))	{		monapi_cmemoryinfo_delete(ret);		return NULL;	}	ret->Size--;		if (tek_decode(mi->Size, mi->Data, ret->Data) != 0) {		// Decompress failed		monapi_cmemoryinfo_dispose(ret);		monapi_cmemoryinfo_delete(ret);		return NULL;	}		ret->Data[ret->Size] = 0;	return ret;}monapi_cmemoryinfo* ST5DecompressFile(const char* file, bool prompt /*= false*/){	monapi_cmemoryinfo* mi = ReadFile(file, prompt), * ret = NULL;	if (mi == NULL) return ret;		if (prompt) printf("%s: Decompressing %s....", SVR, file);	ret = ST5Decompress(mi);	if (prompt) printf(ret != NULL ? "OK\n" : "ERROR\n");	monapi_cmemoryinfo_dispose(mi);	monapi_cmemoryinfo_delete(mi);	return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -