stoneage8.5/石器时代8.5客户端最新源代码/石器源码/system/unpack.cpp

332 lines
7.0 KiB
C++
Raw Permalink Normal View History

2020-06-23 15:53:23 +08:00
#include<stdio.h>
2020-06-23 15:27:59 +08:00
#include<stdlib.h>
#include<string.h>
#include "../systeminc/version.h"
#include"../systeminc/unpack.h"
#include "zlib.h"
#pragma comment(lib,"zlib.lib")
#ifdef _STONDEBUG_
extern int g_iMallocCount;
#endif
#define BIT_CMP (unsigned char)0x80
#define BIT_ZERO (unsigned char)0x40
#define BIT_REP_LARG (unsigned char)0x10
#define BIT_REP_LARG2 (unsigned char)0x20
unsigned char *encoder( unsigned char *buf, unsigned char **disBuf,
unsigned int width, unsigned int height, unsigned int *len, int cmpFlag )
{
unsigned char *wBuf, *ewBuf, *eBuf;
unsigned char *wBuf1, *buf1;
unsigned char *wBuf2, *buf2;
unsigned char idx;
int flag = 1;
RD_HEADER *header;
unsigned int cnt, cnt2;
unsigned char repData;
int mode;
unsigned int l, el;
int addWBuf;
if( *disBuf == NULL ){
if( (wBuf = (unsigned char *)MALLOC( width * height + sizeof( RD_HEADER ) )) == NULL )
{
return NULL;
}
#ifdef _STONDEBUG_
g_iMallocCount++;
#endif
*disBuf = wBuf;
}else{
wBuf = *disBuf;
}
if( cmpFlag ){
flag = 1;
}else{
flag = 0;
}
eBuf = buf + width * height;
ewBuf = wBuf + width * height + sizeof( RD_HEADER );
wBuf1 = wBuf+sizeof( RD_HEADER );
buf1 = buf;
while( cmpFlag ){
if( buf1 >= eBuf ){
flag = 1;
break;
}
if( wBuf1 >= ewBuf ){
flag = 0;
break;
}
if( *buf1 == 0 && *(buf1+1) == 0 ){
idx = BIT_CMP | BIT_ZERO;
cnt = 2;
buf1 += 2;
while( buf1 < eBuf && cnt < 0xfffff ){
if( *buf1 != 0 ){
break;
}
buf1++;
cnt++;
}
if( cnt <= 0xf ){
addWBuf = 0;
}else
if( cnt <= 0xfff ){
addWBuf = 1;
}else{
addWBuf = 2;
}
if( wBuf1+addWBuf >= ewBuf ){
flag = 0;
break;
}
if( addWBuf == 0 ){
idx |= (cnt & 0x0f);
*wBuf1++ = idx;
continue;
}else
if( addWBuf == 1 ){
idx |= (BIT_REP_LARG | ((cnt >> 8) & 0xf));
*wBuf1++ = idx;
*wBuf1++ = (unsigned char)(cnt & 0xff);
continue;
}else{
idx |= (BIT_REP_LARG2 | ((cnt >> 16) & 0xf));
*wBuf1++ = idx;
*wBuf1++ = (unsigned char)((cnt >> 8) & 0xff);
*wBuf1++ = (unsigned char)(cnt & 0xff);
continue;
}
}
if( *buf1 == *(buf1+1) && *buf1 == *(buf1+2) ){
repData = *buf1;
idx = BIT_CMP;
cnt = 3;
buf1 += 3;
while( buf1 < eBuf && cnt < 0xfffff ){
if( *buf1 != repData ){
break;
}
buf1++;
cnt++;
}
if( cnt <= 0xf ){
addWBuf = 1;
}else
if( cnt <= 0xfff ){
addWBuf = 2;
}else{
addWBuf = 3;
}
if( wBuf1+addWBuf >= ewBuf ){
flag = 0;
break;
}
if( addWBuf == 1 ){
idx |= (cnt & 0x0f);
*wBuf1++ = idx;
*wBuf1++ = repData;
continue;
}else
if( addWBuf == 2 ){
idx |= (BIT_REP_LARG | ((cnt >> 8) & 0xf));
*wBuf1++ = idx;
*wBuf1++ = repData;
*wBuf1++ = (unsigned char)(cnt & 0xff);
continue;
}else{
idx |= (BIT_REP_LARG2 | ((cnt >> 16) & 0xf));
*wBuf1++ = idx;
*wBuf1++ = repData;
*wBuf1++ = (unsigned char)((cnt >> 8) & 0xff);
*wBuf1++ = (unsigned char)(cnt & 0xff);
continue;
}
}
idx = 0;
cnt2 = 0;
buf2 = buf1;
wBuf2 = wBuf1;
while( 1 ){
if( buf2 >= eBuf || cnt2 >= 0xfff ){
mode = 0;
break;
}
if( wBuf2 >= ewBuf ){
mode = 1;
break;
}
if( buf2+2 < eBuf ){
if( *buf2 == 0 && *(buf2+1) == 0 ){
mode = 0;
break;
}
if( *buf2 != 0 && *buf2 == *(buf2+1) && *(buf2+1) == *(buf2+2) ){
mode = 0;
break;
}
}
buf2++;
wBuf2++;
cnt2++;
}
if( cnt2 <= 0xf ){
addWBuf = 0;
}else
if( cnt2 <= 0xfff ){
addWBuf = 1;
}else{
addWBuf = 2;
}
if( mode == 1 || wBuf2+addWBuf >= ewBuf ){
flag = 0;
break;
}
if( addWBuf == 0 ){
idx = (cnt2 & 0xf);
*wBuf1++ = idx;
}else
if( addWBuf == 1 ){
idx = BIT_REP_LARG | ((cnt2 >> 8) & 0xf);
*wBuf1++ = idx;
*wBuf1++ = (unsigned char)(cnt2 & 0xff);
}else{
idx = BIT_REP_LARG2 | ((cnt2 >> 16) & 0xf);
*wBuf1++ = idx;
*wBuf1++ = (unsigned char)((cnt2 >> 8) & 0xff);
*wBuf1++ = (unsigned char)(cnt2 & 0xff);
}
for( cnt = 0; cnt < cnt2; cnt++ ){
*wBuf1++ = *buf1++;
}
}
header = (RD_HEADER *)wBuf;
header->id[0] = 'R';
header->id[1] = 'D';
header->width = width;
header->height = height;
if( flag == 1 )
{
header->compressFlag = 1;
header->size = wBuf1 - wBuf;
l = header->size;
}
else
2020-06-23 15:53:23 +08:00
// ???????
2020-06-23 15:27:59 +08:00
{
header->compressFlag = 0;
header->size = (int)wBuf + width * height + sizeof( RD_HEADER );
wBuf1 = wBuf + sizeof( RD_HEADER );
buf1 = buf;
el = width * height;
for( l = 0; l < el; l++ )
*wBuf1++ = *buf1++;
l += sizeof( RD_HEADER );
}
*len = l;
return wBuf;
}
#ifdef _NEW_COLOR_
extern int NewColor16Flg;
#endif
unsigned char *decoder( unsigned char *buf, unsigned char **disBuf,
unsigned int *width1, unsigned int *height1, unsigned int *len )
{
RD_HEADER *header;
unsigned char *wBuf, *ewBuf, *eBuf;
unsigned char *wBuf1, *buf1;
unsigned int width, height;
unsigned int cnt;
unsigned int l, el;
unsigned char repData;
unsigned char idx;
if( *disBuf == NULL )
return NULL;
wBuf = *disBuf;
header = (RD_HEADER *)buf;
if( header->id[0] != 'R' || header->id[1] != 'D' ){
return NULL;
}
width = header->width;
height = header->height;
2020-06-23 15:53:23 +08:00
if( header->compressFlag == 0 ){//羶樓躇
2020-06-23 15:27:59 +08:00
wBuf1 = wBuf;
buf1 = buf+sizeof( RD_HEADER );
el = width * height;
for( l = 0; l < el; l++ )
*wBuf1++ = *buf1++;
*len = l;
*width1 = width;
*height1 = height;
return wBuf;
#ifdef _NEW_COLOR_
}else if( header->compressFlag >= 16 ){
*len = width * height * 4;
*width1 = width;
*height1 = height;
uncompress(*disBuf,(unsigned long *)len,buf+sizeof(RD_HEADER),header->size - sizeof(RD_HEADER));
if(header->compressFlag == 16)
NewColor16Flg=1;
else{
NewColor16Flg=2;
}
return wBuf;
#endif
2020-06-23 15:53:23 +08:00
}else{//樓躇
2020-06-23 15:27:59 +08:00
eBuf = buf + header->size;
ewBuf = wBuf + width * height;
wBuf1 = wBuf;
buf1 = buf+sizeof( RD_HEADER );
while( buf1 < eBuf ){
idx = *buf1++;
if( (idx & BIT_CMP) != 0 ){
if( (idx & BIT_ZERO) != 0 ){
repData = 0;
}else{
repData = *buf1++;
}
if( (idx & BIT_REP_LARG2) != 0 ){
cnt = ((idx & 0x0f)<<16);
cnt |= ((*buf1) << 8);
buf1++;
cnt |= *buf1++;
}else
if( (idx & BIT_REP_LARG) != 0 ){
cnt = ((idx & 0x0f)<<8);
cnt |= *buf1++;
}else{
cnt = (idx & 0x0f);
}
memset( wBuf1, repData, cnt );
wBuf1 += cnt;
}else{
if( (idx & BIT_REP_LARG) != 0 ) {
cnt = ((idx & 0x0f)<<8);
cnt |= *buf1++;
}else{
cnt = (idx & 0x0f);
}
if( cnt >= 0xfffff ){
return NULL;
}
for( l = 0; l < cnt; l++ )
*wBuf1++ = *buf1++;
}
}
*len = width * height;
*width1 = width;
*height1 = height;
return wBuf;
}
}