bugfix: correct range of DDL for specified detector
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataInflaterHuffman.cxx
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)
37   , fLegacyMode(-1)
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
49   if (fHuffmanCoderList) delete fHuffmanCoderList;
50   fHuffmanCoderList=NULL;
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;
125   if (fLegacyMode!=0) {
126   if ((++fCurrentParameter)>=(int)fHuffmanCoders.size()) fCurrentParameter=0;
127   fLegacyMode=1;
128   }
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
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 }
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 }