summaryrefslogtreecommitdiffstats
path: root/hostTools/lzma/decompress/RangeCoder.h
blob: ae6f9747dc5bf0c85ca60ac6c7b5f66ad0df533f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#ifndef __COMPRESSION_RANGECODER_H
#define __COMPRESSION_RANGECODER_H

#include "IInOutStreams.h"

#define kNumTopBits 24
#define kTopValue (1 << kNumTopBits)

typedef struct CRangeDecoder
{
  UINT32  m_Range;
  UINT32  m_Code;
} CRangeDecoder;



INLINE void RangeDecoderInit(
    ISequentialInStream *in_stream, 
    CRangeDecoder *rangeDecoder)
  {
    int i;
    rangeDecoder->m_Code = 0;
    rangeDecoder->m_Range = (UINT32)(-1);
    for(i = 0; i < 5; i++)
      rangeDecoder->m_Code = (rangeDecoder->m_Code << 8) | InStreamReadByte(in_stream);
  }

INLINE UINT32 RangeDecodeDirectBits(
    ISequentialInStream *in_stream, 
    CRangeDecoder *rangeDecoder, 
    UINT32 aNumTotalBits)
  {
    UINT32 aRange = rangeDecoder->m_Range;
    UINT32 aCode = rangeDecoder->m_Code;        
    UINT32 aResult = 0;
    UINT32 i;
    for (i = aNumTotalBits; i > 0; i--)
    {
      UINT32 t;
      aRange >>= 1;
      t = (aCode - aRange) >> 31;
      aCode -= aRange & (t - 1);
      aResult = (aResult << 1) | (1 - t);

      if (aRange < kTopValue)
      {
        aCode = (aCode << 8) | InStreamReadByte(in_stream);
        aRange <<= 8; 
      }
    }
    rangeDecoder->m_Range = aRange;
    rangeDecoder->m_Code = aCode;
    return aResult;
  }

#endif