svn-gvsig-desktop / branches / v051 / libraries / libjni-ecwcompress / include / include-sdk / NCSJPCMQCoder.h @ 38104
History | View | Annotate | Download (5.59 KB)
1 | 3538 | nacho | /********************************************************
|
---|---|---|---|
2 | ** Copyright 2003 Earth Resource Mapping Ltd.
|
||
3 | ** This document contains proprietary source code of
|
||
4 | ** Earth Resource Mapping Ltd, and can only be used under
|
||
5 | ** one of the three licenses as described in the
|
||
6 | ** license.txt file supplied with this distribution.
|
||
7 | ** See separate license.txt file for license details
|
||
8 | ** and conditions.
|
||
9 | **
|
||
10 | ** This software is covered by US patent #6,442,298,
|
||
11 | ** #6,102,897 and #6,633,688. Rights to use these patents
|
||
12 | ** is included in the license agreements.
|
||
13 | **
|
||
14 | ** FILE: $Archive: /NCS/Source/include/NCSJPCMQCoder.h $
|
||
15 | ** CREATED: 12/02/2003 3:27:34 PM
|
||
16 | ** AUTHOR: Simon Cope
|
||
17 | ** PURPOSE: CNCSJPCMQCoder class header
|
||
18 | ** EDITS: [xx] ddMmmyy NAME COMMENTS
|
||
19 | *******************************************************/
|
||
20 | |||
21 | #ifndef NCSJPCMQCODER_H
|
||
22 | #define NCSJPCMQCODER_H
|
||
23 | |||
24 | #include "NCSJPCTypes.h" |
||
25 | |||
26 | //
|
||
27 | // Defining this uses a "Common Decoding Path" optimisation from the
|
||
28 | // JPEG2000 book by Taubman and MArcellin. Benchmarking indicates
|
||
29 | // this is SLOWER on on Pentium4 type CPU, as the small efficiency gain
|
||
30 | // from one less if test in the CDP path is more than offset by the
|
||
31 | // significant additional complexity in the non-CDP path, so it is
|
||
32 | // NOT defined by default.
|
||
33 | //
|
||
34 | #undef NCSJPC_USE_CDP_OPT
|
||
35 | |||
36 | //
|
||
37 | // Inline certain functions for performance improvements,
|
||
38 | // including SetCurCtx() and Renormd().
|
||
39 | //
|
||
40 | #define NCSJPC_MQ_INLINE NCS_INLINE
|
||
41 | #define NCSJPC_MQC_NUMCTXS 19 |
||
42 | |||
43 | /**
|
||
44 | * CNCSJPCMQCoder class - the JPC MQ Coder.
|
||
45 | *
|
||
46 | * @author Simon Cope
|
||
47 | * @version $Revision$ $Author$ $Date$
|
||
48 | */
|
||
49 | class NCSJPC_EXPORT_ALL CNCSJPCMQCoder { |
||
50 | public:
|
||
51 | CNCSJPCMQCoder(); |
||
52 | virtual ~CNCSJPCMQCoder(); |
||
53 | |||
54 | static void InitDec(UINT8 *pData, UINT32 nLen, bool bFirstSeg); |
||
55 | static void InitEnc(UINT8 *pData, UINT32 nLen); |
||
56 | static void Flush(); |
||
57 | #ifdef NCSJPC_USE_CDP_OPT
|
||
58 | static NCSJPC_MQ_INLINE INT32 Decode(UINT8 nCtx) {
|
||
59 | UINT16 nQEval = sm_Contexts[nCtx].nQEval; |
||
60 | INT32 d = sm_Contexts[nCtx].nD; |
||
61 | |||
62 | sm_D -= nQEval; |
||
63 | if(sm_D < 0) { |
||
64 | UINT8 n; |
||
65 | sm_A += sm_D; |
||
66 | sm_C.m_CHiLo.m_CHigh += sm_D; |
||
67 | |||
68 | if((INT16)sm_C.m_CHiLo.m_CHigh >= 0) { |
||
69 | |||
70 | // MPS Exchange
|
||
71 | if(sm_A < nQEval) {
|
||
72 | d = !d; |
||
73 | n = sm_Contexts[nCtx].nNLPS; |
||
74 | } else {
|
||
75 | n = sm_Contexts[nCtx].nNMPS; |
||
76 | } |
||
77 | } else {
|
||
78 | sm_C.m_CHiLo.m_CHigh += nQEval; |
||
79 | //LPSExchange
|
||
80 | if(sm_A < nQEval) {
|
||
81 | n = sm_Contexts[nCtx].nNMPS; |
||
82 | } else {
|
||
83 | d = !d; |
||
84 | n = sm_Contexts[nCtx].nNLPS; |
||
85 | } |
||
86 | sm_A = nQEval; |
||
87 | } |
||
88 | sm_Contexts[nCtx] = sm_States[n]; |
||
89 | |||
90 | Renormd(); |
||
91 | |||
92 | if(sm_A - 0x8000 < sm_C.m_CHiLo.m_CHigh) { |
||
93 | sm_D = sm_A - 0x8000;
|
||
94 | sm_A -= sm_D; |
||
95 | sm_C.m_CHiLo.m_CHigh -= sm_D; |
||
96 | } else {
|
||
97 | sm_D = sm_C.m_CHiLo.m_CHigh; |
||
98 | sm_A -= sm_C.m_CHiLo.m_CHigh; |
||
99 | sm_C.m_CHiLo.m_CHigh = 0;
|
||
100 | } |
||
101 | return(d);
|
||
102 | } |
||
103 | return(d);
|
||
104 | }; |
||
105 | #else // NCSJPC_USE_CDP_OPT |
||
106 | static NCSJPC_MQ_INLINE INT32 Decode(UINT8 nCtx) {
|
||
107 | UINT16 nQEval = sm_Contexts[nCtx].nQEval; |
||
108 | INT32 d = sm_Contexts[nCtx].nD; |
||
109 | |||
110 | sm_A -= nQEval; |
||
111 | |||
112 | if (sm_C.m_CHiLo.m_CHigh >= nQEval) {
|
||
113 | sm_C.m_CHiLo.m_CHigh -= nQEval; |
||
114 | |||
115 | if (/*(INT16)sm_A >= 0) {*/sm_A < 0x8000) { |
||
116 | // MPS Exchange
|
||
117 | if (sm_A < nQEval) {
|
||
118 | d = !d; |
||
119 | sm_Contexts[nCtx] = sm_States[sm_Contexts[nCtx].nNLPS]; |
||
120 | } else {
|
||
121 | sm_Contexts[nCtx] = sm_States[sm_Contexts[nCtx].nNMPS]; |
||
122 | } |
||
123 | // Renormd MPS
|
||
124 | RenormDec(); |
||
125 | } |
||
126 | } else {
|
||
127 | //LPSExchange
|
||
128 | if (sm_A < nQEval) {
|
||
129 | sm_Contexts[nCtx] = sm_States[sm_Contexts[nCtx].nNMPS]; |
||
130 | } else {
|
||
131 | d = !d; |
||
132 | sm_Contexts[nCtx] = sm_States[sm_Contexts[nCtx].nNLPS]; |
||
133 | } |
||
134 | sm_A = nQEval; |
||
135 | // Renormd LPS
|
||
136 | RenormDec(); |
||
137 | } |
||
138 | return(d);
|
||
139 | }; |
||
140 | #endif // NCSJPC_USE_CDP_OPT |
||
141 | // static NCSJPC_MQ_INLINE void Encode(INT32 d, UINT8 nCtx)
|
||
142 | // {
|
||
143 | // sm_SymbolStream[sm_nSymbolStream++] = d;
|
||
144 | // sm_SymbolStream[sm_nSymbolStream++] = nCtx;
|
||
145 | // }
|
||
146 | |||
147 | static NCSJPC_MQ_INLINE void Encode(INT32 d, UINT8 nCtx) |
||
148 | { |
||
149 | if (sm_Contexts[nCtx].nD == d) {
|
||
150 | UINT16 nQEval = sm_Contexts[nCtx].nQEval; |
||
151 | sm_A -= nQEval; |
||
152 | if (sm_A < 0x8000) { |
||
153 | if (sm_A >= nQEval) {
|
||
154 | sm_C.m_C24 += nQEval; |
||
155 | } else {
|
||
156 | sm_A = nQEval; |
||
157 | } |
||
158 | sm_Contexts[nCtx] = sm_States[sm_Contexts[nCtx].nNMPS]; |
||
159 | RenormEnc(); |
||
160 | } else {
|
||
161 | sm_C.m_C24 += nQEval; |
||
162 | } |
||
163 | } else {
|
||
164 | UINT16 nQEval = sm_Contexts[nCtx].nQEval; |
||
165 | sm_A -= nQEval; |
||
166 | |||
167 | if (sm_A < nQEval) {
|
||
168 | sm_C.m_C24 += nQEval; |
||
169 | } else {
|
||
170 | sm_A = nQEval; |
||
171 | } |
||
172 | sm_Contexts[nCtx] = sm_States[sm_Contexts[nCtx].nNLPS]; |
||
173 | RenormEnc(); |
||
174 | } |
||
175 | }; |
||
176 | static void ResetStates(); |
||
177 | static void SetState(UINT8 nCtx, int msb, int prob); |
||
178 | static INT32 GetBit();
|
||
179 | static void SetBits(); |
||
180 | //private:
|
||
181 | struct CHiLo {
|
||
182 | #ifdef NCSBO_MSBFIRST
|
||
183 | UINT16 m_CHigh; |
||
184 | UINT8 m_CLow; |
||
185 | UINT8 __pad[1];
|
||
186 | #else
|
||
187 | UINT8 __pad[1];
|
||
188 | UINT8 m_CLow; |
||
189 | UINT16 m_CHigh; |
||
190 | #endif
|
||
191 | }; |
||
192 | |||
193 | static union CHiLoUnion { |
||
194 | struct CHiLo m_CHiLo;
|
||
195 | UINT32 m_C24; |
||
196 | } sm_C; |
||
197 | |||
198 | #ifdef NCSJPC_USE_CDP_OPT
|
||
199 | static INT32 sm_D;
|
||
200 | #endif // NCSJPC_USE_CDP_OPT |
||
201 | static UINT16 sm_A;
|
||
202 | static UINT16 sm_nCT;
|
||
203 | static INT32 sm_nIndex;
|
||
204 | static UINT8 *sm_pB;
|
||
205 | //static UINT8 sm_SymbolStream[16384];//FIXME
|
||
206 | //static UINT32 sm_nSymbolStream;
|
||
207 | // The extra pad bytes helps with alignment and makes it faster
|
||
208 | typedef struct State { |
||
209 | UINT16 nQEval; |
||
210 | UINT16 nD; |
||
211 | UINT8 nNMPS; |
||
212 | UINT8 nNLPS; |
||
213 | UINT8 __pad[2];
|
||
214 | } State; |
||
215 | |||
216 | static State sm_Contexts[NCSJPC_MQC_NUMCTXS];
|
||
217 | static const State sm_States[47*2]; |
||
218 | static UINT8 sm_ShiftLut[4096]; |
||
219 | |||
220 | static void ByteIn(); |
||
221 | static void ByteOut(); |
||
222 | static void RenormDec(); |
||
223 | static void RenormEnc(); |
||
224 | }; |
||
225 | |||
226 | #endif // !NCSJPCMQCODER_H |