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