00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef PLANCK_COMPRESS_UTILS_H
00033 #define PLANCK_COMPRESS_UTILS_H
00034
00035 #include <limits>
00036 #include <vector>
00037 #include <iterator>
00038
00039 #include "datatypes.h"
00040 #include "error_handling.h"
00041 #include "math_utils.h"
00042
00043 class obitstream
00044 {
00045 private:
00046 std::vector<uint8> data;
00047 tsize bitpos;
00048
00049 template<typename T> void put_internal (const T &val, uint8 bits)
00050 {
00051 int bitsleft = 8-(bitpos&7);
00052 if (bitsleft==8) data.push_back(0);
00053 if (bits<=bitsleft)
00054 {
00055 data.back() |= ((val&((T(1)<<bits)-1))<<(bitsleft-bits));
00056 bitpos+=bits;
00057 }
00058 else
00059 {
00060 data.back() |= ((val>>(bits-bitsleft))&((1<<bitsleft)-1));
00061 bitpos+=bitsleft;
00062 put_internal(val,bits-bitsleft);
00063 }
00064 }
00065
00066 public:
00067 obitstream() : bitpos(0) {}
00068
00069 template<typename T> void put (const T &val, uint8 bits)
00070 {
00071 if (bits==0) return;
00072 planck_assert(bits<=(sizeof(T)<<3),"too many bits for this data type");
00073
00074 put_internal(val,bits);
00075 }
00076
00077 const std::vector<uint8> &state() const
00078 { return data; }
00079 };
00080
00081 class ibitstream
00082 {
00083 private:
00084 const std::vector<uint8> data;
00085 tsize bitpos;
00086
00087 template<typename T> void get_internal (T &val, int bits)
00088 {
00089 int bitsleft = 8-(bitpos&7);
00090 if (bits<=bitsleft)
00091 {
00092 val |= ((data[bitpos>>3]>>(bitsleft-bits))&((1<<bits)-1));
00093 bitpos+=bits;
00094 }
00095 else
00096 {
00097 val |= T((data[bitpos>>3])&((1<<bitsleft)-1))<<(bits-bitsleft);
00098 bitpos+=bitsleft;
00099 get_internal(val,bits-bitsleft);
00100 }
00101 }
00102 public:
00103 ibitstream(const std::vector<uint8> &indata) : data(indata), bitpos(0) {}
00104
00105 template<typename T> T get (uint8 bits)
00106 {
00107 if (bits==0) return T(0);
00108 planck_assert(bits<=(sizeof(T)<<3),"too many bits for this data type");
00109 planck_assert((bitpos+bits)<=8*data.size(),"reading past end of stream");
00110 T res=T(0);
00111 get_internal(res,bits);
00112 return res;
00113 }
00114 };
00115
00116 template<typename T,bool> struct notNegativeHelper__
00117 { notNegativeHelper__(const T &) {} };
00118 template<typename T> struct notNegativeHelper__<T,true>
00119 {
00120 notNegativeHelper__(const T &val)
00121 { planck_assert(val>=T(0),"numbers must be nonnegative");}
00122 };
00123 template<typename T> void assertNotNegative(const T &val)
00124 { notNegativeHelper__<T,std::numeric_limits<T>::is_signed> dummy(val); }
00125
00126 template<typename Iter> void interpol_encode2 (Iter l, Iter r, obitstream &obs,
00127 int shift)
00128 {
00129 if (r-l<=1) return;
00130 typedef std::iterator_traits<Iter> traits;
00131 typedef typename traits::value_type T;
00132
00133 Iter m=l+(r-l)/2;
00134 T nval = ((*r-*l)>>shift) - (r-l) + 1;
00135 if (nval<=1) return;
00136
00137 uint8 nb = 1+ilog2(nval-1);
00138 T val = ((*m)>>shift)-(((*l)>>shift)+(m-l));
00139 T nshort=(T(1)<<nb)-nval;
00140 #if 0
00141
00142 T nrot=nval-(nshort>>1);
00143 if (val>=nrot)
00144 val-=nrot;
00145 else
00146 val+=(nval-nrot);
00147 #endif
00148 if (val<nshort)
00149 obs.put(val,nb-1);
00150 else
00151 obs.put(val+nshort,nb);
00152 interpol_encode2(l,m,obs,shift);
00153 interpol_encode2(m,r,obs,shift);
00154 }
00155
00156 template<typename Iter> void interpol_encode (Iter l, Iter r, obitstream &obs)
00157 {
00158 typedef std::iterator_traits<Iter> traits;
00159 typedef typename traits::value_type T;
00160
00161 if (l==r)
00162 { obs.put(0,8); return; }
00163
00164 assertNotNegative(*l);
00165
00166 T combo=*l;
00167 for (Iter i=l+1; i!=r; ++i)
00168 {
00169 planck_assert(*i>*(i-1),"numbers not strictly increasing");
00170 combo|=*i;
00171 }
00172 int shift = trailingZeros(combo);
00173 T maxnum=(*(r-1))>>shift;
00174 if (T(r-l)>maxnum) maxnum=T(r-l);
00175 uint8 maxbits=1+ilog2(maxnum);
00176 obs.put(maxbits,8);
00177 obs.put(shift,8);
00178 obs.put(r-l,maxbits);
00179 obs.put((*l)>>shift,maxbits);
00180 if (r-l==1) return;
00181 obs.put((*(r-1))>>shift,maxbits);
00182 interpol_encode2(l,r-1,obs,shift);
00183 }
00184
00185 template<typename Iter> void interpol_decode2 (Iter l, Iter r, ibitstream &ibs,
00186 int shift)
00187 {
00188 if (r-l<=1) return;
00189 typedef std::iterator_traits<Iter> traits;
00190 typedef typename traits::value_type T;
00191
00192 Iter m=l+(r-l)/2;
00193 T nval = ((*r-*l)>>shift) - (r-l) + 1;
00194 T val=0;
00195
00196 if (nval>1)
00197 {
00198 uint8 nb = 1+ilog2(nval-1);
00199 T nshort=(T(1)<<nb)-nval;
00200 val=ibs.get<T>(nb-1);
00201 if (val>=nshort)
00202 val=(val<<1)+ ibs.get<T>(1) - nshort;
00203 #if 0
00204
00205 T nrot=nval-(nshort>>1);
00206 if (val<(nval-nrot))
00207 val+=nrot;
00208 else
00209 val-=(nval-nrot);
00210 #endif
00211 }
00212 *m=*l+(((m-l)+val)<<shift);
00213
00214 interpol_decode2(l,m,ibs,shift);
00215 interpol_decode2(m,r,ibs,shift);
00216 }
00217
00218 template<typename T> void interpol_decode (std::vector<T> &v, ibitstream &ibs)
00219 {
00220 uint8 maxbits=ibs.get<uint8>(8);
00221 if (maxbits==0) { v.clear(); return; }
00222 int shift = ibs.get<int>(8);
00223 v.resize(ibs.get<tsize>(maxbits));
00224 v[0]=ibs.get<T>(maxbits)<<shift;
00225 if (v.size()==1) return;
00226 v[v.size()-1]=ibs.get<T>(maxbits)<<shift;
00227 interpol_decode2(v.begin(),v.end()-1,ibs,shift);
00228 }
00229
00230 #endif