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