📄 decoder.cpp
字号:
// Decoder.cpp#include "Decoder.h"UINT32 kDistStart[kDistTableSizeMax];BYTE *CDecoder::Create(BYTE *memoryPointer, const BYTE *properties){ UINT32 startValue = 0; int i; for (i = 0; i < kDistTableSizeMax; i++) { kDistStart[i] = startValue; startValue += (1 << kDistDirectBits[i]); } for(i = 0; i < kNumPosModels; i++) { memoryPointer = m_PosDecoders[i].Create(memoryPointer, kDistDirectBits[kStartPosModelIndex + i]); } // int numLiteralPosStateBits = 0; // int numLiteralContextBits = 3; // int numPosStateBits = 2; BYTE firstByte = properties[0]; int numLiteralContextBits = firstByte % 9; BYTE remainder = firstByte / 9; int numLiteralPosStateBits = remainder % 5; int numPosStateBits = remainder / 5; memoryPointer = m_LiteralDecoder.Create(memoryPointer, numLiteralPosStateBits, numLiteralContextBits); int numPosStates = 1 << numPosStateBits; m_LenDecoder.Create(numPosStates); m_RepMatchLenDecoder.Create(numPosStates); m_PosStateMask = numPosStates - 1; return memoryPointer;}bool CDecoder::Code(const BYTE *inStream, BYTE *outStream, UINT32 inSize, UINT32 outSize){ // Init m_RangeDecoder.Init(inStream, inSize); m_OutWindowStream.Init(outStream); int i; for(i = 0; i < kNumStates; i++) { for (int j = 0; j <= m_PosStateMask; j++) { m_MainChoiceDecoders[i][j].Init(); m_MatchRepShortChoiceDecoders[i][j].Init(); } m_MatchChoiceDecoders[i].Init(); m_MatchRepChoiceDecoders[i].Init(); m_MatchRep1ChoiceDecoders[i].Init(); m_MatchRep2ChoiceDecoders[i].Init(); } m_LiteralDecoder.Init(); for (i = 0; i < kNumLenToPosStates; i++) m_PosSlotDecoder[i].Init(); for(i = 0; i < kNumPosModels; i++) m_PosDecoders[i].Init(); m_LenDecoder.Init(); m_RepMatchLenDecoder.Init(); m_PosAlignDecoder.Init(); // Code CState state; state.Init(); bool peviousIsMatch = false; BYTE previousByte = 0; UINT32 repDistances[kNumRepDistances]; for(i = 0 ; i < kNumRepDistances; i++) repDistances[i] = 0; UINT32 nowPos = 0; while(nowPos < outSize) { int posState = nowPos & m_PosStateMask; if (m_MainChoiceDecoders[state.m_Index][posState].Decode(&m_RangeDecoder) == kMainChoiceLiteralIndex) { state.UpdateChar(); if(peviousIsMatch) { BYTE matchByte = m_OutWindowStream.GetOneByte(0 - repDistances[0] - 1); previousByte = m_LiteralDecoder.DecodeWithMatchByte(&m_RangeDecoder, nowPos, previousByte, matchByte); peviousIsMatch = false; } else previousByte = m_LiteralDecoder.DecodeNormal(&m_RangeDecoder, nowPos, previousByte); m_OutWindowStream.PutOneByte(previousByte); nowPos++; } else { peviousIsMatch = true; UINT32 distance; int len; if(m_MatchChoiceDecoders[state.m_Index].Decode(&m_RangeDecoder) == kMatchChoiceRepetitionIndex) { if(m_MatchRepChoiceDecoders[state.m_Index].Decode(&m_RangeDecoder) == 0) { if(m_MatchRepShortChoiceDecoders[state.m_Index][posState].Decode(&m_RangeDecoder) == 0) { state.UpdateShortRep(); previousByte = m_OutWindowStream.GetOneByte(0 - repDistances[0] - 1); m_OutWindowStream.PutOneByte(previousByte); nowPos++; continue; } distance = repDistances[0]; } else { if(m_MatchRep1ChoiceDecoders[state.m_Index].Decode(&m_RangeDecoder) == 0) { distance = repDistances[1]; repDistances[1] = repDistances[0]; } else { if (m_MatchRep2ChoiceDecoders[state.m_Index].Decode(&m_RangeDecoder) == 0) { distance = repDistances[2]; } else { distance = repDistances[3]; repDistances[3] = repDistances[2]; } repDistances[2] = repDistances[1]; repDistances[1] = repDistances[0]; } repDistances[0] = distance; } len = m_RepMatchLenDecoder.Decode(&m_RangeDecoder, posState) + kMatchMinLen; state.UpdateRep(); } else { len = kMatchMinLen + m_LenDecoder.Decode(&m_RangeDecoder, posState); state.UpdateMatch(); int posSlot = m_PosSlotDecoder[GetLenToPosState(len)].Decode(&m_RangeDecoder); if (posSlot >= kStartPosModelIndex) { distance = kDistStart[posSlot]; if (posSlot < kEndPosModelIndex) distance += m_PosDecoders[posSlot - kStartPosModelIndex].Decode(&m_RangeDecoder); else { distance += (m_RangeDecoder.DecodeDirectBits(kDistDirectBits[posSlot] - kNumAlignBits) << kNumAlignBits); distance += m_PosAlignDecoder.Decode(&m_RangeDecoder); } } else distance = posSlot; repDistances[3] = repDistances[2]; repDistances[2] = repDistances[1]; repDistances[1] = repDistances[0]; repDistances[0] = distance; } if (distance >= nowPos) return false; m_OutWindowStream.CopyBackBlock(distance, len); nowPos += len; previousByte = m_OutWindowStream.GetOneByte(0 - 1); } } return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -