]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/comp/AliHLTTPCCompModelDeflater.cxx
coverity reports 15781 15550 15089 13953 13952 13951 13950 11215 10013 10012 10011
[u/mrichter/AliRoot.git] / HLT / TPCLib / comp / AliHLTTPCCompModelDeflater.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: Timm Steinbeck <timm@kip.uni-heidelberg.de>           *
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   AliHLTTPCCompModelDeflater.cxx
20     @author Timm Steinbeck
21     @date   
22     @brief  A copy processing component for the HLT. */
23
24 #if __GNUC__ >= 3
25 using namespace std;
26 #endif
27
28 #include "AliHLTTPCCompModelDeflater.h"
29 #include "AliHLTTPCTransform.h"
30 #include "AliHLTTPCTrack.h"
31 #include "AliHLTTPCModelTrack.h"
32 #include "AliHLTTPCCompDataCompressorHelper.h"
33 #include "AliHLTDataTypes.h"
34 #include <cerrno>
35
36 AliHLTTPCCompModelDeflater::AliHLTTPCCompModelDeflater():
37     fWriteShape(true),
38     fBitDataCurrentWord(0),
39     fBitDataCurrentPosInWord(0),
40     fBitDataCurrentOutput(0),
41     fBitDataCurrentOutputStart(0),
42     fBitDataCurrentOutputEnd(0)
43     {
44       // see header file for class documentation
45     }
46
47 AliHLTTPCCompModelDeflater::~AliHLTTPCCompModelDeflater()
48     {
49       // see header file for class documentation
50     }
51
52 void AliHLTTPCCompModelDeflater::InitBitDataOutput( AliHLTUInt8_t* output, UInt_t outputSize )
53    {
54      // see header file for class documenation
55      fBitDataCurrentWord = 0;
56      fBitDataCurrentPosInWord = 7;
57      fBitDataCurrentOutput = fBitDataCurrentOutputStart = output;
58      fBitDataCurrentOutputEnd = output+outputSize;
59    }
60
61 AliHLTUInt8_t AliHLTTPCCompModelDeflater::GetCurrentOutputByte( Int_t offset ) const
62    {
63      // see header file for class documentation
64      if ( !offset )
65        return fBitDataCurrentWord;
66      else
67        return *(fBitDataCurrentOutput+offset);
68    }
69
70 bool AliHLTTPCCompModelDeflater::OutputBit( AliHLTUInt32_t const & value )
71    {
72      // see header file for class documentation
73      if ( fBitDataCurrentOutput>=fBitDataCurrentOutputEnd )
74        return false;
75      fBitDataCurrentWord |= (value & 1) << fBitDataCurrentPosInWord;
76      if ( fBitDataCurrentPosInWord )
77        fBitDataCurrentPosInWord--;
78      else
79        {
80          *fBitDataCurrentOutput = fBitDataCurrentWord;
81          fBitDataCurrentPosInWord = 7;
82          fBitDataCurrentOutput++;
83          fBitDataCurrentWord = 0;
84        }
85      return true;
86    }
87    
88 bool AliHLTTPCCompModelDeflater::OutputBits( AliHLTUInt64_t const & value, UInt_t const & bitCount )
89    {
90      // see header file for class documentation
91      if ( bitCount>64 )
92        {
93          HLTFatal( "Internal error: Attempt to write more than 64 bits (%u)", (unsigned)bitCount );
94          return false;
95        }
96      UInt_t bitsToWrite=bitCount;
97      UInt_t curBitCount;
98      while ( bitsToWrite>0 )
99        {
100          if ( fBitDataCurrentOutput>=fBitDataCurrentOutputEnd )
101            return false;
102 #if 1
103          if ( bitsToWrite >= fBitDataCurrentPosInWord+1 )
104            curBitCount = fBitDataCurrentPosInWord+1;
105          else
106            curBitCount = bitsToWrite;
107          fBitDataCurrentWord |= ( (value >> (bitsToWrite-curBitCount)) & ((1<<curBitCount)-1) ) << (fBitDataCurrentPosInWord+1-curBitCount);
108          if ( fBitDataCurrentPosInWord < curBitCount )
109            {
110              *fBitDataCurrentOutput = fBitDataCurrentWord;
111              fBitDataCurrentPosInWord = 7;
112              fBitDataCurrentOutput++;
113              fBitDataCurrentWord = 0;
114            }
115          else
116            fBitDataCurrentPosInWord -= curBitCount;
117          bitsToWrite -= curBitCount;
118          
119 #else
120          AliHLTUInt8_t curValue;
121          if ( bitsToWrite>=8 )
122            {
123              curBitCount=8;
124              curValue = (value >> bitsToWrite-8) & 0xFF;
125              bitsToWrite -= 8;
126            }
127          else
128            {
129              curBitCount=bitsToWrite;
130              curValue = value & ( (1<<bitsToWrite)-1 );
131              bitsToWrite = 0;
132            }
133          if ( fBitDataCurrentPosInWord+1>curBitCount )
134            {
135              fBitDataCurrentWord |= curValue << (fBitDataCurrentPosInWord-curBitCount+1);
136              fBitDataCurrentPosInWord -= curBitCount;
137            }
138             else if ( fBitDataCurrentPosInWord+1==curBitCount )
139               {
140                 fBitDataCurrentWord |= curValue;
141                 *fBitDataCurrentOutput = fBitDataCurrentWord;
142                 fBitDataCurrentPosInWord = 7;
143                 fBitDataCurrentOutput++;
144                 fBitDataCurrentWord = 0;
145               }
146             else
147               {
148                 const UInt_t first = fBitDataCurrentPosInWord+1; // Number of bits for first block
149                 const UInt_t second = curBitCount-first; // Number of bits for second block
150                 fBitDataCurrentWord |= ( curValue >> second ) & ((1<<first)-1);
151                 *fBitDataCurrentOutput = fBitDataCurrentWord;
152                 fBitDataCurrentOutput++;
153                 if ( fBitDataCurrentOutput>=fBitDataCurrentOutputEnd )
154                   return false;
155                 fBitDataCurrentWord = curValue & ((1<<second)-1) << (8-second);
156                 fBitDataCurrentPosInWord = 7-second;
157               }
158 #endif
159        }
160      return true;
161    }
162
163 void AliHLTTPCCompModelDeflater::Pad8Bits()
164    {
165      // see header file for class documenation
166      if ( fBitDataCurrentPosInWord==7 )
167        return;
168      *fBitDataCurrentOutput = fBitDataCurrentWord;
169      fBitDataCurrentPosInWord = 7;
170      fBitDataCurrentOutput++;
171      fBitDataCurrentWord = 0;
172    }
173
174 bool AliHLTTPCCompModelDeflater::OutputBytes( AliHLTUInt8_t const * data, UInt_t const & byteCount )
175    {
176      // see header file for class documenation
177      Pad8Bits();
178      if ( fBitDataCurrentOutput+byteCount>fBitDataCurrentOutputEnd )
179        return false;
180      memcpy( fBitDataCurrentOutput, data, byteCount );
181      fBitDataCurrentOutput += byteCount;
182      return true;
183    }
184
185 int AliHLTTPCCompModelDeflater::CompressTracks( AliHLTUInt8_t* inData, UInt_t const& inputSize, AliHLTUInt8_t* output, UInt_t& outputSize )
186     {
187       // see header file for class documentation
188       AliHLTUInt8_t* inputPtr = inData;
189       AliHLTUInt8_t* inputEndPtr = inData+inputSize;
190       
191       if ( inputPtr+sizeof(AliHLTUInt32_t)>inputEndPtr )
192         {
193           HLTError( "Cannot read input data version number" );
194           return EIO;
195         }
196       if ( *(AliHLTUInt32_t*)inputPtr != 0 )
197         {
198           HLTError( "Only input data format version 0 is supported. Found version: %u",
199                     (unsigned)*(AliHLTUInt32_t*)inputPtr );
200           return EINVAL;
201         }
202       inputPtr += sizeof(AliHLTUInt32_t);
203       
204       printf( "outuptSize: %lu\n", (unsigned long)outputSize );
205       
206       // FIXME: check return value of OutputBit(s) to make code more robust
207       InitBitDataOutput( output, outputSize );
208       HLTDebug( "Output: Position: %lu / %u (0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte() );
209       OutputBits( 0, 4 ); // Version information
210       HLTDebug( "Output: Position: %lu / %u (0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte() );
211       OutputBit( fWriteShape ? 1 : 0 ); // Data format flag
212       HLTDebug( "Output: Position: %lu / %u (0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte() );
213       Pad8Bits();
214       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
215       
216       AliHLTTPCClusterModel *cluster;
217       Int_t temp;
218       Int_t power;
219       
220       Int_t timeo,pado,chargeo,padshapeo,timeshapeo;
221       timeo=pado=chargeo=padshapeo=timeshapeo=0;
222       unsigned trackCnt=0;
223       while( inputPtr<inputEndPtr )
224         {
225           if ( !OutputBytes( inputPtr, sizeof(AliHLTTPCTrackModel) ) )
226             {
227               HLTError( "Not enough space to write compressed data. %lu already written",
228                         (unsigned long)GetBitDataOutputSizeBytes() );
229               printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
230               outputSize = GetBitDataOutputSizeBytes();
231               return ENOBUFS;
232             }
233           HLTDebug( "sizeof(AliHLTTPCTrackModel): %d", sizeof(AliHLTTPCTrackModel) );
234           HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
235           inputPtr += sizeof(AliHLTTPCTrackModel);
236           
237           Int_t origslice=-1,slice,clustercount=0;
238           for(Int_t i=0; i<AliHLTTPCTransform::GetNRows(); i++)
239             {
240               cluster = (AliHLTTPCClusterModel*)inputPtr;
241               inputPtr += sizeof(AliHLTTPCClusterModel);
242               
243               //Write empty flag:
244               if ( !OutputBit( cluster->fPresent ? 1 : 0 ) )
245                 {
246                   HLTError( "Not enough space to write compressed data. %lu already written",
247                             (unsigned long)GetBitDataOutputSizeBytes() );
248                   printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
249                   outputSize = GetBitDataOutputSizeBytes();
250                   return ENOBUFS;
251                 }
252               HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
253               if ( !cluster->fPresent )
254                 continue;
255             
256               if ( cluster->fSlice<0 || cluster->fSlice>35 )
257                 {
258                   HLTError( "Inconsistent slice number %u (track %u, cluster %d)", cluster->fSlice, trackCnt, i );
259                   printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
260                   return EINVAL;
261                 }
262               
263               //Write slice number of first point
264               if ( clustercount==0 )
265                 {
266                   origslice = cluster->fSlice;
267                   if ( !OutputBits( origslice,6 ) ) //Need 6 bits to encode slice number
268                     {
269                       HLTError( "Not enough space to write compressed data. %lu already written",
270                                 (unsigned long)GetBitDataOutputSizeBytes() );
271                       printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
272                       outputSize = GetBitDataOutputSizeBytes();
273                       return ENOBUFS;
274                     }
275                   HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
276                 }
277               else
278                 {
279                   slice = cluster->fSlice;
280                   if( slice == origslice )
281                     {
282                       if ( !OutputBit( 0 ) )  //No change of slice
283                         {
284                           HLTError( "Not enough space to write compressed data. %lu already written",
285                                     (unsigned long)GetBitDataOutputSizeBytes() );
286                           outputSize = GetBitDataOutputSizeBytes();
287                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
288                           return ENOBUFS;
289                         }
290                       HLTDebug( "No slice change (%d/%d)", (int)origslice, (int)slice );
291                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
292                     }
293                   else
294                     {
295                       if ( !OutputBit( 1 ) )
296                         {
297                           HLTError( "Not enough space to write compressed data. %lu already written",
298                                     (unsigned long)GetBitDataOutputSizeBytes() );
299                           outputSize = GetBitDataOutputSizeBytes();
300                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
301                           return ENOBUFS;
302                         }
303                       HLTDebug( "Slice change (%d/%d)", (int)origslice, (int)slice );
304                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
305                       if ( !OutputBits( slice, 6 ) )
306                         {
307                           HLTError( "Not enough space to write compressed data. %lu already written",
308                                     (unsigned long)GetBitDataOutputSizeBytes() );
309                           outputSize = GetBitDataOutputSizeBytes();
310                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
311                           return ENOBUFS;
312                         }
313                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
314                       origslice=slice;
315                     }
316                 }
317               
318               //Write time information:
319               temp = (Int_t)rint(cluster->fDTime);
320               if( temp<0 )
321                 {
322                 if ( !OutputBit( 0 ) )
323                   {
324                     HLTError( "Not enough space to write compressed data. %lu already written",
325                               (unsigned long)GetBitDataOutputSizeBytes() );
326                     outputSize = GetBitDataOutputSizeBytes();
327                     printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
328                     return ENOBUFS;
329                   }
330                 HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
331                 }
332               else
333                 {
334                   if ( !OutputBit( 1 ) )
335                     {
336                       HLTError( "Not enough space to write compressed data. %lu already written",
337                                 (unsigned long)GetBitDataOutputSizeBytes() );
338                       printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
339                       outputSize = GetBitDataOutputSizeBytes();
340                       return ENOBUFS;
341                     }
342                   HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
343                 }
344               power = 1<<(AliHLTTPCCompDataCompressorHelper::GetNTimeBits()-1);
345               if ( abs(temp)>=power )
346                 {
347                   //cout<<abs(temp)<<" "<<power<<endl;
348                   timeo++;
349                   temp=power - 1;
350                 }
351               temp = abs(temp);
352               if ( !OutputBits(temp,(AliHLTTPCCompDataCompressorHelper::GetNTimeBits()-1)) )
353                 {
354                   HLTError( "Not enough space to write compressed data. %lu already written",
355                             (unsigned long)GetBitDataOutputSizeBytes() );
356                   printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
357                   outputSize = GetBitDataOutputSizeBytes();
358                   return ENOBUFS;
359                 }
360               HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-2), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
361               
362               //Write pad information:
363               temp = (Int_t)rint(cluster->fDPad);
364               HLTDebug( "cluster->fDPad (%d): %f - temp: %d", clustercount, cluster->fDPad, temp );
365               if ( temp<0 )
366                 {
367                   if ( !OutputBit( 0 ) )
368                     {
369                       HLTError( "Not enough space to write compressed data. %lu already written",
370                                 (unsigned long)GetBitDataOutputSizeBytes() );
371                       outputSize = GetBitDataOutputSizeBytes();
372                       printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
373                       return ENOBUFS;
374                     }
375                   HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
376                 }
377               else
378                 {
379                 if ( !OutputBit( 1 ) )
380                   {
381                     HLTError( "Not enough space to write compressed data. %lu already written",
382                               (unsigned long)GetBitDataOutputSizeBytes() );
383                     outputSize = GetBitDataOutputSizeBytes();
384                     printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
385                     return ENOBUFS;
386                   }
387                 HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
388                 }
389               power = 1<<(AliHLTTPCCompDataCompressorHelper::GetNPadBits()-1);
390               if ( abs(temp)>=power )
391                 {
392                   pado++;
393                   temp=power - 1;
394                 }
395               temp = abs(temp);
396               if ( !OutputBits(temp,(AliHLTTPCCompDataCompressorHelper::GetNPadBits()-1)) )
397                 {
398                   HLTError( "Not enough space to write compressed data. %lu already written",
399                             (unsigned long)GetBitDataOutputSizeBytes() );
400                   outputSize = GetBitDataOutputSizeBytes();
401                   printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
402                   return ENOBUFS;
403                 }
404               HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-2), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
405               
406               //Write charge information:
407               temp = (Int_t)cluster->fDCharge;
408               power = 1<<(AliHLTTPCCompDataCompressorHelper::GetNChargeBits());
409               if ( abs(temp)>=power )
410                 {
411                   chargeo++;
412                   temp=power - 1;
413                 }
414               temp = abs(temp);
415               if ( !OutputBits(temp,(AliHLTTPCCompDataCompressorHelper::GetNChargeBits())) )
416                 {
417                   HLTError( "Not enough space to write compressed data. %lu already written",
418                             (unsigned long)GetBitDataOutputSizeBytes() );
419                   outputSize = GetBitDataOutputSizeBytes();
420                   printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
421                   return ENOBUFS;
422                 }
423               HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-2), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
424               
425               if ( fWriteShape )
426                 {
427                   //Write shape information:
428                   // HLTInfo("DSigmaY %f", cluster->fDSigmaY);
429                   temp = (Int_t)rint(cluster->fDSigmaY);
430                   // HLTInfo("temp %d", temp);
431                   if( temp<0 )
432                     {
433                       if ( !OutputBit( 0 ) )
434                         {
435                           HLTError( "Not enough space to write compressed data. %lu already written",
436                                     (unsigned long)GetBitDataOutputSizeBytes() );
437                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
438                           outputSize = GetBitDataOutputSizeBytes();
439                           return ENOBUFS;
440                         }
441                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
442                     }
443                   else
444                     {
445                       if ( !OutputBit( 1 ) )
446                         {
447                           HLTError( "Not enough space to write compressed data. %lu already written",
448                                     (unsigned long)GetBitDataOutputSizeBytes() );
449                           outputSize = GetBitDataOutputSizeBytes();
450                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
451                           return ENOBUFS;
452                         }
453                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
454                     }
455                   power = 1<<(AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1);
456                   if ( abs(temp) >= power )
457                     {
458                       padshapeo++;
459                       temp = power - 1;
460                     }
461                   temp = abs(temp);
462                   if ( !OutputBits(temp,(AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1)) )
463                     {
464                       HLTError( "Not enough space to write compressed data. %lu already written",
465                                 (unsigned long)GetBitDataOutputSizeBytes() );
466                       printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
467                       outputSize = GetBitDataOutputSizeBytes();
468                       return ENOBUFS;
469                     }
470                   HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-2), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
471                   
472                   temp = (Int_t)rint(cluster->fDSigmaZ);
473                   if ( temp<0 )
474                     {
475                       if ( !OutputBit( 0 ) )
476                         {
477                           HLTError( "Not enough space to write compressed data. %lu already written",
478                                     (unsigned long)GetBitDataOutputSizeBytes() );
479                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
480                           outputSize = GetBitDataOutputSizeBytes();
481                           return ENOBUFS;
482                         }
483                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
484                     }
485                   else
486                     {
487                       if ( !OutputBit( 1 ) )
488                         {
489                           HLTError( "Not enough space to write compressed data. %lu already written",
490                                     (unsigned long)GetBitDataOutputSizeBytes() );
491                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
492                           outputSize = GetBitDataOutputSizeBytes();
493                           return ENOBUFS;
494                         }
495                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
496                     }
497                   power = 1<<(AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1);
498                   if ( abs(temp) >= power )
499                     {
500                       timeshapeo++;
501                       temp=power - 1;
502                     }
503                   temp = abs(temp);
504                   if ( !OutputBits(temp,(AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1)) )
505                     {
506                       HLTError( "Not enough space to write compressed data. %lu already written",
507                                 (unsigned long)GetBitDataOutputSizeBytes() );
508                       printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
509                       outputSize = GetBitDataOutputSizeBytes();
510                       return ENOBUFS;
511                     }
512                   HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-2), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
513                 }
514               
515               clustercount++;
516             }
517           trackCnt++;
518         }
519       
520       CloseBitDataOutput();
521       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
522       outputSize = GetBitDataOutputSizeBytes();
523       return 0;
524     }
525
526 int AliHLTTPCCompModelDeflater::CompressRemainingClusters( AliHLTUInt8_t* inData, UInt_t const& inputSize, AliHLTUInt8_t* output, UInt_t& outputSize )
527     {
528       // see header file for class documentation
529       AliHLTUInt8_t* inputPtr = inData;
530       AliHLTUInt8_t* inputEndPtr = inData+inputSize;
531       
532       AliHLTUInt32_t version = *(AliHLTUInt32_t*)inputPtr;
533       inputPtr += sizeof(AliHLTUInt32_t);
534       if ( version != 0 )
535         {
536           HLTError( "Unsupported version %hu. Only version 0 supported currently.", version );
537           return EIO;
538         }
539       
540       InitBitDataOutput( output, outputSize );
541       // FIXME: check return value of OutputBits to make code more robust
542       OutputBits( 0, 4 ); // Version information
543       //OutputBit( fWriteShape ); // Data format flag
544       Pad8Bits();
545       
546       //Write the remaining clusters in a compressed format.
547       
548       for(Int_t slice=0; slice<=35; slice++)
549         {
550           for(Int_t patch=0; patch < 6; patch++)
551             {
552               UInt_t i;
553               HLTDebug( "slice %u patch %u: %u padrows",
554                         (unsigned)slice, (unsigned)patch, (unsigned)*inputPtr );
555               //Write number of padrows with clusters
556               if ( inputPtr>=inputEndPtr )
557                 {
558                   HLTError( "Corrupt input data, cannot read row counter for slice %u, partition %u", (unsigned)slice, (unsigned)patch );
559                   return EIO;
560                 }
561               if ( !OutputBits( *inputPtr,8 ) )
562                 {
563                   HLTError( "Not enough space to write compressed data. %lu already written",
564                             (unsigned long)GetBitDataOutputSizeBytes() );
565                   outputSize = GetBitDataOutputSizeBytes();
566                   return ENOBUFS;
567                 }
568               if ( !*inputPtr )
569                 {
570                   inputPtr++;
571                   continue;
572                 }
573               UInt_t nRows=(UInt_t)*inputPtr;
574               inputPtr++;
575               if ( inputPtr>=inputEndPtr )
576                 {
577                   HLTError( "Corrupt input data, unexpected end of data after row counter for slice %u, partition %u", (unsigned)slice, (unsigned)patch );
578                   return EIO;
579                 }
580               
581               for ( UInt_t jj=0; jj<nRows; jj++ )
582                 {
583                   
584                   AliHLTTPCRemainingRow *thisRow = (AliHLTTPCRemainingRow*)inputPtr;
585                   if ( inputPtr+sizeof(AliHLTTPCRemainingRow)>inputEndPtr )
586                     {
587                       HLTError( "Corrupt input data, cannot read row data for row %u of slice %u, partition %u", (unsigned)jj, (unsigned)slice, (unsigned)patch );
588                       return EIO;
589                     }
590                   AliHLTTPCRemainingCluster *cl = thisRow->fClusters;
591                   HLTDebug( "Row %u: %u clusters", (unsigned)thisRow->fPadRow, (unsigned)thisRow->fNClusters );
592                   if ( inputPtr+sizeof(AliHLTTPCRemainingRow)+thisRow->fNClusters*sizeof(AliHLTTPCRemainingCluster)>inputEndPtr )
593                     {
594                       HLTError( "Corrupt input data, unable to read clusters for row %u, slice %u, partition %u", (unsigned)jj, (unsigned)slice, (unsigned)patch );
595                       return EIO;
596                     }
597                   Int_t padrow = thisRow->fPadRow;
598                   if ( !OutputBits(padrow,8) ) //Write padrow #
599                     {
600                       HLTError( "Not enough space to write compressed data. %lu already written",
601                                 (unsigned long)GetBitDataOutputSizeBytes() );
602                       outputSize = GetBitDataOutputSizeBytes();
603                       return ENOBUFS;
604                     }
605                   if( thisRow->fNClusters >= 1<<10)
606                     {
607                       HLTError( "Too many remaining clusters (%u)", (unsigned)thisRow->fNClusters );
608                       return ERANGE;
609                     }
610                   if ( !OutputBits(thisRow->fNClusters,10) )//Write number of clusters on this padrow
611                     {
612                       HLTError( "Not enough space to write compressed data. %lu already written",
613                                 (unsigned long)GetBitDataOutputSizeBytes() );
614                       outputSize = GetBitDataOutputSizeBytes();
615                       return ENOBUFS;
616                     }
617                   for ( i=0; i<thisRow->fNClusters; i++ )
618                     {
619                       
620                       Float_t padw = sqrt(cl[i].fSigmaY2);
621                       //HLTInfo( "padw0: %f", padw );
622                       Float_t timew = sqrt( cl[i].fSigmaZ2 );
623                       
624                       //Check for saturation in the widths.
625                       //Basically only store a certain number of decimals here, and cut the widths which is higher:
626                       if(padw >= (1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) / AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor())
627                         padw = (1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) / AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor() - 1/AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor();
628                       //HLTInfo( "padw1: %f", padw );
629                       if(timew >= (1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) / AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor())
630                         timew = (1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) / AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor() - 1/AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor();;
631                       
632                       //Write pad
633                       Int_t buff;
634                       buff = (Int_t)rint(cl[i].fPad*AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor());
635                       if(buff<0)
636                         {
637                           HLTError( "Wrong pad value %d (%f, %f, row %u, i: %u)",buff, cl[i].fPad, AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor(), (unsigned)thisRow->fNClusters, (unsigned)i );
638                           return EINVAL;
639                         }
640                       if ( !OutputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNPadBitsRemaining()) )
641                         {
642                           HLTError( "Not enough space to write compressed data. %lu already written",
643                                     (unsigned long)GetBitDataOutputSizeBytes() );
644                         outputSize = GetBitDataOutputSizeBytes();
645                         return ENOBUFS;
646                         }
647                       
648                     
649                       //Write time
650                       buff = (Int_t)rint(cl[i].fTime*AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor());
651                       if(buff<0)
652                         {
653                           HLTError( "Wrong time value %d",buff);
654                         return EINVAL;
655                         }
656                       if ( !OutputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNTimeBitsRemaining()) )
657                         {
658                           HLTError( "Not enough space to write compressed data. %lu already written",
659                                     (unsigned long)GetBitDataOutputSizeBytes() );
660                           outputSize = GetBitDataOutputSizeBytes();
661                           return ENOBUFS;
662                         }
663                       
664                       //Write widths
665                       buff = (Int_t)rint(padw*AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor());
666                       HLTDebug( "padw/buff: %d (%d / 0x%08X)", buff, 
667                                 (buff & ((1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining())-1)),
668                                 (buff & ((1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining())-1)) );
669                       
670                       if ( !OutputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) )
671                         {
672                         HLTError( "Not enough space to write compressed data. %lu already written",
673                                   (unsigned long)GetBitDataOutputSizeBytes() );
674                         outputSize = GetBitDataOutputSizeBytes();
675                         return ENOBUFS;
676                         }
677                       buff = (Int_t)rint(timew*AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor());
678                       if ( !OutputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) )
679                         {
680                           HLTError( "Not enough space to write compressed data. %lu already written",
681                                     (unsigned long)GetBitDataOutputSizeBytes() );
682                           outputSize = GetBitDataOutputSizeBytes();
683                           return ENOBUFS;
684                         }
685                       
686                       //Write charge 
687                       buff = cl[i].fCharge;
688                       if(buff >= 1<<(AliHLTTPCCompDataCompressorHelper::GetNChargeBits()))
689                         buff = (1<<(AliHLTTPCCompDataCompressorHelper::GetNChargeBits()))-1;
690                       if ( !OutputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNChargeBits()) )
691                         {
692                           HLTError( "Not enough space to write compressed data. %lu already written",
693                                     (unsigned long)GetBitDataOutputSizeBytes() );
694                           outputSize = GetBitDataOutputSizeBytes();
695                           return ENOBUFS;
696                         }
697                     }
698                   inputPtr += sizeof(AliHLTTPCRemainingRow)+thisRow->fNClusters*sizeof(AliHLTTPCRemainingCluster);
699                 }
700             }
701           
702         }
703       CloseBitDataOutput();
704       outputSize = GetBitDataOutputSizeBytes();
705       return 0;
706     }