Statistics
| Revision:

svn-gvsig-desktop / tags / extI18n-0.1.0-1045_8 / libraries / libjni-ecw / include / NCSJPCMQCoder.h @ 40799

History | View | Annotate | Download (5.59 KB)

1
/********************************************************
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: 3538 $ $Author: nacho $ $Date: 2006-01-09 12:56:54 +0100 (Mon, 09 Jan 2006) $ 
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