golomb.cpp

00001 /* ***** BEGIN LICENSE BLOCK *****
00002 *
00003 * $Id: golomb.cpp,v 1.2 2005/01/30 05:11:40 gabest Exp $ $Name:  $
00004 *
00005 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006 *
00007 * The contents of this file are subject to the Mozilla Public License
00008 * Version 1.1 (the "License"); you may not use this file except in compliance
00009 * with the License. You may obtain a copy of the License at
00010 * http://www.mozilla.org/MPL/
00011 *
00012 * Software distributed under the License is distributed on an "AS IS" basis,
00013 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
00014 * the specific language governing rights and limitations under the License.
00015 *
00016 * The Original Code is BBC Research and Development code.
00017 *
00018 * The Initial Developer of the Original Code is the British Broadcasting
00019 * Corporation.
00020 * Portions created by the Initial Developer are Copyright (C) 2004.
00021 * All Rights Reserved.
00022 *
00023 * Contributor(s): Thomas Davies (Original Author)
00024 *
00025 * Alternatively, the contents of this file may be used under the terms of
00026 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
00027 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
00028 * the GPL or the LGPL are applicable instead of those above. If you wish to
00029 * allow use of your version of this file only under the terms of the either
00030 * the GPL or LGPL and not to allow others to use your version of this file
00031 * under the MPL, indicate your decision by deleting the provisions above
00032 * and replace them with the notice and other provisions required by the GPL
00033 * or LGPL. If you do not delete the provisions above, a recipient may use
00034 * your version of this file under the terms of any one of the MPL, the GPL
00035 * or the LGPL.
00036 * ***** END LICENSE BLOCK ***** */
00037 
00038 #include <libdirac_common/golomb.h>
00039 #include <libdirac_common/bit_manager.h>
00040 using namespace dirac;
00041 
00042 #include <cmath>
00043 #include <cstdlib>
00044 #include <iostream>
00045 
00046 using std::vector;
00047 namespace dirac
00048 {
00049 void UnsignedGolombCode(BasicOutputManager& bitman, const unsigned int val)
00050 {
00051     unsigned int M = 0;
00052     unsigned int info;
00053     unsigned int val2 = val;
00054 
00055     val2++;
00056     while (val2>1)
00057         {//get the log base 2 of val.
00058         val2 >>= 1;
00059         M++;        
00060     }
00061     info = val - (1<<M) + 1;
00062 
00063     //add length M+1 prefix
00064     for ( unsigned int i=1 ; i<=M ; ++i)
00065         bitman.OutputBit(0);
00066     
00067     bitman.OutputBit(1);
00068 
00069     //add info bits
00070     for (unsigned int i=0 ; i<M ;++i)
00071         bitman.OutputBit( info & (1<<i) );        
00072     
00073 
00074 }
00075 void UnsignedGolombCode(std::vector<bool>& bitvec, const unsigned int val)
00076 {
00077     unsigned int M = 0;
00078     unsigned int info;
00079     unsigned int val2 = val;
00080 
00081     bitvec.clear();
00082     val2++;
00083     while ( val2>1 )
00084     {//get the log base 2 of val.
00085         val2 >>= 1;
00086         M++;        
00087     }
00088     info = val - (1<<M) + 1;
00089 
00090     //add length M+1 prefix
00091     for ( unsigned int i=1 ; i<=M ; ++i)
00092         bitvec.push_back(0);
00093     
00094     bitvec.push_back(1);
00095 
00096     //add info bits
00097     for ( unsigned int i=0 ; i<M ; ++i)
00098         bitvec.push_back( info & (1<<i) );
00099 
00100 }
00101 
00102 void GolombCode(BasicOutputManager& bitman, const int val)
00103 {
00104 
00105     //code the magnitude
00106     UnsignedGolombCode(bitman,(unsigned int) abs(val));
00107 
00108     //do sign
00109     if (val>0) bitman.OutputBit(1);
00110     else if (val<0) bitman.OutputBit(0);
00111 }
00112 
00113 void GolombCode(vector<bool>& bitvec, const int val)
00114 {
00115 
00116     //code the magnitude
00117     UnsignedGolombCode(bitvec,(unsigned int) abs(val));
00118 
00119     //do sign
00120     if (val>0) bitvec.push_back(1);
00121     else if (val<0) bitvec.push_back(0);
00122 }
00123 
00124 unsigned int UnsignedGolombDecode(BitInputManager& bitman)
00125 {    
00126     unsigned int M = 0;
00127     unsigned int info = 0;
00128     bool bit = 0;
00129     unsigned int val = 0;
00130 
00131     do
00132     {
00133         bit = bitman.InputBit();
00134         if ( !bit )
00135             M++;
00136     }
00137     while( !bit && M<64 );//terminate if the number is too big!
00138 
00139     //now get the M info bits    
00140     for ( unsigned int i=0 ; i<M ; ++i)
00141     {
00142         bit = bitman.InputBit();
00143         if ( bit )
00144             info |= (1<<i);
00145     }// i    
00146     val = (1<<M) -1 + info;
00147 
00148     return val;
00149 }
00150 
00151 unsigned int UnsignedGolombDecode(const std::vector<bool>& bitvec)
00152 {
00153     unsigned int M = 0;
00154     unsigned int info = 0;
00155     bool bit = 0;
00156     unsigned int val = 0;
00157 
00158     unsigned int index = 0;//index into bitvec
00159 
00160     do
00161     {
00162         bit = bitvec[++index];
00163         if (!bit)
00164             M++;
00165     }
00166     while( !bit && M<64 );//terminate if the number is too big!
00167 
00168     //now get the M info bits    
00169     for ( unsigned int i=0 ;i<M ; ++i)
00170     {
00171         bit = bitvec[++index];
00172         if (bit)
00173             info |= (1<<i);
00174     }    
00175     val = (1<<M) - 1 + info;
00176 
00177     return val;
00178 }
00179 
00180 int GolombDecode(BitInputManager& bitman)
00181 {
00182 
00183     int val = int(UnsignedGolombDecode(bitman));
00184     bool bit;
00185 
00186      //get the sign
00187     if (val != 0)
00188     {
00189         bit = bitman.InputBit();
00190         if ( !bit )
00191             val = -val;
00192     }
00193     return val;        
00194 }
00195 
00196 int GolombDecode(const vector<bool>& bitvec)
00197 {
00198 
00199     int val = int(UnsignedGolombDecode(bitvec));
00200     bool bit;
00201 
00202      //get sign
00203     if (val != 0)
00204     {
00205         bit = bitvec[bitvec.size()-1];
00206         if (!bit)
00207             val = -val;
00208     }
00209     return val;        
00210 }
00211 } // namespace dirac

Generated on Tue Dec 13 14:47:13 2005 for guliverkli by  doxygen 1.4.5