1// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "JBig2_GeneralDecoder.h"
8#include "JBig2_ArithDecoder.h"
9#include "JBig2_ArithIntDecoder.h"
10#include "JBig2_HuffmanDecoder.h"
11#include "JBig2_HuffmanTable.h"
12#include "JBig2_PatternDict.h"
13CJBig2_Image *CJBig2_GRDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
14{
15    if (GBW == 0 || GBH == 0) {
16        CJBig2_Image* pImage;
17        JBIG2_ALLOC(pImage, CJBig2_Image(GBW, GBH));
18        return pImage;
19    }
20    if(GBTEMPLATE == 0) {
21        if((GBAT[0] == 3) && (GBAT[1] == (signed char) - 1)
22                && (GBAT[2] == (signed char) - 3) && (GBAT[3] == (signed char) - 1)
23                && (GBAT[4] == 2) && (GBAT[5] == (signed char) - 2)
24                && (GBAT[6] == (signed char) - 2) && (GBAT[7] == (signed char) - 2)) {
25            return decode_Arith_Template0_opt3(pArithDecoder, gbContext);
26        } else {
27            return decode_Arith_Template0_unopt(pArithDecoder, gbContext);
28        }
29    } else if(GBTEMPLATE == 1) {
30        if((GBAT[0] == 3) && (GBAT[1] == (signed char) - 1)) {
31            return decode_Arith_Template1_opt3(pArithDecoder, gbContext);
32        } else {
33            return decode_Arith_Template1_unopt(pArithDecoder, gbContext);
34        }
35    } else if(GBTEMPLATE == 2) {
36        if((GBAT[0] == 2) && (GBAT[1] == (signed char) - 1)) {
37            return decode_Arith_Template2_opt3(pArithDecoder, gbContext);
38        } else {
39            return decode_Arith_Template2_unopt(pArithDecoder, gbContext);
40        }
41    } else {
42        if((GBAT[0] == 2) && (GBAT[1] == (signed char) - 1)) {
43            return decode_Arith_Template3_opt3(pArithDecoder, gbContext);
44        } else {
45            return decode_Arith_Template3_unopt(pArithDecoder, gbContext);
46        }
47    }
48}
49CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
50{
51    FX_BOOL LTP, SLTP, bVal;
52    FX_DWORD CONTEXT;
53    CJBig2_Image *GBREG;
54    FX_DWORD line1, line2, line3;
55    LTP = 0;
56    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
57    GBREG->fill(0);
58    for(FX_DWORD h = 0; h < GBH; h++) {
59        if(TPGDON) {
60            SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
61            LTP = LTP ^ SLTP;
62        }
63        if(LTP == 1) {
64            GBREG->copyLine(h, h - 1);
65        } else {
66            line1 = GBREG->getPixel(2, h - 2);
67            line1 |= GBREG->getPixel(1, h - 2) << 1;
68            line1 |= GBREG->getPixel(0, h - 2) << 2;
69            line2 = GBREG->getPixel(3, h - 1);
70            line2 |= GBREG->getPixel(2, h - 1) << 1;
71            line2 |= GBREG->getPixel(1, h - 1) << 2;
72            line2 |= GBREG->getPixel(0, h - 1) << 3;
73            line3 = 0;
74            for(FX_DWORD w = 0; w < GBW; w++) {
75                if(USESKIP && SKIP->getPixel(w, h)) {
76                    bVal = 0;
77                } else {
78                    CONTEXT = line3;
79                    CONTEXT |= line2 << 4;
80                    CONTEXT |= line1 << 11;
81                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
82                }
83                if(bVal) {
84                    GBREG->setPixel(w, h, bVal);
85                }
86                line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x1f;
87                line2 = ((line2 << 1) | GBREG->getPixel(w + 4, h - 1)) & 0x7f;
88                line3 = ((line3 << 1) | bVal) & 0x0f;
89            }
90        }
91    }
92    return GBREG;
93}
94CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
95{
96    FX_BOOL LTP, SLTP, bVal;
97    FX_DWORD CONTEXT;
98    CJBig2_Image *GBREG;
99    FX_DWORD line1, line2;
100    FX_BYTE *pLine, cVal;
101    FX_INTPTR nStride, nStride2;
102    FX_INT32 nBits, k;
103    LTP = 0;
104    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
105    if (GBREG->m_pData == NULL) {
106        delete GBREG;
107        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
108        return NULL;
109    }
110    pLine = GBREG->m_pData;
111    nStride = GBREG->m_nStride;
112    nStride2 = nStride << 1;
113    for(FX_DWORD h = 0; h < GBH; h++) {
114        if(TPGDON) {
115            SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
116            LTP = LTP ^ SLTP;
117        }
118        if(LTP == 1) {
119            GBREG->copyLine(h, h - 1);
120        } else {
121            line1 = (h > 1) ? pLine[-nStride2] << 6 : 0;
122            line2 = (h > 0) ? pLine[-nStride] : 0;
123            CONTEXT = (line1 & 0xf800) | (line2 & 0x07f0);
124            for(FX_DWORD w = 0; w < GBW; w += 8) {
125                if(w + 8 < GBW) {
126                    nBits = 8;
127                    if(h > 1) {
128                        line1 = (line1 << 8) | (pLine[-nStride2 + (w >> 3) + 1] << 6);
129                    }
130                    if(h > 0) {
131                        line2 = (line2 << 8) | (pLine[-nStride + (w >> 3) + 1]);
132                    }
133                } else {
134                    nBits = GBW - w;
135                    if(h > 1) {
136                        line1 <<= 8;
137                    }
138                    if(h > 0) {
139                        line2 <<= 8;
140                    }
141                }
142                cVal = 0;
143                for(k = 0; k < nBits; k++) {
144                    if(USESKIP && SKIP->getPixel(w, h)) {
145                        bVal = 0;
146                    } else {
147                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
148                    }
149                    cVal |= bVal << (7 - k);
150                    CONTEXT = ((CONTEXT & 0x7bf7) << 1) | bVal
151                              | ((line1 >> (7 - k)) & 0x0800)
152                              | ((line2 >> (7 - k)) & 0x0010);
153                }
154                pLine[w >> 3] = cVal;
155            }
156        }
157        pLine += nStride;
158    }
159    return GBREG;
160}
161CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
162{
163    FX_BOOL LTP, SLTP, bVal;
164    FX_DWORD CONTEXT;
165    CJBig2_Image *GBREG;
166    FX_DWORD line1, line2;
167    FX_BYTE *pLine, *pLine1, *pLine2, cVal;
168    FX_INT32 nStride, nStride2, k;
169    FX_INT32 nLineBytes, nBitsLeft, cc;
170    LTP = 0;
171    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
172    if (GBREG->m_pData == NULL) {
173        delete GBREG;
174        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
175        return NULL;
176    }
177    pLine = GBREG->m_pData;
178    nStride = GBREG->m_nStride;
179    nStride2 = nStride << 1;
180    nLineBytes = ((GBW + 7) >> 3) - 1;
181    nBitsLeft = GBW - (nLineBytes << 3);
182    FX_DWORD height = GBH & 0x7fffffff;
183    for(FX_DWORD h = 0; h < height; h++) {
184        if(TPGDON) {
185            SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
186            LTP = LTP ^ SLTP;
187        }
188        if(LTP == 1) {
189            GBREG->copyLine(h, h - 1);
190        } else {
191            if(h > 1) {
192                pLine1 = pLine - nStride2;
193                pLine2 = pLine - nStride;
194                line1 = (*pLine1++) << 6;
195                line2 = *pLine2++;
196                CONTEXT = ((line1 & 0xf800) | (line2 & 0x07f0));
197                for(cc = 0; cc < nLineBytes; cc++) {
198                    line1 = (line1 << 8) | ((*pLine1++) << 6);
199                    line2 = (line2 << 8) | (*pLine2++);
200                    cVal = 0;
201                    for(k = 7; k >= 0; k--) {
202                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
203                        cVal |= bVal << k;
204                        CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
205                                   | ((line1 >> k) & 0x0800)
206                                   | ((line2 >> k) & 0x0010));
207                    }
208                    pLine[cc] = cVal;
209                }
210                line1 <<= 8;
211                line2 <<= 8;
212                cVal = 0;
213                for(k = 0; k < nBitsLeft; k++) {
214                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
215                    cVal |= bVal << (7 - k);
216                    CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
217                               | ((line1 >> (7 - k)) & 0x0800)
218                               | ((line2 >> (7 - k)) & 0x0010));
219                }
220                pLine[nLineBytes] = cVal;
221            } else {
222                pLine2 = pLine - nStride;
223                line2 = (h & 1) ? (*pLine2++) : 0;
224                CONTEXT = (line2 & 0x07f0);
225                for(cc = 0; cc < nLineBytes; cc++) {
226                    if(h & 1) {
227                        line2 = (line2 << 8) | (*pLine2++);
228                    }
229                    cVal = 0;
230                    for(k = 7; k >= 0; k--) {
231                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
232                        cVal |= bVal << k;
233                        CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
234                                   | ((line2 >> k) & 0x0010));
235                    }
236                    pLine[cc] = cVal;
237                }
238                line2 <<= 8;
239                cVal = 0;
240                for(k = 0; k < nBitsLeft; k++) {
241                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
242                    cVal |= bVal << (7 - k);
243                    CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
244                               | (((line2 >> (7 - k))) & 0x0010));
245                }
246                pLine[nLineBytes] = cVal;
247            }
248        }
249        pLine += nStride;
250    }
251    return GBREG;
252}
253CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
254{
255    FX_BOOL LTP, SLTP, bVal;
256    FX_DWORD CONTEXT;
257    CJBig2_Image *GBREG;
258    FX_DWORD line1, line2, line3;
259    LTP = 0;
260    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
261    GBREG->fill(0);
262    for(FX_DWORD h = 0; h < GBH; h++) {
263        if(TPGDON) {
264            SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
265            LTP = LTP ^ SLTP;
266        }
267        if(LTP == 1) {
268            GBREG->copyLine(h, h - 1);
269        } else {
270            line1 = GBREG->getPixel(1, h - 2);
271            line1 |= GBREG->getPixel(0, h - 2) << 1;
272            line2 = GBREG->getPixel(2, h - 1);
273            line2 |= GBREG->getPixel(1, h - 1) << 1;
274            line2 |= GBREG->getPixel(0, h - 1) << 2;
275            line3 = 0;
276            for(FX_DWORD w = 0; w < GBW; w++) {
277                if(USESKIP && SKIP->getPixel(w, h)) {
278                    bVal = 0;
279                } else {
280                    CONTEXT = line3;
281                    CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
282                    CONTEXT |= line2 << 5;
283                    CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
284                    CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
285                    CONTEXT |= line1 << 12;
286                    CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
287                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
288                }
289                if(bVal) {
290                    GBREG->setPixel(w, h, bVal);
291                }
292                line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
293                line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
294                line3 = ((line3 << 1) | bVal) & 0x0f;
295            }
296        }
297    }
298    return GBREG;
299}
300CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
301{
302    FX_BOOL LTP, SLTP, bVal;
303    FX_DWORD CONTEXT;
304    CJBig2_Image *GBREG;
305    FX_DWORD line1, line2, line3;
306    LTP = 0;
307    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
308    GBREG->fill(0);
309    for(FX_DWORD h = 0; h < GBH; h++) {
310        if(TPGDON) {
311            SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
312            LTP = LTP ^ SLTP;
313        }
314        if(LTP == 1) {
315            GBREG->copyLine(h, h - 1);
316        } else {
317            line1 = GBREG->getPixel(2, h - 2);
318            line1 |= GBREG->getPixel(1, h - 2) << 1;
319            line1 |= GBREG->getPixel(0, h - 2) << 2;
320            line2 = GBREG->getPixel(3, h - 1);
321            line2 |= GBREG->getPixel(2, h - 1) << 1;
322            line2 |= GBREG->getPixel(1, h - 1) << 2;
323            line2 |= GBREG->getPixel(0, h - 1) << 3;
324            line3 = 0;
325            for(FX_DWORD w = 0; w < GBW; w++) {
326                if(USESKIP && SKIP->getPixel(w, h)) {
327                    bVal = 0;
328                } else {
329                    CONTEXT = line3;
330                    CONTEXT |= line2 << 3;
331                    CONTEXT |= line1 << 9;
332                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
333                }
334                if(bVal) {
335                    GBREG->setPixel(w, h, bVal);
336                }
337                line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
338                line2 = ((line2 << 1) | GBREG->getPixel(w + 4, h - 1)) & 0x3f;
339                line3 = ((line3 << 1) | bVal) & 0x07;
340            }
341        }
342    }
343    return GBREG;
344}
345CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
346{
347    FX_BOOL LTP, SLTP, bVal;
348    FX_DWORD CONTEXT;
349    CJBig2_Image *GBREG;
350    FX_DWORD line1, line2;
351    FX_BYTE *pLine, cVal;
352    FX_INTPTR nStride, nStride2;
353    FX_INT32 nBits, k;
354    LTP = 0;
355    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
356    if (GBREG->m_pData == NULL) {
357        delete GBREG;
358        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
359        return NULL;
360    }
361    pLine = GBREG->m_pData;
362    nStride = GBREG->m_nStride;
363    nStride2 = nStride << 1;
364    for(FX_DWORD h = 0; h < GBH; h++) {
365        if(TPGDON) {
366            SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
367            LTP = LTP ^ SLTP;
368        }
369        if(LTP == 1) {
370            GBREG->copyLine(h, h - 1);
371        } else {
372            line1 = (h > 1) ? pLine[-nStride2] << 4 : 0;
373            line2 = (h > 0) ? pLine[-nStride] : 0;
374            CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
375            for(FX_DWORD w = 0; w < GBW; w += 8) {
376                if(w + 8 < GBW) {
377                    nBits = 8;
378                    if(h > 1) {
379                        line1 = (line1 << 8) | (pLine[-nStride2 + (w >> 3) + 1] << 4);
380                    }
381                    if(h > 0) {
382                        line2 = (line2 << 8) | (pLine[-nStride + (w >> 3) + 1]);
383                    }
384                } else {
385                    nBits = GBW - w;
386                    if(h > 1) {
387                        line1 <<= 8;
388                    }
389                    if(h > 0) {
390                        line2 <<= 8;
391                    }
392                }
393                cVal = 0;
394                for(k = 0; k < nBits; k++) {
395                    if(USESKIP && SKIP->getPixel(w, h)) {
396                        bVal = 0;
397                    } else {
398                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
399                    }
400                    cVal |= bVal << (7 - k);
401                    CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
402                              | ((line1 >> (7 - k)) & 0x0200)
403                              | ((line2 >> (8 - k)) & 0x0008);
404                }
405                pLine[w >> 3] = cVal;
406            }
407        }
408        pLine += nStride;
409    }
410    return GBREG;
411}
412CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
413{
414    FX_BOOL LTP, SLTP, bVal;
415    FX_DWORD CONTEXT;
416    CJBig2_Image *GBREG;
417    FX_DWORD line1, line2;
418    FX_BYTE *pLine, *pLine1, *pLine2, cVal;
419    FX_INT32 nStride, nStride2, k;
420    FX_INT32 nLineBytes, nBitsLeft, cc;
421    LTP = 0;
422    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
423    if (GBREG->m_pData == NULL) {
424        delete GBREG;
425        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
426        return NULL;
427    }
428    pLine = GBREG->m_pData;
429    nStride = GBREG->m_nStride;
430    nStride2 = nStride << 1;
431    nLineBytes = ((GBW + 7) >> 3) - 1;
432    nBitsLeft = GBW - (nLineBytes << 3);
433    for(FX_DWORD h = 0; h < GBH; h++) {
434        if(TPGDON) {
435            SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
436            LTP = LTP ^ SLTP;
437        }
438        if(LTP == 1) {
439            GBREG->copyLine(h, h - 1);
440        } else {
441            if(h > 1) {
442                pLine1 = pLine - nStride2;
443                pLine2 = pLine - nStride;
444                line1 = (*pLine1++) << 4;
445                line2 = *pLine2++;
446                CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
447                for(cc = 0; cc < nLineBytes; cc++) {
448                    line1 = (line1 << 8) | ((*pLine1++) << 4);
449                    line2 = (line2 << 8) | (*pLine2++);
450                    cVal = 0;
451                    for(k = 7; k >= 0; k--) {
452                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
453                        cVal |= bVal << k;
454                        CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
455                                  | ((line1 >> k) & 0x0200)
456                                  | ((line2 >> (k + 1)) & 0x0008);
457                    }
458                    pLine[cc] = cVal;
459                }
460                line1 <<= 8;
461                line2 <<= 8;
462                cVal = 0;
463                for(k = 0; k < nBitsLeft; k++) {
464                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
465                    cVal |= bVal << (7 - k);
466                    CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
467                              | ((line1 >> (7 - k)) & 0x0200)
468                              | ((line2 >> (8 - k)) & 0x0008);
469                }
470                pLine[nLineBytes] = cVal;
471            } else {
472                pLine2 = pLine - nStride;
473                line2 = (h & 1) ? (*pLine2++) : 0;
474                CONTEXT = (line2 >> 1) & 0x01f8;
475                for(cc = 0; cc < nLineBytes; cc++) {
476                    if(h & 1) {
477                        line2 = (line2 << 8) | (*pLine2++);
478                    }
479                    cVal = 0;
480                    for(k = 7; k >= 0; k--) {
481                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
482                        cVal |= bVal << k;
483                        CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
484                                  | ((line2 >> (k + 1)) & 0x0008);
485                    }
486                    pLine[cc] = cVal;
487                }
488                line2 <<= 8;
489                cVal = 0;
490                for(k = 0; k < nBitsLeft; k++) {
491                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
492                    cVal |= bVal << (7 - k);
493                    CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
494                              | ((line2 >> (8 - k)) & 0x0008);
495                }
496                pLine[nLineBytes] = cVal;
497            }
498        }
499        pLine += nStride;
500    }
501    return GBREG;
502}
503CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
504{
505    FX_BOOL LTP, SLTP, bVal;
506    FX_DWORD CONTEXT;
507    CJBig2_Image *GBREG;
508    FX_DWORD line1, line2, line3;
509    LTP = 0;
510    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
511    GBREG->fill(0);
512    for(FX_DWORD h = 0; h < GBH; h++) {
513        if(TPGDON) {
514            SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
515            LTP = LTP ^ SLTP;
516        }
517        if(LTP == 1) {
518            GBREG->copyLine(h, h - 1);
519        } else {
520            line1 = GBREG->getPixel(2, h - 2);
521            line1 |= GBREG->getPixel(1, h - 2) << 1;
522            line1 |= GBREG->getPixel(0, h - 2) << 2;
523            line2 = GBREG->getPixel(2, h - 1);
524            line2 |= GBREG->getPixel(1, h - 1) << 1;
525            line2 |= GBREG->getPixel(0, h - 1) << 2;
526            line3 = 0;
527            for(FX_DWORD w = 0; w < GBW; w++) {
528                if(USESKIP && SKIP->getPixel(w, h)) {
529                    bVal = 0;
530                } else {
531                    CONTEXT = line3;
532                    CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
533                    CONTEXT |= line2 << 4;
534                    CONTEXT |= line1 << 9;
535                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
536                }
537                if(bVal) {
538                    GBREG->setPixel(w, h, bVal);
539                }
540                line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
541                line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
542                line3 = ((line3 << 1) | bVal) & 0x07;
543            }
544        }
545    }
546    return GBREG;
547}
548CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
549{
550    FX_BOOL LTP, SLTP, bVal;
551    FX_DWORD CONTEXT;
552    CJBig2_Image *GBREG;
553    FX_DWORD line1, line2, line3;
554    LTP = 0;
555    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
556    GBREG->fill(0);
557    for(FX_DWORD h = 0; h < GBH; h++) {
558        if(TPGDON) {
559            SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
560            LTP = LTP ^ SLTP;
561        }
562        if(LTP == 1) {
563            GBREG->copyLine(h, h - 1);
564        } else {
565            line1 = GBREG->getPixel(1, h - 2);
566            line1 |= GBREG->getPixel(0, h - 2) << 1;
567            line2 = GBREG->getPixel(2, h - 1);
568            line2 |= GBREG->getPixel(1, h - 1) << 1;
569            line2 |= GBREG->getPixel(0, h - 1) << 2;
570            line3 = 0;
571            for(FX_DWORD w = 0; w < GBW; w++) {
572                if(USESKIP && SKIP->getPixel(w, h)) {
573                    bVal = 0;
574                } else {
575                    CONTEXT = line3;
576                    CONTEXT |= line2 << 2;
577                    CONTEXT |= line1 << 7;
578                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
579                }
580                if(bVal) {
581                    GBREG->setPixel(w, h, bVal);
582                }
583                line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
584                line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
585                line3 = ((line3 << 1) | bVal) & 0x03;
586            }
587        }
588    }
589    return GBREG;
590}
591CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
592{
593    FX_BOOL LTP, SLTP, bVal;
594    FX_DWORD CONTEXT;
595    CJBig2_Image *GBREG;
596    FX_DWORD line1, line2;
597    FX_BYTE *pLine, cVal;
598    FX_INTPTR nStride, nStride2;
599    FX_INT32 nBits, k;
600    LTP = 0;
601    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
602    if (GBREG->m_pData == NULL) {
603        delete GBREG;
604        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
605        return NULL;
606    }
607    pLine = GBREG->m_pData;
608    nStride = GBREG->m_nStride;
609    nStride2 = nStride << 1;
610    for(FX_DWORD h = 0; h < GBH; h++) {
611        if(TPGDON) {
612            SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
613            LTP = LTP ^ SLTP;
614        }
615        if(LTP == 1) {
616            GBREG->copyLine(h, h - 1);
617        } else {
618            line1 = (h > 1) ? pLine[-nStride2] << 1 : 0;
619            line2 = (h > 0) ? pLine[-nStride] : 0;
620            CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
621            for(FX_DWORD w = 0; w < GBW; w += 8) {
622                if(w + 8 < GBW) {
623                    nBits = 8;
624                    if(h > 1) {
625                        line1 = (line1 << 8) | (pLine[-nStride2 + (w >> 3) + 1] << 1);
626                    }
627                    if(h > 0) {
628                        line2 = (line2 << 8) | (pLine[-nStride + (w >> 3) + 1]);
629                    }
630                } else {
631                    nBits = GBW - w;
632                    if(h > 1) {
633                        line1 <<= 8;
634                    }
635                    if(h > 0) {
636                        line2 <<= 8;
637                    }
638                }
639                cVal = 0;
640                for(k = 0; k < nBits; k++) {
641                    if(USESKIP && SKIP->getPixel(w, h)) {
642                        bVal = 0;
643                    } else {
644                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
645                    }
646                    cVal |= bVal << (7 - k);
647                    CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
648                              | ((line1 >> (7 - k)) & 0x0080)
649                              | ((line2 >> (10 - k)) & 0x0004);
650                }
651                pLine[w >> 3] = cVal;
652            }
653        }
654        pLine += nStride;
655    }
656    return GBREG;
657}
658CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
659{
660    FX_BOOL LTP, SLTP, bVal;
661    FX_DWORD CONTEXT;
662    CJBig2_Image *GBREG;
663    FX_DWORD line1, line2;
664    FX_BYTE *pLine, *pLine1, *pLine2, cVal;
665    FX_INT32 nStride, nStride2, k;
666    FX_INT32 nLineBytes, nBitsLeft, cc;
667    LTP = 0;
668    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
669    if (GBREG->m_pData == NULL) {
670        delete GBREG;
671        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
672        return NULL;
673    }
674    pLine = GBREG->m_pData;
675    nStride = GBREG->m_nStride;
676    nStride2 = nStride << 1;
677    nLineBytes = ((GBW + 7) >> 3) - 1;
678    nBitsLeft = GBW - (nLineBytes << 3);
679    for(FX_DWORD h = 0; h < GBH; h++) {
680        if(TPGDON) {
681            SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
682            LTP = LTP ^ SLTP;
683        }
684        if(LTP == 1) {
685            GBREG->copyLine(h, h - 1);
686        } else {
687            if(h > 1) {
688                pLine1 = pLine - nStride2;
689                pLine2 = pLine - nStride;
690                line1 = (*pLine1++) << 1;
691                line2 = *pLine2++;
692                CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
693                for(cc = 0; cc < nLineBytes; cc++) {
694                    line1 = (line1 << 8) | ((*pLine1++) << 1);
695                    line2 = (line2 << 8) | (*pLine2++);
696                    cVal = 0;
697                    for(k = 7; k >= 0; k--) {
698                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
699                        cVal |= bVal << k;
700                        CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
701                                  | ((line1 >> k) & 0x0080)
702                                  | ((line2 >> (k + 3)) & 0x0004);
703                    }
704                    pLine[cc] = cVal;
705                }
706                line1 <<= 8;
707                line2 <<= 8;
708                cVal = 0;
709                for(k = 0; k < nBitsLeft; k++) {
710                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
711                    cVal |= bVal << (7 - k);
712                    CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
713                              | ((line1 >> (7 - k)) & 0x0080)
714                              | ((line2 >> (10 - k)) & 0x0004);
715                }
716                pLine[nLineBytes] = cVal;
717            } else {
718                pLine2 = pLine - nStride;
719                line2 = (h & 1) ? (*pLine2++) : 0;
720                CONTEXT = (line2 >> 3) & 0x007c;
721                for(cc = 0; cc < nLineBytes; cc++) {
722                    if(h & 1) {
723                        line2 = (line2 << 8) | (*pLine2++);
724                    }
725                    cVal = 0;
726                    for(k = 7; k >= 0; k--) {
727                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
728                        cVal |= bVal << k;
729                        CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
730                                  | ((line2 >> (k + 3)) & 0x0004);
731                    }
732                    pLine[cc] = cVal;
733                }
734                line2 <<= 8;
735                cVal = 0;
736                for(k = 0; k < nBitsLeft; k++) {
737                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
738                    cVal |= bVal << (7 - k);
739                    CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
740                              | (((line2 >> (10 - k))) & 0x0004);
741                }
742                pLine[nLineBytes] = cVal;
743            }
744        }
745        pLine += nStride;
746    }
747    return GBREG;
748}
749CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
750{
751    FX_BOOL LTP, SLTP, bVal;
752    FX_DWORD CONTEXT;
753    CJBig2_Image *GBREG;
754    FX_DWORD line1, line2, line3;
755    LTP = 0;
756    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
757    GBREG->fill(0);
758    for(FX_DWORD h = 0; h < GBH; h++) {
759        if(TPGDON) {
760            SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
761            LTP = LTP ^ SLTP;
762        }
763        if(LTP == 1) {
764            GBREG->copyLine(h, h - 1);
765        } else {
766            line1 = GBREG->getPixel(1, h - 2);
767            line1 |= GBREG->getPixel(0, h - 2) << 1;
768            line2 = GBREG->getPixel(1, h - 1);
769            line2 |= GBREG->getPixel(0, h - 1) << 1;
770            line3 = 0;
771            for(FX_DWORD w = 0; w < GBW; w++) {
772                if(USESKIP && SKIP->getPixel(w, h)) {
773                    bVal = 0;
774                } else {
775                    CONTEXT = line3;
776                    CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
777                    CONTEXT |= line2 << 3;
778                    CONTEXT |= line1 << 7;
779                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
780                }
781                if(bVal) {
782                    GBREG->setPixel(w, h, bVal);
783                }
784                line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
785                line2 = ((line2 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x0f;
786                line3 = ((line3 << 1) | bVal) & 0x03;
787            }
788        }
789    }
790    return GBREG;
791}
792CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
793{
794    FX_BOOL LTP, SLTP, bVal;
795    FX_DWORD CONTEXT;
796    CJBig2_Image *GBREG;
797    FX_DWORD line1, line2;
798    LTP = 0;
799    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
800    GBREG->fill(0);
801    for(FX_DWORD h = 0; h < GBH; h++) {
802        if(TPGDON) {
803            SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
804            LTP = LTP ^ SLTP;
805        }
806        if(LTP == 1) {
807            GBREG->copyLine(h, h - 1);
808        } else {
809            line1 = GBREG->getPixel(2, h - 1);
810            line1 |= GBREG->getPixel(1, h - 1) << 1;
811            line1 |= GBREG->getPixel(0, h - 1) << 2;
812            line2 = 0;
813            for(FX_DWORD w = 0; w < GBW; w++) {
814                if(USESKIP && SKIP->getPixel(w, h)) {
815                    bVal = 0;
816                } else {
817                    CONTEXT = line2;
818                    CONTEXT |= line1 << 4;
819                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
820                }
821                if(bVal) {
822                    GBREG->setPixel(w, h, bVal);
823                }
824                line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x3f;
825                line2 = ((line2 << 1) | bVal) & 0x0f;
826            }
827        }
828    }
829    return GBREG;
830}
831CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
832{
833    FX_BOOL LTP, SLTP, bVal;
834    FX_DWORD CONTEXT;
835    CJBig2_Image *GBREG;
836    FX_DWORD line1;
837    FX_BYTE *pLine, cVal;
838    FX_INTPTR nStride, nStride2;
839    FX_INT32 nBits, k;
840    LTP = 0;
841    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
842    if (GBREG->m_pData == NULL) {
843        delete GBREG;
844        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
845        return NULL;
846    }
847    pLine = GBREG->m_pData;
848    nStride = GBREG->m_nStride;
849    nStride2 = nStride << 1;
850    for(FX_DWORD h = 0; h < GBH; h++) {
851        if(TPGDON) {
852            SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
853            LTP = LTP ^ SLTP;
854        }
855        if(LTP == 1) {
856            GBREG->copyLine(h, h - 1);
857        } else {
858            line1 = (h > 0) ? pLine[-nStride] : 0;
859            CONTEXT = (line1 >> 1) & 0x03f0;
860            for(FX_DWORD w = 0; w < GBW; w += 8) {
861                if(w + 8 < GBW) {
862                    nBits = 8;
863                    if(h > 0) {
864                        line1 = (line1 << 8) | (pLine[-nStride + (w >> 3) + 1]);
865                    }
866                } else {
867                    nBits = GBW - w;
868                    if(h > 0) {
869                        line1 <<= 8;
870                    }
871                }
872                cVal = 0;
873                for(k = 0; k < nBits; k++) {
874                    if(USESKIP && SKIP->getPixel(w, h)) {
875                        bVal = 0;
876                    } else {
877                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
878                    }
879                    cVal |= bVal << (7 - k);
880                    CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
881                              | ((line1 >> (8 - k)) & 0x0010);
882                }
883                pLine[w >> 3] = cVal;
884            }
885        }
886        pLine += nStride;
887    }
888    return GBREG;
889}
890CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
891{
892    FX_BOOL LTP, SLTP, bVal;
893    FX_DWORD CONTEXT;
894    CJBig2_Image *GBREG;
895    FX_DWORD line1;
896    FX_BYTE *pLine, *pLine1, cVal;
897    FX_INT32 nStride, k;
898    FX_INT32 nLineBytes, nBitsLeft, cc;
899    LTP = 0;
900    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
901    if (GBREG->m_pData == NULL) {
902        delete GBREG;
903        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
904        return NULL;
905    }
906    pLine = GBREG->m_pData;
907    nStride = GBREG->m_nStride;
908    nLineBytes = ((GBW + 7) >> 3) - 1;
909    nBitsLeft = GBW - (nLineBytes << 3);
910    for(FX_DWORD h = 0; h < GBH; h++) {
911        if(TPGDON) {
912            SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
913            LTP = LTP ^ SLTP;
914        }
915        if(LTP == 1) {
916            GBREG->copyLine(h, h - 1);
917        } else {
918            if(h > 0) {
919                pLine1 = pLine - nStride;
920                line1 = *pLine1++;
921                CONTEXT = (line1 >> 1) & 0x03f0;
922                for(cc = 0; cc < nLineBytes; cc++) {
923                    line1 = (line1 << 8) | (*pLine1++);
924                    cVal = 0;
925                    for(k = 7; k >= 0; k--) {
926                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
927                        cVal |= bVal << k;
928                        CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
929                                  | ((line1 >> (k + 1)) & 0x0010);
930                    }
931                    pLine[cc] = cVal;
932                }
933                line1 <<= 8;
934                cVal = 0;
935                for(k = 0; k < nBitsLeft; k++) {
936                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
937                    cVal |= bVal << (7 - k);
938                    CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
939                              | ((line1 >> (8 - k)) & 0x0010);
940                }
941                pLine[nLineBytes] = cVal;
942            } else {
943                CONTEXT = 0;
944                for(cc = 0; cc < nLineBytes; cc++) {
945                    cVal = 0;
946                    for(k = 7; k >= 0; k--) {
947                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
948                        cVal |= bVal << k;
949                        CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
950                    }
951                    pLine[cc] = cVal;
952                }
953                cVal = 0;
954                for(k = 0; k < nBitsLeft; k++) {
955                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
956                    cVal |= bVal << (7 - k);
957                    CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
958                }
959                pLine[nLineBytes] = cVal;
960            }
961        }
962        pLine += nStride;
963    }
964    return GBREG;
965}
966CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
967{
968    FX_BOOL LTP, SLTP, bVal;
969    FX_DWORD CONTEXT;
970    CJBig2_Image *GBREG;
971    FX_DWORD line1, line2;
972    LTP = 0;
973    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
974    GBREG->fill(0);
975    for(FX_DWORD h = 0; h < GBH; h++) {
976        if(TPGDON) {
977            SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
978            LTP = LTP ^ SLTP;
979        }
980        if(LTP == 1) {
981            GBREG->copyLine(h, h - 1);
982        } else {
983            line1 = GBREG->getPixel(1, h - 1);
984            line1 |= GBREG->getPixel(0, h - 1) << 1;
985            line2 = 0;
986            for(FX_DWORD w = 0; w < GBW; w++) {
987                if(USESKIP && SKIP->getPixel(w, h)) {
988                    bVal = 0;
989                } else {
990                    CONTEXT = line2;
991                    CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
992                    CONTEXT |= line1 << 5;
993                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
994                }
995                if(bVal) {
996                    GBREG->setPixel(w, h, bVal);
997                }
998                line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x1f;
999                line2 = ((line2 << 1) | bVal) & 0x0f;
1000            }
1001        }
1002    }
1003    return GBREG;
1004}
1005CJBig2_Image *CJBig2_GRDProc::decode_Arith_V2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
1006{
1007    FX_BOOL LTP, SLTP, bVal;
1008    FX_DWORD CONTEXT;
1009    CJBig2_Image *GBREG;
1010    FX_DWORD line1, line2, line3;
1011    LTP = 0;
1012    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
1013    GBREG->fill(0);
1014    for(FX_DWORD h = 0; h < GBH; h++) {
1015        if(TPGDON) {
1016            switch(GBTEMPLATE) {
1017                case 0:
1018                    CONTEXT = 0x9b25;
1019                    break;
1020                case 1:
1021                    CONTEXT = 0x0795;
1022                    break;
1023                case 2:
1024                    CONTEXT = 0x00e5;
1025                    break;
1026                case 3:
1027                    CONTEXT = 0x0195;
1028                    break;
1029            }
1030            SLTP = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1031            LTP = LTP ^ SLTP;
1032        }
1033        if(LTP == 1) {
1034            GBREG->copyLine(h, h - 1);
1035        } else {
1036            switch(GBTEMPLATE) {
1037                case 0: {
1038                        line1 = GBREG->getPixel(1, h - 2);
1039                        line1 |= GBREG->getPixel(0, h - 2) << 1;
1040                        line2 = GBREG->getPixel(2, h - 1);
1041                        line2 |= GBREG->getPixel(1, h - 1) << 1;
1042                        line2 |= GBREG->getPixel(0, h - 1) << 2;
1043                        line3 = 0;
1044                        for(FX_DWORD w = 0; w < GBW; w++) {
1045                            if(USESKIP && SKIP->getPixel(w, h)) {
1046                                bVal = 0;
1047                            } else {
1048                                CONTEXT = line3;
1049                                CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1050                                CONTEXT |= line2 << 5;
1051                                CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
1052                                CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
1053                                CONTEXT |= line1 << 12;
1054                                CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
1055                                bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1056                            }
1057                            if(bVal) {
1058                                GBREG->setPixel(w, h, bVal);
1059                            }
1060                            line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
1061                            line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
1062                            line3 = ((line3 << 1) | bVal) & 0x0f;
1063                        }
1064                    }
1065                    break;
1066                case 1: {
1067                        line1 = GBREG->getPixel(2, h - 2);
1068                        line1 |= GBREG->getPixel(1, h - 2) << 1;
1069                        line1 |= GBREG->getPixel(0, h - 2) << 2;
1070                        line2 = GBREG->getPixel(2, h - 1);
1071                        line2 |= GBREG->getPixel(1, h - 1) << 1;
1072                        line2 |= GBREG->getPixel(0, h - 1) << 2;
1073                        line3 = 0;
1074                        for(FX_DWORD w = 0; w < GBW; w++) {
1075                            if(USESKIP && SKIP->getPixel(w, h)) {
1076                                bVal = 0;
1077                            } else {
1078                                CONTEXT = line3;
1079                                CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
1080                                CONTEXT |= line2 << 4;
1081                                CONTEXT |= line1 << 9;
1082                                bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1083                            }
1084                            if(bVal) {
1085                                GBREG->setPixel(w, h, bVal);
1086                            }
1087                            line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
1088                            line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
1089                            line3 = ((line3 << 1) | bVal) & 0x07;
1090                        }
1091                    }
1092                    break;
1093                case 2: {
1094                        line1 = GBREG->getPixel(1, h - 2);
1095                        line1 |= GBREG->getPixel(0, h - 2) << 1;
1096                        line2 = GBREG->getPixel(1, h - 1);
1097                        line2 |= GBREG->getPixel(0, h - 1) << 1;
1098                        line3 = 0;
1099                        for(FX_DWORD w = 0; w < GBW; w++) {
1100                            if(USESKIP && SKIP->getPixel(w, h)) {
1101                                bVal = 0;
1102                            } else {
1103                                CONTEXT = line3;
1104                                CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
1105                                CONTEXT |= line2 << 3;
1106                                CONTEXT |= line1 << 7;
1107                                bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1108                            }
1109                            if(bVal) {
1110                                GBREG->setPixel(w, h, bVal);
1111                            }
1112                            line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
1113                            line2 = ((line2 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x0f;
1114                            line3 = ((line3 << 1) | bVal) & 0x03;
1115                        }
1116                    }
1117                    break;
1118                case 3: {
1119                        line1 = GBREG->getPixel(1, h - 1);
1120                        line1 |= GBREG->getPixel(0, h - 1) << 1;
1121                        line2 = 0;
1122                        for(FX_DWORD w = 0; w < GBW; w++) {
1123                            if(USESKIP && SKIP->getPixel(w, h)) {
1124                                bVal = 0;
1125                            } else {
1126                                CONTEXT = line2;
1127                                CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1128                                CONTEXT |= line1 << 5;
1129                                bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1130                            }
1131                            if(bVal) {
1132                                GBREG->setPixel(w, h, bVal);
1133                            }
1134                            line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x1f;
1135                            line2 = ((line2 << 1) | bVal) & 0x0f;
1136                        }
1137                    }
1138                    break;
1139            }
1140        }
1141    }
1142    return GBREG;
1143}
1144CJBig2_Image *CJBig2_GRDProc::decode_Arith_V1(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
1145{
1146    FX_BOOL LTP, SLTP, bVal;
1147    FX_DWORD CONTEXT = 0;
1148    CJBig2_Image *GBREG;
1149    LTP = 0;
1150    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
1151    GBREG->fill(0);
1152    for(FX_DWORD h = 0; h < GBH; h++) {
1153        if(TPGDON) {
1154            switch(GBTEMPLATE) {
1155                case 0:
1156                    CONTEXT = 0x9b25;
1157                    break;
1158                case 1:
1159                    CONTEXT = 0x0795;
1160                    break;
1161                case 2:
1162                    CONTEXT = 0x00e5;
1163                    break;
1164                case 3:
1165                    CONTEXT = 0x0195;
1166                    break;
1167            }
1168            SLTP = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1169            LTP = LTP ^ SLTP;
1170        }
1171        if(LTP == 1) {
1172            for(FX_DWORD w = 0; w < GBW; w++) {
1173                GBREG->setPixel(w, h, GBREG->getPixel(w, h - 1));
1174            }
1175        } else {
1176            for(FX_DWORD w = 0; w < GBW; w++) {
1177                if(USESKIP && SKIP->getPixel(w, h)) {
1178                    GBREG->setPixel(w, h, 0);
1179                } else {
1180                    CONTEXT = 0;
1181                    switch(GBTEMPLATE) {
1182                        case 0:
1183                            CONTEXT |= GBREG->getPixel(w - 1, h);
1184                            CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1185                            CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
1186                            CONTEXT |= GBREG->getPixel(w - 4, h) << 3;
1187                            CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1188                            CONTEXT |= GBREG->getPixel(w + 2, h - 1) << 5;
1189                            CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 6;
1190                            CONTEXT |= GBREG->getPixel(w, h - 1) << 7;
1191                            CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 8;
1192                            CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 9;
1193                            CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
1194                            CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
1195                            CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 12;
1196                            CONTEXT |= GBREG->getPixel(w, h - 2) << 13;
1197                            CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 14;
1198                            CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
1199                            break;
1200                        case 1:
1201                            CONTEXT |= GBREG->getPixel(w - 1, h);
1202                            CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1203                            CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
1204                            CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
1205                            CONTEXT |= GBREG->getPixel(w + 2, h - 1) << 4;
1206                            CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 5;
1207                            CONTEXT |= GBREG->getPixel(w, h - 1) << 6;
1208                            CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 7;
1209                            CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 8;
1210                            CONTEXT |= GBREG->getPixel(w + 2, h - 2) << 9;
1211                            CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 10;
1212                            CONTEXT |= GBREG->getPixel(w, h - 2) << 11;
1213                            CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 12;
1214                            break;
1215                        case 2:
1216                            CONTEXT |= GBREG->getPixel(w - 1, h);
1217                            CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1218                            CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
1219                            CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 3;
1220                            CONTEXT |= GBREG->getPixel(w, h - 1) << 4;
1221                            CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 5;
1222                            CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 6;
1223                            CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 7;
1224                            CONTEXT |= GBREG->getPixel(w, h - 2) << 8;
1225                            CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 9;
1226                            break;
1227                        case 3:
1228                            CONTEXT |= GBREG->getPixel(w - 1, h);
1229                            CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1230                            CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
1231                            CONTEXT |= GBREG->getPixel(w - 4, h) << 3;
1232                            CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1233                            CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 5;
1234                            CONTEXT |= GBREG->getPixel(w, h - 1) << 6;
1235                            CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 7;
1236                            CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 8;
1237                            CONTEXT |= GBREG->getPixel(w - 3, h - 1) << 9;
1238                            break;
1239                    }
1240                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1241                    GBREG->setPixel(w, h, bVal);
1242                }
1243            }
1244        }
1245    }
1246    return GBREG;
1247}
1248CJBig2_Image *CJBig2_GRDProc::decode_MMR(CJBig2_BitStream *pStream)
1249{
1250    int bitpos, i;
1251    CJBig2_Image *pImage;
1252    JBIG2_ALLOC(pImage, CJBig2_Image(GBW, GBH));
1253    if (pImage->m_pData == NULL) {
1254        delete pImage;
1255        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
1256        return NULL;
1257    }
1258    bitpos = (int)pStream->getBitPos();
1259    _FaxG4Decode(m_pModule, pStream->getBuf(), pStream->getLength(), &bitpos, pImage->m_pData, GBW, GBH, pImage->m_nStride);
1260    pStream->setBitPos(bitpos);
1261    for(i = 0; (FX_DWORD)i < pImage->m_nStride * GBH; i++) {
1262        pImage->m_pData[i] = ~pImage->m_pData[i];
1263    }
1264    return pImage;
1265}
1266CJBig2_Image *CJBig2_GRRDProc::decode(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1267{
1268    if (GRW == 0 || GRH == 0) {
1269        CJBig2_Image* pImage;
1270        JBIG2_ALLOC(pImage, CJBig2_Image(GRW, GRH));
1271        return pImage;
1272    }
1273    if(GRTEMPLATE == 0) {
1274        if((GRAT[0] == (signed char) - 1) && (GRAT[1] == (signed char) - 1)
1275                && (GRAT[2] == (signed char) - 1) && (GRAT[3] == (signed char) - 1)
1276                && (GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
1277            return decode_Template0_opt(pArithDecoder, grContext);
1278        } else {
1279            return decode_Template0_unopt(pArithDecoder, grContext);
1280        }
1281    } else {
1282        if((GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
1283            return decode_Template1_opt(pArithDecoder, grContext);
1284        } else {
1285            return decode_Template1_unopt(pArithDecoder, grContext);
1286        }
1287    }
1288}
1289CJBig2_Image *CJBig2_GRRDProc::decode_Template0_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1290{
1291    FX_BOOL LTP, SLTP, bVal;
1292    FX_DWORD CONTEXT;
1293    CJBig2_Image *GRREG;
1294    FX_DWORD line1, line2, line3, line4, line5;
1295    LTP = 0;
1296    JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1297    GRREG->fill(0);
1298    for(FX_DWORD h = 0; h < GRH; h++) {
1299        if(TPGRON) {
1300            SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
1301            LTP = LTP ^ SLTP;
1302        }
1303        if(LTP == 0) {
1304            line1 = GRREG->getPixel(1, h - 1);
1305            line1 |= GRREG->getPixel(0, h - 1) << 1;
1306            line2 = 0;
1307            line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
1308            line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1) << 1;
1309            line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1310            line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1311            line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1312            line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1313            line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1314            line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1315            for(FX_DWORD w = 0; w < GRW; w++) {
1316                CONTEXT = line5;
1317                CONTEXT |= line4 << 3;
1318                CONTEXT |= line3 << 6;
1319                CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1320                CONTEXT |= line2 << 9;
1321                CONTEXT |= line1 << 10;
1322                CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1323                bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1324                GRREG->setPixel(w, h, bVal);
1325                line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
1326                line2 = ((line2 << 1) | bVal) & 0x01;
1327                line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY - 1)) & 0x03;
1328                line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1329                line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x07;
1330            }
1331        } else {
1332            line1 = GRREG->getPixel(1, h - 1);
1333            line1 |= GRREG->getPixel(0, h - 1) << 1;
1334            line2 = 0;
1335            line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
1336            line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1) << 1;
1337            line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1338            line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1339            line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1340            line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1341            line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1342            line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1343            for(FX_DWORD w = 0; w < GRW; w++) {
1344                bVal = GRREFERENCE->getPixel(w, h);
1345                if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
1346                        && (bVal == GRREFERENCE->getPixel(w, h - 1))
1347                        && (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
1348                        && (bVal == GRREFERENCE->getPixel(w - 1, h))
1349                        && (bVal == GRREFERENCE->getPixel(w + 1, h))
1350                        && (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
1351                        && (bVal == GRREFERENCE->getPixel(w, h + 1))
1352                        && (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
1353                    CONTEXT = line5;
1354                    CONTEXT |= line4 << 3;
1355                    CONTEXT |= line3 << 6;
1356                    CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1357                    CONTEXT |= line2 << 9;
1358                    CONTEXT |= line1 << 10;
1359                    CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1360                    bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1361                }
1362                GRREG->setPixel(w, h, bVal);
1363                line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
1364                line2 = ((line2 << 1) | bVal) & 0x01;
1365                line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY - 1)) & 0x03;
1366                line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1367                line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x07;
1368            }
1369        }
1370    }
1371    return GRREG;
1372}
1373CJBig2_Image *CJBig2_GRRDProc::decode_Template0_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1374{
1375    FX_BOOL LTP, SLTP, bVal;
1376    FX_DWORD CONTEXT;
1377    CJBig2_Image *GRREG;
1378    FX_DWORD line1, line1_r, line2_r, line3_r;
1379    FX_BYTE *pLine, *pLineR, cVal;
1380    FX_INTPTR nStride, nStrideR, nOffset;
1381    FX_INT32 k, nBits;
1382    FX_INT32 GRWR, GRHR;
1383    FX_INT32 GRW, GRH;
1384    GRW = (FX_INT32)CJBig2_GRRDProc::GRW;
1385    GRH = (FX_INT32)CJBig2_GRRDProc::GRH;
1386    LTP = 0;
1387    JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1388    if (GRREG->m_pData == NULL) {
1389        delete GRREG;
1390        m_pModule->JBig2_Error("Generic refinement region decoding procedure: Create Image Failed with width = %d, height = %d\n", GRW, GRH);
1391        return NULL;
1392    }
1393    pLine = GRREG->m_pData;
1394    pLineR = GRREFERENCE->m_pData;
1395    nStride = GRREG->m_nStride;
1396    nStrideR = GRREFERENCE->m_nStride;
1397    GRWR = (FX_INT32)GRREFERENCE->m_nWidth;
1398    GRHR = (FX_INT32)GRREFERENCE->m_nHeight;
1399    if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
1400        GRREFERENCEDY = 0;
1401    }
1402    nOffset = -GRREFERENCEDY * nStrideR;
1403    for (FX_INT32 h = 0; h < GRH; h++) {
1404        if(TPGRON) {
1405            SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
1406            LTP = LTP ^ SLTP;
1407        }
1408        line1 = (h > 0) ? pLine[-nStride] << 4 : 0;
1409        FX_INT32 reference_h = h - GRREFERENCEDY;
1410        FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
1411        FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
1412        FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
1413        line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
1414        line2_r = line2_r_ok ? pLineR[nOffset] : 0;
1415        line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
1416        if(LTP == 0) {
1417            CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0)
1418                      | ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
1419            for (FX_INT32 w = 0; w < GRW; w += 8) {
1420                nBits = GRW - w > 8 ? 8 : GRW - w;
1421                if (h > 0)
1422                    line1 = (line1 << 8) |
1423                            (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
1424                if (h > GRHR + GRREFERENCEDY + 1) {
1425                    line1_r = 0;
1426                    line2_r  = 0;
1427                    line3_r = 0;
1428                } else {
1429                    if(line1_r_ok)
1430                        line1_r = (line1_r << 8) |
1431                                  (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1432                    if(line2_r_ok)
1433                        line2_r = (line2_r << 8) |
1434                                  (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1435                    if(line3_r_ok)
1436                        line3_r = (line3_r << 8) |
1437                                  (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1438                    else {
1439                        line3_r = 0;
1440                    }
1441                }
1442                cVal = 0;
1443                for (k = 0; k < nBits; k++) {
1444                    bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1445                    cVal |= bVal << (7 - k);
1446                    CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
1447                              ((line1 >> (7 - k)) & 0x0400) |
1448                              ((line1_r >> (7 - k)) & 0x0040) |
1449                              ((line2_r >> (10 - k)) & 0x0008) |
1450                              ((line3_r >> (13 - k)) & 0x0001);
1451                }
1452                pLine[w >> 3] = cVal;
1453            }
1454        } else {
1455            CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0)
1456                      | ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
1457            for (FX_INT32 w = 0; w < GRW; w += 8) {
1458                nBits = GRW - w > 8 ? 8 : GRW - w;
1459                if (h > 0)
1460                    line1 = (line1 << 8) |
1461                            (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
1462                if(line1_r_ok)
1463                    line1_r = (line1_r << 8) |
1464                              (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1465                if(line2_r_ok)
1466                    line2_r = (line2_r << 8) |
1467                              (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1468                if(line3_r_ok)
1469                    line3_r = (line3_r << 8) |
1470                              (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1471                else {
1472                    line3_r = 0;
1473                }
1474                cVal = 0;
1475                for (k = 0; k < nBits; k++) {
1476                    bVal = GRREFERENCE->getPixel(w + k, h);
1477                    if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1))
1478                            && (bVal == GRREFERENCE->getPixel(w + k, h - 1))
1479                            && (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1))
1480                            && (bVal == GRREFERENCE->getPixel(w + k - 1, h))
1481                            && (bVal == GRREFERENCE->getPixel(w + k + 1, h))
1482                            && (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1))
1483                            && (bVal == GRREFERENCE->getPixel(w + k, h + 1))
1484                            && (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
1485                        bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1486                    }
1487                    cVal |= bVal << (7 - k);
1488                    CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
1489                              ((line1 >> (7 - k)) & 0x0400) |
1490                              ((line1_r >> (7 - k)) & 0x0040) |
1491                              ((line2_r >> (10 - k)) & 0x0008) |
1492                              ((line3_r >> (13 - k)) & 0x0001);
1493                }
1494                pLine[w >> 3] = cVal;
1495            }
1496        }
1497        pLine += nStride;
1498        if (h < GRHR + GRREFERENCEDY) {
1499            pLineR += nStrideR;
1500        }
1501    }
1502    return GRREG;
1503}
1504CJBig2_Image *CJBig2_GRRDProc::decode_Template1_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1505{
1506    FX_BOOL LTP, SLTP, bVal;
1507    FX_DWORD CONTEXT;
1508    CJBig2_Image *GRREG;
1509    FX_DWORD line1, line2, line3, line4, line5;
1510    LTP = 0;
1511    JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1512    GRREG->fill(0);
1513    for(FX_DWORD h = 0; h < GRH; h++) {
1514        if(TPGRON) {
1515            SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
1516            LTP = LTP ^ SLTP;
1517        }
1518        if(LTP == 0) {
1519            line1 = GRREG->getPixel(1, h - 1);
1520            line1 |= GRREG->getPixel(0, h - 1) << 1;
1521            line1 |= GRREG->getPixel(-1, h - 1) << 2;
1522            line2 = 0;
1523            line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
1524            line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1525            line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1526            line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1527            line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1528            line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1529            for(FX_DWORD w = 0; w < GRW; w++) {
1530                CONTEXT = line5;
1531                CONTEXT |= line4 << 2;
1532                CONTEXT |= line3 << 5;
1533                CONTEXT |= line2 << 6;
1534                CONTEXT |= line1 << 7;
1535                bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1536                GRREG->setPixel(w, h, bVal);
1537                line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
1538                line2 = ((line2 << 1) | bVal) & 0x01;
1539                line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1)) & 0x01;
1540                line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1541                line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x03;
1542            }
1543        } else {
1544            line1 = GRREG->getPixel(1, h - 1);
1545            line1 |= GRREG->getPixel(0, h - 1) << 1;
1546            line1 |= GRREG->getPixel(-1, h - 1) << 2;
1547            line2 = 0;
1548            line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
1549            line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1550            line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1551            line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1552            line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1553            line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1554            for(FX_DWORD w = 0; w < GRW; w++) {
1555                bVal = GRREFERENCE->getPixel(w, h);
1556                if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
1557                        && (bVal == GRREFERENCE->getPixel(w, h - 1))
1558                        && (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
1559                        && (bVal == GRREFERENCE->getPixel(w - 1, h))
1560                        && (bVal == GRREFERENCE->getPixel(w + 1, h))
1561                        && (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
1562                        && (bVal == GRREFERENCE->getPixel(w, h + 1))
1563                        && (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
1564                    CONTEXT = line5;
1565                    CONTEXT |= line4 << 2;
1566                    CONTEXT |= line3 << 5;
1567                    CONTEXT |= line2 << 6;
1568                    CONTEXT |= line1 << 7;
1569                    bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1570                }
1571                GRREG->setPixel(w, h, bVal);
1572                line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
1573                line2 = ((line2 << 1) | bVal) & 0x01;
1574                line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1)) & 0x01;
1575                line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1576                line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x03;
1577            }
1578        }
1579    }
1580    return GRREG;
1581}
1582CJBig2_Image *CJBig2_GRRDProc::decode_Template1_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1583{
1584    FX_BOOL LTP, SLTP, bVal;
1585    FX_DWORD CONTEXT;
1586    CJBig2_Image *GRREG;
1587    FX_DWORD line1, line1_r, line2_r, line3_r;
1588    FX_BYTE *pLine, *pLineR, cVal;
1589    FX_INTPTR nStride, nStrideR, nOffset;
1590    FX_INT32 k, nBits;
1591    FX_INT32 GRWR, GRHR;
1592    FX_INT32 GRW, GRH;
1593    GRW = (FX_INT32)CJBig2_GRRDProc::GRW;
1594    GRH = (FX_INT32)CJBig2_GRRDProc::GRH;
1595    LTP = 0;
1596    JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1597    if (GRREG->m_pData == NULL) {
1598        delete GRREG;
1599        m_pModule->JBig2_Error("Generic refinement region decoding procedure: Create Image Failed with width = %d, height = %d\n", GRW, GRH);
1600        return NULL;
1601    }
1602    pLine = GRREG->m_pData;
1603    pLineR = GRREFERENCE->m_pData;
1604    nStride = GRREG->m_nStride;
1605    nStrideR = GRREFERENCE->m_nStride;
1606    GRWR = (FX_INT32)GRREFERENCE->m_nWidth;
1607    GRHR = (FX_INT32)GRREFERENCE->m_nHeight;
1608    if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
1609        GRREFERENCEDY = 0;
1610    }
1611    nOffset = -GRREFERENCEDY * nStrideR;
1612    for (FX_INT32 h = 0; h < GRH; h++) {
1613        if(TPGRON) {
1614            SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
1615            LTP = LTP ^ SLTP;
1616        }
1617        line1 = (h > 0) ? pLine[-nStride] << 1 : 0;
1618        FX_INT32 reference_h = h - GRREFERENCEDY;
1619        FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
1620        FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
1621        FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
1622        line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
1623        line2_r = line2_r_ok ? pLineR[nOffset] : 0;
1624        line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
1625        if(LTP == 0) {
1626            CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020)
1627                      | ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
1628            for (FX_INT32 w = 0; w < GRW; w += 8) {
1629                nBits = GRW - w > 8 ? 8 : GRW - w;
1630                if (h > 0)
1631                    line1 = (line1 << 8) |
1632                            (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
1633                if(line1_r_ok)
1634                    line1_r = (line1_r << 8) |
1635                              (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1636                if(line2_r_ok)
1637                    line2_r = (line2_r << 8) |
1638                              (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1639                if(line3_r_ok)
1640                    line3_r = (line3_r << 8) |
1641                              (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1642                else {
1643                    line3_r = 0;
1644                }
1645                cVal = 0;
1646                for (k = 0; k < nBits; k++) {
1647                    bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1648                    cVal |= bVal << (7 - k);
1649                    CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
1650                              ((line1 >> (7 - k)) & 0x0080) |
1651                              ((line1_r >> (9 - k)) & 0x0020) |
1652                              ((line2_r >> (11 - k)) & 0x0004) |
1653                              ((line3_r >> (13 - k)) & 0x0001);
1654                }
1655                pLine[w >> 3] = cVal;
1656            }
1657        } else {
1658            CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020)
1659                      | ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
1660            for (FX_INT32 w = 0; w < GRW; w += 8) {
1661                nBits = GRW - w > 8 ? 8 : GRW - w;
1662                if (h > 0)
1663                    line1 = (line1 << 8) |
1664                            (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
1665                if(line1_r_ok)
1666                    line1_r = (line1_r << 8) |
1667                              (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1668                if(line2_r_ok)
1669                    line2_r = (line2_r << 8) |
1670                              (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1671                if(line3_r_ok)
1672                    line3_r = (line3_r << 8) |
1673                              (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1674                else {
1675                    line3_r = 0;
1676                }
1677                cVal = 0;
1678                for (k = 0; k < nBits; k++) {
1679                    bVal = GRREFERENCE->getPixel(w + k, h);
1680                    if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1))
1681                            && (bVal == GRREFERENCE->getPixel(w + k, h - 1))
1682                            && (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1))
1683                            && (bVal == GRREFERENCE->getPixel(w + k - 1, h))
1684                            && (bVal == GRREFERENCE->getPixel(w + k + 1, h))
1685                            && (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1))
1686                            && (bVal == GRREFERENCE->getPixel(w + k, h + 1))
1687                            && (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
1688                        bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1689                    }
1690                    cVal |= bVal << (7 - k);
1691                    CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
1692                              ((line1 >> (7 - k)) & 0x0080) |
1693                              ((line1_r >> (9 - k)) & 0x0020) |
1694                              ((line2_r >> (11 - k)) & 0x0004) |
1695                              ((line3_r >> (13 - k)) & 0x0001);
1696                }
1697                pLine[w >> 3] = cVal;
1698            }
1699        }
1700        pLine += nStride;
1701        if (h < GRHR + GRREFERENCEDY) {
1702            pLineR += nStrideR;
1703        }
1704    }
1705    return GRREG;
1706}
1707CJBig2_Image *CJBig2_GRRDProc::decode_V1(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1708{
1709    FX_BOOL LTP, SLTP, bVal;
1710    FX_BOOL TPGRPIX, TPGRVAL;
1711    FX_DWORD CONTEXT;
1712    CJBig2_Image *GRREG;
1713    LTP = 0;
1714    JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1715    GRREG->fill(0);
1716    for(FX_DWORD h = 0; h < GRH; h++) {
1717        if(TPGRON) {
1718            switch(GRTEMPLATE) {
1719                case 0:
1720                    CONTEXT = 0x0010;
1721                    break;
1722                case 1:
1723                    CONTEXT = 0x0008;
1724                    break;
1725            }
1726            SLTP = pArithDecoder->DECODE(&grContext[CONTEXT]);
1727            LTP = LTP ^ SLTP;
1728        }
1729        if(LTP == 0) {
1730            for(FX_DWORD w = 0; w < GRW; w++) {
1731                CONTEXT = 0;
1732                switch(GRTEMPLATE) {
1733                    case 0:
1734                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1735                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1736                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1737                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 3;
1738                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 4;
1739                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 5;
1740                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1) << 6;
1741                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 7;
1742                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1743                        CONTEXT |= GRREG->getPixel(w - 1, h) << 9;
1744                        CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 10;
1745                        CONTEXT |= GRREG->getPixel(w, h - 1) << 11;
1746                        CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1747                        break;
1748                    case 1:
1749                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1750                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1751                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 2;
1752                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 3;
1753                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 4;
1754                        CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 5;
1755                        CONTEXT |= GRREG->getPixel(w - 1, h) << 6;
1756                        CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 7;
1757                        CONTEXT |= GRREG->getPixel(w, h - 1) << 8;
1758                        CONTEXT |= GRREG->getPixel(w - 1, h - 1) << 9;
1759                        break;
1760                }
1761                bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1762                GRREG->setPixel(w, h, bVal);
1763            }
1764        } else {
1765            for(FX_DWORD w = 0; w < GRW; w++) {
1766                bVal = GRREFERENCE->getPixel(w, h);
1767                if(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
1768                        && (bVal == GRREFERENCE->getPixel(w, h - 1))
1769                        && (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
1770                        && (bVal == GRREFERENCE->getPixel(w - 1, h))
1771                        && (bVal == GRREFERENCE->getPixel(w + 1, h))
1772                        && (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
1773                        && (bVal == GRREFERENCE->getPixel(w, h + 1))
1774                        && (bVal == GRREFERENCE->getPixel(w + 1, h + 1))) {
1775                    TPGRPIX = 1;
1776                    TPGRVAL = bVal;
1777                } else {
1778                    TPGRPIX = 0;
1779                }
1780                if(TPGRPIX) {
1781                    GRREG->setPixel(w, h, TPGRVAL);
1782                } else {
1783                    CONTEXT = 0;
1784                    switch(GRTEMPLATE) {
1785                        case 0:
1786                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1787                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1788                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1789                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 3;
1790                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 4;
1791                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 5;
1792                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1) << 6;
1793                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 7;
1794                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1795                            CONTEXT |= GRREG->getPixel(w - 1, h) << 9;
1796                            CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 10;
1797                            CONTEXT |= GRREG->getPixel(w, h - 1) << 11;
1798                            CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1799                            break;
1800                        case 1:
1801                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1802                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1803                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 2;
1804                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 3;
1805                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 4;
1806                            CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 5;
1807                            CONTEXT |= GRREG->getPixel(w - 1, h) << 6;
1808                            CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 7;
1809                            CONTEXT |= GRREG->getPixel(w, h - 1) << 8;
1810                            CONTEXT |= GRREG->getPixel(w - 1, h - 1) << 9;
1811                            break;
1812                    }
1813                    bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1814                    GRREG->setPixel(w, h, bVal);
1815                }
1816            }
1817        }
1818    }
1819    return GRREG;
1820}
1821CJBig2_Image *CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream *pStream, JBig2ArithCtx *grContext)
1822{
1823    FX_INT32 STRIPT, FIRSTS;
1824    FX_DWORD NINSTANCES;
1825    FX_INT32 DT, DFS, CURS;
1826    FX_BYTE CURT;
1827    FX_INT32 SI, TI;
1828    FX_DWORD IDI;
1829    CJBig2_Image *IBI;
1830    FX_DWORD WI, HI;
1831    FX_INT32 IDS;
1832    FX_BOOL RI;
1833    FX_INT32 RDWI, RDHI, RDXI, RDYI;
1834    CJBig2_Image *IBOI;
1835    FX_DWORD WOI, HOI;
1836    CJBig2_Image *SBREG;
1837    FX_BOOL bFirst;
1838    FX_DWORD nTmp;
1839    FX_INT32 nVal, nBits;
1840    CJBig2_HuffmanDecoder *pHuffmanDecoder;
1841    CJBig2_GRRDProc *pGRRD;
1842    CJBig2_ArithDecoder *pArithDecoder;
1843    JBIG2_ALLOC(pHuffmanDecoder, CJBig2_HuffmanDecoder(pStream));
1844    JBIG2_ALLOC(SBREG, CJBig2_Image(SBW, SBH));
1845    SBREG->fill(SBDEFPIXEL);
1846    if(pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0) {
1847        m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1848        goto failed;
1849    }
1850    STRIPT *= SBSTRIPS;
1851    STRIPT = -STRIPT;
1852    FIRSTS = 0;
1853    NINSTANCES = 0;
1854    while(NINSTANCES < SBNUMINSTANCES) {
1855        if(pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0) {
1856            m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1857            goto failed;
1858        }
1859        DT *= SBSTRIPS;
1860        STRIPT = STRIPT + DT;
1861        bFirst = TRUE;
1862        for(;;) {
1863            if(bFirst) {
1864                if(pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0) {
1865                    m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1866                    goto failed;
1867                }
1868                FIRSTS = FIRSTS + DFS;
1869                CURS = FIRSTS;
1870                bFirst = FALSE;
1871            } else {
1872                nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS);
1873                if(nVal == JBIG2_OOB) {
1874                    break;
1875                } else if(nVal != 0) {
1876                    m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1877                    goto failed;
1878                } else {
1879                    CURS = CURS + IDS + SBDSOFFSET;
1880                }
1881            }
1882            if(SBSTRIPS == 1) {
1883                CURT = 0;
1884            } else {
1885                nTmp = 1;
1886                while((FX_DWORD)(1 << nTmp) < SBSTRIPS) {
1887                    nTmp ++;
1888                }
1889                if(pStream->readNBits(nTmp, &nVal) != 0) {
1890                    m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1891                    goto failed;
1892                }
1893                CURT = nVal;
1894            }
1895            TI = STRIPT + CURT;
1896            nVal = 0;
1897            nBits = 0;
1898            for(;;) {
1899                if(pStream->read1Bit(&nTmp) != 0) {
1900                    m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1901                    goto failed;
1902                }
1903                nVal = (nVal << 1) | nTmp;
1904                nBits ++;
1905                for(IDI = 0; IDI < SBNUMSYMS; IDI++) {
1906                    if((nBits == SBSYMCODES[IDI].codelen) && (nVal == SBSYMCODES[IDI].code)) {
1907                        break;
1908                    }
1909                }
1910                if(IDI < SBNUMSYMS) {
1911                    break;
1912                }
1913            }
1914            if(SBREFINE == 0) {
1915                RI = 0;
1916            } else {
1917                if(pStream->read1Bit(&RI) != 0) {
1918                    m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1919                    goto failed;
1920                }
1921            }
1922            if(RI == 0) {
1923                IBI = SBSYMS[IDI];
1924            } else {
1925                if((pHuffmanDecoder->decodeAValue(SBHUFFRDW, &RDWI) != 0)
1926                        || (pHuffmanDecoder->decodeAValue(SBHUFFRDH, &RDHI) != 0)
1927                        || (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0)
1928                        || (pHuffmanDecoder->decodeAValue(SBHUFFRDY, &RDYI) != 0)
1929                        || (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
1930                    m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1931                    goto failed;
1932                }
1933                pStream->alignByte();
1934                nTmp = pStream->getOffset();
1935                IBOI = SBSYMS[IDI];
1936                if (!IBOI) {
1937                    goto failed;
1938                }
1939                WOI = IBOI->m_nWidth;
1940                HOI = IBOI->m_nHeight;
1941                if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
1942                    m_pModule->JBig2_Error("text region decoding procedure (huffman): Invalid RDWI or RDHI value.");
1943                    goto failed;
1944                }
1945                JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
1946                pGRRD->GRW = WOI + RDWI;
1947                pGRRD->GRH = HOI + RDHI;
1948                pGRRD->GRTEMPLATE = SBRTEMPLATE;
1949                pGRRD->GRREFERENCE = IBOI;
1950                pGRRD->GRREFERENCEDX = (RDWI >> 2) + RDXI;
1951                pGRRD->GRREFERENCEDY = (RDHI >> 2) + RDYI;
1952                pGRRD->TPGRON = 0;
1953                pGRRD->GRAT[0] = SBRAT[0];
1954                pGRRD->GRAT[1] = SBRAT[1];
1955                pGRRD->GRAT[2] = SBRAT[2];
1956                pGRRD->GRAT[3] = SBRAT[3];
1957                JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(pStream));
1958                IBI = pGRRD->decode(pArithDecoder, grContext);
1959                if(IBI == NULL) {
1960                    delete pGRRD;
1961                    delete pArithDecoder;
1962                    goto failed;
1963                }
1964                delete pArithDecoder;
1965                pStream->alignByte();
1966                pStream->offset(2);
1967                if((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
1968                    delete IBI;
1969                    delete pGRRD;
1970                    m_pModule->JBig2_Error("text region decoding procedure (huffman):"
1971                                           "bytes processed by generic refinement region decoding procedure doesn't equal SBHUFFRSIZE.");
1972                    goto failed;
1973                }
1974                delete pGRRD;
1975            }
1976            if (!IBI) {
1977                continue;
1978            }
1979            WI = IBI->m_nWidth;
1980            HI = IBI->m_nHeight;
1981            if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT)
1982                                   || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
1983                CURS = CURS + WI - 1;
1984            } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT)
1985                                          || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
1986                CURS = CURS + HI - 1;
1987            }
1988            SI = CURS;
1989            if(TRANSPOSED == 0) {
1990                switch(REFCORNER) {
1991                    case JBIG2_CORNER_TOPLEFT:
1992                        SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
1993                        break;
1994                    case JBIG2_CORNER_TOPRIGHT:
1995                        SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
1996                        break;
1997                    case JBIG2_CORNER_BOTTOMLEFT:
1998                        SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
1999                        break;
2000                    case JBIG2_CORNER_BOTTOMRIGHT:
2001                        SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
2002                        break;
2003                }
2004            } else {
2005                switch(REFCORNER) {
2006                    case JBIG2_CORNER_TOPLEFT:
2007                        SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
2008                        break;
2009                    case JBIG2_CORNER_TOPRIGHT:
2010                        SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
2011                        break;
2012                    case JBIG2_CORNER_BOTTOMLEFT:
2013                        SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
2014                        break;
2015                    case JBIG2_CORNER_BOTTOMRIGHT:
2016                        SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
2017                        break;
2018                }
2019            }
2020            if(RI != 0) {
2021                delete IBI;
2022            }
2023            if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2024                                   || (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
2025                CURS = CURS + WI - 1;
2026            } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2027                                          || (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
2028                CURS = CURS + HI - 1;
2029            }
2030            NINSTANCES = NINSTANCES + 1;
2031        }
2032    }
2033    delete pHuffmanDecoder;
2034    return SBREG;
2035failed:
2036    delete pHuffmanDecoder;
2037    delete SBREG;
2038    return NULL;
2039}
2040CJBig2_Image *CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext,
2041        JBig2IntDecoderState *pIDS)
2042{
2043    FX_INT32 STRIPT, FIRSTS;
2044    FX_DWORD NINSTANCES;
2045    FX_INT32 DT, DFS, CURS;
2046    FX_INT32 CURT;
2047    FX_INT32 SI, TI;
2048    FX_DWORD IDI;
2049    CJBig2_Image *IBI;
2050    FX_DWORD WI, HI;
2051    FX_INT32 IDS;
2052    FX_BOOL RI;
2053    FX_INT32 RDWI, RDHI, RDXI, RDYI;
2054    CJBig2_Image *IBOI;
2055    FX_DWORD WOI, HOI;
2056    CJBig2_Image *SBREG;
2057    FX_BOOL bFirst;
2058    FX_INT32 nRet, nVal;
2059    FX_INT32 bRetained;
2060    CJBig2_ArithIntDecoder *IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH, *IARDX, *IARDY;
2061    CJBig2_ArithIaidDecoder *IAID;
2062    CJBig2_GRRDProc *pGRRD;
2063    if(pIDS) {
2064        IADT = pIDS->IADT;
2065        IAFS = pIDS->IAFS;
2066        IADS = pIDS->IADS;
2067        IAIT = pIDS->IAIT;
2068        IARI = pIDS->IARI;
2069        IARDW = pIDS->IARDW;
2070        IARDH = pIDS->IARDH;
2071        IARDX = pIDS->IARDX;
2072        IARDY = pIDS->IARDY;
2073        IAID = pIDS->IAID;
2074        bRetained = TRUE;
2075    } else {
2076        JBIG2_ALLOC(IADT, CJBig2_ArithIntDecoder());
2077        JBIG2_ALLOC(IAFS, CJBig2_ArithIntDecoder());
2078        JBIG2_ALLOC(IADS, CJBig2_ArithIntDecoder());
2079        JBIG2_ALLOC(IAIT, CJBig2_ArithIntDecoder());
2080        JBIG2_ALLOC(IARI, CJBig2_ArithIntDecoder());
2081        JBIG2_ALLOC(IARDW, CJBig2_ArithIntDecoder());
2082        JBIG2_ALLOC(IARDH, CJBig2_ArithIntDecoder());
2083        JBIG2_ALLOC(IARDX, CJBig2_ArithIntDecoder());
2084        JBIG2_ALLOC(IARDY, CJBig2_ArithIntDecoder());
2085        JBIG2_ALLOC(IAID , CJBig2_ArithIaidDecoder(SBSYMCODELEN));
2086        bRetained = FALSE;
2087    }
2088    JBIG2_ALLOC(SBREG, CJBig2_Image(SBW, SBH));
2089    SBREG->fill(SBDEFPIXEL);
2090    if(IADT->decode(pArithDecoder, &STRIPT) == -1) {
2091        m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2092        goto failed;
2093    }
2094    STRIPT *= SBSTRIPS;
2095    STRIPT = -STRIPT;
2096    FIRSTS = 0;
2097    NINSTANCES = 0;
2098    while(NINSTANCES < SBNUMINSTANCES) {
2099        if(IADT->decode(pArithDecoder, &DT) == -1) {
2100            m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2101            goto failed;
2102        }
2103        DT *= SBSTRIPS;
2104        STRIPT = STRIPT + DT;
2105        bFirst = TRUE;
2106        for(;;) {
2107            if(bFirst) {
2108                if(IAFS->decode(pArithDecoder, &DFS) == -1) {
2109                    m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2110                    goto failed;
2111                }
2112                FIRSTS = FIRSTS + DFS;
2113                CURS = FIRSTS;
2114                bFirst = FALSE;
2115            } else {
2116                nRet = IADS->decode(pArithDecoder, &IDS);
2117                if(nRet == JBIG2_OOB) {
2118                    break;
2119                } else if(nRet != 0) {
2120                    m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2121                    goto failed;
2122                } else {
2123                    CURS = CURS + IDS + SBDSOFFSET;
2124                }
2125            }
2126            if (NINSTANCES >= SBNUMINSTANCES) {
2127                break;
2128            }
2129            if(SBSTRIPS == 1) {
2130                CURT = 0;
2131            } else {
2132                if(IAIT->decode(pArithDecoder, &nVal) == -1) {
2133                    m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2134                    goto failed;
2135                }
2136                CURT = nVal;
2137            }
2138            TI = STRIPT + CURT;
2139            if(IAID->decode(pArithDecoder, &nVal) == -1) {
2140                m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2141                goto failed;
2142            }
2143            IDI = nVal;
2144            if(IDI >= SBNUMSYMS) {
2145                m_pModule->JBig2_Error("text region decoding procedure (arith): symbol id out of range.(%d/%d)",
2146                                       IDI, SBNUMSYMS);
2147                goto failed;
2148            }
2149            if(SBREFINE == 0) {
2150                RI = 0;
2151            } else {
2152                if(IARI->decode(pArithDecoder, &RI) == -1) {
2153                    m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2154                    goto failed;
2155                }
2156            }
2157            if (!SBSYMS[IDI]) {
2158                goto failed;
2159            }
2160            if(RI == 0) {
2161                IBI = SBSYMS[IDI];
2162            } else {
2163                if((IARDW->decode(pArithDecoder, &RDWI) == -1)
2164                        || (IARDH->decode(pArithDecoder, &RDHI) == -1)
2165                        || (IARDX->decode(pArithDecoder, &RDXI) == -1)
2166                        || (IARDY->decode(pArithDecoder, &RDYI) == -1)) {
2167                    m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2168                    goto failed;
2169                }
2170                IBOI = SBSYMS[IDI];
2171                WOI = IBOI->m_nWidth;
2172                HOI = IBOI->m_nHeight;
2173                if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
2174                    m_pModule->JBig2_Error("text region decoding procedure (arith): Invalid RDWI or RDHI value.");
2175                    goto failed;
2176                }
2177                JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
2178                pGRRD->GRW = WOI + RDWI;
2179                pGRRD->GRH = HOI + RDHI;
2180                pGRRD->GRTEMPLATE = SBRTEMPLATE;
2181                pGRRD->GRREFERENCE = IBOI;
2182                pGRRD->GRREFERENCEDX = (RDWI >> 1) + RDXI;
2183                pGRRD->GRREFERENCEDY = (RDHI >> 1) + RDYI;
2184                pGRRD->TPGRON = 0;
2185                pGRRD->GRAT[0] = SBRAT[0];
2186                pGRRD->GRAT[1] = SBRAT[1];
2187                pGRRD->GRAT[2] = SBRAT[2];
2188                pGRRD->GRAT[3] = SBRAT[3];
2189                IBI = pGRRD->decode(pArithDecoder, grContext);
2190                if(IBI == NULL) {
2191                    delete pGRRD;
2192                    goto failed;
2193                }
2194                delete pGRRD;
2195            }
2196            WI = IBI->m_nWidth;
2197            HI = IBI->m_nHeight;
2198            if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT)
2199                                   || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
2200                CURS = CURS + WI - 1;
2201            } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT)
2202                                          || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
2203                CURS = CURS + HI - 1;
2204            }
2205            SI = CURS;
2206            if(TRANSPOSED == 0) {
2207                switch(REFCORNER) {
2208                    case JBIG2_CORNER_TOPLEFT:
2209                        SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
2210                        break;
2211                    case JBIG2_CORNER_TOPRIGHT:
2212                        SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
2213                        break;
2214                    case JBIG2_CORNER_BOTTOMLEFT:
2215                        SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
2216                        break;
2217                    case JBIG2_CORNER_BOTTOMRIGHT:
2218                        SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
2219                        break;
2220                }
2221            } else {
2222                switch(REFCORNER) {
2223                    case JBIG2_CORNER_TOPLEFT:
2224                        SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
2225                        break;
2226                    case JBIG2_CORNER_TOPRIGHT:
2227                        SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
2228                        break;
2229                    case JBIG2_CORNER_BOTTOMLEFT:
2230                        SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
2231                        break;
2232                    case JBIG2_CORNER_BOTTOMRIGHT:
2233                        SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
2234                        break;
2235                }
2236            }
2237            if(RI != 0) {
2238                delete IBI;
2239            }
2240            if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2241                                   || (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
2242                CURS = CURS + WI - 1;
2243            } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2244                                          || (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
2245                CURS = CURS + HI - 1;
2246            }
2247            NINSTANCES = NINSTANCES + 1;
2248        }
2249    }
2250    if(bRetained == FALSE) {
2251        delete IADT;
2252        delete IAFS;
2253        delete IADS;
2254        delete IAIT;
2255        delete IARI;
2256        delete IARDW;
2257        delete IARDH;
2258        delete IARDX;
2259        delete IARDY;
2260        delete IAID;
2261    }
2262    return SBREG;
2263failed:
2264    if(bRetained == FALSE) {
2265        delete IADT;
2266        delete IAFS;
2267        delete IADS;
2268        delete IAIT;
2269        delete IARI;
2270        delete IARDW;
2271        delete IARDH;
2272        delete IARDX;
2273        delete IARDY;
2274        delete IAID;
2275    }
2276    delete SBREG;
2277    return NULL;
2278}
2279CJBig2_SymbolDict *CJBig2_SDDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder,
2280        JBig2ArithCtx *gbContext, JBig2ArithCtx *grContext)
2281{
2282    CJBig2_Image **SDNEWSYMS;
2283    FX_DWORD HCHEIGHT, NSYMSDECODED;
2284    FX_INT32 HCDH;
2285    FX_DWORD SYMWIDTH, TOTWIDTH, HCFIRSTSYM;
2286    FX_INT32 DW;
2287    CJBig2_Image *BS;
2288    FX_DWORD I, J, REFAGGNINST;
2289    FX_BOOL *EXFLAGS;
2290    FX_DWORD EXINDEX;
2291    FX_BOOL CUREXFLAG;
2292    FX_DWORD EXRUNLENGTH;
2293    FX_INT32 nVal;
2294    FX_DWORD nTmp;
2295    FX_BOOL SBHUFF;
2296    FX_DWORD SBNUMSYMS;
2297    FX_BYTE SBSYMCODELEN;
2298    FX_DWORD IDI;
2299    FX_INT32 RDXI, RDYI;
2300    CJBig2_Image **SBSYMS;
2301    CJBig2_HuffmanTable *SBHUFFFS, *SBHUFFDS, *SBHUFFDT, *SBHUFFRDW, *SBHUFFRDH, *SBHUFFRDX, *SBHUFFRDY,
2302                        *SBHUFFRSIZE;
2303    CJBig2_GRRDProc *pGRRD;
2304    CJBig2_GRDProc *pGRD;
2305    CJBig2_ArithIntDecoder *IADH, *IADW, *IAAI, *IARDX, *IARDY, *IAEX,
2306                           *IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH;
2307    CJBig2_ArithIaidDecoder *IAID;
2308    CJBig2_SymbolDict *pDict;
2309    JBIG2_ALLOC(IADH, CJBig2_ArithIntDecoder());
2310    JBIG2_ALLOC(IADW, CJBig2_ArithIntDecoder());
2311    JBIG2_ALLOC(IAAI, CJBig2_ArithIntDecoder());
2312    JBIG2_ALLOC(IARDX, CJBig2_ArithIntDecoder());
2313    JBIG2_ALLOC(IARDY, CJBig2_ArithIntDecoder());
2314    JBIG2_ALLOC(IAEX, CJBig2_ArithIntDecoder());
2315    JBIG2_ALLOC(IADT, CJBig2_ArithIntDecoder());
2316    JBIG2_ALLOC(IAFS, CJBig2_ArithIntDecoder());
2317    JBIG2_ALLOC(IADS, CJBig2_ArithIntDecoder());
2318    JBIG2_ALLOC(IAIT, CJBig2_ArithIntDecoder());
2319    JBIG2_ALLOC(IARI, CJBig2_ArithIntDecoder());
2320    JBIG2_ALLOC(IARDW, CJBig2_ArithIntDecoder());
2321    JBIG2_ALLOC(IARDH, CJBig2_ArithIntDecoder());
2322    nTmp = 0;
2323    while((FX_DWORD)(1 << nTmp) < (SDNUMINSYMS + SDNUMNEWSYMS)) {
2324        nTmp ++;
2325    }
2326    JBIG2_ALLOC(IAID, CJBig2_ArithIaidDecoder((FX_BYTE)nTmp));
2327    SDNEWSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SDNUMNEWSYMS, sizeof(CJBig2_Image*));
2328    FXSYS_memset32(SDNEWSYMS, 0 , SDNUMNEWSYMS * sizeof(CJBig2_Image*));
2329    HCHEIGHT = 0;
2330    NSYMSDECODED = 0;
2331    while(NSYMSDECODED < SDNUMNEWSYMS) {
2332        BS = NULL;
2333        if(IADH->decode(pArithDecoder, &HCDH) == -1) {
2334            m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2335            goto failed;
2336        }
2337        HCHEIGHT = HCHEIGHT + HCDH;
2338        if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
2339            m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): invalid HCHEIGHT value.");
2340            goto failed;
2341        }
2342        SYMWIDTH = 0;
2343        TOTWIDTH = 0;
2344        HCFIRSTSYM = NSYMSDECODED;
2345        for(;;) {
2346            nVal = IADW->decode(pArithDecoder, &DW);
2347            if(nVal == JBIG2_OOB) {
2348                break;
2349            } else if(nVal != 0) {
2350                m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2351                goto failed;
2352            } else {
2353                if (NSYMSDECODED >= SDNUMNEWSYMS) {
2354                    m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): NSYMSDECODED >= SDNUMNEWSYMS.");
2355                    goto failed;
2356                }
2357                SYMWIDTH = SYMWIDTH + DW;
2358                if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) {
2359                    m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): invalid SYMWIDTH value.");
2360                    goto failed;
2361                } else if (HCHEIGHT == 0 || SYMWIDTH == 0) {
2362                    TOTWIDTH = TOTWIDTH + SYMWIDTH;
2363                    SDNEWSYMS[NSYMSDECODED] = NULL;
2364                    NSYMSDECODED = NSYMSDECODED + 1;
2365                    continue;
2366                }
2367                TOTWIDTH = TOTWIDTH + SYMWIDTH;
2368            }
2369            if(SDREFAGG == 0) {
2370                JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
2371                pGRD->MMR = 0;
2372                pGRD->GBW = SYMWIDTH;
2373                pGRD->GBH = HCHEIGHT;
2374                pGRD->GBTEMPLATE = SDTEMPLATE;
2375                pGRD->TPGDON = 0;
2376                pGRD->USESKIP = 0;
2377                pGRD->GBAT[0] = SDAT[0];
2378                pGRD->GBAT[1] = SDAT[1];
2379                pGRD->GBAT[2] = SDAT[2];
2380                pGRD->GBAT[3] = SDAT[3];
2381                pGRD->GBAT[4] = SDAT[4];
2382                pGRD->GBAT[5] = SDAT[5];
2383                pGRD->GBAT[6] = SDAT[6];
2384                pGRD->GBAT[7] = SDAT[7];
2385                BS = pGRD->decode_Arith(pArithDecoder, gbContext);
2386                if(BS == NULL) {
2387                    delete pGRD;
2388                    goto failed;
2389                }
2390                delete pGRD;
2391            } else {
2392                if(IAAI->decode(pArithDecoder, (int*)&REFAGGNINST) == -1) {
2393                    m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2394                    goto failed;
2395                }
2396                if(REFAGGNINST > 1) {
2397                    CJBig2_TRDProc *pDecoder;
2398                    JBIG2_ALLOC(pDecoder, CJBig2_TRDProc());
2399                    pDecoder->SBHUFF = SDHUFF;
2400                    pDecoder->SBREFINE = 1;
2401                    pDecoder->SBW = SYMWIDTH;
2402                    pDecoder->SBH = HCHEIGHT;
2403                    pDecoder->SBNUMINSTANCES = REFAGGNINST;
2404                    pDecoder->SBSTRIPS = 1;
2405                    pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
2406                    SBNUMSYMS = pDecoder->SBNUMSYMS;
2407                    nTmp = 0;
2408                    while((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
2409                        nTmp ++;
2410                    }
2411                    SBSYMCODELEN = (FX_BYTE)nTmp;
2412                    pDecoder->SBSYMCODELEN = SBSYMCODELEN;
2413                    SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(CJBig2_Image*));
2414                    JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2415                    JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*));
2416                    pDecoder->SBSYMS = SBSYMS;
2417                    pDecoder->SBDEFPIXEL = 0;
2418                    pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
2419                    pDecoder->TRANSPOSED = 0;
2420                    pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
2421                    pDecoder->SBDSOFFSET = 0;
2422                    JBIG2_ALLOC(SBHUFFFS, CJBig2_HuffmanTable(HuffmanTable_B6,
2423                                sizeof(HuffmanTable_B6) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B6));
2424                    JBIG2_ALLOC(SBHUFFDS, CJBig2_HuffmanTable(HuffmanTable_B8,
2425                                sizeof(HuffmanTable_B8) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B8));
2426                    JBIG2_ALLOC(SBHUFFDT, CJBig2_HuffmanTable(HuffmanTable_B11,
2427                                sizeof(HuffmanTable_B11) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B11));
2428                    JBIG2_ALLOC(SBHUFFRDW, CJBig2_HuffmanTable(HuffmanTable_B15,
2429                                sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2430                    JBIG2_ALLOC(SBHUFFRDH, CJBig2_HuffmanTable(HuffmanTable_B15,
2431                                sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2432                    JBIG2_ALLOC(SBHUFFRDX, CJBig2_HuffmanTable(HuffmanTable_B15,
2433                                sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2434                    JBIG2_ALLOC(SBHUFFRDY, CJBig2_HuffmanTable(HuffmanTable_B15,
2435                                sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2436                    JBIG2_ALLOC(SBHUFFRSIZE, CJBig2_HuffmanTable(HuffmanTable_B1,
2437                                sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
2438                    pDecoder->SBHUFFFS = SBHUFFFS;
2439                    pDecoder->SBHUFFDS = SBHUFFDS;
2440                    pDecoder->SBHUFFDT = SBHUFFDT;
2441                    pDecoder->SBHUFFRDW = SBHUFFRDW;
2442                    pDecoder->SBHUFFRDH = SBHUFFRDH;
2443                    pDecoder->SBHUFFRDX = SBHUFFRDX;
2444                    pDecoder->SBHUFFRDY = SBHUFFRDY;
2445                    pDecoder->SBHUFFRSIZE = SBHUFFRSIZE;
2446                    pDecoder->SBRTEMPLATE = SDRTEMPLATE;
2447                    pDecoder->SBRAT[0] = SDRAT[0];
2448                    pDecoder->SBRAT[1] = SDRAT[1];
2449                    pDecoder->SBRAT[2] = SDRAT[2];
2450                    pDecoder->SBRAT[3] = SDRAT[3];
2451                    JBig2IntDecoderState ids;
2452                    ids.IADT = IADT;
2453                    ids.IAFS = IAFS;
2454                    ids.IADS = IADS;
2455                    ids.IAIT = IAIT;
2456                    ids.IARI = IARI;
2457                    ids.IARDW = IARDW;
2458                    ids.IARDH = IARDH;
2459                    ids.IARDX = IARDX;
2460                    ids.IARDY = IARDY;
2461                    ids.IAID = IAID;
2462                    BS = pDecoder->decode_Arith(pArithDecoder, grContext, &ids);
2463                    if(BS == NULL) {
2464                        m_pModule->JBig2_Free(SBSYMS);
2465                        delete SBHUFFFS;
2466                        delete SBHUFFDS;
2467                        delete SBHUFFDT;
2468                        delete SBHUFFRDW;
2469                        delete SBHUFFRDH;
2470                        delete SBHUFFRDX;
2471                        delete SBHUFFRDY;
2472                        delete SBHUFFRSIZE;
2473                        delete pDecoder;
2474                        goto failed;
2475                    }
2476                    m_pModule->JBig2_Free(SBSYMS);
2477                    delete SBHUFFFS;
2478                    delete SBHUFFDS;
2479                    delete SBHUFFDT;
2480                    delete SBHUFFRDW;
2481                    delete SBHUFFRDH;
2482                    delete SBHUFFRDX;
2483                    delete SBHUFFRDY;
2484                    delete SBHUFFRSIZE;
2485                    delete pDecoder;
2486                } else if(REFAGGNINST == 1) {
2487                    SBHUFF = SDHUFF;
2488                    SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
2489                    if(IAID->decode(pArithDecoder, (int*)&IDI) == -1) {
2490                        m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2491                        goto failed;
2492                    }
2493                    if((IARDX->decode(pArithDecoder, &RDXI) == -1)
2494                            || (IARDY->decode(pArithDecoder, &RDYI) == -1)) {
2495                        m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2496                        goto failed;
2497                    }
2498                    if (IDI >= SBNUMSYMS) {
2499                        m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith):"
2500                                               " refinement references unknown symbol %d", IDI);
2501                        goto failed;
2502                    }
2503                    SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(CJBig2_Image*));
2504                    JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2505                    JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*));
2506                    if (!SBSYMS[IDI]) {
2507                        m_pModule->JBig2_Free(SBSYMS);
2508                        goto failed;
2509                    }
2510                    JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
2511                    pGRRD->GRW = SYMWIDTH;
2512                    pGRRD->GRH = HCHEIGHT;
2513                    pGRRD->GRTEMPLATE = SDRTEMPLATE;
2514                    pGRRD->GRREFERENCE = SBSYMS[IDI];
2515                    pGRRD->GRREFERENCEDX = RDXI;
2516                    pGRRD->GRREFERENCEDY = RDYI;
2517                    pGRRD->TPGRON = 0;
2518                    pGRRD->GRAT[0] = SDRAT[0];
2519                    pGRRD->GRAT[1] = SDRAT[1];
2520                    pGRRD->GRAT[2] = SDRAT[2];
2521                    pGRRD->GRAT[3] = SDRAT[3];
2522                    BS = pGRRD->decode(pArithDecoder, grContext);
2523                    if(BS == NULL) {
2524                        m_pModule->JBig2_Free(SBSYMS);
2525                        delete pGRRD;
2526                        goto failed;
2527                    }
2528                    m_pModule->JBig2_Free(SBSYMS);
2529                    delete pGRRD;
2530                }
2531            }
2532            SDNEWSYMS[NSYMSDECODED] = BS;
2533            BS = NULL;
2534            NSYMSDECODED = NSYMSDECODED + 1;
2535        }
2536    }
2537    EXINDEX = 0;
2538    CUREXFLAG = 0;
2539    EXFLAGS = (FX_BOOL*)m_pModule->JBig2_Malloc2(sizeof(FX_BOOL), (SDNUMINSYMS + SDNUMNEWSYMS));
2540    while(EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
2541        if(IAEX->decode(pArithDecoder, (int*)&EXRUNLENGTH) == -1) {
2542            m_pModule->JBig2_Free(EXFLAGS);
2543            m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2544            goto failed;
2545        }
2546        if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) {
2547            m_pModule->JBig2_Free(EXFLAGS);
2548            m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): Invalid EXRUNLENGTH value.");
2549            goto failed;
2550        }
2551        if(EXRUNLENGTH != 0) {
2552            for(I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) {
2553                EXFLAGS[I] = CUREXFLAG;
2554            }
2555        }
2556        EXINDEX = EXINDEX + EXRUNLENGTH;
2557        CUREXFLAG = !CUREXFLAG;
2558    }
2559    JBIG2_ALLOC(pDict, CJBig2_SymbolDict());
2560    pDict->SDNUMEXSYMS = SDNUMEXSYMS;
2561    pDict->SDEXSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), SDNUMEXSYMS);
2562    I = J = 0;
2563    for(I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
2564        if(EXFLAGS[I] && J < SDNUMEXSYMS) {
2565            if(I < SDNUMINSYMS) {
2566                JBIG2_ALLOC(pDict->SDEXSYMS[J], CJBig2_Image(*SDINSYMS[I]));
2567            } else {
2568                pDict->SDEXSYMS[J] = SDNEWSYMS[I - SDNUMINSYMS];
2569            }
2570            J = J + 1;
2571        } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
2572            delete SDNEWSYMS[I - SDNUMINSYMS];
2573        }
2574    }
2575    if (J < SDNUMEXSYMS) {
2576        pDict->SDNUMEXSYMS = J;
2577    }
2578    m_pModule->JBig2_Free(EXFLAGS);
2579    m_pModule->JBig2_Free(SDNEWSYMS);
2580    delete IADH;
2581    delete IADW;
2582    delete IAAI;
2583    delete IARDX;
2584    delete IARDY;
2585    delete IAEX;
2586    delete IAID;
2587    delete IADT;
2588    delete IAFS;
2589    delete IADS;
2590    delete IAIT;
2591    delete IARI;
2592    delete IARDW;
2593    delete IARDH;
2594    return pDict;
2595failed:
2596    for(I = 0; I < NSYMSDECODED; I++) {
2597        if (SDNEWSYMS[I]) {
2598            delete SDNEWSYMS[I];
2599            SDNEWSYMS[I] = NULL;
2600        }
2601    }
2602    m_pModule->JBig2_Free(SDNEWSYMS);
2603    delete IADH;
2604    delete IADW;
2605    delete IAAI;
2606    delete IARDX;
2607    delete IARDY;
2608    delete IAEX;
2609    delete IAID;
2610    delete IADT;
2611    delete IAFS;
2612    delete IADS;
2613    delete IAIT;
2614    delete IARI;
2615    delete IARDW;
2616    delete IARDH;
2617    return NULL;
2618}
2619CJBig2_SymbolDict *CJBig2_SDDProc::decode_Huffman(CJBig2_BitStream *pStream,
2620        JBig2ArithCtx *gbContext, JBig2ArithCtx *grContext, IFX_Pause* pPause)
2621{
2622    CJBig2_Image **SDNEWSYMS;
2623    FX_DWORD *SDNEWSYMWIDTHS;
2624    FX_DWORD HCHEIGHT, NSYMSDECODED;
2625    FX_INT32 HCDH;
2626    FX_DWORD SYMWIDTH, TOTWIDTH, HCFIRSTSYM;
2627    FX_INT32 DW;
2628    CJBig2_Image *BS, *BHC;
2629    FX_DWORD I, J, REFAGGNINST;
2630    FX_BOOL *EXFLAGS;
2631    FX_DWORD EXINDEX;
2632    FX_BOOL CUREXFLAG;
2633    FX_DWORD EXRUNLENGTH;
2634    FX_INT32 nVal, nBits;
2635    FX_DWORD nTmp;
2636    FX_BOOL SBHUFF;
2637    FX_DWORD SBNUMSYMS;
2638    FX_BYTE SBSYMCODELEN;
2639    JBig2HuffmanCode *SBSYMCODES;
2640    FX_DWORD IDI;
2641    FX_INT32 RDXI, RDYI;
2642    FX_DWORD BMSIZE;
2643    FX_DWORD stride;
2644    CJBig2_Image **SBSYMS;
2645    CJBig2_HuffmanTable *SBHUFFFS, *SBHUFFDS, *SBHUFFDT, *SBHUFFRDW, *SBHUFFRDH, *SBHUFFRDX, *SBHUFFRDY,
2646                        *SBHUFFRSIZE, *pTable;
2647    CJBig2_HuffmanDecoder *pHuffmanDecoder;
2648    CJBig2_GRRDProc *pGRRD;
2649    CJBig2_ArithDecoder *pArithDecoder;
2650    CJBig2_GRDProc *pGRD;
2651    CJBig2_SymbolDict *pDict;
2652    JBIG2_ALLOC(pHuffmanDecoder, CJBig2_HuffmanDecoder(pStream));
2653    SDNEWSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SDNUMNEWSYMS, sizeof(CJBig2_Image*));
2654    FXSYS_memset32(SDNEWSYMS, 0 , SDNUMNEWSYMS * sizeof(CJBig2_Image*));
2655    SDNEWSYMWIDTHS = NULL;
2656    BHC = NULL;
2657    if(SDREFAGG == 0) {
2658        SDNEWSYMWIDTHS = (FX_DWORD *)m_pModule->JBig2_Malloc2(SDNUMNEWSYMS, sizeof(FX_DWORD));
2659        FXSYS_memset32(SDNEWSYMWIDTHS, 0 , SDNUMNEWSYMS * sizeof(FX_DWORD));
2660    }
2661    HCHEIGHT = 0;
2662    NSYMSDECODED = 0;
2663    BS = NULL;
2664    while(NSYMSDECODED < SDNUMNEWSYMS) {
2665        if(pHuffmanDecoder->decodeAValue(SDHUFFDH, &HCDH) != 0) {
2666            m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2667            goto failed;
2668        }
2669        HCHEIGHT = HCHEIGHT + HCDH;
2670        if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
2671            m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): invalid HCHEIGHT value.");
2672            goto failed;
2673        }
2674        SYMWIDTH = 0;
2675        TOTWIDTH = 0;
2676        HCFIRSTSYM = NSYMSDECODED;
2677        for(;;) {
2678            nVal = pHuffmanDecoder->decodeAValue(SDHUFFDW, &DW);
2679            if(nVal == JBIG2_OOB) {
2680                break;
2681            } else if(nVal != 0) {
2682                m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2683                goto failed;
2684            } else {
2685                if (NSYMSDECODED >= SDNUMNEWSYMS) {
2686                    m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): NSYMSDECODED >= SDNUMNEWSYMS.");
2687                    goto failed;
2688                }
2689                SYMWIDTH = SYMWIDTH + DW;
2690                if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) {
2691                    m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): invalid SYMWIDTH value.");
2692                    goto failed;
2693                } else if (HCHEIGHT == 0 || SYMWIDTH == 0) {
2694                    TOTWIDTH = TOTWIDTH + SYMWIDTH;
2695                    SDNEWSYMS[NSYMSDECODED] = NULL;
2696                    NSYMSDECODED = NSYMSDECODED + 1;
2697                    continue;
2698                }
2699                TOTWIDTH = TOTWIDTH + SYMWIDTH;
2700            }
2701            if(SDREFAGG == 1) {
2702                if(pHuffmanDecoder->decodeAValue(SDHUFFAGGINST, (int*)&REFAGGNINST) != 0) {
2703                    m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2704                    goto failed;
2705                }
2706                BS = NULL;
2707                if(REFAGGNINST > 1) {
2708                    CJBig2_TRDProc *pDecoder;
2709                    JBIG2_ALLOC(pDecoder, CJBig2_TRDProc());
2710                    pDecoder->SBHUFF = SDHUFF;
2711                    pDecoder->SBREFINE = 1;
2712                    pDecoder->SBW = SYMWIDTH;
2713                    pDecoder->SBH = HCHEIGHT;
2714                    pDecoder->SBNUMINSTANCES = REFAGGNINST;
2715                    pDecoder->SBSTRIPS = 1;
2716                    pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
2717                    SBNUMSYMS = pDecoder->SBNUMSYMS;
2718                    SBSYMCODES = (JBig2HuffmanCode*)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(JBig2HuffmanCode));
2719                    nTmp = 1;
2720                    while((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
2721                        nTmp ++;
2722                    }
2723                    for(I = 0; I < SBNUMSYMS; I++) {
2724                        SBSYMCODES[I].codelen = nTmp;
2725                        SBSYMCODES[I].code = I;
2726                    }
2727                    pDecoder->SBSYMCODES = SBSYMCODES;
2728                    SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(CJBig2_Image*));
2729                    JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2730                    JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*));
2731                    pDecoder->SBSYMS = SBSYMS;
2732                    pDecoder->SBDEFPIXEL = 0;
2733                    pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
2734                    pDecoder->TRANSPOSED = 0;
2735                    pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
2736                    pDecoder->SBDSOFFSET = 0;
2737                    JBIG2_ALLOC(SBHUFFFS, CJBig2_HuffmanTable(HuffmanTable_B6,
2738                                sizeof(HuffmanTable_B6) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B6));
2739                    JBIG2_ALLOC(SBHUFFDS, CJBig2_HuffmanTable(HuffmanTable_B8,
2740                                sizeof(HuffmanTable_B8) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B8));
2741                    JBIG2_ALLOC(SBHUFFDT, CJBig2_HuffmanTable(HuffmanTable_B11,
2742                                sizeof(HuffmanTable_B11) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B11));
2743                    JBIG2_ALLOC(SBHUFFRDW, CJBig2_HuffmanTable(HuffmanTable_B15,
2744                                sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2745                    JBIG2_ALLOC(SBHUFFRDH, CJBig2_HuffmanTable(HuffmanTable_B15,
2746                                sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2747                    JBIG2_ALLOC(SBHUFFRDX, CJBig2_HuffmanTable(HuffmanTable_B15,
2748                                sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2749                    JBIG2_ALLOC(SBHUFFRDY, CJBig2_HuffmanTable(HuffmanTable_B15,
2750                                sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2751                    JBIG2_ALLOC(SBHUFFRSIZE, CJBig2_HuffmanTable(HuffmanTable_B1,
2752                                sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
2753                    pDecoder->SBHUFFFS = SBHUFFFS;
2754                    pDecoder->SBHUFFDS = SBHUFFDS;
2755                    pDecoder->SBHUFFDT = SBHUFFDT;
2756                    pDecoder->SBHUFFRDW = SBHUFFRDW;
2757                    pDecoder->SBHUFFRDH = SBHUFFRDH;
2758                    pDecoder->SBHUFFRDX = SBHUFFRDX;
2759                    pDecoder->SBHUFFRDY = SBHUFFRDY;
2760                    pDecoder->SBHUFFRSIZE = SBHUFFRSIZE;
2761                    pDecoder->SBRTEMPLATE = SDRTEMPLATE;
2762                    pDecoder->SBRAT[0] = SDRAT[0];
2763                    pDecoder->SBRAT[1] = SDRAT[1];
2764                    pDecoder->SBRAT[2] = SDRAT[2];
2765                    pDecoder->SBRAT[3] = SDRAT[3];
2766                    BS = pDecoder->decode_Huffman(pStream, grContext);
2767                    if(BS == NULL) {
2768                        m_pModule->JBig2_Free(SBSYMCODES);
2769                        m_pModule->JBig2_Free(SBSYMS);
2770                        delete SBHUFFFS;
2771                        delete SBHUFFDS;
2772                        delete SBHUFFDT;
2773                        delete SBHUFFRDW;
2774                        delete SBHUFFRDH;
2775                        delete SBHUFFRDX;
2776                        delete SBHUFFRDY;
2777                        delete SBHUFFRSIZE;
2778                        delete pDecoder;
2779                        goto failed;
2780                    }
2781                    m_pModule->JBig2_Free(SBSYMCODES);
2782                    m_pModule->JBig2_Free(SBSYMS);
2783                    delete SBHUFFFS;
2784                    delete SBHUFFDS;
2785                    delete SBHUFFDT;
2786                    delete SBHUFFRDW;
2787                    delete SBHUFFRDH;
2788                    delete SBHUFFRDX;
2789                    delete SBHUFFRDY;
2790                    delete SBHUFFRSIZE;
2791                    delete pDecoder;
2792                } else if(REFAGGNINST == 1) {
2793                    SBHUFF = SDHUFF;
2794                    SBNUMSYMS = SDNUMINSYMS + SDNUMNEWSYMS;
2795                    nTmp = 1;
2796                    while((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
2797                        nTmp ++;
2798                    }
2799                    SBSYMCODELEN = (FX_BYTE)nTmp;
2800                    SBSYMCODES = (JBig2HuffmanCode*)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(JBig2HuffmanCode));
2801                    for(I = 0; I < SBNUMSYMS; I++) {
2802                        SBSYMCODES[I].codelen = SBSYMCODELEN;
2803                        SBSYMCODES[I].code = I;
2804                    }
2805                    nVal = 0;
2806                    nBits = 0;
2807                    for(;;) {
2808                        if(pStream->read1Bit(&nTmp) != 0) {
2809                            m_pModule->JBig2_Free(SBSYMCODES);
2810                            m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2811                            goto failed;
2812                        }
2813                        nVal = (nVal << 1) | nTmp;
2814                        for(IDI = 0; IDI < SBNUMSYMS; IDI++) {
2815                            if((nVal == SBSYMCODES[IDI].code)
2816                                    && (nBits == SBSYMCODES[IDI].codelen)) {
2817                                break;
2818                            }
2819                        }
2820                        if(IDI < SBNUMSYMS) {
2821                            break;
2822                        }
2823                    }
2824                    m_pModule->JBig2_Free(SBSYMCODES);
2825                    JBIG2_ALLOC(SBHUFFRDX, CJBig2_HuffmanTable(HuffmanTable_B15,
2826                                sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2827                    JBIG2_ALLOC(SBHUFFRSIZE, CJBig2_HuffmanTable(HuffmanTable_B1,
2828                                sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
2829                    if((pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0)
2830                            || (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDYI) != 0)
2831                            || (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
2832                        delete SBHUFFRDX;
2833                        delete SBHUFFRSIZE;
2834                        m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2835                        goto failed;
2836                    }
2837                    delete SBHUFFRDX;
2838                    delete SBHUFFRSIZE;
2839                    pStream->alignByte();
2840                    nTmp = pStream->getOffset();
2841                    SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(CJBig2_Image*));
2842                    JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2843                    JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*));
2844                    JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
2845                    pGRRD->GRW = SYMWIDTH;
2846                    pGRRD->GRH = HCHEIGHT;
2847                    pGRRD->GRTEMPLATE = SDRTEMPLATE;
2848                    pGRRD->GRREFERENCE = SBSYMS[IDI];
2849                    pGRRD->GRREFERENCEDX = RDXI;
2850                    pGRRD->GRREFERENCEDY = RDYI;
2851                    pGRRD->TPGRON = 0;
2852                    pGRRD->GRAT[0] = SDRAT[0];
2853                    pGRRD->GRAT[1] = SDRAT[1];
2854                    pGRRD->GRAT[2] = SDRAT[2];
2855                    pGRRD->GRAT[3] = SDRAT[3];
2856                    JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(pStream));
2857                    BS = pGRRD->decode(pArithDecoder, grContext);
2858                    if(BS == NULL) {
2859                        m_pModule->JBig2_Free(SBSYMS);
2860                        delete pGRRD;
2861                        delete pArithDecoder;
2862                        goto failed;
2863                    }
2864                    pStream->alignByte();
2865                    pStream->offset(2);
2866                    if((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
2867                        delete BS;
2868                        m_pModule->JBig2_Free(SBSYMS);
2869                        delete pGRRD;
2870                        delete pArithDecoder;
2871                        m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman):"
2872                                               "bytes processed by generic refinement region decoding procedure doesn't equal SBHUFFRSIZE.");
2873                        goto failed;
2874                    }
2875                    m_pModule->JBig2_Free(SBSYMS);
2876                    delete pGRRD;
2877                    delete pArithDecoder;
2878                }
2879                SDNEWSYMS[NSYMSDECODED] = BS;
2880            }
2881            if(SDREFAGG == 0) {
2882                SDNEWSYMWIDTHS[NSYMSDECODED] = SYMWIDTH;
2883            }
2884            NSYMSDECODED = NSYMSDECODED + 1;
2885        }
2886        if(SDREFAGG == 0) {
2887            if(pHuffmanDecoder->decodeAValue(SDHUFFBMSIZE, (FX_INT32*)&BMSIZE) != 0) {
2888                m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2889                goto failed;
2890            }
2891            pStream->alignByte();
2892            if(BMSIZE == 0) {
2893                stride = (TOTWIDTH + 7) >> 3;
2894                if(pStream->getByteLeft() >= stride * HCHEIGHT) {
2895                    JBIG2_ALLOC(BHC, CJBig2_Image(TOTWIDTH, HCHEIGHT));
2896                    for(I = 0; I < HCHEIGHT; I ++) {
2897                        JBIG2_memcpy(BHC->m_pData + I * BHC->m_nStride, pStream->getPointer(), stride);
2898                        pStream->offset(stride);
2899                    }
2900                } else {
2901                    m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2902                    goto failed;
2903                }
2904            } else {
2905                JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
2906                pGRD->MMR = 1;
2907                pGRD->GBW = TOTWIDTH;
2908                pGRD->GBH = HCHEIGHT;
2909                FXCODEC_STATUS status = pGRD->Start_decode_MMR(&BHC, pStream);
2910                while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
2911                    pGRD->Continue_decode(pPause);
2912                }
2913                delete pGRD;
2914                pStream->alignByte();
2915            }
2916            nTmp = 0;
2917            if (!BHC) {
2918                continue;
2919            }
2920            for(I = HCFIRSTSYM; I < NSYMSDECODED; I++) {
2921                SDNEWSYMS[I] = BHC->subImage(nTmp, 0, SDNEWSYMWIDTHS[I], HCHEIGHT);
2922                nTmp += SDNEWSYMWIDTHS[I];
2923            }
2924            delete BHC;
2925            BHC = NULL;
2926        }
2927    }
2928    EXINDEX = 0;
2929    CUREXFLAG = 0;
2930    JBIG2_ALLOC(pTable, CJBig2_HuffmanTable(HuffmanTable_B1,
2931                                            sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
2932    EXFLAGS = (FX_BOOL*)m_pModule->JBig2_Malloc2(sizeof(FX_BOOL), (SDNUMINSYMS + SDNUMNEWSYMS));
2933    while(EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
2934        if(pHuffmanDecoder->decodeAValue(pTable, (int*)&EXRUNLENGTH) != 0) {
2935            delete pTable;
2936            m_pModule->JBig2_Free(EXFLAGS);
2937            m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2938            goto failed;
2939        }
2940        if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) {
2941            delete pTable;
2942            m_pModule->JBig2_Free(EXFLAGS);
2943            m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): Invalid EXRUNLENGTH value.");
2944            goto failed;
2945        }
2946        if(EXRUNLENGTH != 0) {
2947            for(I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) {
2948                EXFLAGS[I] = CUREXFLAG;
2949            }
2950        }
2951        EXINDEX = EXINDEX + EXRUNLENGTH;
2952        CUREXFLAG = !CUREXFLAG;
2953    }
2954    delete pTable;
2955    JBIG2_ALLOC(pDict, CJBig2_SymbolDict());
2956    pDict->SDNUMEXSYMS = SDNUMEXSYMS;
2957    pDict->SDEXSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), SDNUMEXSYMS);
2958    I = J = 0;
2959    for(I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
2960        if(EXFLAGS[I] && J < SDNUMEXSYMS) {
2961            if(I < SDNUMINSYMS) {
2962                JBIG2_ALLOC(pDict->SDEXSYMS[J], CJBig2_Image(*SDINSYMS[I]));
2963            } else {
2964                pDict->SDEXSYMS[J] = SDNEWSYMS[I - SDNUMINSYMS];
2965            }
2966            J = J + 1;
2967        } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
2968            delete SDNEWSYMS[I - SDNUMINSYMS];
2969        }
2970    }
2971    if (J < SDNUMEXSYMS) {
2972        pDict->SDNUMEXSYMS = J;
2973    }
2974    m_pModule->JBig2_Free(EXFLAGS);
2975    m_pModule->JBig2_Free(SDNEWSYMS);
2976    if(SDREFAGG == 0) {
2977        m_pModule->JBig2_Free(SDNEWSYMWIDTHS);
2978    }
2979    delete pHuffmanDecoder;
2980    return pDict;
2981failed:
2982    for(I = 0; I < NSYMSDECODED; I++) {
2983        if (SDNEWSYMS[I]) {
2984            delete SDNEWSYMS[I];
2985        }
2986    }
2987    m_pModule->JBig2_Free(SDNEWSYMS);
2988    if(SDREFAGG == 0) {
2989        m_pModule->JBig2_Free(SDNEWSYMWIDTHS);
2990    }
2991    delete pHuffmanDecoder;
2992    return NULL;
2993}
2994CJBig2_Image *CJBig2_HTRDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder,
2995        JBig2ArithCtx *gbContext, IFX_Pause* pPause)
2996{
2997    FX_DWORD ng, mg;
2998    FX_INT32 x, y;
2999    CJBig2_Image *HSKIP;
3000    FX_DWORD HBPP;
3001    FX_DWORD *GI;
3002    CJBig2_Image *HTREG;
3003    CJBig2_GSIDProc *pGID;
3004    JBIG2_ALLOC(HTREG, CJBig2_Image(HBW, HBH));
3005    HTREG->fill(HDEFPIXEL);
3006    HSKIP = NULL;
3007    if(HENABLESKIP == 1) {
3008        JBIG2_ALLOC(HSKIP, CJBig2_Image(HGW, HGH));
3009        for(mg = 0; mg < HGH; mg++) {
3010            for(ng = 0; ng < HGW; ng++) {
3011                x = (HGX + mg * HRY + ng * HRX) >> 8;
3012                y = (HGY + mg * HRX - ng * HRY) >> 8;
3013                if((x + HPW <= 0) | (x >= (FX_INT32)HBW)
3014                        | (y + HPH <= 0) | (y >= (FX_INT32)HPH)) {
3015                    HSKIP->setPixel(ng, mg, 1);
3016                } else {
3017                    HSKIP->setPixel(ng, mg, 0);
3018                }
3019            }
3020        }
3021    }
3022    HBPP = 1;
3023    while((FX_DWORD)(1 << HBPP) < HNUMPATS) {
3024        HBPP ++;
3025    }
3026    JBIG2_ALLOC(pGID, CJBig2_GSIDProc());
3027    pGID->GSMMR = HMMR;
3028    pGID->GSW = HGW;
3029    pGID->GSH = HGH;
3030    pGID->GSBPP = (FX_BYTE)HBPP;
3031    pGID->GSUSESKIP = HENABLESKIP;
3032    pGID->GSKIP = HSKIP;
3033    pGID->GSTEMPLATE = HTEMPLATE;
3034    GI = pGID->decode_Arith(pArithDecoder, gbContext, pPause);
3035    if(GI == NULL) {
3036        goto failed;
3037    }
3038    for(mg = 0; mg < HGH; mg++) {
3039        for(ng = 0; ng < HGW; ng++) {
3040            x = (HGX + mg * HRY + ng * HRX) >> 8;
3041            y = (HGY + mg * HRX - ng * HRY) >> 8;
3042            FX_DWORD pat_index = GI[mg * HGW + ng];
3043            if (pat_index >= HNUMPATS) {
3044                pat_index = HNUMPATS - 1;
3045            }
3046            HTREG->composeFrom(x, y, HPATS[pat_index], HCOMBOP);
3047        }
3048    }
3049    m_pModule->JBig2_Free(GI);
3050    if(HSKIP) {
3051        delete HSKIP;
3052    }
3053    delete pGID;
3054    return HTREG;
3055failed:
3056    if(HSKIP) {
3057        delete HSKIP;
3058    }
3059    delete pGID;
3060    delete HTREG;
3061    return NULL;
3062}
3063CJBig2_Image *CJBig2_HTRDProc::decode_MMR(CJBig2_BitStream *pStream, IFX_Pause* pPause)
3064{
3065    FX_DWORD ng, mg;
3066    FX_INT32 x, y;
3067    FX_DWORD HBPP;
3068    FX_DWORD *GI;
3069    CJBig2_Image *HTREG;
3070    CJBig2_GSIDProc *pGID;
3071    JBIG2_ALLOC(HTREG, CJBig2_Image(HBW, HBH));
3072    HTREG->fill(HDEFPIXEL);
3073    HBPP = 1;
3074    while((FX_DWORD)(1 << HBPP) < HNUMPATS) {
3075        HBPP ++;
3076    }
3077    JBIG2_ALLOC(pGID, CJBig2_GSIDProc());
3078    pGID->GSMMR = HMMR;
3079    pGID->GSW = HGW;
3080    pGID->GSH = HGH;
3081    pGID->GSBPP = (FX_BYTE)HBPP;
3082    pGID->GSUSESKIP = 0;
3083    GI = pGID->decode_MMR(pStream, pPause);
3084    if(GI == NULL) {
3085        goto failed;
3086    }
3087    for(mg = 0; mg < HGH; mg++) {
3088        for(ng = 0; ng < HGW; ng++) {
3089            x = (HGX + mg * HRY + ng * HRX) >> 8;
3090            y = (HGY + mg * HRX - ng * HRY) >> 8;
3091            FX_DWORD pat_index = GI[mg * HGW + ng];
3092            if (pat_index >= HNUMPATS) {
3093                pat_index = HNUMPATS - 1;
3094            }
3095            HTREG->composeFrom(x, y, HPATS[pat_index], HCOMBOP);
3096        }
3097    }
3098    m_pModule->JBig2_Free(GI);
3099    delete pGID;
3100    return HTREG;
3101failed:
3102    delete pGID;
3103    delete HTREG;
3104    return NULL;
3105}
3106CJBig2_PatternDict *CJBig2_PDDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder,
3107        JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3108{
3109    FX_DWORD GRAY;
3110    CJBig2_Image *BHDC = NULL;
3111    CJBig2_PatternDict *pDict;
3112    CJBig2_GRDProc *pGRD;
3113    JBIG2_ALLOC(pDict, CJBig2_PatternDict());
3114    pDict->NUMPATS = GRAYMAX + 1;
3115    pDict->HDPATS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), pDict->NUMPATS);
3116    JBIG2_memset(pDict->HDPATS, 0, sizeof(CJBig2_Image*)*pDict->NUMPATS);
3117    JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
3118    pGRD->MMR = HDMMR;
3119    pGRD->GBW = (GRAYMAX + 1) * HDPW;
3120    pGRD->GBH = HDPH;
3121    pGRD->GBTEMPLATE = HDTEMPLATE;
3122    pGRD->TPGDON = 0;
3123    pGRD->USESKIP = 0;
3124    pGRD->GBAT[0] = -(FX_INT32)HDPW;
3125    pGRD->GBAT[1] = 0;
3126    if(pGRD->GBTEMPLATE == 0) {
3127        pGRD->GBAT[2] = -3;
3128        pGRD->GBAT[3] = -1;
3129        pGRD->GBAT[4] = 2;
3130        pGRD->GBAT[5] = -2;
3131        pGRD->GBAT[6] = -2;
3132        pGRD->GBAT[7] = -2;
3133    }
3134    FXCODEC_STATUS status = pGRD->Start_decode_Arith(&BHDC, pArithDecoder, gbContext);
3135    while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3136        pGRD->Continue_decode(pPause);
3137    }
3138    if(BHDC == NULL) {
3139        delete pGRD;
3140        goto failed;
3141    }
3142    delete pGRD;
3143    GRAY = 0;
3144    while(GRAY <= GRAYMAX) {
3145        pDict->HDPATS[GRAY] = BHDC->subImage(HDPW * GRAY, 0, HDPW, HDPH);
3146        GRAY = GRAY + 1;
3147    }
3148    delete BHDC;
3149    return pDict;
3150failed:
3151    delete pDict;
3152    return NULL;
3153}
3154
3155CJBig2_PatternDict *CJBig2_PDDProc::decode_MMR(CJBig2_BitStream *pStream, IFX_Pause* pPause)
3156{
3157    FX_DWORD GRAY;
3158    CJBig2_Image *BHDC = NULL;
3159    CJBig2_PatternDict *pDict;
3160    CJBig2_GRDProc *pGRD;
3161    JBIG2_ALLOC(pDict, CJBig2_PatternDict());
3162    pDict->NUMPATS = GRAYMAX + 1;
3163    pDict->HDPATS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), pDict->NUMPATS);
3164    JBIG2_memset(pDict->HDPATS, 0, sizeof(CJBig2_Image*)*pDict->NUMPATS);
3165    JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
3166    pGRD->MMR = HDMMR;
3167    pGRD->GBW = (GRAYMAX + 1) * HDPW;
3168    pGRD->GBH = HDPH;
3169    FXCODEC_STATUS status = pGRD->Start_decode_MMR(&BHDC, pStream);
3170    while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3171        pGRD->Continue_decode(pPause);
3172    }
3173    if(BHDC == NULL) {
3174        delete pGRD;
3175        goto failed;
3176    }
3177    delete pGRD;
3178    GRAY = 0;
3179    while(GRAY <= GRAYMAX) {
3180        pDict->HDPATS[GRAY] = BHDC->subImage(HDPW * GRAY, 0, HDPW, HDPH);
3181        GRAY = GRAY + 1;
3182    }
3183    delete BHDC;
3184    return pDict;
3185failed:
3186    delete pDict;
3187    return NULL;
3188}
3189FX_DWORD *CJBig2_GSIDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder,
3190                                        JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3191{
3192    CJBig2_Image **GSPLANES;
3193    FX_INT32 J, K;
3194    FX_DWORD x, y;
3195    FX_DWORD *GSVALS;
3196    CJBig2_GRDProc *pGRD;
3197    GSPLANES = (CJBig2_Image **)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), GSBPP);
3198    if (!GSPLANES) {
3199        return NULL;
3200    }
3201    GSVALS = (FX_DWORD*)m_pModule->JBig2_Malloc3(sizeof(FX_DWORD), GSW, GSH);
3202    if (!GSVALS) {
3203        m_pModule->JBig2_Free(GSPLANES);
3204        return NULL;
3205    }
3206    JBIG2_memset(GSPLANES, 0, sizeof(CJBig2_Image*)*GSBPP);
3207    JBIG2_memset(GSVALS, 0, sizeof(FX_DWORD)*GSW * GSH);
3208    JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
3209    pGRD->MMR = GSMMR;
3210    pGRD->GBW = GSW;
3211    pGRD->GBH = GSH;
3212    pGRD->GBTEMPLATE = GSTEMPLATE;
3213    pGRD->TPGDON = 0;
3214    pGRD->USESKIP = GSUSESKIP;
3215    pGRD->SKIP = GSKIP;
3216    if(GSTEMPLATE <= 1) {
3217        pGRD->GBAT[0] = 3;
3218    } else {
3219        pGRD->GBAT[0] = 2;
3220    }
3221    pGRD->GBAT[1] = -1;
3222    if(pGRD->GBTEMPLATE == 0) {
3223        pGRD->GBAT[2] = -3;
3224        pGRD->GBAT[3] = -1;
3225        pGRD->GBAT[4] = 2;
3226        pGRD->GBAT[5] = -2;
3227        pGRD->GBAT[6] = -2;
3228        pGRD->GBAT[7] = -2;
3229    }
3230    FXCODEC_STATUS status = pGRD->Start_decode_Arith(&GSPLANES[GSBPP - 1], pArithDecoder, gbContext);
3231    while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3232        pGRD->Continue_decode(pPause);
3233    }
3234    if(GSPLANES[GSBPP - 1] == NULL) {
3235        goto failed;
3236    }
3237    J = GSBPP - 2;
3238    while(J >= 0) {
3239        FXCODEC_STATUS status = pGRD->Start_decode_Arith(&GSPLANES[J], pArithDecoder, gbContext);
3240        while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3241            pGRD->Continue_decode(pPause);
3242        }
3243        if(GSPLANES[J] == NULL) {
3244            for(K = GSBPP - 1; K > J; K--) {
3245                delete GSPLANES[K];
3246                goto failed;
3247            }
3248        }
3249        GSPLANES[J]->composeFrom(0, 0, GSPLANES[J + 1], JBIG2_COMPOSE_XOR);
3250        J = J - 1;
3251    }
3252    for(y = 0; y < GSH; y++) {
3253        for(x = 0; x < GSW; x++) {
3254            for(J = 0; J < GSBPP; J++) {
3255                GSVALS[y * GSW + x] |= GSPLANES[J]->getPixel(x, y) << J;
3256            }
3257        }
3258    }
3259    for(J = 0; J < GSBPP; J++) {
3260        delete GSPLANES[J];
3261    }
3262    m_pModule->JBig2_Free(GSPLANES);
3263    delete pGRD;
3264    return GSVALS;
3265failed:
3266    m_pModule->JBig2_Free(GSPLANES);
3267    delete pGRD;
3268    m_pModule->JBig2_Free(GSVALS);
3269    return NULL;
3270}
3271FX_DWORD *CJBig2_GSIDProc::decode_MMR(CJBig2_BitStream *pStream, IFX_Pause* pPause)
3272{
3273    CJBig2_Image **GSPLANES;
3274    FX_INT32 J, K;
3275    FX_DWORD x, y;
3276    FX_DWORD *GSVALS;
3277    CJBig2_GRDProc *pGRD;
3278    GSPLANES = (CJBig2_Image **)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), GSBPP);
3279    if (!GSPLANES) {
3280        return NULL;
3281    }
3282    GSVALS = (FX_DWORD*)m_pModule->JBig2_Malloc3(sizeof(FX_DWORD), GSW, GSH);
3283    if (!GSVALS) {
3284        if (GSPLANES) {
3285            m_pModule->JBig2_Free(GSPLANES);
3286        }
3287        return NULL;
3288    }
3289    JBIG2_memset(GSPLANES, 0, sizeof(CJBig2_Image*)*GSBPP);
3290    JBIG2_memset(GSVALS, 0, sizeof(FX_DWORD)*GSW * GSH);
3291    JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
3292    pGRD->MMR = GSMMR;
3293    pGRD->GBW = GSW;
3294    pGRD->GBH = GSH;
3295    FXCODEC_STATUS status = pGRD->Start_decode_MMR(&GSPLANES[GSBPP - 1], pStream);
3296    while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3297        pGRD->Continue_decode(pPause);
3298    }
3299    if(GSPLANES[GSBPP - 1] == NULL) {
3300        goto failed;
3301    }
3302    pStream->alignByte();
3303    pStream->offset(3);
3304    J = GSBPP - 2;
3305    while(J >= 0) {
3306        FXCODEC_STATUS status = pGRD->Start_decode_MMR(&GSPLANES[J], pStream);
3307        while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3308            pGRD->Continue_decode(pPause);
3309        }
3310        if(GSPLANES[J] == NULL) {
3311            for(K = GSBPP - 1; K > J; K--) {
3312                delete GSPLANES[K];
3313                goto failed;
3314            }
3315        }
3316        pStream->alignByte();
3317        pStream->offset(3);
3318        GSPLANES[J]->composeFrom(0, 0, GSPLANES[J + 1], JBIG2_COMPOSE_XOR);
3319        J = J - 1;
3320    }
3321    for(y = 0; y < GSH; y++) {
3322        for(x = 0; x < GSW; x++) {
3323            for(J = 0; J < GSBPP; J++) {
3324                GSVALS[y * GSW + x] |= GSPLANES[J]->getPixel(x, y) << J;
3325            }
3326        }
3327    }
3328    for(J = 0; J < GSBPP; J++) {
3329        delete GSPLANES[J];
3330    }
3331    m_pModule->JBig2_Free(GSPLANES);
3332    delete pGRD;
3333    return GSVALS;
3334failed:
3335    m_pModule->JBig2_Free(GSPLANES);
3336    delete pGRD;
3337    m_pModule->JBig2_Free(GSVALS);
3338    return NULL;
3339}
3340FXCODEC_STATUS CJBig2_GRDProc::Start_decode_Arith(CJBig2_Image** pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3341{
3342    if (GBW == 0 || GBH == 0) {
3343        m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3344        return FXCODEC_STATUS_DECODE_FINISH;
3345    }
3346    m_ProssiveStatus = FXCODEC_STATUS_DECODE_READY;
3347    m_pPause = pPause;
3348    if(*pImage == NULL) {
3349        JBIG2_ALLOC((*pImage), CJBig2_Image(GBW, GBH));
3350    }
3351    if ((*pImage)->m_pData == NULL) {
3352        delete *pImage;
3353        *pImage = NULL;
3354        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
3355        m_ProssiveStatus = FXCODEC_STATUS_ERROR;
3356        return FXCODEC_STATUS_ERROR;
3357    }
3358    m_DecodeType = 1;
3359    m_pImage = pImage;
3360    (*m_pImage)->fill(0);
3361    m_pArithDecoder = pArithDecoder;
3362    m_gbContext = gbContext;
3363    LTP = 0;
3364    m_pLine = NULL;
3365    m_loopIndex = 0;
3366    return decode_Arith(pPause);
3367}
3368FXCODEC_STATUS CJBig2_GRDProc::decode_Arith(IFX_Pause* pPause)
3369{
3370    int iline = m_loopIndex;
3371    CJBig2_Image* pImage = *m_pImage;
3372    if(GBTEMPLATE == 0) {
3373        if((GBAT[0] == 3) && (GBAT[1] == (signed char) - 1)
3374                && (GBAT[2] == (signed char) - 3) && (GBAT[3] == (signed char) - 1)
3375                && (GBAT[4] == 2) && (GBAT[5] == (signed char) - 2)
3376                && (GBAT[6] == (signed char) - 2) && (GBAT[7] == (signed char) - 2)) {
3377            m_ProssiveStatus = decode_Arith_Template0_opt3(pImage, m_pArithDecoder, m_gbContext, pPause);
3378        } else {
3379            m_ProssiveStatus = decode_Arith_Template0_unopt(pImage, m_pArithDecoder, m_gbContext, pPause);
3380        }
3381    } else if(GBTEMPLATE == 1) {
3382        if((GBAT[0] == 3) && (GBAT[1] == (signed char) - 1)) {
3383            m_ProssiveStatus = decode_Arith_Template1_opt3(pImage, m_pArithDecoder, m_gbContext, pPause);
3384        } else {
3385            m_ProssiveStatus = decode_Arith_Template1_unopt(pImage, m_pArithDecoder, m_gbContext, pPause);
3386        }
3387    } else if(GBTEMPLATE == 2) {
3388        if((GBAT[0] == 2) && (GBAT[1] == (signed char) - 1)) {
3389            m_ProssiveStatus =  decode_Arith_Template2_opt3(pImage, m_pArithDecoder, m_gbContext, pPause);
3390        } else {
3391            m_ProssiveStatus =  decode_Arith_Template2_unopt(pImage, m_pArithDecoder, m_gbContext, pPause);
3392        }
3393    } else {
3394        if((GBAT[0] == 2) && (GBAT[1] == (signed char) - 1)) {
3395            m_ProssiveStatus = decode_Arith_Template3_opt3(pImage, m_pArithDecoder, m_gbContext, pPause);
3396        } else {
3397            m_ProssiveStatus = decode_Arith_Template3_unopt(pImage, m_pArithDecoder, m_gbContext, pPause);
3398        }
3399    }
3400    m_ReplaceRect.left = 0;
3401    m_ReplaceRect.right = pImage->m_nWidth;
3402    m_ReplaceRect.top = iline;
3403    m_ReplaceRect.bottom = m_loopIndex;
3404    if(m_ProssiveStatus == FXCODEC_STATUS_DECODE_FINISH) {
3405        m_loopIndex = 0;
3406    }
3407    return m_ProssiveStatus;
3408}
3409FXCODEC_STATUS CJBig2_GRDProc::Start_decode_Arith_V2(CJBig2_Image** pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3410{
3411    if(GBW == 0 || GBH == 0) {
3412        * pImage = NULL;
3413        m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3414        return FXCODEC_STATUS_DECODE_FINISH;
3415    }
3416    if(*pImage == NULL) {
3417        JBIG2_ALLOC((*pImage), CJBig2_Image(GBW, GBH));
3418    }
3419    if ((*pImage)->m_pData == NULL) {
3420        delete *pImage;
3421        *pImage = NULL;
3422        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
3423        m_ProssiveStatus = FXCODEC_STATUS_ERROR;
3424        return FXCODEC_STATUS_ERROR;
3425    }
3426    m_ProssiveStatus = FXCODEC_STATUS_DECODE_READY;
3427    m_DecodeType = 2;
3428    m_pPause = pPause;
3429    m_pImage = pImage;
3430    (*m_pImage)->fill(0);
3431    LTP = 0;
3432    m_loopIndex = 0;
3433    m_pArithDecoder = pArithDecoder;
3434    m_gbContext = gbContext;
3435    return decode_Arith_V2(pPause);
3436}
3437FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_V2(IFX_Pause* pPause)
3438{
3439    FX_BOOL SLTP, bVal;
3440    FX_DWORD CONTEXT;
3441    CJBig2_Image *GBREG = *m_pImage;
3442    FX_DWORD line1, line2, line3;
3443    LTP = 0;
3444    JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
3445    GBREG->fill(0);
3446    for(; m_loopIndex < GBH; m_loopIndex++) {
3447        if(TPGDON) {
3448            switch(GBTEMPLATE) {
3449                case 0:
3450                    CONTEXT = 0x9b25;
3451                    break;
3452                case 1:
3453                    CONTEXT = 0x0795;
3454                    break;
3455                case 2:
3456                    CONTEXT = 0x00e5;
3457                    break;
3458                case 3:
3459                    CONTEXT = 0x0195;
3460                    break;
3461            }
3462            SLTP = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3463            LTP = LTP ^ SLTP;
3464        }
3465        if(LTP == 1) {
3466            GBREG->copyLine(m_loopIndex, m_loopIndex - 1);
3467        } else {
3468            switch(GBTEMPLATE) {
3469                case 0: {
3470                        line1 = GBREG->getPixel(1, m_loopIndex - 2);
3471                        line1 |= GBREG->getPixel(0, m_loopIndex - 2) << 1;
3472                        line2 = GBREG->getPixel(2, m_loopIndex - 1);
3473                        line2 |= GBREG->getPixel(1, m_loopIndex - 1) << 1;
3474                        line2 |= GBREG->getPixel(0, m_loopIndex - 1) << 2;
3475                        line3 = 0;
3476                        for(FX_DWORD w = 0; w < GBW; w++) {
3477                            if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3478                                bVal = 0;
3479                            } else {
3480                                CONTEXT = line3;
3481                                CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
3482                                CONTEXT |= line2 << 5;
3483                                CONTEXT |= GBREG->getPixel(w + GBAT[2], m_loopIndex + GBAT[3]) << 10;
3484                                CONTEXT |= GBREG->getPixel(w + GBAT[4], m_loopIndex + GBAT[5]) << 11;
3485                                CONTEXT |= line1 << 12;
3486                                CONTEXT |= GBREG->getPixel(w + GBAT[6], m_loopIndex + GBAT[7]) << 15;
3487                                bVal = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3488                            }
3489                            if(bVal) {
3490                                GBREG->setPixel(w, m_loopIndex, bVal);
3491                            }
3492                            line1 = ((line1 << 1) | GBREG->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
3493                            line2 = ((line2 << 1) | GBREG->getPixel(w + 3, m_loopIndex - 1)) & 0x1f;
3494                            line3 = ((line3 << 1) | bVal) & 0x0f;
3495                        }
3496                    }
3497                    break;
3498                case 1: {
3499                        line1 = GBREG->getPixel(2, m_loopIndex - 2);
3500                        line1 |= GBREG->getPixel(1, m_loopIndex - 2) << 1;
3501                        line1 |= GBREG->getPixel(0, m_loopIndex - 2) << 2;
3502                        line2 = GBREG->getPixel(2, m_loopIndex - 1);
3503                        line2 |= GBREG->getPixel(1, m_loopIndex - 1) << 1;
3504                        line2 |= GBREG->getPixel(0, m_loopIndex - 1) << 2;
3505                        line3 = 0;
3506                        for(FX_DWORD w = 0; w < GBW; w++) {
3507                            if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3508                                bVal = 0;
3509                            } else {
3510                                CONTEXT = line3;
3511                                CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 3;
3512                                CONTEXT |= line2 << 4;
3513                                CONTEXT |= line1 << 9;
3514                                bVal = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3515                            }
3516                            if(bVal) {
3517                                GBREG->setPixel(w, m_loopIndex, bVal);
3518                            }
3519                            line1 = ((line1 << 1) | GBREG->getPixel(w + 3, m_loopIndex - 2)) & 0x0f;
3520                            line2 = ((line2 << 1) | GBREG->getPixel(w + 3, m_loopIndex - 1)) & 0x1f;
3521                            line3 = ((line3 << 1) | bVal) & 0x07;
3522                        }
3523                    }
3524                    break;
3525                case 2: {
3526                        line1 = GBREG->getPixel(1, m_loopIndex - 2);
3527                        line1 |= GBREG->getPixel(0, m_loopIndex - 2) << 1;
3528                        line2 = GBREG->getPixel(1, m_loopIndex - 1);
3529                        line2 |= GBREG->getPixel(0, m_loopIndex - 1) << 1;
3530                        line3 = 0;
3531                        for(FX_DWORD w = 0; w < GBW; w++) {
3532                            if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3533                                bVal = 0;
3534                            } else {
3535                                CONTEXT = line3;
3536                                CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 2;
3537                                CONTEXT |= line2 << 3;
3538                                CONTEXT |= line1 << 7;
3539                                bVal = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3540                            }
3541                            if(bVal) {
3542                                GBREG->setPixel(w, m_loopIndex, bVal);
3543                            }
3544                            line1 = ((line1 << 1) | GBREG->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
3545                            line2 = ((line2 << 1) | GBREG->getPixel(w + 2, m_loopIndex - 1)) & 0x0f;
3546                            line3 = ((line3 << 1) | bVal) & 0x03;
3547                        }
3548                    }
3549                    break;
3550                case 3: {
3551                        line1 = GBREG->getPixel(1, m_loopIndex - 1);
3552                        line1 |= GBREG->getPixel(0, m_loopIndex - 1) << 1;
3553                        line2 = 0;
3554                        for(FX_DWORD w = 0; w < GBW; w++) {
3555                            if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3556                                bVal = 0;
3557                            } else {
3558                                CONTEXT = line2;
3559                                CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
3560                                CONTEXT |= line1 << 5;
3561                                bVal = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3562                            }
3563                            if(bVal) {
3564                                GBREG->setPixel(w, m_loopIndex, bVal);
3565                            }
3566                            line1 = ((line1 << 1) | GBREG->getPixel(w + 2, m_loopIndex - 1)) & 0x1f;
3567                            line2 = ((line2 << 1) | bVal) & 0x0f;
3568                        }
3569                    }
3570                    break;
3571            }
3572        }
3573        if(pPause && pPause->NeedToPauseNow()) {
3574            m_loopIndex ++;
3575            m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3576            return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3577        }
3578    }
3579    m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3580    return FXCODEC_STATUS_DECODE_FINISH;
3581}
3582FXCODEC_STATUS CJBig2_GRDProc::Start_decode_Arith_V1(CJBig2_Image** pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3583{
3584    if(GBW == 0 || GBH == 0) {
3585        * pImage = NULL;
3586        m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3587        return FXCODEC_STATUS_DECODE_FINISH;
3588    }
3589    if(*pImage == NULL) {
3590        JBIG2_ALLOC((*pImage), CJBig2_Image(GBW, GBH));
3591    }
3592    if ((*pImage)->m_pData == NULL) {
3593        delete *pImage;
3594        *pImage = NULL;
3595        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
3596        m_ProssiveStatus = FXCODEC_STATUS_ERROR;
3597        return FXCODEC_STATUS_ERROR;
3598    }
3599    m_ProssiveStatus = FXCODEC_STATUS_DECODE_READY;
3600    m_pPause = pPause;
3601    m_pImage = pImage;
3602    m_DecodeType = 3;
3603    (*m_pImage)->fill(0);
3604    LTP = 0;
3605    m_loopIndex = 0;
3606    m_pArithDecoder = pArithDecoder;
3607    m_gbContext = gbContext;
3608    return decode_Arith_V1(pPause);
3609}
3610FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_V1(IFX_Pause* pPause)
3611{
3612    FX_BOOL SLTP, bVal;
3613    FX_DWORD CONTEXT = 0;
3614    CJBig2_Image *GBREG = (*m_pImage);
3615    for(; m_loopIndex < GBH; m_loopIndex++) {
3616        if(TPGDON) {
3617            switch(GBTEMPLATE) {
3618                case 0:
3619                    CONTEXT = 0x9b25;
3620                    break;
3621                case 1:
3622                    CONTEXT = 0x0795;
3623                    break;
3624                case 2:
3625                    CONTEXT = 0x00e5;
3626                    break;
3627                case 3:
3628                    CONTEXT = 0x0195;
3629                    break;
3630            }
3631            SLTP = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3632            LTP = LTP ^ SLTP;
3633        }
3634        if(LTP == 1) {
3635            for(FX_DWORD w = 0; w < GBW; w++) {
3636                GBREG->setPixel(w, m_loopIndex, GBREG->getPixel(w, m_loopIndex - 1));
3637            }
3638        } else {
3639            for(FX_DWORD w = 0; w < GBW; w++) {
3640                if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3641                    GBREG->setPixel(w, m_loopIndex, 0);
3642                } else {
3643                    CONTEXT = 0;
3644                    switch(GBTEMPLATE) {
3645                        case 0:
3646                            CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex);
3647                            CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex) << 1;
3648                            CONTEXT |= GBREG->getPixel(w - 3, m_loopIndex) << 2;
3649                            CONTEXT |= GBREG->getPixel(w - 4, m_loopIndex) << 3;
3650                            CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
3651                            CONTEXT |= GBREG->getPixel(w + 2, m_loopIndex - 1) << 5;
3652                            CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 1) << 6;
3653                            CONTEXT |= GBREG->getPixel(w, m_loopIndex - 1) << 7;
3654                            CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 1) << 8;
3655                            CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex - 1) << 9;
3656                            CONTEXT |= GBREG->getPixel(w + GBAT[2], m_loopIndex + GBAT[3]) << 10;
3657                            CONTEXT |= GBREG->getPixel(w + GBAT[4], m_loopIndex + GBAT[5]) << 11;
3658                            CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 2) << 12;
3659                            CONTEXT |= GBREG->getPixel(w, m_loopIndex - 2) << 13;
3660                            CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 2) << 14;
3661                            CONTEXT |= GBREG->getPixel(w + GBAT[6], m_loopIndex + GBAT[7]) << 15;
3662                            break;
3663                        case 1:
3664                            CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex);
3665                            CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex) << 1;
3666                            CONTEXT |= GBREG->getPixel(w - 3, m_loopIndex) << 2;
3667                            CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 3;
3668                            CONTEXT |= GBREG->getPixel(w + 2, m_loopIndex - 1) << 4;
3669                            CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 1) << 5;
3670                            CONTEXT |= GBREG->getPixel(w, m_loopIndex - 1) << 6;
3671                            CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 1) << 7;
3672                            CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex - 1) << 8;
3673                            CONTEXT |= GBREG->getPixel(w + 2, m_loopIndex - 2) << 9;
3674                            CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 2) << 10;
3675                            CONTEXT |= GBREG->getPixel(w, m_loopIndex - 2) << 11;
3676                            CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 2) << 12;
3677                            break;
3678                        case 2:
3679                            CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex);
3680                            CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex) << 1;
3681                            CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 2;
3682                            CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 1) << 3;
3683                            CONTEXT |= GBREG->getPixel(w, m_loopIndex - 1) << 4;
3684                            CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 1) << 5;
3685                            CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex - 1) << 6;
3686                            CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 2) << 7;
3687                            CONTEXT |= GBREG->getPixel(w, m_loopIndex - 2) << 8;
3688                            CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 2) << 9;
3689                            break;
3690                        case 3:
3691                            CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex);
3692                            CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex) << 1;
3693                            CONTEXT |= GBREG->getPixel(w - 3, m_loopIndex) << 2;
3694                            CONTEXT |= GBREG->getPixel(w - 4, m_loopIndex) << 3;
3695                            CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
3696                            CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 1) << 5;
3697                            CONTEXT |= GBREG->getPixel(w, m_loopIndex - 1) << 6;
3698                            CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 1) << 7;
3699                            CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex - 1) << 8;
3700                            CONTEXT |= GBREG->getPixel(w - 3, m_loopIndex - 1) << 9;
3701                            break;
3702                    }
3703                    bVal = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3704                    GBREG->setPixel(w, m_loopIndex, bVal);
3705                }
3706            }
3707        }
3708        if(pPause && pPause->NeedToPauseNow()) {
3709            m_loopIndex ++;
3710            m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3711            return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3712        }
3713    }
3714    m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3715    return FXCODEC_STATUS_DECODE_FINISH;
3716}
3717FXCODEC_STATUS CJBig2_GRDProc::Start_decode_MMR(CJBig2_Image** pImage, CJBig2_BitStream *pStream, IFX_Pause* pPause)
3718{
3719    int bitpos, i;
3720    JBIG2_ALLOC((* pImage), CJBig2_Image(GBW, GBH));
3721    if ((* pImage)->m_pData == NULL) {
3722        delete (* pImage);
3723        (* pImage) = NULL;
3724        m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
3725        m_ProssiveStatus = FXCODEC_STATUS_ERROR;
3726        return m_ProssiveStatus;
3727    }
3728    bitpos = (int)pStream->getBitPos();
3729    _FaxG4Decode(m_pModule, pStream->getBuf(), pStream->getLength(), &bitpos, (* pImage)->m_pData, GBW, GBH, (* pImage)->m_nStride);
3730    pStream->setBitPos(bitpos);
3731    for(i = 0; (FX_DWORD)i < (* pImage)->m_nStride * GBH; i++) {
3732        (* pImage)->m_pData[i] = ~(* pImage)->m_pData[i];
3733    }
3734    m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3735    return m_ProssiveStatus;
3736}
3737FXCODEC_STATUS CJBig2_GRDProc::decode_MMR()
3738{
3739    return m_ProssiveStatus;
3740}
3741FXCODEC_STATUS CJBig2_GRDProc::Continue_decode(IFX_Pause* pPause)
3742{
3743    if(m_ProssiveStatus != FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3744        return m_ProssiveStatus;
3745    }
3746    switch (m_DecodeType) {
3747        case 1:
3748            return decode_Arith(pPause);
3749        case 2:
3750            return decode_Arith_V2(pPause);
3751        case 3:
3752            return decode_Arith_V1(pPause);
3753        case 4:
3754            return decode_MMR();
3755    }
3756    m_ProssiveStatus = FXCODEC_STATUS_ERROR;
3757    return m_ProssiveStatus;
3758}
3759FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3(CJBig2_Image *pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3760{
3761    FX_BOOL SLTP, bVal;
3762    FX_DWORD CONTEXT;
3763    FX_DWORD line1, line2;
3764    FX_BYTE *pLine1, *pLine2, cVal;
3765    FX_INT32 nStride, nStride2, k;
3766    FX_INT32 nLineBytes, nBitsLeft, cc;
3767    if(m_pLine == NULL) {
3768        m_pLine = pImage->m_pData;
3769    }
3770    nStride = pImage->m_nStride;
3771    nStride2 = nStride << 1;
3772    nLineBytes = ((GBW + 7) >> 3) - 1;
3773    nBitsLeft = GBW - (nLineBytes << 3);
3774    FX_DWORD height = GBH & 0x7fffffff;
3775    for(; m_loopIndex < height; m_loopIndex++) {
3776        if(TPGDON) {
3777            SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
3778            LTP = LTP ^ SLTP;
3779        }
3780        if(LTP == 1) {
3781            pImage->copyLine(m_loopIndex, m_loopIndex - 1);
3782        } else {
3783            if(m_loopIndex > 1) {
3784                pLine1 = m_pLine - nStride2;
3785                pLine2 = m_pLine - nStride;
3786                line1 = (*pLine1++) << 6;
3787                line2 = *pLine2++;
3788                CONTEXT = ((line1 & 0xf800) | (line2 & 0x07f0));
3789                for(cc = 0; cc < nLineBytes; cc++) {
3790                    line1 = (line1 << 8) | ((*pLine1++) << 6);
3791                    line2 = (line2 << 8) | (*pLine2++);
3792                    cVal = 0;
3793                    for(k = 7; k >= 0; k--) {
3794                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3795                        cVal |= bVal << k;
3796                        CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
3797                                   | ((line1 >> k) & 0x0800)
3798                                   | ((line2 >> k) & 0x0010));
3799                    }
3800                    m_pLine[cc] = cVal;
3801                }
3802                line1 <<= 8;
3803                line2 <<= 8;
3804                cVal = 0;
3805                for(k = 0; k < nBitsLeft; k++) {
3806                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3807                    cVal |= bVal << (7 - k);
3808                    CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
3809                               | ((line1 >> (7 - k)) & 0x0800)
3810                               | ((line2 >> (7 - k)) & 0x0010));
3811                }
3812                m_pLine[nLineBytes] = cVal;
3813            } else {
3814                pLine2 = m_pLine - nStride;
3815                line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
3816                CONTEXT = (line2 & 0x07f0);
3817                for(cc = 0; cc < nLineBytes; cc++) {
3818                    if(m_loopIndex & 1) {
3819                        line2 = (line2 << 8) | (*pLine2++);
3820                    }
3821                    cVal = 0;
3822                    for(k = 7; k >= 0; k--) {
3823                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3824                        cVal |= bVal << k;
3825                        CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
3826                                   | ((line2 >> k) & 0x0010));
3827                    }
3828                    m_pLine[cc] = cVal;
3829                }
3830                line2 <<= 8;
3831                cVal = 0;
3832                for(k = 0; k < nBitsLeft; k++) {
3833                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3834                    cVal |= bVal << (7 - k);
3835                    CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
3836                               | ((line2 >> (7 - k)) & 0x0010));
3837                }
3838                m_pLine[nLineBytes] = cVal;
3839            }
3840        }
3841        m_pLine += nStride;
3842        if(pPause && pPause->NeedToPauseNow()) {
3843            m_loopIndex++;
3844            m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3845            return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3846        }
3847    }
3848    m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3849    return FXCODEC_STATUS_DECODE_FINISH;
3850}
3851FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_unopt(CJBig2_Image * pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3852{
3853    FX_BOOL SLTP, bVal;
3854    FX_DWORD CONTEXT;
3855    FX_DWORD line1, line2, line3;
3856    for(; m_loopIndex < GBH; m_loopIndex++) {
3857        if(TPGDON) {
3858            SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
3859            LTP = LTP ^ SLTP;
3860        }
3861        if(LTP == 1) {
3862            pImage->copyLine(m_loopIndex, m_loopIndex - 1);
3863        } else {
3864            line1 = pImage->getPixel(1, m_loopIndex - 2);
3865            line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
3866            line2 = pImage->getPixel(2, m_loopIndex - 1);
3867            line2 |= pImage->getPixel(1, m_loopIndex - 1) << 1;
3868            line2 |= pImage->getPixel(0, m_loopIndex - 1) << 2;
3869            line3 = 0;
3870            for(FX_DWORD w = 0; w < GBW; w++) {
3871                if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3872                    bVal = 0;
3873                } else {
3874                    CONTEXT = line3;
3875                    CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
3876                    CONTEXT |= line2 << 5;
3877                    CONTEXT |= pImage->getPixel(w + GBAT[2], m_loopIndex + GBAT[3]) << 10;
3878                    CONTEXT |= pImage->getPixel(w + GBAT[4], m_loopIndex + GBAT[5]) << 11;
3879                    CONTEXT |= line1 << 12;
3880                    CONTEXT |= pImage->getPixel(w + GBAT[6], m_loopIndex + GBAT[7]) << 15;
3881                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3882                }
3883                if(bVal) {
3884                    pImage->setPixel(w, m_loopIndex, bVal);
3885                }
3886                line1 = ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
3887                line2 = ((line2 << 1) | pImage->getPixel(w + 3, m_loopIndex - 1)) & 0x1f;
3888                line3 = ((line3 << 1) | bVal) & 0x0f;
3889            }
3890        }
3891        if(pPause && pPause->NeedToPauseNow()) {
3892            m_loopIndex++;
3893            m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3894            return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3895        }
3896    }
3897    m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3898    return FXCODEC_STATUS_DECODE_FINISH;
3899}
3900FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3(CJBig2_Image *pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3901{
3902    FX_BOOL SLTP, bVal;
3903    FX_DWORD CONTEXT;
3904    FX_DWORD line1, line2;
3905    FX_BYTE *pLine1, *pLine2, cVal;
3906    FX_INT32 nStride, nStride2, k;
3907    FX_INT32 nLineBytes, nBitsLeft, cc;
3908    if (!m_pLine) {
3909        m_pLine = pImage->m_pData;
3910    }
3911    nStride = pImage->m_nStride;
3912    nStride2 = nStride << 1;
3913    nLineBytes = ((GBW + 7) >> 3) - 1;
3914    nBitsLeft = GBW - (nLineBytes << 3);
3915    for(; m_loopIndex < GBH; m_loopIndex++) {
3916        if(TPGDON) {
3917            SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
3918            LTP = LTP ^ SLTP;
3919        }
3920        if(LTP == 1) {
3921            pImage->copyLine(m_loopIndex, m_loopIndex - 1);
3922        } else {
3923            if(m_loopIndex > 1) {
3924                pLine1 = m_pLine - nStride2;
3925                pLine2 = m_pLine - nStride;
3926                line1 = (*pLine1++) << 4;
3927                line2 = *pLine2++;
3928                CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
3929                for(cc = 0; cc < nLineBytes; cc++) {
3930                    line1 = (line1 << 8) | ((*pLine1++) << 4);
3931                    line2 = (line2 << 8) | (*pLine2++);
3932                    cVal = 0;
3933                    for(k = 7; k >= 0; k--) {
3934                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3935                        cVal |= bVal << k;
3936                        CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
3937                                  | ((line1 >> k) & 0x0200)
3938                                  | ((line2 >> (k + 1)) & 0x0008);
3939                    }
3940                    m_pLine[cc] = cVal;
3941                }
3942                line1 <<= 8;
3943                line2 <<= 8;
3944                cVal = 0;
3945                for(k = 0; k < nBitsLeft; k++) {
3946                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3947                    cVal |= bVal << (7 - k);
3948                    CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
3949                              | ((line1 >> (7 - k)) & 0x0200)
3950                              | ((line2 >> (8 - k)) & 0x0008);
3951                }
3952                m_pLine[nLineBytes] = cVal;
3953            } else {
3954                pLine2 = m_pLine - nStride;
3955                line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
3956                CONTEXT = (line2 >> 1) & 0x01f8;
3957                for(cc = 0; cc < nLineBytes; cc++) {
3958                    if(m_loopIndex & 1) {
3959                        line2 = (line2 << 8) | (*pLine2++);
3960                    }
3961                    cVal = 0;
3962                    for(k = 7; k >= 0; k--) {
3963                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3964                        cVal |= bVal << k;
3965                        CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
3966                                  | ((line2 >> (k + 1)) & 0x0008);
3967                    }
3968                    m_pLine[cc] = cVal;
3969                }
3970                line2 <<= 8;
3971                cVal = 0;
3972                for(k = 0; k < nBitsLeft; k++) {
3973                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3974                    cVal |= bVal << (7 - k);
3975                    CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
3976                              | ((line2 >> (8 - k)) & 0x0008);
3977                }
3978                m_pLine[nLineBytes] = cVal;
3979            }
3980        }
3981        m_pLine += nStride;
3982        if(pPause && pPause->NeedToPauseNow()) {
3983            m_loopIndex++;
3984            m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3985            return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3986        }
3987    }
3988    m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3989    return FXCODEC_STATUS_DECODE_FINISH;
3990}
3991FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_unopt(CJBig2_Image * pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3992{
3993    FX_BOOL SLTP, bVal;
3994    FX_DWORD CONTEXT;
3995    FX_DWORD line1, line2, line3;
3996    for(FX_DWORD h = 0; h < GBH; h++) {
3997        if(TPGDON) {
3998            SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
3999            LTP = LTP ^ SLTP;
4000        }
4001        if(LTP == 1) {
4002            pImage->copyLine(h, h - 1);
4003        } else {
4004            line1 = pImage->getPixel(2, h - 2);
4005            line1 |= pImage->getPixel(1, h - 2) << 1;
4006            line1 |= pImage->getPixel(0, h - 2) << 2;
4007            line2 = pImage->getPixel(2, h - 1);
4008            line2 |= pImage->getPixel(1, h - 1) << 1;
4009            line2 |= pImage->getPixel(0, h - 1) << 2;
4010            line3 = 0;
4011            for(FX_DWORD w = 0; w < GBW; w++) {
4012                if(USESKIP && SKIP->getPixel(w, h)) {
4013                    bVal = 0;
4014                } else {
4015                    CONTEXT = line3;
4016                    CONTEXT |= pImage->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
4017                    CONTEXT |= line2 << 4;
4018                    CONTEXT |= line1 << 9;
4019                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4020                }
4021                if(bVal) {
4022                    pImage->setPixel(w, h, bVal);
4023                }
4024                line1 = ((line1 << 1) | pImage->getPixel(w + 3, h - 2)) & 0x0f;
4025                line2 = ((line2 << 1) | pImage->getPixel(w + 3, h - 1)) & 0x1f;
4026                line3 = ((line3 << 1) | bVal) & 0x07;
4027            }
4028        }
4029        if(pPause && pPause->NeedToPauseNow()) {
4030            m_loopIndex++;
4031            m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
4032            return FXCODEC_STATUS_DECODE_TOBECONTINUE;
4033        }
4034    }
4035    m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
4036    return FXCODEC_STATUS_DECODE_FINISH;
4037}
4038FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3(CJBig2_Image *pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
4039{
4040    FX_BOOL SLTP, bVal;
4041    FX_DWORD CONTEXT;
4042    FX_DWORD line1, line2;
4043    FX_BYTE *pLine1, *pLine2, cVal;
4044    FX_INT32 nStride, nStride2, k;
4045    FX_INT32 nLineBytes, nBitsLeft, cc;
4046    if(!m_pLine) {
4047        m_pLine = pImage->m_pData;
4048    }
4049    nStride = pImage->m_nStride;
4050    nStride2 = nStride << 1;
4051    nLineBytes = ((GBW + 7) >> 3) - 1;
4052    nBitsLeft = GBW - (nLineBytes << 3);
4053    for(; m_loopIndex < GBH; m_loopIndex++) {
4054        if(TPGDON) {
4055            SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
4056            LTP = LTP ^ SLTP;
4057        }
4058        if(LTP == 1) {
4059            pImage->copyLine(m_loopIndex, m_loopIndex - 1);
4060        } else {
4061            if(m_loopIndex > 1) {
4062                pLine1 = m_pLine - nStride2;
4063                pLine2 = m_pLine - nStride;
4064                line1 = (*pLine1++) << 1;
4065                line2 = *pLine2++;
4066                CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
4067                for(cc = 0; cc < nLineBytes; cc++) {
4068                    line1 = (line1 << 8) | ((*pLine1++) << 1);
4069                    line2 = (line2 << 8) | (*pLine2++);
4070                    cVal = 0;
4071                    for(k = 7; k >= 0; k--) {
4072                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4073                        cVal |= bVal << k;
4074                        CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
4075                                  | ((line1 >> k) & 0x0080)
4076                                  | ((line2 >> (k + 3)) & 0x0004);
4077                    }
4078                    m_pLine[cc] = cVal;
4079                }
4080                line1 <<= 8;
4081                line2 <<= 8;
4082                cVal = 0;
4083                for(k = 0; k < nBitsLeft; k++) {
4084                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4085                    cVal |= bVal << (7 - k);
4086                    CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
4087                              | ((line1 >> (7 - k)) & 0x0080)
4088                              | ((line2 >> (10 - k)) & 0x0004);
4089                }
4090                m_pLine[nLineBytes] = cVal;
4091            } else {
4092                pLine2 = m_pLine - nStride;
4093                line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
4094                CONTEXT = (line2 >> 3) & 0x007c;
4095                for(cc = 0; cc < nLineBytes; cc++) {
4096                    if(m_loopIndex & 1) {
4097                        line2 = (line2 << 8) | (*pLine2++);
4098                    }
4099                    cVal = 0;
4100                    for(k = 7; k >= 0; k--) {
4101                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4102                        cVal |= bVal << k;
4103                        CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
4104                                  | ((line2 >> (k + 3)) & 0x0004);
4105                    }
4106                    m_pLine[cc] = cVal;
4107                }
4108                line2 <<= 8;
4109                cVal = 0;
4110                for(k = 0; k < nBitsLeft; k++) {
4111                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4112                    cVal |= bVal << (7 - k);
4113                    CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
4114                              | (((line2 >> (10 - k))) & 0x0004);
4115                }
4116                m_pLine[nLineBytes] = cVal;
4117            }
4118        }
4119        m_pLine += nStride;
4120        if(pPause && m_loopIndex % 50 == 0 && pPause->NeedToPauseNow()) {
4121            m_loopIndex++;
4122            m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
4123            return FXCODEC_STATUS_DECODE_TOBECONTINUE;
4124        }
4125    }
4126    m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
4127    return FXCODEC_STATUS_DECODE_FINISH;
4128}
4129FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_unopt(CJBig2_Image * pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
4130{
4131    FX_BOOL SLTP, bVal;
4132    FX_DWORD CONTEXT;
4133    FX_DWORD line1, line2, line3;
4134    for(; m_loopIndex < GBH; m_loopIndex++) {
4135        if(TPGDON) {
4136            SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
4137            LTP = LTP ^ SLTP;
4138        }
4139        if(LTP == 1) {
4140            pImage->copyLine(m_loopIndex, m_loopIndex - 1);
4141        } else {
4142            line1 = pImage->getPixel(1, m_loopIndex - 2);
4143            line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
4144            line2 = pImage->getPixel(1, m_loopIndex - 1);
4145            line2 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
4146            line3 = 0;
4147            for(FX_DWORD w = 0; w < GBW; w++) {
4148                if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
4149                    bVal = 0;
4150                } else {
4151                    CONTEXT = line3;
4152                    CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 2;
4153                    CONTEXT |= line2 << 3;
4154                    CONTEXT |= line1 << 7;
4155                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4156                }
4157                if(bVal) {
4158                    pImage->setPixel(w, m_loopIndex, bVal);
4159                }
4160                line1 = ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
4161                line2 = ((line2 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x0f;
4162                line3 = ((line3 << 1) | bVal) & 0x03;
4163            }
4164        }
4165        if(pPause && pPause->NeedToPauseNow()) {
4166            m_loopIndex++;
4167            m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
4168            return FXCODEC_STATUS_DECODE_TOBECONTINUE;
4169        }
4170    }
4171    m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
4172    return FXCODEC_STATUS_DECODE_FINISH;
4173}
4174FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3(CJBig2_Image *pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
4175{
4176    FX_BOOL SLTP, bVal;
4177    FX_DWORD CONTEXT;
4178    FX_DWORD line1;
4179    FX_BYTE *pLine1, cVal;
4180    FX_INT32 nStride, k;
4181    FX_INT32 nLineBytes, nBitsLeft, cc;
4182    if (!m_pLine) {
4183        m_pLine = pImage->m_pData;
4184    }
4185    nStride = pImage->m_nStride;
4186    nLineBytes = ((GBW + 7) >> 3) - 1;
4187    nBitsLeft = GBW - (nLineBytes << 3);
4188    for(; m_loopIndex < GBH; m_loopIndex++) {
4189        if(TPGDON) {
4190            SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
4191            LTP = LTP ^ SLTP;
4192        }
4193        if(LTP == 1) {
4194            pImage->copyLine(m_loopIndex, m_loopIndex - 1);
4195        } else {
4196            if(m_loopIndex > 0) {
4197                pLine1 = m_pLine - nStride;
4198                line1 = *pLine1++;
4199                CONTEXT = (line1 >> 1) & 0x03f0;
4200                for(cc = 0; cc < nLineBytes; cc++) {
4201                    line1 = (line1 << 8) | (*pLine1++);
4202                    cVal = 0;
4203                    for(k = 7; k >= 0; k--) {
4204                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4205                        cVal |= bVal << k;
4206                        CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
4207                                  | ((line1 >> (k + 1)) & 0x0010);
4208                    }
4209                    m_pLine[cc] = cVal;
4210                }
4211                line1 <<= 8;
4212                cVal = 0;
4213                for(k = 0; k < nBitsLeft; k++) {
4214                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4215                    cVal |= bVal << (7 - k);
4216                    CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
4217                              | ((line1 >> (8 - k)) & 0x0010);
4218                }
4219                m_pLine[nLineBytes] = cVal;
4220            } else {
4221                CONTEXT = 0;
4222                for(cc = 0; cc < nLineBytes; cc++) {
4223                    cVal = 0;
4224                    for(k = 7; k >= 0; k--) {
4225                        bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4226                        cVal |= bVal << k;
4227                        CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
4228                    }
4229                    m_pLine[cc] = cVal;
4230                }
4231                cVal = 0;
4232                for(k = 0; k < nBitsLeft; k++) {
4233                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4234                    cVal |= bVal << (7 - k);
4235                    CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
4236                }
4237                m_pLine[nLineBytes] = cVal;
4238            }
4239        }
4240        m_pLine += nStride;
4241        if(pPause && pPause->NeedToPauseNow()) {
4242            m_loopIndex++;
4243            m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
4244            return FXCODEC_STATUS_DECODE_TOBECONTINUE;
4245        }
4246    }
4247    m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
4248    return FXCODEC_STATUS_DECODE_FINISH;
4249}
4250FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_unopt(CJBig2_Image * pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
4251{
4252    FX_BOOL SLTP, bVal;
4253    FX_DWORD CONTEXT;
4254    FX_DWORD line1, line2;
4255    for(; m_loopIndex < GBH; m_loopIndex++) {
4256        if(TPGDON) {
4257            SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
4258            LTP = LTP ^ SLTP;
4259        }
4260        if(LTP == 1) {
4261            pImage->copyLine(m_loopIndex, m_loopIndex - 1);
4262        } else {
4263            line1 = pImage->getPixel(1, m_loopIndex - 1);
4264            line1 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
4265            line2 = 0;
4266            for(FX_DWORD w = 0; w < GBW; w++) {
4267                if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
4268                    bVal = 0;
4269                } else {
4270                    CONTEXT = line2;
4271                    CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
4272                    CONTEXT |= line1 << 5;
4273                    bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4274                }
4275                if(bVal) {
4276                    pImage->setPixel(w, m_loopIndex, bVal);
4277                }
4278                line1 = ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x1f;
4279                line2 = ((line2 << 1) | bVal) & 0x0f;
4280            }
4281        }
4282        if(pPause && pPause->NeedToPauseNow()) {
4283            m_loopIndex++;
4284            m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
4285            return FXCODEC_STATUS_DECODE_TOBECONTINUE;
4286        }
4287    }
4288    m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
4289    return FXCODEC_STATUS_DECODE_FINISH;
4290}
4291