Guard against null image data in CJBig2_GRRDProc.
[pdfium.git] / core / src / fxcodec / jbig2 / JBig2_GeneralDecoder.cpp
1 // Copyright 2014 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_GeneralDecoder.h"
8 #include "JBig2_ArithDecoder.h"
9 #include "JBig2_ArithIntDecoder.h"
10 #include "JBig2_HuffmanDecoder.h"
11 #include "JBig2_HuffmanTable.h"
12 #include "JBig2_PatternDict.h"
13
14 extern const JBig2ArithQe QeTable[] = {
15     {0x5601, 1, 1, 1},   {0x3401, 2, 6, 0},   {0x1801, 3, 9, 0},
16     {0x0AC1, 4, 12, 0},  {0x0521, 5, 29, 0},  {0x0221, 38, 33, 0},
17     {0x5601, 7, 6, 1},   {0x5401, 8, 14, 0},  {0x4801, 9, 14, 0},
18     {0x3801, 10, 14, 0}, {0x3001, 11, 17, 0}, {0x2401, 12, 18, 0},
19     {0x1C01, 13, 20, 0}, {0x1601, 29, 21, 0}, {0x5601, 15, 14, 1},
20     {0x5401, 16, 14, 0}, {0x5101, 17, 15, 0}, {0x4801, 18, 16, 0},
21     {0x3801, 19, 17, 0}, {0x3401, 20, 18, 0}, {0x3001, 21, 19, 0},
22     {0x2801, 22, 19, 0}, {0x2401, 23, 20, 0}, {0x2201, 24, 21, 0},
23     {0x1C01, 25, 22, 0}, {0x1801, 26, 23, 0}, {0x1601, 27, 24, 0},
24     {0x1401, 28, 25, 0}, {0x1201, 29, 26, 0}, {0x1101, 30, 27, 0},
25     {0x0AC1, 31, 28, 0}, {0x09C1, 32, 29, 0}, {0x08A1, 33, 30, 0},
26     {0x0521, 34, 31, 0}, {0x0441, 35, 32, 0}, {0x02A1, 36, 33, 0},
27     {0x0221, 37, 34, 0}, {0x0141, 38, 35, 0}, {0x0111, 39, 36, 0},
28     {0x0085, 40, 37, 0}, {0x0049, 41, 38, 0}, {0x0025, 42, 39, 0},
29     {0x0015, 43, 40, 0}, {0x0009, 44, 41, 0}, {0x0005, 45, 42, 0},
30     {0x0001, 45, 43, 0}, {0x5601, 46, 46, 0}};
31
32 extern const unsigned int JBIG2_QE_NUM = FX_ArraySize(QeTable);
33
34 CJBig2_Image* CJBig2_GRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
35                                            JBig2ArithCtx* gbContext) {
36   if (GBW == 0 || GBH == 0) {
37     return new CJBig2_Image(GBW, GBH);
38   }
39   if (GBTEMPLATE == 0) {
40     if ((GBAT[0] == 3) && (GBAT[1] == (int8_t)-1) && (GBAT[2] == (int8_t)-3) &&
41         (GBAT[3] == (int8_t)-1) && (GBAT[4] == 2) && (GBAT[5] == (int8_t)-2) &&
42         (GBAT[6] == (int8_t)-2) && (GBAT[7] == (int8_t)-2)) {
43       return decode_Arith_Template0_opt3(pArithDecoder, gbContext);
44     } else {
45       return decode_Arith_Template0_unopt(pArithDecoder, gbContext);
46     }
47   } else if (GBTEMPLATE == 1) {
48     if ((GBAT[0] == 3) && (GBAT[1] == (int8_t)-1)) {
49       return decode_Arith_Template1_opt3(pArithDecoder, gbContext);
50     } else {
51       return decode_Arith_Template1_unopt(pArithDecoder, gbContext);
52     }
53   } else if (GBTEMPLATE == 2) {
54     if ((GBAT[0] == 2) && (GBAT[1] == (int8_t)-1)) {
55       return decode_Arith_Template2_opt3(pArithDecoder, gbContext);
56     } else {
57       return decode_Arith_Template2_unopt(pArithDecoder, gbContext);
58     }
59   } else {
60     if ((GBAT[0] == 2) && (GBAT[1] == (int8_t)-1)) {
61       return decode_Arith_Template3_opt3(pArithDecoder, gbContext);
62     } else {
63       return decode_Arith_Template3_unopt(pArithDecoder, gbContext);
64     }
65   }
66 }
67 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3(
68     CJBig2_ArithDecoder* pArithDecoder,
69     JBig2ArithCtx* gbContext) {
70   FX_BOOL LTP, SLTP, bVal;
71   FX_DWORD CONTEXT;
72   FX_DWORD line1, line2;
73   uint8_t *pLine, *pLine1, *pLine2, cVal;
74   int32_t nStride, nStride2, k;
75   int32_t nLineBytes, nBitsLeft, cc;
76   LTP = 0;
77   CJBig2_Image* GBREG = new CJBig2_Image(GBW, GBH);
78   if (GBREG->m_pData == NULL) {
79     delete GBREG;
80     return NULL;
81   }
82   pLine = GBREG->m_pData;
83   nStride = GBREG->m_nStride;
84   nStride2 = nStride << 1;
85   nLineBytes = ((GBW + 7) >> 3) - 1;
86   nBitsLeft = GBW - (nLineBytes << 3);
87   FX_DWORD height = GBH & 0x7fffffff;
88   for (FX_DWORD h = 0; h < height; h++) {
89     if (TPGDON) {
90       SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
91       LTP = LTP ^ SLTP;
92     }
93     if (LTP == 1) {
94       GBREG->copyLine(h, h - 1);
95     } else {
96       if (h > 1) {
97         pLine1 = pLine - nStride2;
98         pLine2 = pLine - nStride;
99         line1 = (*pLine1++) << 6;
100         line2 = *pLine2++;
101         CONTEXT = ((line1 & 0xf800) | (line2 & 0x07f0));
102         for (cc = 0; cc < nLineBytes; cc++) {
103           line1 = (line1 << 8) | ((*pLine1++) << 6);
104           line2 = (line2 << 8) | (*pLine2++);
105           cVal = 0;
106           for (k = 7; k >= 0; k--) {
107             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
108             cVal |= bVal << k;
109             CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
110                        ((line1 >> k) & 0x0800) | ((line2 >> k) & 0x0010));
111           }
112           pLine[cc] = cVal;
113         }
114         line1 <<= 8;
115         line2 <<= 8;
116         cVal = 0;
117         for (k = 0; k < nBitsLeft; k++) {
118           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
119           cVal |= bVal << (7 - k);
120           CONTEXT =
121               (((CONTEXT & 0x7bf7) << 1) | bVal |
122                ((line1 >> (7 - k)) & 0x0800) | ((line2 >> (7 - k)) & 0x0010));
123         }
124         pLine[nLineBytes] = cVal;
125       } else {
126         pLine2 = pLine - nStride;
127         line2 = (h & 1) ? (*pLine2++) : 0;
128         CONTEXT = (line2 & 0x07f0);
129         for (cc = 0; cc < nLineBytes; cc++) {
130           if (h & 1) {
131             line2 = (line2 << 8) | (*pLine2++);
132           }
133           cVal = 0;
134           for (k = 7; k >= 0; k--) {
135             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
136             cVal |= bVal << k;
137             CONTEXT =
138                 (((CONTEXT & 0x7bf7) << 1) | bVal | ((line2 >> k) & 0x0010));
139           }
140           pLine[cc] = cVal;
141         }
142         line2 <<= 8;
143         cVal = 0;
144         for (k = 0; k < nBitsLeft; k++) {
145           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
146           cVal |= bVal << (7 - k);
147           CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
148                      (((line2 >> (7 - k))) & 0x0010));
149         }
150         pLine[nLineBytes] = cVal;
151       }
152     }
153     pLine += nStride;
154   }
155   return GBREG;
156 }
157 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_unopt(
158     CJBig2_ArithDecoder* pArithDecoder,
159     JBig2ArithCtx* gbContext) {
160   FX_BOOL LTP, SLTP, bVal;
161   FX_DWORD CONTEXT;
162   FX_DWORD line1, line2, line3;
163   LTP = 0;
164   CJBig2_Image* GBREG = new CJBig2_Image(GBW, GBH);
165   GBREG->fill(0);
166   for (FX_DWORD h = 0; h < GBH; h++) {
167     if (TPGDON) {
168       SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
169       LTP = LTP ^ SLTP;
170     }
171     if (LTP == 1) {
172       GBREG->copyLine(h, h - 1);
173     } else {
174       line1 = GBREG->getPixel(1, h - 2);
175       line1 |= GBREG->getPixel(0, h - 2) << 1;
176       line2 = GBREG->getPixel(2, h - 1);
177       line2 |= GBREG->getPixel(1, h - 1) << 1;
178       line2 |= GBREG->getPixel(0, h - 1) << 2;
179       line3 = 0;
180       for (FX_DWORD w = 0; w < GBW; w++) {
181         if (USESKIP && SKIP->getPixel(w, h)) {
182           bVal = 0;
183         } else {
184           CONTEXT = line3;
185           CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
186           CONTEXT |= line2 << 5;
187           CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
188           CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
189           CONTEXT |= line1 << 12;
190           CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
191           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
192         }
193         if (bVal) {
194           GBREG->setPixel(w, h, bVal);
195         }
196         line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
197         line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
198         line3 = ((line3 << 1) | bVal) & 0x0f;
199       }
200     }
201   }
202   return GBREG;
203 }
204 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_opt3(
205     CJBig2_ArithDecoder* pArithDecoder,
206     JBig2ArithCtx* gbContext) {
207   FX_BOOL LTP, SLTP, bVal;
208   FX_DWORD CONTEXT;
209   FX_DWORD line1, line2;
210   uint8_t *pLine, *pLine1, *pLine2, cVal;
211   int32_t nStride, nStride2, k;
212   int32_t nLineBytes, nBitsLeft, cc;
213   LTP = 0;
214   CJBig2_Image* GBREG = new CJBig2_Image(GBW, GBH);
215   if (GBREG->m_pData == NULL) {
216     delete GBREG;
217     return NULL;
218   }
219   pLine = GBREG->m_pData;
220   nStride = GBREG->m_nStride;
221   nStride2 = nStride << 1;
222   nLineBytes = ((GBW + 7) >> 3) - 1;
223   nBitsLeft = GBW - (nLineBytes << 3);
224   for (FX_DWORD h = 0; h < GBH; h++) {
225     if (TPGDON) {
226       SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
227       LTP = LTP ^ SLTP;
228     }
229     if (LTP == 1) {
230       GBREG->copyLine(h, h - 1);
231     } else {
232       if (h > 1) {
233         pLine1 = pLine - nStride2;
234         pLine2 = pLine - nStride;
235         line1 = (*pLine1++) << 4;
236         line2 = *pLine2++;
237         CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
238         for (cc = 0; cc < nLineBytes; cc++) {
239           line1 = (line1 << 8) | ((*pLine1++) << 4);
240           line2 = (line2 << 8) | (*pLine2++);
241           cVal = 0;
242           for (k = 7; k >= 0; k--) {
243             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
244             cVal |= bVal << k;
245             CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
246                       ((line1 >> k) & 0x0200) | ((line2 >> (k + 1)) & 0x0008);
247           }
248           pLine[cc] = cVal;
249         }
250         line1 <<= 8;
251         line2 <<= 8;
252         cVal = 0;
253         for (k = 0; k < nBitsLeft; k++) {
254           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
255           cVal |= bVal << (7 - k);
256           CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
257                     ((line1 >> (7 - k)) & 0x0200) |
258                     ((line2 >> (8 - k)) & 0x0008);
259         }
260         pLine[nLineBytes] = cVal;
261       } else {
262         pLine2 = pLine - nStride;
263         line2 = (h & 1) ? (*pLine2++) : 0;
264         CONTEXT = (line2 >> 1) & 0x01f8;
265         for (cc = 0; cc < nLineBytes; cc++) {
266           if (h & 1) {
267             line2 = (line2 << 8) | (*pLine2++);
268           }
269           cVal = 0;
270           for (k = 7; k >= 0; k--) {
271             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
272             cVal |= bVal << k;
273             CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
274                       ((line2 >> (k + 1)) & 0x0008);
275           }
276           pLine[cc] = cVal;
277         }
278         line2 <<= 8;
279         cVal = 0;
280         for (k = 0; k < nBitsLeft; k++) {
281           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
282           cVal |= bVal << (7 - k);
283           CONTEXT =
284               ((CONTEXT & 0x0efb) << 1) | bVal | ((line2 >> (8 - k)) & 0x0008);
285         }
286         pLine[nLineBytes] = cVal;
287       }
288     }
289     pLine += nStride;
290   }
291   return GBREG;
292 }
293 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_unopt(
294     CJBig2_ArithDecoder* pArithDecoder,
295     JBig2ArithCtx* gbContext) {
296   FX_BOOL LTP, SLTP, bVal;
297   FX_DWORD CONTEXT;
298   FX_DWORD line1, line2, line3;
299   LTP = 0;
300   CJBig2_Image* GBREG = new CJBig2_Image(GBW, GBH);
301   GBREG->fill(0);
302   for (FX_DWORD h = 0; h < GBH; h++) {
303     if (TPGDON) {
304       SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
305       LTP = LTP ^ SLTP;
306     }
307     if (LTP == 1) {
308       GBREG->copyLine(h, h - 1);
309     } else {
310       line1 = GBREG->getPixel(2, h - 2);
311       line1 |= GBREG->getPixel(1, h - 2) << 1;
312       line1 |= GBREG->getPixel(0, h - 2) << 2;
313       line2 = GBREG->getPixel(2, h - 1);
314       line2 |= GBREG->getPixel(1, h - 1) << 1;
315       line2 |= GBREG->getPixel(0, h - 1) << 2;
316       line3 = 0;
317       for (FX_DWORD w = 0; w < GBW; w++) {
318         if (USESKIP && SKIP->getPixel(w, h)) {
319           bVal = 0;
320         } else {
321           CONTEXT = line3;
322           CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
323           CONTEXT |= line2 << 4;
324           CONTEXT |= line1 << 9;
325           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
326         }
327         if (bVal) {
328           GBREG->setPixel(w, h, bVal);
329         }
330         line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
331         line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
332         line3 = ((line3 << 1) | bVal) & 0x07;
333       }
334     }
335   }
336   return GBREG;
337 }
338 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_opt3(
339     CJBig2_ArithDecoder* pArithDecoder,
340     JBig2ArithCtx* gbContext) {
341   FX_BOOL LTP, SLTP, bVal;
342   FX_DWORD CONTEXT;
343   FX_DWORD line1, line2;
344   uint8_t *pLine, *pLine1, *pLine2, cVal;
345   int32_t nStride, nStride2, k;
346   int32_t nLineBytes, nBitsLeft, cc;
347   LTP = 0;
348   CJBig2_Image* GBREG = new CJBig2_Image(GBW, GBH);
349   if (GBREG->m_pData == NULL) {
350     delete GBREG;
351     return NULL;
352   }
353   pLine = GBREG->m_pData;
354   nStride = GBREG->m_nStride;
355   nStride2 = nStride << 1;
356   nLineBytes = ((GBW + 7) >> 3) - 1;
357   nBitsLeft = GBW - (nLineBytes << 3);
358   for (FX_DWORD h = 0; h < GBH; h++) {
359     if (TPGDON) {
360       SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
361       LTP = LTP ^ SLTP;
362     }
363     if (LTP == 1) {
364       GBREG->copyLine(h, h - 1);
365     } else {
366       if (h > 1) {
367         pLine1 = pLine - nStride2;
368         pLine2 = pLine - nStride;
369         line1 = (*pLine1++) << 1;
370         line2 = *pLine2++;
371         CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
372         for (cc = 0; cc < nLineBytes; cc++) {
373           line1 = (line1 << 8) | ((*pLine1++) << 1);
374           line2 = (line2 << 8) | (*pLine2++);
375           cVal = 0;
376           for (k = 7; k >= 0; k--) {
377             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
378             cVal |= bVal << k;
379             CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
380                       ((line1 >> k) & 0x0080) | ((line2 >> (k + 3)) & 0x0004);
381           }
382           pLine[cc] = cVal;
383         }
384         line1 <<= 8;
385         line2 <<= 8;
386         cVal = 0;
387         for (k = 0; k < nBitsLeft; k++) {
388           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
389           cVal |= bVal << (7 - k);
390           CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
391                     ((line1 >> (7 - k)) & 0x0080) |
392                     ((line2 >> (10 - k)) & 0x0004);
393         }
394         pLine[nLineBytes] = cVal;
395       } else {
396         pLine2 = pLine - nStride;
397         line2 = (h & 1) ? (*pLine2++) : 0;
398         CONTEXT = (line2 >> 3) & 0x007c;
399         for (cc = 0; cc < nLineBytes; cc++) {
400           if (h & 1) {
401             line2 = (line2 << 8) | (*pLine2++);
402           }
403           cVal = 0;
404           for (k = 7; k >= 0; k--) {
405             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
406             cVal |= bVal << k;
407             CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
408                       ((line2 >> (k + 3)) & 0x0004);
409           }
410           pLine[cc] = cVal;
411         }
412         line2 <<= 8;
413         cVal = 0;
414         for (k = 0; k < nBitsLeft; k++) {
415           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
416           cVal |= bVal << (7 - k);
417           CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
418                     (((line2 >> (10 - k))) & 0x0004);
419         }
420         pLine[nLineBytes] = cVal;
421       }
422     }
423     pLine += nStride;
424   }
425   return GBREG;
426 }
427 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_unopt(
428     CJBig2_ArithDecoder* pArithDecoder,
429     JBig2ArithCtx* gbContext) {
430   FX_BOOL LTP, SLTP, bVal;
431   FX_DWORD CONTEXT;
432   FX_DWORD line1, line2, line3;
433   LTP = 0;
434   CJBig2_Image* GBREG = new CJBig2_Image(GBW, GBH);
435   GBREG->fill(0);
436   for (FX_DWORD h = 0; h < GBH; h++) {
437     if (TPGDON) {
438       SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
439       LTP = LTP ^ SLTP;
440     }
441     if (LTP == 1) {
442       GBREG->copyLine(h, h - 1);
443     } else {
444       line1 = GBREG->getPixel(1, h - 2);
445       line1 |= GBREG->getPixel(0, h - 2) << 1;
446       line2 = GBREG->getPixel(1, h - 1);
447       line2 |= GBREG->getPixel(0, h - 1) << 1;
448       line3 = 0;
449       for (FX_DWORD w = 0; w < GBW; w++) {
450         if (USESKIP && SKIP->getPixel(w, h)) {
451           bVal = 0;
452         } else {
453           CONTEXT = line3;
454           CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
455           CONTEXT |= line2 << 3;
456           CONTEXT |= line1 << 7;
457           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
458         }
459         if (bVal) {
460           GBREG->setPixel(w, h, bVal);
461         }
462         line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
463         line2 = ((line2 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x0f;
464         line3 = ((line3 << 1) | bVal) & 0x03;
465       }
466     }
467   }
468   return GBREG;
469 }
470 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_opt3(
471     CJBig2_ArithDecoder* pArithDecoder,
472     JBig2ArithCtx* gbContext) {
473   FX_BOOL LTP, SLTP, bVal;
474   FX_DWORD CONTEXT;
475   FX_DWORD line1;
476   uint8_t *pLine, *pLine1, cVal;
477   int32_t nStride, k;
478   int32_t nLineBytes, nBitsLeft, cc;
479   LTP = 0;
480   CJBig2_Image* GBREG = new CJBig2_Image(GBW, GBH);
481   if (GBREG->m_pData == NULL) {
482     delete GBREG;
483     return NULL;
484   }
485   pLine = GBREG->m_pData;
486   nStride = GBREG->m_nStride;
487   nLineBytes = ((GBW + 7) >> 3) - 1;
488   nBitsLeft = GBW - (nLineBytes << 3);
489   for (FX_DWORD h = 0; h < GBH; h++) {
490     if (TPGDON) {
491       SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
492       LTP = LTP ^ SLTP;
493     }
494     if (LTP == 1) {
495       GBREG->copyLine(h, h - 1);
496     } else {
497       if (h > 0) {
498         pLine1 = pLine - nStride;
499         line1 = *pLine1++;
500         CONTEXT = (line1 >> 1) & 0x03f0;
501         for (cc = 0; cc < nLineBytes; cc++) {
502           line1 = (line1 << 8) | (*pLine1++);
503           cVal = 0;
504           for (k = 7; k >= 0; k--) {
505             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
506             cVal |= bVal << k;
507             CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal |
508                       ((line1 >> (k + 1)) & 0x0010);
509           }
510           pLine[cc] = cVal;
511         }
512         line1 <<= 8;
513         cVal = 0;
514         for (k = 0; k < nBitsLeft; k++) {
515           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
516           cVal |= bVal << (7 - k);
517           CONTEXT =
518               ((CONTEXT & 0x01f7) << 1) | bVal | ((line1 >> (8 - k)) & 0x0010);
519         }
520         pLine[nLineBytes] = cVal;
521       } else {
522         CONTEXT = 0;
523         for (cc = 0; cc < nLineBytes; cc++) {
524           cVal = 0;
525           for (k = 7; k >= 0; k--) {
526             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
527             cVal |= bVal << k;
528             CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
529           }
530           pLine[cc] = cVal;
531         }
532         cVal = 0;
533         for (k = 0; k < nBitsLeft; k++) {
534           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
535           cVal |= bVal << (7 - k);
536           CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
537         }
538         pLine[nLineBytes] = cVal;
539       }
540     }
541     pLine += nStride;
542   }
543   return GBREG;
544 }
545 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_unopt(
546     CJBig2_ArithDecoder* pArithDecoder,
547     JBig2ArithCtx* gbContext) {
548   FX_BOOL LTP, SLTP, bVal;
549   FX_DWORD CONTEXT;
550   FX_DWORD line1, line2;
551   LTP = 0;
552   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;
583 }
584 CJBig2_Image* CJBig2_GRRDProc::decode(CJBig2_ArithDecoder* pArithDecoder,
585                                       JBig2ArithCtx* grContext) {
586   if (GRW == 0 || GRH == 0) {
587     return new CJBig2_Image(GRW, GRH);
588   }
589   if (GRTEMPLATE == 0) {
590     if ((GRAT[0] == (int8_t)-1) && (GRAT[1] == (int8_t)-1) &&
591         (GRAT[2] == (int8_t)-1) && (GRAT[3] == (int8_t)-1) &&
592         (GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
593       return decode_Template0_opt(pArithDecoder, grContext);
594     } else {
595       return decode_Template0_unopt(pArithDecoder, grContext);
596     }
597   } else {
598     if ((GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
599       return decode_Template1_opt(pArithDecoder, grContext);
600     } else {
601       return decode_Template1_unopt(pArithDecoder, grContext);
602     }
603   }
604 }
605 CJBig2_Image* CJBig2_GRRDProc::decode_Template0_unopt(
606     CJBig2_ArithDecoder* pArithDecoder,
607     JBig2ArithCtx* grContext) {
608   FX_BOOL LTP, SLTP, bVal;
609   FX_DWORD CONTEXT;
610   FX_DWORD line1, line2, line3, line4, line5;
611   LTP = 0;
612   CJBig2_Image* GRREG = new CJBig2_Image(GRW, GRH);
613   GRREG->fill(0);
614   for (FX_DWORD h = 0; h < GRH; h++) {
615     if (TPGRON) {
616       SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
617       LTP = LTP ^ SLTP;
618     }
619     if (LTP == 0) {
620       line1 = GRREG->getPixel(1, h - 1);
621       line1 |= GRREG->getPixel(0, h - 1) << 1;
622       line2 = 0;
623       line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
624       line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1)
625                << 1;
626       line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
627       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
628       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
629                << 2;
630       line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
631       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
632                << 1;
633       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1)
634                << 2;
635       for (FX_DWORD w = 0; w < GRW; w++) {
636         CONTEXT = line5;
637         CONTEXT |= line4 << 3;
638         CONTEXT |= line3 << 6;
639         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2],
640                                          h - GRREFERENCEDY + GRAT[3])
641                    << 8;
642         CONTEXT |= line2 << 9;
643         CONTEXT |= line1 << 10;
644         CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
645         bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
646         GRREG->setPixel(w, h, bVal);
647         line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
648         line2 = ((line2 << 1) | bVal) & 0x01;
649         line3 = ((line3 << 1) |
650                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
651                                        h - GRREFERENCEDY - 1)) &
652                 0x03;
653         line4 =
654             ((line4 << 1) |
655              GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
656             0x07;
657         line5 = ((line5 << 1) |
658                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
659                                        h - GRREFERENCEDY + 1)) &
660                 0x07;
661       }
662     } else {
663       line1 = GRREG->getPixel(1, h - 1);
664       line1 |= GRREG->getPixel(0, h - 1) << 1;
665       line2 = 0;
666       line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
667       line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1)
668                << 1;
669       line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
670       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
671       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
672                << 2;
673       line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
674       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
675                << 1;
676       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1)
677                << 2;
678       for (FX_DWORD w = 0; w < GRW; w++) {
679         bVal = GRREFERENCE->getPixel(w, h);
680         if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1)) &&
681               (bVal == GRREFERENCE->getPixel(w, h - 1)) &&
682               (bVal == GRREFERENCE->getPixel(w + 1, h - 1)) &&
683               (bVal == GRREFERENCE->getPixel(w - 1, h)) &&
684               (bVal == GRREFERENCE->getPixel(w + 1, h)) &&
685               (bVal == GRREFERENCE->getPixel(w - 1, h + 1)) &&
686               (bVal == GRREFERENCE->getPixel(w, h + 1)) &&
687               (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
688           CONTEXT = line5;
689           CONTEXT |= line4 << 3;
690           CONTEXT |= line3 << 6;
691           CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2],
692                                            h - GRREFERENCEDY + GRAT[3])
693                      << 8;
694           CONTEXT |= line2 << 9;
695           CONTEXT |= line1 << 10;
696           CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
697           bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
698         }
699         GRREG->setPixel(w, h, bVal);
700         line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
701         line2 = ((line2 << 1) | bVal) & 0x01;
702         line3 = ((line3 << 1) |
703                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
704                                        h - GRREFERENCEDY - 1)) &
705                 0x03;
706         line4 =
707             ((line4 << 1) |
708              GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
709             0x07;
710         line5 = ((line5 << 1) |
711                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
712                                        h - GRREFERENCEDY + 1)) &
713                 0x07;
714       }
715     }
716   }
717   return GRREG;
718 }
719 CJBig2_Image* CJBig2_GRRDProc::decode_Template0_opt(
720     CJBig2_ArithDecoder* pArithDecoder,
721     JBig2ArithCtx* grContext) {
722   if (!GRREFERENCE->m_pData)
723     return nullptr;
724
725   FX_BOOL LTP, SLTP, bVal;
726   FX_DWORD CONTEXT;
727   FX_DWORD line1, line1_r, line2_r, line3_r;
728   uint8_t *pLine, *pLineR, cVal;
729   intptr_t nStride, nStrideR, nOffset;
730   int32_t k, nBits;
731   int32_t GRWR, GRHR;
732   int32_t GRW, GRH;
733   GRW = (int32_t)CJBig2_GRRDProc::GRW;
734   GRH = (int32_t)CJBig2_GRRDProc::GRH;
735   LTP = 0;
736   CJBig2_Image* GRREG = new CJBig2_Image(GRW, GRH);
737   if (GRREG->m_pData == NULL) {
738     delete GRREG;
739     return NULL;
740   }
741   pLine = GRREG->m_pData;
742   pLineR = GRREFERENCE->m_pData;
743   nStride = GRREG->m_nStride;
744   nStrideR = GRREFERENCE->m_nStride;
745   GRWR = (int32_t)GRREFERENCE->m_nWidth;
746   GRHR = (int32_t)GRREFERENCE->m_nHeight;
747   if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
748     GRREFERENCEDY = 0;
749   }
750   nOffset = -GRREFERENCEDY * nStrideR;
751   for (int32_t h = 0; h < GRH; h++) {
752     if (TPGRON) {
753       SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
754       LTP = LTP ^ SLTP;
755     }
756     line1 = (h > 0) ? pLine[-nStride] << 4 : 0;
757     int32_t reference_h = h - GRREFERENCEDY;
758     FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
759     FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
760     FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
761     line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
762     line2_r = line2_r_ok ? pLineR[nOffset] : 0;
763     line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
764     if (LTP == 0) {
765       CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0) |
766                 ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
767       for (int32_t w = 0; w < GRW; w += 8) {
768         nBits = GRW - w > 8 ? 8 : GRW - w;
769         if (h > 0)
770           line1 = (line1 << 8) |
771                   (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
772         if (h > GRHR + GRREFERENCEDY + 1) {
773           line1_r = 0;
774           line2_r = 0;
775           line3_r = 0;
776         } else {
777           if (line1_r_ok)
778             line1_r =
779                 (line1_r << 8) |
780                 (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
781           if (line2_r_ok)
782             line2_r = (line2_r << 8) |
783                       (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
784           if (line3_r_ok)
785             line3_r =
786                 (line3_r << 8) |
787                 (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
788           else {
789             line3_r = 0;
790           }
791         }
792         cVal = 0;
793         for (k = 0; k < nBits; k++) {
794           bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
795           cVal |= bVal << (7 - k);
796           CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
797                     ((line1 >> (7 - k)) & 0x0400) |
798                     ((line1_r >> (7 - k)) & 0x0040) |
799                     ((line2_r >> (10 - k)) & 0x0008) |
800                     ((line3_r >> (13 - k)) & 0x0001);
801         }
802         pLine[w >> 3] = cVal;
803       }
804     } else {
805       CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0) |
806                 ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
807       for (int32_t w = 0; w < GRW; w += 8) {
808         nBits = GRW - w > 8 ? 8 : GRW - w;
809         if (h > 0)
810           line1 = (line1 << 8) |
811                   (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
812         if (line1_r_ok)
813           line1_r =
814               (line1_r << 8) |
815               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
816         if (line2_r_ok)
817           line2_r = (line2_r << 8) |
818                     (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
819         if (line3_r_ok)
820           line3_r =
821               (line3_r << 8) |
822               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
823         else {
824           line3_r = 0;
825         }
826         cVal = 0;
827         for (k = 0; k < nBits; k++) {
828           bVal = GRREFERENCE->getPixel(w + k, h);
829           if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1)) &&
830                 (bVal == GRREFERENCE->getPixel(w + k, h - 1)) &&
831                 (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1)) &&
832                 (bVal == GRREFERENCE->getPixel(w + k - 1, h)) &&
833                 (bVal == GRREFERENCE->getPixel(w + k + 1, h)) &&
834                 (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1)) &&
835                 (bVal == GRREFERENCE->getPixel(w + k, h + 1)) &&
836                 (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
837             bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
838           }
839           cVal |= bVal << (7 - k);
840           CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
841                     ((line1 >> (7 - k)) & 0x0400) |
842                     ((line1_r >> (7 - k)) & 0x0040) |
843                     ((line2_r >> (10 - k)) & 0x0008) |
844                     ((line3_r >> (13 - k)) & 0x0001);
845         }
846         pLine[w >> 3] = cVal;
847       }
848     }
849     pLine += nStride;
850     if (h < GRHR + GRREFERENCEDY) {
851       pLineR += nStrideR;
852     }
853   }
854   return GRREG;
855 }
856 CJBig2_Image* CJBig2_GRRDProc::decode_Template1_unopt(
857     CJBig2_ArithDecoder* pArithDecoder,
858     JBig2ArithCtx* grContext) {
859   FX_BOOL LTP, SLTP, bVal;
860   FX_DWORD CONTEXT;
861   FX_DWORD line1, line2, line3, line4, line5;
862   LTP = 0;
863   CJBig2_Image* GRREG = new CJBig2_Image(GRW, GRH);
864   GRREG->fill(0);
865   for (FX_DWORD h = 0; h < GRH; h++) {
866     if (TPGRON) {
867       SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
868       LTP = LTP ^ SLTP;
869     }
870     if (LTP == 0) {
871       line1 = GRREG->getPixel(1, h - 1);
872       line1 |= GRREG->getPixel(0, h - 1) << 1;
873       line1 |= GRREG->getPixel(-1, h - 1) << 2;
874       line2 = 0;
875       line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
876       line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
877       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
878       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
879                << 2;
880       line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
881       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
882                << 1;
883       for (FX_DWORD w = 0; w < GRW; w++) {
884         CONTEXT = line5;
885         CONTEXT |= line4 << 2;
886         CONTEXT |= line3 << 5;
887         CONTEXT |= line2 << 6;
888         CONTEXT |= line1 << 7;
889         bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
890         GRREG->setPixel(w, h, bVal);
891         line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
892         line2 = ((line2 << 1) | bVal) & 0x01;
893         line3 = ((line3 << 1) |
894                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 1,
895                                        h - GRREFERENCEDY - 1)) &
896                 0x01;
897         line4 =
898             ((line4 << 1) |
899              GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
900             0x07;
901         line5 = ((line5 << 1) |
902                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
903                                        h - GRREFERENCEDY + 1)) &
904                 0x03;
905       }
906     } else {
907       line1 = GRREG->getPixel(1, h - 1);
908       line1 |= GRREG->getPixel(0, h - 1) << 1;
909       line1 |= GRREG->getPixel(-1, h - 1) << 2;
910       line2 = 0;
911       line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
912       line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
913       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
914       line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY)
915                << 2;
916       line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
917       line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1)
918                << 1;
919       for (FX_DWORD w = 0; w < GRW; w++) {
920         bVal = GRREFERENCE->getPixel(w, h);
921         if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1)) &&
922               (bVal == GRREFERENCE->getPixel(w, h - 1)) &&
923               (bVal == GRREFERENCE->getPixel(w + 1, h - 1)) &&
924               (bVal == GRREFERENCE->getPixel(w - 1, h)) &&
925               (bVal == GRREFERENCE->getPixel(w + 1, h)) &&
926               (bVal == GRREFERENCE->getPixel(w - 1, h + 1)) &&
927               (bVal == GRREFERENCE->getPixel(w, h + 1)) &&
928               (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
929           CONTEXT = line5;
930           CONTEXT |= line4 << 2;
931           CONTEXT |= line3 << 5;
932           CONTEXT |= line2 << 6;
933           CONTEXT |= line1 << 7;
934           bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
935         }
936         GRREG->setPixel(w, h, bVal);
937         line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
938         line2 = ((line2 << 1) | bVal) & 0x01;
939         line3 = ((line3 << 1) |
940                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 1,
941                                        h - GRREFERENCEDY - 1)) &
942                 0x01;
943         line4 =
944             ((line4 << 1) |
945              GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) &
946             0x07;
947         line5 = ((line5 << 1) |
948                  GRREFERENCE->getPixel(w - GRREFERENCEDX + 2,
949                                        h - GRREFERENCEDY + 1)) &
950                 0x03;
951       }
952     }
953   }
954   return GRREG;
955 }
956 CJBig2_Image* CJBig2_GRRDProc::decode_Template1_opt(
957     CJBig2_ArithDecoder* pArithDecoder,
958     JBig2ArithCtx* grContext) {
959   if (!GRREFERENCE->m_pData)
960     return nullptr;
961
962   FX_BOOL LTP, SLTP, bVal;
963   FX_DWORD CONTEXT;
964   FX_DWORD line1, line1_r, line2_r, line3_r;
965   uint8_t *pLine, *pLineR, cVal;
966   intptr_t nStride, nStrideR, nOffset;
967   int32_t k, nBits;
968   int32_t GRWR, GRHR;
969   int32_t GRW, GRH;
970   GRW = (int32_t)CJBig2_GRRDProc::GRW;
971   GRH = (int32_t)CJBig2_GRRDProc::GRH;
972   LTP = 0;
973   CJBig2_Image* GRREG = new CJBig2_Image(GRW, GRH);
974   if (GRREG->m_pData == NULL) {
975     delete GRREG;
976     return NULL;
977   }
978   pLine = GRREG->m_pData;
979   pLineR = GRREFERENCE->m_pData;
980   nStride = GRREG->m_nStride;
981   nStrideR = GRREFERENCE->m_nStride;
982   GRWR = (int32_t)GRREFERENCE->m_nWidth;
983   GRHR = (int32_t)GRREFERENCE->m_nHeight;
984   if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
985     GRREFERENCEDY = 0;
986   }
987   nOffset = -GRREFERENCEDY * nStrideR;
988   for (int32_t h = 0; h < GRH; h++) {
989     if (TPGRON) {
990       SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
991       LTP = LTP ^ SLTP;
992     }
993     line1 = (h > 0) ? pLine[-nStride] << 1 : 0;
994     int32_t reference_h = h - GRREFERENCEDY;
995     FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
996     FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
997     FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
998     line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
999     line2_r = line2_r_ok ? pLineR[nOffset] : 0;
1000     line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
1001     if (LTP == 0) {
1002       CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020) |
1003                 ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
1004       for (int32_t w = 0; w < GRW; w += 8) {
1005         nBits = GRW - w > 8 ? 8 : GRW - w;
1006         if (h > 0)
1007           line1 = (line1 << 8) |
1008                   (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
1009         if (line1_r_ok)
1010           line1_r =
1011               (line1_r << 8) |
1012               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1013         if (line2_r_ok)
1014           line2_r = (line2_r << 8) |
1015                     (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1016         if (line3_r_ok)
1017           line3_r =
1018               (line3_r << 8) |
1019               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1020         else {
1021           line3_r = 0;
1022         }
1023         cVal = 0;
1024         for (k = 0; k < nBits; k++) {
1025           bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1026           cVal |= bVal << (7 - k);
1027           CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
1028                     ((line1 >> (7 - k)) & 0x0080) |
1029                     ((line1_r >> (9 - k)) & 0x0020) |
1030                     ((line2_r >> (11 - k)) & 0x0004) |
1031                     ((line3_r >> (13 - k)) & 0x0001);
1032         }
1033         pLine[w >> 3] = cVal;
1034       }
1035     } else {
1036       CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020) |
1037                 ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
1038       for (int32_t w = 0; w < GRW; w += 8) {
1039         nBits = GRW - w > 8 ? 8 : GRW - w;
1040         if (h > 0)
1041           line1 = (line1 << 8) |
1042                   (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
1043         if (line1_r_ok)
1044           line1_r =
1045               (line1_r << 8) |
1046               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1047         if (line2_r_ok)
1048           line2_r = (line2_r << 8) |
1049                     (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1050         if (line3_r_ok)
1051           line3_r =
1052               (line3_r << 8) |
1053               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1054         else {
1055           line3_r = 0;
1056         }
1057         cVal = 0;
1058         for (k = 0; k < nBits; k++) {
1059           bVal = GRREFERENCE->getPixel(w + k, h);
1060           if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1)) &&
1061                 (bVal == GRREFERENCE->getPixel(w + k, h - 1)) &&
1062                 (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1)) &&
1063                 (bVal == GRREFERENCE->getPixel(w + k - 1, h)) &&
1064                 (bVal == GRREFERENCE->getPixel(w + k + 1, h)) &&
1065                 (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1)) &&
1066                 (bVal == GRREFERENCE->getPixel(w + k, h + 1)) &&
1067                 (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
1068             bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1069           }
1070           cVal |= bVal << (7 - k);
1071           CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
1072                     ((line1 >> (7 - k)) & 0x0080) |
1073                     ((line1_r >> (9 - k)) & 0x0020) |
1074                     ((line2_r >> (11 - k)) & 0x0004) |
1075                     ((line3_r >> (13 - k)) & 0x0001);
1076         }
1077         pLine[w >> 3] = cVal;
1078       }
1079     }
1080     pLine += nStride;
1081     if (h < GRHR + GRREFERENCEDY) {
1082       pLineR += nStrideR;
1083     }
1084   }
1085   return GRREG;
1086 }
1087
1088 CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream,
1089                                              JBig2ArithCtx* grContext) {
1090   int32_t STRIPT, FIRSTS;
1091   FX_DWORD NINSTANCES;
1092   int32_t DT, DFS, CURS;
1093   uint8_t CURT;
1094   int32_t SI, TI;
1095   FX_DWORD IDI;
1096   CJBig2_Image* IBI;
1097   FX_DWORD WI, HI;
1098   int32_t IDS;
1099   FX_BOOL RI;
1100   int32_t RDWI, RDHI, RDXI, RDYI;
1101   CJBig2_Image* IBOI;
1102   FX_DWORD WOI, HOI;
1103   FX_BOOL bFirst;
1104   FX_DWORD nTmp;
1105   int32_t nVal, nBits;
1106   CJBig2_GRRDProc* pGRRD;
1107   CJBig2_ArithDecoder* pArithDecoder;
1108   CJBig2_HuffmanDecoder* pHuffmanDecoder = new CJBig2_HuffmanDecoder(pStream);
1109   CJBig2_Image* SBREG = new CJBig2_Image(SBW, SBH);
1110   SBREG->fill(SBDEFPIXEL);
1111   if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0) {
1112     goto failed;
1113   }
1114   STRIPT *= SBSTRIPS;
1115   STRIPT = -STRIPT;
1116   FIRSTS = 0;
1117   NINSTANCES = 0;
1118   while (NINSTANCES < SBNUMINSTANCES) {
1119     if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0) {
1120       goto failed;
1121     }
1122     DT *= SBSTRIPS;
1123     STRIPT = STRIPT + DT;
1124     bFirst = TRUE;
1125     for (;;) {
1126       if (bFirst) {
1127         if (pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0) {
1128           goto failed;
1129         }
1130         FIRSTS = FIRSTS + DFS;
1131         CURS = FIRSTS;
1132         bFirst = FALSE;
1133       } else {
1134         nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS);
1135         if (nVal == JBIG2_OOB) {
1136           break;
1137         } else if (nVal != 0) {
1138           goto failed;
1139         } else {
1140           CURS = CURS + IDS + SBDSOFFSET;
1141         }
1142       }
1143       if (SBSTRIPS == 1) {
1144         CURT = 0;
1145       } else {
1146         nTmp = 1;
1147         while ((FX_DWORD)(1 << nTmp) < SBSTRIPS) {
1148           nTmp++;
1149         }
1150         if (pStream->readNBits(nTmp, &nVal) != 0) {
1151           goto failed;
1152         }
1153         CURT = nVal;
1154       }
1155       TI = STRIPT + CURT;
1156       nVal = 0;
1157       nBits = 0;
1158       for (;;) {
1159         if (pStream->read1Bit(&nTmp) != 0) {
1160           goto failed;
1161         }
1162         nVal = (nVal << 1) | nTmp;
1163         nBits++;
1164         for (IDI = 0; IDI < SBNUMSYMS; IDI++) {
1165           if ((nBits == SBSYMCODES[IDI].codelen) &&
1166               (nVal == SBSYMCODES[IDI].code)) {
1167             break;
1168           }
1169         }
1170         if (IDI < SBNUMSYMS) {
1171           break;
1172         }
1173       }
1174       if (SBREFINE == 0) {
1175         RI = 0;
1176       } else {
1177         if (pStream->read1Bit(&RI) != 0) {
1178           goto failed;
1179         }
1180       }
1181       if (RI == 0) {
1182         IBI = SBSYMS[IDI];
1183       } else {
1184         if ((pHuffmanDecoder->decodeAValue(SBHUFFRDW, &RDWI) != 0) ||
1185             (pHuffmanDecoder->decodeAValue(SBHUFFRDH, &RDHI) != 0) ||
1186             (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0) ||
1187             (pHuffmanDecoder->decodeAValue(SBHUFFRDY, &RDYI) != 0) ||
1188             (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
1189           goto failed;
1190         }
1191         pStream->alignByte();
1192         nTmp = pStream->getOffset();
1193         IBOI = SBSYMS[IDI];
1194         if (!IBOI) {
1195           goto failed;
1196         }
1197         WOI = IBOI->m_nWidth;
1198         HOI = IBOI->m_nHeight;
1199         if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
1200           goto failed;
1201         }
1202         pGRRD = new CJBig2_GRRDProc();
1203         pGRRD->GRW = WOI + RDWI;
1204         pGRRD->GRH = HOI + RDHI;
1205         pGRRD->GRTEMPLATE = SBRTEMPLATE;
1206         pGRRD->GRREFERENCE = IBOI;
1207         pGRRD->GRREFERENCEDX = (RDWI >> 2) + RDXI;
1208         pGRRD->GRREFERENCEDY = (RDHI >> 2) + RDYI;
1209         pGRRD->TPGRON = 0;
1210         pGRRD->GRAT[0] = SBRAT[0];
1211         pGRRD->GRAT[1] = SBRAT[1];
1212         pGRRD->GRAT[2] = SBRAT[2];
1213         pGRRD->GRAT[3] = SBRAT[3];
1214         pArithDecoder = new CJBig2_ArithDecoder(pStream);
1215         IBI = pGRRD->decode(pArithDecoder, grContext);
1216         if (IBI == NULL) {
1217           delete pGRRD;
1218           delete pArithDecoder;
1219           goto failed;
1220         }
1221         delete pArithDecoder;
1222         pStream->alignByte();
1223         pStream->offset(2);
1224         if ((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
1225           delete IBI;
1226           delete pGRRD;
1227           goto failed;
1228         }
1229         delete pGRRD;
1230       }
1231       if (!IBI) {
1232         continue;
1233       }
1234       WI = IBI->m_nWidth;
1235       HI = IBI->m_nHeight;
1236       if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
1237                               (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
1238         CURS = CURS + WI - 1;
1239       } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) ||
1240                                      (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
1241         CURS = CURS + HI - 1;
1242       }
1243       SI = CURS;
1244       if (TRANSPOSED == 0) {
1245         switch (REFCORNER) {
1246           case JBIG2_CORNER_TOPLEFT:
1247             SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
1248             break;
1249           case JBIG2_CORNER_TOPRIGHT:
1250             SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
1251             break;
1252           case JBIG2_CORNER_BOTTOMLEFT:
1253             SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
1254             break;
1255           case JBIG2_CORNER_BOTTOMRIGHT:
1256             SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
1257             break;
1258         }
1259       } else {
1260         switch (REFCORNER) {
1261           case JBIG2_CORNER_TOPLEFT:
1262             SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
1263             break;
1264           case JBIG2_CORNER_TOPRIGHT:
1265             SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
1266             break;
1267           case JBIG2_CORNER_BOTTOMLEFT:
1268             SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
1269             break;
1270           case JBIG2_CORNER_BOTTOMRIGHT:
1271             SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
1272             break;
1273         }
1274       }
1275       if (RI != 0) {
1276         delete IBI;
1277       }
1278       if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
1279                               (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
1280         CURS = CURS + WI - 1;
1281       } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
1282                                      (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
1283         CURS = CURS + HI - 1;
1284       }
1285       NINSTANCES = NINSTANCES + 1;
1286     }
1287   }
1288   delete pHuffmanDecoder;
1289   return SBREG;
1290 failed:
1291   delete pHuffmanDecoder;
1292   delete SBREG;
1293   return NULL;
1294 }
1295 CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
1296                                            JBig2ArithCtx* grContext,
1297                                            JBig2IntDecoderState* pIDS) {
1298   int32_t STRIPT, FIRSTS;
1299   FX_DWORD NINSTANCES;
1300   int32_t DT, DFS, CURS;
1301   int32_t CURT;
1302   int32_t SI, TI;
1303   FX_DWORD IDI;
1304   CJBig2_Image* IBI;
1305   FX_DWORD WI, HI;
1306   int32_t IDS;
1307   int RI;
1308   int32_t RDWI, RDHI, RDXI, RDYI;
1309   CJBig2_Image* IBOI;
1310   FX_DWORD WOI, HOI;
1311   CJBig2_Image* SBREG;
1312   FX_BOOL bFirst;
1313   int32_t nRet, nVal;
1314   int32_t bRetained;
1315   CJBig2_ArithIntDecoder *IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH,
1316       *IARDX, *IARDY;
1317   CJBig2_ArithIaidDecoder* IAID;
1318   CJBig2_GRRDProc* pGRRD;
1319   if (pIDS) {
1320     IADT = pIDS->IADT;
1321     IAFS = pIDS->IAFS;
1322     IADS = pIDS->IADS;
1323     IAIT = pIDS->IAIT;
1324     IARI = pIDS->IARI;
1325     IARDW = pIDS->IARDW;
1326     IARDH = pIDS->IARDH;
1327     IARDX = pIDS->IARDX;
1328     IARDY = pIDS->IARDY;
1329     IAID = pIDS->IAID;
1330     bRetained = TRUE;
1331   } else {
1332     IADT = new CJBig2_ArithIntDecoder();
1333     IAFS = new CJBig2_ArithIntDecoder();
1334     IADS = new CJBig2_ArithIntDecoder();
1335     IAIT = new CJBig2_ArithIntDecoder();
1336     IARI = new CJBig2_ArithIntDecoder();
1337     IARDW = new CJBig2_ArithIntDecoder();
1338     IARDH = new CJBig2_ArithIntDecoder();
1339     IARDX = new CJBig2_ArithIntDecoder();
1340     IARDY = new CJBig2_ArithIntDecoder();
1341     IAID = new CJBig2_ArithIaidDecoder(SBSYMCODELEN);
1342     bRetained = FALSE;
1343   }
1344   SBREG = new CJBig2_Image(SBW, SBH);
1345   SBREG->fill(SBDEFPIXEL);
1346   if (IADT->decode(pArithDecoder, &STRIPT) == -1) {
1347     goto failed;
1348   }
1349   STRIPT *= SBSTRIPS;
1350   STRIPT = -STRIPT;
1351   FIRSTS = 0;
1352   NINSTANCES = 0;
1353   while (NINSTANCES < SBNUMINSTANCES) {
1354     if (IADT->decode(pArithDecoder, &DT) == -1) {
1355       goto failed;
1356     }
1357     DT *= SBSTRIPS;
1358     STRIPT = STRIPT + DT;
1359     bFirst = TRUE;
1360     for (;;) {
1361       if (bFirst) {
1362         if (IAFS->decode(pArithDecoder, &DFS) == -1) {
1363           goto failed;
1364         }
1365         FIRSTS = FIRSTS + DFS;
1366         CURS = FIRSTS;
1367         bFirst = FALSE;
1368       } else {
1369         nRet = IADS->decode(pArithDecoder, &IDS);
1370         if (nRet == JBIG2_OOB) {
1371           break;
1372         } else if (nRet != 0) {
1373           goto failed;
1374         } else {
1375           CURS = CURS + IDS + SBDSOFFSET;
1376         }
1377       }
1378       if (NINSTANCES >= SBNUMINSTANCES) {
1379         break;
1380       }
1381       if (SBSTRIPS == 1) {
1382         CURT = 0;
1383       } else {
1384         if (IAIT->decode(pArithDecoder, &nVal) == -1) {
1385           goto failed;
1386         }
1387         CURT = nVal;
1388       }
1389       TI = STRIPT + CURT;
1390       if (IAID->decode(pArithDecoder, &nVal) == -1) {
1391         goto failed;
1392       }
1393       IDI = nVal;
1394       if (IDI >= SBNUMSYMS) {
1395         goto failed;
1396       }
1397       if (SBREFINE == 0) {
1398         RI = 0;
1399       } else {
1400         if (IARI->decode(pArithDecoder, &RI) == -1) {
1401           goto failed;
1402         }
1403       }
1404       if (!SBSYMS[IDI]) {
1405         goto failed;
1406       }
1407       if (RI == 0) {
1408         IBI = SBSYMS[IDI];
1409       } else {
1410         if ((IARDW->decode(pArithDecoder, &RDWI) == -1) ||
1411             (IARDH->decode(pArithDecoder, &RDHI) == -1) ||
1412             (IARDX->decode(pArithDecoder, &RDXI) == -1) ||
1413             (IARDY->decode(pArithDecoder, &RDYI) == -1)) {
1414           goto failed;
1415         }
1416         IBOI = SBSYMS[IDI];
1417         WOI = IBOI->m_nWidth;
1418         HOI = IBOI->m_nHeight;
1419         if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
1420           goto failed;
1421         }
1422         pGRRD = new CJBig2_GRRDProc();
1423         pGRRD->GRW = WOI + RDWI;
1424         pGRRD->GRH = HOI + RDHI;
1425         pGRRD->GRTEMPLATE = SBRTEMPLATE;
1426         pGRRD->GRREFERENCE = IBOI;
1427         pGRRD->GRREFERENCEDX = (RDWI >> 1) + RDXI;
1428         pGRRD->GRREFERENCEDY = (RDHI >> 1) + RDYI;
1429         pGRRD->TPGRON = 0;
1430         pGRRD->GRAT[0] = SBRAT[0];
1431         pGRRD->GRAT[1] = SBRAT[1];
1432         pGRRD->GRAT[2] = SBRAT[2];
1433         pGRRD->GRAT[3] = SBRAT[3];
1434         IBI = pGRRD->decode(pArithDecoder, grContext);
1435         if (IBI == NULL) {
1436           delete pGRRD;
1437           goto failed;
1438         }
1439         delete pGRRD;
1440       }
1441       WI = IBI->m_nWidth;
1442       HI = IBI->m_nHeight;
1443       if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
1444                               (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
1445         CURS = CURS + WI - 1;
1446       } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) ||
1447                                      (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
1448         CURS = CURS + HI - 1;
1449       }
1450       SI = CURS;
1451       if (TRANSPOSED == 0) {
1452         switch (REFCORNER) {
1453           case JBIG2_CORNER_TOPLEFT:
1454             SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
1455             break;
1456           case JBIG2_CORNER_TOPRIGHT:
1457             SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
1458             break;
1459           case JBIG2_CORNER_BOTTOMLEFT:
1460             SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
1461             break;
1462           case JBIG2_CORNER_BOTTOMRIGHT:
1463             SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
1464             break;
1465         }
1466       } else {
1467         switch (REFCORNER) {
1468           case JBIG2_CORNER_TOPLEFT:
1469             SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
1470             break;
1471           case JBIG2_CORNER_TOPRIGHT:
1472             SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
1473             break;
1474           case JBIG2_CORNER_BOTTOMLEFT:
1475             SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
1476             break;
1477           case JBIG2_CORNER_BOTTOMRIGHT:
1478             SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
1479             break;
1480         }
1481       }
1482       if (RI != 0) {
1483         delete IBI;
1484       }
1485       if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
1486                               (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
1487         CURS = CURS + WI - 1;
1488       } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
1489                                      (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
1490         CURS = CURS + HI - 1;
1491       }
1492       NINSTANCES = NINSTANCES + 1;
1493     }
1494   }
1495   if (bRetained == FALSE) {
1496     delete IADT;
1497     delete IAFS;
1498     delete IADS;
1499     delete IAIT;
1500     delete IARI;
1501     delete IARDW;
1502     delete IARDH;
1503     delete IARDX;
1504     delete IARDY;
1505     delete IAID;
1506   }
1507   return SBREG;
1508 failed:
1509   if (bRetained == FALSE) {
1510     delete IADT;
1511     delete IAFS;
1512     delete IADS;
1513     delete IAIT;
1514     delete IARI;
1515     delete IARDW;
1516     delete IARDH;
1517     delete IARDX;
1518     delete IARDY;
1519     delete IAID;
1520   }
1521   delete SBREG;
1522   return NULL;
1523 }
1524 CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith(
1525     CJBig2_ArithDecoder* pArithDecoder,
1526     JBig2ArithCtx* gbContext,
1527     JBig2ArithCtx* grContext) {
1528   CJBig2_Image** SDNEWSYMS;
1529   FX_DWORD HCHEIGHT, NSYMSDECODED;
1530   int32_t HCDH;
1531   FX_DWORD SYMWIDTH, TOTWIDTH;
1532   int32_t DW;
1533   CJBig2_Image* BS;
1534   FX_DWORD I, J, REFAGGNINST;
1535   FX_BOOL* EXFLAGS;
1536   FX_DWORD EXINDEX;
1537   FX_BOOL CUREXFLAG;
1538   FX_DWORD EXRUNLENGTH;
1539   int32_t nVal;
1540   FX_DWORD nTmp;
1541   FX_DWORD SBNUMSYMS;
1542   uint8_t SBSYMCODELEN;
1543   FX_DWORD IDI;
1544   int32_t RDXI, RDYI;
1545   CJBig2_Image** SBSYMS;
1546   CJBig2_HuffmanTable *SBHUFFFS, *SBHUFFDS, *SBHUFFDT, *SBHUFFRDW, *SBHUFFRDH,
1547       *SBHUFFRDX, *SBHUFFRDY, *SBHUFFRSIZE;
1548   CJBig2_GRRDProc* pGRRD;
1549   CJBig2_GRDProc* pGRD;
1550   CJBig2_ArithIntDecoder *IADH, *IADW, *IAAI, *IARDX, *IARDY, *IAEX, *IADT,
1551       *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH;
1552   CJBig2_ArithIaidDecoder* IAID;
1553   CJBig2_SymbolDict* pDict;
1554   IADH = new CJBig2_ArithIntDecoder();
1555   IADW = new CJBig2_ArithIntDecoder();
1556   IAAI = new CJBig2_ArithIntDecoder();
1557   IARDX = new CJBig2_ArithIntDecoder();
1558   IARDY = new CJBig2_ArithIntDecoder();
1559   IAEX = new CJBig2_ArithIntDecoder();
1560   IADT = new CJBig2_ArithIntDecoder();
1561   IAFS = new CJBig2_ArithIntDecoder();
1562   IADS = new CJBig2_ArithIntDecoder();
1563   IAIT = new CJBig2_ArithIntDecoder();
1564   IARI = new CJBig2_ArithIntDecoder();
1565   IARDW = new CJBig2_ArithIntDecoder();
1566   IARDH = new CJBig2_ArithIntDecoder();
1567   nTmp = 0;
1568   while ((FX_DWORD)(1 << nTmp) < (SDNUMINSYMS + SDNUMNEWSYMS)) {
1569     nTmp++;
1570   }
1571   IAID = new CJBig2_ArithIaidDecoder((uint8_t)nTmp);
1572   SDNEWSYMS = FX_Alloc(CJBig2_Image*, SDNUMNEWSYMS);
1573   FXSYS_memset(SDNEWSYMS, 0, SDNUMNEWSYMS * sizeof(CJBig2_Image*));
1574   HCHEIGHT = 0;
1575   NSYMSDECODED = 0;
1576   while (NSYMSDECODED < SDNUMNEWSYMS) {
1577     BS = NULL;
1578     if (IADH->decode(pArithDecoder, &HCDH) == -1) {
1579       goto failed;
1580     }
1581     HCHEIGHT = HCHEIGHT + HCDH;
1582     if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
1583       goto failed;
1584     }
1585     SYMWIDTH = 0;
1586     TOTWIDTH = 0;
1587     for (;;) {
1588       nVal = IADW->decode(pArithDecoder, &DW);
1589       if (nVal == JBIG2_OOB) {
1590         break;
1591       } else if (nVal != 0) {
1592         goto failed;
1593       } else {
1594         if (NSYMSDECODED >= SDNUMNEWSYMS) {
1595           goto failed;
1596         }
1597         SYMWIDTH = SYMWIDTH + DW;
1598         if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) {
1599           goto failed;
1600         } else if (HCHEIGHT == 0 || SYMWIDTH == 0) {
1601           TOTWIDTH = TOTWIDTH + SYMWIDTH;
1602           SDNEWSYMS[NSYMSDECODED] = NULL;
1603           NSYMSDECODED = NSYMSDECODED + 1;
1604           continue;
1605         }
1606         TOTWIDTH = TOTWIDTH + SYMWIDTH;
1607       }
1608       if (SDREFAGG == 0) {
1609         pGRD = new CJBig2_GRDProc();
1610         pGRD->MMR = 0;
1611         pGRD->GBW = SYMWIDTH;
1612         pGRD->GBH = HCHEIGHT;
1613         pGRD->GBTEMPLATE = SDTEMPLATE;
1614         pGRD->TPGDON = 0;
1615         pGRD->USESKIP = 0;
1616         pGRD->GBAT[0] = SDAT[0];
1617         pGRD->GBAT[1] = SDAT[1];
1618         pGRD->GBAT[2] = SDAT[2];
1619         pGRD->GBAT[3] = SDAT[3];
1620         pGRD->GBAT[4] = SDAT[4];
1621         pGRD->GBAT[5] = SDAT[5];
1622         pGRD->GBAT[6] = SDAT[6];
1623         pGRD->GBAT[7] = SDAT[7];
1624         BS = pGRD->decode_Arith(pArithDecoder, gbContext);
1625         if (BS == NULL) {
1626           delete pGRD;
1627           goto failed;
1628         }
1629         delete pGRD;
1630       } else {
1631         if (IAAI->decode(pArithDecoder, (int*)&REFAGGNINST) == -1) {
1632           goto failed;
1633         }
1634         if (REFAGGNINST > 1) {
1635           CJBig2_TRDProc* pDecoder;
1636           pDecoder = new CJBig2_TRDProc();
1637           pDecoder->SBHUFF = SDHUFF;
1638           pDecoder->SBREFINE = 1;
1639           pDecoder->SBW = SYMWIDTH;
1640           pDecoder->SBH = HCHEIGHT;
1641           pDecoder->SBNUMINSTANCES = REFAGGNINST;
1642           pDecoder->SBSTRIPS = 1;
1643           pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
1644           SBNUMSYMS = pDecoder->SBNUMSYMS;
1645           nTmp = 0;
1646           while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
1647             nTmp++;
1648           }
1649           SBSYMCODELEN = (uint8_t)nTmp;
1650           pDecoder->SBSYMCODELEN = SBSYMCODELEN;
1651           SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
1652           JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
1653           JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
1654                        NSYMSDECODED * sizeof(CJBig2_Image*));
1655           pDecoder->SBSYMS = SBSYMS;
1656           pDecoder->SBDEFPIXEL = 0;
1657           pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
1658           pDecoder->TRANSPOSED = 0;
1659           pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
1660           pDecoder->SBDSOFFSET = 0;
1661           SBHUFFFS = new CJBig2_HuffmanTable(HuffmanTable_B6,
1662                                              FX_ArraySize(HuffmanTable_B6),
1663                                              HuffmanTable_HTOOB_B6);
1664           SBHUFFDS = new CJBig2_HuffmanTable(HuffmanTable_B8,
1665                                              FX_ArraySize(HuffmanTable_B8),
1666                                              HuffmanTable_HTOOB_B8);
1667           SBHUFFDT = new CJBig2_HuffmanTable(HuffmanTable_B11,
1668                                              FX_ArraySize(HuffmanTable_B11),
1669                                              HuffmanTable_HTOOB_B11);
1670           SBHUFFRDW = new CJBig2_HuffmanTable(HuffmanTable_B15,
1671                                               FX_ArraySize(HuffmanTable_B15),
1672                                               HuffmanTable_HTOOB_B15);
1673           SBHUFFRDH = new CJBig2_HuffmanTable(HuffmanTable_B15,
1674                                               FX_ArraySize(HuffmanTable_B15),
1675                                               HuffmanTable_HTOOB_B15);
1676           SBHUFFRDX = new CJBig2_HuffmanTable(HuffmanTable_B15,
1677                                               FX_ArraySize(HuffmanTable_B15),
1678                                               HuffmanTable_HTOOB_B15);
1679           SBHUFFRDY = new CJBig2_HuffmanTable(HuffmanTable_B15,
1680                                               FX_ArraySize(HuffmanTable_B15),
1681                                               HuffmanTable_HTOOB_B15);
1682           SBHUFFRSIZE = new CJBig2_HuffmanTable(HuffmanTable_B1,
1683                                                 FX_ArraySize(HuffmanTable_B1),
1684                                                 HuffmanTable_HTOOB_B1);
1685           pDecoder->SBHUFFFS = SBHUFFFS;
1686           pDecoder->SBHUFFDS = SBHUFFDS;
1687           pDecoder->SBHUFFDT = SBHUFFDT;
1688           pDecoder->SBHUFFRDW = SBHUFFRDW;
1689           pDecoder->SBHUFFRDH = SBHUFFRDH;
1690           pDecoder->SBHUFFRDX = SBHUFFRDX;
1691           pDecoder->SBHUFFRDY = SBHUFFRDY;
1692           pDecoder->SBHUFFRSIZE = SBHUFFRSIZE;
1693           pDecoder->SBRTEMPLATE = SDRTEMPLATE;
1694           pDecoder->SBRAT[0] = SDRAT[0];
1695           pDecoder->SBRAT[1] = SDRAT[1];
1696           pDecoder->SBRAT[2] = SDRAT[2];
1697           pDecoder->SBRAT[3] = SDRAT[3];
1698           JBig2IntDecoderState ids;
1699           ids.IADT = IADT;
1700           ids.IAFS = IAFS;
1701           ids.IADS = IADS;
1702           ids.IAIT = IAIT;
1703           ids.IARI = IARI;
1704           ids.IARDW = IARDW;
1705           ids.IARDH = IARDH;
1706           ids.IARDX = IARDX;
1707           ids.IARDY = IARDY;
1708           ids.IAID = IAID;
1709           BS = pDecoder->decode_Arith(pArithDecoder, grContext, &ids);
1710           if (BS == NULL) {
1711             FX_Free(SBSYMS);
1712             delete SBHUFFFS;
1713             delete SBHUFFDS;
1714             delete SBHUFFDT;
1715             delete SBHUFFRDW;
1716             delete SBHUFFRDH;
1717             delete SBHUFFRDX;
1718             delete SBHUFFRDY;
1719             delete SBHUFFRSIZE;
1720             delete pDecoder;
1721             goto failed;
1722           }
1723           FX_Free(SBSYMS);
1724           delete SBHUFFFS;
1725           delete SBHUFFDS;
1726           delete SBHUFFDT;
1727           delete SBHUFFRDW;
1728           delete SBHUFFRDH;
1729           delete SBHUFFRDX;
1730           delete SBHUFFRDY;
1731           delete SBHUFFRSIZE;
1732           delete pDecoder;
1733         } else if (REFAGGNINST == 1) {
1734           SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
1735           if (IAID->decode(pArithDecoder, (int*)&IDI) == -1) {
1736             goto failed;
1737           }
1738           if ((IARDX->decode(pArithDecoder, &RDXI) == -1) ||
1739               (IARDY->decode(pArithDecoder, &RDYI) == -1)) {
1740             goto failed;
1741           }
1742           if (IDI >= SBNUMSYMS) {
1743             goto failed;
1744           }
1745           SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
1746           JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
1747           JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
1748                        NSYMSDECODED * sizeof(CJBig2_Image*));
1749           if (!SBSYMS[IDI]) {
1750             FX_Free(SBSYMS);
1751             goto failed;
1752           }
1753           pGRRD = new CJBig2_GRRDProc();
1754           pGRRD->GRW = SYMWIDTH;
1755           pGRRD->GRH = HCHEIGHT;
1756           pGRRD->GRTEMPLATE = SDRTEMPLATE;
1757           pGRRD->GRREFERENCE = SBSYMS[IDI];
1758           pGRRD->GRREFERENCEDX = RDXI;
1759           pGRRD->GRREFERENCEDY = RDYI;
1760           pGRRD->TPGRON = 0;
1761           pGRRD->GRAT[0] = SDRAT[0];
1762           pGRRD->GRAT[1] = SDRAT[1];
1763           pGRRD->GRAT[2] = SDRAT[2];
1764           pGRRD->GRAT[3] = SDRAT[3];
1765           BS = pGRRD->decode(pArithDecoder, grContext);
1766           if (BS == NULL) {
1767             FX_Free(SBSYMS);
1768             delete pGRRD;
1769             goto failed;
1770           }
1771           FX_Free(SBSYMS);
1772           delete pGRRD;
1773         }
1774       }
1775       SDNEWSYMS[NSYMSDECODED] = BS;
1776       BS = NULL;
1777       NSYMSDECODED = NSYMSDECODED + 1;
1778     }
1779   }
1780   EXINDEX = 0;
1781   CUREXFLAG = 0;
1782   EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS);
1783   while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
1784     if (IAEX->decode(pArithDecoder, (int*)&EXRUNLENGTH) == -1) {
1785       FX_Free(EXFLAGS);
1786       goto failed;
1787     }
1788     if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) {
1789       FX_Free(EXFLAGS);
1790       goto failed;
1791     }
1792     if (EXRUNLENGTH != 0) {
1793       for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) {
1794         EXFLAGS[I] = CUREXFLAG;
1795       }
1796     }
1797     EXINDEX = EXINDEX + EXRUNLENGTH;
1798     CUREXFLAG = !CUREXFLAG;
1799   }
1800   pDict = new CJBig2_SymbolDict();
1801   pDict->SDNUMEXSYMS = SDNUMEXSYMS;
1802   pDict->SDEXSYMS = FX_Alloc(CJBig2_Image*, SDNUMEXSYMS);
1803   I = J = 0;
1804   for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
1805     if (EXFLAGS[I] && J < SDNUMEXSYMS) {
1806       if (I < SDNUMINSYMS) {
1807         pDict->SDEXSYMS[J] = new CJBig2_Image(*SDINSYMS[I]);
1808       } else {
1809         pDict->SDEXSYMS[J] = SDNEWSYMS[I - SDNUMINSYMS];
1810       }
1811       J = J + 1;
1812     } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
1813       delete SDNEWSYMS[I - SDNUMINSYMS];
1814     }
1815   }
1816   if (J < SDNUMEXSYMS) {
1817     pDict->SDNUMEXSYMS = J;
1818   }
1819   FX_Free(EXFLAGS);
1820   FX_Free(SDNEWSYMS);
1821   delete IADH;
1822   delete IADW;
1823   delete IAAI;
1824   delete IARDX;
1825   delete IARDY;
1826   delete IAEX;
1827   delete IAID;
1828   delete IADT;
1829   delete IAFS;
1830   delete IADS;
1831   delete IAIT;
1832   delete IARI;
1833   delete IARDW;
1834   delete IARDH;
1835   return pDict;
1836 failed:
1837   for (I = 0; I < NSYMSDECODED; I++) {
1838     if (SDNEWSYMS[I]) {
1839       delete SDNEWSYMS[I];
1840       SDNEWSYMS[I] = NULL;
1841     }
1842   }
1843   FX_Free(SDNEWSYMS);
1844   delete IADH;
1845   delete IADW;
1846   delete IAAI;
1847   delete IARDX;
1848   delete IARDY;
1849   delete IAEX;
1850   delete IAID;
1851   delete IADT;
1852   delete IAFS;
1853   delete IADS;
1854   delete IAIT;
1855   delete IARI;
1856   delete IARDW;
1857   delete IARDH;
1858   return NULL;
1859 }
1860 CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman(CJBig2_BitStream* pStream,
1861                                                   JBig2ArithCtx* gbContext,
1862                                                   JBig2ArithCtx* grContext,
1863                                                   IFX_Pause* pPause) {
1864   CJBig2_Image** SDNEWSYMS;
1865   FX_DWORD* SDNEWSYMWIDTHS;
1866   FX_DWORD HCHEIGHT, NSYMSDECODED;
1867   int32_t HCDH;
1868   FX_DWORD SYMWIDTH, TOTWIDTH, HCFIRSTSYM;
1869   int32_t DW;
1870   CJBig2_Image *BS, *BHC;
1871   FX_DWORD I, J, REFAGGNINST;
1872   FX_BOOL* EXFLAGS;
1873   FX_DWORD EXINDEX;
1874   FX_BOOL CUREXFLAG;
1875   FX_DWORD EXRUNLENGTH;
1876   int32_t nVal, nBits;
1877   FX_DWORD nTmp;
1878   FX_DWORD SBNUMSYMS;
1879   uint8_t SBSYMCODELEN;
1880   JBig2HuffmanCode* SBSYMCODES;
1881   FX_DWORD IDI;
1882   int32_t RDXI, RDYI;
1883   FX_DWORD BMSIZE;
1884   FX_DWORD stride;
1885   CJBig2_Image** SBSYMS;
1886   CJBig2_HuffmanTable *SBHUFFFS, *SBHUFFDS, *SBHUFFDT, *SBHUFFRDW, *SBHUFFRDH,
1887       *SBHUFFRDX, *SBHUFFRDY, *SBHUFFRSIZE, *pTable;
1888   CJBig2_HuffmanDecoder* pHuffmanDecoder;
1889   CJBig2_GRRDProc* pGRRD;
1890   CJBig2_ArithDecoder* pArithDecoder;
1891   CJBig2_GRDProc* pGRD;
1892   CJBig2_SymbolDict* pDict;
1893   pHuffmanDecoder = new CJBig2_HuffmanDecoder(pStream);
1894   SDNEWSYMS = FX_Alloc(CJBig2_Image*, SDNUMNEWSYMS);
1895   FXSYS_memset(SDNEWSYMS, 0, SDNUMNEWSYMS * sizeof(CJBig2_Image*));
1896   SDNEWSYMWIDTHS = NULL;
1897   BHC = NULL;
1898   if (SDREFAGG == 0) {
1899     SDNEWSYMWIDTHS = FX_Alloc(FX_DWORD, SDNUMNEWSYMS);
1900     FXSYS_memset(SDNEWSYMWIDTHS, 0, SDNUMNEWSYMS * sizeof(FX_DWORD));
1901   }
1902   HCHEIGHT = 0;
1903   NSYMSDECODED = 0;
1904   BS = NULL;
1905   while (NSYMSDECODED < SDNUMNEWSYMS) {
1906     if (pHuffmanDecoder->decodeAValue(SDHUFFDH, &HCDH) != 0) {
1907       goto failed;
1908     }
1909     HCHEIGHT = HCHEIGHT + HCDH;
1910     if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
1911       goto failed;
1912     }
1913     SYMWIDTH = 0;
1914     TOTWIDTH = 0;
1915     HCFIRSTSYM = NSYMSDECODED;
1916     for (;;) {
1917       nVal = pHuffmanDecoder->decodeAValue(SDHUFFDW, &DW);
1918       if (nVal == JBIG2_OOB) {
1919         break;
1920       } else if (nVal != 0) {
1921         goto failed;
1922       } else {
1923         if (NSYMSDECODED >= SDNUMNEWSYMS) {
1924           goto failed;
1925         }
1926         SYMWIDTH = SYMWIDTH + DW;
1927         if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) {
1928           goto failed;
1929         } else if (HCHEIGHT == 0 || SYMWIDTH == 0) {
1930           TOTWIDTH = TOTWIDTH + SYMWIDTH;
1931           SDNEWSYMS[NSYMSDECODED] = NULL;
1932           NSYMSDECODED = NSYMSDECODED + 1;
1933           continue;
1934         }
1935         TOTWIDTH = TOTWIDTH + SYMWIDTH;
1936       }
1937       if (SDREFAGG == 1) {
1938         if (pHuffmanDecoder->decodeAValue(SDHUFFAGGINST, (int*)&REFAGGNINST) !=
1939             0) {
1940           goto failed;
1941         }
1942         BS = NULL;
1943         if (REFAGGNINST > 1) {
1944           CJBig2_TRDProc* pDecoder = new CJBig2_TRDProc();
1945           pDecoder->SBHUFF = SDHUFF;
1946           pDecoder->SBREFINE = 1;
1947           pDecoder->SBW = SYMWIDTH;
1948           pDecoder->SBH = HCHEIGHT;
1949           pDecoder->SBNUMINSTANCES = REFAGGNINST;
1950           pDecoder->SBSTRIPS = 1;
1951           pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
1952           SBNUMSYMS = pDecoder->SBNUMSYMS;
1953           SBSYMCODES = FX_Alloc(JBig2HuffmanCode, SBNUMSYMS);
1954           nTmp = 1;
1955           while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
1956             nTmp++;
1957           }
1958           for (I = 0; I < SBNUMSYMS; I++) {
1959             SBSYMCODES[I].codelen = nTmp;
1960             SBSYMCODES[I].code = I;
1961           }
1962           pDecoder->SBSYMCODES = SBSYMCODES;
1963           SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
1964           JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
1965           JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
1966                        NSYMSDECODED * sizeof(CJBig2_Image*));
1967           pDecoder->SBSYMS = SBSYMS;
1968           pDecoder->SBDEFPIXEL = 0;
1969           pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
1970           pDecoder->TRANSPOSED = 0;
1971           pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
1972           pDecoder->SBDSOFFSET = 0;
1973           SBHUFFFS = new CJBig2_HuffmanTable(HuffmanTable_B6,
1974                                              FX_ArraySize(HuffmanTable_B6),
1975                                              HuffmanTable_HTOOB_B6);
1976           SBHUFFDS = new CJBig2_HuffmanTable(HuffmanTable_B8,
1977                                              FX_ArraySize(HuffmanTable_B8),
1978                                              HuffmanTable_HTOOB_B8);
1979           SBHUFFDT = new CJBig2_HuffmanTable(HuffmanTable_B11,
1980                                              FX_ArraySize(HuffmanTable_B11),
1981                                              HuffmanTable_HTOOB_B11);
1982           SBHUFFRDW = new CJBig2_HuffmanTable(HuffmanTable_B15,
1983                                               FX_ArraySize(HuffmanTable_B15),
1984                                               HuffmanTable_HTOOB_B15);
1985           SBHUFFRDH = new CJBig2_HuffmanTable(HuffmanTable_B15,
1986                                               FX_ArraySize(HuffmanTable_B15),
1987                                               HuffmanTable_HTOOB_B15);
1988           SBHUFFRDX = new CJBig2_HuffmanTable(HuffmanTable_B15,
1989                                               FX_ArraySize(HuffmanTable_B15),
1990                                               HuffmanTable_HTOOB_B15);
1991           SBHUFFRDY = new CJBig2_HuffmanTable(HuffmanTable_B15,
1992                                               FX_ArraySize(HuffmanTable_B15),
1993                                               HuffmanTable_HTOOB_B15);
1994           SBHUFFRSIZE = new CJBig2_HuffmanTable(HuffmanTable_B1,
1995                                                 FX_ArraySize(HuffmanTable_B1),
1996                                                 HuffmanTable_HTOOB_B1);
1997           pDecoder->SBHUFFFS = SBHUFFFS;
1998           pDecoder->SBHUFFDS = SBHUFFDS;
1999           pDecoder->SBHUFFDT = SBHUFFDT;
2000           pDecoder->SBHUFFRDW = SBHUFFRDW;
2001           pDecoder->SBHUFFRDH = SBHUFFRDH;
2002           pDecoder->SBHUFFRDX = SBHUFFRDX;
2003           pDecoder->SBHUFFRDY = SBHUFFRDY;
2004           pDecoder->SBHUFFRSIZE = SBHUFFRSIZE;
2005           pDecoder->SBRTEMPLATE = SDRTEMPLATE;
2006           pDecoder->SBRAT[0] = SDRAT[0];
2007           pDecoder->SBRAT[1] = SDRAT[1];
2008           pDecoder->SBRAT[2] = SDRAT[2];
2009           pDecoder->SBRAT[3] = SDRAT[3];
2010           BS = pDecoder->decode_Huffman(pStream, grContext);
2011           if (BS == NULL) {
2012             FX_Free(SBSYMCODES);
2013             FX_Free(SBSYMS);
2014             delete SBHUFFFS;
2015             delete SBHUFFDS;
2016             delete SBHUFFDT;
2017             delete SBHUFFRDW;
2018             delete SBHUFFRDH;
2019             delete SBHUFFRDX;
2020             delete SBHUFFRDY;
2021             delete SBHUFFRSIZE;
2022             delete pDecoder;
2023             goto failed;
2024           }
2025           FX_Free(SBSYMCODES);
2026           FX_Free(SBSYMS);
2027           delete SBHUFFFS;
2028           delete SBHUFFDS;
2029           delete SBHUFFDT;
2030           delete SBHUFFRDW;
2031           delete SBHUFFRDH;
2032           delete SBHUFFRDX;
2033           delete SBHUFFRDY;
2034           delete SBHUFFRSIZE;
2035           delete pDecoder;
2036         } else if (REFAGGNINST == 1) {
2037           SBNUMSYMS = SDNUMINSYMS + SDNUMNEWSYMS;
2038           nTmp = 1;
2039           while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
2040             nTmp++;
2041           }
2042           SBSYMCODELEN = (uint8_t)nTmp;
2043           SBSYMCODES = FX_Alloc(JBig2HuffmanCode, SBNUMSYMS);
2044           for (I = 0; I < SBNUMSYMS; I++) {
2045             SBSYMCODES[I].codelen = SBSYMCODELEN;
2046             SBSYMCODES[I].code = I;
2047           }
2048           nVal = 0;
2049           nBits = 0;
2050           for (;;) {
2051             if (pStream->read1Bit(&nTmp) != 0) {
2052               FX_Free(SBSYMCODES);
2053               goto failed;
2054             }
2055             nVal = (nVal << 1) | nTmp;
2056             for (IDI = 0; IDI < SBNUMSYMS; IDI++) {
2057               if ((nVal == SBSYMCODES[IDI].code) &&
2058                   (nBits == SBSYMCODES[IDI].codelen)) {
2059                 break;
2060               }
2061             }
2062             if (IDI < SBNUMSYMS) {
2063               break;
2064             }
2065           }
2066           FX_Free(SBSYMCODES);
2067           SBHUFFRDX = new CJBig2_HuffmanTable(HuffmanTable_B15,
2068                                               FX_ArraySize(HuffmanTable_B15),
2069                                               HuffmanTable_HTOOB_B15);
2070           SBHUFFRSIZE = new CJBig2_HuffmanTable(HuffmanTable_B1,
2071                                                 FX_ArraySize(HuffmanTable_B1),
2072                                                 HuffmanTable_HTOOB_B1);
2073           if ((pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0) ||
2074               (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDYI) != 0) ||
2075               (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
2076             delete SBHUFFRDX;
2077             delete SBHUFFRSIZE;
2078             goto failed;
2079           }
2080           delete SBHUFFRDX;
2081           delete SBHUFFRSIZE;
2082           pStream->alignByte();
2083           nTmp = pStream->getOffset();
2084           SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
2085           JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2086           JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
2087                        NSYMSDECODED * sizeof(CJBig2_Image*));
2088           pGRRD = new CJBig2_GRRDProc();
2089           pGRRD->GRW = SYMWIDTH;
2090           pGRRD->GRH = HCHEIGHT;
2091           pGRRD->GRTEMPLATE = SDRTEMPLATE;
2092           pGRRD->GRREFERENCE = SBSYMS[IDI];
2093           pGRRD->GRREFERENCEDX = RDXI;
2094           pGRRD->GRREFERENCEDY = RDYI;
2095           pGRRD->TPGRON = 0;
2096           pGRRD->GRAT[0] = SDRAT[0];
2097           pGRRD->GRAT[1] = SDRAT[1];
2098           pGRRD->GRAT[2] = SDRAT[2];
2099           pGRRD->GRAT[3] = SDRAT[3];
2100           pArithDecoder = new CJBig2_ArithDecoder(pStream);
2101           BS = pGRRD->decode(pArithDecoder, grContext);
2102           if (BS == NULL) {
2103             FX_Free(SBSYMS);
2104             delete pGRRD;
2105             delete pArithDecoder;
2106             goto failed;
2107           }
2108           pStream->alignByte();
2109           pStream->offset(2);
2110           if ((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
2111             delete BS;
2112             FX_Free(SBSYMS);
2113             delete pGRRD;
2114             delete pArithDecoder;
2115             goto failed;
2116           }
2117           FX_Free(SBSYMS);
2118           delete pGRRD;
2119           delete pArithDecoder;
2120         }
2121         SDNEWSYMS[NSYMSDECODED] = BS;
2122       }
2123       if (SDREFAGG == 0) {
2124         SDNEWSYMWIDTHS[NSYMSDECODED] = SYMWIDTH;
2125       }
2126       NSYMSDECODED = NSYMSDECODED + 1;
2127     }
2128     if (SDREFAGG == 0) {
2129       if (pHuffmanDecoder->decodeAValue(SDHUFFBMSIZE, (int32_t*)&BMSIZE) != 0) {
2130         goto failed;
2131       }
2132       pStream->alignByte();
2133       if (BMSIZE == 0) {
2134         stride = (TOTWIDTH + 7) >> 3;
2135         if (pStream->getByteLeft() >= stride * HCHEIGHT) {
2136           BHC = new CJBig2_Image(TOTWIDTH, HCHEIGHT);
2137           for (I = 0; I < HCHEIGHT; I++) {
2138             JBIG2_memcpy(BHC->m_pData + I * BHC->m_nStride,
2139                          pStream->getPointer(), stride);
2140             pStream->offset(stride);
2141           }
2142         } else {
2143           goto failed;
2144         }
2145       } else {
2146         pGRD = new CJBig2_GRDProc();
2147         pGRD->MMR = 1;
2148         pGRD->GBW = TOTWIDTH;
2149         pGRD->GBH = HCHEIGHT;
2150         FXCODEC_STATUS status = pGRD->Start_decode_MMR(&BHC, pStream);
2151         while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
2152           pGRD->Continue_decode(pPause);
2153         }
2154         delete pGRD;
2155         pStream->alignByte();
2156       }
2157       nTmp = 0;
2158       if (!BHC) {
2159         continue;
2160       }
2161       for (I = HCFIRSTSYM; I < NSYMSDECODED; I++) {
2162         SDNEWSYMS[I] = BHC->subImage(nTmp, 0, SDNEWSYMWIDTHS[I], HCHEIGHT);
2163         nTmp += SDNEWSYMWIDTHS[I];
2164       }
2165       delete BHC;
2166       BHC = NULL;
2167     }
2168   }
2169   EXINDEX = 0;
2170   CUREXFLAG = 0;
2171   pTable = new CJBig2_HuffmanTable(
2172       HuffmanTable_B1, FX_ArraySize(HuffmanTable_B1), HuffmanTable_HTOOB_B1);
2173   EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS);
2174   while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
2175     if (pHuffmanDecoder->decodeAValue(pTable, (int*)&EXRUNLENGTH) != 0) {
2176       delete pTable;
2177       FX_Free(EXFLAGS);
2178       goto failed;
2179     }
2180     if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) {
2181       delete pTable;
2182       FX_Free(EXFLAGS);
2183       goto failed;
2184     }
2185     if (EXRUNLENGTH != 0) {
2186       for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) {
2187         EXFLAGS[I] = CUREXFLAG;
2188       }
2189     }
2190     EXINDEX = EXINDEX + EXRUNLENGTH;
2191     CUREXFLAG = !CUREXFLAG;
2192   }
2193   delete pTable;
2194   pDict = new CJBig2_SymbolDict();
2195   pDict->SDNUMEXSYMS = SDNUMEXSYMS;
2196   pDict->SDEXSYMS = FX_Alloc(CJBig2_Image*, SDNUMEXSYMS);
2197   I = J = 0;
2198   for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
2199     if (EXFLAGS[I] && J < SDNUMEXSYMS) {
2200       if (I < SDNUMINSYMS) {
2201         pDict->SDEXSYMS[J] = new CJBig2_Image(*SDINSYMS[I]);
2202       } else {
2203         pDict->SDEXSYMS[J] = SDNEWSYMS[I - SDNUMINSYMS];
2204       }
2205       J = J + 1;
2206     } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
2207       delete SDNEWSYMS[I - SDNUMINSYMS];
2208     }
2209   }
2210   if (J < SDNUMEXSYMS) {
2211     pDict->SDNUMEXSYMS = J;
2212   }
2213   FX_Free(EXFLAGS);
2214   FX_Free(SDNEWSYMS);
2215   if (SDREFAGG == 0) {
2216     FX_Free(SDNEWSYMWIDTHS);
2217   }
2218   delete pHuffmanDecoder;
2219   return pDict;
2220 failed:
2221   for (I = 0; I < NSYMSDECODED; I++) {
2222     delete SDNEWSYMS[I];
2223   }
2224   FX_Free(SDNEWSYMS);
2225   if (SDREFAGG == 0) {
2226     FX_Free(SDNEWSYMWIDTHS);
2227   }
2228   delete pHuffmanDecoder;
2229   return NULL;
2230 }
2231 CJBig2_Image* CJBig2_HTRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
2232                                             JBig2ArithCtx* gbContext,
2233                                             IFX_Pause* pPause) {
2234   FX_DWORD ng, mg;
2235   int32_t x, y;
2236   FX_DWORD HBPP;
2237   FX_DWORD* GI;
2238   CJBig2_Image* HSKIP = nullptr;
2239   CJBig2_Image* HTREG = new CJBig2_Image(HBW, HBH);
2240   HTREG->fill(HDEFPIXEL);
2241   if (HENABLESKIP == 1) {
2242     HSKIP = new CJBig2_Image(HGW, HGH);
2243     for (mg = 0; mg < HGH; mg++) {
2244       for (ng = 0; ng < HGW; ng++) {
2245         x = (HGX + mg * HRY + ng * HRX) >> 8;
2246         y = (HGY + mg * HRX - ng * HRY) >> 8;
2247         if ((x + HPW <= 0) | (x >= (int32_t)HBW) | (y + HPH <= 0) |
2248             (y >= (int32_t)HPH)) {
2249           HSKIP->setPixel(ng, mg, 1);
2250         } else {
2251           HSKIP->setPixel(ng, mg, 0);
2252         }
2253       }
2254     }
2255   }
2256   HBPP = 1;
2257   while ((FX_DWORD)(1 << HBPP) < HNUMPATS) {
2258     HBPP++;
2259   }
2260   CJBig2_GSIDProc* pGID = new CJBig2_GSIDProc();
2261   pGID->GSMMR = HMMR;
2262   pGID->GSW = HGW;
2263   pGID->GSH = HGH;
2264   pGID->GSBPP = (uint8_t)HBPP;
2265   pGID->GSUSESKIP = HENABLESKIP;
2266   pGID->GSKIP = HSKIP;
2267   pGID->GSTEMPLATE = HTEMPLATE;
2268   GI = pGID->decode_Arith(pArithDecoder, gbContext, pPause);
2269   if (GI == NULL) {
2270     goto failed;
2271   }
2272   for (mg = 0; mg < HGH; mg++) {
2273     for (ng = 0; ng < HGW; ng++) {
2274       x = (HGX + mg * HRY + ng * HRX) >> 8;
2275       y = (HGY + mg * HRX - ng * HRY) >> 8;
2276       FX_DWORD pat_index = GI[mg * HGW + ng];
2277       if (pat_index >= HNUMPATS) {
2278         pat_index = HNUMPATS - 1;
2279       }
2280       HTREG->composeFrom(x, y, HPATS[pat_index], HCOMBOP);
2281     }
2282   }
2283   FX_Free(GI);
2284   delete HSKIP;
2285   delete pGID;
2286   return HTREG;
2287 failed:
2288   delete HSKIP;
2289   delete pGID;
2290   delete HTREG;
2291   return NULL;
2292 }
2293 CJBig2_Image* CJBig2_HTRDProc::decode_MMR(CJBig2_BitStream* pStream,
2294                                           IFX_Pause* pPause) {
2295   FX_DWORD ng, mg;
2296   int32_t x, y;
2297   FX_DWORD* GI;
2298   CJBig2_Image* HTREG = new CJBig2_Image(HBW, HBH);
2299   HTREG->fill(HDEFPIXEL);
2300   FX_DWORD HBPP = 1;
2301   while ((FX_DWORD)(1 << HBPP) < HNUMPATS) {
2302     HBPP++;
2303   }
2304   CJBig2_GSIDProc* pGID = new CJBig2_GSIDProc();
2305   pGID->GSMMR = HMMR;
2306   pGID->GSW = HGW;
2307   pGID->GSH = HGH;
2308   pGID->GSBPP = (uint8_t)HBPP;
2309   pGID->GSUSESKIP = 0;
2310   GI = pGID->decode_MMR(pStream, pPause);
2311   if (GI == NULL) {
2312     goto failed;
2313   }
2314   for (mg = 0; mg < HGH; mg++) {
2315     for (ng = 0; ng < HGW; ng++) {
2316       x = (HGX + mg * HRY + ng * HRX) >> 8;
2317       y = (HGY + mg * HRX - ng * HRY) >> 8;
2318       FX_DWORD pat_index = GI[mg * HGW + ng];
2319       if (pat_index >= HNUMPATS) {
2320         pat_index = HNUMPATS - 1;
2321       }
2322       HTREG->composeFrom(x, y, HPATS[pat_index], HCOMBOP);
2323     }
2324   }
2325   FX_Free(GI);
2326   delete pGID;
2327   return HTREG;
2328 failed:
2329   delete pGID;
2330   delete HTREG;
2331   return NULL;
2332 }
2333 CJBig2_PatternDict* CJBig2_PDDProc::decode_Arith(
2334     CJBig2_ArithDecoder* pArithDecoder,
2335     JBig2ArithCtx* gbContext,
2336     IFX_Pause* pPause) {
2337   FX_DWORD GRAY;
2338   CJBig2_Image* BHDC = NULL;
2339   CJBig2_PatternDict* pDict = new CJBig2_PatternDict();
2340   pDict->NUMPATS = GRAYMAX + 1;
2341   pDict->HDPATS = FX_Alloc(CJBig2_Image*, pDict->NUMPATS);
2342   JBIG2_memset(pDict->HDPATS, 0, sizeof(CJBig2_Image*) * pDict->NUMPATS);
2343   CJBig2_GRDProc* pGRD = new CJBig2_GRDProc();
2344   pGRD->MMR = HDMMR;
2345   pGRD->GBW = (GRAYMAX + 1) * HDPW;
2346   pGRD->GBH = HDPH;
2347   pGRD->GBTEMPLATE = HDTEMPLATE;
2348   pGRD->TPGDON = 0;
2349   pGRD->USESKIP = 0;
2350   pGRD->GBAT[0] = -(int32_t)HDPW;
2351   pGRD->GBAT[1] = 0;
2352   if (pGRD->GBTEMPLATE == 0) {
2353     pGRD->GBAT[2] = -3;
2354     pGRD->GBAT[3] = -1;
2355     pGRD->GBAT[4] = 2;
2356     pGRD->GBAT[5] = -2;
2357     pGRD->GBAT[6] = -2;
2358     pGRD->GBAT[7] = -2;
2359   }
2360   FXCODEC_STATUS status =
2361       pGRD->Start_decode_Arith(&BHDC, pArithDecoder, gbContext);
2362   while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
2363     pGRD->Continue_decode(pPause);
2364   }
2365   if (BHDC == NULL) {
2366     delete pGRD;
2367     goto failed;
2368   }
2369   delete pGRD;
2370   GRAY = 0;
2371   while (GRAY <= GRAYMAX) {
2372     pDict->HDPATS[GRAY] = BHDC->subImage(HDPW * GRAY, 0, HDPW, HDPH);
2373     GRAY = GRAY + 1;
2374   }
2375   delete BHDC;
2376   return pDict;
2377 failed:
2378   delete pDict;
2379   return NULL;
2380 }
2381
2382 CJBig2_PatternDict* CJBig2_PDDProc::decode_MMR(CJBig2_BitStream* pStream,
2383                                                IFX_Pause* pPause) {
2384   FX_DWORD GRAY;
2385   CJBig2_Image* BHDC = NULL;
2386   CJBig2_PatternDict* pDict = new CJBig2_PatternDict();
2387   pDict->NUMPATS = GRAYMAX + 1;
2388   pDict->HDPATS = FX_Alloc(CJBig2_Image*, pDict->NUMPATS);
2389   JBIG2_memset(pDict->HDPATS, 0, sizeof(CJBig2_Image*) * pDict->NUMPATS);
2390   CJBig2_GRDProc* pGRD = new CJBig2_GRDProc();
2391   pGRD->MMR = HDMMR;
2392   pGRD->GBW = (GRAYMAX + 1) * HDPW;
2393   pGRD->GBH = HDPH;
2394   FXCODEC_STATUS status = pGRD->Start_decode_MMR(&BHDC, pStream);
2395   while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
2396     pGRD->Continue_decode(pPause);
2397   }
2398   if (BHDC == NULL) {
2399     delete pGRD;
2400     goto failed;
2401   }
2402   delete pGRD;
2403   GRAY = 0;
2404   while (GRAY <= GRAYMAX) {
2405     pDict->HDPATS[GRAY] = BHDC->subImage(HDPW * GRAY, 0, HDPW, HDPH);
2406     GRAY = GRAY + 1;
2407   }
2408   delete BHDC;
2409   return pDict;
2410 failed:
2411   delete pDict;
2412   return NULL;
2413 }
2414 FX_DWORD* CJBig2_GSIDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
2415                                         JBig2ArithCtx* gbContext,
2416                                         IFX_Pause* pPause) {
2417   CJBig2_Image** GSPLANES;
2418   int32_t J, K;
2419   FX_DWORD x, y;
2420   FX_DWORD* GSVALS;
2421   GSPLANES = FX_Alloc(CJBig2_Image*, GSBPP);
2422   if (!GSPLANES) {
2423     return NULL;
2424   }
2425   GSVALS = FX_Alloc2D(FX_DWORD, GSW, GSH);
2426   if (!GSVALS) {
2427     FX_Free(GSPLANES);
2428     return NULL;
2429   }
2430   JBIG2_memset(GSPLANES, 0, sizeof(CJBig2_Image*) * GSBPP);
2431   JBIG2_memset(GSVALS, 0, sizeof(FX_DWORD) * GSW * GSH);
2432   CJBig2_GRDProc* pGRD = new CJBig2_GRDProc();
2433   pGRD->MMR = GSMMR;
2434   pGRD->GBW = GSW;
2435   pGRD->GBH = GSH;
2436   pGRD->GBTEMPLATE = GSTEMPLATE;
2437   pGRD->TPGDON = 0;
2438   pGRD->USESKIP = GSUSESKIP;
2439   pGRD->SKIP = GSKIP;
2440   if (GSTEMPLATE <= 1) {
2441     pGRD->GBAT[0] = 3;
2442   } else {
2443     pGRD->GBAT[0] = 2;
2444   }
2445   pGRD->GBAT[1] = -1;
2446   if (pGRD->GBTEMPLATE == 0) {
2447     pGRD->GBAT[2] = -3;
2448     pGRD->GBAT[3] = -1;
2449     pGRD->GBAT[4] = 2;
2450     pGRD->GBAT[5] = -2;
2451     pGRD->GBAT[6] = -2;
2452     pGRD->GBAT[7] = -2;
2453   }
2454   FXCODEC_STATUS status =
2455       pGRD->Start_decode_Arith(&GSPLANES[GSBPP - 1], pArithDecoder, gbContext);
2456   while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
2457     pGRD->Continue_decode(pPause);
2458   }
2459   if (GSPLANES[GSBPP - 1] == NULL) {
2460     goto failed;
2461   }
2462   J = GSBPP - 2;
2463   while (J >= 0) {
2464     FXCODEC_STATUS status =
2465         pGRD->Start_decode_Arith(&GSPLANES[J], pArithDecoder, gbContext);
2466     while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
2467       pGRD->Continue_decode(pPause);
2468     }
2469     if (GSPLANES[J] == NULL) {
2470       for (K = GSBPP - 1; K > J; K--) {
2471         delete GSPLANES[K];
2472         goto failed;
2473       }
2474     }
2475     GSPLANES[J]->composeFrom(0, 0, GSPLANES[J + 1], JBIG2_COMPOSE_XOR);
2476     J = J - 1;
2477   }
2478   for (y = 0; y < GSH; y++) {
2479     for (x = 0; x < GSW; x++) {
2480       for (J = 0; J < GSBPP; J++) {
2481         GSVALS[y * GSW + x] |= GSPLANES[J]->getPixel(x, y) << J;
2482       }
2483     }
2484   }
2485   for (J = 0; J < GSBPP; J++) {
2486     delete GSPLANES[J];
2487   }
2488   FX_Free(GSPLANES);
2489   delete pGRD;
2490   return GSVALS;
2491 failed:
2492   FX_Free(GSPLANES);
2493   delete pGRD;
2494   FX_Free(GSVALS);
2495   return NULL;
2496 }
2497 FX_DWORD* CJBig2_GSIDProc::decode_MMR(CJBig2_BitStream* pStream,
2498                                       IFX_Pause* pPause) {
2499   CJBig2_Image** GSPLANES;
2500   int32_t J, K;
2501   FX_DWORD x, y;
2502   FX_DWORD* GSVALS;
2503   GSPLANES = FX_Alloc(CJBig2_Image*, GSBPP);
2504   if (!GSPLANES) {
2505     return NULL;
2506   }
2507   GSVALS = FX_Alloc2D(FX_DWORD, GSW, GSH);
2508   if (!GSVALS) {
2509     FX_Free(GSPLANES);
2510     return NULL;
2511   }
2512   JBIG2_memset(GSPLANES, 0, sizeof(CJBig2_Image*) * GSBPP);
2513   JBIG2_memset(GSVALS, 0, sizeof(FX_DWORD) * GSW * GSH);
2514   CJBig2_GRDProc* pGRD = new CJBig2_GRDProc();
2515   pGRD->MMR = GSMMR;
2516   pGRD->GBW = GSW;
2517   pGRD->GBH = GSH;
2518   FXCODEC_STATUS status = pGRD->Start_decode_MMR(&GSPLANES[GSBPP - 1], pStream);
2519   while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
2520     pGRD->Continue_decode(pPause);
2521   }
2522   if (GSPLANES[GSBPP - 1] == NULL) {
2523     goto failed;
2524   }
2525   pStream->alignByte();
2526   pStream->offset(3);
2527   J = GSBPP - 2;
2528   while (J >= 0) {
2529     FXCODEC_STATUS status = pGRD->Start_decode_MMR(&GSPLANES[J], pStream);
2530     while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
2531       pGRD->Continue_decode(pPause);
2532     }
2533     if (GSPLANES[J] == NULL) {
2534       for (K = GSBPP - 1; K > J; K--) {
2535         delete GSPLANES[K];
2536         goto failed;
2537       }
2538     }
2539     pStream->alignByte();
2540     pStream->offset(3);
2541     GSPLANES[J]->composeFrom(0, 0, GSPLANES[J + 1], JBIG2_COMPOSE_XOR);
2542     J = J - 1;
2543   }
2544   for (y = 0; y < GSH; y++) {
2545     for (x = 0; x < GSW; x++) {
2546       for (J = 0; J < GSBPP; J++) {
2547         GSVALS[y * GSW + x] |= GSPLANES[J]->getPixel(x, y) << J;
2548       }
2549     }
2550   }
2551   for (J = 0; J < GSBPP; J++) {
2552     delete GSPLANES[J];
2553   }
2554   FX_Free(GSPLANES);
2555   delete pGRD;
2556   return GSVALS;
2557 failed:
2558   FX_Free(GSPLANES);
2559   delete pGRD;
2560   FX_Free(GSVALS);
2561   return NULL;
2562 }
2563 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_Arith(
2564     CJBig2_Image** pImage,
2565     CJBig2_ArithDecoder* pArithDecoder,
2566     JBig2ArithCtx* gbContext,
2567     IFX_Pause* pPause) {
2568   if (GBW == 0 || GBH == 0) {
2569     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
2570     return FXCODEC_STATUS_DECODE_FINISH;
2571   }
2572   m_ProssiveStatus = FXCODEC_STATUS_DECODE_READY;
2573   m_pPause = pPause;
2574   if (!*pImage)
2575     *pImage = new CJBig2_Image(GBW, GBH);
2576   if ((*pImage)->m_pData == NULL) {
2577     delete *pImage;
2578     *pImage = NULL;
2579     m_ProssiveStatus = FXCODEC_STATUS_ERROR;
2580     return FXCODEC_STATUS_ERROR;
2581   }
2582   m_DecodeType = 1;
2583   m_pImage = pImage;
2584   (*m_pImage)->fill(0);
2585   m_pArithDecoder = pArithDecoder;
2586   m_gbContext = gbContext;
2587   LTP = 0;
2588   m_pLine = NULL;
2589   m_loopIndex = 0;
2590   return decode_Arith(pPause);
2591 }
2592 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith(IFX_Pause* pPause) {
2593   int iline = m_loopIndex;
2594   CJBig2_Image* pImage = *m_pImage;
2595   if (GBTEMPLATE == 0) {
2596     if ((GBAT[0] == 3) && (GBAT[1] == (int8_t)-1) && (GBAT[2] == (int8_t)-3) &&
2597         (GBAT[3] == (int8_t)-1) && (GBAT[4] == 2) && (GBAT[5] == (int8_t)-2) &&
2598         (GBAT[6] == (int8_t)-2) && (GBAT[7] == (int8_t)-2)) {
2599       m_ProssiveStatus = decode_Arith_Template0_opt3(pImage, m_pArithDecoder,
2600                                                      m_gbContext, pPause);
2601     } else {
2602       m_ProssiveStatus = decode_Arith_Template0_unopt(pImage, m_pArithDecoder,
2603                                                       m_gbContext, pPause);
2604     }
2605   } else if (GBTEMPLATE == 1) {
2606     if ((GBAT[0] == 3) && (GBAT[1] == (int8_t)-1)) {
2607       m_ProssiveStatus = decode_Arith_Template1_opt3(pImage, m_pArithDecoder,
2608                                                      m_gbContext, pPause);
2609     } else {
2610       m_ProssiveStatus = decode_Arith_Template1_unopt(pImage, m_pArithDecoder,
2611                                                       m_gbContext, pPause);
2612     }
2613   } else if (GBTEMPLATE == 2) {
2614     if ((GBAT[0] == 2) && (GBAT[1] == (int8_t)-1)) {
2615       m_ProssiveStatus = decode_Arith_Template2_opt3(pImage, m_pArithDecoder,
2616                                                      m_gbContext, pPause);
2617     } else {
2618       m_ProssiveStatus = decode_Arith_Template2_unopt(pImage, m_pArithDecoder,
2619                                                       m_gbContext, pPause);
2620     }
2621   } else {
2622     if ((GBAT[0] == 2) && (GBAT[1] == (int8_t)-1)) {
2623       m_ProssiveStatus = decode_Arith_Template3_opt3(pImage, m_pArithDecoder,
2624                                                      m_gbContext, pPause);
2625     } else {
2626       m_ProssiveStatus = decode_Arith_Template3_unopt(pImage, m_pArithDecoder,
2627                                                       m_gbContext, pPause);
2628     }
2629   }
2630   m_ReplaceRect.left = 0;
2631   m_ReplaceRect.right = pImage->m_nWidth;
2632   m_ReplaceRect.top = iline;
2633   m_ReplaceRect.bottom = m_loopIndex;
2634   if (m_ProssiveStatus == FXCODEC_STATUS_DECODE_FINISH) {
2635     m_loopIndex = 0;
2636   }
2637   return m_ProssiveStatus;
2638 }
2639 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_MMR(CJBig2_Image** pImage,
2640                                                 CJBig2_BitStream* pStream,
2641                                                 IFX_Pause* pPause) {
2642   int bitpos, i;
2643   *pImage = new CJBig2_Image(GBW, GBH);
2644   if ((*pImage)->m_pData == NULL) {
2645     delete (*pImage);
2646     (*pImage) = NULL;
2647     m_ProssiveStatus = FXCODEC_STATUS_ERROR;
2648     return m_ProssiveStatus;
2649   }
2650   bitpos = (int)pStream->getBitPos();
2651   _FaxG4Decode(pStream->getBuf(), pStream->getLength(), &bitpos,
2652                (*pImage)->m_pData, GBW, GBH, (*pImage)->m_nStride);
2653   pStream->setBitPos(bitpos);
2654   for (i = 0; (FX_DWORD)i < (*pImage)->m_nStride * GBH; i++) {
2655     (*pImage)->m_pData[i] = ~(*pImage)->m_pData[i];
2656   }
2657   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
2658   return m_ProssiveStatus;
2659 }
2660
2661 FXCODEC_STATUS CJBig2_GRDProc::Continue_decode(IFX_Pause* pPause) {
2662   if (m_ProssiveStatus != FXCODEC_STATUS_DECODE_TOBECONTINUE)
2663     return m_ProssiveStatus;
2664
2665   if (m_DecodeType != 1) {
2666     m_ProssiveStatus = FXCODEC_STATUS_ERROR;
2667     return m_ProssiveStatus;
2668   }
2669
2670   return decode_Arith(pPause);
2671 }
2672
2673 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3(
2674     CJBig2_Image* pImage,
2675     CJBig2_ArithDecoder* pArithDecoder,
2676     JBig2ArithCtx* gbContext,
2677     IFX_Pause* pPause) {
2678   FX_BOOL SLTP, bVal;
2679   FX_DWORD CONTEXT;
2680   FX_DWORD line1, line2;
2681   uint8_t *pLine1, *pLine2, cVal;
2682   int32_t nStride, nStride2, k;
2683   int32_t nLineBytes, nBitsLeft, cc;
2684   if (m_pLine == NULL) {
2685     m_pLine = pImage->m_pData;
2686   }
2687   nStride = pImage->m_nStride;
2688   nStride2 = nStride << 1;
2689   nLineBytes = ((GBW + 7) >> 3) - 1;
2690   nBitsLeft = GBW - (nLineBytes << 3);
2691   FX_DWORD height = GBH & 0x7fffffff;
2692   for (; m_loopIndex < height; m_loopIndex++) {
2693     if (TPGDON) {
2694       SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
2695       LTP = LTP ^ SLTP;
2696     }
2697     if (LTP == 1) {
2698       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
2699     } else {
2700       if (m_loopIndex > 1) {
2701         pLine1 = m_pLine - nStride2;
2702         pLine2 = m_pLine - nStride;
2703         line1 = (*pLine1++) << 6;
2704         line2 = *pLine2++;
2705         CONTEXT = ((line1 & 0xf800) | (line2 & 0x07f0));
2706         for (cc = 0; cc < nLineBytes; cc++) {
2707           line1 = (line1 << 8) | ((*pLine1++) << 6);
2708           line2 = (line2 << 8) | (*pLine2++);
2709           cVal = 0;
2710           for (k = 7; k >= 0; k--) {
2711             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
2712             cVal |= bVal << k;
2713             CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
2714                        ((line1 >> k) & 0x0800) | ((line2 >> k) & 0x0010));
2715           }
2716           m_pLine[cc] = cVal;
2717         }
2718         line1 <<= 8;
2719         line2 <<= 8;
2720         cVal = 0;
2721         for (k = 0; k < nBitsLeft; k++) {
2722           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
2723           cVal |= bVal << (7 - k);
2724           CONTEXT =
2725               (((CONTEXT & 0x7bf7) << 1) | bVal |
2726                ((line1 >> (7 - k)) & 0x0800) | ((line2 >> (7 - k)) & 0x0010));
2727         }
2728         m_pLine[nLineBytes] = cVal;
2729       } else {
2730         pLine2 = m_pLine - nStride;
2731         line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
2732         CONTEXT = (line2 & 0x07f0);
2733         for (cc = 0; cc < nLineBytes; cc++) {
2734           if (m_loopIndex & 1) {
2735             line2 = (line2 << 8) | (*pLine2++);
2736           }
2737           cVal = 0;
2738           for (k = 7; k >= 0; k--) {
2739             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
2740             cVal |= bVal << k;
2741             CONTEXT =
2742                 (((CONTEXT & 0x7bf7) << 1) | bVal | ((line2 >> k) & 0x0010));
2743           }
2744           m_pLine[cc] = cVal;
2745         }
2746         line2 <<= 8;
2747         cVal = 0;
2748         for (k = 0; k < nBitsLeft; k++) {
2749           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
2750           cVal |= bVal << (7 - k);
2751           CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
2752                      ((line2 >> (7 - k)) & 0x0010));
2753         }
2754         m_pLine[nLineBytes] = cVal;
2755       }
2756     }
2757     m_pLine += nStride;
2758     if (pPause && pPause->NeedToPauseNow()) {
2759       m_loopIndex++;
2760       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
2761       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
2762     }
2763   }
2764   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
2765   return FXCODEC_STATUS_DECODE_FINISH;
2766 }
2767 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_unopt(
2768     CJBig2_Image* pImage,
2769     CJBig2_ArithDecoder* pArithDecoder,
2770     JBig2ArithCtx* gbContext,
2771     IFX_Pause* pPause) {
2772   FX_BOOL SLTP, bVal;
2773   FX_DWORD CONTEXT;
2774   FX_DWORD line1, line2, line3;
2775   for (; m_loopIndex < GBH; m_loopIndex++) {
2776     if (TPGDON) {
2777       SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
2778       LTP = LTP ^ SLTP;
2779     }
2780     if (LTP == 1) {
2781       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
2782     } else {
2783       line1 = pImage->getPixel(1, m_loopIndex - 2);
2784       line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
2785       line2 = pImage->getPixel(2, m_loopIndex - 1);
2786       line2 |= pImage->getPixel(1, m_loopIndex - 1) << 1;
2787       line2 |= pImage->getPixel(0, m_loopIndex - 1) << 2;
2788       line3 = 0;
2789       for (FX_DWORD w = 0; w < GBW; w++) {
2790         if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
2791           bVal = 0;
2792         } else {
2793           CONTEXT = line3;
2794           CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
2795           CONTEXT |= line2 << 5;
2796           CONTEXT |= pImage->getPixel(w + GBAT[2], m_loopIndex + GBAT[3]) << 10;
2797           CONTEXT |= pImage->getPixel(w + GBAT[4], m_loopIndex + GBAT[5]) << 11;
2798           CONTEXT |= line1 << 12;
2799           CONTEXT |= pImage->getPixel(w + GBAT[6], m_loopIndex + GBAT[7]) << 15;
2800           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
2801         }
2802         if (bVal) {
2803           pImage->setPixel(w, m_loopIndex, bVal);
2804         }
2805         line1 =
2806             ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
2807         line2 =
2808             ((line2 << 1) | pImage->getPixel(w + 3, m_loopIndex - 1)) & 0x1f;
2809         line3 = ((line3 << 1) | bVal) & 0x0f;
2810       }
2811     }
2812     if (pPause && pPause->NeedToPauseNow()) {
2813       m_loopIndex++;
2814       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
2815       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
2816     }
2817   }
2818   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
2819   return FXCODEC_STATUS_DECODE_FINISH;
2820 }
2821 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3(
2822     CJBig2_Image* pImage,
2823     CJBig2_ArithDecoder* pArithDecoder,
2824     JBig2ArithCtx* gbContext,
2825     IFX_Pause* pPause) {
2826   FX_BOOL SLTP, bVal;
2827   FX_DWORD CONTEXT;
2828   FX_DWORD line1, line2;
2829   uint8_t *pLine1, *pLine2, cVal;
2830   int32_t nStride, nStride2, k;
2831   int32_t nLineBytes, nBitsLeft, cc;
2832   if (!m_pLine) {
2833     m_pLine = pImage->m_pData;
2834   }
2835   nStride = pImage->m_nStride;
2836   nStride2 = nStride << 1;
2837   nLineBytes = ((GBW + 7) >> 3) - 1;
2838   nBitsLeft = GBW - (nLineBytes << 3);
2839   for (; m_loopIndex < GBH; m_loopIndex++) {
2840     if (TPGDON) {
2841       SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
2842       LTP = LTP ^ SLTP;
2843     }
2844     if (LTP == 1) {
2845       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
2846     } else {
2847       if (m_loopIndex > 1) {
2848         pLine1 = m_pLine - nStride2;
2849         pLine2 = m_pLine - nStride;
2850         line1 = (*pLine1++) << 4;
2851         line2 = *pLine2++;
2852         CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
2853         for (cc = 0; cc < nLineBytes; cc++) {
2854           line1 = (line1 << 8) | ((*pLine1++) << 4);
2855           line2 = (line2 << 8) | (*pLine2++);
2856           cVal = 0;
2857           for (k = 7; k >= 0; k--) {
2858             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
2859             cVal |= bVal << k;
2860             CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
2861                       ((line1 >> k) & 0x0200) | ((line2 >> (k + 1)) & 0x0008);
2862           }
2863           m_pLine[cc] = cVal;
2864         }
2865         line1 <<= 8;
2866         line2 <<= 8;
2867         cVal = 0;
2868         for (k = 0; k < nBitsLeft; k++) {
2869           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
2870           cVal |= bVal << (7 - k);
2871           CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
2872                     ((line1 >> (7 - k)) & 0x0200) |
2873                     ((line2 >> (8 - k)) & 0x0008);
2874         }
2875         m_pLine[nLineBytes] = cVal;
2876       } else {
2877         pLine2 = m_pLine - nStride;
2878         line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
2879         CONTEXT = (line2 >> 1) & 0x01f8;
2880         for (cc = 0; cc < nLineBytes; cc++) {
2881           if (m_loopIndex & 1) {
2882             line2 = (line2 << 8) | (*pLine2++);
2883           }
2884           cVal = 0;
2885           for (k = 7; k >= 0; k--) {
2886             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
2887             cVal |= bVal << k;
2888             CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
2889                       ((line2 >> (k + 1)) & 0x0008);
2890           }
2891           m_pLine[cc] = cVal;
2892         }
2893         line2 <<= 8;
2894         cVal = 0;
2895         for (k = 0; k < nBitsLeft; k++) {
2896           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
2897           cVal |= bVal << (7 - k);
2898           CONTEXT =
2899               ((CONTEXT & 0x0efb) << 1) | bVal | ((line2 >> (8 - k)) & 0x0008);
2900         }
2901         m_pLine[nLineBytes] = cVal;
2902       }
2903     }
2904     m_pLine += nStride;
2905     if (pPause && pPause->NeedToPauseNow()) {
2906       m_loopIndex++;
2907       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
2908       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
2909     }
2910   }
2911   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
2912   return FXCODEC_STATUS_DECODE_FINISH;
2913 }
2914 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_unopt(
2915     CJBig2_Image* pImage,
2916     CJBig2_ArithDecoder* pArithDecoder,
2917     JBig2ArithCtx* gbContext,
2918     IFX_Pause* pPause) {
2919   FX_BOOL SLTP, bVal;
2920   FX_DWORD CONTEXT;
2921   FX_DWORD line1, line2, line3;
2922   for (FX_DWORD h = 0; h < GBH; h++) {
2923     if (TPGDON) {
2924       SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
2925       LTP = LTP ^ SLTP;
2926     }
2927     if (LTP == 1) {
2928       pImage->copyLine(h, h - 1);
2929     } else {
2930       line1 = pImage->getPixel(2, h - 2);
2931       line1 |= pImage->getPixel(1, h - 2) << 1;
2932       line1 |= pImage->getPixel(0, h - 2) << 2;
2933       line2 = pImage->getPixel(2, h - 1);
2934       line2 |= pImage->getPixel(1, h - 1) << 1;
2935       line2 |= pImage->getPixel(0, h - 1) << 2;
2936       line3 = 0;
2937       for (FX_DWORD w = 0; w < GBW; w++) {
2938         if (USESKIP && SKIP->getPixel(w, h)) {
2939           bVal = 0;
2940         } else {
2941           CONTEXT = line3;
2942           CONTEXT |= pImage->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
2943           CONTEXT |= line2 << 4;
2944           CONTEXT |= line1 << 9;
2945           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
2946         }
2947         if (bVal) {
2948           pImage->setPixel(w, h, bVal);
2949         }
2950         line1 = ((line1 << 1) | pImage->getPixel(w + 3, h - 2)) & 0x0f;
2951         line2 = ((line2 << 1) | pImage->getPixel(w + 3, h - 1)) & 0x1f;
2952         line3 = ((line3 << 1) | bVal) & 0x07;
2953       }
2954     }
2955     if (pPause && pPause->NeedToPauseNow()) {
2956       m_loopIndex++;
2957       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
2958       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
2959     }
2960   }
2961   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
2962   return FXCODEC_STATUS_DECODE_FINISH;
2963 }
2964 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3(
2965     CJBig2_Image* pImage,
2966     CJBig2_ArithDecoder* pArithDecoder,
2967     JBig2ArithCtx* gbContext,
2968     IFX_Pause* pPause) {
2969   FX_BOOL SLTP, bVal;
2970   FX_DWORD CONTEXT;
2971   FX_DWORD line1, line2;
2972   uint8_t *pLine1, *pLine2, cVal;
2973   int32_t nStride, nStride2, k;
2974   int32_t nLineBytes, nBitsLeft, cc;
2975   if (!m_pLine) {
2976     m_pLine = pImage->m_pData;
2977   }
2978   nStride = pImage->m_nStride;
2979   nStride2 = nStride << 1;
2980   nLineBytes = ((GBW + 7) >> 3) - 1;
2981   nBitsLeft = GBW - (nLineBytes << 3);
2982   for (; m_loopIndex < GBH; m_loopIndex++) {
2983     if (TPGDON) {
2984       SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
2985       LTP = LTP ^ SLTP;
2986     }
2987     if (LTP == 1) {
2988       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
2989     } else {
2990       if (m_loopIndex > 1) {
2991         pLine1 = m_pLine - nStride2;
2992         pLine2 = m_pLine - nStride;
2993         line1 = (*pLine1++) << 1;
2994         line2 = *pLine2++;
2995         CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
2996         for (cc = 0; cc < nLineBytes; cc++) {
2997           line1 = (line1 << 8) | ((*pLine1++) << 1);
2998           line2 = (line2 << 8) | (*pLine2++);
2999           cVal = 0;
3000           for (k = 7; k >= 0; k--) {
3001             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3002             cVal |= bVal << k;
3003             CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
3004                       ((line1 >> k) & 0x0080) | ((line2 >> (k + 3)) & 0x0004);
3005           }
3006           m_pLine[cc] = cVal;
3007         }
3008         line1 <<= 8;
3009         line2 <<= 8;
3010         cVal = 0;
3011         for (k = 0; k < nBitsLeft; k++) {
3012           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3013           cVal |= bVal << (7 - k);
3014           CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
3015                     ((line1 >> (7 - k)) & 0x0080) |
3016                     ((line2 >> (10 - k)) & 0x0004);
3017         }
3018         m_pLine[nLineBytes] = cVal;
3019       } else {
3020         pLine2 = m_pLine - nStride;
3021         line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
3022         CONTEXT = (line2 >> 3) & 0x007c;
3023         for (cc = 0; cc < nLineBytes; cc++) {
3024           if (m_loopIndex & 1) {
3025             line2 = (line2 << 8) | (*pLine2++);
3026           }
3027           cVal = 0;
3028           for (k = 7; k >= 0; k--) {
3029             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3030             cVal |= bVal << k;
3031             CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
3032                       ((line2 >> (k + 3)) & 0x0004);
3033           }
3034           m_pLine[cc] = cVal;
3035         }
3036         line2 <<= 8;
3037         cVal = 0;
3038         for (k = 0; k < nBitsLeft; k++) {
3039           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3040           cVal |= bVal << (7 - k);
3041           CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
3042                     (((line2 >> (10 - k))) & 0x0004);
3043         }
3044         m_pLine[nLineBytes] = cVal;
3045       }
3046     }
3047     m_pLine += nStride;
3048     if (pPause && m_loopIndex % 50 == 0 && pPause->NeedToPauseNow()) {
3049       m_loopIndex++;
3050       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3051       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3052     }
3053   }
3054   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3055   return FXCODEC_STATUS_DECODE_FINISH;
3056 }
3057 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_unopt(
3058     CJBig2_Image* pImage,
3059     CJBig2_ArithDecoder* pArithDecoder,
3060     JBig2ArithCtx* gbContext,
3061     IFX_Pause* pPause) {
3062   FX_BOOL SLTP, bVal;
3063   FX_DWORD CONTEXT;
3064   FX_DWORD line1, line2, line3;
3065   for (; m_loopIndex < GBH; m_loopIndex++) {
3066     if (TPGDON) {
3067       SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
3068       LTP = LTP ^ SLTP;
3069     }
3070     if (LTP == 1) {
3071       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
3072     } else {
3073       line1 = pImage->getPixel(1, m_loopIndex - 2);
3074       line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
3075       line2 = pImage->getPixel(1, m_loopIndex - 1);
3076       line2 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
3077       line3 = 0;
3078       for (FX_DWORD w = 0; w < GBW; w++) {
3079         if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3080           bVal = 0;
3081         } else {
3082           CONTEXT = line3;
3083           CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 2;
3084           CONTEXT |= line2 << 3;
3085           CONTEXT |= line1 << 7;
3086           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3087         }
3088         if (bVal) {
3089           pImage->setPixel(w, m_loopIndex, bVal);
3090         }
3091         line1 =
3092             ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
3093         line2 =
3094             ((line2 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x0f;
3095         line3 = ((line3 << 1) | bVal) & 0x03;
3096       }
3097     }
3098     if (pPause && pPause->NeedToPauseNow()) {
3099       m_loopIndex++;
3100       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3101       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3102     }
3103   }
3104   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3105   return FXCODEC_STATUS_DECODE_FINISH;
3106 }
3107 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3(
3108     CJBig2_Image* pImage,
3109     CJBig2_ArithDecoder* pArithDecoder,
3110     JBig2ArithCtx* gbContext,
3111     IFX_Pause* pPause) {
3112   FX_BOOL SLTP, bVal;
3113   FX_DWORD CONTEXT;
3114   FX_DWORD line1;
3115   uint8_t *pLine1, cVal;
3116   int32_t nStride, k;
3117   int32_t nLineBytes, nBitsLeft, cc;
3118   if (!m_pLine) {
3119     m_pLine = pImage->m_pData;
3120   }
3121   nStride = pImage->m_nStride;
3122   nLineBytes = ((GBW + 7) >> 3) - 1;
3123   nBitsLeft = GBW - (nLineBytes << 3);
3124   for (; m_loopIndex < GBH; m_loopIndex++) {
3125     if (TPGDON) {
3126       SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
3127       LTP = LTP ^ SLTP;
3128     }
3129     if (LTP == 1) {
3130       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
3131     } else {
3132       if (m_loopIndex > 0) {
3133         pLine1 = m_pLine - nStride;
3134         line1 = *pLine1++;
3135         CONTEXT = (line1 >> 1) & 0x03f0;
3136         for (cc = 0; cc < nLineBytes; cc++) {
3137           line1 = (line1 << 8) | (*pLine1++);
3138           cVal = 0;
3139           for (k = 7; k >= 0; k--) {
3140             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3141             cVal |= bVal << k;
3142             CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal |
3143                       ((line1 >> (k + 1)) & 0x0010);
3144           }
3145           m_pLine[cc] = cVal;
3146         }
3147         line1 <<= 8;
3148         cVal = 0;
3149         for (k = 0; k < nBitsLeft; k++) {
3150           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3151           cVal |= bVal << (7 - k);
3152           CONTEXT =
3153               ((CONTEXT & 0x01f7) << 1) | bVal | ((line1 >> (8 - k)) & 0x0010);
3154         }
3155         m_pLine[nLineBytes] = cVal;
3156       } else {
3157         CONTEXT = 0;
3158         for (cc = 0; cc < nLineBytes; cc++) {
3159           cVal = 0;
3160           for (k = 7; k >= 0; k--) {
3161             bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3162             cVal |= bVal << k;
3163             CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
3164           }
3165           m_pLine[cc] = cVal;
3166         }
3167         cVal = 0;
3168         for (k = 0; k < nBitsLeft; k++) {
3169           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3170           cVal |= bVal << (7 - k);
3171           CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
3172         }
3173         m_pLine[nLineBytes] = cVal;
3174       }
3175     }
3176     m_pLine += nStride;
3177     if (pPause && pPause->NeedToPauseNow()) {
3178       m_loopIndex++;
3179       m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3180       return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3181     }
3182   }
3183   m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3184   return FXCODEC_STATUS_DECODE_FINISH;
3185 }
3186 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_unopt(
3187     CJBig2_Image* pImage,
3188     CJBig2_ArithDecoder* pArithDecoder,
3189     JBig2ArithCtx* gbContext,
3190     IFX_Pause* pPause) {
3191   FX_BOOL SLTP, bVal;
3192   FX_DWORD CONTEXT;
3193   FX_DWORD line1, line2;
3194   for (; m_loopIndex < GBH; m_loopIndex++) {
3195     if (TPGDON) {
3196       SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
3197       LTP = LTP ^ SLTP;
3198     }
3199     if (LTP == 1) {
3200       pImage->copyLine(m_loopIndex, m_loopIndex - 1);
3201     } else {
3202       line1 = pImage->getPixel(1, m_loopIndex - 1);
3203       line1 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
3204       line2 = 0;
3205       for (FX_DWORD w = 0; w < GBW; w++) {
3206         if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3207           bVal = 0;
3208         } else {
3209           CONTEXT = line2;
3210           CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
3211           CONTEXT |= line1 << 5;
3212           bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3213         }
3214         if (bVal) {
3215           pImage->setPixel(w, m_loopIndex, bVal);
3216         }
3217         line1 =
3218             ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x1f;
3219         line2 = ((line2 << 1) | bVal) & 0x0f;
3220       }
3221     }