summaryrefslogtreecommitdiffstats
path: root/hostTools/lzma/compress/AriBitCoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'hostTools/lzma/compress/AriBitCoder.h')
-rw-r--r--hostTools/lzma/compress/AriBitCoder.h101
1 files changed, 101 insertions, 0 deletions
diff --git a/hostTools/lzma/compress/AriBitCoder.h b/hostTools/lzma/compress/AriBitCoder.h
new file mode 100644
index 0000000..76328cd
--- /dev/null
+++ b/hostTools/lzma/compress/AriBitCoder.h
@@ -0,0 +1,101 @@
+#ifndef __COMPRESSION_BITCODER_H
+#define __COMPRESSION_BITCODER_H
+
+#include "RangeCoder.h"
+
+namespace NCompression {
+namespace NArithmetic {
+
+const int kNumBitModelTotalBits = 11;
+const UINT32 kBitModelTotal = (1 << kNumBitModelTotalBits);
+
+const int kNumMoveReducingBits = 2;
+
+
+class CPriceTables
+{
+public:
+ UINT32 m_StatePrices[kBitModelTotal >> kNumMoveReducingBits];
+ CPriceTables();
+};
+
+extern CPriceTables g_PriceTables;
+
+
+/////////////////////////////
+// CBitModel
+
+template <int aNumMoveBits>
+class CBitModel
+{
+public:
+ UINT32 m_Probability;
+ void UpdateModel(UINT32 aSymbol)
+ {
+ /*
+ m_Probability -= (m_Probability + ((aSymbol - 1) & ((1 << aNumMoveBits) - 1))) >> aNumMoveBits;
+ m_Probability += (1 - aSymbol) << (kNumBitModelTotalBits - aNumMoveBits);
+ */
+ if (aSymbol == 0)
+ m_Probability += (kBitModelTotal - m_Probability) >> aNumMoveBits;
+ else
+ m_Probability -= (m_Probability) >> aNumMoveBits;
+ }
+public:
+ void Init() { m_Probability = kBitModelTotal / 2; }
+};
+
+template <int aNumMoveBits>
+class CBitEncoder: public CBitModel<aNumMoveBits>
+{
+public:
+ void Encode(CRangeEncoder *aRangeEncoder, UINT32 aSymbol)
+ {
+ aRangeEncoder->EncodeBit(this->m_Probability, kNumBitModelTotalBits, aSymbol);
+ this->UpdateModel(aSymbol);
+ }
+ UINT32 GetPrice(UINT32 aSymbol) const
+ {
+ return g_PriceTables.m_StatePrices[
+ (((this->m_Probability - aSymbol) ^ ((-(int)aSymbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+ }
+};
+
+
+template <int aNumMoveBits>
+class CBitDecoder: public CBitModel<aNumMoveBits>
+{
+public:
+ UINT32 Decode(CRangeDecoder *aRangeDecoder)
+ {
+ UINT32 aNewBound = (aRangeDecoder->m_Range >> kNumBitModelTotalBits) * this->m_Probability;
+ if (aRangeDecoder->m_Code < aNewBound)
+ {
+ aRangeDecoder->m_Range = aNewBound;
+ this->m_Probability += (kBitModelTotal - this->m_Probability) >> aNumMoveBits;
+ if (aRangeDecoder->m_Range < kTopValue)
+ {
+ aRangeDecoder->m_Code = (aRangeDecoder->m_Code << 8) | aRangeDecoder->m_Stream.ReadByte();
+ aRangeDecoder->m_Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ aRangeDecoder->m_Range -= aNewBound;
+ aRangeDecoder->m_Code -= aNewBound;
+ this->m_Probability -= (this->m_Probability) >> aNumMoveBits;
+ if (aRangeDecoder->m_Range < kTopValue)
+ {
+ aRangeDecoder->m_Code = (aRangeDecoder->m_Code << 8) | aRangeDecoder->m_Stream.ReadByte();
+ aRangeDecoder->m_Range <<= 8;
+ }
+ return 1;
+ }
+ }
+};
+
+}}
+
+
+#endif