diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2009-10-27 14:38:53 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2009-10-27 14:38:53 +0000 |
| commit | 878ede3080ab2cfb627aca505c397d9765052996 (patch) | |
| tree | 98bff371070e1dca0295f0ca58d64ac4ee8042ce /src/engine/e_compression.cpp | |
| parent | 9b99ec0e60b60134e46f2f71d707230948f7db03 (diff) | |
| download | zcatch-878ede3080ab2cfb627aca505c397d9765052996.tar.gz zcatch-878ede3080ab2cfb627aca505c397d9765052996.zip | |
major update with stuff
Diffstat (limited to 'src/engine/e_compression.cpp')
| -rw-r--r-- | src/engine/e_compression.cpp | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/engine/e_compression.cpp b/src/engine/e_compression.cpp new file mode 100644 index 00000000..f4d6e0c0 --- /dev/null +++ b/src/engine/e_compression.cpp @@ -0,0 +1,86 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#include <base/system.h> + +/* 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; + + do + { + 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); + } while(0); + + 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_); +} + |