Home | History | Annotate | Download | only in jbig2
      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 
     14 extern 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 
     64 extern const unsigned int JBIG2_QE_NUM = sizeof(QeTable) / sizeof(JBig2ArithQe);
     65 
     66 CJBig2_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 }
    102 CJBig2_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 }
    147 CJBig2_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 }
    214 CJBig2_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 }
    306 CJBig2_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 }
    353 CJBig2_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 }
    398 CJBig2_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 }
    465 CJBig2_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 }
    556 CJBig2_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 }
    601 CJBig2_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 }
    644 CJBig2_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 }
    711 CJBig2_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 }
    802 CJBig2_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 }
    845 CJBig2_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 }
    884 CJBig2_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 }
    942 CJBig2_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 }
   1018 CJBig2_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 }
   1057 CJBig2_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 }
   1196 CJBig2_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 }
   1300 CJBig2_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 }
   1318 CJBig2_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 }
   1341 CJBig2_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 }
   1425 CJBig2_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 }
   1556 CJBig2_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 }
   1634 CJBig2_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 }
   1759 CJBig2_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 }
   1873 CJBig2_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;
   2087 failed:
   2088     delete pHuffmanDecoder;
   2089     delete SBREG;
   2090     return NULL;
   2091 }
   2092 CJBig2_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;
   2315 failed:
   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 }
   2331 CJBig2_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;
   2644 failed:
   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 }
   2668 CJBig2_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;
   3028 failed:
   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 }
   3041 CJBig2_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;
   3102 failed:
   3103     if(HSKIP) {
   3104         delete HSKIP;
   3105     }
   3106     delete pGID;
   3107     delete HTREG;
   3108     return NULL;
   3109 }
   3110 CJBig2_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;
   3148 failed:
   3149     delete pGID;
   3150     delete HTREG;
   3151     return NULL;
   3152 }
   3153 CJBig2_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;
   3197 failed:
   3198     delete pDict;
   3199     return NULL;
   3200 }
   3201 
   3202 CJBig2_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;
   3232 failed:
   3233     delete pDict;
   3234     return NULL;
   3235 }
   3236 FX_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;
   3312 failed:
   3313     m_pModule->JBig2_Free(GSPLANES);
   3314     delete pGRD;
   3315     m_pModule->JBig2_Free(GSVALS);
   3316     return NULL;
   3317 }
   3318 FX_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;
   3381 failed:
   3382     m_pModule->JBig2_Free(GSPLANES);
   3383     delete pGRD;
   3384     m_pModule->JBig2_Free(GSVALS);
   3385     return NULL;
   3386 }
   3387 FXCODEC_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 }
   3415 FXCODEC_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 }
   3456 FXCODEC_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 }
   3484 FXCODEC_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 }
   3629 FXCODEC_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 }
   3657 FXCODEC_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 }
   3764 FXCODEC_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 }
   3784 FXCODEC_STATUS CJBig2_GRDProc::decode_MMR()
   3785 {
   3786     return m_ProssiveStatus;
   3787 }
   3788 FXCODEC_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 }
   3806 FXCODEC_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 }
   3898 FXCODEC_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 }
   3947 FXCODEC_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 }
   4038 FXCODEC_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 }
   4085 FXCODEC_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 }
   4176 FXCODEC_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 }
   4221 FXCODEC_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 }
   4297 FXCODEC_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