]>
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) |
9409b4b1 | 38 | { |
39 | // see header file for class documentation | |
40 | // or | |
41 | // refer to README to build package | |
42 | // or | |
43 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
44 | } | |
45 | ||
46 | AliHLTDataInflaterHuffman::~AliHLTDataInflaterHuffman() | |
47 | { | |
48 | // destructor | |
7d2d4632 | 49 | if (fHuffmanCoderList) delete fHuffmanCoderList; |
50 | fHuffmanCoderList=NULL; | |
9409b4b1 | 51 | } |
52 | ||
53 | int AliHLTDataInflaterHuffman::AddParameterDefinition(const char* name, unsigned bitLength) | |
54 | { | |
55 | /// search a parameter definition in the decoder configuration, and set the index | |
56 | /// array, return reference id | |
57 | /// TODO: this code is a copy of AliHLTDataDeflaterHuffman::AddParameterDefinition | |
58 | /// make a common base class | |
59 | if (!name) return -EINVAL; | |
60 | if (!fHuffmanCoderList) return -ENODEV; | |
61 | TObject* pObj=fHuffmanCoderList->FindObject(name); | |
62 | if (!pObj) { | |
63 | HLTError("can not find decoder of id '%s'", name); | |
64 | return -ENOENT; | |
65 | } | |
66 | AliHLTHuffman* pHuffman=dynamic_cast<AliHLTHuffman*>(pObj); | |
67 | if (!pHuffman) { | |
68 | HLTError("object %s has wrong type, expected AliHLTHuffman", name); | |
69 | return -EBADF; | |
70 | } | |
71 | if (pHuffman->GetMaxBits()!=bitLength) { | |
72 | HLTError("mismatch in bitlengt: can not use decoder %s of length %d for encoding of %d bits", pHuffman->GetName(), pHuffman->GetMaxBits(), bitLength); | |
73 | return -EPERM; | |
74 | } | |
75 | ||
76 | fHuffmanCoders.push_back(pHuffman); | |
77 | return fHuffmanCoders.size()-1; | |
78 | } | |
79 | ||
80 | int AliHLTDataInflaterHuffman::InitDecoders(TList* decoderlist) | |
81 | { | |
82 | /// init list of decoders | |
83 | /// expects to be an external pointer, valid throughout the livetime of | |
84 | /// the instance | |
85 | /// TODO: this code is a copy of AliHLTDataDeflaterHuffman::InitDecoders | |
86 | /// make a common base class | |
87 | if (!decoderlist) return -EINVAL; | |
88 | if (!fHuffmanCoderList) { | |
89 | fHuffmanCoderList=new TList; | |
90 | } else { | |
91 | if (fHuffmanCoderList->GetEntries()>0 && fHuffmanCoderList->IsOwner()) { | |
92 | HLTWarning("list of decoders owns already %d object(s), but disabling ownership now because of new external pointers"); | |
93 | } | |
94 | } | |
95 | if (!fHuffmanCoderList) return -ENOMEM; | |
96 | fHuffmanCoderList->SetOwner(kFALSE); | |
97 | TIter next(decoderlist); | |
98 | TObject* pObj=NULL; | |
99 | while ((pObj=next())!=NULL) { | |
100 | if (dynamic_cast<AliHLTHuffman*>(pObj)==NULL) continue; | |
101 | if (fHuffmanCoderList->FindObject(pObj->GetName())) { | |
102 | HLTError("duplicate entry of name '%s'", pObj->GetName()); | |
103 | return -EEXIST; | |
104 | } | |
105 | fHuffmanCoderList->Add(pObj); | |
106 | } | |
107 | ||
108 | return fHuffmanCoderList->GetEntries(); | |
109 | } | |
110 | ||
111 | bool AliHLTDataInflaterHuffman::NextValue(AliHLTUInt64_t& value, AliHLTUInt32_t& length) | |
112 | { | |
113 | /// overloaded from AliHLTDataInflater | |
114 | /// functions reads the sequence of parameters as defined by the decoder | |
115 | /// list, than it starts at the first parameter again | |
116 | value=0; | |
117 | length=0; | |
118 | AliHLTUInt64_t input=0; | |
119 | AliHLTUInt32_t inputLength=64; | |
120 | if (GetRemainingBitDataSizeBytes()<=sizeof(AliHLTUInt64_t)) { | |
121 | inputLength=8*GetRemainingBitDataSizeBytes(); | |
122 | inputLength-=(7-GetCurrentBitInputPosition()); | |
123 | } | |
124 | if (!InputBits(input, inputLength)) return false; | |
70d61ae2 | 125 | if (fLegacyMode!=0) { |
9409b4b1 | 126 | if ((++fCurrentParameter)>=(int)fHuffmanCoders.size()) fCurrentParameter=0; |
70d61ae2 | 127 | fLegacyMode=1; |
128 | } | |
129 | if (fHuffmanCoders.size()==0 || fCurrentParameter<0) return false; | |
9409b4b1 | 130 | // the huffman code is decoded from bit 0 corresponding to the top node and then to |
131 | // the left. The bitstream stores the reversed huffman code from MSB to LSB to ensure | |
132 | // a continous bit stream, that's why then input word needs to be reversed before | |
133 | // decoding. | |
134 | // TODO: introducing DecodeReverse into AliHLTHuffman can speed up the reading | |
135 | std::bitset<64> bits; | |
136 | for (unsigned bit=0; bit<inputLength; bit++) {bits[inputLength-1-bit]=input&0x1;input>>=1;} | |
137 | AliHLTUInt32_t codeLength=0; | |
138 | if (!fHuffmanCoders[fCurrentParameter]->Decode(bits, value, length, codeLength)) return false; | |
139 | if (inputLength<codeLength) { | |
140 | HLTError("huffman decoder '%s' pretends to have %d bit(s) decoded, but only %d available", | |
141 | fHuffmanCoders[fCurrentParameter]->GetName(), codeLength, inputLength); | |
142 | return false; | |
143 | } | |
144 | inputLength-=codeLength; | |
145 | RewindBitPosition(inputLength); | |
146 | ||
147 | return true; | |
148 | } | |
7d2d4632 | 149 | |
150 | void AliHLTDataInflaterHuffman::Clear(Option_t * option) | |
151 | { | |
152 | /// clear the object | |
153 | fCurrentParameter=-1; | |
154 | ||
155 | if (strcmp(option, "all")==0) { | |
156 | fHuffmanCoders.clear(); | |
157 | if (fHuffmanCoderList) delete fHuffmanCoderList; | |
158 | fHuffmanCoderList=NULL; | |
159 | } | |
160 | ||
161 | AliHLTDataInflater::Clear(option); | |
162 | } |