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