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