3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /// @file AliHLTDataInflaterHuffman.cxx
20 /// @author Matthias Richter
22 /// @brief Data inflater implementation for huffman encoded data
25 #include "AliHLTDataInflaterHuffman.h"
26 #include "AliHLTHuffman.h"
29 /** ROOT macro for the implementation of ROOT specific class methods */
30 ClassImp(AliHLTDataInflaterHuffman)
32 AliHLTDataInflaterHuffman::AliHLTDataInflaterHuffman()
33 : AliHLTDataInflater()
35 , fHuffmanCoderList(NULL)
36 , fCurrentParameter(-1)
39 // see header file for class documentation
41 // refer to README to build package
43 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
46 AliHLTDataInflaterHuffman::~AliHLTDataInflaterHuffman()
49 if (fHuffmanCoderList) delete fHuffmanCoderList;
50 fHuffmanCoderList=NULL;
53 int AliHLTDataInflaterHuffman::AddParameterDefinition(const char* name, unsigned bitLength)
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);
63 HLTError("can not find decoder of id '%s'", name);
66 AliHLTHuffman* pHuffman=dynamic_cast<AliHLTHuffman*>(pObj);
68 HLTError("object %s has wrong type, expected AliHLTHuffman", name);
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);
76 fHuffmanCoders.push_back(pHuffman);
77 return fHuffmanCoders.size()-1;
80 int AliHLTDataInflaterHuffman::InitDecoders(TList* decoderlist)
82 /// init list of decoders
83 /// expects to be an external pointer, valid throughout the livetime of
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;
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");
95 if (!fHuffmanCoderList) return -ENOMEM;
96 fHuffmanCoderList->SetOwner(kFALSE);
97 TIter next(decoderlist);
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());
105 fHuffmanCoderList->Add(pObj);
108 return fHuffmanCoderList->GetEntries();
111 bool AliHLTDataInflaterHuffman::NextValue(AliHLTUInt64_t& value, AliHLTUInt32_t& length)
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
118 AliHLTUInt64_t input=0;
119 AliHLTUInt32_t inputLength=64;
120 if (GetRemainingBitDataSizeBytes()<=sizeof(AliHLTUInt64_t)) {
121 inputLength=8*GetRemainingBitDataSizeBytes();
122 inputLength-=(7-GetCurrentBitInputPosition());
124 if (!InputBits(input, inputLength)) return false;
125 if (fLegacyMode!=0) {
126 if ((++fCurrentParameter)>=(int)fHuffmanCoders.size()) fCurrentParameter=0;
129 if (fHuffmanCoders.size()==0 || fCurrentParameter<0) return false;
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
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);
144 inputLength-=codeLength;
145 RewindBitPosition(inputLength);
150 void AliHLTDataInflaterHuffman::Clear(Option_t * option)
153 fCurrentParameter=-1;
155 if (strcmp(option, "all")==0) {
156 fHuffmanCoders.clear();
157 if (fHuffmanCoderList) delete fHuffmanCoderList;
158 fHuffmanCoderList=NULL;
161 AliHLTDataInflater::Clear(option);