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