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