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