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