depack.c
来自「一些初级的网络编程」· C语言 代码 · 共 164 行
C
164 行
/*
* aPLib compression library - the smaller the better :)
*
* C depacker
*
* Copyright (c) 1998-2004 by Joergen Ibsen / Jibz
* All Rights Reserved
*
* http://www.ibsensoftware.com/
*/
#include "depack.h"
/* internal data structure */
typedef struct {
const unsigned char *source;
unsigned char *destination;
unsigned int tag;
unsigned int bitcount;
} APDEPACKDATA;
static int aP_getbit(APDEPACKDATA *ud)
{
unsigned int bit;
/* check if tag is empty */
if (!ud->bitcount--)
{
/* load next tag */
ud->tag = *ud->source++;
ud->bitcount = 7;
}
/* shift bit out of tag */
bit = (ud->tag >> 7) & 0x01;
ud->tag <<= 1;
return bit;
}
static unsigned int aP_getgamma(APDEPACKDATA *ud)
{
unsigned int result = 1;
/* input gamma2-encoded bits */
do {
result = (result << 1) + aP_getbit(ud);
} while (aP_getbit(ud));
return (result);
}
unsigned int aP_depack(const void *source, void *destination)
{
APDEPACKDATA ud;
unsigned int offs, len, R0, LWM;
int done;
int i;
ud.source = (const unsigned char *) source;
ud.destination = (unsigned char *) destination;
ud.bitcount = 0;
LWM = 0;
done = 0;
/* first byte verbatim */
*ud.destination++ = *ud.source++;
/* main decompression loop */
while (!done)
{
if (aP_getbit(&ud))
{
if (aP_getbit(&ud))
{
if (aP_getbit(&ud))
{
offs = 0;
for (i = 4; i; i--) offs = (offs << 1) + aP_getbit(&ud);
if (offs)
{
*ud.destination = *(ud.destination - offs);
ud.destination++;
} else {
*ud.destination++ = 0x00;
}
LWM = 0;
} else {
offs = *ud.source++;
len = 2 + (offs & 0x0001);
offs >>= 1;
if (offs)
{
for (; len; len--)
{
*ud.destination = *(ud.destination - offs);
ud.destination++;
}
} else done = 1;
R0 = offs;
LWM = 1;
}
} else {
offs = aP_getgamma(&ud);
if ((LWM == 0) && (offs == 2))
{
offs = R0;
len = aP_getgamma(&ud);
for (; len; len--)
{
*ud.destination = *(ud.destination - offs);
ud.destination++;
}
} else {
if (LWM == 0) offs -= 3; else offs -= 2;
offs <<= 8;
offs += *ud.source++;
len = aP_getgamma(&ud);
if (offs >= 32000) len++;
if (offs >= 1280) len++;
if (offs < 128) len += 2;
for (; len; len--)
{
*ud.destination = *(ud.destination - offs);
ud.destination++;
}
R0 = offs;
}
LWM = 1;
}
} else {
*ud.destination++ = *ud.source++;
LWM = 0;
}
}
return ud.destination - (unsigned char *) destination;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?