1370b324cSopenharmony_cipackage SevenZip.Compression.LZMA; 2370b324cSopenharmony_ci 3370b324cSopenharmony_ciimport SevenZip.Compression.RangeCoder.BitTreeEncoder; 4370b324cSopenharmony_ciimport SevenZip.Compression.LZMA.Base; 5370b324cSopenharmony_ciimport SevenZip.Compression.LZ.BinTree; 6370b324cSopenharmony_ciimport SevenZip.ICodeProgress; 7370b324cSopenharmony_ciimport java.io.IOException; 8370b324cSopenharmony_ci 9370b324cSopenharmony_cipublic class Encoder 10370b324cSopenharmony_ci{ 11370b324cSopenharmony_ci public static final int EMatchFinderTypeBT2 = 0; 12370b324cSopenharmony_ci public static final int EMatchFinderTypeBT4 = 1; 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci 15370b324cSopenharmony_ci 16370b324cSopenharmony_ci 17370b324cSopenharmony_ci static final int kIfinityPrice = 0xFFFFFFF; 18370b324cSopenharmony_ci 19370b324cSopenharmony_ci static byte[] g_FastPos = new byte[1 << 11]; 20370b324cSopenharmony_ci 21370b324cSopenharmony_ci static 22370b324cSopenharmony_ci { 23370b324cSopenharmony_ci int kFastSlots = 22; 24370b324cSopenharmony_ci int c = 2; 25370b324cSopenharmony_ci g_FastPos[0] = 0; 26370b324cSopenharmony_ci g_FastPos[1] = 1; 27370b324cSopenharmony_ci for (int slotFast = 2; slotFast < kFastSlots; slotFast++) 28370b324cSopenharmony_ci { 29370b324cSopenharmony_ci int k = (1 << ((slotFast >> 1) - 1)); 30370b324cSopenharmony_ci for (int j = 0; j < k; j++, c++) 31370b324cSopenharmony_ci g_FastPos[c] = (byte)slotFast; 32370b324cSopenharmony_ci } 33370b324cSopenharmony_ci } 34370b324cSopenharmony_ci 35370b324cSopenharmony_ci static int GetPosSlot(int pos) 36370b324cSopenharmony_ci { 37370b324cSopenharmony_ci if (pos < (1 << 11)) 38370b324cSopenharmony_ci return g_FastPos[pos]; 39370b324cSopenharmony_ci if (pos < (1 << 21)) 40370b324cSopenharmony_ci return (g_FastPos[pos >> 10] + 20); 41370b324cSopenharmony_ci return (g_FastPos[pos >> 20] + 40); 42370b324cSopenharmony_ci } 43370b324cSopenharmony_ci 44370b324cSopenharmony_ci static int GetPosSlot2(int pos) 45370b324cSopenharmony_ci { 46370b324cSopenharmony_ci if (pos < (1 << 17)) 47370b324cSopenharmony_ci return (g_FastPos[pos >> 6] + 12); 48370b324cSopenharmony_ci if (pos < (1 << 27)) 49370b324cSopenharmony_ci return (g_FastPos[pos >> 16] + 32); 50370b324cSopenharmony_ci return (g_FastPos[pos >> 26] + 52); 51370b324cSopenharmony_ci } 52370b324cSopenharmony_ci 53370b324cSopenharmony_ci int _state = Base.StateInit(); 54370b324cSopenharmony_ci byte _previousByte; 55370b324cSopenharmony_ci int[] _repDistances = new int[Base.kNumRepDistances]; 56370b324cSopenharmony_ci 57370b324cSopenharmony_ci void BaseInit() 58370b324cSopenharmony_ci { 59370b324cSopenharmony_ci _state = Base.StateInit(); 60370b324cSopenharmony_ci _previousByte = 0; 61370b324cSopenharmony_ci for (int i = 0; i < Base.kNumRepDistances; i++) 62370b324cSopenharmony_ci _repDistances[i] = 0; 63370b324cSopenharmony_ci } 64370b324cSopenharmony_ci 65370b324cSopenharmony_ci static final int kDefaultDictionaryLogSize = 22; 66370b324cSopenharmony_ci static final int kNumFastBytesDefault = 0x20; 67370b324cSopenharmony_ci 68370b324cSopenharmony_ci class LiteralEncoder 69370b324cSopenharmony_ci { 70370b324cSopenharmony_ci class Encoder2 71370b324cSopenharmony_ci { 72370b324cSopenharmony_ci short[] m_Encoders = new short[0x300]; 73370b324cSopenharmony_ci 74370b324cSopenharmony_ci public void Init() { SevenZip.Compression.RangeCoder.Encoder.InitBitModels(m_Encoders); } 75370b324cSopenharmony_ci 76370b324cSopenharmony_ci 77370b324cSopenharmony_ci 78370b324cSopenharmony_ci public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte symbol) throws IOException 79370b324cSopenharmony_ci { 80370b324cSopenharmony_ci int context = 1; 81370b324cSopenharmony_ci for (int i = 7; i >= 0; i--) 82370b324cSopenharmony_ci { 83370b324cSopenharmony_ci int bit = ((symbol >> i) & 1); 84370b324cSopenharmony_ci rangeEncoder.Encode(m_Encoders, context, bit); 85370b324cSopenharmony_ci context = (context << 1) | bit; 86370b324cSopenharmony_ci } 87370b324cSopenharmony_ci } 88370b324cSopenharmony_ci 89370b324cSopenharmony_ci public void EncodeMatched(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol) throws IOException 90370b324cSopenharmony_ci { 91370b324cSopenharmony_ci int context = 1; 92370b324cSopenharmony_ci boolean same = true; 93370b324cSopenharmony_ci for (int i = 7; i >= 0; i--) 94370b324cSopenharmony_ci { 95370b324cSopenharmony_ci int bit = ((symbol >> i) & 1); 96370b324cSopenharmony_ci int state = context; 97370b324cSopenharmony_ci if (same) 98370b324cSopenharmony_ci { 99370b324cSopenharmony_ci int matchBit = ((matchByte >> i) & 1); 100370b324cSopenharmony_ci state += ((1 + matchBit) << 8); 101370b324cSopenharmony_ci same = (matchBit == bit); 102370b324cSopenharmony_ci } 103370b324cSopenharmony_ci rangeEncoder.Encode(m_Encoders, state, bit); 104370b324cSopenharmony_ci context = (context << 1) | bit; 105370b324cSopenharmony_ci } 106370b324cSopenharmony_ci } 107370b324cSopenharmony_ci 108370b324cSopenharmony_ci public int GetPrice(boolean matchMode, byte matchByte, byte symbol) 109370b324cSopenharmony_ci { 110370b324cSopenharmony_ci int price = 0; 111370b324cSopenharmony_ci int context = 1; 112370b324cSopenharmony_ci int i = 7; 113370b324cSopenharmony_ci if (matchMode) 114370b324cSopenharmony_ci { 115370b324cSopenharmony_ci for (; i >= 0; i--) 116370b324cSopenharmony_ci { 117370b324cSopenharmony_ci int matchBit = (matchByte >> i) & 1; 118370b324cSopenharmony_ci int bit = (symbol >> i) & 1; 119370b324cSopenharmony_ci price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[((1 + matchBit) << 8) + context], bit); 120370b324cSopenharmony_ci context = (context << 1) | bit; 121370b324cSopenharmony_ci if (matchBit != bit) 122370b324cSopenharmony_ci { 123370b324cSopenharmony_ci i--; 124370b324cSopenharmony_ci break; 125370b324cSopenharmony_ci } 126370b324cSopenharmony_ci } 127370b324cSopenharmony_ci } 128370b324cSopenharmony_ci for (; i >= 0; i--) 129370b324cSopenharmony_ci { 130370b324cSopenharmony_ci int bit = (symbol >> i) & 1; 131370b324cSopenharmony_ci price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[context], bit); 132370b324cSopenharmony_ci context = (context << 1) | bit; 133370b324cSopenharmony_ci } 134370b324cSopenharmony_ci return price; 135370b324cSopenharmony_ci } 136370b324cSopenharmony_ci } 137370b324cSopenharmony_ci 138370b324cSopenharmony_ci Encoder2[] m_Coders; 139370b324cSopenharmony_ci int m_NumPrevBits; 140370b324cSopenharmony_ci int m_NumPosBits; 141370b324cSopenharmony_ci int m_PosMask; 142370b324cSopenharmony_ci 143370b324cSopenharmony_ci public void Create(int numPosBits, int numPrevBits) 144370b324cSopenharmony_ci { 145370b324cSopenharmony_ci if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits) 146370b324cSopenharmony_ci return; 147370b324cSopenharmony_ci m_NumPosBits = numPosBits; 148370b324cSopenharmony_ci m_PosMask = (1 << numPosBits) - 1; 149370b324cSopenharmony_ci m_NumPrevBits = numPrevBits; 150370b324cSopenharmony_ci int numStates = 1 << (m_NumPrevBits + m_NumPosBits); 151370b324cSopenharmony_ci m_Coders = new Encoder2[numStates]; 152370b324cSopenharmony_ci for (int i = 0; i < numStates; i++) 153370b324cSopenharmony_ci m_Coders[i] = new Encoder2(); 154370b324cSopenharmony_ci } 155370b324cSopenharmony_ci 156370b324cSopenharmony_ci public void Init() 157370b324cSopenharmony_ci { 158370b324cSopenharmony_ci int numStates = 1 << (m_NumPrevBits + m_NumPosBits); 159370b324cSopenharmony_ci for (int i = 0; i < numStates; i++) 160370b324cSopenharmony_ci m_Coders[i].Init(); 161370b324cSopenharmony_ci } 162370b324cSopenharmony_ci 163370b324cSopenharmony_ci public Encoder2 GetSubCoder(int pos, byte prevByte) 164370b324cSopenharmony_ci { return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))]; } 165370b324cSopenharmony_ci } 166370b324cSopenharmony_ci 167370b324cSopenharmony_ci class LenEncoder 168370b324cSopenharmony_ci { 169370b324cSopenharmony_ci short[] _choice = new short[2]; 170370b324cSopenharmony_ci BitTreeEncoder[] _lowCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax]; 171370b324cSopenharmony_ci BitTreeEncoder[] _midCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax]; 172370b324cSopenharmony_ci BitTreeEncoder _highCoder = new BitTreeEncoder(Base.kNumHighLenBits); 173370b324cSopenharmony_ci 174370b324cSopenharmony_ci 175370b324cSopenharmony_ci public LenEncoder() 176370b324cSopenharmony_ci { 177370b324cSopenharmony_ci for (int posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++) 178370b324cSopenharmony_ci { 179370b324cSopenharmony_ci _lowCoder[posState] = new BitTreeEncoder(Base.kNumLowLenBits); 180370b324cSopenharmony_ci _midCoder[posState] = new BitTreeEncoder(Base.kNumMidLenBits); 181370b324cSopenharmony_ci } 182370b324cSopenharmony_ci } 183370b324cSopenharmony_ci 184370b324cSopenharmony_ci public void Init(int numPosStates) 185370b324cSopenharmony_ci { 186370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_choice); 187370b324cSopenharmony_ci 188370b324cSopenharmony_ci for (int posState = 0; posState < numPosStates; posState++) 189370b324cSopenharmony_ci { 190370b324cSopenharmony_ci _lowCoder[posState].Init(); 191370b324cSopenharmony_ci _midCoder[posState].Init(); 192370b324cSopenharmony_ci } 193370b324cSopenharmony_ci _highCoder.Init(); 194370b324cSopenharmony_ci } 195370b324cSopenharmony_ci 196370b324cSopenharmony_ci public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException 197370b324cSopenharmony_ci { 198370b324cSopenharmony_ci if (symbol < Base.kNumLowLenSymbols) 199370b324cSopenharmony_ci { 200370b324cSopenharmony_ci rangeEncoder.Encode(_choice, 0, 0); 201370b324cSopenharmony_ci _lowCoder[posState].Encode(rangeEncoder, symbol); 202370b324cSopenharmony_ci } 203370b324cSopenharmony_ci else 204370b324cSopenharmony_ci { 205370b324cSopenharmony_ci symbol -= Base.kNumLowLenSymbols; 206370b324cSopenharmony_ci rangeEncoder.Encode(_choice, 0, 1); 207370b324cSopenharmony_ci if (symbol < Base.kNumMidLenSymbols) 208370b324cSopenharmony_ci { 209370b324cSopenharmony_ci rangeEncoder.Encode(_choice, 1, 0); 210370b324cSopenharmony_ci _midCoder[posState].Encode(rangeEncoder, symbol); 211370b324cSopenharmony_ci } 212370b324cSopenharmony_ci else 213370b324cSopenharmony_ci { 214370b324cSopenharmony_ci rangeEncoder.Encode(_choice, 1, 1); 215370b324cSopenharmony_ci _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols); 216370b324cSopenharmony_ci } 217370b324cSopenharmony_ci } 218370b324cSopenharmony_ci } 219370b324cSopenharmony_ci 220370b324cSopenharmony_ci public void SetPrices(int posState, int numSymbols, int[] prices, int st) 221370b324cSopenharmony_ci { 222370b324cSopenharmony_ci int a0 = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[0]); 223370b324cSopenharmony_ci int a1 = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[0]); 224370b324cSopenharmony_ci int b0 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[1]); 225370b324cSopenharmony_ci int b1 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[1]); 226370b324cSopenharmony_ci int i = 0; 227370b324cSopenharmony_ci for (i = 0; i < Base.kNumLowLenSymbols; i++) 228370b324cSopenharmony_ci { 229370b324cSopenharmony_ci if (i >= numSymbols) 230370b324cSopenharmony_ci return; 231370b324cSopenharmony_ci prices[st + i] = a0 + _lowCoder[posState].GetPrice(i); 232370b324cSopenharmony_ci } 233370b324cSopenharmony_ci for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++) 234370b324cSopenharmony_ci { 235370b324cSopenharmony_ci if (i >= numSymbols) 236370b324cSopenharmony_ci return; 237370b324cSopenharmony_ci prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols); 238370b324cSopenharmony_ci } 239370b324cSopenharmony_ci for (; i < numSymbols; i++) 240370b324cSopenharmony_ci prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols); 241370b324cSopenharmony_ci } 242370b324cSopenharmony_ci }; 243370b324cSopenharmony_ci 244370b324cSopenharmony_ci public static final int kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; 245370b324cSopenharmony_ci 246370b324cSopenharmony_ci class LenPriceTableEncoder extends LenEncoder 247370b324cSopenharmony_ci { 248370b324cSopenharmony_ci int[] _prices = new int[Base.kNumLenSymbols<<Base.kNumPosStatesBitsEncodingMax]; 249370b324cSopenharmony_ci int _tableSize; 250370b324cSopenharmony_ci int[] _counters = new int[Base.kNumPosStatesEncodingMax]; 251370b324cSopenharmony_ci 252370b324cSopenharmony_ci public void SetTableSize(int tableSize) { _tableSize = tableSize; } 253370b324cSopenharmony_ci 254370b324cSopenharmony_ci public int GetPrice(int symbol, int posState) 255370b324cSopenharmony_ci { 256370b324cSopenharmony_ci return _prices[posState * Base.kNumLenSymbols + symbol]; 257370b324cSopenharmony_ci } 258370b324cSopenharmony_ci 259370b324cSopenharmony_ci void UpdateTable(int posState) 260370b324cSopenharmony_ci { 261370b324cSopenharmony_ci SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols); 262370b324cSopenharmony_ci _counters[posState] = _tableSize; 263370b324cSopenharmony_ci } 264370b324cSopenharmony_ci 265370b324cSopenharmony_ci public void UpdateTables(int numPosStates) 266370b324cSopenharmony_ci { 267370b324cSopenharmony_ci for (int posState = 0; posState < numPosStates; posState++) 268370b324cSopenharmony_ci UpdateTable(posState); 269370b324cSopenharmony_ci } 270370b324cSopenharmony_ci 271370b324cSopenharmony_ci public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException 272370b324cSopenharmony_ci { 273370b324cSopenharmony_ci super.Encode(rangeEncoder, symbol, posState); 274370b324cSopenharmony_ci if (--_counters[posState] == 0) 275370b324cSopenharmony_ci UpdateTable(posState); 276370b324cSopenharmony_ci } 277370b324cSopenharmony_ci } 278370b324cSopenharmony_ci 279370b324cSopenharmony_ci static final int kNumOpts = 1 << 12; 280370b324cSopenharmony_ci class Optimal 281370b324cSopenharmony_ci { 282370b324cSopenharmony_ci public int State; 283370b324cSopenharmony_ci 284370b324cSopenharmony_ci public boolean Prev1IsChar; 285370b324cSopenharmony_ci public boolean Prev2; 286370b324cSopenharmony_ci 287370b324cSopenharmony_ci public int PosPrev2; 288370b324cSopenharmony_ci public int BackPrev2; 289370b324cSopenharmony_ci 290370b324cSopenharmony_ci public int Price; 291370b324cSopenharmony_ci public int PosPrev; 292370b324cSopenharmony_ci public int BackPrev; 293370b324cSopenharmony_ci 294370b324cSopenharmony_ci public int Backs0; 295370b324cSopenharmony_ci public int Backs1; 296370b324cSopenharmony_ci public int Backs2; 297370b324cSopenharmony_ci public int Backs3; 298370b324cSopenharmony_ci 299370b324cSopenharmony_ci public void MakeAsChar() { BackPrev = -1; Prev1IsChar = false; } 300370b324cSopenharmony_ci public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; } 301370b324cSopenharmony_ci public boolean IsShortRep() { return (BackPrev == 0); } 302370b324cSopenharmony_ci }; 303370b324cSopenharmony_ci Optimal[] _optimum = new Optimal[kNumOpts]; 304370b324cSopenharmony_ci SevenZip.Compression.LZ.BinTree _matchFinder = null; 305370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder _rangeEncoder = new SevenZip.Compression.RangeCoder.Encoder(); 306370b324cSopenharmony_ci 307370b324cSopenharmony_ci short[] _isMatch = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax]; 308370b324cSopenharmony_ci short[] _isRep = new short[Base.kNumStates]; 309370b324cSopenharmony_ci short[] _isRepG0 = new short[Base.kNumStates]; 310370b324cSopenharmony_ci short[] _isRepG1 = new short[Base.kNumStates]; 311370b324cSopenharmony_ci short[] _isRepG2 = new short[Base.kNumStates]; 312370b324cSopenharmony_ci short[] _isRep0Long = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax]; 313370b324cSopenharmony_ci 314370b324cSopenharmony_ci BitTreeEncoder[] _posSlotEncoder = new BitTreeEncoder[Base.kNumLenToPosStates]; // kNumPosSlotBits 315370b324cSopenharmony_ci 316370b324cSopenharmony_ci short[] _posEncoders = new short[Base.kNumFullDistances-Base.kEndPosModelIndex]; 317370b324cSopenharmony_ci BitTreeEncoder _posAlignEncoder = new BitTreeEncoder(Base.kNumAlignBits); 318370b324cSopenharmony_ci 319370b324cSopenharmony_ci LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder(); 320370b324cSopenharmony_ci LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder(); 321370b324cSopenharmony_ci 322370b324cSopenharmony_ci LiteralEncoder _literalEncoder = new LiteralEncoder(); 323370b324cSopenharmony_ci 324370b324cSopenharmony_ci int[] _matchDistances = new int[Base.kMatchMaxLen*2+2]; 325370b324cSopenharmony_ci 326370b324cSopenharmony_ci int _numFastBytes = kNumFastBytesDefault; 327370b324cSopenharmony_ci int _longestMatchLength; 328370b324cSopenharmony_ci int _numDistancePairs; 329370b324cSopenharmony_ci 330370b324cSopenharmony_ci int _additionalOffset; 331370b324cSopenharmony_ci 332370b324cSopenharmony_ci int _optimumEndIndex; 333370b324cSopenharmony_ci int _optimumCurrentIndex; 334370b324cSopenharmony_ci 335370b324cSopenharmony_ci boolean _longestMatchWasFound; 336370b324cSopenharmony_ci 337370b324cSopenharmony_ci int[] _posSlotPrices = new int[1<<(Base.kNumPosSlotBits+Base.kNumLenToPosStatesBits)]; 338370b324cSopenharmony_ci int[] _distancesPrices = new int[Base.kNumFullDistances<<Base.kNumLenToPosStatesBits]; 339370b324cSopenharmony_ci int[] _alignPrices = new int[Base.kAlignTableSize]; 340370b324cSopenharmony_ci int _alignPriceCount; 341370b324cSopenharmony_ci 342370b324cSopenharmony_ci int _distTableSize = (kDefaultDictionaryLogSize * 2); 343370b324cSopenharmony_ci 344370b324cSopenharmony_ci int _posStateBits = 2; 345370b324cSopenharmony_ci int _posStateMask = (4 - 1); 346370b324cSopenharmony_ci int _numLiteralPosStateBits = 0; 347370b324cSopenharmony_ci int _numLiteralContextBits = 3; 348370b324cSopenharmony_ci 349370b324cSopenharmony_ci int _dictionarySize = (1 << kDefaultDictionaryLogSize); 350370b324cSopenharmony_ci int _dictionarySizePrev = -1; 351370b324cSopenharmony_ci int _numFastBytesPrev = -1; 352370b324cSopenharmony_ci 353370b324cSopenharmony_ci long nowPos64; 354370b324cSopenharmony_ci boolean _finished; 355370b324cSopenharmony_ci java.io.InputStream _inStream; 356370b324cSopenharmony_ci 357370b324cSopenharmony_ci int _matchFinderType = EMatchFinderTypeBT4; 358370b324cSopenharmony_ci boolean _writeEndMark = false; 359370b324cSopenharmony_ci 360370b324cSopenharmony_ci boolean _needReleaseMFStream = false; 361370b324cSopenharmony_ci 362370b324cSopenharmony_ci void Create() 363370b324cSopenharmony_ci { 364370b324cSopenharmony_ci if (_matchFinder == null) 365370b324cSopenharmony_ci { 366370b324cSopenharmony_ci SevenZip.Compression.LZ.BinTree bt = new SevenZip.Compression.LZ.BinTree(); 367370b324cSopenharmony_ci int numHashBytes = 4; 368370b324cSopenharmony_ci if (_matchFinderType == EMatchFinderTypeBT2) 369370b324cSopenharmony_ci numHashBytes = 2; 370370b324cSopenharmony_ci bt.SetType(numHashBytes); 371370b324cSopenharmony_ci _matchFinder = bt; 372370b324cSopenharmony_ci } 373370b324cSopenharmony_ci _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits); 374370b324cSopenharmony_ci 375370b324cSopenharmony_ci if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes) 376370b324cSopenharmony_ci return; 377370b324cSopenharmony_ci _matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1); 378370b324cSopenharmony_ci _dictionarySizePrev = _dictionarySize; 379370b324cSopenharmony_ci _numFastBytesPrev = _numFastBytes; 380370b324cSopenharmony_ci } 381370b324cSopenharmony_ci 382370b324cSopenharmony_ci public Encoder() 383370b324cSopenharmony_ci { 384370b324cSopenharmony_ci for (int i = 0; i < kNumOpts; i++) 385370b324cSopenharmony_ci _optimum[i] = new Optimal(); 386370b324cSopenharmony_ci for (int i = 0; i < Base.kNumLenToPosStates; i++) 387370b324cSopenharmony_ci _posSlotEncoder[i] = new BitTreeEncoder(Base.kNumPosSlotBits); 388370b324cSopenharmony_ci } 389370b324cSopenharmony_ci 390370b324cSopenharmony_ci void SetWriteEndMarkerMode(boolean writeEndMarker) 391370b324cSopenharmony_ci { 392370b324cSopenharmony_ci _writeEndMark = writeEndMarker; 393370b324cSopenharmony_ci } 394370b324cSopenharmony_ci 395370b324cSopenharmony_ci void Init() 396370b324cSopenharmony_ci { 397370b324cSopenharmony_ci BaseInit(); 398370b324cSopenharmony_ci _rangeEncoder.Init(); 399370b324cSopenharmony_ci 400370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isMatch); 401370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep0Long); 402370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep); 403370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG0); 404370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG1); 405370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG2); 406370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_posEncoders); 407370b324cSopenharmony_ci 408370b324cSopenharmony_ci 409370b324cSopenharmony_ci 410370b324cSopenharmony_ci 411370b324cSopenharmony_ci 412370b324cSopenharmony_ci 413370b324cSopenharmony_ci 414370b324cSopenharmony_ci _literalEncoder.Init(); 415370b324cSopenharmony_ci for (int i = 0; i < Base.kNumLenToPosStates; i++) 416370b324cSopenharmony_ci _posSlotEncoder[i].Init(); 417370b324cSopenharmony_ci 418370b324cSopenharmony_ci 419370b324cSopenharmony_ci 420370b324cSopenharmony_ci _lenEncoder.Init(1 << _posStateBits); 421370b324cSopenharmony_ci _repMatchLenEncoder.Init(1 << _posStateBits); 422370b324cSopenharmony_ci 423370b324cSopenharmony_ci _posAlignEncoder.Init(); 424370b324cSopenharmony_ci 425370b324cSopenharmony_ci _longestMatchWasFound = false; 426370b324cSopenharmony_ci _optimumEndIndex = 0; 427370b324cSopenharmony_ci _optimumCurrentIndex = 0; 428370b324cSopenharmony_ci _additionalOffset = 0; 429370b324cSopenharmony_ci } 430370b324cSopenharmony_ci 431370b324cSopenharmony_ci int ReadMatchDistances() throws java.io.IOException 432370b324cSopenharmony_ci { 433370b324cSopenharmony_ci int lenRes = 0; 434370b324cSopenharmony_ci _numDistancePairs = _matchFinder.GetMatches(_matchDistances); 435370b324cSopenharmony_ci if (_numDistancePairs > 0) 436370b324cSopenharmony_ci { 437370b324cSopenharmony_ci lenRes = _matchDistances[_numDistancePairs - 2]; 438370b324cSopenharmony_ci if (lenRes == _numFastBytes) 439370b324cSopenharmony_ci lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[_numDistancePairs - 1], 440370b324cSopenharmony_ci Base.kMatchMaxLen - lenRes); 441370b324cSopenharmony_ci } 442370b324cSopenharmony_ci _additionalOffset++; 443370b324cSopenharmony_ci return lenRes; 444370b324cSopenharmony_ci } 445370b324cSopenharmony_ci 446370b324cSopenharmony_ci void MovePos(int num) throws java.io.IOException 447370b324cSopenharmony_ci { 448370b324cSopenharmony_ci if (num > 0) 449370b324cSopenharmony_ci { 450370b324cSopenharmony_ci _matchFinder.Skip(num); 451370b324cSopenharmony_ci _additionalOffset += num; 452370b324cSopenharmony_ci } 453370b324cSopenharmony_ci } 454370b324cSopenharmony_ci 455370b324cSopenharmony_ci int GetRepLen1Price(int state, int posState) 456370b324cSopenharmony_ci { 457370b324cSopenharmony_ci return SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]) + 458370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]); 459370b324cSopenharmony_ci } 460370b324cSopenharmony_ci 461370b324cSopenharmony_ci int GetPureRepPrice(int repIndex, int state, int posState) 462370b324cSopenharmony_ci { 463370b324cSopenharmony_ci int price; 464370b324cSopenharmony_ci if (repIndex == 0) 465370b324cSopenharmony_ci { 466370b324cSopenharmony_ci price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]); 467370b324cSopenharmony_ci price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]); 468370b324cSopenharmony_ci } 469370b324cSopenharmony_ci else 470370b324cSopenharmony_ci { 471370b324cSopenharmony_ci price = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG0[state]); 472370b324cSopenharmony_ci if (repIndex == 1) 473370b324cSopenharmony_ci price += SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG1[state]); 474370b324cSopenharmony_ci else 475370b324cSopenharmony_ci { 476370b324cSopenharmony_ci price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG1[state]); 477370b324cSopenharmony_ci price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(_isRepG2[state], repIndex - 2); 478370b324cSopenharmony_ci } 479370b324cSopenharmony_ci } 480370b324cSopenharmony_ci return price; 481370b324cSopenharmony_ci } 482370b324cSopenharmony_ci 483370b324cSopenharmony_ci int GetRepPrice(int repIndex, int len, int state, int posState) 484370b324cSopenharmony_ci { 485370b324cSopenharmony_ci int price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState); 486370b324cSopenharmony_ci return price + GetPureRepPrice(repIndex, state, posState); 487370b324cSopenharmony_ci } 488370b324cSopenharmony_ci 489370b324cSopenharmony_ci int GetPosLenPrice(int pos, int len, int posState) 490370b324cSopenharmony_ci { 491370b324cSopenharmony_ci int price; 492370b324cSopenharmony_ci int lenToPosState = Base.GetLenToPosState(len); 493370b324cSopenharmony_ci if (pos < Base.kNumFullDistances) 494370b324cSopenharmony_ci price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos]; 495370b324cSopenharmony_ci else 496370b324cSopenharmony_ci price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] + 497370b324cSopenharmony_ci _alignPrices[pos & Base.kAlignMask]; 498370b324cSopenharmony_ci return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState); 499370b324cSopenharmony_ci } 500370b324cSopenharmony_ci 501370b324cSopenharmony_ci int Backward(int cur) 502370b324cSopenharmony_ci { 503370b324cSopenharmony_ci _optimumEndIndex = cur; 504370b324cSopenharmony_ci int posMem = _optimum[cur].PosPrev; 505370b324cSopenharmony_ci int backMem = _optimum[cur].BackPrev; 506370b324cSopenharmony_ci do 507370b324cSopenharmony_ci { 508370b324cSopenharmony_ci if (_optimum[cur].Prev1IsChar) 509370b324cSopenharmony_ci { 510370b324cSopenharmony_ci _optimum[posMem].MakeAsChar(); 511370b324cSopenharmony_ci _optimum[posMem].PosPrev = posMem - 1; 512370b324cSopenharmony_ci if (_optimum[cur].Prev2) 513370b324cSopenharmony_ci { 514370b324cSopenharmony_ci _optimum[posMem - 1].Prev1IsChar = false; 515370b324cSopenharmony_ci _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2; 516370b324cSopenharmony_ci _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2; 517370b324cSopenharmony_ci } 518370b324cSopenharmony_ci } 519370b324cSopenharmony_ci int posPrev = posMem; 520370b324cSopenharmony_ci int backCur = backMem; 521370b324cSopenharmony_ci 522370b324cSopenharmony_ci backMem = _optimum[posPrev].BackPrev; 523370b324cSopenharmony_ci posMem = _optimum[posPrev].PosPrev; 524370b324cSopenharmony_ci 525370b324cSopenharmony_ci _optimum[posPrev].BackPrev = backCur; 526370b324cSopenharmony_ci _optimum[posPrev].PosPrev = cur; 527370b324cSopenharmony_ci cur = posPrev; 528370b324cSopenharmony_ci } 529370b324cSopenharmony_ci while (cur > 0); 530370b324cSopenharmony_ci backRes = _optimum[0].BackPrev; 531370b324cSopenharmony_ci _optimumCurrentIndex = _optimum[0].PosPrev; 532370b324cSopenharmony_ci return _optimumCurrentIndex; 533370b324cSopenharmony_ci } 534370b324cSopenharmony_ci 535370b324cSopenharmony_ci int[] reps = new int[Base.kNumRepDistances]; 536370b324cSopenharmony_ci int[] repLens = new int[Base.kNumRepDistances]; 537370b324cSopenharmony_ci int backRes; 538370b324cSopenharmony_ci 539370b324cSopenharmony_ci int GetOptimum(int position) throws IOException 540370b324cSopenharmony_ci { 541370b324cSopenharmony_ci if (_optimumEndIndex != _optimumCurrentIndex) 542370b324cSopenharmony_ci { 543370b324cSopenharmony_ci int lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex; 544370b324cSopenharmony_ci backRes = _optimum[_optimumCurrentIndex].BackPrev; 545370b324cSopenharmony_ci _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev; 546370b324cSopenharmony_ci return lenRes; 547370b324cSopenharmony_ci } 548370b324cSopenharmony_ci _optimumCurrentIndex = _optimumEndIndex = 0; 549370b324cSopenharmony_ci 550370b324cSopenharmony_ci int lenMain, numDistancePairs; 551370b324cSopenharmony_ci if (!_longestMatchWasFound) 552370b324cSopenharmony_ci { 553370b324cSopenharmony_ci lenMain = ReadMatchDistances(); 554370b324cSopenharmony_ci } 555370b324cSopenharmony_ci else 556370b324cSopenharmony_ci { 557370b324cSopenharmony_ci lenMain = _longestMatchLength; 558370b324cSopenharmony_ci _longestMatchWasFound = false; 559370b324cSopenharmony_ci } 560370b324cSopenharmony_ci numDistancePairs = _numDistancePairs; 561370b324cSopenharmony_ci 562370b324cSopenharmony_ci int numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1; 563370b324cSopenharmony_ci if (numAvailableBytes < 2) 564370b324cSopenharmony_ci { 565370b324cSopenharmony_ci backRes = -1; 566370b324cSopenharmony_ci return 1; 567370b324cSopenharmony_ci } 568370b324cSopenharmony_ci if (numAvailableBytes > Base.kMatchMaxLen) 569370b324cSopenharmony_ci numAvailableBytes = Base.kMatchMaxLen; 570370b324cSopenharmony_ci 571370b324cSopenharmony_ci int repMaxIndex = 0; 572370b324cSopenharmony_ci int i; 573370b324cSopenharmony_ci for (i = 0; i < Base.kNumRepDistances; i++) 574370b324cSopenharmony_ci { 575370b324cSopenharmony_ci reps[i] = _repDistances[i]; 576370b324cSopenharmony_ci repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen); 577370b324cSopenharmony_ci if (repLens[i] > repLens[repMaxIndex]) 578370b324cSopenharmony_ci repMaxIndex = i; 579370b324cSopenharmony_ci } 580370b324cSopenharmony_ci if (repLens[repMaxIndex] >= _numFastBytes) 581370b324cSopenharmony_ci { 582370b324cSopenharmony_ci backRes = repMaxIndex; 583370b324cSopenharmony_ci int lenRes = repLens[repMaxIndex]; 584370b324cSopenharmony_ci MovePos(lenRes - 1); 585370b324cSopenharmony_ci return lenRes; 586370b324cSopenharmony_ci } 587370b324cSopenharmony_ci 588370b324cSopenharmony_ci if (lenMain >= _numFastBytes) 589370b324cSopenharmony_ci { 590370b324cSopenharmony_ci backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances; 591370b324cSopenharmony_ci MovePos(lenMain - 1); 592370b324cSopenharmony_ci return lenMain; 593370b324cSopenharmony_ci } 594370b324cSopenharmony_ci 595370b324cSopenharmony_ci byte currentByte = _matchFinder.GetIndexByte(0 - 1); 596370b324cSopenharmony_ci byte matchByte = _matchFinder.GetIndexByte(0 - _repDistances[0] - 1 - 1); 597370b324cSopenharmony_ci 598370b324cSopenharmony_ci if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2) 599370b324cSopenharmony_ci { 600370b324cSopenharmony_ci backRes = -1; 601370b324cSopenharmony_ci return 1; 602370b324cSopenharmony_ci } 603370b324cSopenharmony_ci 604370b324cSopenharmony_ci _optimum[0].State = _state; 605370b324cSopenharmony_ci 606370b324cSopenharmony_ci int posState = (position & _posStateMask); 607370b324cSopenharmony_ci 608370b324cSopenharmony_ci _optimum[1].Price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]) + 609370b324cSopenharmony_ci _literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!Base.StateIsCharState(_state), matchByte, currentByte); 610370b324cSopenharmony_ci _optimum[1].MakeAsChar(); 611370b324cSopenharmony_ci 612370b324cSopenharmony_ci int matchPrice = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]); 613370b324cSopenharmony_ci int repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[_state]); 614370b324cSopenharmony_ci 615370b324cSopenharmony_ci if (matchByte == currentByte) 616370b324cSopenharmony_ci { 617370b324cSopenharmony_ci int shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState); 618370b324cSopenharmony_ci if (shortRepPrice < _optimum[1].Price) 619370b324cSopenharmony_ci { 620370b324cSopenharmony_ci _optimum[1].Price = shortRepPrice; 621370b324cSopenharmony_ci _optimum[1].MakeAsShortRep(); 622370b324cSopenharmony_ci } 623370b324cSopenharmony_ci } 624370b324cSopenharmony_ci 625370b324cSopenharmony_ci int lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]); 626370b324cSopenharmony_ci 627370b324cSopenharmony_ci if (lenEnd < 2) 628370b324cSopenharmony_ci { 629370b324cSopenharmony_ci backRes = _optimum[1].BackPrev; 630370b324cSopenharmony_ci return 1; 631370b324cSopenharmony_ci } 632370b324cSopenharmony_ci 633370b324cSopenharmony_ci _optimum[1].PosPrev = 0; 634370b324cSopenharmony_ci 635370b324cSopenharmony_ci _optimum[0].Backs0 = reps[0]; 636370b324cSopenharmony_ci _optimum[0].Backs1 = reps[1]; 637370b324cSopenharmony_ci _optimum[0].Backs2 = reps[2]; 638370b324cSopenharmony_ci _optimum[0].Backs3 = reps[3]; 639370b324cSopenharmony_ci 640370b324cSopenharmony_ci int len = lenEnd; 641370b324cSopenharmony_ci do 642370b324cSopenharmony_ci _optimum[len--].Price = kIfinityPrice; 643370b324cSopenharmony_ci while (len >= 2); 644370b324cSopenharmony_ci 645370b324cSopenharmony_ci for (i = 0; i < Base.kNumRepDistances; i++) 646370b324cSopenharmony_ci { 647370b324cSopenharmony_ci int repLen = repLens[i]; 648370b324cSopenharmony_ci if (repLen < 2) 649370b324cSopenharmony_ci continue; 650370b324cSopenharmony_ci int price = repMatchPrice + GetPureRepPrice(i, _state, posState); 651370b324cSopenharmony_ci do 652370b324cSopenharmony_ci { 653370b324cSopenharmony_ci int curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState); 654370b324cSopenharmony_ci Optimal optimum = _optimum[repLen]; 655370b324cSopenharmony_ci if (curAndLenPrice < optimum.Price) 656370b324cSopenharmony_ci { 657370b324cSopenharmony_ci optimum.Price = curAndLenPrice; 658370b324cSopenharmony_ci optimum.PosPrev = 0; 659370b324cSopenharmony_ci optimum.BackPrev = i; 660370b324cSopenharmony_ci optimum.Prev1IsChar = false; 661370b324cSopenharmony_ci } 662370b324cSopenharmony_ci } 663370b324cSopenharmony_ci while (--repLen >= 2); 664370b324cSopenharmony_ci } 665370b324cSopenharmony_ci 666370b324cSopenharmony_ci int normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[_state]); 667370b324cSopenharmony_ci 668370b324cSopenharmony_ci len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); 669370b324cSopenharmony_ci if (len <= lenMain) 670370b324cSopenharmony_ci { 671370b324cSopenharmony_ci int offs = 0; 672370b324cSopenharmony_ci while (len > _matchDistances[offs]) 673370b324cSopenharmony_ci offs += 2; 674370b324cSopenharmony_ci for (; ; len++) 675370b324cSopenharmony_ci { 676370b324cSopenharmony_ci int distance = _matchDistances[offs + 1]; 677370b324cSopenharmony_ci int curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState); 678370b324cSopenharmony_ci Optimal optimum = _optimum[len]; 679370b324cSopenharmony_ci if (curAndLenPrice < optimum.Price) 680370b324cSopenharmony_ci { 681370b324cSopenharmony_ci optimum.Price = curAndLenPrice; 682370b324cSopenharmony_ci optimum.PosPrev = 0; 683370b324cSopenharmony_ci optimum.BackPrev = distance + Base.kNumRepDistances; 684370b324cSopenharmony_ci optimum.Prev1IsChar = false; 685370b324cSopenharmony_ci } 686370b324cSopenharmony_ci if (len == _matchDistances[offs]) 687370b324cSopenharmony_ci { 688370b324cSopenharmony_ci offs += 2; 689370b324cSopenharmony_ci if (offs == numDistancePairs) 690370b324cSopenharmony_ci break; 691370b324cSopenharmony_ci } 692370b324cSopenharmony_ci } 693370b324cSopenharmony_ci } 694370b324cSopenharmony_ci 695370b324cSopenharmony_ci int cur = 0; 696370b324cSopenharmony_ci 697370b324cSopenharmony_ci while (true) 698370b324cSopenharmony_ci { 699370b324cSopenharmony_ci cur++; 700370b324cSopenharmony_ci if (cur == lenEnd) 701370b324cSopenharmony_ci return Backward(cur); 702370b324cSopenharmony_ci int newLen = ReadMatchDistances(); 703370b324cSopenharmony_ci numDistancePairs = _numDistancePairs; 704370b324cSopenharmony_ci if (newLen >= _numFastBytes) 705370b324cSopenharmony_ci { 706370b324cSopenharmony_ci 707370b324cSopenharmony_ci _longestMatchLength = newLen; 708370b324cSopenharmony_ci _longestMatchWasFound = true; 709370b324cSopenharmony_ci return Backward(cur); 710370b324cSopenharmony_ci } 711370b324cSopenharmony_ci position++; 712370b324cSopenharmony_ci int posPrev = _optimum[cur].PosPrev; 713370b324cSopenharmony_ci int state; 714370b324cSopenharmony_ci if (_optimum[cur].Prev1IsChar) 715370b324cSopenharmony_ci { 716370b324cSopenharmony_ci posPrev--; 717370b324cSopenharmony_ci if (_optimum[cur].Prev2) 718370b324cSopenharmony_ci { 719370b324cSopenharmony_ci state = _optimum[_optimum[cur].PosPrev2].State; 720370b324cSopenharmony_ci if (_optimum[cur].BackPrev2 < Base.kNumRepDistances) 721370b324cSopenharmony_ci state = Base.StateUpdateRep(state); 722370b324cSopenharmony_ci else 723370b324cSopenharmony_ci state = Base.StateUpdateMatch(state); 724370b324cSopenharmony_ci } 725370b324cSopenharmony_ci else 726370b324cSopenharmony_ci state = _optimum[posPrev].State; 727370b324cSopenharmony_ci state = Base.StateUpdateChar(state); 728370b324cSopenharmony_ci } 729370b324cSopenharmony_ci else 730370b324cSopenharmony_ci state = _optimum[posPrev].State; 731370b324cSopenharmony_ci if (posPrev == cur - 1) 732370b324cSopenharmony_ci { 733370b324cSopenharmony_ci if (_optimum[cur].IsShortRep()) 734370b324cSopenharmony_ci state = Base.StateUpdateShortRep(state); 735370b324cSopenharmony_ci else 736370b324cSopenharmony_ci state = Base.StateUpdateChar(state); 737370b324cSopenharmony_ci } 738370b324cSopenharmony_ci else 739370b324cSopenharmony_ci { 740370b324cSopenharmony_ci int pos; 741370b324cSopenharmony_ci if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2) 742370b324cSopenharmony_ci { 743370b324cSopenharmony_ci posPrev = _optimum[cur].PosPrev2; 744370b324cSopenharmony_ci pos = _optimum[cur].BackPrev2; 745370b324cSopenharmony_ci state = Base.StateUpdateRep(state); 746370b324cSopenharmony_ci } 747370b324cSopenharmony_ci else 748370b324cSopenharmony_ci { 749370b324cSopenharmony_ci pos = _optimum[cur].BackPrev; 750370b324cSopenharmony_ci if (pos < Base.kNumRepDistances) 751370b324cSopenharmony_ci state = Base.StateUpdateRep(state); 752370b324cSopenharmony_ci else 753370b324cSopenharmony_ci state = Base.StateUpdateMatch(state); 754370b324cSopenharmony_ci } 755370b324cSopenharmony_ci Optimal opt = _optimum[posPrev]; 756370b324cSopenharmony_ci if (pos < Base.kNumRepDistances) 757370b324cSopenharmony_ci { 758370b324cSopenharmony_ci if (pos == 0) 759370b324cSopenharmony_ci { 760370b324cSopenharmony_ci reps[0] = opt.Backs0; 761370b324cSopenharmony_ci reps[1] = opt.Backs1; 762370b324cSopenharmony_ci reps[2] = opt.Backs2; 763370b324cSopenharmony_ci reps[3] = opt.Backs3; 764370b324cSopenharmony_ci } 765370b324cSopenharmony_ci else if (pos == 1) 766370b324cSopenharmony_ci { 767370b324cSopenharmony_ci reps[0] = opt.Backs1; 768370b324cSopenharmony_ci reps[1] = opt.Backs0; 769370b324cSopenharmony_ci reps[2] = opt.Backs2; 770370b324cSopenharmony_ci reps[3] = opt.Backs3; 771370b324cSopenharmony_ci } 772370b324cSopenharmony_ci else if (pos == 2) 773370b324cSopenharmony_ci { 774370b324cSopenharmony_ci reps[0] = opt.Backs2; 775370b324cSopenharmony_ci reps[1] = opt.Backs0; 776370b324cSopenharmony_ci reps[2] = opt.Backs1; 777370b324cSopenharmony_ci reps[3] = opt.Backs3; 778370b324cSopenharmony_ci } 779370b324cSopenharmony_ci else 780370b324cSopenharmony_ci { 781370b324cSopenharmony_ci reps[0] = opt.Backs3; 782370b324cSopenharmony_ci reps[1] = opt.Backs0; 783370b324cSopenharmony_ci reps[2] = opt.Backs1; 784370b324cSopenharmony_ci reps[3] = opt.Backs2; 785370b324cSopenharmony_ci } 786370b324cSopenharmony_ci } 787370b324cSopenharmony_ci else 788370b324cSopenharmony_ci { 789370b324cSopenharmony_ci reps[0] = (pos - Base.kNumRepDistances); 790370b324cSopenharmony_ci reps[1] = opt.Backs0; 791370b324cSopenharmony_ci reps[2] = opt.Backs1; 792370b324cSopenharmony_ci reps[3] = opt.Backs2; 793370b324cSopenharmony_ci } 794370b324cSopenharmony_ci } 795370b324cSopenharmony_ci _optimum[cur].State = state; 796370b324cSopenharmony_ci _optimum[cur].Backs0 = reps[0]; 797370b324cSopenharmony_ci _optimum[cur].Backs1 = reps[1]; 798370b324cSopenharmony_ci _optimum[cur].Backs2 = reps[2]; 799370b324cSopenharmony_ci _optimum[cur].Backs3 = reps[3]; 800370b324cSopenharmony_ci int curPrice = _optimum[cur].Price; 801370b324cSopenharmony_ci 802370b324cSopenharmony_ci currentByte = _matchFinder.GetIndexByte(0 - 1); 803370b324cSopenharmony_ci matchByte = _matchFinder.GetIndexByte(0 - reps[0] - 1 - 1); 804370b324cSopenharmony_ci 805370b324cSopenharmony_ci posState = (position & _posStateMask); 806370b324cSopenharmony_ci 807370b324cSopenharmony_ci int curAnd1Price = curPrice + 808370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]) + 809370b324cSopenharmony_ci _literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)). 810370b324cSopenharmony_ci GetPrice(!Base.StateIsCharState(state), matchByte, currentByte); 811370b324cSopenharmony_ci 812370b324cSopenharmony_ci Optimal nextOptimum = _optimum[cur + 1]; 813370b324cSopenharmony_ci 814370b324cSopenharmony_ci boolean nextIsChar = false; 815370b324cSopenharmony_ci if (curAnd1Price < nextOptimum.Price) 816370b324cSopenharmony_ci { 817370b324cSopenharmony_ci nextOptimum.Price = curAnd1Price; 818370b324cSopenharmony_ci nextOptimum.PosPrev = cur; 819370b324cSopenharmony_ci nextOptimum.MakeAsChar(); 820370b324cSopenharmony_ci nextIsChar = true; 821370b324cSopenharmony_ci } 822370b324cSopenharmony_ci 823370b324cSopenharmony_ci matchPrice = curPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]); 824370b324cSopenharmony_ci repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state]); 825370b324cSopenharmony_ci 826370b324cSopenharmony_ci if (matchByte == currentByte && 827370b324cSopenharmony_ci !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0)) 828370b324cSopenharmony_ci { 829370b324cSopenharmony_ci int shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState); 830370b324cSopenharmony_ci if (shortRepPrice <= nextOptimum.Price) 831370b324cSopenharmony_ci { 832370b324cSopenharmony_ci nextOptimum.Price = shortRepPrice; 833370b324cSopenharmony_ci nextOptimum.PosPrev = cur; 834370b324cSopenharmony_ci nextOptimum.MakeAsShortRep(); 835370b324cSopenharmony_ci nextIsChar = true; 836370b324cSopenharmony_ci } 837370b324cSopenharmony_ci } 838370b324cSopenharmony_ci 839370b324cSopenharmony_ci int numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1; 840370b324cSopenharmony_ci numAvailableBytesFull = Math.min(kNumOpts - 1 - cur, numAvailableBytesFull); 841370b324cSopenharmony_ci numAvailableBytes = numAvailableBytesFull; 842370b324cSopenharmony_ci 843370b324cSopenharmony_ci if (numAvailableBytes < 2) 844370b324cSopenharmony_ci continue; 845370b324cSopenharmony_ci if (numAvailableBytes > _numFastBytes) 846370b324cSopenharmony_ci numAvailableBytes = _numFastBytes; 847370b324cSopenharmony_ci if (!nextIsChar && matchByte != currentByte) 848370b324cSopenharmony_ci { 849370b324cSopenharmony_ci // try Literal + rep0 850370b324cSopenharmony_ci int t = Math.min(numAvailableBytesFull - 1, _numFastBytes); 851370b324cSopenharmony_ci int lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t); 852370b324cSopenharmony_ci if (lenTest2 >= 2) 853370b324cSopenharmony_ci { 854370b324cSopenharmony_ci int state2 = Base.StateUpdateChar(state); 855370b324cSopenharmony_ci 856370b324cSopenharmony_ci int posStateNext = (position + 1) & _posStateMask; 857370b324cSopenharmony_ci int nextRepMatchPrice = curAnd1Price + 858370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) + 859370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]); 860370b324cSopenharmony_ci { 861370b324cSopenharmony_ci int offset = cur + 1 + lenTest2; 862370b324cSopenharmony_ci while (lenEnd < offset) 863370b324cSopenharmony_ci _optimum[++lenEnd].Price = kIfinityPrice; 864370b324cSopenharmony_ci int curAndLenPrice = nextRepMatchPrice + GetRepPrice( 865370b324cSopenharmony_ci 0, lenTest2, state2, posStateNext); 866370b324cSopenharmony_ci Optimal optimum = _optimum[offset]; 867370b324cSopenharmony_ci if (curAndLenPrice < optimum.Price) 868370b324cSopenharmony_ci { 869370b324cSopenharmony_ci optimum.Price = curAndLenPrice; 870370b324cSopenharmony_ci optimum.PosPrev = cur + 1; 871370b324cSopenharmony_ci optimum.BackPrev = 0; 872370b324cSopenharmony_ci optimum.Prev1IsChar = true; 873370b324cSopenharmony_ci optimum.Prev2 = false; 874370b324cSopenharmony_ci } 875370b324cSopenharmony_ci } 876370b324cSopenharmony_ci } 877370b324cSopenharmony_ci } 878370b324cSopenharmony_ci 879370b324cSopenharmony_ci int startLen = 2; // speed optimization 880370b324cSopenharmony_ci 881370b324cSopenharmony_ci for (int repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++) 882370b324cSopenharmony_ci { 883370b324cSopenharmony_ci int lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes); 884370b324cSopenharmony_ci if (lenTest < 2) 885370b324cSopenharmony_ci continue; 886370b324cSopenharmony_ci int lenTestTemp = lenTest; 887370b324cSopenharmony_ci do 888370b324cSopenharmony_ci { 889370b324cSopenharmony_ci while (lenEnd < cur + lenTest) 890370b324cSopenharmony_ci _optimum[++lenEnd].Price = kIfinityPrice; 891370b324cSopenharmony_ci int curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState); 892370b324cSopenharmony_ci Optimal optimum = _optimum[cur + lenTest]; 893370b324cSopenharmony_ci if (curAndLenPrice < optimum.Price) 894370b324cSopenharmony_ci { 895370b324cSopenharmony_ci optimum.Price = curAndLenPrice; 896370b324cSopenharmony_ci optimum.PosPrev = cur; 897370b324cSopenharmony_ci optimum.BackPrev = repIndex; 898370b324cSopenharmony_ci optimum.Prev1IsChar = false; 899370b324cSopenharmony_ci } 900370b324cSopenharmony_ci } 901370b324cSopenharmony_ci while (--lenTest >= 2); 902370b324cSopenharmony_ci lenTest = lenTestTemp; 903370b324cSopenharmony_ci 904370b324cSopenharmony_ci if (repIndex == 0) 905370b324cSopenharmony_ci startLen = lenTest + 1; 906370b324cSopenharmony_ci 907370b324cSopenharmony_ci // if (_maxMode) 908370b324cSopenharmony_ci if (lenTest < numAvailableBytesFull) 909370b324cSopenharmony_ci { 910370b324cSopenharmony_ci int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes); 911370b324cSopenharmony_ci int lenTest2 = _matchFinder.GetMatchLen(lenTest, reps[repIndex], t); 912370b324cSopenharmony_ci if (lenTest2 >= 2) 913370b324cSopenharmony_ci { 914370b324cSopenharmony_ci int state2 = Base.StateUpdateRep(state); 915370b324cSopenharmony_ci 916370b324cSopenharmony_ci int posStateNext = (position + lenTest) & _posStateMask; 917370b324cSopenharmony_ci int curAndLenCharPrice = 918370b324cSopenharmony_ci repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) + 919370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) + 920370b324cSopenharmony_ci _literalEncoder.GetSubCoder(position + lenTest, 921370b324cSopenharmony_ci _matchFinder.GetIndexByte(lenTest - 1 - 1)).GetPrice(true, 922370b324cSopenharmony_ci _matchFinder.GetIndexByte(lenTest - 1 - (reps[repIndex] + 1)), 923370b324cSopenharmony_ci _matchFinder.GetIndexByte(lenTest - 1)); 924370b324cSopenharmony_ci state2 = Base.StateUpdateChar(state2); 925370b324cSopenharmony_ci posStateNext = (position + lenTest + 1) & _posStateMask; 926370b324cSopenharmony_ci int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]); 927370b324cSopenharmony_ci int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]); 928370b324cSopenharmony_ci 929370b324cSopenharmony_ci // for(; lenTest2 >= 2; lenTest2--) 930370b324cSopenharmony_ci { 931370b324cSopenharmony_ci int offset = lenTest + 1 + lenTest2; 932370b324cSopenharmony_ci while (lenEnd < cur + offset) 933370b324cSopenharmony_ci _optimum[++lenEnd].Price = kIfinityPrice; 934370b324cSopenharmony_ci int curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); 935370b324cSopenharmony_ci Optimal optimum = _optimum[cur + offset]; 936370b324cSopenharmony_ci if (curAndLenPrice < optimum.Price) 937370b324cSopenharmony_ci { 938370b324cSopenharmony_ci optimum.Price = curAndLenPrice; 939370b324cSopenharmony_ci optimum.PosPrev = cur + lenTest + 1; 940370b324cSopenharmony_ci optimum.BackPrev = 0; 941370b324cSopenharmony_ci optimum.Prev1IsChar = true; 942370b324cSopenharmony_ci optimum.Prev2 = true; 943370b324cSopenharmony_ci optimum.PosPrev2 = cur; 944370b324cSopenharmony_ci optimum.BackPrev2 = repIndex; 945370b324cSopenharmony_ci } 946370b324cSopenharmony_ci } 947370b324cSopenharmony_ci } 948370b324cSopenharmony_ci } 949370b324cSopenharmony_ci } 950370b324cSopenharmony_ci 951370b324cSopenharmony_ci if (newLen > numAvailableBytes) 952370b324cSopenharmony_ci { 953370b324cSopenharmony_ci newLen = numAvailableBytes; 954370b324cSopenharmony_ci for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ; 955370b324cSopenharmony_ci _matchDistances[numDistancePairs] = newLen; 956370b324cSopenharmony_ci numDistancePairs += 2; 957370b324cSopenharmony_ci } 958370b324cSopenharmony_ci if (newLen >= startLen) 959370b324cSopenharmony_ci { 960370b324cSopenharmony_ci normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[state]); 961370b324cSopenharmony_ci while (lenEnd < cur + newLen) 962370b324cSopenharmony_ci _optimum[++lenEnd].Price = kIfinityPrice; 963370b324cSopenharmony_ci 964370b324cSopenharmony_ci int offs = 0; 965370b324cSopenharmony_ci while (startLen > _matchDistances[offs]) 966370b324cSopenharmony_ci offs += 2; 967370b324cSopenharmony_ci 968370b324cSopenharmony_ci for (int lenTest = startLen; ; lenTest++) 969370b324cSopenharmony_ci { 970370b324cSopenharmony_ci int curBack = _matchDistances[offs + 1]; 971370b324cSopenharmony_ci int curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState); 972370b324cSopenharmony_ci Optimal optimum = _optimum[cur + lenTest]; 973370b324cSopenharmony_ci if (curAndLenPrice < optimum.Price) 974370b324cSopenharmony_ci { 975370b324cSopenharmony_ci optimum.Price = curAndLenPrice; 976370b324cSopenharmony_ci optimum.PosPrev = cur; 977370b324cSopenharmony_ci optimum.BackPrev = curBack + Base.kNumRepDistances; 978370b324cSopenharmony_ci optimum.Prev1IsChar = false; 979370b324cSopenharmony_ci } 980370b324cSopenharmony_ci 981370b324cSopenharmony_ci if (lenTest == _matchDistances[offs]) 982370b324cSopenharmony_ci { 983370b324cSopenharmony_ci if (lenTest < numAvailableBytesFull) 984370b324cSopenharmony_ci { 985370b324cSopenharmony_ci int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes); 986370b324cSopenharmony_ci int lenTest2 = _matchFinder.GetMatchLen(lenTest, curBack, t); 987370b324cSopenharmony_ci if (lenTest2 >= 2) 988370b324cSopenharmony_ci { 989370b324cSopenharmony_ci int state2 = Base.StateUpdateMatch(state); 990370b324cSopenharmony_ci 991370b324cSopenharmony_ci int posStateNext = (position + lenTest) & _posStateMask; 992370b324cSopenharmony_ci int curAndLenCharPrice = curAndLenPrice + 993370b324cSopenharmony_ci SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) + 994370b324cSopenharmony_ci _literalEncoder.GetSubCoder(position + lenTest, 995370b324cSopenharmony_ci _matchFinder.GetIndexByte(lenTest - 1 - 1)). 996370b324cSopenharmony_ci GetPrice(true, 997370b324cSopenharmony_ci _matchFinder.GetIndexByte(lenTest - (curBack + 1) - 1), 998370b324cSopenharmony_ci _matchFinder.GetIndexByte(lenTest - 1)); 999370b324cSopenharmony_ci state2 = Base.StateUpdateChar(state2); 1000370b324cSopenharmony_ci posStateNext = (position + lenTest + 1) & _posStateMask; 1001370b324cSopenharmony_ci int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]); 1002370b324cSopenharmony_ci int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]); 1003370b324cSopenharmony_ci 1004370b324cSopenharmony_ci int offset = lenTest + 1 + lenTest2; 1005370b324cSopenharmony_ci while (lenEnd < cur + offset) 1006370b324cSopenharmony_ci _optimum[++lenEnd].Price = kIfinityPrice; 1007370b324cSopenharmony_ci curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); 1008370b324cSopenharmony_ci optimum = _optimum[cur + offset]; 1009370b324cSopenharmony_ci if (curAndLenPrice < optimum.Price) 1010370b324cSopenharmony_ci { 1011370b324cSopenharmony_ci optimum.Price = curAndLenPrice; 1012370b324cSopenharmony_ci optimum.PosPrev = cur + lenTest + 1; 1013370b324cSopenharmony_ci optimum.BackPrev = 0; 1014370b324cSopenharmony_ci optimum.Prev1IsChar = true; 1015370b324cSopenharmony_ci optimum.Prev2 = true; 1016370b324cSopenharmony_ci optimum.PosPrev2 = cur; 1017370b324cSopenharmony_ci optimum.BackPrev2 = curBack + Base.kNumRepDistances; 1018370b324cSopenharmony_ci } 1019370b324cSopenharmony_ci } 1020370b324cSopenharmony_ci } 1021370b324cSopenharmony_ci offs += 2; 1022370b324cSopenharmony_ci if (offs == numDistancePairs) 1023370b324cSopenharmony_ci break; 1024370b324cSopenharmony_ci } 1025370b324cSopenharmony_ci } 1026370b324cSopenharmony_ci } 1027370b324cSopenharmony_ci } 1028370b324cSopenharmony_ci } 1029370b324cSopenharmony_ci 1030370b324cSopenharmony_ci boolean ChangePair(int smallDist, int bigDist) 1031370b324cSopenharmony_ci { 1032370b324cSopenharmony_ci int kDif = 7; 1033370b324cSopenharmony_ci return (smallDist < (1 << (32 - kDif)) && bigDist >= (smallDist << kDif)); 1034370b324cSopenharmony_ci } 1035370b324cSopenharmony_ci 1036370b324cSopenharmony_ci void WriteEndMarker(int posState) throws IOException 1037370b324cSopenharmony_ci { 1038370b324cSopenharmony_ci if (!_writeEndMark) 1039370b324cSopenharmony_ci return; 1040370b324cSopenharmony_ci 1041370b324cSopenharmony_ci _rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 1); 1042370b324cSopenharmony_ci _rangeEncoder.Encode(_isRep, _state, 0); 1043370b324cSopenharmony_ci _state = Base.StateUpdateMatch(_state); 1044370b324cSopenharmony_ci int len = Base.kMatchMinLen; 1045370b324cSopenharmony_ci _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); 1046370b324cSopenharmony_ci int posSlot = (1 << Base.kNumPosSlotBits) - 1; 1047370b324cSopenharmony_ci int lenToPosState = Base.GetLenToPosState(len); 1048370b324cSopenharmony_ci _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot); 1049370b324cSopenharmony_ci int footerBits = 30; 1050370b324cSopenharmony_ci int posReduced = (1 << footerBits) - 1; 1051370b324cSopenharmony_ci _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); 1052370b324cSopenharmony_ci _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); 1053370b324cSopenharmony_ci } 1054370b324cSopenharmony_ci 1055370b324cSopenharmony_ci void Flush(int nowPos) throws IOException 1056370b324cSopenharmony_ci { 1057370b324cSopenharmony_ci ReleaseMFStream(); 1058370b324cSopenharmony_ci WriteEndMarker(nowPos & _posStateMask); 1059370b324cSopenharmony_ci _rangeEncoder.FlushData(); 1060370b324cSopenharmony_ci _rangeEncoder.FlushStream(); 1061370b324cSopenharmony_ci } 1062370b324cSopenharmony_ci 1063370b324cSopenharmony_ci public void CodeOneBlock(long[] inSize, long[] outSize, boolean[] finished) throws IOException 1064370b324cSopenharmony_ci { 1065370b324cSopenharmony_ci inSize[0] = 0; 1066370b324cSopenharmony_ci outSize[0] = 0; 1067370b324cSopenharmony_ci finished[0] = true; 1068370b324cSopenharmony_ci 1069370b324cSopenharmony_ci if (_inStream != null) 1070370b324cSopenharmony_ci { 1071370b324cSopenharmony_ci _matchFinder.SetStream(_inStream); 1072370b324cSopenharmony_ci _matchFinder.Init(); 1073370b324cSopenharmony_ci _needReleaseMFStream = true; 1074370b324cSopenharmony_ci _inStream = null; 1075370b324cSopenharmony_ci } 1076370b324cSopenharmony_ci 1077370b324cSopenharmony_ci if (_finished) 1078370b324cSopenharmony_ci return; 1079370b324cSopenharmony_ci _finished = true; 1080370b324cSopenharmony_ci 1081370b324cSopenharmony_ci 1082370b324cSopenharmony_ci long progressPosValuePrev = nowPos64; 1083370b324cSopenharmony_ci if (nowPos64 == 0) 1084370b324cSopenharmony_ci { 1085370b324cSopenharmony_ci if (_matchFinder.GetNumAvailableBytes() == 0) 1086370b324cSopenharmony_ci { 1087370b324cSopenharmony_ci Flush((int)nowPos64); 1088370b324cSopenharmony_ci return; 1089370b324cSopenharmony_ci } 1090370b324cSopenharmony_ci 1091370b324cSopenharmony_ci ReadMatchDistances(); 1092370b324cSopenharmony_ci int posState = (int)(nowPos64) & _posStateMask; 1093370b324cSopenharmony_ci _rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 0); 1094370b324cSopenharmony_ci _state = Base.StateUpdateChar(_state); 1095370b324cSopenharmony_ci byte curByte = _matchFinder.GetIndexByte(0 - _additionalOffset); 1096370b324cSopenharmony_ci _literalEncoder.GetSubCoder((int)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte); 1097370b324cSopenharmony_ci _previousByte = curByte; 1098370b324cSopenharmony_ci _additionalOffset--; 1099370b324cSopenharmony_ci nowPos64++; 1100370b324cSopenharmony_ci } 1101370b324cSopenharmony_ci if (_matchFinder.GetNumAvailableBytes() == 0) 1102370b324cSopenharmony_ci { 1103370b324cSopenharmony_ci Flush((int)nowPos64); 1104370b324cSopenharmony_ci return; 1105370b324cSopenharmony_ci } 1106370b324cSopenharmony_ci while (true) 1107370b324cSopenharmony_ci { 1108370b324cSopenharmony_ci 1109370b324cSopenharmony_ci int len = GetOptimum((int)nowPos64); 1110370b324cSopenharmony_ci int pos = backRes; 1111370b324cSopenharmony_ci int posState = ((int)nowPos64) & _posStateMask; 1112370b324cSopenharmony_ci int complexState = (_state << Base.kNumPosStatesBitsMax) + posState; 1113370b324cSopenharmony_ci if (len == 1 && pos == -1) 1114370b324cSopenharmony_ci { 1115370b324cSopenharmony_ci _rangeEncoder.Encode(_isMatch, complexState, 0); 1116370b324cSopenharmony_ci byte curByte = _matchFinder.GetIndexByte((int)(0 - _additionalOffset)); 1117370b324cSopenharmony_ci LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((int)nowPos64, _previousByte); 1118370b324cSopenharmony_ci if (!Base.StateIsCharState(_state)) 1119370b324cSopenharmony_ci { 1120370b324cSopenharmony_ci byte matchByte = _matchFinder.GetIndexByte((int)(0 - _repDistances[0] - 1 - _additionalOffset)); 1121370b324cSopenharmony_ci subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte); 1122370b324cSopenharmony_ci } 1123370b324cSopenharmony_ci else 1124370b324cSopenharmony_ci subCoder.Encode(_rangeEncoder, curByte); 1125370b324cSopenharmony_ci _previousByte = curByte; 1126370b324cSopenharmony_ci _state = Base.StateUpdateChar(_state); 1127370b324cSopenharmony_ci } 1128370b324cSopenharmony_ci else 1129370b324cSopenharmony_ci { 1130370b324cSopenharmony_ci _rangeEncoder.Encode(_isMatch, complexState, 1); 1131370b324cSopenharmony_ci if (pos < Base.kNumRepDistances) 1132370b324cSopenharmony_ci { 1133370b324cSopenharmony_ci _rangeEncoder.Encode(_isRep, _state, 1); 1134370b324cSopenharmony_ci if (pos == 0) 1135370b324cSopenharmony_ci { 1136370b324cSopenharmony_ci _rangeEncoder.Encode(_isRepG0, _state, 0); 1137370b324cSopenharmony_ci if (len == 1) 1138370b324cSopenharmony_ci _rangeEncoder.Encode(_isRep0Long, complexState, 0); 1139370b324cSopenharmony_ci else 1140370b324cSopenharmony_ci _rangeEncoder.Encode(_isRep0Long, complexState, 1); 1141370b324cSopenharmony_ci } 1142370b324cSopenharmony_ci else 1143370b324cSopenharmony_ci { 1144370b324cSopenharmony_ci _rangeEncoder.Encode(_isRepG0, _state, 1); 1145370b324cSopenharmony_ci if (pos == 1) 1146370b324cSopenharmony_ci _rangeEncoder.Encode(_isRepG1, _state, 0); 1147370b324cSopenharmony_ci else 1148370b324cSopenharmony_ci { 1149370b324cSopenharmony_ci _rangeEncoder.Encode(_isRepG1, _state, 1); 1150370b324cSopenharmony_ci _rangeEncoder.Encode(_isRepG2, _state, pos - 2); 1151370b324cSopenharmony_ci } 1152370b324cSopenharmony_ci } 1153370b324cSopenharmony_ci if (len == 1) 1154370b324cSopenharmony_ci _state = Base.StateUpdateShortRep(_state); 1155370b324cSopenharmony_ci else 1156370b324cSopenharmony_ci { 1157370b324cSopenharmony_ci _repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); 1158370b324cSopenharmony_ci _state = Base.StateUpdateRep(_state); 1159370b324cSopenharmony_ci } 1160370b324cSopenharmony_ci int distance = _repDistances[pos]; 1161370b324cSopenharmony_ci if (pos != 0) 1162370b324cSopenharmony_ci { 1163370b324cSopenharmony_ci for (int i = pos; i >= 1; i--) 1164370b324cSopenharmony_ci _repDistances[i] = _repDistances[i - 1]; 1165370b324cSopenharmony_ci _repDistances[0] = distance; 1166370b324cSopenharmony_ci } 1167370b324cSopenharmony_ci } 1168370b324cSopenharmony_ci else 1169370b324cSopenharmony_ci { 1170370b324cSopenharmony_ci _rangeEncoder.Encode(_isRep, _state, 0); 1171370b324cSopenharmony_ci _state = Base.StateUpdateMatch(_state); 1172370b324cSopenharmony_ci _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); 1173370b324cSopenharmony_ci pos -= Base.kNumRepDistances; 1174370b324cSopenharmony_ci int posSlot = GetPosSlot(pos); 1175370b324cSopenharmony_ci int lenToPosState = Base.GetLenToPosState(len); 1176370b324cSopenharmony_ci _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot); 1177370b324cSopenharmony_ci 1178370b324cSopenharmony_ci if (posSlot >= Base.kStartPosModelIndex) 1179370b324cSopenharmony_ci { 1180370b324cSopenharmony_ci int footerBits = (int)((posSlot >> 1) - 1); 1181370b324cSopenharmony_ci int baseVal = ((2 | (posSlot & 1)) << footerBits); 1182370b324cSopenharmony_ci int posReduced = pos - baseVal; 1183370b324cSopenharmony_ci 1184370b324cSopenharmony_ci if (posSlot < Base.kEndPosModelIndex) 1185370b324cSopenharmony_ci BitTreeEncoder.ReverseEncode(_posEncoders, 1186370b324cSopenharmony_ci baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced); 1187370b324cSopenharmony_ci else 1188370b324cSopenharmony_ci { 1189370b324cSopenharmony_ci _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); 1190370b324cSopenharmony_ci _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); 1191370b324cSopenharmony_ci _alignPriceCount++; 1192370b324cSopenharmony_ci } 1193370b324cSopenharmony_ci } 1194370b324cSopenharmony_ci int distance = pos; 1195370b324cSopenharmony_ci for (int i = Base.kNumRepDistances - 1; i >= 1; i--) 1196370b324cSopenharmony_ci _repDistances[i] = _repDistances[i - 1]; 1197370b324cSopenharmony_ci _repDistances[0] = distance; 1198370b324cSopenharmony_ci _matchPriceCount++; 1199370b324cSopenharmony_ci } 1200370b324cSopenharmony_ci _previousByte = _matchFinder.GetIndexByte(len - 1 - _additionalOffset); 1201370b324cSopenharmony_ci } 1202370b324cSopenharmony_ci _additionalOffset -= len; 1203370b324cSopenharmony_ci nowPos64 += len; 1204370b324cSopenharmony_ci if (_additionalOffset == 0) 1205370b324cSopenharmony_ci { 1206370b324cSopenharmony_ci // if (!_fastMode) 1207370b324cSopenharmony_ci if (_matchPriceCount >= (1 << 7)) 1208370b324cSopenharmony_ci FillDistancesPrices(); 1209370b324cSopenharmony_ci if (_alignPriceCount >= Base.kAlignTableSize) 1210370b324cSopenharmony_ci FillAlignPrices(); 1211370b324cSopenharmony_ci inSize[0] = nowPos64; 1212370b324cSopenharmony_ci outSize[0] = _rangeEncoder.GetProcessedSizeAdd(); 1213370b324cSopenharmony_ci if (_matchFinder.GetNumAvailableBytes() == 0) 1214370b324cSopenharmony_ci { 1215370b324cSopenharmony_ci Flush((int)nowPos64); 1216370b324cSopenharmony_ci return; 1217370b324cSopenharmony_ci } 1218370b324cSopenharmony_ci 1219370b324cSopenharmony_ci if (nowPos64 - progressPosValuePrev >= (1 << 12)) 1220370b324cSopenharmony_ci { 1221370b324cSopenharmony_ci _finished = false; 1222370b324cSopenharmony_ci finished[0] = false; 1223370b324cSopenharmony_ci return; 1224370b324cSopenharmony_ci } 1225370b324cSopenharmony_ci } 1226370b324cSopenharmony_ci } 1227370b324cSopenharmony_ci } 1228370b324cSopenharmony_ci 1229370b324cSopenharmony_ci void ReleaseMFStream() 1230370b324cSopenharmony_ci { 1231370b324cSopenharmony_ci if (_matchFinder != null && _needReleaseMFStream) 1232370b324cSopenharmony_ci { 1233370b324cSopenharmony_ci _matchFinder.ReleaseStream(); 1234370b324cSopenharmony_ci _needReleaseMFStream = false; 1235370b324cSopenharmony_ci } 1236370b324cSopenharmony_ci } 1237370b324cSopenharmony_ci 1238370b324cSopenharmony_ci void SetOutStream(java.io.OutputStream outStream) 1239370b324cSopenharmony_ci { _rangeEncoder.SetStream(outStream); } 1240370b324cSopenharmony_ci void ReleaseOutStream() 1241370b324cSopenharmony_ci { _rangeEncoder.ReleaseStream(); } 1242370b324cSopenharmony_ci 1243370b324cSopenharmony_ci void ReleaseStreams() 1244370b324cSopenharmony_ci { 1245370b324cSopenharmony_ci ReleaseMFStream(); 1246370b324cSopenharmony_ci ReleaseOutStream(); 1247370b324cSopenharmony_ci } 1248370b324cSopenharmony_ci 1249370b324cSopenharmony_ci void SetStreams(java.io.InputStream inStream, java.io.OutputStream outStream, 1250370b324cSopenharmony_ci long inSize, long outSize) 1251370b324cSopenharmony_ci { 1252370b324cSopenharmony_ci _inStream = inStream; 1253370b324cSopenharmony_ci _finished = false; 1254370b324cSopenharmony_ci Create(); 1255370b324cSopenharmony_ci SetOutStream(outStream); 1256370b324cSopenharmony_ci Init(); 1257370b324cSopenharmony_ci 1258370b324cSopenharmony_ci // if (!_fastMode) 1259370b324cSopenharmony_ci { 1260370b324cSopenharmony_ci FillDistancesPrices(); 1261370b324cSopenharmony_ci FillAlignPrices(); 1262370b324cSopenharmony_ci } 1263370b324cSopenharmony_ci 1264370b324cSopenharmony_ci _lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen); 1265370b324cSopenharmony_ci _lenEncoder.UpdateTables(1 << _posStateBits); 1266370b324cSopenharmony_ci _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen); 1267370b324cSopenharmony_ci _repMatchLenEncoder.UpdateTables(1 << _posStateBits); 1268370b324cSopenharmony_ci 1269370b324cSopenharmony_ci nowPos64 = 0; 1270370b324cSopenharmony_ci } 1271370b324cSopenharmony_ci 1272370b324cSopenharmony_ci long[] processedInSize = new long[1]; long[] processedOutSize = new long[1]; boolean[] finished = new boolean[1]; 1273370b324cSopenharmony_ci public void Code(java.io.InputStream inStream, java.io.OutputStream outStream, 1274370b324cSopenharmony_ci long inSize, long outSize, ICodeProgress progress) throws IOException 1275370b324cSopenharmony_ci { 1276370b324cSopenharmony_ci _needReleaseMFStream = false; 1277370b324cSopenharmony_ci try 1278370b324cSopenharmony_ci { 1279370b324cSopenharmony_ci SetStreams(inStream, outStream, inSize, outSize); 1280370b324cSopenharmony_ci while (true) 1281370b324cSopenharmony_ci { 1282370b324cSopenharmony_ci 1283370b324cSopenharmony_ci 1284370b324cSopenharmony_ci 1285370b324cSopenharmony_ci CodeOneBlock(processedInSize, processedOutSize, finished); 1286370b324cSopenharmony_ci if (finished[0]) 1287370b324cSopenharmony_ci return; 1288370b324cSopenharmony_ci if (progress != null) 1289370b324cSopenharmony_ci { 1290370b324cSopenharmony_ci progress.SetProgress(processedInSize[0], processedOutSize[0]); 1291370b324cSopenharmony_ci } 1292370b324cSopenharmony_ci } 1293370b324cSopenharmony_ci } 1294370b324cSopenharmony_ci finally 1295370b324cSopenharmony_ci { 1296370b324cSopenharmony_ci ReleaseStreams(); 1297370b324cSopenharmony_ci } 1298370b324cSopenharmony_ci } 1299370b324cSopenharmony_ci 1300370b324cSopenharmony_ci public static final int kPropSize = 5; 1301370b324cSopenharmony_ci byte[] properties = new byte[kPropSize]; 1302370b324cSopenharmony_ci 1303370b324cSopenharmony_ci public void WriteCoderProperties(java.io.OutputStream outStream) throws IOException 1304370b324cSopenharmony_ci { 1305370b324cSopenharmony_ci properties[0] = (byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits); 1306370b324cSopenharmony_ci for (int i = 0; i < 4; i++) 1307370b324cSopenharmony_ci properties[1 + i] = (byte)(_dictionarySize >> (8 * i)); 1308370b324cSopenharmony_ci outStream.write(properties, 0, kPropSize); 1309370b324cSopenharmony_ci } 1310370b324cSopenharmony_ci 1311370b324cSopenharmony_ci int[] tempPrices = new int[Base.kNumFullDistances]; 1312370b324cSopenharmony_ci int _matchPriceCount; 1313370b324cSopenharmony_ci 1314370b324cSopenharmony_ci void FillDistancesPrices() 1315370b324cSopenharmony_ci { 1316370b324cSopenharmony_ci for (int i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++) 1317370b324cSopenharmony_ci { 1318370b324cSopenharmony_ci int posSlot = GetPosSlot(i); 1319370b324cSopenharmony_ci int footerBits = (int)((posSlot >> 1) - 1); 1320370b324cSopenharmony_ci int baseVal = ((2 | (posSlot & 1)) << footerBits); 1321370b324cSopenharmony_ci tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders, 1322370b324cSopenharmony_ci baseVal - posSlot - 1, footerBits, i - baseVal); 1323370b324cSopenharmony_ci } 1324370b324cSopenharmony_ci 1325370b324cSopenharmony_ci for (int lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++) 1326370b324cSopenharmony_ci { 1327370b324cSopenharmony_ci int posSlot; 1328370b324cSopenharmony_ci BitTreeEncoder encoder = _posSlotEncoder[lenToPosState]; 1329370b324cSopenharmony_ci 1330370b324cSopenharmony_ci int st = (lenToPosState << Base.kNumPosSlotBits); 1331370b324cSopenharmony_ci for (posSlot = 0; posSlot < _distTableSize; posSlot++) 1332370b324cSopenharmony_ci _posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot); 1333370b324cSopenharmony_ci for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++) 1334370b324cSopenharmony_ci _posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << SevenZip.Compression.RangeCoder.Encoder.kNumBitPriceShiftBits); 1335370b324cSopenharmony_ci 1336370b324cSopenharmony_ci int st2 = lenToPosState * Base.kNumFullDistances; 1337370b324cSopenharmony_ci int i; 1338370b324cSopenharmony_ci for (i = 0; i < Base.kStartPosModelIndex; i++) 1339370b324cSopenharmony_ci _distancesPrices[st2 + i] = _posSlotPrices[st + i]; 1340370b324cSopenharmony_ci for (; i < Base.kNumFullDistances; i++) 1341370b324cSopenharmony_ci _distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i]; 1342370b324cSopenharmony_ci } 1343370b324cSopenharmony_ci _matchPriceCount = 0; 1344370b324cSopenharmony_ci } 1345370b324cSopenharmony_ci 1346370b324cSopenharmony_ci void FillAlignPrices() 1347370b324cSopenharmony_ci { 1348370b324cSopenharmony_ci for (int i = 0; i < Base.kAlignTableSize; i++) 1349370b324cSopenharmony_ci _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i); 1350370b324cSopenharmony_ci _alignPriceCount = 0; 1351370b324cSopenharmony_ci } 1352370b324cSopenharmony_ci 1353370b324cSopenharmony_ci 1354370b324cSopenharmony_ci public boolean SetAlgorithm(int algorithm) 1355370b324cSopenharmony_ci { 1356370b324cSopenharmony_ci /* 1357370b324cSopenharmony_ci _fastMode = (algorithm == 0); 1358370b324cSopenharmony_ci _maxMode = (algorithm >= 2); 1359370b324cSopenharmony_ci */ 1360370b324cSopenharmony_ci return true; 1361370b324cSopenharmony_ci } 1362370b324cSopenharmony_ci 1363370b324cSopenharmony_ci public boolean SetDictionarySize(int dictionarySize) 1364370b324cSopenharmony_ci { 1365370b324cSopenharmony_ci int kDicLogSizeMaxCompress = 29; 1366370b324cSopenharmony_ci if (dictionarySize < (1 << Base.kDicLogSizeMin) || dictionarySize > (1 << kDicLogSizeMaxCompress)) 1367370b324cSopenharmony_ci return false; 1368370b324cSopenharmony_ci _dictionarySize = dictionarySize; 1369370b324cSopenharmony_ci int dicLogSize; 1370370b324cSopenharmony_ci for (dicLogSize = 0; dictionarySize > (1 << dicLogSize); dicLogSize++) ; 1371370b324cSopenharmony_ci _distTableSize = dicLogSize * 2; 1372370b324cSopenharmony_ci return true; 1373370b324cSopenharmony_ci } 1374370b324cSopenharmony_ci 1375370b324cSopenharmony_ci public boolean SetNumFastBytes(int numFastBytes) 1376370b324cSopenharmony_ci { 1377370b324cSopenharmony_ci if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen) 1378370b324cSopenharmony_ci return false; 1379370b324cSopenharmony_ci _numFastBytes = numFastBytes; 1380370b324cSopenharmony_ci return true; 1381370b324cSopenharmony_ci } 1382370b324cSopenharmony_ci 1383370b324cSopenharmony_ci public boolean SetMatchFinder(int matchFinderIndex) 1384370b324cSopenharmony_ci { 1385370b324cSopenharmony_ci if (matchFinderIndex < 0 || matchFinderIndex > 2) 1386370b324cSopenharmony_ci return false; 1387370b324cSopenharmony_ci int matchFinderIndexPrev = _matchFinderType; 1388370b324cSopenharmony_ci _matchFinderType = matchFinderIndex; 1389370b324cSopenharmony_ci if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType) 1390370b324cSopenharmony_ci { 1391370b324cSopenharmony_ci _dictionarySizePrev = -1; 1392370b324cSopenharmony_ci _matchFinder = null; 1393370b324cSopenharmony_ci } 1394370b324cSopenharmony_ci return true; 1395370b324cSopenharmony_ci } 1396370b324cSopenharmony_ci 1397370b324cSopenharmony_ci public boolean SetLcLpPb(int lc, int lp, int pb) 1398370b324cSopenharmony_ci { 1399370b324cSopenharmony_ci if ( 1400370b324cSopenharmony_ci lp < 0 || lp > Base.kNumLitPosStatesBitsEncodingMax || 1401370b324cSopenharmony_ci lc < 0 || lc > Base.kNumLitContextBitsMax || 1402370b324cSopenharmony_ci pb < 0 || pb > Base.kNumPosStatesBitsEncodingMax) 1403370b324cSopenharmony_ci return false; 1404370b324cSopenharmony_ci _numLiteralPosStateBits = lp; 1405370b324cSopenharmony_ci _numLiteralContextBits = lc; 1406370b324cSopenharmony_ci _posStateBits = pb; 1407370b324cSopenharmony_ci _posStateMask = ((1) << _posStateBits) - 1; 1408370b324cSopenharmony_ci return true; 1409370b324cSopenharmony_ci } 1410370b324cSopenharmony_ci 1411370b324cSopenharmony_ci public void SetEndMarkerMode(boolean endMarkerMode) 1412370b324cSopenharmony_ci { 1413370b324cSopenharmony_ci _writeEndMark = endMarkerMode; 1414370b324cSopenharmony_ci } 1415370b324cSopenharmony_ci} 1416370b324cSopenharmony_ci 1417