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_GrrdProc.h"
      8 
      9 #include <memory>
     10 
     11 #include "JBig2_ArithDecoder.h"
     12 #include "JBig2_BitStream.h"
     13 #include "JBig2_Image.h"
     14 
     15 CJBig2_Image* CJBig2_GRRDProc::decode(CJBig2_ArithDecoder* pArithDecoder,
     16                                       JBig2ArithCtx* grContext) {
     17   if (GRW == 0 || GRH == 0)
     18     return new CJBig2_Image(GRW, GRH);
     19 
     20   if (GRTEMPLATE == 0) {
     21     if ((GRAT[0] == -1) && (GRAT[1] == -1) && (GRAT[2] == -1) &&
     22         (GRAT[3] == -1) && (GRREFERENCEDX == 0) &&
     23         (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
     24       return decode_Template0_opt(pArithDecoder, grContext);
     25     }
     26     return decode_Template0_unopt(pArithDecoder, grContext);
     27   }
     28 
     29   if ((GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth))
     30     return decode_Template1_opt(pArithDecoder, grContext);
     31   return decode_Template1_unopt(pArithDecoder, grContext);
     32 }
     33 
     34 CJBig2_Image* CJBig2_GRRDProc::decode_Template0_unopt(
     35     CJBig2_ArithDecoder* pArithDecoder,
     36     JBig2ArithCtx* grContext) {
     37   FX_BOOL LTP, SLTP, bVal;
     38   FX_DWORD CONTEXT;
     39   FX_DWORD line1, line2, line3, line4, line5;
     40   LTP = 0;
     41   std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(GRW, GRH));
     42   GRREG->fill(0);
     43   for (FX_DWORD h = 0; h < GRH; h++) {
     44     if (TPGRON) {
     45       SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
     46       LTP = LTP ^ SLTP;
     47     }
     48     if (LTP == 0) {
     49       line1 = GRREG->getPixel(1, h - 1);
     50       line1 |= GRREG->getPixel(0, h - 1) << 1;
     51       line2 = 0;
     52       line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
     53       line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1)
     54                << 1;
     55       line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
     56       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
     57       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
     58                << 2;
     59       line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
     60       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
     61                << 1;
     62       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1)
     63                << 2;
     64       for (FX_DWORD w = 0; w < GRW; w++) {
     65         CONTEXT = line5;
     66         CONTEXT |= line4 << 3;
     67         CONTEXT |= line3 << 6;
     68         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2],
     69                                          h - GRREFERENCEDY + GRAT[3])
     70                    << 8;
     71         CONTEXT |= line2 << 9;
     72         CONTEXT |= line1 << 10;
     73         CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
     74         bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
     75         GRREG->setPixel(w, h, bVal);
     76         line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
     77         line2 = ((line2 << 1) | bVal) & 0x01;
     78         line3 = ((line3 << 1) |
     79                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
     80                                        h - GRREFERENCEDY - 1)) &
     81                 0x03;
     82         line4 =
     83             ((line4 << 1) |
     84              GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
     85             0x07;
     86         line5 = ((line5 << 1) |
     87                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
     88                                        h - GRREFERENCEDY + 1)) &
     89                 0x07;
     90       }
     91     } else {
     92       line1 = GRREG->getPixel(1, h - 1);
     93       line1 |= GRREG->getPixel(0, h - 1) << 1;
     94       line2 = 0;
     95       line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
     96       line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1)
     97                << 1;
     98       line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
     99       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
    100       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
    101                << 2;
    102       line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
    103       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
    104                << 1;
    105       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1)
    106                << 2;
    107       for (FX_DWORD w = 0; w < GRW; w++) {
    108         bVal = GRREFERENCE->getPixel(w, h);
    109         if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1)) &&
    110               (bVal == GRREFERENCE->getPixel(w, h - 1)) &&
    111               (bVal == GRREFERENCE->getPixel(w + 1, h - 1)) &&
    112               (bVal == GRREFERENCE->getPixel(w - 1, h)) &&
    113               (bVal == GRREFERENCE->getPixel(w + 1, h)) &&
    114               (bVal == GRREFERENCE->getPixel(w - 1, h + 1)) &&
    115               (bVal == GRREFERENCE->getPixel(w, h + 1)) &&
    116               (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
    117           CONTEXT = line5;
    118           CONTEXT |= line4 << 3;
    119           CONTEXT |= line3 << 6;
    120           CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2],
    121                                            h - GRREFERENCEDY + GRAT[3])
    122                      << 8;
    123           CONTEXT |= line2 << 9;
    124           CONTEXT |= line1 << 10;
    125           CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
    126           bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
    127         }
    128         GRREG->setPixel(w, h, bVal);
    129         line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
    130         line2 = ((line2 << 1) | bVal) & 0x01;
    131         line3 = ((line3 << 1) |
    132                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
    133                                        h - GRREFERENCEDY - 1)) &
    134                 0x03;
    135         line4 =
    136             ((line4 << 1) |
    137              GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
    138             0x07;
    139         line5 = ((line5 << 1) |
    140                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
    141                                        h - GRREFERENCEDY + 1)) &
    142                 0x07;
    143       }
    144     }
    145   }
    146   return GRREG.release();
    147 }
    148 
    149 CJBig2_Image* CJBig2_GRRDProc::decode_Template0_opt(
    150     CJBig2_ArithDecoder* pArithDecoder,
    151     JBig2ArithCtx* grContext) {
    152   if (!GRREFERENCE->m_pData)
    153     return nullptr;
    154 
    155   FX_BOOL LTP, SLTP, bVal;
    156   FX_DWORD CONTEXT;
    157   FX_DWORD line1, line1_r, line2_r, line3_r;
    158   uint8_t* pLine, *pLineR, cVal;
    159   intptr_t nStride, nStrideR, nOffset;
    160   int32_t k, nBits;
    161   int32_t GRWR, GRHR;
    162   int32_t GRW, GRH;
    163   GRW = (int32_t)CJBig2_GRRDProc::GRW;
    164   GRH = (int32_t)CJBig2_GRRDProc::GRH;
    165   LTP = 0;
    166   std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(GRW, GRH));
    167   if (!GRREG->m_pData)
    168     return nullptr;
    169 
    170   pLine = GRREG->m_pData;
    171   pLineR = GRREFERENCE->m_pData;
    172   nStride = GRREG->m_nStride;
    173   nStrideR = GRREFERENCE->m_nStride;
    174   GRWR = (int32_t)GRREFERENCE->m_nWidth;
    175   GRHR = (int32_t)GRREFERENCE->m_nHeight;
    176   if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
    177     GRREFERENCEDY = 0;
    178   }
    179   nOffset = -GRREFERENCEDY * nStrideR;
    180   for (int32_t h = 0; h < GRH; h++) {
    181     if (TPGRON) {
    182       SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
    183       LTP = LTP ^ SLTP;
    184     }
    185     line1 = (h > 0) ? pLine[-nStride] << 4 : 0;
    186     int32_t reference_h = h - GRREFERENCEDY;
    187     FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
    188     FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
    189     FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
    190     line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
    191     line2_r = line2_r_ok ? pLineR[nOffset] : 0;
    192     line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
    193     if (LTP == 0) {
    194       CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0) |
    195                 ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
    196       for (int32_t w = 0; w < GRW; w += 8) {
    197         nBits = GRW - w > 8 ? 8 : GRW - w;
    198         if (h > 0)
    199           line1 = (line1 << 8) |
    200                   (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
    201         if (h > GRHR + GRREFERENCEDY + 1) {
    202           line1_r = 0;
    203           line2_r = 0;
    204           line3_r = 0;
    205         } else {
    206           if (line1_r_ok)
    207             line1_r =
    208                 (line1_r << 8) |
    209                 (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
    210           if (line2_r_ok)
    211             line2_r = (line2_r << 8) |
    212                       (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
    213           if (line3_r_ok) {
    214             line3_r =
    215                 (line3_r << 8) |
    216                 (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
    217           } else {
    218             line3_r = 0;
    219           }
    220         }
    221         cVal = 0;
    222         for (k = 0; k < nBits; k++) {
    223           bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
    224           cVal |= bVal << (7 - k);
    225           CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
    226                     ((line1 >> (7 - k)) & 0x0400) |
    227                     ((line1_r >> (7 - k)) & 0x0040) |
    228                     ((line2_r >> (10 - k)) & 0x0008) |
    229                     ((line3_r >> (13 - k)) & 0x0001);
    230         }
    231         pLine[w >> 3] = cVal;
    232       }
    233     } else {
    234       CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0) |
    235                 ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
    236       for (int32_t w = 0; w < GRW; w += 8) {
    237         nBits = GRW - w > 8 ? 8 : GRW - w;
    238         if (h > 0)
    239           line1 = (line1 << 8) |
    240                   (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
    241         if (line1_r_ok)
    242           line1_r =
    243               (line1_r << 8) |
    244               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
    245         if (line2_r_ok)
    246           line2_r = (line2_r << 8) |
    247                     (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
    248         if (line3_r_ok) {
    249           line3_r =
    250               (line3_r << 8) |
    251               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
    252         } else {
    253           line3_r = 0;
    254         }
    255         cVal = 0;
    256         for (k = 0; k < nBits; k++) {
    257           bVal = GRREFERENCE->getPixel(w + k, h);
    258           if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1)) &&
    259                 (bVal == GRREFERENCE->getPixel(w + k, h - 1)) &&
    260                 (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1)) &&
    261                 (bVal == GRREFERENCE->getPixel(w + k - 1, h)) &&
    262                 (bVal == GRREFERENCE->getPixel(w + k + 1, h)) &&
    263                 (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1)) &&
    264                 (bVal == GRREFERENCE->getPixel(w + k, h + 1)) &&
    265                 (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
    266             bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
    267           }
    268           cVal |= bVal << (7 - k);
    269           CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
    270                     ((line1 >> (7 - k)) & 0x0400) |
    271                     ((line1_r >> (7 - k)) & 0x0040) |
    272                     ((line2_r >> (10 - k)) & 0x0008) |
    273                     ((line3_r >> (13 - k)) & 0x0001);
    274         }
    275         pLine[w >> 3] = cVal;
    276       }
    277     }
    278     pLine += nStride;
    279     if (h < GRHR + GRREFERENCEDY) {
    280       pLineR += nStrideR;
    281     }
    282   }
    283   return GRREG.release();
    284 }
    285 
    286 CJBig2_Image* CJBig2_GRRDProc::decode_Template1_unopt(
    287     CJBig2_ArithDecoder* pArithDecoder,
    288     JBig2ArithCtx* grContext) {
    289   FX_BOOL LTP, SLTP, bVal;
    290   FX_DWORD CONTEXT;
    291   FX_DWORD line1, line2, line3, line4, line5;
    292   LTP = 0;
    293   std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(GRW, GRH));
    294   GRREG->fill(0);
    295   for (FX_DWORD h = 0; h < GRH; h++) {
    296     if (TPGRON) {
    297       SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
    298       LTP = LTP ^ SLTP;
    299     }
    300     if (LTP == 0) {
    301       line1 = GRREG->getPixel(1, h - 1);
    302       line1 |= GRREG->getPixel(0, h - 1) << 1;
    303       line1 |= GRREG->getPixel(-1, h - 1) << 2;
    304       line2 = 0;
    305       line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
    306       line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
    307       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
    308       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
    309                << 2;
    310       line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
    311       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
    312                << 1;
    313       for (FX_DWORD w = 0; w < GRW; w++) {
    314         CONTEXT = line5;
    315         CONTEXT |= line4 << 2;
    316         CONTEXT |= line3 << 5;
    317         CONTEXT |= line2 << 6;
    318         CONTEXT |= line1 << 7;
    319         bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
    320         GRREG->setPixel(w, h, bVal);
    321         line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
    322         line2 = ((line2 << 1) | bVal) & 0x01;
    323         line3 = ((line3 << 1) |
    324                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 1,
    325                                        h - GRREFERENCEDY - 1)) &
    326                 0x01;
    327         line4 =
    328             ((line4 << 1) |
    329              GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
    330             0x07;
    331         line5 = ((line5 << 1) |
    332                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
    333                                        h - GRREFERENCEDY + 1)) &
    334                 0x03;
    335       }
    336     } else {
    337       line1 = GRREG->getPixel(1, h - 1);
    338       line1 |= GRREG->getPixel(0, h - 1) << 1;
    339       line1 |= GRREG->getPixel(-1, h - 1) << 2;
    340       line2 = 0;
    341       line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
    342       line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
    343       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
    344       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
    345                << 2;
    346       line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
    347       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
    348                << 1;
    349       for (FX_DWORD w = 0; w < GRW; w++) {
    350         bVal = GRREFERENCE->getPixel(w, h);
    351         if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1)) &&
    352               (bVal == GRREFERENCE->getPixel(w, h - 1)) &&
    353               (bVal == GRREFERENCE->getPixel(w + 1, h - 1)) &&
    354               (bVal == GRREFERENCE->getPixel(w - 1, h)) &&
    355               (bVal == GRREFERENCE->getPixel(w + 1, h)) &&
    356               (bVal == GRREFERENCE->getPixel(w - 1, h + 1)) &&
    357               (bVal == GRREFERENCE->getPixel(w, h + 1)) &&
    358               (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
    359           CONTEXT = line5;
    360           CONTEXT |= line4 << 2;
    361           CONTEXT |= line3 << 5;
    362           CONTEXT |= line2 << 6;
    363           CONTEXT |= line1 << 7;
    364           bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
    365         }
    366         GRREG->setPixel(w, h, bVal);
    367         line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
    368         line2 = ((line2 << 1) | bVal) & 0x01;
    369         line3 = ((line3 << 1) |
    370                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 1,
    371                                        h - GRREFERENCEDY - 1)) &
    372                 0x01;
    373         line4 =
    374             ((line4 << 1) |
    375              GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
    376             0x07;
    377         line5 = ((line5 << 1) |
    378                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
    379                                        h - GRREFERENCEDY + 1)) &
    380                 0x03;
    381       }
    382     }
    383   }
    384   return GRREG.release();
    385 }
    386 
    387 CJBig2_Image* CJBig2_GRRDProc::decode_Template1_opt(
    388     CJBig2_ArithDecoder* pArithDecoder,
    389     JBig2ArithCtx* grContext) {
    390   if (!GRREFERENCE->m_pData)
    391     return nullptr;
    392 
    393   FX_BOOL LTP, SLTP, bVal;
    394   FX_DWORD CONTEXT;
    395   FX_DWORD line1, line1_r, line2_r, line3_r;
    396   uint8_t* pLine, *pLineR, cVal;
    397   intptr_t nStride, nStrideR, nOffset;
    398   int32_t k, nBits;
    399   int32_t GRWR, GRHR;
    400   int32_t GRW, GRH;
    401   GRW = (int32_t)CJBig2_GRRDProc::GRW;
    402   GRH = (int32_t)CJBig2_GRRDProc::GRH;
    403   LTP = 0;
    404   std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(GRW, GRH));
    405   if (!GRREG->m_pData)
    406     return nullptr;
    407 
    408   pLine = GRREG->m_pData;
    409   pLineR = GRREFERENCE->m_pData;
    410   nStride = GRREG->m_nStride;
    411   nStrideR = GRREFERENCE->m_nStride;
    412   GRWR = (int32_t)GRREFERENCE->m_nWidth;
    413   GRHR = (int32_t)GRREFERENCE->m_nHeight;
    414   if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
    415     GRREFERENCEDY = 0;
    416   }
    417   nOffset = -GRREFERENCEDY * nStrideR;
    418   for (int32_t h = 0; h < GRH; h++) {
    419     if (TPGRON) {
    420       SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
    421       LTP = LTP ^ SLTP;
    422     }
    423     line1 = (h > 0) ? pLine[-nStride] << 1 : 0;
    424     int32_t reference_h = h - GRREFERENCEDY;
    425     FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
    426     FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
    427     FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
    428     line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
    429     line2_r = line2_r_ok ? pLineR[nOffset] : 0;
    430     line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
    431     if (LTP == 0) {
    432       CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020) |
    433                 ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
    434       for (int32_t w = 0; w < GRW; w += 8) {
    435         nBits = GRW - w > 8 ? 8 : GRW - w;
    436         if (h > 0)
    437           line1 = (line1 << 8) |
    438                   (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
    439         if (line1_r_ok)
    440           line1_r =
    441               (line1_r << 8) |
    442               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
    443         if (line2_r_ok)
    444           line2_r = (line2_r << 8) |
    445                     (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
    446         if (line3_r_ok) {
    447           line3_r =
    448               (line3_r << 8) |
    449               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
    450         } else {
    451           line3_r = 0;
    452         }
    453         cVal = 0;
    454         for (k = 0; k < nBits; k++) {
    455           bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
    456           cVal |= bVal << (7 - k);
    457           CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
    458                     ((line1 >> (7 - k)) & 0x0080) |
    459                     ((line1_r >> (9 - k)) & 0x0020) |
    460                     ((line2_r >> (11 - k)) & 0x0004) |
    461                     ((line3_r >> (13 - k)) & 0x0001);
    462         }
    463         pLine[w >> 3] = cVal;
    464       }
    465     } else {
    466       CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020) |
    467                 ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
    468       for (int32_t w = 0; w < GRW; w += 8) {
    469         nBits = GRW - w > 8 ? 8 : GRW - w;
    470         if (h > 0)
    471           line1 = (line1 << 8) |
    472                   (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
    473         if (line1_r_ok)
    474           line1_r =
    475               (line1_r << 8) |
    476               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
    477         if (line2_r_ok)
    478           line2_r = (line2_r << 8) |
    479                     (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
    480         if (line3_r_ok) {
    481           line3_r =
    482               (line3_r << 8) |
    483               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
    484         } else {
    485           line3_r = 0;
    486         }
    487         cVal = 0;
    488         for (k = 0; k < nBits; k++) {
    489           bVal = GRREFERENCE->getPixel(w + k, h);
    490           if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1)) &&
    491                 (bVal == GRREFERENCE->getPixel(w + k, h - 1)) &&
    492                 (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1)) &&
    493                 (bVal == GRREFERENCE->getPixel(w + k - 1, h)) &&
    494                 (bVal == GRREFERENCE->getPixel(w + k + 1, h)) &&
    495                 (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1)) &&
    496                 (bVal == GRREFERENCE->getPixel(w + k, h + 1)) &&
    497                 (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
    498             bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
    499           }
    500           cVal |= bVal << (7 - k);
    501           CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
    502                     ((line1 >> (7 - k)) & 0x0080) |
    503                     ((line1_r >> (9 - k)) & 0x0020) |
    504                     ((line2_r >> (11 - k)) & 0x0004) |
    505                     ((line3_r >> (13 - k)) & 0x0001);
    506         }
    507         pLine[w >> 3] = cVal;
    508       }
    509     }
    510     pLine += nStride;
    511     if (h < GRHR + GRREFERENCEDY) {
    512       pLineR += nStrideR;
    513     }
    514   }
    515   return GRREG.release();
    516 }
    517