00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef _RVLCOMPRESS_HPP
00013 #define _RVLCOMPRESS_HPP
00014
00015 #include "lemur-platform.h"
00016
00017 #define pow2_7 128
00018 #define pow2_14 16384
00019 #define pow2_21 2097152
00020 #define pow2_28 268435456
00021
00022 #define pow2_31 2147483648U
00023
00024
00025 class RVLCompress {
00026 public:
00028 static int compress_ints (int *data_ptr, unsigned char *out_ptr, int size);
00029
00031 static int decompress_ints(unsigned char *data_ptr, int *out_ptr, int num_bytes);
00032
00034 static int compressedSize( int data );
00035
00036 static char* compress_int( char* dest, int data );
00037 static char* compress_longlong( char* dest, INT64 data );
00038 static const char* decompress_int( const char* source, int& data );
00039 static const char* decompress_longlong( const char* source, INT64& data );
00040 static const char* decompress_int_count( const char* source, int* result, int numInts );
00041 static const char* skip_ints( const char* source, int numInts );
00042
00043 };
00044
00045 inline const char* RVLCompress::decompress_int( const char* source, int& data ) {
00046 const unsigned int terminator = (1<<7);
00047 const unsigned int mask = ((1<<7)-1);
00048
00049 if( source[0] & terminator ) {
00050 data = source[0] & mask;
00051 return source + 1;
00052 } else if ( source[1] & terminator ) {
00053 data = (source[0]) |
00054 ((source[1]&mask) << 7);
00055 return source + 2;
00056 } else if ( source[2] & terminator ) {
00057 data = (source[0]) |
00058 (source[1] << 7) |
00059 ((source[2]&mask) << 14);
00060 return source + 3;
00061 } else if ( source[3] & terminator ) {
00062 data = (source[0]) |
00063 (source[1] << 7) |
00064 (source[2] << 14) |
00065 ((source[3]&mask) << 21);
00066 return source + 4;
00067 } else {
00068 data = (source[0]) |
00069 (source[1] << 7) |
00070 (source[2] << 14) |
00071 (source[3] << 21) |
00072 ((source[4]&mask) << 28);
00073 return source + 5;
00074 }
00075 }
00076
00077 inline const char* RVLCompress::decompress_longlong( const char* source, INT64& data ) {
00078 const unsigned int terminator = (1<<7);
00079 const unsigned int mask = ((1<<7)-1);
00080 unsigned int i;
00081
00082 data = 0;
00083
00084 for( i=0; i<10; i++ ) {
00085 if( source[i] & terminator ) {
00086 data |= ((source[i] & mask) << 7*i);
00087 break;
00088 } else {
00089 data |= (source[i] << 7*i);
00090 }
00091 }
00092
00093 return source + i + 1;
00094 }
00095
00096 inline const char* RVLCompress::decompress_int_count( const char* source, int* result, int numInts ) {
00097 const char* ptr = source;
00098
00099 for( int i=0; i<numInts; i++ ) {
00100 ptr = decompress_int( ptr, result[i] );
00101 }
00102
00103 return ptr;
00104 }
00105
00106 inline const char* RVLCompress::skip_ints( const char* source, int numInts ) {
00107 while( numInts-- ) {
00108 while( !(*source & 0x80) )
00109 source++;
00110 source++;
00111 }
00112 return source;
00113 }
00114
00115
00116 #endif