1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// LzmaEncoder.cs 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing System; 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace SevenZip.Compression.LZMA 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync using RangeCoder; 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties 10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync enum EMatchFinderType 12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync BT2, 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync BT4, 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync }; 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt32 kIfinityPrice = 0xFFFFFFF; 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync static Byte[] g_FastPos = new Byte[1 << 11]; 20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync static Encoder() 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const Byte kFastSlots = 22; 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int c = 2; 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync g_FastPos[0] = 0; 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync g_FastPos[1] = 1; 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++) 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 k = ((UInt32)1 << ((slotFast >> 1) - 1)); 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 j = 0; j < k; j++, c++) 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync g_FastPos[c] = slotFast; 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync static UInt32 GetPosSlot(UInt32 pos) 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos < (1 << 11)) 38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return g_FastPos[pos]; 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos < (1 << 21)) 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (UInt32)(g_FastPos[pos >> 10] + 20); 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (UInt32)(g_FastPos[pos >> 20] + 40); 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync static UInt32 GetPosSlot2(UInt32 pos) 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos < (1 << 17)) 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (UInt32)(g_FastPos[pos >> 6] + 12); 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos < (1 << 27)) 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (UInt32)(g_FastPos[pos >> 16] + 32); 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (UInt32)(g_FastPos[pos >> 26] + 52); 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Base.State _state = new Base.State(); 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte _previousByte; 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32[] _repDistances = new UInt32[Base.kNumRepDistances]; 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void BaseInit() 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _state.Init(); 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _previousByte = 0; 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 i = 0; i < Base.kNumRepDistances; i++) 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _repDistances[i] = 0; 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const int kDefaultDictionaryLogSize = 22; 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt32 kNumFastBytesDefault = 0x20; 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync class LiteralEncoder 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public struct Encoder2 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync BitEncoder[] m_Encoders; 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void Create() { m_Encoders = new BitEncoder[0x300]; } 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void Init() { for (int i = 0; i < 0x300; i++) m_Encoders[i].Init(); } 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void Encode(RangeCoder.Encoder rangeEncoder, byte symbol) 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint context = 1; 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 7; i >= 0; i--) 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint bit = (uint)((symbol >> i) & 1); 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync m_Encoders[context].Encode(rangeEncoder, bit); 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync context = (context << 1) | bit; 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void EncodeMatched(RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol) 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint context = 1; 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool same = true; 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 7; i >= 0; i--) 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint bit = (uint)((symbol >> i) & 1); 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint state = context; 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (same) 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint matchBit = (uint)((matchByte >> i) & 1); 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state += ((1 + matchBit) << 8); 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync same = (matchBit == bit); 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync m_Encoders[state].Encode(rangeEncoder, bit); 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync context = (context << 1) | bit; 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public uint GetPrice(bool matchMode, byte matchByte, byte symbol) 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint price = 0; 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint context = 1; 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i = 7; 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (matchMode) 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (; i >= 0; i--) 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint matchBit = (uint)(matchByte >> i) & 1; 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint bit = (uint)(symbol >> i) & 1; 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync price += m_Encoders[((1 + matchBit) << 8) + context].GetPrice(bit); 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync context = (context << 1) | bit; 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (matchBit != bit) 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync i--; 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (; i >= 0; i--) 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint bit = (uint)(symbol >> i) & 1; 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync price += m_Encoders[context].GetPrice(bit); 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync context = (context << 1) | bit; 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return price; 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Encoder2[] m_Coders; 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int m_NumPrevBits; 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int m_NumPosBits; 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint m_PosMask; 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void Create(int numPosBits, int numPrevBits) 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits) 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync m_NumPosBits = numPosBits; 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync m_PosMask = ((uint)1 << numPosBits) - 1; 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync m_NumPrevBits = numPrevBits; 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); 151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync m_Coders = new Encoder2[numStates]; 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (uint i = 0; i < numStates; i++) 153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync m_Coders[i].Create(); 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void Init() 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (uint i = 0; i < numStates; i++) 160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync m_Coders[i].Init(); 161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public Encoder2 GetSubCoder(UInt32 pos, Byte prevByte) 164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits))]; } 165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync class LenEncoder 168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitEncoder _choice = new RangeCoder.BitEncoder(); 170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitEncoder _choice2 = new RangeCoder.BitEncoder(); 171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitTreeEncoder[] _lowCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax]; 172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitTreeEncoder[] _midCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax]; 173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitTreeEncoder _highCoder = new RangeCoder.BitTreeEncoder(Base.kNumHighLenBits); 174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public LenEncoder() 176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++) 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _lowCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumLowLenBits); 180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _midCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumMidLenBits); 181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void Init(UInt32 numPosStates) 185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _choice.Init(); 187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _choice2.Init(); 188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 posState = 0; posState < numPosStates; posState++) 189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _lowCoder[posState].Init(); 191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _midCoder[posState].Init(); 192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _highCoder.Init(); 194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState) 197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (symbol < Base.kNumLowLenSymbols) 199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _choice.Encode(rangeEncoder, 0); 201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _lowCoder[posState].Encode(rangeEncoder, symbol); 202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync symbol -= Base.kNumLowLenSymbols; 206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _choice.Encode(rangeEncoder, 1); 207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (symbol < Base.kNumMidLenSymbols) 208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _choice2.Encode(rangeEncoder, 0); 210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _midCoder[posState].Encode(rangeEncoder, symbol); 211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _choice2.Encode(rangeEncoder, 1); 215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols); 216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32[] prices, UInt32 st) 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 a0 = _choice.GetPrice0(); 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 a1 = _choice.GetPrice1(); 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 b0 = a1 + _choice2.GetPrice0(); 225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 b1 = a1 + _choice2.GetPrice1(); 226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i = 0; 227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < Base.kNumLowLenSymbols; i++) 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (i >= numSymbols) 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prices[st + i] = a0 + _lowCoder[posState].GetPrice(i); 232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++) 234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (i >= numSymbols) 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols); 238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (; i < numSymbols; i++) 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols); 241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync }; 243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt32 kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; 245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync class LenPriceTableEncoder : LenEncoder 247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32[] _prices = new UInt32[Base.kNumLenSymbols << Base.kNumPosStatesBitsEncodingMax]; 249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _tableSize; 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32[] _counters = new UInt32[Base.kNumPosStatesEncodingMax]; 251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; } 253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public UInt32 GetPrice(UInt32 symbol, UInt32 posState) 255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _prices[posState * Base.kNumLenSymbols + symbol]; 257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void UpdateTable(UInt32 posState) 260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols); 262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _counters[posState] = _tableSize; 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void UpdateTables(UInt32 numPosStates) 266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 posState = 0; posState < numPosStates; posState++) 268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UpdateTable(posState); 269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public new void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState) 272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync base.Encode(rangeEncoder, symbol, posState); 274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (--_counters[posState] == 0) 275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UpdateTable(posState); 276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt32 kNumOpts = 1 << 12; 280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync class Optimal 281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public Base.State State; 283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public bool Prev1IsChar; 285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public bool Prev2; 286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public UInt32 PosPrev2; 288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public UInt32 BackPrev2; 289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public UInt32 Price; 291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public UInt32 PosPrev; 292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public UInt32 BackPrev; 293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public UInt32 Backs0; 295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public UInt32 Backs1; 296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public UInt32 Backs2; 297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public UInt32 Backs3; 298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void MakeAsChar() { BackPrev = 0xFFFFFFFF; Prev1IsChar = false; } 300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; } 301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public bool IsShortRep() { return (BackPrev == 0); } 302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync }; 303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Optimal[] _optimum = new Optimal[kNumOpts]; 304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync LZ.IMatchFinder _matchFinder = null; 305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.Encoder _rangeEncoder = new RangeCoder.Encoder(); 306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitEncoder[] _isMatch = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; 308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitEncoder[] _isRep = new RangeCoder.BitEncoder[Base.kNumStates]; 309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitEncoder[] _isRepG0 = new RangeCoder.BitEncoder[Base.kNumStates]; 310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitEncoder[] _isRepG1 = new RangeCoder.BitEncoder[Base.kNumStates]; 311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitEncoder[] _isRepG2 = new RangeCoder.BitEncoder[Base.kNumStates]; 312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitEncoder[] _isRep0Long = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; 313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitTreeEncoder[] _posSlotEncoder = new RangeCoder.BitTreeEncoder[Base.kNumLenToPosStates]; 315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitEncoder[] _posEncoders = new RangeCoder.BitEncoder[Base.kNumFullDistances - Base.kEndPosModelIndex]; 317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitTreeEncoder _posAlignEncoder = new RangeCoder.BitTreeEncoder(Base.kNumAlignBits); 318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder(); 320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder(); 321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync LiteralEncoder _literalEncoder = new LiteralEncoder(); 323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32[] _matchDistances = new UInt32[Base.kMatchMaxLen * 2 + 2]; 325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _numFastBytes = kNumFastBytesDefault; 327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _longestMatchLength; 328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _numDistancePairs; 329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _additionalOffset; 331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _optimumEndIndex; 333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _optimumCurrentIndex; 334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool _longestMatchWasFound; 336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32[] _posSlotPrices = new UInt32[1 << (Base.kNumPosSlotBits + Base.kNumLenToPosStatesBits)]; 338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32[] _distancesPrices = new UInt32[Base.kNumFullDistances << Base.kNumLenToPosStatesBits]; 339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32[] _alignPrices = new UInt32[Base.kAlignTableSize]; 340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _alignPriceCount; 341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _distTableSize = (kDefaultDictionaryLogSize * 2); 343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int _posStateBits = 2; 345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _posStateMask = (4 - 1); 346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int _numLiteralPosStateBits = 0; 347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int _numLiteralContextBits = 3; 348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _dictionarySize = (1 << kDefaultDictionaryLogSize); 350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _dictionarySizePrev = 0xFFFFFFFF; 351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _numFastBytesPrev = 0xFFFFFFFF; 352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int64 nowPos64; 354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool _finished; 355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync System.IO.Stream _inStream; 356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync EMatchFinderType _matchFinderType = EMatchFinderType.BT4; 358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool _writeEndMark = false; 359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool _needReleaseMFStream; 361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void Create() 363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_matchFinder == null) 365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync LZ.BinTree bt = new LZ.BinTree(); 367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numHashBytes = 4; 368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_matchFinderType == EMatchFinderType.BT2) 369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numHashBytes = 2; 370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bt.SetType(numHashBytes); 371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder = bt; 372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits); 374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes) 376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1); 378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _dictionarySizePrev = _dictionarySize; 379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _numFastBytesPrev = _numFastBytes; 380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public Encoder() 383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < kNumOpts; i++) 385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[i] = new Optimal(); 386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < Base.kNumLenToPosStates; i++) 387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posSlotEncoder[i] = new RangeCoder.BitTreeEncoder(Base.kNumPosSlotBits); 388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void SetWriteEndMarkerMode(bool writeEndMarker) 391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _writeEndMark = writeEndMarker; 393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void Init() 396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync BaseInit(); 398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeEncoder.Init(); 399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint i; 401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < Base.kNumStates; i++) 402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (uint j = 0; j <= _posStateMask; j++) 404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint complexState = (i << Base.kNumPosStatesBitsMax) + j; 406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isMatch[complexState].Init(); 407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRep0Long[complexState].Init(); 408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRep[i].Init(); 410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRepG0[i].Init(); 411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRepG1[i].Init(); 412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRepG2[i].Init(); 413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _literalEncoder.Init(); 415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < Base.kNumLenToPosStates; i++) 416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posSlotEncoder[i].Init(); 417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++) 418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posEncoders[i].Init(); 419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _lenEncoder.Init((UInt32)1 << _posStateBits); 421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _repMatchLenEncoder.Init((UInt32)1 << _posStateBits); 422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posAlignEncoder.Init(); 424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _longestMatchWasFound = false; 426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimumEndIndex = 0; 427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimumCurrentIndex = 0; 428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _additionalOffset = 0; 429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void ReadMatchDistances(out UInt32 lenRes, out UInt32 numDistancePairs) 432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync lenRes = 0; 434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numDistancePairs = _matchFinder.GetMatches(_matchDistances); 435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numDistancePairs > 0) 436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync lenRes = _matchDistances[numDistancePairs - 2]; 438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (lenRes == _numFastBytes) 439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[numDistancePairs - 1], 440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Base.kMatchMaxLen - lenRes); 441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _additionalOffset++; 443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void MovePos(UInt32 num) 447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (num > 0) 449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.Skip(num); 451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _additionalOffset += num; 452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 GetRepLen1Price(Base.State state, UInt32 posState) 456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _isRepG0[state.Index].GetPrice0() + 458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0(); 459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 GetPureRepPrice(UInt32 repIndex, Base.State state, UInt32 posState) 462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 price; 464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (repIndex == 0) 465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync price = _isRepG0[state.Index].GetPrice0(); 467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync price += _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1(); 468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync price = _isRepG0[state.Index].GetPrice1(); 472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (repIndex == 1) 473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync price += _isRepG1[state.Index].GetPrice0(); 474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync price += _isRepG1[state.Index].GetPrice1(); 477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync price += _isRepG2[state.Index].GetPrice(repIndex - 2); 478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return price; 481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, Base.State state, UInt32 posState) 484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState); 486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return price + GetPureRepPrice(repIndex, state, posState); 487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 488baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) 490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 price; 492baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenToPosState = Base.GetLenToPosState(len); 493baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos < Base.kNumFullDistances) 494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos]; 495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] + 497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _alignPrices[pos & Base.kAlignMask]; 498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState); 499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 Backward(out UInt32 backRes, UInt32 cur) 502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimumEndIndex = cur; 504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posMem = _optimum[cur].PosPrev; 505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 backMem = _optimum[cur].BackPrev; 506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do 507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_optimum[cur].Prev1IsChar) 509baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[posMem].MakeAsChar(); 511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[posMem].PosPrev = posMem - 1; 512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_optimum[cur].Prev2) 513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[posMem - 1].Prev1IsChar = false; 515baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2; 516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2; 517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posPrev = posMem; 520baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 backCur = backMem; 521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync backMem = _optimum[posPrev].BackPrev; 523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync posMem = _optimum[posPrev].PosPrev; 524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 525baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[posPrev].BackPrev = backCur; 526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[posPrev].PosPrev = cur; 527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync cur = posPrev; 528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (cur > 0); 530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync backRes = _optimum[0].BackPrev; 531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimumCurrentIndex = _optimum[0].PosPrev; 532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _optimumCurrentIndex; 533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 534baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 535baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32[] reps = new UInt32[Base.kNumRepDistances]; 536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32[] repLens = new UInt32[Base.kNumRepDistances]; 537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 GetOptimum(UInt32 position, out UInt32 backRes) 540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_optimumEndIndex != _optimumCurrentIndex) 542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 543baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex; 544baa3858d3f5d128a5c8466b700098109edcad5f2repo sync backRes = _optimum[_optimumCurrentIndex].BackPrev; 545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev; 546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return lenRes; 547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimumCurrentIndex = _optimumEndIndex = 0; 549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenMain, numDistancePairs; 551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_longestMatchWasFound) 552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReadMatchDistances(out lenMain, out numDistancePairs); 554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync lenMain = _longestMatchLength; 558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numDistancePairs = _numDistancePairs; 559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _longestMatchWasFound = false; 560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 561baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1; 563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numAvailableBytes < 2) 564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync backRes = 0xFFFFFFFF; 566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 1; 567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numAvailableBytes > Base.kMatchMaxLen) 569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numAvailableBytes = Base.kMatchMaxLen; 570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 repMaxIndex = 0; 572baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < Base.kNumRepDistances; i++) 574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[i] = _repDistances[i]; 576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen); 577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (repLens[i] > repLens[repMaxIndex]) 578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync repMaxIndex = i; 579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (repLens[repMaxIndex] >= _numFastBytes) 581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync backRes = repMaxIndex; 583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenRes = repLens[repMaxIndex]; 584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MovePos(lenRes - 1); 585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return lenRes; 586baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (lenMain >= _numFastBytes) 589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances; 591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MovePos(lenMain - 1); 592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return lenMain; 593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte currentByte = _matchFinder.GetIndexByte(0 - 1); 596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - 1)); 597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2) 599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync backRes = (UInt32)0xFFFFFFFF; 601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 1; 602baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[0].State = _state; 605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posState = (position & _posStateMask); 607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[1].Price = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() + 609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!_state.IsCharState(), matchByte, currentByte); 610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[1].MakeAsChar(); 611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 matchPrice = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1(); 613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1(); 614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (matchByte == currentByte) 616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState); 618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (shortRepPrice < _optimum[1].Price) 619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[1].Price = shortRepPrice; 621baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[1].MakeAsShortRep(); 622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]); 626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if(lenEnd < 2) 628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync backRes = _optimum[1].BackPrev; 630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 1; 631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[1].PosPrev = 0; 634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[0].Backs0 = reps[0]; 636baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[0].Backs1 = reps[1]; 637baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[0].Backs2 = reps[2]; 638baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[0].Backs3 = reps[3]; 639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 len = lenEnd; 641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do 642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[len--].Price = kIfinityPrice; 643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (len >= 2); 644baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 645baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < Base.kNumRepDistances; i++) 646baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 repLen = repLens[i]; 648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (repLen < 2) 649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState); 651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do 652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState); 654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Optimal optimum = _optimum[repLen]; 655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (curAndLenPrice < optimum.Price) 656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Price = curAndLenPrice; 658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.PosPrev = 0; 659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.BackPrev = i; 660baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Prev1IsChar = false; 661baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 662baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (--repLen >= 2); 664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0(); 667baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 668baa3858d3f5d128a5c8466b700098109edcad5f2repo sync len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); 669baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (len <= lenMain) 670baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 offs = 0; 672baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (len > _matchDistances[offs]) 673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync offs += 2; 674baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (; ; len++) 675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 676baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 distance = _matchDistances[offs + 1]; 677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState); 678baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Optimal optimum = _optimum[len]; 679baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (curAndLenPrice < optimum.Price) 680baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 681baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Price = curAndLenPrice; 682baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.PosPrev = 0; 683baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.BackPrev = distance + Base.kNumRepDistances; 684baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Prev1IsChar = false; 685baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 686baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (len == _matchDistances[offs]) 687baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 688baa3858d3f5d128a5c8466b700098109edcad5f2repo sync offs += 2; 689baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (offs == numDistancePairs) 690baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 691baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 692baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 694baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 695baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 cur = 0; 696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 697baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (true) 698baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 699baa3858d3f5d128a5c8466b700098109edcad5f2repo sync cur++; 700baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (cur == lenEnd) 701baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return Backward(out backRes, cur); 702baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 newLen; 703baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReadMatchDistances(out newLen, out numDistancePairs); 704baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (newLen >= _numFastBytes) 705baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 706baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _numDistancePairs = numDistancePairs; 707baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _longestMatchLength = newLen; 708baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _longestMatchWasFound = true; 709baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return Backward(out backRes, cur); 710baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 711baa3858d3f5d128a5c8466b700098109edcad5f2repo sync position++; 712baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posPrev = _optimum[cur].PosPrev; 713baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Base.State state; 714baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_optimum[cur].Prev1IsChar) 715baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 716baa3858d3f5d128a5c8466b700098109edcad5f2repo sync posPrev--; 717baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_optimum[cur].Prev2) 718baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 719baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state = _optimum[_optimum[cur].PosPrev2].State; 720baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_optimum[cur].BackPrev2 < Base.kNumRepDistances) 721baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state.UpdateRep(); 722baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 723baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state.UpdateMatch(); 724baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 725baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 726baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state = _optimum[posPrev].State; 727baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state.UpdateChar(); 728baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 729baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 730baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state = _optimum[posPrev].State; 731baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (posPrev == cur - 1) 732baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 733baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_optimum[cur].IsShortRep()) 734baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state.UpdateShortRep(); 735baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 736baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state.UpdateChar(); 737baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 738baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 739baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 740baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 pos; 741baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2) 742baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 743baa3858d3f5d128a5c8466b700098109edcad5f2repo sync posPrev = _optimum[cur].PosPrev2; 744baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pos = _optimum[cur].BackPrev2; 745baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state.UpdateRep(); 746baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 747baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 748baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 749baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pos = _optimum[cur].BackPrev; 750baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos < Base.kNumRepDistances) 751baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state.UpdateRep(); 752baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 753baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state.UpdateMatch(); 754baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 755baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Optimal opt = _optimum[posPrev]; 756baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos < Base.kNumRepDistances) 757baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 758baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos == 0) 759baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 760baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[0] = opt.Backs0; 761baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[1] = opt.Backs1; 762baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[2] = opt.Backs2; 763baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[3] = opt.Backs3; 764baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 765baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (pos == 1) 766baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 767baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[0] = opt.Backs1; 768baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[1] = opt.Backs0; 769baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[2] = opt.Backs2; 770baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[3] = opt.Backs3; 771baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 772baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (pos == 2) 773baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 774baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[0] = opt.Backs2; 775baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[1] = opt.Backs0; 776baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[2] = opt.Backs1; 777baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[3] = opt.Backs3; 778baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 779baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 780baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 781baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[0] = opt.Backs3; 782baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[1] = opt.Backs0; 783baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[2] = opt.Backs1; 784baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[3] = opt.Backs2; 785baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 786baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 787baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 788baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 789baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[0] = (pos - Base.kNumRepDistances); 790baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[1] = opt.Backs0; 791baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[2] = opt.Backs1; 792baa3858d3f5d128a5c8466b700098109edcad5f2repo sync reps[3] = opt.Backs2; 793baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 794baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 795baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[cur].State = state; 796baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[cur].Backs0 = reps[0]; 797baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[cur].Backs1 = reps[1]; 798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[cur].Backs2 = reps[2]; 799baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[cur].Backs3 = reps[3]; 800baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curPrice = _optimum[cur].Price; 801baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync currentByte = _matchFinder.GetIndexByte(0 - 1); 803baa3858d3f5d128a5c8466b700098109edcad5f2repo sync matchByte = _matchFinder.GetIndexByte((Int32)(0 - reps[0] - 1 - 1)); 804baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 805baa3858d3f5d128a5c8466b700098109edcad5f2repo sync posState = (position & _posStateMask); 806baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 807baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curAnd1Price = curPrice + 808baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() + 809baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)). 810baa3858d3f5d128a5c8466b700098109edcad5f2repo sync GetPrice(!state.IsCharState(), matchByte, currentByte); 811baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 812baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Optimal nextOptimum = _optimum[cur + 1]; 813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool nextIsChar = false; 815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (curAnd1Price < nextOptimum.Price) 816baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 817baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextOptimum.Price = curAnd1Price; 818baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextOptimum.PosPrev = cur; 819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextOptimum.MakeAsChar(); 820baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextIsChar = true; 821baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 822baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync matchPrice = curPrice + _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1(); 824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1(); 825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 826baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (matchByte == currentByte && 827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0)) 828baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 829baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState); 830baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (shortRepPrice <= nextOptimum.Price) 831baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 832baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextOptimum.Price = shortRepPrice; 833baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextOptimum.PosPrev = cur; 834baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextOptimum.MakeAsShortRep(); 835baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextIsChar = true; 836baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 837baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 838baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 839baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1; 840baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numAvailableBytesFull = Math.Min(kNumOpts - 1 - cur, numAvailableBytesFull); 841baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numAvailableBytes = numAvailableBytesFull; 842baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 843baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numAvailableBytes < 2) 844baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 845baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numAvailableBytes > _numFastBytes) 846baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numAvailableBytes = _numFastBytes; 847baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!nextIsChar && matchByte != currentByte) 848baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 849baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // try Literal + rep0 850baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 t = Math.Min(numAvailableBytesFull - 1, _numFastBytes); 851baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t); 852baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (lenTest2 >= 2) 853baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 854baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Base.State state2 = state; 855baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state2.UpdateChar(); 856baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posStateNext = (position + 1) & _posStateMask; 857baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 nextRepMatchPrice = curAnd1Price + 858baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1() + 859baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRep[state2.Index].GetPrice1(); 860baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 861baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 offset = cur + 1 + lenTest2; 862baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (lenEnd < offset) 863baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[++lenEnd].Price = kIfinityPrice; 864baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( 865baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 0, lenTest2, state2, posStateNext); 866baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Optimal optimum = _optimum[offset]; 867baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (curAndLenPrice < optimum.Price) 868baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 869baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Price = curAndLenPrice; 870baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.PosPrev = cur + 1; 871baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.BackPrev = 0; 872baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Prev1IsChar = true; 873baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Prev2 = false; 874baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 875baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 876baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 877baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 878baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 879baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 startLen = 2; // speed optimization 880baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 881baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++) 882baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 883baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes); 884baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (lenTest < 2) 885baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 886baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenTestTemp = lenTest; 887baa3858d3f5d128a5c8466b700098109edcad5f2repo sync do 888baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 889baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (lenEnd < cur + lenTest) 890baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[++lenEnd].Price = kIfinityPrice; 891baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState); 892baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Optimal optimum = _optimum[cur + lenTest]; 893baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (curAndLenPrice < optimum.Price) 894baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 895baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Price = curAndLenPrice; 896baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.PosPrev = cur; 897baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.BackPrev = repIndex; 898baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Prev1IsChar = false; 899baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 900baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 901baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while(--lenTest >= 2); 902baa3858d3f5d128a5c8466b700098109edcad5f2repo sync lenTest = lenTestTemp; 903baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 904baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (repIndex == 0) 905baa3858d3f5d128a5c8466b700098109edcad5f2repo sync startLen = lenTest + 1; 906baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 907baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // if (_maxMode) 908baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (lenTest < numAvailableBytesFull) 909baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 910baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes); 911baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, reps[repIndex], t); 912baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (lenTest2 >= 2) 913baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 914baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Base.State state2 = state; 915baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state2.UpdateRep(); 916baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posStateNext = (position + lenTest) & _posStateMask; 917baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curAndLenCharPrice = 918baa3858d3f5d128a5c8466b700098109edcad5f2repo sync repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) + 919baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() + 920baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _literalEncoder.GetSubCoder(position + lenTest, 921baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)).GetPrice(true, 922baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.GetIndexByte((Int32)((Int32)lenTest - 1 - (Int32)(reps[repIndex] + 1))), 923baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.GetIndexByte((Int32)lenTest - 1)); 924baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state2.UpdateChar(); 925baa3858d3f5d128a5c8466b700098109edcad5f2repo sync posStateNext = (position + lenTest + 1) & _posStateMask; 926baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1(); 927baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1(); 928baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 929baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // for(; lenTest2 >= 2; lenTest2--) 930baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 931baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 offset = lenTest + 1 + lenTest2; 932baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while(lenEnd < cur + offset) 933baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[++lenEnd].Price = kIfinityPrice; 934baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); 935baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Optimal optimum = _optimum[cur + offset]; 936baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (curAndLenPrice < optimum.Price) 937baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 938baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Price = curAndLenPrice; 939baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.PosPrev = cur + lenTest + 1; 940baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.BackPrev = 0; 941baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Prev1IsChar = true; 942baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Prev2 = true; 943baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.PosPrev2 = cur; 944baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.BackPrev2 = repIndex; 945baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 946baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 947baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 948baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 949baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 950baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 951baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (newLen > numAvailableBytes) 952baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 953baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newLen = numAvailableBytes; 954baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ; 955baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchDistances[numDistancePairs] = newLen; 956baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numDistancePairs += 2; 957baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 958baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (newLen >= startLen) 959baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 960baa3858d3f5d128a5c8466b700098109edcad5f2repo sync normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0(); 961baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (lenEnd < cur + newLen) 962baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[++lenEnd].Price = kIfinityPrice; 963baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 964baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 offs = 0; 965baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (startLen > _matchDistances[offs]) 966baa3858d3f5d128a5c8466b700098109edcad5f2repo sync offs += 2; 967baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 968baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 lenTest = startLen; ; lenTest++) 969baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 970baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curBack = _matchDistances[offs + 1]; 971baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState); 972baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Optimal optimum = _optimum[cur + lenTest]; 973baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (curAndLenPrice < optimum.Price) 974baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 975baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Price = curAndLenPrice; 976baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.PosPrev = cur; 977baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.BackPrev = curBack + Base.kNumRepDistances; 978baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Prev1IsChar = false; 979baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 980baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 981baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (lenTest == _matchDistances[offs]) 982baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 983baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (lenTest < numAvailableBytesFull) 984baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 985baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes); 986baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, curBack, t); 987baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (lenTest2 >= 2) 988baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 989baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Base.State state2 = state; 990baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state2.UpdateMatch(); 991baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posStateNext = (position + lenTest) & _posStateMask; 992baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curAndLenCharPrice = curAndLenPrice + 993baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() + 994baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _literalEncoder.GetSubCoder(position + lenTest, 995baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)). 996baa3858d3f5d128a5c8466b700098109edcad5f2repo sync GetPrice(true, 997baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.GetIndexByte((Int32)lenTest - (Int32)(curBack + 1) - 1), 998baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.GetIndexByte((Int32)lenTest - 1)); 999baa3858d3f5d128a5c8466b700098109edcad5f2repo sync state2.UpdateChar(); 1000baa3858d3f5d128a5c8466b700098109edcad5f2repo sync posStateNext = (position + lenTest + 1) & _posStateMask; 1001baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1(); 1002baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1(); 1003baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1004baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 offset = lenTest + 1 + lenTest2; 1005baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (lenEnd < cur + offset) 1006baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _optimum[++lenEnd].Price = kIfinityPrice; 1007baa3858d3f5d128a5c8466b700098109edcad5f2repo sync curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); 1008baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum = _optimum[cur + offset]; 1009baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (curAndLenPrice < optimum.Price) 1010baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1011baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Price = curAndLenPrice; 1012baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.PosPrev = cur + lenTest + 1; 1013baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.BackPrev = 0; 1014baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Prev1IsChar = true; 1015baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.Prev2 = true; 1016baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.PosPrev2 = cur; 1017baa3858d3f5d128a5c8466b700098109edcad5f2repo sync optimum.BackPrev2 = curBack + Base.kNumRepDistances; 1018baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1019baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1020baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1021baa3858d3f5d128a5c8466b700098109edcad5f2repo sync offs += 2; 1022baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (offs == numDistancePairs) 1023baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1024baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1025baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1026baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1027baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1028baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1029baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1030baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool ChangePair(UInt32 smallDist, UInt32 bigDist) 1031baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1032baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const int kDif = 7; 1033baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (smallDist < ((UInt32)(1) << (32 - kDif)) && bigDist >= (smallDist << kDif)); 1034baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1035baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1036baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void WriteEndMarker(UInt32 posState) 1037baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1038baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_writeEndMark) 1039baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 1040baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1041baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 1); 1042baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRep[_state.Index].Encode(_rangeEncoder, 0); 1043baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _state.UpdateMatch(); 1044baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 len = Base.kMatchMinLen; 1045baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); 1046baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posSlot = (1 << Base.kNumPosSlotBits) - 1; 1047baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenToPosState = Base.GetLenToPosState(len); 1048baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot); 1049baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int footerBits = 30; 1050baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posReduced = (((UInt32)1) << footerBits) - 1; 1051baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); 1052baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); 1053baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1054baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1055baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void Flush(UInt32 nowPos) 1056baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1057baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReleaseMFStream(); 1058baa3858d3f5d128a5c8466b700098109edcad5f2repo sync WriteEndMarker(nowPos & _posStateMask); 1059baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeEncoder.FlushData(); 1060baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeEncoder.FlushStream(); 1061baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1062baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1063baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void CodeOneBlock(out Int64 inSize, out Int64 outSize, out bool finished) 1064baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1065baa3858d3f5d128a5c8466b700098109edcad5f2repo sync inSize = 0; 1066baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outSize = 0; 1067baa3858d3f5d128a5c8466b700098109edcad5f2repo sync finished = true; 1068baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1069baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_inStream != null) 1070baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1071baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.SetStream(_inStream); 1072baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.Init(); 1073baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _needReleaseMFStream = true; 1074baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _inStream = null; 1075baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_trainSize > 0) 1076baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.Skip(_trainSize); 1077baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1078baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1079baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_finished) 1080baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 1081baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _finished = true; 1082baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1083baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1084baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int64 progressPosValuePrev = nowPos64; 1085baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (nowPos64 == 0) 1086baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1087baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_matchFinder.GetNumAvailableBytes() == 0) 1088baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1089baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Flush((UInt32)nowPos64); 1090baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 1091baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1092baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 len, numDistancePairs; // it's not used 1093baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReadMatchDistances(out len, out numDistancePairs); 1094baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posState = (UInt32)(nowPos64) & _posStateMask; 1095baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 0); 1096baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _state.UpdateChar(); 1097baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset)); 1098baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _literalEncoder.GetSubCoder((UInt32)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte); 1099baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _previousByte = curByte; 1100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _additionalOffset--; 1101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nowPos64++; 1102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_matchFinder.GetNumAvailableBytes() == 0) 1104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Flush((UInt32)nowPos64); 1106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 1107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (true) 1109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 pos; 1111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 len = GetOptimum((UInt32)nowPos64, out pos); 1112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posState = ((UInt32)nowPos64) & _posStateMask; 1114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 complexState = (_state.Index << Base.kNumPosStatesBitsMax) + posState; 1115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (len == 1 && pos == 0xFFFFFFFF) 1116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isMatch[complexState].Encode(_rangeEncoder, 0); 1118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset)); 1119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((UInt32)nowPos64, _previousByte); 1120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_state.IsCharState()) 1121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - _additionalOffset)); 1123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte); 1124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subCoder.Encode(_rangeEncoder, curByte); 1127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _previousByte = curByte; 1128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _state.UpdateChar(); 1129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isMatch[complexState].Encode(_rangeEncoder, 1); 1133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos < Base.kNumRepDistances) 1134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRep[_state.Index].Encode(_rangeEncoder, 1); 1136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos == 0) 1137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRepG0[_state.Index].Encode(_rangeEncoder, 0); 1139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (len == 1) 1140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRep0Long[complexState].Encode(_rangeEncoder, 0); 1141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRep0Long[complexState].Encode(_rangeEncoder, 1); 1143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRepG0[_state.Index].Encode(_rangeEncoder, 1); 1147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos == 1) 1148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRepG1[_state.Index].Encode(_rangeEncoder, 0); 1149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRepG1[_state.Index].Encode(_rangeEncoder, 1); 1152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRepG2[_state.Index].Encode(_rangeEncoder, pos - 2); 1153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (len == 1) 1156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _state.UpdateShortRep(); 1157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); 1160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _state.UpdateRep(); 1161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 distance = _repDistances[pos]; 1163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos != 0) 1164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 i = pos; i >= 1; i--) 1166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _repDistances[i] = _repDistances[i - 1]; 1167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _repDistances[0] = distance; 1168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _isRep[_state.Index].Encode(_rangeEncoder, 0); 1173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _state.UpdateMatch(); 1174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); 1175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pos -= Base.kNumRepDistances; 1176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posSlot = GetPosSlot(pos); 1177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 lenToPosState = Base.GetLenToPosState(len); 1178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot); 1179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (posSlot >= Base.kStartPosModelIndex) 1181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int footerBits = (int)((posSlot >> 1) - 1); 1183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits); 1184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posReduced = pos - baseVal; 1185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (posSlot < Base.kEndPosModelIndex) 1187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitTreeEncoder.ReverseEncode(_posEncoders, 1188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced); 1189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); 1192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); 1193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _alignPriceCount++; 1194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 distance = pos; 1197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 i = Base.kNumRepDistances - 1; i >= 1; i--) 1198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _repDistances[i] = _repDistances[i - 1]; 1199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _repDistances[0] = distance; 1200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchPriceCount++; 1201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _previousByte = _matchFinder.GetIndexByte((Int32)(len - 1 - _additionalOffset)); 1203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _additionalOffset -= len; 1205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nowPos64 += len; 1206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_additionalOffset == 0) 1207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // if (!_fastMode) 1209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_matchPriceCount >= (1 << 7)) 1210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync FillDistancesPrices(); 1211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_alignPriceCount >= Base.kAlignTableSize) 1212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync FillAlignPrices(); 1213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync inSize = nowPos64; 1214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outSize = _rangeEncoder.GetProcessedSizeAdd(); 1215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_matchFinder.GetNumAvailableBytes() == 0) 1216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Flush((UInt32)nowPos64); 1218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 1219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (nowPos64 - progressPosValuePrev >= (1 << 12)) 1222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _finished = false; 1224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync finished = false; 1225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 1226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void ReleaseMFStream() 1232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_matchFinder != null && _needReleaseMFStream) 1234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder.ReleaseStream(); 1236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _needReleaseMFStream = false; 1237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void SetOutStream(System.IO.Stream outStream) { _rangeEncoder.SetStream(outStream); } 1241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void ReleaseOutStream() { _rangeEncoder.ReleaseStream(); } 1242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void ReleaseStreams() 1244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReleaseMFStream(); 1246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReleaseOutStream(); 1247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void SetStreams(System.IO.Stream inStream, System.IO.Stream outStream, 1250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int64 inSize, Int64 outSize) 1251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _inStream = inStream; 1253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _finished = false; 1254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Create(); 1255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetOutStream(outStream); 1256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Init(); 1257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // if (!_fastMode) 1259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync FillDistancesPrices(); 1261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync FillAlignPrices(); 1262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen); 1265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _lenEncoder.UpdateTables((UInt32)1 << _posStateBits); 1266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen); 1267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _repMatchLenEncoder.UpdateTables((UInt32)1 << _posStateBits); 1268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nowPos64 = 0; 1270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void Code(System.IO.Stream inStream, System.IO.Stream outStream, 1274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int64 inSize, Int64 outSize, ICodeProgress progress) 1275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _needReleaseMFStream = false; 1277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync try 1278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetStreams(inStream, outStream, inSize, outSize); 1280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (true) 1281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int64 processedInSize; 1283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int64 processedOutSize; 1284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool finished; 1285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CodeOneBlock(out processedInSize, out processedOutSize, out finished); 1286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (finished) 1287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 1288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (progress != null) 1289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync progress.SetProgress(processedInSize, processedOutSize); 1291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync finally 1295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReleaseStreams(); 1297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const int kPropSize = 5; 1301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte[] properties = new Byte[kPropSize]; 1302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void WriteCoderProperties(System.IO.Stream outStream) 1304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync properties[0] = (Byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits); 1306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < 4; i++) 1307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync properties[1 + i] = (Byte)((_dictionarySize >> (8 * i)) & 0xFF); 1308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outStream.Write(properties, 0, kPropSize); 1309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32[] tempPrices = new UInt32[Base.kNumFullDistances]; 1312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 _matchPriceCount; 1313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void FillDistancesPrices() 1315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++) 1317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posSlot = GetPosSlot(i); 1319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int footerBits = (int)((posSlot >> 1) - 1); 1320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits); 1321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders, 1322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync baseVal - posSlot - 1, footerBits, i - baseVal); 1323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++) 1326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 posSlot; 1328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RangeCoder.BitTreeEncoder encoder = _posSlotEncoder[lenToPosState]; 1329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 st = (lenToPosState << Base.kNumPosSlotBits); 1331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (posSlot = 0; posSlot < _distTableSize; posSlot++) 1332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot); 1333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++) 1334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << RangeCoder.BitEncoder.kNumBitPriceShiftBits); 1335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 st2 = lenToPosState * Base.kNumFullDistances; 1337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 1338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < Base.kStartPosModelIndex; i++) 1339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _distancesPrices[st2 + i] = _posSlotPrices[st + i]; 1340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (; i < Base.kNumFullDistances; i++) 1341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i]; 1342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchPriceCount = 0; 1344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void FillAlignPrices() 1347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 i = 0; i < Base.kAlignTableSize; i++) 1349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i); 1350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _alignPriceCount = 0; 1351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync static string[] kMatchFinderIDs = 1355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync "BT2", 1357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync "BT4", 1358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync }; 1359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync static int FindMatchFinder(string s) 1361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int m = 0; m < kMatchFinderIDs.Length; m++) 1363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (s == kMatchFinderIDs[m]) 1364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return m; 1365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return -1; 1366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void SetCoderProperties(CoderPropID[] propIDs, object[] properties) 1369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 i = 0; i < properties.Length; i++) 1371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync object prop = properties[i]; 1373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync switch (propIDs[i]) 1374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case CoderPropID.NumFastBytes: 1376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!(prop is Int32)) 1378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int32 numFastBytes = (Int32)prop; 1380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen) 1381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _numFastBytes = (UInt32)numFastBytes; 1383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case CoderPropID.Algorithm: 1386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 1388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!(prop is Int32)) 1389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int32 maximize = (Int32)prop; 1391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _fastMode = (maximize == 0); 1392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _maxMode = (maximize >= 2); 1393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 1394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case CoderPropID.MatchFinder: 1397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!(prop is String)) 1399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync EMatchFinderType matchFinderIndexPrev = _matchFinderType; 1401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int m = FindMatchFinder(((string)prop).ToUpper()); 1402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (m < 0) 1403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinderType = (EMatchFinderType)m; 1405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType) 1406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _dictionarySizePrev = 0xFFFFFFFF; 1408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _matchFinder = null; 1409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case CoderPropID.DictionarySize: 1413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const int kDicLogSizeMaxCompress = 30; 1415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!(prop is Int32)) 1416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); ; 1417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int32 dictionarySize = (Int32)prop; 1418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (dictionarySize < (UInt32)(1 << Base.kDicLogSizeMin) || 1419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dictionarySize > (UInt32)(1 << kDicLogSizeMaxCompress)) 1420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _dictionarySize = (UInt32)dictionarySize; 1422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int dicLogSize; 1423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++) 1424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (dictionarySize <= ((UInt32)(1) << dicLogSize)) 1425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _distTableSize = (UInt32)dicLogSize * 2; 1427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case CoderPropID.PosStateBits: 1430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!(prop is Int32)) 1432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int32 v = (Int32)prop; 1434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (v < 0 || v > (UInt32)Base.kNumPosStatesBitsEncodingMax) 1435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posStateBits = (int)v; 1437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _posStateMask = (((UInt32)1) << (int)_posStateBits) - 1; 1438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case CoderPropID.LitPosBits: 1441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!(prop is Int32)) 1443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int32 v = (Int32)prop; 1445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (v < 0 || v > (UInt32)Base.kNumLitPosStatesBitsEncodingMax) 1446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _numLiteralPosStateBits = (int)v; 1448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case CoderPropID.LitContextBits: 1451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!(prop is Int32)) 1453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int32 v = (Int32)prop; 1455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (v < 0 || v > (UInt32)Base.kNumLitContextBitsMax) 1456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); ; 1457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _numLiteralContextBits = (int)v; 1458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case CoderPropID.EndMarker: 1461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!(prop is Boolean)) 1463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetWriteEndMarkerMode((Boolean)prop); 1465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync default: 1468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw new InvalidParamException(); 1469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint _trainSize = 0; 1474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void SetTrainSize(uint trainSize) 1475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _trainSize = trainSize; 1477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1481