]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTDataInflater.h
bugfix 88038: inconsistent handling of reference counters in library manager
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataInflater.h
1 //-*- Mode: C++ -*-
2 // $Id$
3 #ifndef ALIHLTDATAINFLATER_H
4 #define ALIHLTDATAINFLATER_H
5 //* This file is property of and copyright by the ALICE HLT Project        * 
6 //* ALICE Experiment at CERN, All rights reserved.                         *
7 //* See cxx source for full Copyright notice                               *
8
9 /// @file   AliHLTDataInflater.h
10 /// @author Matthias Richter, Timm Steinbeck
11 /// @date   2011-08-10
12 /// @brief  Data inflater reading the bitstream from the AliHLTDataDeflater
13 /// @note   Code original from AliHLTTPCCompModelInflater
14
15 #include "AliHLTLogging.h"
16 #include "AliHLTDataTypes.h"
17 #include "AliHLTStdIncludes.h"
18
19 /**
20  * @class AliHLTDataInflater
21  * Data inflating interface to a bitstream encoded by AliHLTDataDeflater
22  *
23  * Setting up the data inflater:
24  * <pre>
25   AliHLTDataInflater inflater;
26   if (inflater.InitBitDataInput(pData, dataSize)<0) {
27     // can not initialize
28   }
29  * </pre>
30  *
31  * If the layout in the bitstream is known the parts of known bit length
32  * can be read by
33  * - InputBit(value)
34  * - InputBits(value, length)
35  *
36  * For inflating huffman encoded streams where the symbol length is unknown
37  * one has to read a fixed value, retrieve the symbol and rewind the stream.
38  * Example how to read a fixed number of bits from the stream and rewind
39  * after the length of the symbol has been determined.
40  * <pre>
41   AliHLTUInt64_t inputWord=0;
42   int inputLength=sizeof(inputWord)*8;
43   while (outClusterCnt<nofClusters && inflater.InputBits(inputWord, inputLength)) {
44     // check how many of the bits belong to the symbol and rewind the
45     // input stream
46     int symbolLength=...;
47     inputWord>>=(inputLength-symbolLength);
48     if (!inflater.RewindBitPosition(inputLength-symbolLength)) {
49       // some error
50       break;
51     }
52
53     // do something with data in input word
54
55     // check if there is less remaining data than the full input word bit length
56     UInt_t bytes=inflater.GetRemainingBitDataSizeBytes();
57     if (bytes>0 && bytes<=sizeof(inputWord)) {
58       // reading the last bytes
59       // available bits are determined by cuurent position+1 (because
60       // position 0 means 1 bit still available) and the bits in the
61       // available bytes
62       inputLength=inflater.GetCurrentBitInputPosition()+1+(bytes-1)*8;
63     }
64   }
65  * </pre>
66  * 
67  *
68  * @ingroup alihlt_base
69  */
70 class AliHLTDataInflater : public AliHLTLogging
71 {
72 public:
73   /// standard constructor
74   AliHLTDataInflater();
75   /// destructor
76   ~AliHLTDataInflater();
77
78   /** init inflater for reading
79    * @param input  AliHLTUInt8_t* pointer to input data
80    * @param inputSize UInt_t input data size
81    */
82   int InitBitDataInput(const AliHLTUInt8_t* input, UInt_t inputSize );
83
84   /** close inflater for reading */     
85   void CloseBitDataInput();
86       
87   /** function to get current byte input position 
88    * @return unsigned long value of current byte input position
89    */
90   unsigned long GetCurrentByteInputPosition() const
91   {
92     return (unsigned long)( fBitDataCurrentInput - fBitDataCurrentInputStart );
93   }
94
95   /** function to get current bit input position
96    * @return unsigned value of current bit input position
97    */
98   unsigned GetCurrentBitInputPosition() const
99   {
100     return fBitDataCurrentPosInWord;
101   }
102
103   /** function to get current input byte
104    * @return AliHLTUInt8_t value of current input byte
105    */
106   AliHLTUInt8_t GetCurrentInputByte() const
107   {
108     return fBitDataCurrentWord;
109   }
110
111   /** function to determine end of bit input
112    * @return boolean if end is reached or not
113    */
114   bool EndOfBitInput() const
115   {
116     return (fBitDataCurrentInput>=fBitDataCurrentInputEnd);
117   }
118       
119   /** function to get bit data input size bytes
120    * @return UInt_t value of bit data input size bytes
121    */
122   UInt_t GetBitDataInputSizeBytes() const
123   {
124     return fBitDataCurrentInput-fBitDataCurrentInputStart;
125   }
126
127   /** get number of remaining input bytes
128    * the last byte might be already partially read, use
129    * GetCurrentBitInputPosition()
130    */
131   UInt_t GetRemainingBitDataSizeBytes() const
132   {
133     return fBitDataCurrentInputEnd-fBitDataCurrentInput;
134   }
135
136   /** function to determine input bit
137    * @return boolean (if bit is 1 or 0)
138    */
139   bool InputBit( AliHLTUInt8_t & value );
140
141   /** function to read bits from bitstream
142    * @param value
143    * @param bitCount
144    * @return boolean 
145    */
146   template<typename T>
147   bool InputBits( T & value, UInt_t const & bitCount );
148
149   /**
150    * Rewind the current bit position by the given number of bits.
151    */
152   bool RewindBitPosition(UInt_t const & bitCount);
153  
154   /** function pad 8 bits */
155   void Pad8Bits();
156
157   /** function to determine input bytes
158    * @param data       AliHLTUInt8_t* pointer to input data
159    * @param byteCount  UInt_t const &
160    * @return boolean
161    */
162   bool InputBytes( AliHLTUInt8_t* data, UInt_t const & byteCount );
163
164   /**
165    * Read the next value.
166    * Data read function for inflaters for different formats
167    */
168   virtual bool NextValue(AliHLTUInt64_t& /*value*/, AliHLTUInt32_t& /*length*/) {return false;}
169   /// switch to next parameter
170   virtual int NextParameter() {return -ENOSYS;}
171
172   /// clear the object and reset pointer references
173   virtual void Clear(Option_t * /*option*/ ="");
174
175   /// print info
176   virtual void Print(Option_t *option="") const;
177
178   /// print info
179   virtual void Print(ostream& out, Option_t *option="") const;
180
181 protected:
182 private:
183   /** copy constructor prohibited */
184   AliHLTDataInflater(const AliHLTDataInflater&);
185   /** assignment operator prohibited */
186   AliHLTDataInflater& operator=(const AliHLTDataInflater&);
187
188   /** member variable for bit data current word */
189   AliHLTUInt8_t fBitDataCurrentWord; // member variable for bit data current word
190   /** member variable for bit data current position in word */
191   UInt_t fBitDataCurrentPosInWord;// member variable for bit data current position in word
192   /** member variable for bit data current input */
193   const AliHLTUInt8_t *fBitDataCurrentInput; // member variable for bit data current input
194   /** member variable for bit data current input start */
195   const AliHLTUInt8_t *fBitDataCurrentInputStart; // member variable for bit data current input star
196   /** member variable for bit data current input end */
197   const AliHLTUInt8_t *fBitDataCurrentInputEnd; // member variable for bit data current input end
198
199   ClassDef(AliHLTDataInflater, 0)
200 };
201
202 template<typename T>
203 bool AliHLTDataInflater::InputBits( T & value, UInt_t const & bitCount )
204 {
205   // read bits from the input stream into variable
206   if (bitCount>sizeof(T)*8) {
207     HLTFatal( "variable of type size %u too small to read %u bits", sizeof(T)*8, (unsigned)bitCount);
208     return false;
209   }
210   UInt_t bitsToRead=bitCount;
211   UInt_t curBitCount;
212   value = 0;
213   while ( bitsToRead>0 ) {
214     if ( fBitDataCurrentInput>=fBitDataCurrentInputEnd )
215       return false;
216     if ( bitsToRead >= fBitDataCurrentPosInWord+1 )
217       curBitCount = fBitDataCurrentPosInWord+1;
218     else
219       curBitCount = bitsToRead;
220     value = (value << curBitCount) | ( (fBitDataCurrentWord >> (fBitDataCurrentPosInWord-curBitCount+1)) & ((1 << curBitCount)-1) );
221     if ( fBitDataCurrentPosInWord < curBitCount ) {
222       fBitDataCurrentInput++;
223       fBitDataCurrentPosInWord = 7;
224       if ( fBitDataCurrentInput<fBitDataCurrentInputEnd ) {
225         fBitDataCurrentWord = *fBitDataCurrentInput;
226       }
227     }
228     else
229       fBitDataCurrentPosInWord -= curBitCount;
230     bitsToRead -= curBitCount;
231   }
232   return true;
233 }
234
235 ostream& operator<<(ostream &out, const AliHLTDataInflater& me);
236
237 #endif