Home | History | Annotate | Download | only in jbig2
      1 // Copyright 2015 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_GrdProc.h"
      8 
      9 #include <memory>
     10 
     11 #include "JBig2_ArithDecoder.h"
     12 #include "JBig2_BitStream.h"
     13 #include "JBig2_Image.h"
     14 #include "core/include/fxcodec/fx_codec.h"
     15 
     16 CJBig2_GRDProc::CJBig2_GRDProc()
     17     : m_loopIndex(0),
     18       m_pLine(nullptr),
     19       m_pPause(nullptr),
     20       m_DecodeType(0),
     21       LTP(0) {
     22   m_ReplaceRect.left = 0;
     23   m_ReplaceRect.bottom = 0;
     24   m_ReplaceRect.top = 0;
     25   m_ReplaceRect.right = 0;
     26 }
     27 
     28 bool CJBig2_GRDProc::UseTemplate0Opt3() const {
     29   return (GBAT[0] == 3) && (GBAT[1] == -1) && (GBAT[2] == -3) &&
     30          (GBAT[3] == -1) && (GBAT[4] == 2) && (GBAT[5] == -2) &&
     31          (GBAT[6] == -2) && (GBAT[7] == -2);
     32 }
     33 
     34 bool CJBig2_GRDProc::UseTemplate1Opt3() const {
     35   return (GBAT[0] == 3) && (GBAT[1] == -1);
     36 }
     37 
     38 bool CJBig2_GRDProc::UseTemplate23Opt3() const {
     39   return (GBAT[0] == 2) && (GBAT[1] == -1);
     40 }
     41 
     42 CJBig2_Image* CJBig2_GRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
     43                                            JBig2ArithCtx* gbContext) {
     44   if (GBW == 0 || GBH == 0)
     45     return new CJBig2_Image(GBW, GBH);
     46 
     47   if (GBTEMPLATE == 0) {
     48     if (UseTemplate0Opt3())
     49       return decode_Arith_Template0_opt3(pArithDecoder, gbContext);
     50     return decode_Arith_Template0_unopt(pArithDecoder, gbContext);
     51   } else if (GBTEMPLATE == 1) {
     52     if (UseTemplate1Opt3())
     53       return decode_Arith_Template1_opt3(pArithDecoder, gbContext);
     54     return decode_Arith_Template1_unopt(pArithDecoder, gbContext);
     55   } else if (GBTEMPLATE == 2) {
     56     if (UseTemplate23Opt3())
     57       return decode_Arith_Template2_opt3(pArithDecoder, gbContext);
     58     return decode_Arith_Template2_unopt(pArithDecoder, gbContext);
     59   } else {
     60     if (UseTemplate23Opt3())
     61       return decode_Arith_Template3_opt3(pArithDecoder, gbContext);
     62     return decode_Arith_Template3_unopt(pArithDecoder, gbContext);
     63   }
     64 }
     65 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3(
     66     CJBig2_ArithDecoder* pArithDecoder,
     67     JBig2ArithCtx* gbContext) {
     68   FX_BOOL LTP, SLTP, bVal;
     69   FX_DWORD CONTEXT;
     70   FX_DWORD line1, line2;
     71   uint8_t* pLine, *pLine1, *pLine2, cVal;
     72   int32_t nStride, nStride2, k;
     73   int32_t nLineBytes, nBitsLeft, cc;
     74   LTP = 0;
     75   std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
     76   if (!GBREG->m_pData)
     77     return nullptr;
     78 
     79   pLine = GBREG->m_pData;
     80   nStride = GBREG->m_nStride;
     81   nStride2 = nStride << 1;
     82   nLineBytes = ((GBW + 7) >> 3) - 1;
     83   nBitsLeft = GBW - (nLineBytes << 3);
     84   FX_DWORD height = GBH & 0x7fffffff;
     85   for (FX_DWORD h = 0; h < height; h++) {
     86     if (TPGDON) {
     87       SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
     88       LTP = LTP ^ SLTP;
     89     }
     90     if (LTP == 1) {
     91       GBREG->copyLine(h, h - 1);
     92     } else {
     93       if (h > 1) {
     94         pLine1 = pLine - nStride2;
     95         pLine2 = pLine - nStride;
     96         line1 = (*pLine1++) << 6;
     97         line2 = *pLine2++;
     98         CONTEXT = ((line1 & 0xf800) | (line2 & 0x07f0));
     99         for (cc = 0; cc < nLineBytes; cc++) {
    100           line1 = (line1 << 8) | ((*pLine1++) << 6);
    101           line2 = (line2 << 8) | (*pLine2++);
    102           cVal = 0;
    103           for (k = 7; k >= 0; k--) {
    104             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    105             cVal |= bVal << k;
    106             CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
    107                        ((line1 >> k) & 0x0800) | ((line2 >> k) & 0x0010));
    108           }
    109           pLine[cc] = cVal;
    110         }
    111         line1 <<= 8;
    112         line2 <<= 8;
    113         cVal = 0;
    114         for (k = 0; k < nBitsLeft; k++) {
    115           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    116           cVal |= bVal << (7 - k);
    117           CONTEXT =
    118               (((CONTEXT & 0x7bf7) << 1) | bVal |
    119                ((line1 >> (7 - k)) & 0x0800) | ((line2 >> (7 - k)) & 0x0010));
    120         }
    121         pLine[nLineBytes] = cVal;
    122       } else {
    123         pLine2 = pLine - nStride;
    124         line2 = (h & 1) ? (*pLine2++) : 0;
    125         CONTEXT = (line2 & 0x07f0);
    126         for (cc = 0; cc < nLineBytes; cc++) {
    127           if (h & 1) {
    128             line2 = (line2 << 8) | (*pLine2++);
    129           }
    130           cVal = 0;
    131           for (k = 7; k >= 0; k--) {
    132             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    133             cVal |= bVal << k;
    134             CONTEXT =
    135                 (((CONTEXT & 0x7bf7) << 1) | bVal | ((line2 >> k) & 0x0010));
    136           }
    137           pLine[cc] = cVal;
    138         }
    139         line2 <<= 8;
    140         cVal = 0;
    141         for (k = 0; k < nBitsLeft; k++) {
    142           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    143           cVal |= bVal << (7 - k);
    144           CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
    145                      (((line2 >> (7 - k))) & 0x0010));
    146         }
    147         pLine[nLineBytes] = cVal;
    148       }
    149     }
    150     pLine += nStride;
    151   }
    152   return GBREG.release();
    153 }
    154 
    155 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_unopt(
    156     CJBig2_ArithDecoder* pArithDecoder,
    157     JBig2ArithCtx* gbContext) {
    158   FX_BOOL LTP, SLTP, bVal;
    159   FX_DWORD CONTEXT;
    160   FX_DWORD line1, line2, line3;
    161   LTP = 0;
    162   std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
    163   GBREG->fill(0);
    164   for (FX_DWORD h = 0; h < GBH; h++) {
    165     if (TPGDON) {
    166       SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
    167       LTP = LTP ^ SLTP;
    168     }
    169     if (LTP == 1) {
    170       GBREG->copyLine(h, h - 1);
    171     } else {
    172       line1 = GBREG->getPixel(1, h - 2);
    173       line1 |= GBREG->getPixel(0, h - 2) << 1;
    174       line2 = GBREG->getPixel(2, h - 1);
    175       line2 |= GBREG->getPixel(1, h - 1) << 1;
    176       line2 |= GBREG->getPixel(0, h - 1) << 2;
    177       line3 = 0;
    178       for (FX_DWORD w = 0; w < GBW; w++) {
    179         if (USESKIP && SKIP->getPixel(w, h)) {
    180           bVal = 0;
    181         } else {
    182           CONTEXT = line3;
    183           CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
    184           CONTEXT |= line2 << 5;
    185           CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
    186           CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
    187           CONTEXT |= line1 << 12;
    188           CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
    189           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    190         }
    191         if (bVal) {
    192           GBREG->setPixel(w, h, bVal);
    193         }
    194         line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
    195         line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
    196         line3 = ((line3 << 1) | bVal) & 0x0f;
    197       }
    198     }
    199   }
    200   return GBREG.release();
    201 }
    202 
    203 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_opt3(
    204     CJBig2_ArithDecoder* pArithDecoder,
    205     JBig2ArithCtx* gbContext) {
    206   FX_BOOL LTP, SLTP, bVal;
    207   FX_DWORD CONTEXT;
    208   FX_DWORD line1, line2;
    209   uint8_t* pLine, *pLine1, *pLine2, cVal;
    210   int32_t nStride, nStride2, k;
    211   int32_t nLineBytes, nBitsLeft, cc;
    212   LTP = 0;
    213   std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
    214   if (!GBREG->m_pData)
    215     return nullptr;
    216 
    217   pLine = GBREG->m_pData;
    218   nStride = GBREG->m_nStride;
    219   nStride2 = nStride << 1;
    220   nLineBytes = ((GBW + 7) >> 3) - 1;
    221   nBitsLeft = GBW - (nLineBytes << 3);
    222   for (FX_DWORD h = 0; h < GBH; h++) {
    223     if (TPGDON) {
    224       SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
    225       LTP = LTP ^ SLTP;
    226     }
    227     if (LTP == 1) {
    228       GBREG->copyLine(h, h - 1);
    229     } else {
    230       if (h > 1) {
    231         pLine1 = pLine - nStride2;
    232         pLine2 = pLine - nStride;
    233         line1 = (*pLine1++) << 4;
    234         line2 = *pLine2++;
    235         CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
    236         for (cc = 0; cc < nLineBytes; cc++) {
    237           line1 = (line1 << 8) | ((*pLine1++) << 4);
    238           line2 = (line2 << 8) | (*pLine2++);
    239           cVal = 0;
    240           for (k = 7; k >= 0; k--) {
    241             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    242             cVal |= bVal << k;
    243             CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
    244                       ((line1 >> k) & 0x0200) | ((line2 >> (k + 1)) & 0x0008);
    245           }
    246           pLine[cc] = cVal;
    247         }
    248         line1 <<= 8;
    249         line2 <<= 8;
    250         cVal = 0;
    251         for (k = 0; k < nBitsLeft; k++) {
    252           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    253           cVal |= bVal << (7 - k);
    254           CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
    255                     ((line1 >> (7 - k)) & 0x0200) |
    256                     ((line2 >> (8 - k)) & 0x0008);
    257         }
    258         pLine[nLineBytes] = cVal;
    259       } else {
    260         pLine2 = pLine - nStride;
    261         line2 = (h & 1) ? (*pLine2++) : 0;
    262         CONTEXT = (line2 >> 1) & 0x01f8;
    263         for (cc = 0; cc < nLineBytes; cc++) {
    264           if (h & 1) {
    265             line2 = (line2 << 8) | (*pLine2++);
    266           }
    267           cVal = 0;
    268           for (k = 7; k >= 0; k--) {
    269             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    270             cVal |= bVal << k;
    271             CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
    272                       ((line2 >> (k + 1)) & 0x0008);
    273           }
    274           pLine[cc] = cVal;
    275         }
    276         line2 <<= 8;
    277         cVal = 0;
    278         for (k = 0; k < nBitsLeft; k++) {
    279           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    280           cVal |= bVal << (7 - k);
    281           CONTEXT =
    282               ((CONTEXT & 0x0efb) << 1) | bVal | ((line2 >> (8 - k)) & 0x0008);
    283         }
    284         pLine[nLineBytes] = cVal;
    285       }
    286     }
    287     pLine += nStride;
    288   }
    289   return GBREG.release();
    290 }
    291 
    292 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_unopt(
    293     CJBig2_ArithDecoder* pArithDecoder,
    294     JBig2ArithCtx* gbContext) {
    295   FX_BOOL LTP, SLTP, bVal;
    296   FX_DWORD CONTEXT;
    297   FX_DWORD line1, line2, line3;
    298   LTP = 0;
    299   std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
    300   GBREG->fill(0);
    301   for (FX_DWORD h = 0; h < GBH; h++) {
    302     if (TPGDON) {
    303       SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
    304       LTP = LTP ^ SLTP;
    305     }
    306     if (LTP == 1) {
    307       GBREG->copyLine(h, h - 1);
    308     } else {
    309       line1 = GBREG->getPixel(2, h - 2);
    310       line1 |= GBREG->getPixel(1, h - 2) << 1;
    311       line1 |= GBREG->getPixel(0, h - 2) << 2;
    312       line2 = GBREG->getPixel(2, h - 1);
    313       line2 |= GBREG->getPixel(1, h - 1) << 1;
    314       line2 |= GBREG->getPixel(0, h - 1) << 2;
    315       line3 = 0;
    316       for (FX_DWORD w = 0; w < GBW; w++) {
    317         if (USESKIP && SKIP->getPixel(w, h)) {
    318           bVal = 0;
    319         } else {
    320           CONTEXT = line3;
    321           CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
    322           CONTEXT |= line2 << 4;
    323           CONTEXT |= line1 << 9;
    324           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    325         }
    326         if (bVal) {
    327           GBREG->setPixel(w, h, bVal);
    328         }
    329         line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
    330         line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
    331         line3 = ((line3 << 1) | bVal) & 0x07;
    332       }
    333     }
    334   }
    335   return GBREG.release();
    336 }
    337 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_opt3(
    338     CJBig2_ArithDecoder* pArithDecoder,
    339     JBig2ArithCtx* gbContext) {
    340   FX_BOOL LTP, SLTP, bVal;
    341   FX_DWORD CONTEXT;
    342   FX_DWORD line1, line2;
    343   uint8_t* pLine, *pLine1, *pLine2, cVal;
    344   int32_t nStride, nStride2, k;
    345   int32_t nLineBytes, nBitsLeft, cc;
    346   LTP = 0;
    347   std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
    348   if (!GBREG->m_pData)
    349     return nullptr;
    350 
    351   pLine = GBREG->m_pData;
    352   nStride = GBREG->m_nStride;
    353   nStride2 = nStride << 1;
    354   nLineBytes = ((GBW + 7) >> 3) - 1;
    355   nBitsLeft = GBW - (nLineBytes << 3);
    356   for (FX_DWORD h = 0; h < GBH; h++) {
    357     if (TPGDON) {
    358       SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
    359       LTP = LTP ^ SLTP;
    360     }
    361     if (LTP == 1) {
    362       GBREG->copyLine(h, h - 1);
    363     } else {
    364       if (h > 1) {
    365         pLine1 = pLine - nStride2;
    366         pLine2 = pLine - nStride;
    367         line1 = (*pLine1++) << 1;
    368         line2 = *pLine2++;
    369         CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
    370         for (cc = 0; cc < nLineBytes; cc++) {
    371           line1 = (line1 << 8) | ((*pLine1++) << 1);
    372           line2 = (line2 << 8) | (*pLine2++);
    373           cVal = 0;
    374           for (k = 7; k >= 0; k--) {
    375             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    376             cVal |= bVal << k;
    377             CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
    378                       ((line1 >> k) & 0x0080) | ((line2 >> (k + 3)) & 0x0004);
    379           }
    380           pLine[cc] = cVal;
    381         }
    382         line1 <<= 8;
    383         line2 <<= 8;
    384         cVal = 0;
    385         for (k = 0; k < nBitsLeft; k++) {
    386           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    387           cVal |= bVal << (7 - k);
    388           CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
    389                     ((line1 >> (7 - k)) & 0x0080) |
    390                     ((line2 >> (10 - k)) & 0x0004);
    391         }
    392         pLine[nLineBytes] = cVal;
    393       } else {
    394         pLine2 = pLine - nStride;
    395         line2 = (h & 1) ? (*pLine2++) : 0;
    396         CONTEXT = (line2 >> 3) & 0x007c;
    397         for (cc = 0; cc < nLineBytes; cc++) {
    398           if (h & 1) {
    399             line2 = (line2 << 8) | (*pLine2++);
    400           }
    401           cVal = 0;
    402           for (k = 7; k >= 0; k--) {
    403             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    404             cVal |= bVal << k;
    405             CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
    406                       ((line2 >> (k + 3)) & 0x0004);
    407           }
    408           pLine[cc] = cVal;
    409         }
    410         line2 <<= 8;
    411         cVal = 0;
    412         for (k = 0; k < nBitsLeft; k++) {
    413           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    414           cVal |= bVal << (7 - k);
    415           CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
    416                     (((line2 >> (10 - k))) & 0x0004);
    417         }
    418         pLine[nLineBytes] = cVal;
    419       }
    420     }
    421     pLine += nStride;
    422   }
    423   return GBREG.release();
    424 }
    425 
    426 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_unopt(
    427     CJBig2_ArithDecoder* pArithDecoder,
    428     JBig2ArithCtx* gbContext) {
    429   FX_BOOL LTP, SLTP, bVal;
    430   FX_DWORD CONTEXT;
    431   FX_DWORD line1, line2, line3;
    432   LTP = 0;
    433   std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
    434   GBREG->fill(0);
    435   for (FX_DWORD h = 0; h < GBH; h++) {
    436     if (TPGDON) {
    437       SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
    438       LTP = LTP ^ SLTP;
    439     }
    440     if (LTP == 1) {
    441       GBREG->copyLine(h, h - 1);
    442     } else {
    443       line1 = GBREG->getPixel(1, h - 2);
    444       line1 |= GBREG->getPixel(0, h - 2) << 1;
    445       line2 = GBREG->getPixel(1, h - 1);
    446       line2 |= GBREG->getPixel(0, h - 1) << 1;
    447       line3 = 0;
    448       for (FX_DWORD w = 0; w < GBW; w++) {
    449         if (USESKIP && SKIP->getPixel(w, h)) {
    450           bVal = 0;
    451         } else {
    452           CONTEXT = line3;
    453           CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
    454           CONTEXT |= line2 << 3;
    455           CONTEXT |= line1 << 7;
    456           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    457         }
    458         if (bVal) {
    459           GBREG->setPixel(w, h, bVal);
    460         }
    461         line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
    462         line2 = ((line2 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x0f;
    463         line3 = ((line3 << 1) | bVal) & 0x03;
    464       }
    465     }
    466   }
    467   return GBREG.release();
    468 }
    469 
    470 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_opt3(
    471     CJBig2_ArithDecoder* pArithDecoder,
    472     JBig2ArithCtx* gbContext) {
    473   FX_BOOL LTP, SLTP, bVal;
    474   FX_DWORD CONTEXT;
    475   FX_DWORD line1;
    476   uint8_t* pLine, *pLine1, cVal;
    477   int32_t nStride, k;
    478   int32_t nLineBytes, nBitsLeft, cc;
    479   LTP = 0;
    480   std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
    481   if (!GBREG->m_pData)
    482     return nullptr;
    483 
    484   pLine = GBREG->m_pData;
    485   nStride = GBREG->m_nStride;
    486   nLineBytes = ((GBW + 7) >> 3) - 1;
    487   nBitsLeft = GBW - (nLineBytes << 3);
    488   for (FX_DWORD h = 0; h < GBH; h++) {
    489     if (TPGDON) {
    490       SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
    491       LTP = LTP ^ SLTP;
    492     }
    493     if (LTP == 1) {
    494       GBREG->copyLine(h, h - 1);
    495     } else {
    496       if (h > 0) {
    497         pLine1 = pLine - nStride;
    498         line1 = *pLine1++;
    499         CONTEXT = (line1 >> 1) & 0x03f0;
    500         for (cc = 0; cc < nLineBytes; cc++) {
    501           line1 = (line1 << 8) | (*pLine1++);
    502           cVal = 0;
    503           for (k = 7; k >= 0; k--) {
    504             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    505             cVal |= bVal << k;
    506             CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal |
    507                       ((line1 >> (k + 1)) & 0x0010);
    508           }
    509           pLine[cc] = cVal;
    510         }
    511         line1 <<= 8;
    512         cVal = 0;
    513         for (k = 0; k < nBitsLeft; k++) {
    514           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    515           cVal |= bVal << (7 - k);
    516           CONTEXT =
    517               ((CONTEXT & 0x01f7) << 1) | bVal | ((line1 >> (8 - k)) & 0x0010);
    518         }
    519         pLine[nLineBytes] = cVal;
    520       } else {
    521         CONTEXT = 0;
    522         for (cc = 0; cc < nLineBytes; cc++) {
    523           cVal = 0;
    524           for (k = 7; k >= 0; k--) {
    525             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    526             cVal |= bVal << k;
    527             CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
    528           }
    529           pLine[cc] = cVal;
    530         }
    531         cVal = 0;
    532         for (k = 0; k < nBitsLeft; k++) {
    533           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    534           cVal |= bVal << (7 - k);
    535           CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
    536         }
    537         pLine[nLineBytes] = cVal;
    538       }
    539     }
    540     pLine += nStride;
    541   }
    542   return GBREG.release();
    543 }
    544 
    545 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_unopt(
    546     CJBig2_ArithDecoder* pArithDecoder,
    547     JBig2ArithCtx* gbContext) {
    548   FX_BOOL LTP, SLTP, bVal;
    549   FX_DWORD CONTEXT;
    550   FX_DWORD line1, line2;
    551   LTP = 0;
    552   std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
    553   GBREG->fill(0);
    554   for (FX_DWORD h = 0; h < GBH; h++) {
    555     if (TPGDON) {
    556       SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
    557       LTP = LTP ^ SLTP;
    558     }
    559     if (LTP == 1) {
    560       GBREG->copyLine(h, h - 1);
    561     } else {
    562       line1 = GBREG->getPixel(1, h - 1);
    563       line1 |= GBREG->getPixel(0, h - 1) << 1;
    564       line2 = 0;
    565       for (FX_DWORD w = 0; w < GBW; w++) {
    566         if (USESKIP && SKIP->getPixel(w, h)) {
    567           bVal = 0;
    568         } else {
    569           CONTEXT = line2;
    570           CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
    571           CONTEXT |= line1 << 5;
    572           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    573         }
    574         if (bVal) {
    575           GBREG->setPixel(w, h, bVal);
    576         }
    577         line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x1f;
    578         line2 = ((line2 << 1) | bVal) & 0x0f;
    579       }
    580     }
    581   }
    582   return GBREG.release();
    583 }
    584 
    585 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_Arith(
    586     CJBig2_Image** pImage,
    587     CJBig2_ArithDecoder* pArithDecoder,
    588     JBig2ArithCtx* gbContext,
    589     IFX_Pause* pPause) {
    590   if (GBW == 0 || GBH == 0) {
    591     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
    592     return FXCODEC_STATUS_DECODE_FINISH;
    593   }
    594   m_ProssiveStatus = FXCODEC_STATUS_DECODE_READY;
    595   m_pPause = pPause;
    596   if (!*pImage)
    597     *pImage = new CJBig2_Image(GBW, GBH);
    598   if (!(*pImage)->m_pData) {
    599     delete *pImage;
    600     *pImage = nullptr;
    601     m_ProssiveStatus = FXCODEC_STATUS_ERROR;
    602     return FXCODEC_STATUS_ERROR;
    603   }
    604   m_DecodeType = 1;
    605   m_pImage = pImage;
    606   (*m_pImage)->fill(0);
    607   m_pArithDecoder = pArithDecoder;
    608   m_gbContext = gbContext;
    609   LTP = 0;
    610   m_pLine = nullptr;
    611   m_loopIndex = 0;
    612   return decode_Arith(pPause);
    613 }
    614 
    615 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith(IFX_Pause* pPause) {
    616   int iline = m_loopIndex;
    617   CJBig2_Image* pImage = *m_pImage;
    618   if (GBTEMPLATE == 0) {
    619     if (UseTemplate0Opt3()) {
    620       m_ProssiveStatus = decode_Arith_Template0_opt3(pImage, m_pArithDecoder,
    621                                                      m_gbContext, pPause);
    622     } else {
    623       m_ProssiveStatus = decode_Arith_Template0_unopt(pImage, m_pArithDecoder,
    624                                                       m_gbContext, pPause);
    625     }
    626   } else if (GBTEMPLATE == 1) {
    627     if (UseTemplate1Opt3()) {
    628       m_ProssiveStatus = decode_Arith_Template1_opt3(pImage, m_pArithDecoder,
    629                                                      m_gbContext, pPause);
    630     } else {
    631       m_ProssiveStatus = decode_Arith_Template1_unopt(pImage, m_pArithDecoder,
    632                                                       m_gbContext, pPause);
    633     }
    634   } else if (GBTEMPLATE == 2) {
    635     if (UseTemplate23Opt3()) {
    636       m_ProssiveStatus = decode_Arith_Template2_opt3(pImage, m_pArithDecoder,
    637                                                      m_gbContext, pPause);
    638     } else {
    639       m_ProssiveStatus = decode_Arith_Template2_unopt(pImage, m_pArithDecoder,
    640                                                       m_gbContext, pPause);
    641     }
    642   } else {
    643     if (UseTemplate23Opt3()) {
    644       m_ProssiveStatus = decode_Arith_Template3_opt3(pImage, m_pArithDecoder,
    645                                                      m_gbContext, pPause);
    646     } else {
    647       m_ProssiveStatus = decode_Arith_Template3_unopt(pImage, m_pArithDecoder,
    648                                                       m_gbContext, pPause);
    649     }
    650   }
    651   m_ReplaceRect.left = 0;
    652   m_ReplaceRect.right = pImage->m_nWidth;
    653   m_ReplaceRect.top = iline;
    654   m_ReplaceRect.bottom = m_loopIndex;
    655   if (m_ProssiveStatus == FXCODEC_STATUS_DECODE_FINISH) {
    656     m_loopIndex = 0;
    657   }
    658   return m_ProssiveStatus;
    659 }
    660 
    661 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_MMR(CJBig2_Image** pImage,
    662                                                 CJBig2_BitStream* pStream,
    663                                                 IFX_Pause* pPause) {
    664   int bitpos, i;
    665   *pImage = new CJBig2_Image(GBW, GBH);
    666   if (!(*pImage)->m_pData) {
    667     delete (*pImage);
    668     (*pImage) = nullptr;
    669     m_ProssiveStatus = FXCODEC_STATUS_ERROR;
    670     return m_ProssiveStatus;
    671   }
    672   bitpos = (int)pStream->getBitPos();
    673   FaxG4Decode(pStream->getBuf(), pStream->getLength(), &bitpos,
    674               (*pImage)->m_pData, GBW, GBH, (*pImage)->m_nStride);
    675   pStream->setBitPos(bitpos);
    676   for (i = 0; (FX_DWORD)i < (*pImage)->m_nStride * GBH; i++) {
    677     (*pImage)->m_pData[i] = ~(*pImage)->m_pData[i];
    678   }
    679   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
    680   return m_ProssiveStatus;
    681 }
    682 
    683 FXCODEC_STATUS CJBig2_GRDProc::Continue_decode(IFX_Pause* pPause) {
    684   if (m_ProssiveStatus != FXCODEC_STATUS_DECODE_TOBECONTINUE)
    685     return m_ProssiveStatus;
    686 
    687   if (m_DecodeType != 1) {
    688     m_ProssiveStatus = FXCODEC_STATUS_ERROR;
    689     return m_ProssiveStatus;
    690   }
    691 
    692   return decode_Arith(pPause);
    693 }
    694 
    695 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3(
    696     CJBig2_Image* pImage,
    697     CJBig2_ArithDecoder* pArithDecoder,
    698     JBig2ArithCtx* gbContext,
    699     IFX_Pause* pPause) {
    700   FX_BOOL SLTP, bVal;
    701   FX_DWORD CONTEXT;
    702   FX_DWORD line1, line2;
    703   uint8_t* pLine1, *pLine2, cVal;
    704   int32_t nStride, nStride2, k;
    705   int32_t nLineBytes, nBitsLeft, cc;
    706   if (!m_pLine) {
    707     m_pLine = pImage->m_pData;
    708   }
    709   nStride = pImage->m_nStride;
    710   nStride2 = nStride << 1;
    711   nLineBytes = ((GBW + 7) >> 3) - 1;
    712   nBitsLeft = GBW - (nLineBytes << 3);
    713   FX_DWORD height = GBH & 0x7fffffff;
    714   for (; m_loopIndex < height; m_loopIndex++) {
    715     if (TPGDON) {
    716       SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
    717       LTP = LTP ^ SLTP;
    718     }
    719     if (LTP == 1) {
    720       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
    721     } else {
    722       if (m_loopIndex > 1) {
    723         pLine1 = m_pLine - nStride2;
    724         pLine2 = m_pLine - nStride;
    725         line1 = (*pLine1++) << 6;
    726         line2 = *pLine2++;
    727         CONTEXT = ((line1 & 0xf800) | (line2 & 0x07f0));
    728         for (cc = 0; cc < nLineBytes; cc++) {
    729           line1 = (line1 << 8) | ((*pLine1++) << 6);
    730           line2 = (line2 << 8) | (*pLine2++);
    731           cVal = 0;
    732           for (k = 7; k >= 0; k--) {
    733             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    734             cVal |= bVal << k;
    735             CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
    736                        ((line1 >> k) & 0x0800) | ((line2 >> k) & 0x0010));
    737           }
    738           m_pLine[cc] = cVal;
    739         }
    740         line1 <<= 8;
    741         line2 <<= 8;
    742         cVal = 0;
    743         for (k = 0; k < nBitsLeft; k++) {
    744           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    745           cVal |= bVal << (7 - k);
    746           CONTEXT =
    747               (((CONTEXT & 0x7bf7) << 1) | bVal |
    748                ((line1 >> (7 - k)) & 0x0800) | ((line2 >> (7 - k)) & 0x0010));
    749         }
    750         m_pLine[nLineBytes] = cVal;
    751       } else {
    752         pLine2 = m_pLine - nStride;
    753         line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
    754         CONTEXT = (line2 & 0x07f0);
    755         for (cc = 0; cc < nLineBytes; cc++) {
    756           if (m_loopIndex & 1) {
    757             line2 = (line2 << 8) | (*pLine2++);
    758           }
    759           cVal = 0;
    760           for (k = 7; k >= 0; k--) {
    761             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    762             cVal |= bVal << k;
    763             CONTEXT =
    764                 (((CONTEXT & 0x7bf7) << 1) | bVal | ((line2 >> k) & 0x0010));
    765           }
    766           m_pLine[cc] = cVal;
    767         }
    768         line2 <<= 8;
    769         cVal = 0;
    770         for (k = 0; k < nBitsLeft; k++) {
    771           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    772           cVal |= bVal << (7 - k);
    773           CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
    774                      ((line2 >> (7 - k)) & 0x0010));
    775         }
    776         m_pLine[nLineBytes] = cVal;
    777       }
    778     }
    779     m_pLine += nStride;
    780     if (pPause && pPause->NeedToPauseNow()) {
    781       m_loopIndex++;
    782       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
    783       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
    784     }
    785   }
    786   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
    787   return FXCODEC_STATUS_DECODE_FINISH;
    788 }
    789 
    790 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_unopt(
    791     CJBig2_Image* pImage,
    792     CJBig2_ArithDecoder* pArithDecoder,
    793     JBig2ArithCtx* gbContext,
    794     IFX_Pause* pPause) {
    795   FX_BOOL SLTP, bVal;
    796   FX_DWORD CONTEXT;
    797   FX_DWORD line1, line2, line3;
    798   for (; m_loopIndex < GBH; m_loopIndex++) {
    799     if (TPGDON) {
    800       SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
    801       LTP = LTP ^ SLTP;
    802     }
    803     if (LTP == 1) {
    804       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
    805     } else {
    806       line1 = pImage->getPixel(1, m_loopIndex - 2);
    807       line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
    808       line2 = pImage->getPixel(2, m_loopIndex - 1);
    809       line2 |= pImage->getPixel(1, m_loopIndex - 1) << 1;
    810       line2 |= pImage->getPixel(0, m_loopIndex - 1) << 2;
    811       line3 = 0;
    812       for (FX_DWORD w = 0; w < GBW; w++) {
    813         if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
    814           bVal = 0;
    815         } else {
    816           CONTEXT = line3;
    817           CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
    818           CONTEXT |= line2 << 5;
    819           CONTEXT |= pImage->getPixel(w + GBAT[2], m_loopIndex + GBAT[3]) << 10;
    820           CONTEXT |= pImage->getPixel(w + GBAT[4], m_loopIndex + GBAT[5]) << 11;
    821           CONTEXT |= line1 << 12;
    822           CONTEXT |= pImage->getPixel(w + GBAT[6], m_loopIndex + GBAT[7]) << 15;
    823           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    824         }
    825         if (bVal) {
    826           pImage->setPixel(w, m_loopIndex, bVal);
    827         }
    828         line1 =
    829             ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
    830         line2 =
    831             ((line2 << 1) | pImage->getPixel(w + 3, m_loopIndex - 1)) & 0x1f;
    832         line3 = ((line3 << 1) | bVal) & 0x0f;
    833       }
    834     }
    835     if (pPause && pPause->NeedToPauseNow()) {
    836       m_loopIndex++;
    837       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
    838       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
    839     }
    840   }
    841   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
    842   return FXCODEC_STATUS_DECODE_FINISH;
    843 }
    844 
    845 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3(
    846     CJBig2_Image* pImage,
    847     CJBig2_ArithDecoder* pArithDecoder,
    848     JBig2ArithCtx* gbContext,
    849     IFX_Pause* pPause) {
    850   FX_BOOL SLTP, bVal;
    851   FX_DWORD CONTEXT;
    852   FX_DWORD line1, line2;
    853   uint8_t* pLine1, *pLine2, cVal;
    854   int32_t nStride, nStride2, k;
    855   int32_t nLineBytes, nBitsLeft, cc;
    856   if (!m_pLine) {
    857     m_pLine = pImage->m_pData;
    858   }
    859   nStride = pImage->m_nStride;
    860   nStride2 = nStride << 1;
    861   nLineBytes = ((GBW + 7) >> 3) - 1;
    862   nBitsLeft = GBW - (nLineBytes << 3);
    863   for (; m_loopIndex < GBH; m_loopIndex++) {
    864     if (TPGDON) {
    865       SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
    866       LTP = LTP ^ SLTP;
    867     }
    868     if (LTP == 1) {
    869       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
    870     } else {
    871       if (m_loopIndex > 1) {
    872         pLine1 = m_pLine - nStride2;
    873         pLine2 = m_pLine - nStride;
    874         line1 = (*pLine1++) << 4;
    875         line2 = *pLine2++;
    876         CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
    877         for (cc = 0; cc < nLineBytes; cc++) {
    878           line1 = (line1 << 8) | ((*pLine1++) << 4);
    879           line2 = (line2 << 8) | (*pLine2++);
    880           cVal = 0;
    881           for (k = 7; k >= 0; k--) {
    882             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    883             cVal |= bVal << k;
    884             CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
    885                       ((line1 >> k) & 0x0200) | ((line2 >> (k + 1)) & 0x0008);
    886           }
    887           m_pLine[cc] = cVal;
    888         }
    889         line1 <<= 8;
    890         line2 <<= 8;
    891         cVal = 0;
    892         for (k = 0; k < nBitsLeft; k++) {
    893           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    894           cVal |= bVal << (7 - k);
    895           CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
    896                     ((line1 >> (7 - k)) & 0x0200) |
    897                     ((line2 >> (8 - k)) & 0x0008);
    898         }
    899         m_pLine[nLineBytes] = cVal;
    900       } else {
    901         pLine2 = m_pLine - nStride;
    902         line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
    903         CONTEXT = (line2 >> 1) & 0x01f8;
    904         for (cc = 0; cc < nLineBytes; cc++) {
    905           if (m_loopIndex & 1) {
    906             line2 = (line2 << 8) | (*pLine2++);
    907           }
    908           cVal = 0;
    909           for (k = 7; k >= 0; k--) {
    910             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    911             cVal |= bVal << k;
    912             CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
    913                       ((line2 >> (k + 1)) & 0x0008);
    914           }
    915           m_pLine[cc] = cVal;
    916         }
    917         line2 <<= 8;
    918         cVal = 0;
    919         for (k = 0; k < nBitsLeft; k++) {
    920           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    921           cVal |= bVal << (7 - k);
    922           CONTEXT =
    923               ((CONTEXT & 0x0efb) << 1) | bVal | ((line2 >> (8 - k)) & 0x0008);
    924         }
    925         m_pLine[nLineBytes] = cVal;
    926       }
    927     }
    928     m_pLine += nStride;
    929     if (pPause && pPause->NeedToPauseNow()) {
    930       m_loopIndex++;
    931       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
    932       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
    933     }
    934   }
    935   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
    936   return FXCODEC_STATUS_DECODE_FINISH;
    937 }
    938 
    939 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_unopt(
    940     CJBig2_Image* pImage,
    941     CJBig2_ArithDecoder* pArithDecoder,
    942     JBig2ArithCtx* gbContext,
    943     IFX_Pause* pPause) {
    944   FX_BOOL SLTP, bVal;
    945   FX_DWORD CONTEXT;
    946   FX_DWORD line1, line2, line3;
    947   for (FX_DWORD h = 0; h < GBH; h++) {
    948     if (TPGDON) {
    949       SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
    950       LTP = LTP ^ SLTP;
    951     }
    952     if (LTP == 1) {
    953       pImage->copyLine(h, h - 1);
    954     } else {
    955       line1 = pImage->getPixel(2, h - 2);
    956       line1 |= pImage->getPixel(1, h - 2) << 1;
    957       line1 |= pImage->getPixel(0, h - 2) << 2;
    958       line2 = pImage->getPixel(2, h - 1);
    959       line2 |= pImage->getPixel(1, h - 1) << 1;
    960       line2 |= pImage->getPixel(0, h - 1) << 2;
    961       line3 = 0;
    962       for (FX_DWORD w = 0; w < GBW; w++) {
    963         if (USESKIP && SKIP->getPixel(w, h)) {
    964           bVal = 0;
    965         } else {
    966           CONTEXT = line3;
    967           CONTEXT |= pImage->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
    968           CONTEXT |= line2 << 4;
    969           CONTEXT |= line1 << 9;
    970           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
    971         }
    972         if (bVal) {
    973           pImage->setPixel(w, h, bVal);
    974         }
    975         line1 = ((line1 << 1) | pImage->getPixel(w + 3, h - 2)) & 0x0f;
    976         line2 = ((line2 << 1) | pImage->getPixel(w + 3, h - 1)) & 0x1f;
    977         line3 = ((line3 << 1) | bVal) & 0x07;
    978       }
    979     }
    980     if (pPause && pPause->NeedToPauseNow()) {
    981       m_loopIndex++;
    982       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
    983       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
    984     }
    985   }
    986   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
    987   return FXCODEC_STATUS_DECODE_FINISH;
    988 }
    989 
    990 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3(
    991     CJBig2_Image* pImage,
    992     CJBig2_ArithDecoder* pArithDecoder,
    993     JBig2ArithCtx* gbContext,
    994     IFX_Pause* pPause) {
    995   FX_BOOL SLTP, bVal;
    996   FX_DWORD CONTEXT;
    997   FX_DWORD line1, line2;
    998   uint8_t* pLine1, *pLine2, cVal;
    999   int32_t nStride, nStride2, k;
   1000   int32_t nLineBytes, nBitsLeft, cc;
   1001   if (!m_pLine) {
   1002     m_pLine = pImage->m_pData;
   1003   }
   1004   nStride = pImage->m_nStride;
   1005   nStride2 = nStride << 1;
   1006   nLineBytes = ((GBW + 7) >> 3) - 1;
   1007   nBitsLeft = GBW - (nLineBytes << 3);
   1008   for (; m_loopIndex < GBH; m_loopIndex++) {
   1009     if (TPGDON) {
   1010       SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
   1011       LTP = LTP ^ SLTP;
   1012     }
   1013     if (LTP == 1) {
   1014       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
   1015     } else {
   1016       if (m_loopIndex > 1) {
   1017         pLine1 = m_pLine - nStride2;
   1018         pLine2 = m_pLine - nStride;
   1019         line1 = (*pLine1++) << 1;
   1020         line2 = *pLine2++;
   1021         CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
   1022         for (cc = 0; cc < nLineBytes; cc++) {
   1023           line1 = (line1 << 8) | ((*pLine1++) << 1);
   1024           line2 = (line2 << 8) | (*pLine2++);
   1025           cVal = 0;
   1026           for (k = 7; k >= 0; k--) {
   1027             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
   1028             cVal |= bVal << k;
   1029             CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
   1030                       ((line1 >> k) & 0x0080) | ((line2 >> (k + 3)) & 0x0004);
   1031           }
   1032           m_pLine[cc] = cVal;
   1033         }
   1034         line1 <<= 8;
   1035         line2 <<= 8;
   1036         cVal = 0;
   1037         for (k = 0; k < nBitsLeft; k++) {
   1038           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
   1039           cVal |= bVal << (7 - k);
   1040           CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
   1041                     ((line1 >> (7 - k)) & 0x0080) |
   1042                     ((line2 >> (10 - k)) & 0x0004);
   1043         }
   1044         m_pLine[nLineBytes] = cVal;
   1045       } else {
   1046         pLine2 = m_pLine - nStride;
   1047         line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
   1048         CONTEXT = (line2 >> 3) & 0x007c;
   1049         for (cc = 0; cc < nLineBytes; cc++) {
   1050           if (m_loopIndex & 1) {
   1051             line2 = (line2 << 8) | (*pLine2++);
   1052           }
   1053           cVal = 0;
   1054           for (k = 7; k >= 0; k--) {
   1055             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
   1056             cVal |= bVal << k;
   1057             CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
   1058                       ((line2 >> (k + 3)) & 0x0004);
   1059           }
   1060           m_pLine[cc] = cVal;
   1061         }
   1062         line2 <<= 8;
   1063         cVal = 0;
   1064         for (k = 0; k < nBitsLeft; k++) {
   1065           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
   1066           cVal |= bVal << (7 - k);
   1067           CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
   1068                     (((line2 >> (10 - k))) & 0x0004);
   1069         }
   1070         m_pLine[nLineBytes] = cVal;
   1071       }
   1072     }
   1073     m_pLine += nStride;
   1074     if (pPause && m_loopIndex % 50 == 0 && pPause->NeedToPauseNow()) {
   1075       m_loopIndex++;
   1076       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   1077       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
   1078     }
   1079   }
   1080   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
   1081   return FXCODEC_STATUS_DECODE_FINISH;
   1082 }
   1083 
   1084 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_unopt(
   1085     CJBig2_Image* pImage,
   1086     CJBig2_ArithDecoder* pArithDecoder,
   1087     JBig2ArithCtx* gbContext,
   1088     IFX_Pause* pPause) {
   1089   FX_BOOL SLTP, bVal;
   1090   FX_DWORD CONTEXT;
   1091   FX_DWORD line1, line2, line3;
   1092   for (; m_loopIndex < GBH; m_loopIndex++) {
   1093     if (TPGDON) {
   1094       SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
   1095       LTP = LTP ^ SLTP;
   1096     }
   1097     if (LTP == 1) {
   1098       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
   1099     } else {
   1100       line1 = pImage->getPixel(1, m_loopIndex - 2);
   1101       line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
   1102       line2 = pImage->getPixel(1, m_loopIndex - 1);
   1103       line2 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
   1104       line3 = 0;
   1105       for (FX_DWORD w = 0; w < GBW; w++) {
   1106         if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
   1107           bVal = 0;
   1108         } else {
   1109           CONTEXT = line3;
   1110           CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 2;
   1111           CONTEXT |= line2 << 3;
   1112           CONTEXT |= line1 << 7;
   1113           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
   1114         }
   1115         if (bVal) {
   1116           pImage->setPixel(w, m_loopIndex, bVal);
   1117         }
   1118         line1 =
   1119             ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
   1120         line2 =
   1121             ((line2 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x0f;
   1122         line3 = ((line3 << 1) | bVal) & 0x03;
   1123       }
   1124     }
   1125     if (pPause && pPause->NeedToPauseNow()) {
   1126       m_loopIndex++;
   1127       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   1128       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
   1129     }
   1130   }
   1131   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
   1132   return FXCODEC_STATUS_DECODE_FINISH;
   1133 }
   1134 
   1135 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3(
   1136     CJBig2_Image* pImage,
   1137     CJBig2_ArithDecoder* pArithDecoder,
   1138     JBig2ArithCtx* gbContext,
   1139     IFX_Pause* pPause) {
   1140   FX_BOOL SLTP, bVal;
   1141   FX_DWORD CONTEXT;
   1142   FX_DWORD line1;
   1143   uint8_t* pLine1, cVal;
   1144   int32_t nStride, k;
   1145   int32_t nLineBytes, nBitsLeft, cc;
   1146   if (!m_pLine) {
   1147     m_pLine = pImage->m_pData;
   1148   }
   1149   nStride = pImage->m_nStride;
   1150   nLineBytes = ((GBW + 7) >> 3) - 1;
   1151   nBitsLeft = GBW - (nLineBytes << 3);
   1152   for (; m_loopIndex < GBH; m_loopIndex++) {
   1153     if (TPGDON) {
   1154       SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
   1155       LTP = LTP ^ SLTP;
   1156     }
   1157     if (LTP == 1) {
   1158       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
   1159     } else {
   1160       if (m_loopIndex > 0) {
   1161         pLine1 = m_pLine - nStride;
   1162         line1 = *pLine1++;
   1163         CONTEXT = (line1 >> 1) & 0x03f0;
   1164         for (cc = 0; cc < nLineBytes; cc++) {
   1165           line1 = (line1 << 8) | (*pLine1++);
   1166           cVal = 0;
   1167           for (k = 7; k >= 0; k--) {
   1168             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
   1169             cVal |= bVal << k;
   1170             CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal |
   1171                       ((line1 >> (k + 1)) & 0x0010);
   1172           }
   1173           m_pLine[cc] = cVal;
   1174         }
   1175         line1 <<= 8;
   1176         cVal = 0;
   1177         for (k = 0; k < nBitsLeft; k++) {
   1178           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
   1179           cVal |= bVal << (7 - k);
   1180           CONTEXT =
   1181               ((CONTEXT & 0x01f7) << 1) | bVal | ((line1 >> (8 - k)) & 0x0010);
   1182         }
   1183         m_pLine[nLineBytes] = cVal;
   1184       } else {
   1185         CONTEXT = 0;
   1186         for (cc = 0; cc < nLineBytes; cc++) {
   1187           cVal = 0;
   1188           for (k = 7; k >= 0; k--) {
   1189             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
   1190             cVal |= bVal << k;
   1191             CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
   1192           }
   1193           m_pLine[cc] = cVal;
   1194         }
   1195         cVal = 0;
   1196         for (k = 0; k < nBitsLeft; k++) {
   1197           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
   1198           cVal |= bVal << (7 - k);
   1199           CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
   1200         }
   1201         m_pLine[nLineBytes] = cVal;
   1202       }
   1203     }
   1204     m_pLine += nStride;
   1205     if (pPause && pPause->NeedToPauseNow()) {
   1206       m_loopIndex++;
   1207       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   1208       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
   1209     }
   1210   }
   1211   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
   1212   return FXCODEC_STATUS_DECODE_FINISH;
   1213 }
   1214 
   1215 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_unopt(
   1216     CJBig2_Image* pImage,
   1217     CJBig2_ArithDecoder* pArithDecoder,
   1218     JBig2ArithCtx* gbContext,
   1219     IFX_Pause* pPause) {
   1220   FX_BOOL SLTP, bVal;
   1221   FX_DWORD CONTEXT;
   1222   FX_DWORD line1, line2;
   1223   for (; m_loopIndex < GBH; m_loopIndex++) {
   1224     if (TPGDON) {
   1225       SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
   1226       LTP = LTP ^ SLTP;
   1227     }
   1228     if (LTP == 1) {
   1229       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
   1230     } else {
   1231       line1 = pImage->getPixel(1, m_loopIndex - 1);
   1232       line1 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
   1233       line2 = 0;
   1234       for (FX_DWORD w = 0; w < GBW; w++) {
   1235         if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
   1236           bVal = 0;
   1237         } else {
   1238           CONTEXT = line2;
   1239           CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
   1240           CONTEXT |= line1 << 5;
   1241           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
   1242         }
   1243         if (bVal) {
   1244           pImage->setPixel(w, m_loopIndex, bVal);
   1245         }
   1246         line1 =
   1247             ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x1f;
   1248         line2 = ((line2 << 1) | bVal) & 0x0f;
   1249       }
   1250     }
   1251     if (pPause && pPause->NeedToPauseNow()) {
   1252       m_loopIndex++;
   1253       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   1254       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
   1255     }
   1256   }
   1257   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
   1258   return FXCODEC_STATUS_DECODE_FINISH;
   1259 }
   1260