Line data Source code
1 : //**************************************************************************
2 : //* This file is property of and copyright by the ALICE HLT Project *
3 : //* ALICE Experiment at CERN, All rights reserved. *
4 : //* *
5 : //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
6 : //* for The ALICE HLT Project. *
7 : //* *
8 : //* Permission to use, copy, modify and distribute this software and its *
9 : //* documentation strictly for non-commercial purposes is hereby granted *
10 : //* without fee, provided that the above copyright notice appears in all *
11 : //* copies and that both the copyright notice and this permission notice *
12 : //* appear in the supporting documentation. The authors make no claims *
13 : //* about the suitability of this software for any purpose. It is *
14 : //* provided "as is" without express or implied warranty. *
15 : //**************************************************************************
16 :
17 : /// @file AliHLTDataInflaterHuffman.cxx
18 : /// @author Matthias Richter
19 : /// @date 2011-09-01
20 : /// @brief Data inflater implementation for huffman encoded data
21 : /// @note
22 :
23 : #include "AliHLTDataInflaterHuffman.h"
24 : #include "AliHLTHuffman.h"
25 : #include "TList.h"
26 :
27 : /** ROOT macro for the implementation of ROOT specific class methods */
28 126 : ClassImp(AliHLTDataInflaterHuffman)
29 :
30 : AliHLTDataInflaterHuffman::AliHLTDataInflaterHuffman()
31 0 : : AliHLTDataInflater()
32 0 : , fHuffmanCoders()
33 0 : , fHuffmanCoderList(NULL)
34 0 : , fCurrentParameter(-1)
35 0 : , fLegacyMode(-1)
36 0 : , fInput(0)
37 0 : , fInputLength(0)
38 0 : {
39 : // constructor, see header file for class documentation
40 0 : }
41 :
42 : AliHLTDataInflaterHuffman::~AliHLTDataInflaterHuffman()
43 0 : {
44 : // destructor
45 0 : if (fHuffmanCoderList) delete fHuffmanCoderList;
46 0 : fHuffmanCoderList=NULL;
47 0 : }
48 :
49 : int AliHLTDataInflaterHuffman::AddParameterDefinition(const char* name, unsigned bitLength)
50 : {
51 : /// search a parameter definition in the decoder configuration, and set the index
52 : /// array, return reference id
53 : /// TODO: this code is a copy of AliHLTDataDeflaterHuffman::AddParameterDefinition
54 : /// make a common base class
55 0 : if (!name) return -EINVAL;
56 0 : if (!fHuffmanCoderList) return -ENODEV;
57 0 : TObject* pObj=fHuffmanCoderList->FindObject(name);
58 0 : if (!pObj) {
59 0 : HLTError("can not find decoder of id '%s'", name);
60 0 : return -ENOENT;
61 : }
62 0 : AliHLTHuffman* pHuffman=dynamic_cast<AliHLTHuffman*>(pObj);
63 0 : if (!pHuffman) {
64 0 : HLTError("object %s has wrong type, expected AliHLTHuffman", name);
65 0 : return -EBADF;
66 : }
67 0 : if (pHuffman->GetMaxBits()!=bitLength) {
68 0 : HLTError("mismatch in bitlengt: can not use decoder %s of length %d for encoding of %d bits", pHuffman->GetName(), pHuffman->GetMaxBits(), bitLength);
69 0 : return -EPERM;
70 : }
71 :
72 0 : fHuffmanCoders.push_back(pHuffman);
73 0 : return fHuffmanCoders.size()-1;
74 0 : }
75 :
76 : int AliHLTDataInflaterHuffman::InitDecoders(TList* decoderlist)
77 : {
78 : /// init list of decoders
79 : /// expects to be an external pointer, valid throughout the livetime of
80 : /// the instance
81 : /// TODO: this code is a copy of AliHLTDataDeflaterHuffman::InitDecoders
82 : /// make a common base class
83 0 : if (!decoderlist) return -EINVAL;
84 0 : if (!fHuffmanCoderList) {
85 0 : fHuffmanCoderList=new TList;
86 0 : } else {
87 0 : if (fHuffmanCoderList->GetEntries()>0 && fHuffmanCoderList->IsOwner()) {
88 0 : HLTWarning("list of decoders owns already %d object(s), but disabling ownership now because of new external pointers");
89 : }
90 : }
91 0 : if (!fHuffmanCoderList) return -ENOMEM;
92 0 : fHuffmanCoderList->SetOwner(kFALSE);
93 0 : TIter next(decoderlist);
94 : TObject* pObj=NULL;
95 0 : while ((pObj=next())!=NULL) {
96 : AliHLTHuffman* coder=NULL;
97 0 : if ((coder=dynamic_cast<AliHLTHuffman*>(pObj))==NULL) continue;
98 0 : if (fHuffmanCoderList->FindObject(pObj->GetName())) {
99 0 : HLTError("duplicate entry of name '%s'", pObj->GetName());
100 0 : return -EEXIST;
101 : }
102 0 : fHuffmanCoderList->Add(pObj);
103 0 : coder->InitMaxCodeLength();
104 0 : }
105 :
106 0 : return fHuffmanCoderList->GetEntries();
107 0 : }
108 :
109 : bool AliHLTDataInflaterHuffman::NextValue(AliHLTUInt64_t& value, AliHLTUInt32_t& length)
110 : {
111 : /// overloaded from AliHLTDataInflater
112 : /// functions reads the sequence of parameters as defined by the decoder
113 : /// list, than it starts at the first parameter again
114 0 : value=0;
115 0 : length=0;
116 0 : if (fLegacyMode!=0) {
117 0 : if ((++fCurrentParameter)>=(int)fHuffmanCoders.size()) fCurrentParameter=0;
118 0 : fLegacyMode=1;
119 0 : }
120 0 : if (fHuffmanCoders.size()==0 || fCurrentParameter<0) return false;
121 0 : if (fInputLength<fHuffmanCoders[fCurrentParameter]->GetMaxCodeLength() ||
122 0 : fHuffmanCoders[fCurrentParameter]->GetMaxCodeLength()==0)
123 : {
124 0 : AliHLTUInt64_t input=0;
125 0 : AliHLTUInt32_t inputLength=64-fInputLength;
126 0 : if (GetRemainingBitDataSizeBytes()<=sizeof(AliHLTUInt64_t)) {
127 0 : inputLength=8*GetRemainingBitDataSizeBytes();
128 0 : inputLength-=(7-GetCurrentBitInputPosition());
129 0 : }
130 0 : if (64-fInputLength<inputLength) inputLength=64-fInputLength;
131 0 : if (!GetBits(input, inputLength)) return false;
132 0 : input<<=(64-inputLength);
133 0 : input>>=fInputLength;
134 0 : fInput|=input;
135 0 : fInputLength+=inputLength;
136 0 : }
137 0 : AliHLTUInt32_t codeLength=0;
138 0 : if (!fHuffmanCoders[fCurrentParameter]->DecodeMSB(fInput, value, length, codeLength)) return false;
139 : HLTDebug(" code 0x%08x length %d value %d", fInput>>(64-codeLength), codeLength, value);
140 0 : if (fInputLength<codeLength) {
141 0 : HLTError("huffman decoder '%s' pretends to have %d bit(s) decoded, but only %d available",
142 : fHuffmanCoders[fCurrentParameter]->GetName(), codeLength, fInputLength);
143 0 : return false;
144 : }
145 0 : fInput<<=codeLength;
146 0 : fInputLength-=codeLength;
147 :
148 0 : return true;
149 0 : }
150 :
151 : bool AliHLTDataInflaterHuffman::InputBit( AliHLTUInt8_t & value )
152 : {
153 : /// special overload of InputBit method to consider the
154 : /// internal register
155 0 : if (fInputLength > 0) {
156 : const int shiftval=sizeof(fInput)*8 - 1;
157 0 : value = (fInput>>shiftval) & 0x1;
158 0 : fInput<<=1;
159 0 : fInputLength-=1;
160 : HLTDebug(" code 0x%08x length 1", value);
161 : return true;
162 : }
163 :
164 0 : return AliHLTDataInflater::InputBit(value);
165 0 : }
166 :
167 : void AliHLTDataInflaterHuffman::Pad8Bits()
168 : {
169 : /// special overload of Pad8Bits method to clear the
170 : /// internal register and rewind the read pointer
171 0 : RewindCache();
172 0 : AliHLTDataInflater::Pad8Bits();
173 0 : }
174 :
175 : void AliHLTDataInflaterHuffman::RewindCache()
176 : {
177 0 : RewindBitPosition(fInputLength);
178 0 : fInputLength = 0;
179 0 : fInput = 0;
180 0 : }
181 :
182 : void AliHLTDataInflaterHuffman::Print(Option_t* option) const
183 : {
184 : /// Print info
185 0 : for (vector<AliHLTHuffman*>::const_iterator coder=fHuffmanCoders.begin();
186 0 : coder!=fHuffmanCoders.end(); coder++) {
187 0 : if (!*coder) continue;
188 0 : (*coder)->Print(option);
189 0 : }
190 0 : }
191 :
192 : void AliHLTDataInflaterHuffman::Clear(Option_t * option)
193 : {
194 : /// clear the object
195 0 : fCurrentParameter=-1;
196 0 : fInput=0;
197 0 : fInputLength=0;
198 :
199 0 : if (strcmp(option, "all")==0) {
200 0 : fHuffmanCoders.clear();
201 0 : if (fHuffmanCoderList) delete fHuffmanCoderList;
202 0 : fHuffmanCoderList=NULL;
203 0 : }
204 :
205 0 : AliHLTDataInflater::Clear(option);
206 0 : }
|