- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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