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