1/*
2Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
3Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
4
5This library is free software; you can redistribute it and/or
6modify it under the terms of the GNU Lesser General Public
7License version 2.1 as published by the Free Software Foundation.
8
9This library is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12Lesser General Public License for more details.
13
14You should have received a copy of the GNU Lesser General Public
15License along with this library; if not, write to the Free Software
16Foundation, 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
25namespace NLiteral {
26
27const int kNumMoveBits = 5;
28
29class CDecoder2
30{
31 CMyBitDecoder<kNumMoveBits> m_Decoders[3][1 << 8];
32public:
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
83class CDecoder
84{
85 CDecoder2 *m_Coders;
86 UINT32 m_NumPrevBits;
87 UINT32 m_NumPosBits;
88 UINT32 m_PosMask;
89public:
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