研究下大面积的自动客户端补丁导入 加密函数
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;
}
*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;
}
// ゼロの圧縮(2個以上なら圧縮)
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++;
}
// 0の連続が16個未満の時
if( cnt <= 0xf )
{
addWBuf = 0;
}
else
// 16個以上4096未満の時
if( cnt <= 0xfff )
{
addWBuf = 1;
}
// 4096以上の時
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 1
// ゼロ以外で圧縮(3個以上なら圧縮)
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++;
}
// 連続データが16個未満の時
if( cnt <= 0xf )
{
addWBuf = 1;
}
else
// 16個以上4096未満の時
if( cnt <= 0xfff )
{
addWBuf = 2;
}
// 4096以上の時
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;
}
}
#endif
// 圧縮無し
// 最初はどこまで圧縮しないかを見るだけ
idx = 0;
cnt2 = 0;
buf2 = buf1;
wBuf2 = wBuf1;
while( 1 )
{
// 終了チェック
if( buf2 >= eBuf // 読み込むデータが無いので終了
|| cnt2 >= 0xfff ) // 一回に扱えるデータ長を超えたので次へ
{
mode = 0;
break;
}
if( wBuf2 >= ewBuf )
{
// 圧縮データサイズが元データサイズを超えたので終了
mode = 1;
break;
}
// データの最後から4番目以前なら圧縮データがあるか確認する
// それ以外は無圧縮として扱う
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
// 圧縮せずにコピー
{
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;
}