1 | /* |
2 | Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net ) |
3 | Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org ) |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License version 2.1 as published by the Free Software Foundation. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with this library; if not, write to the Free Software |
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ |
18 | |
19 | #ifndef __LITERALCODER_H |
20 | #define __LITERALCODER_H |
21 | |
22 | #include "aribitcd.h" |
23 | #include "rcdefs.h" |
24 | |
25 | namespace NLiteral { |
26 | |
27 | const int kNumMoveBits = 5; |
28 | |
29 | class CDecoder2 |
30 | { |
31 | CMyBitDecoder<kNumMoveBits> m_Decoders[3][1 << 8]; |
32 | public: |
33 | void Init() |
34 | { |
35 | for (int i = 0; i < 3; i++) |
36 | for (int j = 1; j < (1 << 8); j++) |
37 | m_Decoders[i][j].Init(); |
38 | } |
39 | |
40 | BYTE DecodeNormal(CMyRangeDecoder *aRangeDecoder) |
41 | { |
42 | UINT32 aSymbol = 1; |
43 | RC_INIT_VAR |
44 | do |
45 | { |
46 | // aSymbol = (aSymbol << 1) | m_Decoders[0][aSymbol].Decode(aRangeDecoder); |
47 | RC_GETBIT(kNumMoveBits, m_Decoders[0][aSymbol].m_Probability, aSymbol) |
48 | } |
49 | while (aSymbol < 0x100); |
50 | RC_FLUSH_VAR |
51 | return aSymbol; |
52 | } |
53 | |
54 | BYTE DecodeWithMatchByte(CMyRangeDecoder *aRangeDecoder, BYTE aMatchByte) |
55 | { |
56 | UINT32 aSymbol = 1; |
57 | RC_INIT_VAR |
58 | do |
59 | { |
60 | UINT32 aMatchBit = (aMatchByte >> 7) & 1; |
61 | aMatchByte <<= 1; |
62 | // UINT32 aBit = m_Decoders[1 + aMatchBit][aSymbol].Decode(aRangeDecoder); |
63 | // aSymbol = (aSymbol << 1) | aBit; |
64 | UINT32 aBit; |
65 | RC_GETBIT2(kNumMoveBits, m_Decoders[1 + aMatchBit][aSymbol].m_Probability, aSymbol, |
66 | aBit = 0, aBit = 1) |
67 | if (aMatchBit != aBit) |
68 | { |
69 | while (aSymbol < 0x100) |
70 | { |
71 | // aSymbol = (aSymbol << 1) | m_Decoders[0][aSymbol].Decode(aRangeDecoder); |
72 | RC_GETBIT(kNumMoveBits, m_Decoders[0][aSymbol].m_Probability, aSymbol) |
73 | } |
74 | break; |
75 | } |
76 | } |
77 | while (aSymbol < 0x100); |
78 | RC_FLUSH_VAR |
79 | return aSymbol; |
80 | } |
81 | }; |
82 | |
83 | class CDecoder |
84 | { |
85 | CDecoder2 *m_Coders; |
86 | UINT32 m_NumPrevBits; |
87 | UINT32 m_NumPosBits; |
88 | UINT32 m_PosMask; |
89 | public: |
90 | CDecoder(): m_Coders(0) {} |
91 | ~CDecoder() { Free(); } |
92 | void Free() |
93 | { |
94 | delete []m_Coders; |
95 | m_Coders = 0; |
96 | } |
97 | void Create(UINT32 aNumPosBits, UINT32 aNumPrevBits) |
98 | { |
99 | Free(); |
100 | m_NumPosBits = aNumPosBits; |
101 | m_PosMask = (1 << aNumPosBits) - 1; |
102 | m_NumPrevBits = aNumPrevBits; |
103 | UINT32 aNumStates = 1 << (m_NumPrevBits + m_NumPosBits); |
104 | m_Coders = new CDecoder2[aNumStates]; |
105 | } |
106 | void Init() |
107 | { |
108 | UINT32 aNumStates = 1 << (m_NumPrevBits + m_NumPosBits); |
109 | for (UINT32 i = 0; i < aNumStates; i++) |
110 | m_Coders[i].Init(); |
111 | } |
112 | UINT32 GetState(UINT32 aPos, BYTE aPrevByte) const |
113 | { return ((aPos & m_PosMask) << m_NumPrevBits) + (aPrevByte >> (8 - m_NumPrevBits)); } |
114 | BYTE DecodeNormal(CMyRangeDecoder *aRangeDecoder, UINT32 aPos, BYTE aPrevByte) |
115 | { return m_Coders[GetState(aPos, aPrevByte)].DecodeNormal(aRangeDecoder); } |
116 | BYTE DecodeWithMatchByte(CMyRangeDecoder *aRangeDecoder, UINT32 aPos, BYTE aPrevByte, BYTE aMatchByte) |
117 | { return m_Coders[GetState(aPos, aPrevByte)].DecodeWithMatchByte(aRangeDecoder, aMatchByte); } |
118 | }; |
119 | |
120 | } |
121 | |
122 | #endif |
123 | |