Fix a heap overflow in CJBig2_Context::parseSymbolDict
[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     FX_BYTE *pLine, cVal;
154     FX_INTPTR nStride, nStride2;
155     FX_INT32 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     FX_BYTE *pLine, *pLine1, *pLine2, cVal;
221     FX_INT32 nStride, nStride2, k;
222     FX_INT32 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     FX_BYTE *pLine, cVal;
405     FX_INTPTR nStride, nStride2;
406     FX_INT32 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     FX_BYTE *pLine, *pLine1, *pLine2, cVal;
472     FX_INT32 nStride, nStride2, k;
473     FX_INT32 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     FX_BYTE *pLine, cVal;
651     FX_INTPTR nStride, nStride2;
652     FX_INT32 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     FX_BYTE *pLine, *pLine1, *pLine2, cVal;
718     FX_INT32 nStride, nStride2, k;
719     FX_INT32 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     FX_BYTE *pLine, cVal;
891     FX_INTPTR nStride, nStride2;
892     FX_INT32 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     nStride2 = nStride << 1;
903     for(FX_DWORD h = 0; h < GBH; h++) {
904         if(TPGDON) {
905             SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
906             LTP = LTP ^ SLTP;
907         }
908         if(LTP == 1) {
909             GBREG->copyLine(h, h - 1);
910         } else {
911             line1 = (h > 0) ? pLine[-nStride] : 0;
912             CONTEXT = (line1 >> 1) & 0x03f0;
913             for(FX_DWORD w = 0; w < GBW; w += 8) {
914                 if(w + 8 < GBW) {
915                     nBits = 8;
916                     if(h > 0) {
917                         line1 = (line1 << 8) | (pLine[-nStride + (w >> 3) + 1]);
918                     }
919                 } else {
920                     nBits = GBW - w;
921                     if(h > 0) {
922                         line1 <<= 8;
923                     }
924                 }
925                 cVal = 0;
926                 for(k = 0; k < nBits; k++) {
927                     if(USESKIP && SKIP->getPixel(w, h)) {
928                         bVal = 0;
929                     } else {
930                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
931                     }
932                     cVal |= bVal << (7 - k);
933                     CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
934                               | ((line1 >> (8 - k)) & 0x0010);
935                 }
936                 pLine[w >> 3] = cVal;
937             }
938         }
939         pLine += nStride;
940     }
941     return GBREG;
942 }
943 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
944 {
945     FX_BOOL LTP, SLTP, bVal;
946     FX_DWORD CONTEXT;
947     CJBig2_Image *GBREG;
948     FX_DWORD line1;
949     FX_BYTE *pLine, *pLine1, cVal;
950     FX_INT32 nStride, k;
951     FX_INT32 nLineBytes, nBitsLeft, cc;
952     LTP = 0;
953     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
954     if (GBREG->m_pData == NULL) {
955         delete GBREG;
956         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
957         return NULL;
958     }
959     pLine = GBREG->m_pData;
960     nStride = GBREG->m_nStride;
961     nLineBytes = ((GBW + 7) >> 3) - 1;
962     nBitsLeft = GBW - (nLineBytes << 3);
963     for(FX_DWORD h = 0; h < GBH; h++) {
964         if(TPGDON) {
965             SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
966             LTP = LTP ^ SLTP;
967         }
968         if(LTP == 1) {
969             GBREG->copyLine(h, h - 1);
970         } else {
971             if(h > 0) {
972                 pLine1 = pLine - nStride;
973                 line1 = *pLine1++;
974                 CONTEXT = (line1 >> 1) & 0x03f0;
975                 for(cc = 0; cc < nLineBytes; cc++) {
976                     line1 = (line1 << 8) | (*pLine1++);
977                     cVal = 0;
978                     for(k = 7; k >= 0; k--) {
979                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
980                         cVal |= bVal << k;
981                         CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
982                                   | ((line1 >> (k + 1)) & 0x0010);
983                     }
984                     pLine[cc] = cVal;
985                 }
986                 line1 <<= 8;
987                 cVal = 0;
988                 for(k = 0; k < nBitsLeft; k++) {
989                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
990                     cVal |= bVal << (7 - k);
991                     CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
992                               | ((line1 >> (8 - k)) & 0x0010);
993                 }
994                 pLine[nLineBytes] = cVal;
995             } else {
996                 CONTEXT = 0;
997                 for(cc = 0; cc < nLineBytes; cc++) {
998                     cVal = 0;
999                     for(k = 7; k >= 0; k--) {
1000                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1001                         cVal |= bVal << k;
1002                         CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
1003                     }
1004                     pLine[cc] = cVal;
1005                 }
1006                 cVal = 0;
1007                 for(k = 0; k < nBitsLeft; k++) {
1008                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1009                     cVal |= bVal << (7 - k);
1010                     CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
1011                 }
1012                 pLine[nLineBytes] = cVal;
1013             }
1014         }
1015         pLine += nStride;
1016     }
1017     return GBREG;
1018 }
1019 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
1020 {
1021     FX_BOOL LTP, SLTP, bVal;
1022     FX_DWORD CONTEXT;
1023     CJBig2_Image *GBREG;
1024     FX_DWORD line1, line2;
1025     LTP = 0;
1026     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
1027     GBREG->fill(0);
1028     for(FX_DWORD h = 0; h < GBH; h++) {
1029         if(TPGDON) {
1030             SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
1031             LTP = LTP ^ SLTP;
1032         }
1033         if(LTP == 1) {
1034             GBREG->copyLine(h, h - 1);
1035         } else {
1036             line1 = GBREG->getPixel(1, h - 1);
1037             line1 |= GBREG->getPixel(0, h - 1) << 1;
1038             line2 = 0;
1039             for(FX_DWORD w = 0; w < GBW; w++) {
1040                 if(USESKIP && SKIP->getPixel(w, h)) {
1041                     bVal = 0;
1042                 } else {
1043                     CONTEXT = line2;
1044                     CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1045                     CONTEXT |= line1 << 5;
1046                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1047                 }
1048                 if(bVal) {
1049                     GBREG->setPixel(w, h, bVal);
1050                 }
1051                 line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x1f;
1052                 line2 = ((line2 << 1) | bVal) & 0x0f;
1053             }
1054         }
1055     }
1056     return GBREG;
1057 }
1058 CJBig2_Image *CJBig2_GRDProc::decode_Arith_V2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
1059 {
1060     FX_BOOL LTP, SLTP, bVal;
1061     FX_DWORD CONTEXT;
1062     CJBig2_Image *GBREG;
1063     FX_DWORD line1, line2, line3;
1064     LTP = 0;
1065     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
1066     GBREG->fill(0);
1067     for(FX_DWORD h = 0; h < GBH; h++) {
1068         if(TPGDON) {
1069             switch(GBTEMPLATE) {
1070                 case 0:
1071                     CONTEXT = 0x9b25;
1072                     break;
1073                 case 1:
1074                     CONTEXT = 0x0795;
1075                     break;
1076                 case 2:
1077                     CONTEXT = 0x00e5;
1078                     break;
1079                 case 3:
1080                     CONTEXT = 0x0195;
1081                     break;
1082             }
1083             SLTP = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1084             LTP = LTP ^ SLTP;
1085         }
1086         if(LTP == 1) {
1087             GBREG->copyLine(h, h - 1);
1088         } else {
1089             switch(GBTEMPLATE) {
1090                 case 0: {
1091                         line1 = GBREG->getPixel(1, h - 2);
1092                         line1 |= GBREG->getPixel(0, h - 2) << 1;
1093                         line2 = GBREG->getPixel(2, h - 1);
1094                         line2 |= GBREG->getPixel(1, h - 1) << 1;
1095                         line2 |= GBREG->getPixel(0, h - 1) << 2;
1096                         line3 = 0;
1097                         for(FX_DWORD w = 0; w < GBW; w++) {
1098                             if(USESKIP && SKIP->getPixel(w, h)) {
1099                                 bVal = 0;
1100                             } else {
1101                                 CONTEXT = line3;
1102                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1103                                 CONTEXT |= line2 << 5;
1104                                 CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
1105                                 CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
1106                                 CONTEXT |= line1 << 12;
1107                                 CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
1108                                 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1109                             }
1110                             if(bVal) {
1111                                 GBREG->setPixel(w, h, bVal);
1112                             }
1113                             line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
1114                             line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
1115                             line3 = ((line3 << 1) | bVal) & 0x0f;
1116                         }
1117                     }
1118                     break;
1119                 case 1: {
1120                         line1 = GBREG->getPixel(2, h - 2);
1121                         line1 |= GBREG->getPixel(1, h - 2) << 1;
1122                         line1 |= GBREG->getPixel(0, h - 2) << 2;
1123                         line2 = GBREG->getPixel(2, h - 1);
1124                         line2 |= GBREG->getPixel(1, h - 1) << 1;
1125                         line2 |= GBREG->getPixel(0, h - 1) << 2;
1126                         line3 = 0;
1127                         for(FX_DWORD w = 0; w < GBW; w++) {
1128                             if(USESKIP && SKIP->getPixel(w, h)) {
1129                                 bVal = 0;
1130                             } else {
1131                                 CONTEXT = line3;
1132                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
1133                                 CONTEXT |= line2 << 4;
1134                                 CONTEXT |= line1 << 9;
1135                                 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1136                             }
1137                             if(bVal) {
1138                                 GBREG->setPixel(w, h, bVal);
1139                             }
1140                             line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
1141                             line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
1142                             line3 = ((line3 << 1) | bVal) & 0x07;
1143                         }
1144                     }
1145                     break;
1146                 case 2: {
1147                         line1 = GBREG->getPixel(1, h - 2);
1148                         line1 |= GBREG->getPixel(0, h - 2) << 1;
1149                         line2 = GBREG->getPixel(1, h - 1);
1150                         line2 |= GBREG->getPixel(0, h - 1) << 1;
1151                         line3 = 0;
1152                         for(FX_DWORD w = 0; w < GBW; w++) {
1153                             if(USESKIP && SKIP->getPixel(w, h)) {
1154                                 bVal = 0;
1155                             } else {
1156                                 CONTEXT = line3;
1157                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
1158                                 CONTEXT |= line2 << 3;
1159                                 CONTEXT |= line1 << 7;
1160                                 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1161                             }
1162                             if(bVal) {
1163                                 GBREG->setPixel(w, h, bVal);
1164                             }
1165                             line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
1166                             line2 = ((line2 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x0f;
1167                             line3 = ((line3 << 1) | bVal) & 0x03;
1168                         }
1169                     }
1170                     break;
1171                 case 3: {
1172                         line1 = GBREG->getPixel(1, h - 1);
1173                         line1 |= GBREG->getPixel(0, h - 1) << 1;
1174                         line2 = 0;
1175                         for(FX_DWORD w = 0; w < GBW; w++) {
1176                             if(USESKIP && SKIP->getPixel(w, h)) {
1177                                 bVal = 0;
1178                             } else {
1179                                 CONTEXT = line2;
1180                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1181                                 CONTEXT |= line1 << 5;
1182                                 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1183                             }
1184                             if(bVal) {
1185                                 GBREG->setPixel(w, h, bVal);
1186                             }
1187                             line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x1f;
1188                             line2 = ((line2 << 1) | bVal) & 0x0f;
1189                         }
1190                     }
1191                     break;
1192             }
1193         }
1194     }
1195     return GBREG;
1196 }
1197 CJBig2_Image *CJBig2_GRDProc::decode_Arith_V1(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
1198 {
1199     FX_BOOL LTP, SLTP, bVal;
1200     FX_DWORD CONTEXT = 0;
1201     CJBig2_Image *GBREG;
1202     LTP = 0;
1203     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
1204     GBREG->fill(0);
1205     for(FX_DWORD h = 0; h < GBH; h++) {
1206         if(TPGDON) {
1207             switch(GBTEMPLATE) {
1208                 case 0:
1209                     CONTEXT = 0x9b25;
1210                     break;
1211                 case 1:
1212                     CONTEXT = 0x0795;
1213                     break;
1214                 case 2:
1215                     CONTEXT = 0x00e5;
1216                     break;
1217                 case 3:
1218                     CONTEXT = 0x0195;
1219                     break;
1220             }
1221             SLTP = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1222             LTP = LTP ^ SLTP;
1223         }
1224         if(LTP == 1) {
1225             for(FX_DWORD w = 0; w < GBW; w++) {
1226                 GBREG->setPixel(w, h, GBREG->getPixel(w, h - 1));
1227             }
1228         } else {
1229             for(FX_DWORD w = 0; w < GBW; w++) {
1230                 if(USESKIP && SKIP->getPixel(w, h)) {
1231                     GBREG->setPixel(w, h, 0);
1232                 } else {
1233                     CONTEXT = 0;
1234                     switch(GBTEMPLATE) {
1235                         case 0:
1236                             CONTEXT |= GBREG->getPixel(w - 1, h);
1237                             CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1238                             CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
1239                             CONTEXT |= GBREG->getPixel(w - 4, h) << 3;
1240                             CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1241                             CONTEXT |= GBREG->getPixel(w + 2, h - 1) << 5;
1242                             CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 6;
1243                             CONTEXT |= GBREG->getPixel(w, h - 1) << 7;
1244                             CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 8;
1245                             CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 9;
1246                             CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
1247                             CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
1248                             CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 12;
1249                             CONTEXT |= GBREG->getPixel(w, h - 2) << 13;
1250                             CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 14;
1251                             CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
1252                             break;
1253                         case 1:
1254                             CONTEXT |= GBREG->getPixel(w - 1, h);
1255                             CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1256                             CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
1257                             CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
1258                             CONTEXT |= GBREG->getPixel(w + 2, h - 1) << 4;
1259                             CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 5;
1260                             CONTEXT |= GBREG->getPixel(w, h - 1) << 6;
1261                             CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 7;
1262                             CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 8;
1263                             CONTEXT |= GBREG->getPixel(w + 2, h - 2) << 9;
1264                             CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 10;
1265                             CONTEXT |= GBREG->getPixel(w, h - 2) << 11;
1266                             CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 12;
1267                             break;
1268                         case 2:
1269                             CONTEXT |= GBREG->getPixel(w - 1, h);
1270                             CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1271                             CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
1272                             CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 3;
1273                             CONTEXT |= GBREG->getPixel(w, h - 1) << 4;
1274                             CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 5;
1275                             CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 6;
1276                             CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 7;
1277                             CONTEXT |= GBREG->getPixel(w, h - 2) << 8;
1278                             CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 9;
1279                             break;
1280                         case 3:
1281                             CONTEXT |= GBREG->getPixel(w - 1, h);
1282                             CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1283                             CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
1284                             CONTEXT |= GBREG->getPixel(w - 4, h) << 3;
1285                             CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1286                             CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 5;
1287                             CONTEXT |= GBREG->getPixel(w, h - 1) << 6;
1288                             CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 7;
1289                             CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 8;
1290                             CONTEXT |= GBREG->getPixel(w - 3, h - 1) << 9;
1291                             break;
1292                     }
1293                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1294                     GBREG->setPixel(w, h, bVal);
1295                 }
1296             }
1297         }
1298     }
1299     return GBREG;
1300 }
1301 CJBig2_Image *CJBig2_GRDProc::decode_MMR(CJBig2_BitStream *pStream)
1302 {
1303     int bitpos, i;
1304     CJBig2_Image *pImage;
1305     JBIG2_ALLOC(pImage, CJBig2_Image(GBW, GBH));
1306     if (pImage->m_pData == NULL) {
1307         delete pImage;
1308         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
1309         return NULL;
1310     }
1311     bitpos = (int)pStream->getBitPos();
1312     _FaxG4Decode(m_pModule, pStream->getBuf(), pStream->getLength(), &bitpos, pImage->m_pData, GBW, GBH, pImage->m_nStride);
1313     pStream->setBitPos(bitpos);
1314     for(i = 0; (FX_DWORD)i < pImage->m_nStride * GBH; i++) {
1315         pImage->m_pData[i] = ~pImage->m_pData[i];
1316     }
1317     return pImage;
1318 }
1319 CJBig2_Image *CJBig2_GRRDProc::decode(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1320 {
1321     if (GRW == 0 || GRH == 0) {
1322         CJBig2_Image* pImage;
1323         JBIG2_ALLOC(pImage, CJBig2_Image(GRW, GRH));
1324         return pImage;
1325     }
1326     if(GRTEMPLATE == 0) {
1327         if((GRAT[0] == (signed char) - 1) && (GRAT[1] == (signed char) - 1)
1328                 && (GRAT[2] == (signed char) - 1) && (GRAT[3] == (signed char) - 1)
1329                 && (GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
1330             return decode_Template0_opt(pArithDecoder, grContext);
1331         } else {
1332             return decode_Template0_unopt(pArithDecoder, grContext);
1333         }
1334     } else {
1335         if((GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
1336             return decode_Template1_opt(pArithDecoder, grContext);
1337         } else {
1338             return decode_Template1_unopt(pArithDecoder, grContext);
1339         }
1340     }
1341 }
1342 CJBig2_Image *CJBig2_GRRDProc::decode_Template0_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1343 {
1344     FX_BOOL LTP, SLTP, bVal;
1345     FX_DWORD CONTEXT;
1346     CJBig2_Image *GRREG;
1347     FX_DWORD line1, line2, line3, line4, line5;
1348     LTP = 0;
1349     JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1350     GRREG->fill(0);
1351     for(FX_DWORD h = 0; h < GRH; h++) {
1352         if(TPGRON) {
1353             SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
1354             LTP = LTP ^ SLTP;
1355         }
1356         if(LTP == 0) {
1357             line1 = GRREG->getPixel(1, h - 1);
1358             line1 |= GRREG->getPixel(0, h - 1) << 1;
1359             line2 = 0;
1360             line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
1361             line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1) << 1;
1362             line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1363             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1364             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1365             line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1366             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1367             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1368             for(FX_DWORD w = 0; w < GRW; w++) {
1369                 CONTEXT = line5;
1370                 CONTEXT |= line4 << 3;
1371                 CONTEXT |= line3 << 6;
1372                 CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1373                 CONTEXT |= line2 << 9;
1374                 CONTEXT |= line1 << 10;
1375                 CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1376                 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1377                 GRREG->setPixel(w, h, bVal);
1378                 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
1379                 line2 = ((line2 << 1) | bVal) & 0x01;
1380                 line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY - 1)) & 0x03;
1381                 line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1382                 line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x07;
1383             }
1384         } else {
1385             line1 = GRREG->getPixel(1, h - 1);
1386             line1 |= GRREG->getPixel(0, h - 1) << 1;
1387             line2 = 0;
1388             line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
1389             line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1) << 1;
1390             line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1391             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1392             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1393             line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1394             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1395             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1396             for(FX_DWORD w = 0; w < GRW; w++) {
1397                 bVal = GRREFERENCE->getPixel(w, h);
1398                 if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
1399                         && (bVal == GRREFERENCE->getPixel(w, h - 1))
1400                         && (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
1401                         && (bVal == GRREFERENCE->getPixel(w - 1, h))
1402                         && (bVal == GRREFERENCE->getPixel(w + 1, h))
1403                         && (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
1404                         && (bVal == GRREFERENCE->getPixel(w, h + 1))
1405                         && (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
1406                     CONTEXT = line5;
1407                     CONTEXT |= line4 << 3;
1408                     CONTEXT |= line3 << 6;
1409                     CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1410                     CONTEXT |= line2 << 9;
1411                     CONTEXT |= line1 << 10;
1412                     CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1413                     bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1414                 }
1415                 GRREG->setPixel(w, h, bVal);
1416                 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
1417                 line2 = ((line2 << 1) | bVal) & 0x01;
1418                 line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY - 1)) & 0x03;
1419                 line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1420                 line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x07;
1421             }
1422         }
1423     }
1424     return GRREG;
1425 }
1426 CJBig2_Image *CJBig2_GRRDProc::decode_Template0_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1427 {
1428     FX_BOOL LTP, SLTP, bVal;
1429     FX_DWORD CONTEXT;
1430     CJBig2_Image *GRREG;
1431     FX_DWORD line1, line1_r, line2_r, line3_r;
1432     FX_BYTE *pLine, *pLineR, cVal;
1433     FX_INTPTR nStride, nStrideR, nOffset;
1434     FX_INT32 k, nBits;
1435     FX_INT32 GRWR, GRHR;
1436     FX_INT32 GRW, GRH;
1437     GRW = (FX_INT32)CJBig2_GRRDProc::GRW;
1438     GRH = (FX_INT32)CJBig2_GRRDProc::GRH;
1439     LTP = 0;
1440     JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1441     if (GRREG->m_pData == NULL) {
1442         delete GRREG;
1443         m_pModule->JBig2_Error("Generic refinement region decoding procedure: Create Image Failed with width = %d, height = %d\n", GRW, GRH);
1444         return NULL;
1445     }
1446     pLine = GRREG->m_pData;
1447     pLineR = GRREFERENCE->m_pData;
1448     nStride = GRREG->m_nStride;
1449     nStrideR = GRREFERENCE->m_nStride;
1450     GRWR = (FX_INT32)GRREFERENCE->m_nWidth;
1451     GRHR = (FX_INT32)GRREFERENCE->m_nHeight;
1452     if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
1453         GRREFERENCEDY = 0;
1454     }
1455     nOffset = -GRREFERENCEDY * nStrideR;
1456     for (FX_INT32 h = 0; h < GRH; h++) {
1457         if(TPGRON) {
1458             SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
1459             LTP = LTP ^ SLTP;
1460         }
1461         line1 = (h > 0) ? pLine[-nStride] << 4 : 0;
1462         FX_INT32 reference_h = h - GRREFERENCEDY;
1463         FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
1464         FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
1465         FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
1466         line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
1467         line2_r = line2_r_ok ? pLineR[nOffset] : 0;
1468         line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
1469         if(LTP == 0) {
1470             CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0)
1471                       | ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
1472             for (FX_INT32 w = 0; w < GRW; w += 8) {
1473                 nBits = GRW - w > 8 ? 8 : GRW - w;
1474                 if (h > 0)
1475                     line1 = (line1 << 8) |
1476                             (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
1477                 if (h > GRHR + GRREFERENCEDY + 1) {
1478                     line1_r = 0;
1479                     line2_r  = 0;
1480                     line3_r = 0;
1481                 } else {
1482                     if(line1_r_ok)
1483                         line1_r = (line1_r << 8) |
1484                                   (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1485                     if(line2_r_ok)
1486                         line2_r = (line2_r << 8) |
1487                                   (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1488                     if(line3_r_ok)
1489                         line3_r = (line3_r << 8) |
1490                                   (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1491                     else {
1492                         line3_r = 0;
1493                     }
1494                 }
1495                 cVal = 0;
1496                 for (k = 0; k < nBits; k++) {
1497                     bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1498                     cVal |= bVal << (7 - k);
1499                     CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
1500                               ((line1 >> (7 - k)) & 0x0400) |
1501                               ((line1_r >> (7 - k)) & 0x0040) |
1502                               ((line2_r >> (10 - k)) & 0x0008) |
1503                               ((line3_r >> (13 - k)) & 0x0001);
1504                 }
1505                 pLine[w >> 3] = cVal;
1506             }
1507         } else {
1508             CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0)
1509                       | ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
1510             for (FX_INT32 w = 0; w < GRW; w += 8) {
1511                 nBits = GRW - w > 8 ? 8 : GRW - w;
1512                 if (h > 0)
1513                     line1 = (line1 << 8) |
1514                             (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
1515                 if(line1_r_ok)
1516                     line1_r = (line1_r << 8) |
1517                               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1518                 if(line2_r_ok)
1519                     line2_r = (line2_r << 8) |
1520                               (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1521                 if(line3_r_ok)
1522                     line3_r = (line3_r << 8) |
1523                               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1524                 else {
1525                     line3_r = 0;
1526                 }
1527                 cVal = 0;
1528                 for (k = 0; k < nBits; k++) {
1529                     bVal = GRREFERENCE->getPixel(w + k, h);
1530                     if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1))
1531                             && (bVal == GRREFERENCE->getPixel(w + k, h - 1))
1532                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1))
1533                             && (bVal == GRREFERENCE->getPixel(w + k - 1, h))
1534                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h))
1535                             && (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1))
1536                             && (bVal == GRREFERENCE->getPixel(w + k, h + 1))
1537                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
1538                         bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1539                     }
1540                     cVal |= bVal << (7 - k);
1541                     CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
1542                               ((line1 >> (7 - k)) & 0x0400) |
1543                               ((line1_r >> (7 - k)) & 0x0040) |
1544                               ((line2_r >> (10 - k)) & 0x0008) |
1545                               ((line3_r >> (13 - k)) & 0x0001);
1546                 }
1547                 pLine[w >> 3] = cVal;
1548             }
1549         }
1550         pLine += nStride;
1551         if (h < GRHR + GRREFERENCEDY) {
1552             pLineR += nStrideR;
1553         }
1554     }
1555     return GRREG;
1556 }
1557 CJBig2_Image *CJBig2_GRRDProc::decode_Template1_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1558 {
1559     FX_BOOL LTP, SLTP, bVal;
1560     FX_DWORD CONTEXT;
1561     CJBig2_Image *GRREG;
1562     FX_DWORD line1, line2, line3, line4, line5;
1563     LTP = 0;
1564     JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1565     GRREG->fill(0);
1566     for(FX_DWORD h = 0; h < GRH; h++) {
1567         if(TPGRON) {
1568             SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
1569             LTP = LTP ^ SLTP;
1570         }
1571         if(LTP == 0) {
1572             line1 = GRREG->getPixel(1, h - 1);
1573             line1 |= GRREG->getPixel(0, h - 1) << 1;
1574             line1 |= GRREG->getPixel(-1, h - 1) << 2;
1575             line2 = 0;
1576             line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
1577             line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1578             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1579             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1580             line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1581             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1582             for(FX_DWORD w = 0; w < GRW; w++) {
1583                 CONTEXT = line5;
1584                 CONTEXT |= line4 << 2;
1585                 CONTEXT |= line3 << 5;
1586                 CONTEXT |= line2 << 6;
1587                 CONTEXT |= line1 << 7;
1588                 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1589                 GRREG->setPixel(w, h, bVal);
1590                 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
1591                 line2 = ((line2 << 1) | bVal) & 0x01;
1592                 line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1)) & 0x01;
1593                 line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1594                 line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x03;
1595             }
1596         } else {
1597             line1 = GRREG->getPixel(1, h - 1);
1598             line1 |= GRREG->getPixel(0, h - 1) << 1;
1599             line1 |= GRREG->getPixel(-1, h - 1) << 2;
1600             line2 = 0;
1601             line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
1602             line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1603             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1604             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1605             line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1606             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1607             for(FX_DWORD w = 0; w < GRW; w++) {
1608                 bVal = GRREFERENCE->getPixel(w, h);
1609                 if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
1610                         && (bVal == GRREFERENCE->getPixel(w, h - 1))
1611                         && (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
1612                         && (bVal == GRREFERENCE->getPixel(w - 1, h))
1613                         && (bVal == GRREFERENCE->getPixel(w + 1, h))
1614                         && (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
1615                         && (bVal == GRREFERENCE->getPixel(w, h + 1))
1616                         && (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
1617                     CONTEXT = line5;
1618                     CONTEXT |= line4 << 2;
1619                     CONTEXT |= line3 << 5;
1620                     CONTEXT |= line2 << 6;
1621                     CONTEXT |= line1 << 7;
1622                     bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1623                 }
1624                 GRREG->setPixel(w, h, bVal);
1625                 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
1626                 line2 = ((line2 << 1) | bVal) & 0x01;
1627                 line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1)) & 0x01;
1628                 line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1629                 line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x03;
1630             }
1631         }
1632     }
1633     return GRREG;
1634 }
1635 CJBig2_Image *CJBig2_GRRDProc::decode_Template1_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1636 {
1637     FX_BOOL LTP, SLTP, bVal;
1638     FX_DWORD CONTEXT;
1639     CJBig2_Image *GRREG;
1640     FX_DWORD line1, line1_r, line2_r, line3_r;
1641     FX_BYTE *pLine, *pLineR, cVal;
1642     FX_INTPTR nStride, nStrideR, nOffset;
1643     FX_INT32 k, nBits;
1644     FX_INT32 GRWR, GRHR;
1645     FX_INT32 GRW, GRH;
1646     GRW = (FX_INT32)CJBig2_GRRDProc::GRW;
1647     GRH = (FX_INT32)CJBig2_GRRDProc::GRH;
1648     LTP = 0;
1649     JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1650     if (GRREG->m_pData == NULL) {
1651         delete GRREG;
1652         m_pModule->JBig2_Error("Generic refinement region decoding procedure: Create Image Failed with width = %d, height = %d\n", GRW, GRH);
1653         return NULL;
1654     }
1655     pLine = GRREG->m_pData;
1656     pLineR = GRREFERENCE->m_pData;
1657     nStride = GRREG->m_nStride;
1658     nStrideR = GRREFERENCE->m_nStride;
1659     GRWR = (FX_INT32)GRREFERENCE->m_nWidth;
1660     GRHR = (FX_INT32)GRREFERENCE->m_nHeight;
1661     if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
1662         GRREFERENCEDY = 0;
1663     }
1664     nOffset = -GRREFERENCEDY * nStrideR;
1665     for (FX_INT32 h = 0; h < GRH; h++) {
1666         if(TPGRON) {
1667             SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
1668             LTP = LTP ^ SLTP;
1669         }
1670         line1 = (h > 0) ? pLine[-nStride] << 1 : 0;
1671         FX_INT32 reference_h = h - GRREFERENCEDY;
1672         FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
1673         FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
1674         FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
1675         line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
1676         line2_r = line2_r_ok ? pLineR[nOffset] : 0;
1677         line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
1678         if(LTP == 0) {
1679             CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020)
1680                       | ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
1681             for (FX_INT32 w = 0; w < GRW; w += 8) {
1682                 nBits = GRW - w > 8 ? 8 : GRW - w;
1683                 if (h > 0)
1684                     line1 = (line1 << 8) |
1685                             (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
1686                 if(line1_r_ok)
1687                     line1_r = (line1_r << 8) |
1688                               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1689                 if(line2_r_ok)
1690                     line2_r = (line2_r << 8) |
1691                               (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1692                 if(line3_r_ok)
1693                     line3_r = (line3_r << 8) |
1694                               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1695                 else {
1696                     line3_r = 0;
1697                 }
1698                 cVal = 0;
1699                 for (k = 0; k < nBits; k++) {
1700                     bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1701                     cVal |= bVal << (7 - k);
1702                     CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
1703                               ((line1 >> (7 - k)) & 0x0080) |
1704                               ((line1_r >> (9 - k)) & 0x0020) |
1705                               ((line2_r >> (11 - k)) & 0x0004) |
1706                               ((line3_r >> (13 - k)) & 0x0001);
1707                 }
1708                 pLine[w >> 3] = cVal;
1709             }
1710         } else {
1711             CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020)
1712                       | ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
1713             for (FX_INT32 w = 0; w < GRW; w += 8) {
1714                 nBits = GRW - w > 8 ? 8 : GRW - w;
1715                 if (h > 0)
1716                     line1 = (line1 << 8) |
1717                             (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
1718                 if(line1_r_ok)
1719                     line1_r = (line1_r << 8) |
1720                               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1721                 if(line2_r_ok)
1722                     line2_r = (line2_r << 8) |
1723                               (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1724                 if(line3_r_ok)
1725                     line3_r = (line3_r << 8) |
1726                               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1727                 else {
1728                     line3_r = 0;
1729                 }
1730                 cVal = 0;
1731                 for (k = 0; k < nBits; k++) {
1732                     bVal = GRREFERENCE->getPixel(w + k, h);
1733                     if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1))
1734                             && (bVal == GRREFERENCE->getPixel(w + k, h - 1))
1735                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1))
1736                             && (bVal == GRREFERENCE->getPixel(w + k - 1, h))
1737                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h))
1738                             && (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1))
1739                             && (bVal == GRREFERENCE->getPixel(w + k, h + 1))
1740                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
1741                         bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1742                     }
1743                     cVal |= bVal << (7 - k);
1744                     CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
1745                               ((line1 >> (7 - k)) & 0x0080) |
1746                               ((line1_r >> (9 - k)) & 0x0020) |
1747                               ((line2_r >> (11 - k)) & 0x0004) |
1748                               ((line3_r >> (13 - k)) & 0x0001);
1749                 }
1750                 pLine[w >> 3] = cVal;
1751             }
1752         }
1753         pLine += nStride;
1754         if (h < GRHR + GRREFERENCEDY) {
1755             pLineR += nStrideR;
1756         }
1757     }
1758     return GRREG;
1759 }
1760 CJBig2_Image *CJBig2_GRRDProc::decode_V1(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1761 {
1762     FX_BOOL LTP, SLTP, bVal;
1763     FX_BOOL TPGRPIX, TPGRVAL;
1764     FX_DWORD CONTEXT;
1765     CJBig2_Image *GRREG;
1766     LTP = 0;
1767     JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1768     GRREG->fill(0);
1769     for(FX_DWORD h = 0; h < GRH; h++) {
1770         if(TPGRON) {
1771             switch(GRTEMPLATE) {
1772                 case 0:
1773                     CONTEXT = 0x0010;
1774                     break;
1775                 case 1:
1776                     CONTEXT = 0x0008;
1777                     break;
1778             }
1779             SLTP = pArithDecoder->DECODE(&grContext[CONTEXT]);
1780             LTP = LTP ^ SLTP;
1781         }
1782         if(LTP == 0) {
1783             for(FX_DWORD w = 0; w < GRW; w++) {
1784                 CONTEXT = 0;
1785                 switch(GRTEMPLATE) {
1786                     case 0:
1787                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1788                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1789                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1790                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 3;
1791                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 4;
1792                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 5;
1793                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1) << 6;
1794                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 7;
1795                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1796                         CONTEXT |= GRREG->getPixel(w - 1, h) << 9;
1797                         CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 10;
1798                         CONTEXT |= GRREG->getPixel(w, h - 1) << 11;
1799                         CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1800                         break;
1801                     case 1:
1802                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1803                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1804                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 2;
1805                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 3;
1806                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 4;
1807                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 5;
1808                         CONTEXT |= GRREG->getPixel(w - 1, h) << 6;
1809                         CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 7;
1810                         CONTEXT |= GRREG->getPixel(w, h - 1) << 8;
1811                         CONTEXT |= GRREG->getPixel(w - 1, h - 1) << 9;
1812                         break;
1813                 }
1814                 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1815                 GRREG->setPixel(w, h, bVal);
1816             }
1817         } else {
1818             for(FX_DWORD w = 0; w < GRW; w++) {
1819                 bVal = GRREFERENCE->getPixel(w, h);
1820                 if(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
1821                         && (bVal == GRREFERENCE->getPixel(w, h - 1))
1822                         && (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
1823                         && (bVal == GRREFERENCE->getPixel(w - 1, h))
1824                         && (bVal == GRREFERENCE->getPixel(w + 1, h))
1825                         && (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
1826                         && (bVal == GRREFERENCE->getPixel(w, h + 1))
1827                         && (bVal == GRREFERENCE->getPixel(w + 1, h + 1))) {
1828                     TPGRPIX = 1;
1829                     TPGRVAL = bVal;
1830                 } else {
1831                     TPGRPIX = 0;
1832                 }
1833                 if(TPGRPIX) {
1834                     GRREG->setPixel(w, h, TPGRVAL);
1835                 } else {
1836                     CONTEXT = 0;
1837                     switch(GRTEMPLATE) {
1838                         case 0:
1839                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1840                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1841                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1842                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 3;
1843                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 4;
1844                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 5;
1845                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1) << 6;
1846                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 7;
1847                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1848                             CONTEXT |= GRREG->getPixel(w - 1, h) << 9;
1849                             CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 10;
1850                             CONTEXT |= GRREG->getPixel(w, h - 1) << 11;
1851                             CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1852                             break;
1853                         case 1:
1854                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1855                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1856                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 2;
1857                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 3;
1858                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 4;
1859                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 5;
1860                             CONTEXT |= GRREG->getPixel(w - 1, h) << 6;
1861                             CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 7;
1862                             CONTEXT |= GRREG->getPixel(w, h - 1) << 8;
1863                             CONTEXT |= GRREG->getPixel(w - 1, h - 1) << 9;
1864                             break;
1865                     }
1866                     bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1867                     GRREG->setPixel(w, h, bVal);
1868                 }
1869             }
1870         }
1871     }
1872     return GRREG;
1873 }
1874 CJBig2_Image *CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream *pStream, JBig2ArithCtx *grContext)
1875 {
1876     FX_INT32 STRIPT, FIRSTS;
1877     FX_DWORD NINSTANCES;
1878     FX_INT32 DT, DFS, CURS;
1879     FX_BYTE CURT;
1880     FX_INT32 SI, TI;
1881     FX_DWORD IDI;
1882     CJBig2_Image *IBI;
1883     FX_DWORD WI, HI;
1884     FX_INT32 IDS;
1885     FX_BOOL RI;
1886     FX_INT32 RDWI, RDHI, RDXI, RDYI;
1887     CJBig2_Image *IBOI;
1888     FX_DWORD WOI, HOI;
1889     CJBig2_Image *SBREG;
1890     FX_BOOL bFirst;
1891     FX_DWORD nTmp;
1892     FX_INT32 nVal, nBits;
1893     CJBig2_HuffmanDecoder *pHuffmanDecoder;
1894     CJBig2_GRRDProc *pGRRD;
1895     CJBig2_ArithDecoder *pArithDecoder;
1896     JBIG2_ALLOC(pHuffmanDecoder, CJBig2_HuffmanDecoder(pStream));
1897     JBIG2_ALLOC(SBREG, CJBig2_Image(SBW, SBH));
1898     SBREG->fill(SBDEFPIXEL);
1899     if(pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0) {
1900         m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1901         goto failed;
1902     }
1903     STRIPT *= SBSTRIPS;
1904     STRIPT = -STRIPT;
1905     FIRSTS = 0;
1906     NINSTANCES = 0;
1907     while(NINSTANCES < SBNUMINSTANCES) {
1908         if(pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0) {
1909             m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1910             goto failed;
1911         }
1912         DT *= SBSTRIPS;
1913         STRIPT = STRIPT + DT;
1914         bFirst = TRUE;
1915         for(;;) {
1916             if(bFirst) {
1917                 if(pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0) {
1918                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1919                     goto failed;
1920                 }
1921                 FIRSTS = FIRSTS + DFS;
1922                 CURS = FIRSTS;
1923                 bFirst = FALSE;
1924             } else {
1925                 nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS);
1926                 if(nVal == JBIG2_OOB) {
1927                     break;
1928                 } else if(nVal != 0) {
1929                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1930                     goto failed;
1931                 } else {
1932                     CURS = CURS + IDS + SBDSOFFSET;
1933                 }
1934             }
1935             if(SBSTRIPS == 1) {
1936                 CURT = 0;
1937             } else {
1938                 nTmp = 1;
1939                 while((FX_DWORD)(1 << nTmp) < SBSTRIPS) {
1940                     nTmp ++;
1941                 }
1942                 if(pStream->readNBits(nTmp, &nVal) != 0) {
1943                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1944                     goto failed;
1945                 }
1946                 CURT = nVal;
1947             }
1948             TI = STRIPT + CURT;
1949             nVal = 0;
1950             nBits = 0;
1951             for(;;) {
1952                 if(pStream->read1Bit(&nTmp) != 0) {
1953                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1954                     goto failed;
1955                 }
1956                 nVal = (nVal << 1) | nTmp;
1957                 nBits ++;
1958                 for(IDI = 0; IDI < SBNUMSYMS; IDI++) {
1959                     if((nBits == SBSYMCODES[IDI].codelen) && (nVal == SBSYMCODES[IDI].code)) {
1960                         break;
1961                     }
1962                 }
1963                 if(IDI < SBNUMSYMS) {
1964                     break;
1965                 }
1966             }
1967             if(SBREFINE == 0) {
1968                 RI = 0;
1969             } else {
1970                 if(pStream->read1Bit(&RI) != 0) {
1971                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1972                     goto failed;
1973                 }
1974             }
1975             if(RI == 0) {
1976                 IBI = SBSYMS[IDI];
1977             } else {
1978                 if((pHuffmanDecoder->decodeAValue(SBHUFFRDW, &RDWI) != 0)
1979                         || (pHuffmanDecoder->decodeAValue(SBHUFFRDH, &RDHI) != 0)
1980                         || (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0)
1981                         || (pHuffmanDecoder->decodeAValue(SBHUFFRDY, &RDYI) != 0)
1982                         || (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
1983                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1984                     goto failed;
1985                 }
1986                 pStream->alignByte();
1987                 nTmp = pStream->getOffset();
1988                 IBOI = SBSYMS[IDI];
1989                 if (!IBOI) {
1990                     goto failed;
1991                 }
1992                 WOI = IBOI->m_nWidth;
1993                 HOI = IBOI->m_nHeight;
1994                 if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
1995                     m_pModule->JBig2_Error("text region decoding procedure (huffman): Invalid RDWI or RDHI value.");
1996                     goto failed;
1997                 }
1998                 JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
1999                 pGRRD->GRW = WOI + RDWI;
2000                 pGRRD->GRH = HOI + RDHI;
2001                 pGRRD->GRTEMPLATE = SBRTEMPLATE;
2002                 pGRRD->GRREFERENCE = IBOI;
2003                 pGRRD->GRREFERENCEDX = (RDWI >> 2) + RDXI;
2004                 pGRRD->GRREFERENCEDY = (RDHI >> 2) + RDYI;
2005                 pGRRD->TPGRON = 0;
2006                 pGRRD->GRAT[0] = SBRAT[0];
2007                 pGRRD->GRAT[1] = SBRAT[1];
2008                 pGRRD->GRAT[2] = SBRAT[2];
2009                 pGRRD->GRAT[3] = SBRAT[3];
2010                 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(pStream));
2011                 IBI = pGRRD->decode(pArithDecoder, grContext);
2012                 if(IBI == NULL) {
2013                     delete pGRRD;
2014                     delete pArithDecoder;
2015                     goto failed;
2016                 }
2017                 delete pArithDecoder;
2018                 pStream->alignByte();
2019                 pStream->offset(2);
2020                 if((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
2021                     delete IBI;
2022                     delete pGRRD;
2023                     m_pModule->JBig2_Error("text region decoding procedure (huffman):"
2024                                            "bytes processed by generic refinement region decoding procedure doesn't equal SBHUFFRSIZE.");
2025                     goto failed;
2026                 }
2027                 delete pGRRD;
2028             }
2029             if (!IBI) {
2030                 continue;
2031             }
2032             WI = IBI->m_nWidth;
2033             HI = IBI->m_nHeight;
2034             if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT)
2035                                    || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
2036                 CURS = CURS + WI - 1;
2037             } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT)
2038                                           || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
2039                 CURS = CURS + HI - 1;
2040             }
2041             SI = CURS;
2042             if(TRANSPOSED == 0) {
2043                 switch(REFCORNER) {
2044                     case JBIG2_CORNER_TOPLEFT:
2045                         SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
2046                         break;
2047                     case JBIG2_CORNER_TOPRIGHT:
2048                         SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
2049                         break;
2050                     case JBIG2_CORNER_BOTTOMLEFT:
2051                         SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
2052                         break;
2053                     case JBIG2_CORNER_BOTTOMRIGHT:
2054                         SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
2055                         break;
2056                 }
2057             } else {
2058                 switch(REFCORNER) {
2059                     case JBIG2_CORNER_TOPLEFT:
2060                         SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
2061                         break;
2062                     case JBIG2_CORNER_TOPRIGHT:
2063                         SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
2064                         break;
2065                     case JBIG2_CORNER_BOTTOMLEFT:
2066                         SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
2067                         break;
2068                     case JBIG2_CORNER_BOTTOMRIGHT:
2069                         SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
2070                         break;
2071                 }
2072             }
2073             if(RI != 0) {
2074                 delete IBI;
2075             }
2076             if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2077                                    || (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
2078                 CURS = CURS + WI - 1;
2079             } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2080                                           || (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
2081                 CURS = CURS + HI - 1;
2082             }
2083             NINSTANCES = NINSTANCES + 1;
2084         }
2085     }
2086     delete pHuffmanDecoder;
2087     return SBREG;
2088 failed:
2089     delete pHuffmanDecoder;
2090     delete SBREG;
2091     return NULL;
2092 }
2093 CJBig2_Image *CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext,
2094         JBig2IntDecoderState *pIDS)
2095 {
2096     FX_INT32 STRIPT, FIRSTS;
2097     FX_DWORD NINSTANCES;
2098     FX_INT32 DT, DFS, CURS;
2099     FX_INT32 CURT;
2100     FX_INT32 SI, TI;
2101     FX_DWORD IDI;
2102     CJBig2_Image *IBI;
2103     FX_DWORD WI, HI;
2104     FX_INT32 IDS;
2105     FX_BOOL RI;
2106     FX_INT32 RDWI, RDHI, RDXI, RDYI;
2107     CJBig2_Image *IBOI;
2108     FX_DWORD WOI, HOI;
2109     CJBig2_Image *SBREG;
2110     FX_BOOL bFirst;
2111     FX_INT32 nRet, nVal;
2112     FX_INT32 bRetained;
2113     CJBig2_ArithIntDecoder *IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH, *IARDX, *IARDY;
2114     CJBig2_ArithIaidDecoder *IAID;
2115     CJBig2_GRRDProc *pGRRD;
2116     if(pIDS) {
2117         IADT = pIDS->IADT;
2118         IAFS = pIDS->IAFS;
2119         IADS = pIDS->IADS;
2120         IAIT = pIDS->IAIT;
2121         IARI = pIDS->IARI;
2122         IARDW = pIDS->IARDW;
2123         IARDH = pIDS->IARDH;
2124         IARDX = pIDS->IARDX;
2125         IARDY = pIDS->IARDY;
2126         IAID = pIDS->IAID;
2127         bRetained = TRUE;
2128     } else {
2129         JBIG2_ALLOC(IADT, CJBig2_ArithIntDecoder());
2130         JBIG2_ALLOC(IAFS, CJBig2_ArithIntDecoder());
2131         JBIG2_ALLOC(IADS, CJBig2_ArithIntDecoder());
2132         JBIG2_ALLOC(IAIT, CJBig2_ArithIntDecoder());
2133         JBIG2_ALLOC(IARI, CJBig2_ArithIntDecoder());
2134         JBIG2_ALLOC(IARDW, CJBig2_ArithIntDecoder());
2135         JBIG2_ALLOC(IARDH, CJBig2_ArithIntDecoder());
2136         JBIG2_ALLOC(IARDX, CJBig2_ArithIntDecoder());
2137         JBIG2_ALLOC(IARDY, CJBig2_ArithIntDecoder());
2138         JBIG2_ALLOC(IAID , CJBig2_ArithIaidDecoder(SBSYMCODELEN));
2139         bRetained = FALSE;
2140     }
2141     JBIG2_ALLOC(SBREG, CJBig2_Image(SBW, SBH));
2142     SBREG->fill(SBDEFPIXEL);
2143     if(IADT->decode(pArithDecoder, &STRIPT) == -1) {
2144         m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2145         goto failed;
2146     }
2147     STRIPT *= SBSTRIPS;
2148     STRIPT = -STRIPT;
2149     FIRSTS = 0;
2150     NINSTANCES = 0;
2151     while(NINSTANCES < SBNUMINSTANCES) {
2152         if(IADT->decode(pArithDecoder, &DT) == -1) {
2153             m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2154             goto failed;
2155         }
2156         DT *= SBSTRIPS;
2157         STRIPT = STRIPT + DT;
2158         bFirst = TRUE;
2159         for(;;) {
2160             if(bFirst) {
2161                 if(IAFS->decode(pArithDecoder, &DFS) == -1) {
2162                     m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2163                     goto failed;
2164                 }
2165                 FIRSTS = FIRSTS + DFS;
2166                 CURS = FIRSTS;
2167                 bFirst = FALSE;
2168             } else {
2169                 nRet = IADS->decode(pArithDecoder, &IDS);
2170                 if(nRet == JBIG2_OOB) {
2171                     break;
2172                 } else if(nRet != 0) {
2173                     m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2174                     goto failed;
2175                 } else {
2176                     CURS = CURS + IDS + SBDSOFFSET;
2177                 }
2178             }
2179             if (NINSTANCES >= SBNUMINSTANCES) {
2180                 break;
2181             }
2182             if(SBSTRIPS == 1) {
2183                 CURT = 0;
2184             } else {
2185                 if(IAIT->decode(pArithDecoder, &nVal) == -1) {
2186                     m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2187                     goto failed;
2188                 }
2189                 CURT = nVal;
2190             }
2191             TI = STRIPT + CURT;
2192             if(IAID->decode(pArithDecoder, &nVal) == -1) {
2193                 m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2194                 goto failed;
2195             }
2196             IDI = nVal;
2197             if(IDI >= SBNUMSYMS) {
2198                 m_pModule->JBig2_Error("text region decoding procedure (arith): symbol id out of range.(%d/%d)",
2199                                        IDI, SBNUMSYMS);
2200                 goto failed;
2201             }
2202             if(SBREFINE == 0) {
2203                 RI = 0;
2204             } else {
2205                 if(IARI->decode(pArithDecoder, &RI) == -1) {
2206                     m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2207                     goto failed;
2208                 }
2209             }
2210             if (!SBSYMS[IDI]) {
2211                 goto failed;
2212             }
2213             if(RI == 0) {
2214                 IBI = SBSYMS[IDI];
2215             } else {
2216                 if((IARDW->decode(pArithDecoder, &RDWI) == -1)
2217                         || (IARDH->decode(pArithDecoder, &RDHI) == -1)
2218                         || (IARDX->decode(pArithDecoder, &RDXI) == -1)
2219                         || (IARDY->decode(pArithDecoder, &RDYI) == -1)) {
2220                     m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2221                     goto failed;
2222                 }
2223                 IBOI = SBSYMS[IDI];
2224                 WOI = IBOI->m_nWidth;
2225                 HOI = IBOI->m_nHeight;
2226                 if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
2227                     m_pModule->JBig2_Error("text region decoding procedure (arith): Invalid RDWI or RDHI value.");
2228                     goto failed;
2229                 }
2230                 JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
2231                 pGRRD->GRW = WOI + RDWI;
2232                 pGRRD->GRH = HOI + RDHI;
2233                 pGRRD->GRTEMPLATE = SBRTEMPLATE;
2234                 pGRRD->GRREFERENCE = IBOI;
2235                 pGRRD->GRREFERENCEDX = (RDWI >> 1) + RDXI;
2236                 pGRRD->GRREFERENCEDY = (RDHI >> 1) + RDYI;
2237                 pGRRD->TPGRON = 0;
2238                 pGRRD->GRAT[0] = SBRAT[0];
2239                 pGRRD->GRAT[1] = SBRAT[1];
2240                 pGRRD->GRAT[2] = SBRAT[2];
2241                 pGRRD->GRAT[3] = SBRAT[3];
2242                 IBI = pGRRD->decode(pArithDecoder, grContext);
2243                 if(IBI == NULL) {
2244                     delete pGRRD;
2245                     goto failed;
2246                 }
2247                 delete pGRRD;
2248             }
2249             WI = IBI->m_nWidth;
2250             HI = IBI->m_nHeight;
2251             if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT)
2252                                    || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
2253                 CURS = CURS + WI - 1;
2254             } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT)
2255                                           || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
2256                 CURS = CURS + HI - 1;
2257             }
2258             SI = CURS;
2259             if(TRANSPOSED == 0) {
2260                 switch(REFCORNER) {
2261                     case JBIG2_CORNER_TOPLEFT:
2262                         SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
2263                         break;
2264                     case JBIG2_CORNER_TOPRIGHT:
2265                         SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
2266                         break;
2267                     case JBIG2_CORNER_BOTTOMLEFT:
2268                         SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
2269                         break;
2270                     case JBIG2_CORNER_BOTTOMRIGHT:
2271                         SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
2272                         break;
2273                 }
2274             } else {
2275                 switch(REFCORNER) {
2276                     case JBIG2_CORNER_TOPLEFT:
2277                         SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
2278                         break;
2279                     case JBIG2_CORNER_TOPRIGHT:
2280                         SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
2281                         break;
2282                     case JBIG2_CORNER_BOTTOMLEFT:
2283                         SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
2284                         break;
2285                     case JBIG2_CORNER_BOTTOMRIGHT:
2286                         SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
2287                         break;
2288                 }
2289             }
2290             if(RI != 0) {
2291                 delete IBI;
2292             }
2293             if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2294                                    || (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
2295                 CURS = CURS + WI - 1;
2296             } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2297                                           || (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
2298                 CURS = CURS + HI - 1;
2299             }
2300             NINSTANCES = NINSTANCES + 1;
2301         }
2302     }
2303     if(bRetained == FALSE) {
2304         delete IADT;
2305         delete IAFS;
2306         delete IADS;
2307         delete IAIT;
2308         delete IARI;
2309         delete IARDW;
2310         delete IARDH;
2311         delete IARDX;
2312         delete IARDY;
2313         delete IAID;
2314     }
2315     return SBREG;
2316 failed:
2317     if(bRetained == FALSE) {
2318         delete IADT;
2319         delete IAFS;
2320         delete IADS;
2321         delete IAIT;
2322         delete IARI;
2323         delete IARDW;
2324         delete IARDH;
2325         delete IARDX;
2326         delete IARDY;
2327         delete IAID;
2328     }
2329     delete SBREG;
2330     return NULL;
2331 }
2332 CJBig2_SymbolDict *CJBig2_SDDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder,
2333         JBig2ArithCtx *gbContext, JBig2ArithCtx *grContext)
2334 {
2335     CJBig2_Image **SDNEWSYMS;
2336     FX_DWORD HCHEIGHT, NSYMSDECODED;
2337     FX_INT32 HCDH;
2338     FX_DWORD SYMWIDTH, TOTWIDTH, HCFIRSTSYM;
2339     FX_INT32 DW;
2340     CJBig2_Image *BS;
2341     FX_DWORD I, J, REFAGGNINST;
2342     FX_BOOL *EXFLAGS;
2343     FX_DWORD EXINDEX;
2344     FX_BOOL CUREXFLAG;
2345     FX_DWORD EXRUNLENGTH;
2346     FX_INT32 nVal;
2347     FX_DWORD nTmp;
2348     FX_BOOL SBHUFF;
2349     FX_DWORD SBNUMSYMS;
2350     FX_BYTE SBSYMCODELEN;
2351     FX_DWORD IDI;
2352     FX_INT32 RDXI, RDYI;
2353     CJBig2_Image **SBSYMS;
2354     CJBig2_HuffmanTable *SBHUFFFS, *SBHUFFDS, *SBHUFFDT, *SBHUFFRDW, *SBHUFFRDH, *SBHUFFRDX, *SBHUFFRDY,
2355                         *SBHUFFRSIZE;
2356     CJBig2_GRRDProc *pGRRD;
2357     CJBig2_GRDProc *pGRD;
2358     CJBig2_ArithIntDecoder *IADH, *IADW, *IAAI, *IARDX, *IARDY, *IAEX,
2359                            *IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH;
2360     CJBig2_ArithIaidDecoder *IAID;
2361     CJBig2_SymbolDict *pDict;
2362     JBIG2_ALLOC(IADH, CJBig2_ArithIntDecoder());
2363     JBIG2_ALLOC(IADW, CJBig2_ArithIntDecoder());
2364     JBIG2_ALLOC(IAAI, CJBig2_ArithIntDecoder());
2365     JBIG2_ALLOC(IARDX, CJBig2_ArithIntDecoder());
2366     JBIG2_ALLOC(IARDY, CJBig2_ArithIntDecoder());
2367     JBIG2_ALLOC(IAEX, CJBig2_ArithIntDecoder());
2368     JBIG2_ALLOC(IADT, CJBig2_ArithIntDecoder());
2369     JBIG2_ALLOC(IAFS, CJBig2_ArithIntDecoder());
2370     JBIG2_ALLOC(IADS, CJBig2_ArithIntDecoder());
2371     JBIG2_ALLOC(IAIT, CJBig2_ArithIntDecoder());
2372     JBIG2_ALLOC(IARI, CJBig2_ArithIntDecoder());
2373     JBIG2_ALLOC(IARDW, CJBig2_ArithIntDecoder());
2374     JBIG2_ALLOC(IARDH, CJBig2_ArithIntDecoder());
2375     nTmp = 0;
2376     while((FX_DWORD)(1 << nTmp) < (SDNUMINSYMS + SDNUMNEWSYMS)) {
2377         nTmp ++;
2378     }
2379     JBIG2_ALLOC(IAID, CJBig2_ArithIaidDecoder((FX_BYTE)nTmp));
2380     SDNEWSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SDNUMNEWSYMS, sizeof(CJBig2_Image*));
2381     FXSYS_memset32(SDNEWSYMS, 0 , SDNUMNEWSYMS * sizeof(CJBig2_Image*));
2382     HCHEIGHT = 0;
2383     NSYMSDECODED = 0;
2384     while(NSYMSDECODED < SDNUMNEWSYMS) {
2385         BS = NULL;
2386         if(IADH->decode(pArithDecoder, &HCDH) == -1) {
2387             m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2388             goto failed;
2389         }
2390         HCHEIGHT = HCHEIGHT + HCDH;
2391         if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
2392             m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): invalid HCHEIGHT value.");
2393             goto failed;
2394         }
2395         SYMWIDTH = 0;
2396         TOTWIDTH = 0;
2397         HCFIRSTSYM = NSYMSDECODED;
2398         for(;;) {
2399             nVal = IADW->decode(pArithDecoder, &DW);
2400             if(nVal == JBIG2_OOB) {
2401                 break;
2402             } else if(nVal != 0) {
2403                 m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2404                 goto failed;
2405             } else {
2406                 if (NSYMSDECODED >= SDNUMNEWSYMS) {
2407                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): NSYMSDECODED >= SDNUMNEWSYMS.");
2408                     goto failed;
2409                 }
2410                 SYMWIDTH = SYMWIDTH + DW;
2411                 if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) {
2412                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): invalid SYMWIDTH value.");
2413                     goto failed;
2414                 } else if (HCHEIGHT == 0 || SYMWIDTH == 0) {
2415                     TOTWIDTH = TOTWIDTH + SYMWIDTH;
2416                     SDNEWSYMS[NSYMSDECODED] = NULL;
2417                     NSYMSDECODED = NSYMSDECODED + 1;
2418                     continue;
2419                 }
2420                 TOTWIDTH = TOTWIDTH + SYMWIDTH;
2421             }
2422             if(SDREFAGG == 0) {
2423                 JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
2424                 pGRD->MMR = 0;
2425                 pGRD->GBW = SYMWIDTH;
2426                 pGRD->GBH = HCHEIGHT;
2427                 pGRD->GBTEMPLATE = SDTEMPLATE;
2428                 pGRD->TPGDON = 0;
2429                 pGRD->USESKIP = 0;
2430                 pGRD->GBAT[0] = SDAT[0];
2431                 pGRD->GBAT[1] = SDAT[1];
2432                 pGRD->GBAT[2] = SDAT[2];
2433                 pGRD->GBAT[3] = SDAT[3];
2434                 pGRD->GBAT[4] = SDAT[4];
2435                 pGRD->GBAT[5] = SDAT[5];
2436                 pGRD->GBAT[6] = SDAT[6];
2437                 pGRD->GBAT[7] = SDAT[7];
2438                 BS = pGRD->decode_Arith(pArithDecoder, gbContext);
2439                 if(BS == NULL) {
2440                     delete pGRD;
2441                     goto failed;
2442                 }
2443                 delete pGRD;
2444             } else {
2445                 if(IAAI->decode(pArithDecoder, (int*)&REFAGGNINST) == -1) {
2446                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2447                     goto failed;
2448                 }
2449                 if(REFAGGNINST > 1) {
2450                     CJBig2_TRDProc *pDecoder;
2451                     JBIG2_ALLOC(pDecoder, CJBig2_TRDProc());
2452                     pDecoder->SBHUFF = SDHUFF;
2453                     pDecoder->SBREFINE = 1;
2454                     pDecoder->SBW = SYMWIDTH;
2455                     pDecoder->SBH = HCHEIGHT;
2456                     pDecoder->SBNUMINSTANCES = REFAGGNINST;
2457                     pDecoder->SBSTRIPS = 1;
2458                     pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
2459                     SBNUMSYMS = pDecoder->SBNUMSYMS;
2460                     nTmp = 0;
2461                     while((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
2462                         nTmp ++;
2463                     }
2464                     SBSYMCODELEN = (FX_BYTE)nTmp;
2465                     pDecoder->SBSYMCODELEN = SBSYMCODELEN;
2466                     SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(CJBig2_Image*));
2467                     JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2468                     JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*));
2469                     pDecoder->SBSYMS = SBSYMS;
2470                     pDecoder->SBDEFPIXEL = 0;
2471                     pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
2472                     pDecoder->TRANSPOSED = 0;
2473                     pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
2474                     pDecoder->SBDSOFFSET = 0;
2475                     JBIG2_ALLOC(SBHUFFFS, CJBig2_HuffmanTable(HuffmanTable_B6,
2476                                 sizeof(HuffmanTable_B6) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B6));
2477                     JBIG2_ALLOC(SBHUFFDS, CJBig2_HuffmanTable(HuffmanTable_B8,
2478                                 sizeof(HuffmanTable_B8) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B8));
2479                     JBIG2_ALLOC(SBHUFFDT, CJBig2_HuffmanTable(HuffmanTable_B11,
2480                                 sizeof(HuffmanTable_B11) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B11));
2481                     JBIG2_ALLOC(SBHUFFRDW, CJBig2_HuffmanTable(HuffmanTable_B15,
2482                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2483                     JBIG2_ALLOC(SBHUFFRDH, CJBig2_HuffmanTable(HuffmanTable_B15,
2484                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2485                     JBIG2_ALLOC(SBHUFFRDX, CJBig2_HuffmanTable(HuffmanTable_B15,
2486                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2487                     JBIG2_ALLOC(SBHUFFRDY, CJBig2_HuffmanTable(HuffmanTable_B15,
2488                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2489                     JBIG2_ALLOC(SBHUFFRSIZE, CJBig2_HuffmanTable(HuffmanTable_B1,
2490                                 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
2491                     pDecoder->SBHUFFFS = SBHUFFFS;
2492                     pDecoder->SBHUFFDS = SBHUFFDS;
2493                     pDecoder->SBHUFFDT = SBHUFFDT;
2494                     pDecoder->SBHUFFRDW = SBHUFFRDW;
2495                     pDecoder->SBHUFFRDH = SBHUFFRDH;
2496                     pDecoder->SBHUFFRDX = SBHUFFRDX;
2497                     pDecoder->SBHUFFRDY = SBHUFFRDY;
2498                     pDecoder->SBHUFFRSIZE = SBHUFFRSIZE;
2499                     pDecoder->SBRTEMPLATE = SDRTEMPLATE;
2500                     pDecoder->SBRAT[0] = SDRAT[0];
2501                     pDecoder->SBRAT[1] = SDRAT[1];
2502                     pDecoder->SBRAT[2] = SDRAT[2];
2503                     pDecoder->SBRAT[3] = SDRAT[3];
2504                     JBig2IntDecoderState ids;
2505                     ids.IADT = IADT;
2506                     ids.IAFS = IAFS;
2507                     ids.IADS = IADS;
2508                     ids.IAIT = IAIT;
2509                     ids.IARI = IARI;
2510                     ids.IARDW = IARDW;
2511                     ids.IARDH = IARDH;
2512                     ids.IARDX = IARDX;
2513                     ids.IARDY = IARDY;
2514                     ids.IAID = IAID;
2515                     BS = pDecoder->decode_Arith(pArithDecoder, grContext, &ids);
2516                     if(BS == NULL) {
2517                         m_pModule->JBig2_Free(SBSYMS);
2518                         delete SBHUFFFS;
2519                         delete SBHUFFDS;
2520                         delete SBHUFFDT;
2521                         delete SBHUFFRDW;
2522                         delete SBHUFFRDH;
2523                         delete SBHUFFRDX;
2524                         delete SBHUFFRDY;
2525                         delete SBHUFFRSIZE;
2526                         delete pDecoder;
2527                         goto failed;
2528                     }
2529                     m_pModule->JBig2_Free(SBSYMS);
2530                     delete SBHUFFFS;
2531                     delete SBHUFFDS;
2532                     delete SBHUFFDT;
2533                     delete SBHUFFRDW;
2534                     delete SBHUFFRDH;
2535                     delete SBHUFFRDX;
2536                     delete SBHUFFRDY;
2537                     delete SBHUFFRSIZE;
2538                     delete pDecoder;
2539                 } else if(REFAGGNINST == 1) {
2540                     SBHUFF = SDHUFF;
2541                     SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
2542                     if(IAID->decode(pArithDecoder, (int*)&IDI) == -1) {
2543                         m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2544                         goto failed;
2545                     }
2546                     if((IARDX->decode(pArithDecoder, &RDXI) == -1)
2547                             || (IARDY->decode(pArithDecoder, &RDYI) == -1)) {
2548                         m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2549                         goto failed;
2550                     }
2551                     if (IDI >= SBNUMSYMS) {
2552                         m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith):"
2553                                                " refinement references unknown symbol %d", IDI);
2554                         goto failed;
2555                     }
2556                     SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(CJBig2_Image*));
2557                     JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2558                     JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*));
2559                     if (!SBSYMS[IDI]) {
2560                         m_pModule->JBig2_Free(SBSYMS);
2561                         goto failed;
2562                     }
2563                     JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
2564                     pGRRD->GRW = SYMWIDTH;
2565                     pGRRD->GRH = HCHEIGHT;
2566                     pGRRD->GRTEMPLATE = SDRTEMPLATE;
2567                     pGRRD->GRREFERENCE = SBSYMS[IDI];
2568                     pGRRD->GRREFERENCEDX = RDXI;
2569                     pGRRD->GRREFERENCEDY = RDYI;
2570                     pGRRD->TPGRON = 0;
2571                     pGRRD->GRAT[0] = SDRAT[0];
2572                     pGRRD->GRAT[1] = SDRAT[1];
2573                     pGRRD->GRAT[2] = SDRAT[2];
2574                     pGRRD->GRAT[3] = SDRAT[3];
2575                     BS = pGRRD->decode(pArithDecoder, grContext);
2576                     if(BS == NULL) {
2577                         m_pModule->JBig2_Free(SBSYMS);
2578                         delete pGRRD;
2579                         goto failed;
2580                     }
2581                     m_pModule->JBig2_Free(SBSYMS);
2582                     delete pGRRD;
2583                 }
2584             }
2585             SDNEWSYMS[NSYMSDECODED] = BS;
2586             BS = NULL;
2587             NSYMSDECODED = NSYMSDECODED + 1;
2588         }
2589     }
2590     EXINDEX = 0;
2591     CUREXFLAG = 0;
2592     EXFLAGS = (FX_BOOL*)m_pModule->JBig2_Malloc2(sizeof(FX_BOOL), (SDNUMINSYMS + SDNUMNEWSYMS));
2593     while(EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
2594         if(IAEX->decode(pArithDecoder, (int*)&EXRUNLENGTH) == -1) {
2595             m_pModule->JBig2_Free(EXFLAGS);
2596             m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2597             goto failed;
2598         }
2599         if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) {
2600             m_pModule->JBig2_Free(EXFLAGS);
2601             m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): Invalid EXRUNLENGTH value.");
2602             goto failed;
2603         }
2604         if(EXRUNLENGTH != 0) {
2605             for(I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) {
2606                 EXFLAGS[I] = CUREXFLAG;
2607             }
2608         }
2609         EXINDEX = EXINDEX + EXRUNLENGTH;
2610         CUREXFLAG = !CUREXFLAG;
2611     }
2612     JBIG2_ALLOC(pDict, CJBig2_SymbolDict());
2613     pDict->SDNUMEXSYMS = SDNUMEXSYMS;
2614     pDict->SDEXSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), SDNUMEXSYMS);
2615     I = J = 0;
2616     for(I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
2617         if(EXFLAGS[I] && J < SDNUMEXSYMS) {
2618             if(I < SDNUMINSYMS) {
2619                 JBIG2_ALLOC(pDict->SDEXSYMS[J], CJBig2_Image(*SDINSYMS[I]));
2620             } else {
2621                 pDict->SDEXSYMS[J] = SDNEWSYMS[I - SDNUMINSYMS];
2622             }
2623             J = J + 1;
2624         } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
2625             delete SDNEWSYMS[I - SDNUMINSYMS];
2626         }
2627     }
2628     if (J < SDNUMEXSYMS) {
2629         pDict->SDNUMEXSYMS = J;
2630     }
2631     m_pModule->JBig2_Free(EXFLAGS);
2632     m_pModule->JBig2_Free(SDNEWSYMS);
2633     delete IADH;
2634     delete IADW;
2635     delete IAAI;
2636     delete IARDX;
2637     delete IARDY;
2638     delete IAEX;
2639     delete IAID;
2640     delete IADT;
2641     delete IAFS;
2642     delete IADS;
2643     delete IAIT;
2644     delete IARI;
2645     delete IARDW;
2646     delete IARDH;
2647     return pDict;
2648 failed:
2649     for(I = 0; I < NSYMSDECODED; I++) {
2650         if (SDNEWSYMS[I]) {
2651             delete SDNEWSYMS[I];
2652             SDNEWSYMS[I] = NULL;
2653         }
2654     }
2655     m_pModule->JBig2_Free(SDNEWSYMS);
2656     delete IADH;
2657     delete IADW;
2658     delete IAAI;
2659     delete IARDX;
2660     delete IARDY;
2661     delete IAEX;
2662     delete IAID;
2663     delete IADT;
2664     delete IAFS;
2665     delete IADS;
2666     delete IAIT;
2667     delete IARI;
2668     delete IARDW;
2669     delete IARDH;
2670     return NULL;
2671 }
2672 CJBig2_SymbolDict *CJBig2_SDDProc::decode_Huffman(CJBig2_BitStream *pStream,
2673         JBig2ArithCtx *gbContext, JBig2ArithCtx *grContext, IFX_Pause* pPause)
2674 {
2675     CJBig2_Image **SDNEWSYMS;
2676     FX_DWORD *SDNEWSYMWIDTHS;
2677     FX_DWORD HCHEIGHT, NSYMSDECODED;
2678     FX_INT32 HCDH;
2679     FX_DWORD SYMWIDTH, TOTWIDTH, HCFIRSTSYM;
2680     FX_INT32 DW;
2681     CJBig2_Image *BS, *BHC;
2682     FX_DWORD I, J, REFAGGNINST;
2683     FX_BOOL *EXFLAGS;
2684     FX_DWORD EXINDEX;
2685     FX_BOOL CUREXFLAG;
2686     FX_DWORD EXRUNLENGTH;
2687     FX_INT32 nVal, nBits;
2688     FX_DWORD nTmp;
2689     FX_BOOL SBHUFF;
2690     FX_DWORD SBNUMSYMS;
2691     FX_BYTE SBSYMCODELEN;
2692     JBig2HuffmanCode *SBSYMCODES;
2693     FX_DWORD IDI;
2694     FX_INT32 RDXI, RDYI;
2695     FX_DWORD BMSIZE;
2696     FX_DWORD stride;
2697     CJBig2_Image **SBSYMS;
2698     CJBig2_HuffmanTable *SBHUFFFS, *SBHUFFDS, *SBHUFFDT, *SBHUFFRDW, *SBHUFFRDH, *SBHUFFRDX, *SBHUFFRDY,
2699                         *SBHUFFRSIZE, *pTable;
2700     CJBig2_HuffmanDecoder *pHuffmanDecoder;
2701     CJBig2_GRRDProc *pGRRD;
2702     CJBig2_ArithDecoder *pArithDecoder;
2703     CJBig2_GRDProc *pGRD;
2704     CJBig2_SymbolDict *pDict;
2705     JBIG2_ALLOC(pHuffmanDecoder, CJBig2_HuffmanDecoder(pStream));
2706     SDNEWSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SDNUMNEWSYMS, sizeof(CJBig2_Image*));
2707     FXSYS_memset32(SDNEWSYMS, 0 , SDNUMNEWSYMS * sizeof(CJBig2_Image*));
2708     SDNEWSYMWIDTHS = NULL;
2709     BHC = NULL;
2710     if(SDREFAGG == 0) {
2711         SDNEWSYMWIDTHS = (FX_DWORD *)m_pModule->JBig2_Malloc2(SDNUMNEWSYMS, sizeof(FX_DWORD));
2712         FXSYS_memset32(SDNEWSYMWIDTHS, 0 , SDNUMNEWSYMS * sizeof(FX_DWORD));
2713     }
2714     HCHEIGHT = 0;
2715     NSYMSDECODED = 0;
2716     BS = NULL;
2717     while(NSYMSDECODED < SDNUMNEWSYMS) {
2718         if(pHuffmanDecoder->decodeAValue(SDHUFFDH, &HCDH) != 0) {
2719             m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2720             goto failed;
2721         }
2722         HCHEIGHT = HCHEIGHT + HCDH;
2723         if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
2724             m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): invalid HCHEIGHT value.");
2725             goto failed;
2726         }
2727         SYMWIDTH = 0;
2728         TOTWIDTH = 0;
2729         HCFIRSTSYM = NSYMSDECODED;
2730         for(;;) {
2731             nVal = pHuffmanDecoder->decodeAValue(SDHUFFDW, &DW);
2732             if(nVal == JBIG2_OOB) {
2733                 break;
2734             } else if(nVal != 0) {
2735                 m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2736                 goto failed;
2737             } else {
2738                 if (NSYMSDECODED >= SDNUMNEWSYMS) {
2739                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): NSYMSDECODED >= SDNUMNEWSYMS.");
2740                     goto failed;
2741                 }
2742                 SYMWIDTH = SYMWIDTH + DW;
2743                 if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) {
2744                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): invalid SYMWIDTH value.");
2745                     goto failed;
2746                 } else if (HCHEIGHT == 0 || SYMWIDTH == 0) {
2747                     TOTWIDTH = TOTWIDTH + SYMWIDTH;
2748                     SDNEWSYMS[NSYMSDECODED] = NULL;
2749                     NSYMSDECODED = NSYMSDECODED + 1;
2750                     continue;
2751                 }
2752                 TOTWIDTH = TOTWIDTH + SYMWIDTH;
2753             }
2754             if(SDREFAGG == 1) {
2755                 if(pHuffmanDecoder->decodeAValue(SDHUFFAGGINST, (int*)&REFAGGNINST) != 0) {
2756                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2757                     goto failed;
2758                 }
2759                 BS = NULL;
2760                 if(REFAGGNINST > 1) {
2761                     CJBig2_TRDProc *pDecoder;
2762                     JBIG2_ALLOC(pDecoder, CJBig2_TRDProc());
2763                     pDecoder->SBHUFF = SDHUFF;
2764                     pDecoder->SBREFINE = 1;
2765                     pDecoder->SBW = SYMWIDTH;
2766                     pDecoder->SBH = HCHEIGHT;
2767                     pDecoder->SBNUMINSTANCES = REFAGGNINST;
2768                     pDecoder->SBSTRIPS = 1;
2769                     pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
2770                     SBNUMSYMS = pDecoder->SBNUMSYMS;
2771                     SBSYMCODES = (JBig2HuffmanCode*)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(JBig2HuffmanCode));
2772                     nTmp = 1;
2773                     while((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
2774                         nTmp ++;
2775                     }
2776                     for(I = 0; I < SBNUMSYMS; I++) {
2777                         SBSYMCODES[I].codelen = nTmp;
2778                         SBSYMCODES[I].code = I;
2779                     }
2780                     pDecoder->SBSYMCODES = SBSYMCODES;
2781                     SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(CJBig2_Image*));
2782                     JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2783                     JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*));
2784                     pDecoder->SBSYMS = SBSYMS;
2785                     pDecoder->SBDEFPIXEL = 0;
2786                     pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
2787                     pDecoder->TRANSPOSED = 0;
2788                     pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
2789                     pDecoder->SBDSOFFSET = 0;
2790                     JBIG2_ALLOC(SBHUFFFS, CJBig2_HuffmanTable(HuffmanTable_B6,
2791                                 sizeof(HuffmanTable_B6) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B6));
2792                     JBIG2_ALLOC(SBHUFFDS, CJBig2_HuffmanTable(HuffmanTable_B8,
2793                                 sizeof(HuffmanTable_B8) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B8));
2794                     JBIG2_ALLOC(SBHUFFDT, CJBig2_HuffmanTable(HuffmanTable_B11,
2795                                 sizeof(HuffmanTable_B11) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B11));
2796                     JBIG2_ALLOC(SBHUFFRDW, CJBig2_HuffmanTable(HuffmanTable_B15,
2797                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2798                     JBIG2_ALLOC(SBHUFFRDH, CJBig2_HuffmanTable(HuffmanTable_B15,
2799                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2800                     JBIG2_ALLOC(SBHUFFRDX, CJBig2_HuffmanTable(HuffmanTable_B15,
2801                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2802                     JBIG2_ALLOC(SBHUFFRDY, CJBig2_HuffmanTable(HuffmanTable_B15,
2803                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2804                     JBIG2_ALLOC(SBHUFFRSIZE, CJBig2_HuffmanTable(HuffmanTable_B1,
2805                                 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
2806                     pDecoder->SBHUFFFS = SBHUFFFS;
2807                     pDecoder->SBHUFFDS = SBHUFFDS;
2808                     pDecoder->SBHUFFDT = SBHUFFDT;
2809                     pDecoder->SBHUFFRDW = SBHUFFRDW;
2810                     pDecoder->SBHUFFRDH = SBHUFFRDH;
2811                     pDecoder->SBHUFFRDX = SBHUFFRDX;
2812                     pDecoder->SBHUFFRDY = SBHUFFRDY;
2813                     pDecoder->SBHUFFRSIZE = SBHUFFRSIZE;
2814                     pDecoder->SBRTEMPLATE = SDRTEMPLATE;
2815                     pDecoder->SBRAT[0] = SDRAT[0];
2816                     pDecoder->SBRAT[1] = SDRAT[1];
2817                     pDecoder->SBRAT[2] = SDRAT[2];
2818                     pDecoder->SBRAT[3] = SDRAT[3];
2819                     BS = pDecoder->decode_Huffman(pStream, grContext);
2820                     if(BS == NULL) {
2821                         m_pModule->JBig2_Free(SBSYMCODES);
2822                         m_pModule->JBig2_Free(SBSYMS);
2823                         delete SBHUFFFS;
2824                         delete SBHUFFDS;
2825                         delete SBHUFFDT;
2826                         delete SBHUFFRDW;
2827                         delete SBHUFFRDH;
2828                         delete SBHUFFRDX;
2829                         delete SBHUFFRDY;
2830                         delete SBHUFFRSIZE;