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