Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #include "RangeCoderBitTree.h"
  2. #include "lzma.h"
  3.  
  4. static unsigned _cacheSize;
  5. static byte _cache;
  6. static uint64 low;
  7. static unsigned range;
  8.  
  9. static unsigned PriceTable[kBitModelTotal >> kNumMoveReducingBits];
  10.  
  11. void RangeEncoder_Init(void)
  12. {
  13.         int i;
  14.         unsigned start,end,j;
  15.         low = 0;
  16.         range = 0xFFFFFFFF;
  17.         _cacheSize = 1;
  18.         _cache = 0;
  19.         /* init price table */
  20. #define kNumBits (kNumBitModelTotalBits - kNumMoveReducingBits)
  21.         for (i=kNumBits;i--;)
  22.         {
  23.                 start = 1 << (kNumBits - i - 1);
  24.                 end = 1 << (kNumBits - i);
  25.                 for (j=start;j<end;j++)
  26.                         PriceTable[j] = (i<<kNumBitPriceShiftBits) +
  27.                         (((end-j)<<kNumBitPriceShiftBits) >> (kNumBits - i - 1));
  28.         }
  29. #undef kNumBits
  30. }
  31.  
  32. void RangeEncoder_ShiftLow(void)
  33. {
  34.         if ((unsigned)low < 0xFF000000U || (int)(low>>32))
  35.         {
  36.                 byte temp = _cache;
  37.                 do
  38.                 {
  39.                         *curout++ = (byte)(temp + (byte)(low>>32));
  40.                         temp = 0xFF;
  41.                 } while (--_cacheSize);
  42.                 _cache = (byte)((unsigned)low>>24);
  43.         }
  44.         _cacheSize++;
  45.         low = (unsigned)low << 8;
  46. }
  47.  
  48. void RangeEncoder_FlushData(void)
  49. {
  50.         int i;
  51.         for (i=0;i<5;i++)
  52.                 RangeEncoder_ShiftLow();
  53. }
  54.  
  55. void RangeEncoder_EncodeDirectBits(unsigned value,int numTotalBits)
  56. {
  57.         int i;
  58.         for (i=numTotalBits;i--;)
  59.         {
  60.                 range >>= 1;
  61.                 if (((value >> i) & 1) == 1)
  62.                         low += range;
  63.                 if (range < kTopValue)
  64.                 {
  65.                         range <<= 8;
  66.                         RangeEncoder_ShiftLow();
  67.                 }
  68.         }
  69. }
  70.  
  71. void CMyBitEncoder_Encode(CMyBitEncoder* e,unsigned symbol)
  72. {
  73.         unsigned newBound;
  74.         newBound = (range >> kNumBitModelTotalBits) * *e;
  75.         if (symbol == 0)
  76.         {
  77.                 range = newBound;
  78.                 *e += (kBitModelTotal - *e) >> kNumMoveBits;
  79.         }
  80.         else
  81.         {
  82.                 low += newBound;
  83.                 range -= newBound;
  84.                 *e -= *e >> kNumMoveBits;
  85.         }
  86.         if (range < kTopValue)
  87.         {
  88.                 range <<= 8;
  89.                 RangeEncoder_ShiftLow();
  90.         }
  91. }
  92.  
  93. unsigned CMyBitEncoder_GetPrice(CMyBitEncoder* e, unsigned symbol)
  94. {
  95.         return PriceTable[(((*e-symbol)^((-(int)symbol))) & (kBitModelTotal-1)) >> kNumMoveReducingBits];
  96. }
  97. unsigned CMyBitEncoder_GetPrice0(CMyBitEncoder* e)
  98. {
  99.         return PriceTable[*e >> kNumMoveReducingBits];
  100. }
  101. unsigned CMyBitEncoder_GetPrice1(CMyBitEncoder* e)
  102. {
  103.         return PriceTable[(kBitModelTotal - *e) >> kNumMoveReducingBits];
  104. }
  105.  
  106. void CBitTreeEncoder_Init(NRangeCoder_CBitTreeEncoder*e,int numBitLevels)
  107. {
  108.         unsigned i;
  109.         e->numBitLevels = numBitLevels;
  110.         for (i=1;i<((unsigned)1<<numBitLevels);i++)
  111.                 CMyBitEncoder_Init(e->Models[i]);
  112. }
  113. void CBitTreeEncoder_Encode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
  114. {
  115.         unsigned modelIndex = 1;
  116.         int bitIndex;
  117.         unsigned bit;
  118.         for (bitIndex = e->numBitLevels; bitIndex--;)
  119.         {
  120.                 bit = (symbol >> bitIndex) & 1;
  121.                 CMyBitEncoder_Encode(&e->Models[modelIndex],bit);
  122.                 modelIndex = (modelIndex << 1) | bit;
  123.         }
  124. }
  125. void CBitTreeEncoder_ReverseEncode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
  126. {
  127.         unsigned modelIndex = 1;
  128.         int i;
  129.         unsigned bit;
  130.         for (i=0;i<e->numBitLevels;i++)
  131.         {
  132.                 bit = symbol & 1;
  133.                 CMyBitEncoder_Encode(&e->Models[modelIndex],bit);
  134.                 modelIndex = (modelIndex << 1) | bit;
  135.                 symbol >>= 1;
  136.         }
  137. }
  138. unsigned CBitTreeEncoder_GetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
  139. {
  140.         unsigned price = 0;
  141.         symbol |= (1 << e->numBitLevels);
  142.         while (symbol != 1)
  143.         {
  144.                 price += CMyBitEncoder_GetPrice(&e->Models[symbol>>1],symbol&1);
  145.                 symbol >>= 1;
  146.         }
  147.         return price;
  148. }
  149. unsigned CBitTreeEncoder_ReverseGetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
  150. {
  151.         unsigned price=0;
  152.         unsigned modelIndex=1;
  153.         int i;
  154.         unsigned bit;
  155.         for (i=e->numBitLevels;i;i--)
  156.         {
  157.                 bit = symbol&1;
  158.                 symbol >>= 1;
  159.                 price += CMyBitEncoder_GetPrice(&e->Models[modelIndex],bit);
  160.                 modelIndex = (modelIndex<<1)|bit;
  161.         }
  162.         return price;
  163. }
  164. unsigned ReverseBitTreeGetPrice(CMyBitEncoder*Models,unsigned NumBitLevels,unsigned symbol)
  165. {
  166.         unsigned price=0;
  167.         unsigned modelIndex=1;
  168.         unsigned bit;
  169.         int i;
  170.         for (i=NumBitLevels;i;i--)
  171.         {
  172.                 bit = symbol & 1;
  173.                 symbol >>= 1;
  174.                 price += CMyBitEncoder_GetPrice(Models+modelIndex,bit);
  175.                 modelIndex = (modelIndex<<1)|bit;
  176.         }
  177.         return price;
  178. }
  179. void ReverseBitTreeEncode(CMyBitEncoder*Models,int NumBitLevels,unsigned symbol)
  180. {
  181.         unsigned modelIndex = 1;
  182.         int i;
  183.         unsigned bit;
  184.         for (i=0;i<NumBitLevels;i++)
  185.         {
  186.                 bit = symbol & 1;
  187.                 CMyBitEncoder_Encode(Models+modelIndex,bit);
  188.                 modelIndex = (modelIndex<<1)|bit;
  189.                 symbol >>= 1;
  190.         }
  191. }
  192.