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