ROOT logo
// $Id$

//**************************************************************************
//* This file is property of and copyright by the ALICE HLT Project        * 
//* ALICE Experiment at CERN, All rights reserved.                         *
//*                                                                        *
//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
//*                  for The ALICE HLT Project.                            *
//*                                                                        *
//* Permission to use, copy, modify and distribute this software and its   *
//* documentation strictly for non-commercial purposes is hereby granted   *
//* without fee, provided that the above copyright notice appears in all   *
//* copies and that both the copyright notice and this permission notice   *
//* appear in the supporting documentation. The authors make no claims     *
//* about the suitability of this software for any purpose. It is          *
//* provided "as is" without express or implied warranty.                  *
//**************************************************************************

/// @file   AliHLTDataInflaterHuffman.cxx
/// @author Matthias Richter
/// @date   2011-09-01
/// @brief  Data inflater implementation for huffman encoded data
/// @note   

#include "AliHLTDataInflaterHuffman.h"
#include "AliHLTHuffman.h"
#include "TList.h"

/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTDataInflaterHuffman)

AliHLTDataInflaterHuffman::AliHLTDataInflaterHuffman()
  : AliHLTDataInflater()
  , fHuffmanCoders()
  , fHuffmanCoderList(NULL)
  , fCurrentParameter(-1)
  , fLegacyMode(-1)
  , fInput(0)
  , fInputLength(0)
{
  // see header file for class documentation
  // or
  // refer to README to build package
  // or
  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
}

AliHLTDataInflaterHuffman::~AliHLTDataInflaterHuffman()
{
  // destructor
  if (fHuffmanCoderList) delete fHuffmanCoderList;
  fHuffmanCoderList=NULL;
}

int AliHLTDataInflaterHuffman::AddParameterDefinition(const char* name, unsigned bitLength)
{
  /// search a parameter definition in the decoder configuration, and set the index
  /// array, return reference id
  /// TODO: this code is a copy of AliHLTDataDeflaterHuffman::AddParameterDefinition
  /// make a common base class
  if (!name) return -EINVAL;
  if (!fHuffmanCoderList) return -ENODEV;
  TObject* pObj=fHuffmanCoderList->FindObject(name);
  if (!pObj) {
    HLTError("can not find decoder of id '%s'", name);
    return -ENOENT;
  }
  AliHLTHuffman* pHuffman=dynamic_cast<AliHLTHuffman*>(pObj);
  if (!pHuffman) {
    HLTError("object %s has wrong type, expected AliHLTHuffman", name);
    return -EBADF;
  }
  if (pHuffman->GetMaxBits()!=bitLength) {
    HLTError("mismatch in bitlengt: can not use decoder %s of length %d for encoding of %d bits", pHuffman->GetName(), pHuffman->GetMaxBits(), bitLength);
    return -EPERM;
  }

  fHuffmanCoders.push_back(pHuffman);
  return fHuffmanCoders.size()-1;
}

int AliHLTDataInflaterHuffman::InitDecoders(TList* decoderlist)
{
  /// init list of decoders
  /// expects to be an external pointer, valid throughout the livetime of
  /// the instance
  /// TODO: this code is a copy of AliHLTDataDeflaterHuffman::InitDecoders
  /// make a common base class
  if (!decoderlist) return -EINVAL;
  if (!fHuffmanCoderList) {
    fHuffmanCoderList=new TList;
  } else {
    if (fHuffmanCoderList->GetEntries()>0 && fHuffmanCoderList->IsOwner()) {
      HLTWarning("list of decoders owns already %d object(s), but disabling ownership now because of new external pointers");
    }
  }
  if (!fHuffmanCoderList) return -ENOMEM;
  fHuffmanCoderList->SetOwner(kFALSE);
  TIter next(decoderlist);
  TObject* pObj=NULL;
  while ((pObj=next())!=NULL) {
    AliHLTHuffman* coder=NULL;
    if ((coder=dynamic_cast<AliHLTHuffman*>(pObj))==NULL) continue;
    if (fHuffmanCoderList->FindObject(pObj->GetName())) {
      HLTError("duplicate entry of name '%s'", pObj->GetName());
      return -EEXIST;
    }
    fHuffmanCoderList->Add(pObj);
    coder->InitMaxCodeLength();
  }

  return fHuffmanCoderList->GetEntries();
}

bool AliHLTDataInflaterHuffman::NextValue(AliHLTUInt64_t& value, AliHLTUInt32_t& length)
{
  /// overloaded from AliHLTDataInflater
  /// functions reads the sequence of parameters as defined by the decoder
  /// list, than it starts at the first parameter again
  value=0;
  length=0;
  if (fLegacyMode!=0) {
  if ((++fCurrentParameter)>=(int)fHuffmanCoders.size()) fCurrentParameter=0;
  fLegacyMode=1;
  }
  if (fHuffmanCoders.size()==0 || fCurrentParameter<0) return false;
  if (fInputLength<fHuffmanCoders[fCurrentParameter]->GetMaxCodeLength() ||
      fHuffmanCoders[fCurrentParameter]->GetMaxCodeLength()==0)
  {
    AliHLTUInt64_t input=0;
    AliHLTUInt32_t inputLength=64-fInputLength;
    if (GetRemainingBitDataSizeBytes()<=sizeof(AliHLTUInt64_t)) {
      inputLength=8*GetRemainingBitDataSizeBytes();
      inputLength-=(7-GetCurrentBitInputPosition());
    }
    if (64-fInputLength<inputLength) inputLength=64-fInputLength;
    if (!InputBits(input, inputLength)) return false;
    input<<=(64-inputLength);
    input>>=fInputLength;
    fInput|=input;
    fInputLength+=inputLength;
  }
  AliHLTUInt32_t codeLength=0;
  if (!fHuffmanCoders[fCurrentParameter]->DecodeMSB(fInput, value, length, codeLength)) return false;
  if (fInputLength<codeLength) {
    HLTError("huffman decoder '%s' pretends to have %d bit(s) decoded, but only %d available",
	     fHuffmanCoders[fCurrentParameter]->GetName(), codeLength, fInputLength);
    return false;
  }
  fInput<<=codeLength;
  fInputLength-=codeLength;

  return true;
}

void AliHLTDataInflaterHuffman::Print(Option_t* option) const
{
  /// Print info
  for (vector<AliHLTHuffman*>::const_iterator coder=fHuffmanCoders.begin();
       coder!=fHuffmanCoders.end(); coder++) {
    if (!*coder) continue;
    (*coder)->Print(option);
  }
}

void AliHLTDataInflaterHuffman::Clear(Option_t * option)
{
  /// clear the object
  fCurrentParameter=-1;
  fInput=0;
  fInputLength=0;

  if (strcmp(option, "all")==0) {
    fHuffmanCoders.clear();
    if (fHuffmanCoderList) delete fHuffmanCoderList;
    fHuffmanCoderList=NULL;
  }

  AliHLTDataInflater::Clear(option);
}
 AliHLTDataInflaterHuffman.cxx:1
 AliHLTDataInflaterHuffman.cxx:2
 AliHLTDataInflaterHuffman.cxx:3
 AliHLTDataInflaterHuffman.cxx:4
 AliHLTDataInflaterHuffman.cxx:5
 AliHLTDataInflaterHuffman.cxx:6
 AliHLTDataInflaterHuffman.cxx:7
 AliHLTDataInflaterHuffman.cxx:8
 AliHLTDataInflaterHuffman.cxx:9
 AliHLTDataInflaterHuffman.cxx:10
 AliHLTDataInflaterHuffman.cxx:11
 AliHLTDataInflaterHuffman.cxx:12
 AliHLTDataInflaterHuffman.cxx:13
 AliHLTDataInflaterHuffman.cxx:14
 AliHLTDataInflaterHuffman.cxx:15
 AliHLTDataInflaterHuffman.cxx:16
 AliHLTDataInflaterHuffman.cxx:17
 AliHLTDataInflaterHuffman.cxx:18
 AliHLTDataInflaterHuffman.cxx:19
 AliHLTDataInflaterHuffman.cxx:20
 AliHLTDataInflaterHuffman.cxx:21
 AliHLTDataInflaterHuffman.cxx:22
 AliHLTDataInflaterHuffman.cxx:23
 AliHLTDataInflaterHuffman.cxx:24
 AliHLTDataInflaterHuffman.cxx:25
 AliHLTDataInflaterHuffman.cxx:26
 AliHLTDataInflaterHuffman.cxx:27
 AliHLTDataInflaterHuffman.cxx:28
 AliHLTDataInflaterHuffman.cxx:29
 AliHLTDataInflaterHuffman.cxx:30
 AliHLTDataInflaterHuffman.cxx:31
 AliHLTDataInflaterHuffman.cxx:32
 AliHLTDataInflaterHuffman.cxx:33
 AliHLTDataInflaterHuffman.cxx:34
 AliHLTDataInflaterHuffman.cxx:35
 AliHLTDataInflaterHuffman.cxx:36
 AliHLTDataInflaterHuffman.cxx:37
 AliHLTDataInflaterHuffman.cxx:38
 AliHLTDataInflaterHuffman.cxx:39
 AliHLTDataInflaterHuffman.cxx:40
 AliHLTDataInflaterHuffman.cxx:41
 AliHLTDataInflaterHuffman.cxx:42
 AliHLTDataInflaterHuffman.cxx:43
 AliHLTDataInflaterHuffman.cxx:44
 AliHLTDataInflaterHuffman.cxx:45
 AliHLTDataInflaterHuffman.cxx:46
 AliHLTDataInflaterHuffman.cxx:47
 AliHLTDataInflaterHuffman.cxx:48
 AliHLTDataInflaterHuffman.cxx:49
 AliHLTDataInflaterHuffman.cxx:50
 AliHLTDataInflaterHuffman.cxx:51
 AliHLTDataInflaterHuffman.cxx:52
 AliHLTDataInflaterHuffman.cxx:53
 AliHLTDataInflaterHuffman.cxx:54
 AliHLTDataInflaterHuffman.cxx:55
 AliHLTDataInflaterHuffman.cxx:56
 AliHLTDataInflaterHuffman.cxx:57
 AliHLTDataInflaterHuffman.cxx:58
 AliHLTDataInflaterHuffman.cxx:59
 AliHLTDataInflaterHuffman.cxx:60
 AliHLTDataInflaterHuffman.cxx:61
 AliHLTDataInflaterHuffman.cxx:62
 AliHLTDataInflaterHuffman.cxx:63
 AliHLTDataInflaterHuffman.cxx:64
 AliHLTDataInflaterHuffman.cxx:65
 AliHLTDataInflaterHuffman.cxx:66
 AliHLTDataInflaterHuffman.cxx:67
 AliHLTDataInflaterHuffman.cxx:68
 AliHLTDataInflaterHuffman.cxx:69
 AliHLTDataInflaterHuffman.cxx:70
 AliHLTDataInflaterHuffman.cxx:71
 AliHLTDataInflaterHuffman.cxx:72
 AliHLTDataInflaterHuffman.cxx:73
 AliHLTDataInflaterHuffman.cxx:74
 AliHLTDataInflaterHuffman.cxx:75
 AliHLTDataInflaterHuffman.cxx:76
 AliHLTDataInflaterHuffman.cxx:77
 AliHLTDataInflaterHuffman.cxx:78
 AliHLTDataInflaterHuffman.cxx:79
 AliHLTDataInflaterHuffman.cxx:80
 AliHLTDataInflaterHuffman.cxx:81
 AliHLTDataInflaterHuffman.cxx:82
 AliHLTDataInflaterHuffman.cxx:83
 AliHLTDataInflaterHuffman.cxx:84
 AliHLTDataInflaterHuffman.cxx:85
 AliHLTDataInflaterHuffman.cxx:86
 AliHLTDataInflaterHuffman.cxx:87
 AliHLTDataInflaterHuffman.cxx:88
 AliHLTDataInflaterHuffman.cxx:89
 AliHLTDataInflaterHuffman.cxx:90
 AliHLTDataInflaterHuffman.cxx:91
 AliHLTDataInflaterHuffman.cxx:92
 AliHLTDataInflaterHuffman.cxx:93
 AliHLTDataInflaterHuffman.cxx:94
 AliHLTDataInflaterHuffman.cxx:95
 AliHLTDataInflaterHuffman.cxx:96
 AliHLTDataInflaterHuffman.cxx:97
 AliHLTDataInflaterHuffman.cxx:98
 AliHLTDataInflaterHuffman.cxx:99
 AliHLTDataInflaterHuffman.cxx:100
 AliHLTDataInflaterHuffman.cxx:101
 AliHLTDataInflaterHuffman.cxx:102
 AliHLTDataInflaterHuffman.cxx:103
 AliHLTDataInflaterHuffman.cxx:104
 AliHLTDataInflaterHuffman.cxx:105
 AliHLTDataInflaterHuffman.cxx:106
 AliHLTDataInflaterHuffman.cxx:107
 AliHLTDataInflaterHuffman.cxx:108
 AliHLTDataInflaterHuffman.cxx:109
 AliHLTDataInflaterHuffman.cxx:110
 AliHLTDataInflaterHuffman.cxx:111
 AliHLTDataInflaterHuffman.cxx:112
 AliHLTDataInflaterHuffman.cxx:113
 AliHLTDataInflaterHuffman.cxx:114
 AliHLTDataInflaterHuffman.cxx:115
 AliHLTDataInflaterHuffman.cxx:116
 AliHLTDataInflaterHuffman.cxx:117
 AliHLTDataInflaterHuffman.cxx:118
 AliHLTDataInflaterHuffman.cxx:119
 AliHLTDataInflaterHuffman.cxx:120
 AliHLTDataInflaterHuffman.cxx:121
 AliHLTDataInflaterHuffman.cxx:122
 AliHLTDataInflaterHuffman.cxx:123
 AliHLTDataInflaterHuffman.cxx:124
 AliHLTDataInflaterHuffman.cxx:125
 AliHLTDataInflaterHuffman.cxx:126
 AliHLTDataInflaterHuffman.cxx:127
 AliHLTDataInflaterHuffman.cxx:128
 AliHLTDataInflaterHuffman.cxx:129
 AliHLTDataInflaterHuffman.cxx:130
 AliHLTDataInflaterHuffman.cxx:131
 AliHLTDataInflaterHuffman.cxx:132
 AliHLTDataInflaterHuffman.cxx:133
 AliHLTDataInflaterHuffman.cxx:134
 AliHLTDataInflaterHuffman.cxx:135
 AliHLTDataInflaterHuffman.cxx:136
 AliHLTDataInflaterHuffman.cxx:137
 AliHLTDataInflaterHuffman.cxx:138
 AliHLTDataInflaterHuffman.cxx:139
 AliHLTDataInflaterHuffman.cxx:140
 AliHLTDataInflaterHuffman.cxx:141
 AliHLTDataInflaterHuffman.cxx:142
 AliHLTDataInflaterHuffman.cxx:143
 AliHLTDataInflaterHuffman.cxx:144
 AliHLTDataInflaterHuffman.cxx:145
 AliHLTDataInflaterHuffman.cxx:146
 AliHLTDataInflaterHuffman.cxx:147
 AliHLTDataInflaterHuffman.cxx:148
 AliHLTDataInflaterHuffman.cxx:149
 AliHLTDataInflaterHuffman.cxx:150
 AliHLTDataInflaterHuffman.cxx:151
 AliHLTDataInflaterHuffman.cxx:152
 AliHLTDataInflaterHuffman.cxx:153
 AliHLTDataInflaterHuffman.cxx:154
 AliHLTDataInflaterHuffman.cxx:155
 AliHLTDataInflaterHuffman.cxx:156
 AliHLTDataInflaterHuffman.cxx:157
 AliHLTDataInflaterHuffman.cxx:158
 AliHLTDataInflaterHuffman.cxx:159
 AliHLTDataInflaterHuffman.cxx:160
 AliHLTDataInflaterHuffman.cxx:161
 AliHLTDataInflaterHuffman.cxx:162
 AliHLTDataInflaterHuffman.cxx:163
 AliHLTDataInflaterHuffman.cxx:164
 AliHLTDataInflaterHuffman.cxx:165
 AliHLTDataInflaterHuffman.cxx:166
 AliHLTDataInflaterHuffman.cxx:167
 AliHLTDataInflaterHuffman.cxx:168
 AliHLTDataInflaterHuffman.cxx:169
 AliHLTDataInflaterHuffman.cxx:170
 AliHLTDataInflaterHuffman.cxx:171
 AliHLTDataInflaterHuffman.cxx:172
 AliHLTDataInflaterHuffman.cxx:173
 AliHLTDataInflaterHuffman.cxx:174
 AliHLTDataInflaterHuffman.cxx:175
 AliHLTDataInflaterHuffman.cxx:176
 AliHLTDataInflaterHuffman.cxx:177
 AliHLTDataInflaterHuffman.cxx:178
 AliHLTDataInflaterHuffman.cxx:179
 AliHLTDataInflaterHuffman.cxx:180