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