other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 // Compress/RangeCoder/RangeCoderBit.h
michael@0 2
michael@0 3 #ifndef __COMPRESS_RANGECODER_BIT_H
michael@0 4 #define __COMPRESS_RANGECODER_BIT_H
michael@0 5
michael@0 6 #include "RangeCoder.h"
michael@0 7
michael@0 8 namespace NCompress {
michael@0 9 namespace NRangeCoder {
michael@0 10
michael@0 11 const int kNumBitModelTotalBits = 11;
michael@0 12 const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
michael@0 13
michael@0 14 const int kNumMoveReducingBits = 2;
michael@0 15
michael@0 16 const int kNumBitPriceShiftBits = 6;
michael@0 17 const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
michael@0 18
michael@0 19 class CPriceTables
michael@0 20 {
michael@0 21 public:
michael@0 22 static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
michael@0 23 static void Init();
michael@0 24 CPriceTables();
michael@0 25 };
michael@0 26
michael@0 27 template <int numMoveBits>
michael@0 28 class CBitModel
michael@0 29 {
michael@0 30 public:
michael@0 31 UInt32 Prob;
michael@0 32 void UpdateModel(UInt32 symbol)
michael@0 33 {
michael@0 34 /*
michael@0 35 Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
michael@0 36 Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
michael@0 37 */
michael@0 38 if (symbol == 0)
michael@0 39 Prob += (kBitModelTotal - Prob) >> numMoveBits;
michael@0 40 else
michael@0 41 Prob -= (Prob) >> numMoveBits;
michael@0 42 }
michael@0 43 public:
michael@0 44 void Init() { Prob = kBitModelTotal / 2; }
michael@0 45 };
michael@0 46
michael@0 47 template <int numMoveBits>
michael@0 48 class CBitEncoder: public CBitModel<numMoveBits>
michael@0 49 {
michael@0 50 public:
michael@0 51 void Encode(CEncoder *encoder, UInt32 symbol)
michael@0 52 {
michael@0 53 /*
michael@0 54 encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
michael@0 55 this->UpdateModel(symbol);
michael@0 56 */
michael@0 57 UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
michael@0 58 if (symbol == 0)
michael@0 59 {
michael@0 60 encoder->Range = newBound;
michael@0 61 this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
michael@0 62 }
michael@0 63 else
michael@0 64 {
michael@0 65 encoder->Low += newBound;
michael@0 66 encoder->Range -= newBound;
michael@0 67 this->Prob -= (this->Prob) >> numMoveBits;
michael@0 68 }
michael@0 69 if (encoder->Range < kTopValue)
michael@0 70 {
michael@0 71 encoder->Range <<= 8;
michael@0 72 encoder->ShiftLow();
michael@0 73 }
michael@0 74 }
michael@0 75 UInt32 GetPrice(UInt32 symbol) const
michael@0 76 {
michael@0 77 return CPriceTables::ProbPrices[
michael@0 78 (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
michael@0 79 }
michael@0 80 UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
michael@0 81 UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
michael@0 82 };
michael@0 83
michael@0 84
michael@0 85 template <int numMoveBits>
michael@0 86 class CBitDecoder: public CBitModel<numMoveBits>
michael@0 87 {
michael@0 88 public:
michael@0 89 UInt32 Decode(CDecoder *decoder)
michael@0 90 {
michael@0 91 UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
michael@0 92 if (decoder->Code < newBound)
michael@0 93 {
michael@0 94 decoder->Range = newBound;
michael@0 95 this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
michael@0 96 if (decoder->Range < kTopValue)
michael@0 97 {
michael@0 98 decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
michael@0 99 decoder->Range <<= 8;
michael@0 100 }
michael@0 101 return 0;
michael@0 102 }
michael@0 103 else
michael@0 104 {
michael@0 105 decoder->Range -= newBound;
michael@0 106 decoder->Code -= newBound;
michael@0 107 this->Prob -= (this->Prob) >> numMoveBits;
michael@0 108 if (decoder->Range < kTopValue)
michael@0 109 {
michael@0 110 decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
michael@0 111 decoder->Range <<= 8;
michael@0 112 }
michael@0 113 return 1;
michael@0 114 }
michael@0 115 }
michael@0 116 };
michael@0 117
michael@0 118 }}
michael@0 119
michael@0 120 #endif

mercurial