2007-07-13 13:40:04 +00:00
|
|
|
#include <baselib/system.h>
|
2007-05-22 15:03:32 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
2007-07-13 13:40:04 +00:00
|
|
|
// Format: ESDDDDDD EDDDDDDD EDD... Extended, Data, Sign
|
|
|
|
unsigned char *vint_pack(unsigned char *dst, int i)
|
|
|
|
{
|
|
|
|
*dst = (i>>25)&0x40; // set sign bit if i<0
|
|
|
|
i = i^(i>>31); // if(i<0) i = ~i
|
|
|
|
|
|
|
|
*dst |= i&0x3F; // pack 6bit into dst
|
|
|
|
i >>= 6; // discard 6 bits
|
|
|
|
if(i)
|
|
|
|
{
|
|
|
|
*dst |= 0x80; // set extend bit
|
|
|
|
while(1)
|
|
|
|
{
|
|
|
|
dst++;
|
|
|
|
*dst = i&(0x7F); // pack 7bit
|
|
|
|
i >>= 7; // discard 7 bits
|
|
|
|
*dst |= (i!=0)<<7; // set extend bit (may branch)
|
|
|
|
if(!i)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dst++;
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
const unsigned char *vint_unpack(const unsigned char *src, int *i)
|
|
|
|
{
|
|
|
|
int sign = (*src>>6)&1;
|
|
|
|
*i = *src&0x3F;
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
{
|
|
|
|
if(!(*src&0x80)) break;
|
|
|
|
src++;
|
|
|
|
*i |= (*src&(0x7F))<<(6);
|
|
|
|
|
|
|
|
if(!(*src&0x80)) break;
|
|
|
|
src++;
|
|
|
|
*i |= (*src&(0x7F))<<(6+7);
|
|
|
|
|
|
|
|
if(!(*src&0x80)) break;
|
|
|
|
src++;
|
|
|
|
*i |= (*src&(0x7F))<<(6+7+7);
|
|
|
|
|
|
|
|
if(!(*src&0x80)) break;
|
|
|
|
src++;
|
|
|
|
*i |= (*src&(0x7F))<<(6+7+7+7);
|
|
|
|
}
|
|
|
|
|
|
|
|
src++;
|
|
|
|
*i ^= -sign; // if(sign) *i = ~(*i)
|
|
|
|
return src;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
long intpack_decompress(const void *src_, int size, void *dst_)
|
|
|
|
{
|
|
|
|
const unsigned char *src = (unsigned char *)src_;
|
|
|
|
const unsigned char *end = src + size;
|
|
|
|
int *dst = (int *)dst_;
|
|
|
|
while(src < end)
|
|
|
|
{
|
|
|
|
src = vint_unpack(src, dst);
|
|
|
|
dst++;
|
|
|
|
}
|
|
|
|
return (long)((unsigned char *)dst-(unsigned char *)dst_);
|
|
|
|
}
|
|
|
|
|
|
|
|
long intpack_compress(const void *src_, int size, void *dst_)
|
|
|
|
{
|
|
|
|
int *src = (int *)src_;
|
|
|
|
unsigned char *dst = (unsigned char *)dst_;
|
|
|
|
size /= 4;
|
|
|
|
while(size)
|
|
|
|
{
|
|
|
|
dst = vint_pack(dst, *src);
|
|
|
|
size--;
|
|
|
|
src++;
|
|
|
|
}
|
|
|
|
return (long)(dst-(unsigned char *)dst_);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
long zerobit_compress(const void *src_, int size, void *dst_)
|
|
|
|
{
|
|
|
|
unsigned char *src = (unsigned char *)src_;
|
|
|
|
unsigned char *dst = (unsigned char *)dst_;
|
|
|
|
|
|
|
|
//int zerocount = 0 ;
|
|
|
|
while(size)
|
|
|
|
{
|
|
|
|
unsigned char bit = 0x80;
|
|
|
|
unsigned char mask = 0;
|
|
|
|
int dst_move = 1;
|
|
|
|
int chunk = size < 8 ? size : 8;
|
|
|
|
size -= chunk;
|
|
|
|
|
|
|
|
for(int b = 0; b < chunk; b++, bit>>=1)
|
|
|
|
{
|
|
|
|
if(*src)
|
|
|
|
{
|
|
|
|
dst[dst_move] = *src;
|
|
|
|
mask |= bit;
|
|
|
|
dst_move++;
|
|
|
|
}
|
|
|
|
|
|
|
|
src++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*dst = mask;
|
|
|
|
dst += dst_move;
|
|
|
|
}
|
|
|
|
|
|
|
|
long l = (long)(dst-(unsigned char *)dst_);
|
|
|
|
//dbg_msg("zerobit", "%d", (int)l);
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
|
|
|
long zerobit_decompress(const void *src_, int size, void *dst_)
|
|
|
|
{
|
|
|
|
unsigned char *src = (unsigned char *)src_;
|
|
|
|
unsigned char *dst = (unsigned char *)dst_;
|
|
|
|
unsigned char *end = src + size;
|
|
|
|
|
|
|
|
//int zerocount = 0 ;
|
|
|
|
while(src != end)
|
|
|
|
{
|
|
|
|
unsigned char bit = 0x80;
|
|
|
|
unsigned char mask = *src++;
|
|
|
|
|
|
|
|
for(int b = 0; b < 8; b++, bit>>=1)
|
|
|
|
{
|
|
|
|
if(mask&bit)
|
|
|
|
*dst++ = *src++;
|
|
|
|
else
|
|
|
|
*dst++ = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
long l = (long)(dst-(unsigned char *)dst_);
|
|
|
|
//dbg_msg("zerobit", "%d", (int)l);
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|