1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "JBig2_GeneralDecoder.h"
8 #include "JBig2_ArithDecoder.h"
9 #include "JBig2_ArithIntDecoder.h"
10 #include "JBig2_HuffmanDecoder.h"
11 #include "JBig2_HuffmanTable.h"
12 #include "JBig2_PatternDict.h"
13 
14 extern const JBig2ArithQe QeTable[] = {
15     { 0x5601,  1,  1, 1 },
16     { 0x3401,  2,  6, 0 },
17     { 0x1801,  3,  9, 0 },
18     { 0x0AC1,  4, 12, 0 },
19     { 0x0521,  5, 29, 0 },
20     { 0x0221, 38, 33, 0 },
21     { 0x5601,  7,  6, 1 },
22     { 0x5401,  8, 14, 0 },
23     { 0x4801,  9, 14, 0 },
24     { 0x3801, 10, 14, 0 },
25     { 0x3001, 11, 17, 0 },
26     { 0x2401, 12, 18, 0 },
27     { 0x1C01, 13, 20, 0 },
28     { 0x1601, 29, 21, 0 },
29     { 0x5601, 15, 14, 1 },
30     { 0x5401, 16, 14, 0 },
31     { 0x5101, 17, 15, 0 },
32     { 0x4801, 18, 16, 0 },
33     { 0x3801, 19, 17, 0 },
34     { 0x3401, 20, 18, 0 },
35     { 0x3001, 21, 19, 0 },
36     { 0x2801, 22, 19, 0 },
37     { 0x2401, 23, 20, 0 },
38     { 0x2201, 24, 21, 0 },
39     { 0x1C01, 25, 22, 0 },
40     { 0x1801, 26, 23, 0 },
41     { 0x1601, 27, 24, 0 },
42     { 0x1401, 28, 25, 0 },
43     { 0x1201, 29, 26, 0 },
44     { 0x1101, 30, 27, 0 },
45     { 0x0AC1, 31, 28, 0 },
46     { 0x09C1, 32, 29, 0 },
47     { 0x08A1, 33, 30, 0 },
48     { 0x0521, 34, 31, 0 },
49     { 0x0441, 35, 32, 0 },
50     { 0x02A1, 36, 33, 0 },
51     { 0x0221, 37, 34, 0 },
52     { 0x0141, 38, 35, 0 },
53     { 0x0111, 39, 36, 0 },
54     { 0x0085, 40, 37, 0 },
55     { 0x0049, 41, 38, 0 },
56     { 0x0025, 42, 39, 0 },
57     { 0x0015, 43, 40, 0 },
58     { 0x0009, 44, 41, 0 },
59     { 0x0005, 45, 42, 0 },
60     { 0x0001, 45, 43, 0 },
61     { 0x5601, 46, 46, 0 }
62 };
63 
64 extern const unsigned int JBIG2_QE_NUM = sizeof(QeTable) / sizeof(JBig2ArithQe);
65 
decode_Arith(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)66 CJBig2_Image *CJBig2_GRDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
67 {
68     if (GBW == 0 || GBH == 0) {
69         CJBig2_Image* pImage;
70         JBIG2_ALLOC(pImage, CJBig2_Image(GBW, GBH));
71         return pImage;
72     }
73     if(GBTEMPLATE == 0) {
74         if((GBAT[0] == 3) && (GBAT[1] == (signed char) - 1)
75                 && (GBAT[2] == (signed char) - 3) && (GBAT[3] == (signed char) - 1)
76                 && (GBAT[4] == 2) && (GBAT[5] == (signed char) - 2)
77                 && (GBAT[6] == (signed char) - 2) && (GBAT[7] == (signed char) - 2)) {
78             return decode_Arith_Template0_opt3(pArithDecoder, gbContext);
79         } else {
80             return decode_Arith_Template0_unopt(pArithDecoder, gbContext);
81         }
82     } else if(GBTEMPLATE == 1) {
83         if((GBAT[0] == 3) && (GBAT[1] == (signed char) - 1)) {
84             return decode_Arith_Template1_opt3(pArithDecoder, gbContext);
85         } else {
86             return decode_Arith_Template1_unopt(pArithDecoder, gbContext);
87         }
88     } else if(GBTEMPLATE == 2) {
89         if((GBAT[0] == 2) && (GBAT[1] == (signed char) - 1)) {
90             return decode_Arith_Template2_opt3(pArithDecoder, gbContext);
91         } else {
92             return decode_Arith_Template2_unopt(pArithDecoder, gbContext);
93         }
94     } else {
95         if((GBAT[0] == 2) && (GBAT[1] == (signed char) - 1)) {
96             return decode_Arith_Template3_opt3(pArithDecoder, gbContext);
97         } else {
98             return decode_Arith_Template3_unopt(pArithDecoder, gbContext);
99         }
100     }
101 }
decode_Arith_Template0_opt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)102 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
103 {
104     FX_BOOL LTP, SLTP, bVal;
105     FX_DWORD CONTEXT;
106     CJBig2_Image *GBREG;
107     FX_DWORD line1, line2, line3;
108     LTP = 0;
109     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
110     GBREG->fill(0);
111     for(FX_DWORD h = 0; h < GBH; h++) {
112         if(TPGDON) {
113             SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
114             LTP = LTP ^ SLTP;
115         }
116         if(LTP == 1) {
117             GBREG->copyLine(h, h - 1);
118         } else {
119             line1 = GBREG->getPixel(2, h - 2);
120             line1 |= GBREG->getPixel(1, h - 2) << 1;
121             line1 |= GBREG->getPixel(0, h - 2) << 2;
122             line2 = GBREG->getPixel(3, h - 1);
123             line2 |= GBREG->getPixel(2, h - 1) << 1;
124             line2 |= GBREG->getPixel(1, h - 1) << 2;
125             line2 |= GBREG->getPixel(0, h - 1) << 3;
126             line3 = 0;
127             for(FX_DWORD w = 0; w < GBW; w++) {
128                 if(USESKIP && SKIP->getPixel(w, h)) {
129                     bVal = 0;
130                 } else {
131                     CONTEXT = line3;
132                     CONTEXT |= line2 << 4;
133                     CONTEXT |= line1 << 11;
134                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
135                 }
136                 if(bVal) {
137                     GBREG->setPixel(w, h, bVal);
138                 }
139                 line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x1f;
140                 line2 = ((line2 << 1) | GBREG->getPixel(w + 4, h - 1)) & 0x7f;
141                 line3 = ((line3 << 1) | bVal) & 0x0f;
142             }
143         }
144     }
145     return GBREG;
146 }
decode_Arith_Template0_opt2(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)147 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
148 {
149     FX_BOOL LTP, SLTP, bVal;
150     FX_DWORD CONTEXT;
151     CJBig2_Image *GBREG;
152     FX_DWORD line1, line2;
153     FX_BYTE *pLine, cVal;
154     FX_INTPTR nStride, nStride2;
155     FX_INT32 nBits, k;
156     LTP = 0;
157     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
158     if (GBREG->m_pData == NULL) {
159         delete GBREG;
160         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
161         return NULL;
162     }
163     pLine = GBREG->m_pData;
164     nStride = GBREG->m_nStride;
165     nStride2 = nStride << 1;
166     for(FX_DWORD h = 0; h < GBH; h++) {
167         if(TPGDON) {
168             SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
169             LTP = LTP ^ SLTP;
170         }
171         if(LTP == 1) {
172             GBREG->copyLine(h, h - 1);
173         } else {
174             line1 = (h > 1) ? pLine[-nStride2] << 6 : 0;
175             line2 = (h > 0) ? pLine[-nStride] : 0;
176             CONTEXT = (line1 & 0xf800) | (line2 & 0x07f0);
177             for(FX_DWORD w = 0; w < GBW; w += 8) {
178                 if(w + 8 < GBW) {
179                     nBits = 8;
180                     if(h > 1) {
181                         line1 = (line1 << 8) | (pLine[-nStride2 + (w >> 3) + 1] << 6);
182                     }
183                     if(h > 0) {
184                         line2 = (line2 << 8) | (pLine[-nStride + (w >> 3) + 1]);
185                     }
186                 } else {
187                     nBits = GBW - w;
188                     if(h > 1) {
189                         line1 <<= 8;
190                     }
191                     if(h > 0) {
192                         line2 <<= 8;
193                     }
194                 }
195                 cVal = 0;
196                 for(k = 0; k < nBits; k++) {
197                     if(USESKIP && SKIP->getPixel(w, h)) {
198                         bVal = 0;
199                     } else {
200                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
201                     }
202                     cVal |= bVal << (7 - k);
203                     CONTEXT = ((CONTEXT & 0x7bf7) << 1) | bVal
204                               | ((line1 >> (7 - k)) & 0x0800)
205                               | ((line2 >> (7 - k)) & 0x0010);
206                 }
207                 pLine[w >> 3] = cVal;
208             }
209         }
210         pLine += nStride;
211     }
212     return GBREG;
213 }
decode_Arith_Template0_opt3(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)214 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
215 {
216     FX_BOOL LTP, SLTP, bVal;
217     FX_DWORD CONTEXT;
218     CJBig2_Image *GBREG;
219     FX_DWORD line1, line2;
220     FX_BYTE *pLine, *pLine1, *pLine2, cVal;
221     FX_INT32 nStride, nStride2, k;
222     FX_INT32 nLineBytes, nBitsLeft, cc;
223     LTP = 0;
224     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
225     if (GBREG->m_pData == NULL) {
226         delete GBREG;
227         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
228         return NULL;
229     }
230     pLine = GBREG->m_pData;
231     nStride = GBREG->m_nStride;
232     nStride2 = nStride << 1;
233     nLineBytes = ((GBW + 7) >> 3) - 1;
234     nBitsLeft = GBW - (nLineBytes << 3);
235     FX_DWORD height = GBH & 0x7fffffff;
236     for(FX_DWORD h = 0; h < height; h++) {
237         if(TPGDON) {
238             SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
239             LTP = LTP ^ SLTP;
240         }
241         if(LTP == 1) {
242             GBREG->copyLine(h, h - 1);
243         } else {
244             if(h > 1) {
245                 pLine1 = pLine - nStride2;
246                 pLine2 = pLine - nStride;
247                 line1 = (*pLine1++) << 6;
248                 line2 = *pLine2++;
249                 CONTEXT = ((line1 & 0xf800) | (line2 & 0x07f0));
250                 for(cc = 0; cc < nLineBytes; cc++) {
251                     line1 = (line1 << 8) | ((*pLine1++) << 6);
252                     line2 = (line2 << 8) | (*pLine2++);
253                     cVal = 0;
254                     for(k = 7; k >= 0; k--) {
255                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
256                         cVal |= bVal << k;
257                         CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
258                                    | ((line1 >> k) & 0x0800)
259                                    | ((line2 >> k) & 0x0010));
260                     }
261                     pLine[cc] = cVal;
262                 }
263                 line1 <<= 8;
264                 line2 <<= 8;
265                 cVal = 0;
266                 for(k = 0; k < nBitsLeft; k++) {
267                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
268                     cVal |= bVal << (7 - k);
269                     CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
270                                | ((line1 >> (7 - k)) & 0x0800)
271                                | ((line2 >> (7 - k)) & 0x0010));
272                 }
273                 pLine[nLineBytes] = cVal;
274             } else {
275                 pLine2 = pLine - nStride;
276                 line2 = (h & 1) ? (*pLine2++) : 0;
277                 CONTEXT = (line2 & 0x07f0);
278                 for(cc = 0; cc < nLineBytes; cc++) {
279                     if(h & 1) {
280                         line2 = (line2 << 8) | (*pLine2++);
281                     }
282                     cVal = 0;
283                     for(k = 7; k >= 0; k--) {
284                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
285                         cVal |= bVal << k;
286                         CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
287                                    | ((line2 >> k) & 0x0010));
288                     }
289                     pLine[cc] = cVal;
290                 }
291                 line2 <<= 8;
292                 cVal = 0;
293                 for(k = 0; k < nBitsLeft; k++) {
294                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
295                     cVal |= bVal << (7 - k);
296                     CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
297                                | (((line2 >> (7 - k))) & 0x0010));
298                 }
299                 pLine[nLineBytes] = cVal;
300             }
301         }
302         pLine += nStride;
303     }
304     return GBREG;
305 }
decode_Arith_Template0_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)306 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template0_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
307 {
308     FX_BOOL LTP, SLTP, bVal;
309     FX_DWORD CONTEXT;
310     CJBig2_Image *GBREG;
311     FX_DWORD line1, line2, line3;
312     LTP = 0;
313     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
314     GBREG->fill(0);
315     for(FX_DWORD h = 0; h < GBH; h++) {
316         if(TPGDON) {
317             SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
318             LTP = LTP ^ SLTP;
319         }
320         if(LTP == 1) {
321             GBREG->copyLine(h, h - 1);
322         } else {
323             line1 = GBREG->getPixel(1, h - 2);
324             line1 |= GBREG->getPixel(0, h - 2) << 1;
325             line2 = GBREG->getPixel(2, h - 1);
326             line2 |= GBREG->getPixel(1, h - 1) << 1;
327             line2 |= GBREG->getPixel(0, h - 1) << 2;
328             line3 = 0;
329             for(FX_DWORD w = 0; w < GBW; w++) {
330                 if(USESKIP && SKIP->getPixel(w, h)) {
331                     bVal = 0;
332                 } else {
333                     CONTEXT = line3;
334                     CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
335                     CONTEXT |= line2 << 5;
336                     CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
337                     CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
338                     CONTEXT |= line1 << 12;
339                     CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
340                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
341                 }
342                 if(bVal) {
343                     GBREG->setPixel(w, h, bVal);
344                 }
345                 line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
346                 line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
347                 line3 = ((line3 << 1) | bVal) & 0x0f;
348             }
349         }
350     }
351     return GBREG;
352 }
decode_Arith_Template1_opt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)353 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
354 {
355     FX_BOOL LTP, SLTP, bVal;
356     FX_DWORD CONTEXT;
357     CJBig2_Image *GBREG;
358     FX_DWORD line1, line2, line3;
359     LTP = 0;
360     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
361     GBREG->fill(0);
362     for(FX_DWORD h = 0; h < GBH; h++) {
363         if(TPGDON) {
364             SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
365             LTP = LTP ^ SLTP;
366         }
367         if(LTP == 1) {
368             GBREG->copyLine(h, h - 1);
369         } else {
370             line1 = GBREG->getPixel(2, h - 2);
371             line1 |= GBREG->getPixel(1, h - 2) << 1;
372             line1 |= GBREG->getPixel(0, h - 2) << 2;
373             line2 = GBREG->getPixel(3, h - 1);
374             line2 |= GBREG->getPixel(2, h - 1) << 1;
375             line2 |= GBREG->getPixel(1, h - 1) << 2;
376             line2 |= GBREG->getPixel(0, h - 1) << 3;
377             line3 = 0;
378             for(FX_DWORD w = 0; w < GBW; w++) {
379                 if(USESKIP && SKIP->getPixel(w, h)) {
380                     bVal = 0;
381                 } else {
382                     CONTEXT = line3;
383                     CONTEXT |= line2 << 3;
384                     CONTEXT |= line1 << 9;
385                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
386                 }
387                 if(bVal) {
388                     GBREG->setPixel(w, h, bVal);
389                 }
390                 line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
391                 line2 = ((line2 << 1) | GBREG->getPixel(w + 4, h - 1)) & 0x3f;
392                 line3 = ((line3 << 1) | bVal) & 0x07;
393             }
394         }
395     }
396     return GBREG;
397 }
decode_Arith_Template1_opt2(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)398 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
399 {
400     FX_BOOL LTP, SLTP, bVal;
401     FX_DWORD CONTEXT;
402     CJBig2_Image *GBREG;
403     FX_DWORD line1, line2;
404     FX_BYTE *pLine, cVal;
405     FX_INTPTR nStride, nStride2;
406     FX_INT32 nBits, k;
407     LTP = 0;
408     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
409     if (GBREG->m_pData == NULL) {
410         delete GBREG;
411         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
412         return NULL;
413     }
414     pLine = GBREG->m_pData;
415     nStride = GBREG->m_nStride;
416     nStride2 = nStride << 1;
417     for(FX_DWORD h = 0; h < GBH; h++) {
418         if(TPGDON) {
419             SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
420             LTP = LTP ^ SLTP;
421         }
422         if(LTP == 1) {
423             GBREG->copyLine(h, h - 1);
424         } else {
425             line1 = (h > 1) ? pLine[-nStride2] << 4 : 0;
426             line2 = (h > 0) ? pLine[-nStride] : 0;
427             CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
428             for(FX_DWORD w = 0; w < GBW; w += 8) {
429                 if(w + 8 < GBW) {
430                     nBits = 8;
431                     if(h > 1) {
432                         line1 = (line1 << 8) | (pLine[-nStride2 + (w >> 3) + 1] << 4);
433                     }
434                     if(h > 0) {
435                         line2 = (line2 << 8) | (pLine[-nStride + (w >> 3) + 1]);
436                     }
437                 } else {
438                     nBits = GBW - w;
439                     if(h > 1) {
440                         line1 <<= 8;
441                     }
442                     if(h > 0) {
443                         line2 <<= 8;
444                     }
445                 }
446                 cVal = 0;
447                 for(k = 0; k < nBits; k++) {
448                     if(USESKIP && SKIP->getPixel(w, h)) {
449                         bVal = 0;
450                     } else {
451                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
452                     }
453                     cVal |= bVal << (7 - k);
454                     CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
455                               | ((line1 >> (7 - k)) & 0x0200)
456                               | ((line2 >> (8 - k)) & 0x0008);
457                 }
458                 pLine[w >> 3] = cVal;
459             }
460         }
461         pLine += nStride;
462     }
463     return GBREG;
464 }
decode_Arith_Template1_opt3(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)465 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
466 {
467     FX_BOOL LTP, SLTP, bVal;
468     FX_DWORD CONTEXT;
469     CJBig2_Image *GBREG;
470     FX_DWORD line1, line2;
471     FX_BYTE *pLine, *pLine1, *pLine2, cVal;
472     FX_INT32 nStride, nStride2, k;
473     FX_INT32 nLineBytes, nBitsLeft, cc;
474     LTP = 0;
475     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
476     if (GBREG->m_pData == NULL) {
477         delete GBREG;
478         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
479         return NULL;
480     }
481     pLine = GBREG->m_pData;
482     nStride = GBREG->m_nStride;
483     nStride2 = nStride << 1;
484     nLineBytes = ((GBW + 7) >> 3) - 1;
485     nBitsLeft = GBW - (nLineBytes << 3);
486     for(FX_DWORD h = 0; h < GBH; h++) {
487         if(TPGDON) {
488             SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
489             LTP = LTP ^ SLTP;
490         }
491         if(LTP == 1) {
492             GBREG->copyLine(h, h - 1);
493         } else {
494             if(h > 1) {
495                 pLine1 = pLine - nStride2;
496                 pLine2 = pLine - nStride;
497                 line1 = (*pLine1++) << 4;
498                 line2 = *pLine2++;
499                 CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
500                 for(cc = 0; cc < nLineBytes; cc++) {
501                     line1 = (line1 << 8) | ((*pLine1++) << 4);
502                     line2 = (line2 << 8) | (*pLine2++);
503                     cVal = 0;
504                     for(k = 7; k >= 0; k--) {
505                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
506                         cVal |= bVal << k;
507                         CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
508                                   | ((line1 >> k) & 0x0200)
509                                   | ((line2 >> (k + 1)) & 0x0008);
510                     }
511                     pLine[cc] = cVal;
512                 }
513                 line1 <<= 8;
514                 line2 <<= 8;
515                 cVal = 0;
516                 for(k = 0; k < nBitsLeft; k++) {
517                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
518                     cVal |= bVal << (7 - k);
519                     CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
520                               | ((line1 >> (7 - k)) & 0x0200)
521                               | ((line2 >> (8 - k)) & 0x0008);
522                 }
523                 pLine[nLineBytes] = cVal;
524             } else {
525                 pLine2 = pLine - nStride;
526                 line2 = (h & 1) ? (*pLine2++) : 0;
527                 CONTEXT = (line2 >> 1) & 0x01f8;
528                 for(cc = 0; cc < nLineBytes; cc++) {
529                     if(h & 1) {
530                         line2 = (line2 << 8) | (*pLine2++);
531                     }
532                     cVal = 0;
533                     for(k = 7; k >= 0; k--) {
534                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
535                         cVal |= bVal << k;
536                         CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
537                                   | ((line2 >> (k + 1)) & 0x0008);
538                     }
539                     pLine[cc] = cVal;
540                 }
541                 line2 <<= 8;
542                 cVal = 0;
543                 for(k = 0; k < nBitsLeft; k++) {
544                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
545                     cVal |= bVal << (7 - k);
546                     CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
547                               | ((line2 >> (8 - k)) & 0x0008);
548                 }
549                 pLine[nLineBytes] = cVal;
550             }
551         }
552         pLine += nStride;
553     }
554     return GBREG;
555 }
decode_Arith_Template1_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)556 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template1_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
557 {
558     FX_BOOL LTP, SLTP, bVal;
559     FX_DWORD CONTEXT;
560     CJBig2_Image *GBREG;
561     FX_DWORD line1, line2, line3;
562     LTP = 0;
563     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
564     GBREG->fill(0);
565     for(FX_DWORD h = 0; h < GBH; h++) {
566         if(TPGDON) {
567             SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
568             LTP = LTP ^ SLTP;
569         }
570         if(LTP == 1) {
571             GBREG->copyLine(h, h - 1);
572         } else {
573             line1 = GBREG->getPixel(2, h - 2);
574             line1 |= GBREG->getPixel(1, h - 2) << 1;
575             line1 |= GBREG->getPixel(0, h - 2) << 2;
576             line2 = GBREG->getPixel(2, h - 1);
577             line2 |= GBREG->getPixel(1, h - 1) << 1;
578             line2 |= GBREG->getPixel(0, h - 1) << 2;
579             line3 = 0;
580             for(FX_DWORD w = 0; w < GBW; w++) {
581                 if(USESKIP && SKIP->getPixel(w, h)) {
582                     bVal = 0;
583                 } else {
584                     CONTEXT = line3;
585                     CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
586                     CONTEXT |= line2 << 4;
587                     CONTEXT |= line1 << 9;
588                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
589                 }
590                 if(bVal) {
591                     GBREG->setPixel(w, h, bVal);
592                 }
593                 line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
594                 line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
595                 line3 = ((line3 << 1) | bVal) & 0x07;
596             }
597         }
598     }
599     return GBREG;
600 }
decode_Arith_Template2_opt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)601 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
602 {
603     FX_BOOL LTP, SLTP, bVal;
604     FX_DWORD CONTEXT;
605     CJBig2_Image *GBREG;
606     FX_DWORD line1, line2, line3;
607     LTP = 0;
608     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
609     GBREG->fill(0);
610     for(FX_DWORD h = 0; h < GBH; h++) {
611         if(TPGDON) {
612             SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
613             LTP = LTP ^ SLTP;
614         }
615         if(LTP == 1) {
616             GBREG->copyLine(h, h - 1);
617         } else {
618             line1 = GBREG->getPixel(1, h - 2);
619             line1 |= GBREG->getPixel(0, h - 2) << 1;
620             line2 = GBREG->getPixel(2, h - 1);
621             line2 |= GBREG->getPixel(1, h - 1) << 1;
622             line2 |= GBREG->getPixel(0, h - 1) << 2;
623             line3 = 0;
624             for(FX_DWORD w = 0; w < GBW; w++) {
625                 if(USESKIP && SKIP->getPixel(w, h)) {
626                     bVal = 0;
627                 } else {
628                     CONTEXT = line3;
629                     CONTEXT |= line2 << 2;
630                     CONTEXT |= line1 << 7;
631                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
632                 }
633                 if(bVal) {
634                     GBREG->setPixel(w, h, bVal);
635                 }
636                 line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
637                 line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
638                 line3 = ((line3 << 1) | bVal) & 0x03;
639             }
640         }
641     }
642     return GBREG;
643 }
decode_Arith_Template2_opt2(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)644 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
645 {
646     FX_BOOL LTP, SLTP, bVal;
647     FX_DWORD CONTEXT;
648     CJBig2_Image *GBREG;
649     FX_DWORD line1, line2;
650     FX_BYTE *pLine, cVal;
651     FX_INTPTR nStride, nStride2;
652     FX_INT32 nBits, k;
653     LTP = 0;
654     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
655     if (GBREG->m_pData == NULL) {
656         delete GBREG;
657         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
658         return NULL;
659     }
660     pLine = GBREG->m_pData;
661     nStride = GBREG->m_nStride;
662     nStride2 = nStride << 1;
663     for(FX_DWORD h = 0; h < GBH; h++) {
664         if(TPGDON) {
665             SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
666             LTP = LTP ^ SLTP;
667         }
668         if(LTP == 1) {
669             GBREG->copyLine(h, h - 1);
670         } else {
671             line1 = (h > 1) ? pLine[-nStride2] << 1 : 0;
672             line2 = (h > 0) ? pLine[-nStride] : 0;
673             CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
674             for(FX_DWORD w = 0; w < GBW; w += 8) {
675                 if(w + 8 < GBW) {
676                     nBits = 8;
677                     if(h > 1) {
678                         line1 = (line1 << 8) | (pLine[-nStride2 + (w >> 3) + 1] << 1);
679                     }
680                     if(h > 0) {
681                         line2 = (line2 << 8) | (pLine[-nStride + (w >> 3) + 1]);
682                     }
683                 } else {
684                     nBits = GBW - w;
685                     if(h > 1) {
686                         line1 <<= 8;
687                     }
688                     if(h > 0) {
689                         line2 <<= 8;
690                     }
691                 }
692                 cVal = 0;
693                 for(k = 0; k < nBits; k++) {
694                     if(USESKIP && SKIP->getPixel(w, h)) {
695                         bVal = 0;
696                     } else {
697                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
698                     }
699                     cVal |= bVal << (7 - k);
700                     CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
701                               | ((line1 >> (7 - k)) & 0x0080)
702                               | ((line2 >> (10 - k)) & 0x0004);
703                 }
704                 pLine[w >> 3] = cVal;
705             }
706         }
707         pLine += nStride;
708     }
709     return GBREG;
710 }
decode_Arith_Template2_opt3(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)711 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
712 {
713     FX_BOOL LTP, SLTP, bVal;
714     FX_DWORD CONTEXT;
715     CJBig2_Image *GBREG;
716     FX_DWORD line1, line2;
717     FX_BYTE *pLine, *pLine1, *pLine2, cVal;
718     FX_INT32 nStride, nStride2, k;
719     FX_INT32 nLineBytes, nBitsLeft, cc;
720     LTP = 0;
721     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
722     if (GBREG->m_pData == NULL) {
723         delete GBREG;
724         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
725         return NULL;
726     }
727     pLine = GBREG->m_pData;
728     nStride = GBREG->m_nStride;
729     nStride2 = nStride << 1;
730     nLineBytes = ((GBW + 7) >> 3) - 1;
731     nBitsLeft = GBW - (nLineBytes << 3);
732     for(FX_DWORD h = 0; h < GBH; h++) {
733         if(TPGDON) {
734             SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
735             LTP = LTP ^ SLTP;
736         }
737         if(LTP == 1) {
738             GBREG->copyLine(h, h - 1);
739         } else {
740             if(h > 1) {
741                 pLine1 = pLine - nStride2;
742                 pLine2 = pLine - nStride;
743                 line1 = (*pLine1++) << 1;
744                 line2 = *pLine2++;
745                 CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
746                 for(cc = 0; cc < nLineBytes; cc++) {
747                     line1 = (line1 << 8) | ((*pLine1++) << 1);
748                     line2 = (line2 << 8) | (*pLine2++);
749                     cVal = 0;
750                     for(k = 7; k >= 0; k--) {
751                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
752                         cVal |= bVal << k;
753                         CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
754                                   | ((line1 >> k) & 0x0080)
755                                   | ((line2 >> (k + 3)) & 0x0004);
756                     }
757                     pLine[cc] = cVal;
758                 }
759                 line1 <<= 8;
760                 line2 <<= 8;
761                 cVal = 0;
762                 for(k = 0; k < nBitsLeft; k++) {
763                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
764                     cVal |= bVal << (7 - k);
765                     CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
766                               | ((line1 >> (7 - k)) & 0x0080)
767                               | ((line2 >> (10 - k)) & 0x0004);
768                 }
769                 pLine[nLineBytes] = cVal;
770             } else {
771                 pLine2 = pLine - nStride;
772                 line2 = (h & 1) ? (*pLine2++) : 0;
773                 CONTEXT = (line2 >> 3) & 0x007c;
774                 for(cc = 0; cc < nLineBytes; cc++) {
775                     if(h & 1) {
776                         line2 = (line2 << 8) | (*pLine2++);
777                     }
778                     cVal = 0;
779                     for(k = 7; k >= 0; k--) {
780                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
781                         cVal |= bVal << k;
782                         CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
783                                   | ((line2 >> (k + 3)) & 0x0004);
784                     }
785                     pLine[cc] = cVal;
786                 }
787                 line2 <<= 8;
788                 cVal = 0;
789                 for(k = 0; k < nBitsLeft; k++) {
790                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
791                     cVal |= bVal << (7 - k);
792                     CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
793                               | (((line2 >> (10 - k))) & 0x0004);
794                 }
795                 pLine[nLineBytes] = cVal;
796             }
797         }
798         pLine += nStride;
799     }
800     return GBREG;
801 }
decode_Arith_Template2_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)802 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template2_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
803 {
804     FX_BOOL LTP, SLTP, bVal;
805     FX_DWORD CONTEXT;
806     CJBig2_Image *GBREG;
807     FX_DWORD line1, line2, line3;
808     LTP = 0;
809     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
810     GBREG->fill(0);
811     for(FX_DWORD h = 0; h < GBH; h++) {
812         if(TPGDON) {
813             SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
814             LTP = LTP ^ SLTP;
815         }
816         if(LTP == 1) {
817             GBREG->copyLine(h, h - 1);
818         } else {
819             line1 = GBREG->getPixel(1, h - 2);
820             line1 |= GBREG->getPixel(0, h - 2) << 1;
821             line2 = GBREG->getPixel(1, h - 1);
822             line2 |= GBREG->getPixel(0, h - 1) << 1;
823             line3 = 0;
824             for(FX_DWORD w = 0; w < GBW; w++) {
825                 if(USESKIP && SKIP->getPixel(w, h)) {
826                     bVal = 0;
827                 } else {
828                     CONTEXT = line3;
829                     CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
830                     CONTEXT |= line2 << 3;
831                     CONTEXT |= line1 << 7;
832                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
833                 }
834                 if(bVal) {
835                     GBREG->setPixel(w, h, bVal);
836                 }
837                 line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
838                 line2 = ((line2 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x0f;
839                 line3 = ((line3 << 1) | bVal) & 0x03;
840             }
841         }
842     }
843     return GBREG;
844 }
decode_Arith_Template3_opt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)845 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
846 {
847     FX_BOOL LTP, SLTP, bVal;
848     FX_DWORD CONTEXT;
849     CJBig2_Image *GBREG;
850     FX_DWORD line1, line2;
851     LTP = 0;
852     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
853     GBREG->fill(0);
854     for(FX_DWORD h = 0; h < GBH; h++) {
855         if(TPGDON) {
856             SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
857             LTP = LTP ^ SLTP;
858         }
859         if(LTP == 1) {
860             GBREG->copyLine(h, h - 1);
861         } else {
862             line1 = GBREG->getPixel(2, h - 1);
863             line1 |= GBREG->getPixel(1, h - 1) << 1;
864             line1 |= GBREG->getPixel(0, h - 1) << 2;
865             line2 = 0;
866             for(FX_DWORD w = 0; w < GBW; w++) {
867                 if(USESKIP && SKIP->getPixel(w, h)) {
868                     bVal = 0;
869                 } else {
870                     CONTEXT = line2;
871                     CONTEXT |= line1 << 4;
872                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
873                 }
874                 if(bVal) {
875                     GBREG->setPixel(w, h, bVal);
876                 }
877                 line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x3f;
878                 line2 = ((line2 << 1) | bVal) & 0x0f;
879             }
880         }
881     }
882     return GBREG;
883 }
decode_Arith_Template3_opt2(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)884 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_opt2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
885 {
886     FX_BOOL LTP, SLTP, bVal;
887     FX_DWORD CONTEXT;
888     CJBig2_Image *GBREG;
889     FX_DWORD line1;
890     FX_BYTE *pLine, cVal;
891     FX_INTPTR nStride;
892     FX_INT32 nBits, k;
893     LTP = 0;
894     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
895     if (GBREG->m_pData == NULL) {
896         delete GBREG;
897         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
898         return NULL;
899     }
900     pLine = GBREG->m_pData;
901     nStride = GBREG->m_nStride;
902     for(FX_DWORD h = 0; h < GBH; h++) {
903         if(TPGDON) {
904             SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
905             LTP = LTP ^ SLTP;
906         }
907         if(LTP == 1) {
908             GBREG->copyLine(h, h - 1);
909         } else {
910             line1 = (h > 0) ? pLine[-nStride] : 0;
911             CONTEXT = (line1 >> 1) & 0x03f0;
912             for(FX_DWORD w = 0; w < GBW; w += 8) {
913                 if(w + 8 < GBW) {
914                     nBits = 8;
915                     if(h > 0) {
916                         line1 = (line1 << 8) | (pLine[-nStride + (w >> 3) + 1]);
917                     }
918                 } else {
919                     nBits = GBW - w;
920                     if(h > 0) {
921                         line1 <<= 8;
922                     }
923                 }
924                 cVal = 0;
925                 for(k = 0; k < nBits; k++) {
926                     if(USESKIP && SKIP->getPixel(w, h)) {
927                         bVal = 0;
928                     } else {
929                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
930                     }
931                     cVal |= bVal << (7 - k);
932                     CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
933                               | ((line1 >> (8 - k)) & 0x0010);
934                 }
935                 pLine[w >> 3] = cVal;
936             }
937         }
938         pLine += nStride;
939     }
940     return GBREG;
941 }
decode_Arith_Template3_opt3(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)942 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_opt3(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
943 {
944     FX_BOOL LTP, SLTP, bVal;
945     FX_DWORD CONTEXT;
946     CJBig2_Image *GBREG;
947     FX_DWORD line1;
948     FX_BYTE *pLine, *pLine1, cVal;
949     FX_INT32 nStride, k;
950     FX_INT32 nLineBytes, nBitsLeft, cc;
951     LTP = 0;
952     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
953     if (GBREG->m_pData == NULL) {
954         delete GBREG;
955         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
956         return NULL;
957     }
958     pLine = GBREG->m_pData;
959     nStride = GBREG->m_nStride;
960     nLineBytes = ((GBW + 7) >> 3) - 1;
961     nBitsLeft = GBW - (nLineBytes << 3);
962     for(FX_DWORD h = 0; h < GBH; h++) {
963         if(TPGDON) {
964             SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
965             LTP = LTP ^ SLTP;
966         }
967         if(LTP == 1) {
968             GBREG->copyLine(h, h - 1);
969         } else {
970             if(h > 0) {
971                 pLine1 = pLine - nStride;
972                 line1 = *pLine1++;
973                 CONTEXT = (line1 >> 1) & 0x03f0;
974                 for(cc = 0; cc < nLineBytes; cc++) {
975                     line1 = (line1 << 8) | (*pLine1++);
976                     cVal = 0;
977                     for(k = 7; k >= 0; k--) {
978                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
979                         cVal |= bVal << k;
980                         CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
981                                   | ((line1 >> (k + 1)) & 0x0010);
982                     }
983                     pLine[cc] = cVal;
984                 }
985                 line1 <<= 8;
986                 cVal = 0;
987                 for(k = 0; k < nBitsLeft; k++) {
988                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
989                     cVal |= bVal << (7 - k);
990                     CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
991                               | ((line1 >> (8 - k)) & 0x0010);
992                 }
993                 pLine[nLineBytes] = cVal;
994             } else {
995                 CONTEXT = 0;
996                 for(cc = 0; cc < nLineBytes; cc++) {
997                     cVal = 0;
998                     for(k = 7; k >= 0; k--) {
999                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1000                         cVal |= bVal << k;
1001                         CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
1002                     }
1003                     pLine[cc] = cVal;
1004                 }
1005                 cVal = 0;
1006                 for(k = 0; k < nBitsLeft; k++) {
1007                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1008                     cVal |= bVal << (7 - k);
1009                     CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
1010                 }
1011                 pLine[nLineBytes] = cVal;
1012             }
1013         }
1014         pLine += nStride;
1015     }
1016     return GBREG;
1017 }
decode_Arith_Template3_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)1018 CJBig2_Image *CJBig2_GRDProc::decode_Arith_Template3_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
1019 {
1020     FX_BOOL LTP, SLTP, bVal;
1021     FX_DWORD CONTEXT;
1022     CJBig2_Image *GBREG;
1023     FX_DWORD line1, line2;
1024     LTP = 0;
1025     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
1026     GBREG->fill(0);
1027     for(FX_DWORD h = 0; h < GBH; h++) {
1028         if(TPGDON) {
1029             SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
1030             LTP = LTP ^ SLTP;
1031         }
1032         if(LTP == 1) {
1033             GBREG->copyLine(h, h - 1);
1034         } else {
1035             line1 = GBREG->getPixel(1, h - 1);
1036             line1 |= GBREG->getPixel(0, h - 1) << 1;
1037             line2 = 0;
1038             for(FX_DWORD w = 0; w < GBW; w++) {
1039                 if(USESKIP && SKIP->getPixel(w, h)) {
1040                     bVal = 0;
1041                 } else {
1042                     CONTEXT = line2;
1043                     CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1044                     CONTEXT |= line1 << 5;
1045                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1046                 }
1047                 if(bVal) {
1048                     GBREG->setPixel(w, h, bVal);
1049                 }
1050                 line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x1f;
1051                 line2 = ((line2 << 1) | bVal) & 0x0f;
1052             }
1053         }
1054     }
1055     return GBREG;
1056 }
decode_Arith_V2(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)1057 CJBig2_Image *CJBig2_GRDProc::decode_Arith_V2(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
1058 {
1059     FX_BOOL LTP, SLTP, bVal;
1060     FX_DWORD CONTEXT;
1061     CJBig2_Image *GBREG;
1062     FX_DWORD line1, line2, line3;
1063     LTP = 0;
1064     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
1065     GBREG->fill(0);
1066     for(FX_DWORD h = 0; h < GBH; h++) {
1067         if(TPGDON) {
1068             switch(GBTEMPLATE) {
1069                 case 0:
1070                     CONTEXT = 0x9b25;
1071                     break;
1072                 case 1:
1073                     CONTEXT = 0x0795;
1074                     break;
1075                 case 2:
1076                     CONTEXT = 0x00e5;
1077                     break;
1078                 case 3:
1079                     CONTEXT = 0x0195;
1080                     break;
1081             }
1082             SLTP = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1083             LTP = LTP ^ SLTP;
1084         }
1085         if(LTP == 1) {
1086             GBREG->copyLine(h, h - 1);
1087         } else {
1088             switch(GBTEMPLATE) {
1089                 case 0: {
1090                         line1 = GBREG->getPixel(1, h - 2);
1091                         line1 |= GBREG->getPixel(0, h - 2) << 1;
1092                         line2 = GBREG->getPixel(2, h - 1);
1093                         line2 |= GBREG->getPixel(1, h - 1) << 1;
1094                         line2 |= GBREG->getPixel(0, h - 1) << 2;
1095                         line3 = 0;
1096                         for(FX_DWORD w = 0; w < GBW; w++) {
1097                             if(USESKIP && SKIP->getPixel(w, h)) {
1098                                 bVal = 0;
1099                             } else {
1100                                 CONTEXT = line3;
1101                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1102                                 CONTEXT |= line2 << 5;
1103                                 CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
1104                                 CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
1105                                 CONTEXT |= line1 << 12;
1106                                 CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
1107                                 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1108                             }
1109                             if(bVal) {
1110                                 GBREG->setPixel(w, h, bVal);
1111                             }
1112                             line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
1113                             line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
1114                             line3 = ((line3 << 1) | bVal) & 0x0f;
1115                         }
1116                     }
1117                     break;
1118                 case 1: {
1119                         line1 = GBREG->getPixel(2, h - 2);
1120                         line1 |= GBREG->getPixel(1, h - 2) << 1;
1121                         line1 |= GBREG->getPixel(0, h - 2) << 2;
1122                         line2 = GBREG->getPixel(2, h - 1);
1123                         line2 |= GBREG->getPixel(1, h - 1) << 1;
1124                         line2 |= GBREG->getPixel(0, h - 1) << 2;
1125                         line3 = 0;
1126                         for(FX_DWORD w = 0; w < GBW; w++) {
1127                             if(USESKIP && SKIP->getPixel(w, h)) {
1128                                 bVal = 0;
1129                             } else {
1130                                 CONTEXT = line3;
1131                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
1132                                 CONTEXT |= line2 << 4;
1133                                 CONTEXT |= line1 << 9;
1134                                 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1135                             }
1136                             if(bVal) {
1137                                 GBREG->setPixel(w, h, bVal);
1138                             }
1139                             line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
1140                             line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
1141                             line3 = ((line3 << 1) | bVal) & 0x07;
1142                         }
1143                     }
1144                     break;
1145                 case 2: {
1146                         line1 = GBREG->getPixel(1, h - 2);
1147                         line1 |= GBREG->getPixel(0, h - 2) << 1;
1148                         line2 = GBREG->getPixel(1, h - 1);
1149                         line2 |= GBREG->getPixel(0, h - 1) << 1;
1150                         line3 = 0;
1151                         for(FX_DWORD w = 0; w < GBW; w++) {
1152                             if(USESKIP && SKIP->getPixel(w, h)) {
1153                                 bVal = 0;
1154                             } else {
1155                                 CONTEXT = line3;
1156                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
1157                                 CONTEXT |= line2 << 3;
1158                                 CONTEXT |= line1 << 7;
1159                                 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1160                             }
1161                             if(bVal) {
1162                                 GBREG->setPixel(w, h, bVal);
1163                             }
1164                             line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
1165                             line2 = ((line2 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x0f;
1166                             line3 = ((line3 << 1) | bVal) & 0x03;
1167                         }
1168                     }
1169                     break;
1170                 case 3: {
1171                         line1 = GBREG->getPixel(1, h - 1);
1172                         line1 |= GBREG->getPixel(0, h - 1) << 1;
1173                         line2 = 0;
1174                         for(FX_DWORD w = 0; w < GBW; w++) {
1175                             if(USESKIP && SKIP->getPixel(w, h)) {
1176                                 bVal = 0;
1177                             } else {
1178                                 CONTEXT = line2;
1179                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1180                                 CONTEXT |= line1 << 5;
1181                                 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1182                             }
1183                             if(bVal) {
1184                                 GBREG->setPixel(w, h, bVal);
1185                             }
1186                             line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x1f;
1187                             line2 = ((line2 << 1) | bVal) & 0x0f;
1188                         }
1189                     }
1190                     break;
1191             }
1192         }
1193     }
1194     return GBREG;
1195 }
decode_Arith_V1(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)1196 CJBig2_Image *CJBig2_GRDProc::decode_Arith_V1(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext)
1197 {
1198     FX_BOOL LTP, SLTP, bVal;
1199     FX_DWORD CONTEXT = 0;
1200     CJBig2_Image *GBREG;
1201     LTP = 0;
1202     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
1203     GBREG->fill(0);
1204     for(FX_DWORD h = 0; h < GBH; h++) {
1205         if(TPGDON) {
1206             switch(GBTEMPLATE) {
1207                 case 0:
1208                     CONTEXT = 0x9b25;
1209                     break;
1210                 case 1:
1211                     CONTEXT = 0x0795;
1212                     break;
1213                 case 2:
1214                     CONTEXT = 0x00e5;
1215                     break;
1216                 case 3:
1217                     CONTEXT = 0x0195;
1218                     break;
1219             }
1220             SLTP = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1221             LTP = LTP ^ SLTP;
1222         }
1223         if(LTP == 1) {
1224             for(FX_DWORD w = 0; w < GBW; w++) {
1225                 GBREG->setPixel(w, h, GBREG->getPixel(w, h - 1));
1226             }
1227         } else {
1228             for(FX_DWORD w = 0; w < GBW; w++) {
1229                 if(USESKIP && SKIP->getPixel(w, h)) {
1230                     GBREG->setPixel(w, h, 0);
1231                 } else {
1232                     CONTEXT = 0;
1233                     switch(GBTEMPLATE) {
1234                         case 0:
1235                             CONTEXT |= GBREG->getPixel(w - 1, h);
1236                             CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1237                             CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
1238                             CONTEXT |= GBREG->getPixel(w - 4, h) << 3;
1239                             CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1240                             CONTEXT |= GBREG->getPixel(w + 2, h - 1) << 5;
1241                             CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 6;
1242                             CONTEXT |= GBREG->getPixel(w, h - 1) << 7;
1243                             CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 8;
1244                             CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 9;
1245                             CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
1246                             CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
1247                             CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 12;
1248                             CONTEXT |= GBREG->getPixel(w, h - 2) << 13;
1249                             CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 14;
1250                             CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
1251                             break;
1252                         case 1:
1253                             CONTEXT |= GBREG->getPixel(w - 1, h);
1254                             CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1255                             CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
1256                             CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
1257                             CONTEXT |= GBREG->getPixel(w + 2, h - 1) << 4;
1258                             CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 5;
1259                             CONTEXT |= GBREG->getPixel(w, h - 1) << 6;
1260                             CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 7;
1261                             CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 8;
1262                             CONTEXT |= GBREG->getPixel(w + 2, h - 2) << 9;
1263                             CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 10;
1264                             CONTEXT |= GBREG->getPixel(w, h - 2) << 11;
1265                             CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 12;
1266                             break;
1267                         case 2:
1268                             CONTEXT |= GBREG->getPixel(w - 1, h);
1269                             CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1270                             CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
1271                             CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 3;
1272                             CONTEXT |= GBREG->getPixel(w, h - 1) << 4;
1273                             CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 5;
1274                             CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 6;
1275                             CONTEXT |= GBREG->getPixel(w + 1, h - 2) << 7;
1276                             CONTEXT |= GBREG->getPixel(w, h - 2) << 8;
1277                             CONTEXT |= GBREG->getPixel(w - 1, h - 2) << 9;
1278                             break;
1279                         case 3:
1280                             CONTEXT |= GBREG->getPixel(w - 1, h);
1281                             CONTEXT |= GBREG->getPixel(w - 2, h) << 1;
1282                             CONTEXT |= GBREG->getPixel(w - 3, h) << 2;
1283                             CONTEXT |= GBREG->getPixel(w - 4, h) << 3;
1284                             CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
1285                             CONTEXT |= GBREG->getPixel(w + 1, h - 1) << 5;
1286                             CONTEXT |= GBREG->getPixel(w, h - 1) << 6;
1287                             CONTEXT |= GBREG->getPixel(w - 1, h - 1) << 7;
1288                             CONTEXT |= GBREG->getPixel(w - 2, h - 1) << 8;
1289                             CONTEXT |= GBREG->getPixel(w - 3, h - 1) << 9;
1290                             break;
1291                     }
1292                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1293                     GBREG->setPixel(w, h, bVal);
1294                 }
1295             }
1296         }
1297     }
1298     return GBREG;
1299 }
decode_MMR(CJBig2_BitStream * pStream)1300 CJBig2_Image *CJBig2_GRDProc::decode_MMR(CJBig2_BitStream *pStream)
1301 {
1302     int bitpos, i;
1303     CJBig2_Image *pImage;
1304     JBIG2_ALLOC(pImage, CJBig2_Image(GBW, GBH));
1305     if (pImage->m_pData == NULL) {
1306         delete pImage;
1307         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
1308         return NULL;
1309     }
1310     bitpos = (int)pStream->getBitPos();
1311     _FaxG4Decode(m_pModule, pStream->getBuf(), pStream->getLength(), &bitpos, pImage->m_pData, GBW, GBH, pImage->m_nStride);
1312     pStream->setBitPos(bitpos);
1313     for(i = 0; (FX_DWORD)i < pImage->m_nStride * GBH; i++) {
1314         pImage->m_pData[i] = ~pImage->m_pData[i];
1315     }
1316     return pImage;
1317 }
decode(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext)1318 CJBig2_Image *CJBig2_GRRDProc::decode(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1319 {
1320     if (GRW == 0 || GRH == 0) {
1321         CJBig2_Image* pImage;
1322         JBIG2_ALLOC(pImage, CJBig2_Image(GRW, GRH));
1323         return pImage;
1324     }
1325     if(GRTEMPLATE == 0) {
1326         if((GRAT[0] == (signed char) - 1) && (GRAT[1] == (signed char) - 1)
1327                 && (GRAT[2] == (signed char) - 1) && (GRAT[3] == (signed char) - 1)
1328                 && (GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
1329             return decode_Template0_opt(pArithDecoder, grContext);
1330         } else {
1331             return decode_Template0_unopt(pArithDecoder, grContext);
1332         }
1333     } else {
1334         if((GRREFERENCEDX == 0) && (GRW == (FX_DWORD)GRREFERENCE->m_nWidth)) {
1335             return decode_Template1_opt(pArithDecoder, grContext);
1336         } else {
1337             return decode_Template1_unopt(pArithDecoder, grContext);
1338         }
1339     }
1340 }
decode_Template0_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext)1341 CJBig2_Image *CJBig2_GRRDProc::decode_Template0_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1342 {
1343     FX_BOOL LTP, SLTP, bVal;
1344     FX_DWORD CONTEXT;
1345     CJBig2_Image *GRREG;
1346     FX_DWORD line1, line2, line3, line4, line5;
1347     LTP = 0;
1348     JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1349     GRREG->fill(0);
1350     for(FX_DWORD h = 0; h < GRH; h++) {
1351         if(TPGRON) {
1352             SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
1353             LTP = LTP ^ SLTP;
1354         }
1355         if(LTP == 0) {
1356             line1 = GRREG->getPixel(1, h - 1);
1357             line1 |= GRREG->getPixel(0, h - 1) << 1;
1358             line2 = 0;
1359             line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
1360             line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1) << 1;
1361             line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1362             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1363             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1364             line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1365             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1366             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1367             for(FX_DWORD w = 0; w < GRW; w++) {
1368                 CONTEXT = line5;
1369                 CONTEXT |= line4 << 3;
1370                 CONTEXT |= line3 << 6;
1371                 CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1372                 CONTEXT |= line2 << 9;
1373                 CONTEXT |= line1 << 10;
1374                 CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1375                 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1376                 GRREG->setPixel(w, h, bVal);
1377                 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
1378                 line2 = ((line2 << 1) | bVal) & 0x01;
1379                 line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY - 1)) & 0x03;
1380                 line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1381                 line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x07;
1382             }
1383         } else {
1384             line1 = GRREG->getPixel(1, h - 1);
1385             line1 |= GRREG->getPixel(0, h - 1) << 1;
1386             line2 = 0;
1387             line3 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1);
1388             line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1) << 1;
1389             line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1390             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1391             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1392             line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1393             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1394             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1395             for(FX_DWORD w = 0; w < GRW; w++) {
1396                 bVal = GRREFERENCE->getPixel(w, h);
1397                 if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
1398                         && (bVal == GRREFERENCE->getPixel(w, h - 1))
1399                         && (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
1400                         && (bVal == GRREFERENCE->getPixel(w - 1, h))
1401                         && (bVal == GRREFERENCE->getPixel(w + 1, h))
1402                         && (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
1403                         && (bVal == GRREFERENCE->getPixel(w, h + 1))
1404                         && (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
1405                     CONTEXT = line5;
1406                     CONTEXT |= line4 << 3;
1407                     CONTEXT |= line3 << 6;
1408                     CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1409                     CONTEXT |= line2 << 9;
1410                     CONTEXT |= line1 << 10;
1411                     CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1412                     bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1413                 }
1414                 GRREG->setPixel(w, h, bVal);
1415                 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03;
1416                 line2 = ((line2 << 1) | bVal) & 0x01;
1417                 line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY - 1)) & 0x03;
1418                 line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1419                 line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x07;
1420             }
1421         }
1422     }
1423     return GRREG;
1424 }
decode_Template0_opt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext)1425 CJBig2_Image *CJBig2_GRRDProc::decode_Template0_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1426 {
1427     FX_BOOL LTP, SLTP, bVal;
1428     FX_DWORD CONTEXT;
1429     CJBig2_Image *GRREG;
1430     FX_DWORD line1, line1_r, line2_r, line3_r;
1431     FX_BYTE *pLine, *pLineR, cVal;
1432     FX_INTPTR nStride, nStrideR, nOffset;
1433     FX_INT32 k, nBits;
1434     FX_INT32 GRWR, GRHR;
1435     FX_INT32 GRW, GRH;
1436     GRW = (FX_INT32)CJBig2_GRRDProc::GRW;
1437     GRH = (FX_INT32)CJBig2_GRRDProc::GRH;
1438     LTP = 0;
1439     JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1440     if (GRREG->m_pData == NULL) {
1441         delete GRREG;
1442         m_pModule->JBig2_Error("Generic refinement region decoding procedure: Create Image Failed with width = %d, height = %d\n", GRW, GRH);
1443         return NULL;
1444     }
1445     pLine = GRREG->m_pData;
1446     pLineR = GRREFERENCE->m_pData;
1447     nStride = GRREG->m_nStride;
1448     nStrideR = GRREFERENCE->m_nStride;
1449     GRWR = (FX_INT32)GRREFERENCE->m_nWidth;
1450     GRHR = (FX_INT32)GRREFERENCE->m_nHeight;
1451     if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
1452         GRREFERENCEDY = 0;
1453     }
1454     nOffset = -GRREFERENCEDY * nStrideR;
1455     for (FX_INT32 h = 0; h < GRH; h++) {
1456         if(TPGRON) {
1457             SLTP = pArithDecoder->DECODE(&grContext[0x0010]);
1458             LTP = LTP ^ SLTP;
1459         }
1460         line1 = (h > 0) ? pLine[-nStride] << 4 : 0;
1461         FX_INT32 reference_h = h - GRREFERENCEDY;
1462         FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
1463         FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
1464         FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
1465         line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
1466         line2_r = line2_r_ok ? pLineR[nOffset] : 0;
1467         line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
1468         if(LTP == 0) {
1469             CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0)
1470                       | ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
1471             for (FX_INT32 w = 0; w < GRW; w += 8) {
1472                 nBits = GRW - w > 8 ? 8 : GRW - w;
1473                 if (h > 0)
1474                     line1 = (line1 << 8) |
1475                             (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
1476                 if (h > GRHR + GRREFERENCEDY + 1) {
1477                     line1_r = 0;
1478                     line2_r  = 0;
1479                     line3_r = 0;
1480                 } else {
1481                     if(line1_r_ok)
1482                         line1_r = (line1_r << 8) |
1483                                   (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1484                     if(line2_r_ok)
1485                         line2_r = (line2_r << 8) |
1486                                   (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1487                     if(line3_r_ok)
1488                         line3_r = (line3_r << 8) |
1489                                   (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1490                     else {
1491                         line3_r = 0;
1492                     }
1493                 }
1494                 cVal = 0;
1495                 for (k = 0; k < nBits; k++) {
1496                     bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1497                     cVal |= bVal << (7 - k);
1498                     CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
1499                               ((line1 >> (7 - k)) & 0x0400) |
1500                               ((line1_r >> (7 - k)) & 0x0040) |
1501                               ((line2_r >> (10 - k)) & 0x0008) |
1502                               ((line3_r >> (13 - k)) & 0x0001);
1503                 }
1504                 pLine[w >> 3] = cVal;
1505             }
1506         } else {
1507             CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0)
1508                       | ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007);
1509             for (FX_INT32 w = 0; w < GRW; w += 8) {
1510                 nBits = GRW - w > 8 ? 8 : GRW - w;
1511                 if (h > 0)
1512                     line1 = (line1 << 8) |
1513                             (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0);
1514                 if(line1_r_ok)
1515                     line1_r = (line1_r << 8) |
1516                               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1517                 if(line2_r_ok)
1518                     line2_r = (line2_r << 8) |
1519                               (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1520                 if(line3_r_ok)
1521                     line3_r = (line3_r << 8) |
1522                               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1523                 else {
1524                     line3_r = 0;
1525                 }
1526                 cVal = 0;
1527                 for (k = 0; k < nBits; k++) {
1528                     bVal = GRREFERENCE->getPixel(w + k, h);
1529                     if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1))
1530                             && (bVal == GRREFERENCE->getPixel(w + k, h - 1))
1531                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1))
1532                             && (bVal == GRREFERENCE->getPixel(w + k - 1, h))
1533                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h))
1534                             && (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1))
1535                             && (bVal == GRREFERENCE->getPixel(w + k, h + 1))
1536                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
1537                         bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1538                     }
1539                     cVal |= bVal << (7 - k);
1540                     CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) |
1541                               ((line1 >> (7 - k)) & 0x0400) |
1542                               ((line1_r >> (7 - k)) & 0x0040) |
1543                               ((line2_r >> (10 - k)) & 0x0008) |
1544                               ((line3_r >> (13 - k)) & 0x0001);
1545                 }
1546                 pLine[w >> 3] = cVal;
1547             }
1548         }
1549         pLine += nStride;
1550         if (h < GRHR + GRREFERENCEDY) {
1551             pLineR += nStrideR;
1552         }
1553     }
1554     return GRREG;
1555 }
decode_Template1_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext)1556 CJBig2_Image *CJBig2_GRRDProc::decode_Template1_unopt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1557 {
1558     FX_BOOL LTP, SLTP, bVal;
1559     FX_DWORD CONTEXT;
1560     CJBig2_Image *GRREG;
1561     FX_DWORD line1, line2, line3, line4, line5;
1562     LTP = 0;
1563     JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1564     GRREG->fill(0);
1565     for(FX_DWORD h = 0; h < GRH; h++) {
1566         if(TPGRON) {
1567             SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
1568             LTP = LTP ^ SLTP;
1569         }
1570         if(LTP == 0) {
1571             line1 = GRREG->getPixel(1, h - 1);
1572             line1 |= GRREG->getPixel(0, h - 1) << 1;
1573             line1 |= GRREG->getPixel(-1, h - 1) << 2;
1574             line2 = 0;
1575             line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
1576             line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1577             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1578             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1579             line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1580             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1581             for(FX_DWORD w = 0; w < GRW; w++) {
1582                 CONTEXT = line5;
1583                 CONTEXT |= line4 << 2;
1584                 CONTEXT |= line3 << 5;
1585                 CONTEXT |= line2 << 6;
1586                 CONTEXT |= line1 << 7;
1587                 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1588                 GRREG->setPixel(w, h, bVal);
1589                 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
1590                 line2 = ((line2 << 1) | bVal) & 0x01;
1591                 line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1)) & 0x01;
1592                 line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1593                 line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x03;
1594             }
1595         } else {
1596             line1 = GRREG->getPixel(1, h - 1);
1597             line1 |= GRREG->getPixel(0, h - 1) << 1;
1598             line1 |= GRREG->getPixel(-1, h - 1) << 2;
1599             line2 = 0;
1600             line3 = GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1);
1601             line4 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY);
1602             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1;
1603             line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) << 2;
1604             line5 = GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1605             line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1606             for(FX_DWORD w = 0; w < GRW; w++) {
1607                 bVal = GRREFERENCE->getPixel(w, h);
1608                 if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
1609                         && (bVal == GRREFERENCE->getPixel(w, h - 1))
1610                         && (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
1611                         && (bVal == GRREFERENCE->getPixel(w - 1, h))
1612                         && (bVal == GRREFERENCE->getPixel(w + 1, h))
1613                         && (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
1614                         && (bVal == GRREFERENCE->getPixel(w, h + 1))
1615                         && (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) {
1616                     CONTEXT = line5;
1617                     CONTEXT |= line4 << 2;
1618                     CONTEXT |= line3 << 5;
1619                     CONTEXT |= line2 << 6;
1620                     CONTEXT |= line1 << 7;
1621                     bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1622                 }
1623                 GRREG->setPixel(w, h, bVal);
1624                 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07;
1625                 line2 = ((line2 << 1) | bVal) & 0x01;
1626                 line3 = ((line3 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1)) & 0x01;
1627                 line4 = ((line4 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 0x07;
1628                 line5 = ((line5 << 1) | GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY + 1)) & 0x03;
1629             }
1630         }
1631     }
1632     return GRREG;
1633 }
decode_Template1_opt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext)1634 CJBig2_Image *CJBig2_GRRDProc::decode_Template1_opt(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1635 {
1636     FX_BOOL LTP, SLTP, bVal;
1637     FX_DWORD CONTEXT;
1638     CJBig2_Image *GRREG;
1639     FX_DWORD line1, line1_r, line2_r, line3_r;
1640     FX_BYTE *pLine, *pLineR, cVal;
1641     FX_INTPTR nStride, nStrideR, nOffset;
1642     FX_INT32 k, nBits;
1643     FX_INT32 GRWR, GRHR;
1644     FX_INT32 GRW, GRH;
1645     GRW = (FX_INT32)CJBig2_GRRDProc::GRW;
1646     GRH = (FX_INT32)CJBig2_GRRDProc::GRH;
1647     LTP = 0;
1648     JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1649     if (GRREG->m_pData == NULL) {
1650         delete GRREG;
1651         m_pModule->JBig2_Error("Generic refinement region decoding procedure: Create Image Failed with width = %d, height = %d\n", GRW, GRH);
1652         return NULL;
1653     }
1654     pLine = GRREG->m_pData;
1655     pLineR = GRREFERENCE->m_pData;
1656     nStride = GRREG->m_nStride;
1657     nStrideR = GRREFERENCE->m_nStride;
1658     GRWR = (FX_INT32)GRREFERENCE->m_nWidth;
1659     GRHR = (FX_INT32)GRREFERENCE->m_nHeight;
1660     if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) {
1661         GRREFERENCEDY = 0;
1662     }
1663     nOffset = -GRREFERENCEDY * nStrideR;
1664     for (FX_INT32 h = 0; h < GRH; h++) {
1665         if(TPGRON) {
1666             SLTP = pArithDecoder->DECODE(&grContext[0x0008]);
1667             LTP = LTP ^ SLTP;
1668         }
1669         line1 = (h > 0) ? pLine[-nStride] << 1 : 0;
1670         FX_INT32 reference_h = h - GRREFERENCEDY;
1671         FX_BOOL line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1);
1672         FX_BOOL line2_r_ok = (reference_h > -1 && reference_h < GRHR);
1673         FX_BOOL line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1);
1674         line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0;
1675         line2_r = line2_r_ok ? pLineR[nOffset] : 0;
1676         line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0;
1677         if(LTP == 0) {
1678             CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020)
1679                       | ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
1680             for (FX_INT32 w = 0; w < GRW; w += 8) {
1681                 nBits = GRW - w > 8 ? 8 : GRW - w;
1682                 if (h > 0)
1683                     line1 = (line1 << 8) |
1684                             (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
1685                 if(line1_r_ok)
1686                     line1_r = (line1_r << 8) |
1687                               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1688                 if(line2_r_ok)
1689                     line2_r = (line2_r << 8) |
1690                               (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1691                 if(line3_r_ok)
1692                     line3_r = (line3_r << 8) |
1693                               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1694                 else {
1695                     line3_r = 0;
1696                 }
1697                 cVal = 0;
1698                 for (k = 0; k < nBits; k++) {
1699                     bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1700                     cVal |= bVal << (7 - k);
1701                     CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
1702                               ((line1 >> (7 - k)) & 0x0080) |
1703                               ((line1_r >> (9 - k)) & 0x0020) |
1704                               ((line2_r >> (11 - k)) & 0x0004) |
1705                               ((line3_r >> (13 - k)) & 0x0001);
1706                 }
1707                 pLine[w >> 3] = cVal;
1708             }
1709         } else {
1710             CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020)
1711                       | ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003);
1712             for (FX_INT32 w = 0; w < GRW; w += 8) {
1713                 nBits = GRW - w > 8 ? 8 : GRW - w;
1714                 if (h > 0)
1715                     line1 = (line1 << 8) |
1716                             (w + 8 < GRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0);
1717                 if(line1_r_ok)
1718                     line1_r = (line1_r << 8) |
1719                               (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0);
1720                 if(line2_r_ok)
1721                     line2_r = (line2_r << 8) |
1722                               (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0);
1723                 if(line3_r_ok)
1724                     line3_r = (line3_r << 8) |
1725                               (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0);
1726                 else {
1727                     line3_r = 0;
1728                 }
1729                 cVal = 0;
1730                 for (k = 0; k < nBits; k++) {
1731                     bVal = GRREFERENCE->getPixel(w + k, h);
1732                     if(!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1))
1733                             && (bVal == GRREFERENCE->getPixel(w + k, h - 1))
1734                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1))
1735                             && (bVal == GRREFERENCE->getPixel(w + k - 1, h))
1736                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h))
1737                             && (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1))
1738                             && (bVal == GRREFERENCE->getPixel(w + k, h + 1))
1739                             && (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) {
1740                         bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1741                     }
1742                     cVal |= bVal << (7 - k);
1743                     CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) |
1744                               ((line1 >> (7 - k)) & 0x0080) |
1745                               ((line1_r >> (9 - k)) & 0x0020) |
1746                               ((line2_r >> (11 - k)) & 0x0004) |
1747                               ((line3_r >> (13 - k)) & 0x0001);
1748                 }
1749                 pLine[w >> 3] = cVal;
1750             }
1751         }
1752         pLine += nStride;
1753         if (h < GRHR + GRREFERENCEDY) {
1754             pLineR += nStrideR;
1755         }
1756     }
1757     return GRREG;
1758 }
decode_V1(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext)1759 CJBig2_Image *CJBig2_GRRDProc::decode_V1(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext)
1760 {
1761     FX_BOOL LTP, SLTP, bVal;
1762     FX_BOOL TPGRPIX, TPGRVAL;
1763     FX_DWORD CONTEXT;
1764     CJBig2_Image *GRREG;
1765     LTP = 0;
1766     JBIG2_ALLOC(GRREG, CJBig2_Image(GRW, GRH));
1767     GRREG->fill(0);
1768     for(FX_DWORD h = 0; h < GRH; h++) {
1769         if(TPGRON) {
1770             switch(GRTEMPLATE) {
1771                 case 0:
1772                     CONTEXT = 0x0010;
1773                     break;
1774                 case 1:
1775                     CONTEXT = 0x0008;
1776                     break;
1777             }
1778             SLTP = pArithDecoder->DECODE(&grContext[CONTEXT]);
1779             LTP = LTP ^ SLTP;
1780         }
1781         if(LTP == 0) {
1782             for(FX_DWORD w = 0; w < GRW; w++) {
1783                 CONTEXT = 0;
1784                 switch(GRTEMPLATE) {
1785                     case 0:
1786                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1787                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1788                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1789                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 3;
1790                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 4;
1791                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 5;
1792                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1) << 6;
1793                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 7;
1794                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1795                         CONTEXT |= GRREG->getPixel(w - 1, h) << 9;
1796                         CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 10;
1797                         CONTEXT |= GRREG->getPixel(w, h - 1) << 11;
1798                         CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1799                         break;
1800                     case 1:
1801                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1802                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1803                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 2;
1804                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 3;
1805                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 4;
1806                         CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 5;
1807                         CONTEXT |= GRREG->getPixel(w - 1, h) << 6;
1808                         CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 7;
1809                         CONTEXT |= GRREG->getPixel(w, h - 1) << 8;
1810                         CONTEXT |= GRREG->getPixel(w - 1, h - 1) << 9;
1811                         break;
1812                 }
1813                 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1814                 GRREG->setPixel(w, h, bVal);
1815             }
1816         } else {
1817             for(FX_DWORD w = 0; w < GRW; w++) {
1818                 bVal = GRREFERENCE->getPixel(w, h);
1819                 if(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1))
1820                         && (bVal == GRREFERENCE->getPixel(w, h - 1))
1821                         && (bVal == GRREFERENCE->getPixel(w + 1, h - 1))
1822                         && (bVal == GRREFERENCE->getPixel(w - 1, h))
1823                         && (bVal == GRREFERENCE->getPixel(w + 1, h))
1824                         && (bVal == GRREFERENCE->getPixel(w - 1, h + 1))
1825                         && (bVal == GRREFERENCE->getPixel(w, h + 1))
1826                         && (bVal == GRREFERENCE->getPixel(w + 1, h + 1))) {
1827                     TPGRPIX = 1;
1828                     TPGRVAL = bVal;
1829                 } else {
1830                     TPGRPIX = 0;
1831                 }
1832                 if(TPGRPIX) {
1833                     GRREG->setPixel(w, h, TPGRVAL);
1834                 } else {
1835                     CONTEXT = 0;
1836                     switch(GRTEMPLATE) {
1837                         case 0:
1838                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1839                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1840                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) << 2;
1841                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 3;
1842                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 4;
1843                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 5;
1844                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY - 1) << 6;
1845                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 7;
1846                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], h - GRREFERENCEDY + GRAT[3]) << 8;
1847                             CONTEXT |= GRREG->getPixel(w - 1, h) << 9;
1848                             CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 10;
1849                             CONTEXT |= GRREG->getPixel(w, h - 1) << 11;
1850                             CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12;
1851                             break;
1852                         case 1:
1853                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY + 1);
1854                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY + 1) << 1;
1855                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, h - GRREFERENCEDY) << 2;
1856                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY) << 3;
1857                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX - 1, h - GRREFERENCEDY) << 4;
1858                             CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX, h - GRREFERENCEDY - 1) << 5;
1859                             CONTEXT |= GRREG->getPixel(w - 1, h) << 6;
1860                             CONTEXT |= GRREG->getPixel(w + 1, h - 1) << 7;
1861                             CONTEXT |= GRREG->getPixel(w, h - 1) << 8;
1862                             CONTEXT |= GRREG->getPixel(w - 1, h - 1) << 9;
1863                             break;
1864                     }
1865                     bVal = pArithDecoder->DECODE(&grContext[CONTEXT]);
1866                     GRREG->setPixel(w, h, bVal);
1867                 }
1868             }
1869         }
1870     }
1871     return GRREG;
1872 }
decode_Huffman(CJBig2_BitStream * pStream,JBig2ArithCtx * grContext)1873 CJBig2_Image *CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream *pStream, JBig2ArithCtx *grContext)
1874 {
1875     FX_INT32 STRIPT, FIRSTS;
1876     FX_DWORD NINSTANCES;
1877     FX_INT32 DT, DFS, CURS;
1878     FX_BYTE CURT;
1879     FX_INT32 SI, TI;
1880     FX_DWORD IDI;
1881     CJBig2_Image *IBI;
1882     FX_DWORD WI, HI;
1883     FX_INT32 IDS;
1884     FX_BOOL RI;
1885     FX_INT32 RDWI, RDHI, RDXI, RDYI;
1886     CJBig2_Image *IBOI;
1887     FX_DWORD WOI, HOI;
1888     CJBig2_Image *SBREG;
1889     FX_BOOL bFirst;
1890     FX_DWORD nTmp;
1891     FX_INT32 nVal, nBits;
1892     CJBig2_HuffmanDecoder *pHuffmanDecoder;
1893     CJBig2_GRRDProc *pGRRD;
1894     CJBig2_ArithDecoder *pArithDecoder;
1895     JBIG2_ALLOC(pHuffmanDecoder, CJBig2_HuffmanDecoder(pStream));
1896     JBIG2_ALLOC(SBREG, CJBig2_Image(SBW, SBH));
1897     SBREG->fill(SBDEFPIXEL);
1898     if(pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0) {
1899         m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1900         goto failed;
1901     }
1902     STRIPT *= SBSTRIPS;
1903     STRIPT = -STRIPT;
1904     FIRSTS = 0;
1905     NINSTANCES = 0;
1906     while(NINSTANCES < SBNUMINSTANCES) {
1907         if(pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0) {
1908             m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1909             goto failed;
1910         }
1911         DT *= SBSTRIPS;
1912         STRIPT = STRIPT + DT;
1913         bFirst = TRUE;
1914         for(;;) {
1915             if(bFirst) {
1916                 if(pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0) {
1917                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1918                     goto failed;
1919                 }
1920                 FIRSTS = FIRSTS + DFS;
1921                 CURS = FIRSTS;
1922                 bFirst = FALSE;
1923             } else {
1924                 nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS);
1925                 if(nVal == JBIG2_OOB) {
1926                     break;
1927                 } else if(nVal != 0) {
1928                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1929                     goto failed;
1930                 } else {
1931                     CURS = CURS + IDS + SBDSOFFSET;
1932                 }
1933             }
1934             if(SBSTRIPS == 1) {
1935                 CURT = 0;
1936             } else {
1937                 nTmp = 1;
1938                 while((FX_DWORD)(1 << nTmp) < SBSTRIPS) {
1939                     nTmp ++;
1940                 }
1941                 if(pStream->readNBits(nTmp, &nVal) != 0) {
1942                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1943                     goto failed;
1944                 }
1945                 CURT = nVal;
1946             }
1947             TI = STRIPT + CURT;
1948             nVal = 0;
1949             nBits = 0;
1950             for(;;) {
1951                 if(pStream->read1Bit(&nTmp) != 0) {
1952                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1953                     goto failed;
1954                 }
1955                 nVal = (nVal << 1) | nTmp;
1956                 nBits ++;
1957                 for(IDI = 0; IDI < SBNUMSYMS; IDI++) {
1958                     if((nBits == SBSYMCODES[IDI].codelen) && (nVal == SBSYMCODES[IDI].code)) {
1959                         break;
1960                     }
1961                 }
1962                 if(IDI < SBNUMSYMS) {
1963                     break;
1964                 }
1965             }
1966             if(SBREFINE == 0) {
1967                 RI = 0;
1968             } else {
1969                 if(pStream->read1Bit(&RI) != 0) {
1970                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1971                     goto failed;
1972                 }
1973             }
1974             if(RI == 0) {
1975                 IBI = SBSYMS[IDI];
1976             } else {
1977                 if((pHuffmanDecoder->decodeAValue(SBHUFFRDW, &RDWI) != 0)
1978                         || (pHuffmanDecoder->decodeAValue(SBHUFFRDH, &RDHI) != 0)
1979                         || (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0)
1980                         || (pHuffmanDecoder->decodeAValue(SBHUFFRDY, &RDYI) != 0)
1981                         || (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
1982                     m_pModule->JBig2_Error("text region decoding procedure (huffman): too short.");
1983                     goto failed;
1984                 }
1985                 pStream->alignByte();
1986                 nTmp = pStream->getOffset();
1987                 IBOI = SBSYMS[IDI];
1988                 if (!IBOI) {
1989                     goto failed;
1990                 }
1991                 WOI = IBOI->m_nWidth;
1992                 HOI = IBOI->m_nHeight;
1993                 if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
1994                     m_pModule->JBig2_Error("text region decoding procedure (huffman): Invalid RDWI or RDHI value.");
1995                     goto failed;
1996                 }
1997                 JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
1998                 pGRRD->GRW = WOI + RDWI;
1999                 pGRRD->GRH = HOI + RDHI;
2000                 pGRRD->GRTEMPLATE = SBRTEMPLATE;
2001                 pGRRD->GRREFERENCE = IBOI;
2002                 pGRRD->GRREFERENCEDX = (RDWI >> 2) + RDXI;
2003                 pGRRD->GRREFERENCEDY = (RDHI >> 2) + RDYI;
2004                 pGRRD->TPGRON = 0;
2005                 pGRRD->GRAT[0] = SBRAT[0];
2006                 pGRRD->GRAT[1] = SBRAT[1];
2007                 pGRRD->GRAT[2] = SBRAT[2];
2008                 pGRRD->GRAT[3] = SBRAT[3];
2009                 JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(pStream));
2010                 IBI = pGRRD->decode(pArithDecoder, grContext);
2011                 if(IBI == NULL) {
2012                     delete pGRRD;
2013                     delete pArithDecoder;
2014                     goto failed;
2015                 }
2016                 delete pArithDecoder;
2017                 pStream->alignByte();
2018                 pStream->offset(2);
2019                 if((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
2020                     delete IBI;
2021                     delete pGRRD;
2022                     m_pModule->JBig2_Error("text region decoding procedure (huffman):"
2023                                            "bytes processed by generic refinement region decoding procedure doesn't equal SBHUFFRSIZE.");
2024                     goto failed;
2025                 }
2026                 delete pGRRD;
2027             }
2028             if (!IBI) {
2029                 continue;
2030             }
2031             WI = IBI->m_nWidth;
2032             HI = IBI->m_nHeight;
2033             if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT)
2034                                    || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
2035                 CURS = CURS + WI - 1;
2036             } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT)
2037                                           || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
2038                 CURS = CURS + HI - 1;
2039             }
2040             SI = CURS;
2041             if(TRANSPOSED == 0) {
2042                 switch(REFCORNER) {
2043                     case JBIG2_CORNER_TOPLEFT:
2044                         SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
2045                         break;
2046                     case JBIG2_CORNER_TOPRIGHT:
2047                         SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
2048                         break;
2049                     case JBIG2_CORNER_BOTTOMLEFT:
2050                         SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
2051                         break;
2052                     case JBIG2_CORNER_BOTTOMRIGHT:
2053                         SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
2054                         break;
2055                 }
2056             } else {
2057                 switch(REFCORNER) {
2058                     case JBIG2_CORNER_TOPLEFT:
2059                         SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
2060                         break;
2061                     case JBIG2_CORNER_TOPRIGHT:
2062                         SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
2063                         break;
2064                     case JBIG2_CORNER_BOTTOMLEFT:
2065                         SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
2066                         break;
2067                     case JBIG2_CORNER_BOTTOMRIGHT:
2068                         SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
2069                         break;
2070                 }
2071             }
2072             if(RI != 0) {
2073                 delete IBI;
2074             }
2075             if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2076                                    || (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
2077                 CURS = CURS + WI - 1;
2078             } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2079                                           || (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
2080                 CURS = CURS + HI - 1;
2081             }
2082             NINSTANCES = NINSTANCES + 1;
2083         }
2084     }
2085     delete pHuffmanDecoder;
2086     return SBREG;
2087 failed:
2088     delete pHuffmanDecoder;
2089     delete SBREG;
2090     return NULL;
2091 }
decode_Arith(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * grContext,JBig2IntDecoderState * pIDS)2092 CJBig2_Image *CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *grContext,
2093         JBig2IntDecoderState *pIDS)
2094 {
2095     FX_INT32 STRIPT, FIRSTS;
2096     FX_DWORD NINSTANCES;
2097     FX_INT32 DT, DFS, CURS;
2098     FX_INT32 CURT;
2099     FX_INT32 SI, TI;
2100     FX_DWORD IDI;
2101     CJBig2_Image *IBI;
2102     FX_DWORD WI, HI;
2103     FX_INT32 IDS;
2104     FX_BOOL RI;
2105     FX_INT32 RDWI, RDHI, RDXI, RDYI;
2106     CJBig2_Image *IBOI;
2107     FX_DWORD WOI, HOI;
2108     CJBig2_Image *SBREG;
2109     FX_BOOL bFirst;
2110     FX_INT32 nRet, nVal;
2111     FX_INT32 bRetained;
2112     CJBig2_ArithIntDecoder *IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH, *IARDX, *IARDY;
2113     CJBig2_ArithIaidDecoder *IAID;
2114     CJBig2_GRRDProc *pGRRD;
2115     if(pIDS) {
2116         IADT = pIDS->IADT;
2117         IAFS = pIDS->IAFS;
2118         IADS = pIDS->IADS;
2119         IAIT = pIDS->IAIT;
2120         IARI = pIDS->IARI;
2121         IARDW = pIDS->IARDW;
2122         IARDH = pIDS->IARDH;
2123         IARDX = pIDS->IARDX;
2124         IARDY = pIDS->IARDY;
2125         IAID = pIDS->IAID;
2126         bRetained = TRUE;
2127     } else {
2128         JBIG2_ALLOC(IADT, CJBig2_ArithIntDecoder());
2129         JBIG2_ALLOC(IAFS, CJBig2_ArithIntDecoder());
2130         JBIG2_ALLOC(IADS, CJBig2_ArithIntDecoder());
2131         JBIG2_ALLOC(IAIT, CJBig2_ArithIntDecoder());
2132         JBIG2_ALLOC(IARI, CJBig2_ArithIntDecoder());
2133         JBIG2_ALLOC(IARDW, CJBig2_ArithIntDecoder());
2134         JBIG2_ALLOC(IARDH, CJBig2_ArithIntDecoder());
2135         JBIG2_ALLOC(IARDX, CJBig2_ArithIntDecoder());
2136         JBIG2_ALLOC(IARDY, CJBig2_ArithIntDecoder());
2137         JBIG2_ALLOC(IAID , CJBig2_ArithIaidDecoder(SBSYMCODELEN));
2138         bRetained = FALSE;
2139     }
2140     JBIG2_ALLOC(SBREG, CJBig2_Image(SBW, SBH));
2141     SBREG->fill(SBDEFPIXEL);
2142     if(IADT->decode(pArithDecoder, &STRIPT) == -1) {
2143         m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2144         goto failed;
2145     }
2146     STRIPT *= SBSTRIPS;
2147     STRIPT = -STRIPT;
2148     FIRSTS = 0;
2149     NINSTANCES = 0;
2150     while(NINSTANCES < SBNUMINSTANCES) {
2151         if(IADT->decode(pArithDecoder, &DT) == -1) {
2152             m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2153             goto failed;
2154         }
2155         DT *= SBSTRIPS;
2156         STRIPT = STRIPT + DT;
2157         bFirst = TRUE;
2158         for(;;) {
2159             if(bFirst) {
2160                 if(IAFS->decode(pArithDecoder, &DFS) == -1) {
2161                     m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2162                     goto failed;
2163                 }
2164                 FIRSTS = FIRSTS + DFS;
2165                 CURS = FIRSTS;
2166                 bFirst = FALSE;
2167             } else {
2168                 nRet = IADS->decode(pArithDecoder, &IDS);
2169                 if(nRet == JBIG2_OOB) {
2170                     break;
2171                 } else if(nRet != 0) {
2172                     m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2173                     goto failed;
2174                 } else {
2175                     CURS = CURS + IDS + SBDSOFFSET;
2176                 }
2177             }
2178             if (NINSTANCES >= SBNUMINSTANCES) {
2179                 break;
2180             }
2181             if(SBSTRIPS == 1) {
2182                 CURT = 0;
2183             } else {
2184                 if(IAIT->decode(pArithDecoder, &nVal) == -1) {
2185                     m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2186                     goto failed;
2187                 }
2188                 CURT = nVal;
2189             }
2190             TI = STRIPT + CURT;
2191             if(IAID->decode(pArithDecoder, &nVal) == -1) {
2192                 m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2193                 goto failed;
2194             }
2195             IDI = nVal;
2196             if(IDI >= SBNUMSYMS) {
2197                 m_pModule->JBig2_Error("text region decoding procedure (arith): symbol id out of range.(%d/%d)",
2198                                        IDI, SBNUMSYMS);
2199                 goto failed;
2200             }
2201             if(SBREFINE == 0) {
2202                 RI = 0;
2203             } else {
2204                 if(IARI->decode(pArithDecoder, &RI) == -1) {
2205                     m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2206                     goto failed;
2207                 }
2208             }
2209             if (!SBSYMS[IDI]) {
2210                 goto failed;
2211             }
2212             if(RI == 0) {
2213                 IBI = SBSYMS[IDI];
2214             } else {
2215                 if((IARDW->decode(pArithDecoder, &RDWI) == -1)
2216                         || (IARDH->decode(pArithDecoder, &RDHI) == -1)
2217                         || (IARDX->decode(pArithDecoder, &RDXI) == -1)
2218                         || (IARDY->decode(pArithDecoder, &RDYI) == -1)) {
2219                     m_pModule->JBig2_Error("text region decoding procedure (arith): too short.");
2220                     goto failed;
2221                 }
2222                 IBOI = SBSYMS[IDI];
2223                 WOI = IBOI->m_nWidth;
2224                 HOI = IBOI->m_nHeight;
2225                 if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
2226                     m_pModule->JBig2_Error("text region decoding procedure (arith): Invalid RDWI or RDHI value.");
2227                     goto failed;
2228                 }
2229                 JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
2230                 pGRRD->GRW = WOI + RDWI;
2231                 pGRRD->GRH = HOI + RDHI;
2232                 pGRRD->GRTEMPLATE = SBRTEMPLATE;
2233                 pGRRD->GRREFERENCE = IBOI;
2234                 pGRRD->GRREFERENCEDX = (RDWI >> 1) + RDXI;
2235                 pGRRD->GRREFERENCEDY = (RDHI >> 1) + RDYI;
2236                 pGRRD->TPGRON = 0;
2237                 pGRRD->GRAT[0] = SBRAT[0];
2238                 pGRRD->GRAT[1] = SBRAT[1];
2239                 pGRRD->GRAT[2] = SBRAT[2];
2240                 pGRRD->GRAT[3] = SBRAT[3];
2241                 IBI = pGRRD->decode(pArithDecoder, grContext);
2242                 if(IBI == NULL) {
2243                     delete pGRRD;
2244                     goto failed;
2245                 }
2246                 delete pGRRD;
2247             }
2248             WI = IBI->m_nWidth;
2249             HI = IBI->m_nHeight;
2250             if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT)
2251                                    || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
2252                 CURS = CURS + WI - 1;
2253             } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT)
2254                                           || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
2255                 CURS = CURS + HI - 1;
2256             }
2257             SI = CURS;
2258             if(TRANSPOSED == 0) {
2259                 switch(REFCORNER) {
2260                     case JBIG2_CORNER_TOPLEFT:
2261                         SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
2262                         break;
2263                     case JBIG2_CORNER_TOPRIGHT:
2264                         SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
2265                         break;
2266                     case JBIG2_CORNER_BOTTOMLEFT:
2267                         SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
2268                         break;
2269                     case JBIG2_CORNER_BOTTOMRIGHT:
2270                         SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
2271                         break;
2272                 }
2273             } else {
2274                 switch(REFCORNER) {
2275                     case JBIG2_CORNER_TOPLEFT:
2276                         SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
2277                         break;
2278                     case JBIG2_CORNER_TOPRIGHT:
2279                         SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
2280                         break;
2281                     case JBIG2_CORNER_BOTTOMLEFT:
2282                         SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
2283                         break;
2284                     case JBIG2_CORNER_BOTTOMRIGHT:
2285                         SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
2286                         break;
2287                 }
2288             }
2289             if(RI != 0) {
2290                 delete IBI;
2291             }
2292             if(TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2293                                    || (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
2294                 CURS = CURS + WI - 1;
2295             } else if(TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT)
2296                                           || (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
2297                 CURS = CURS + HI - 1;
2298             }
2299             NINSTANCES = NINSTANCES + 1;
2300         }
2301     }
2302     if(bRetained == FALSE) {
2303         delete IADT;
2304         delete IAFS;
2305         delete IADS;
2306         delete IAIT;
2307         delete IARI;
2308         delete IARDW;
2309         delete IARDH;
2310         delete IARDX;
2311         delete IARDY;
2312         delete IAID;
2313     }
2314     return SBREG;
2315 failed:
2316     if(bRetained == FALSE) {
2317         delete IADT;
2318         delete IAFS;
2319         delete IADS;
2320         delete IAIT;
2321         delete IARI;
2322         delete IARDW;
2323         delete IARDH;
2324         delete IARDX;
2325         delete IARDY;
2326         delete IAID;
2327     }
2328     delete SBREG;
2329     return NULL;
2330 }
decode_Arith(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,JBig2ArithCtx * grContext)2331 CJBig2_SymbolDict *CJBig2_SDDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder,
2332         JBig2ArithCtx *gbContext, JBig2ArithCtx *grContext)
2333 {
2334     CJBig2_Image **SDNEWSYMS;
2335     FX_DWORD HCHEIGHT, NSYMSDECODED;
2336     FX_INT32 HCDH;
2337     FX_DWORD SYMWIDTH, TOTWIDTH;
2338     FX_INT32 DW;
2339     CJBig2_Image *BS;
2340     FX_DWORD I, J, REFAGGNINST;
2341     FX_BOOL *EXFLAGS;
2342     FX_DWORD EXINDEX;
2343     FX_BOOL CUREXFLAG;
2344     FX_DWORD EXRUNLENGTH;
2345     FX_INT32 nVal;
2346     FX_DWORD nTmp;
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         for(;;) {
2396             nVal = IADW->decode(pArithDecoder, &DW);
2397             if(nVal == JBIG2_OOB) {
2398                 break;
2399             } else if(nVal != 0) {
2400                 m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2401                 goto failed;
2402             } else {
2403                 if (NSYMSDECODED >= SDNUMNEWSYMS) {
2404                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): NSYMSDECODED >= SDNUMNEWSYMS.");
2405                     goto failed;
2406                 }
2407                 SYMWIDTH = SYMWIDTH + DW;
2408                 if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) {
2409                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): invalid SYMWIDTH value.");
2410                     goto failed;
2411                 } else if (HCHEIGHT == 0 || SYMWIDTH == 0) {
2412                     TOTWIDTH = TOTWIDTH + SYMWIDTH;
2413                     SDNEWSYMS[NSYMSDECODED] = NULL;
2414                     NSYMSDECODED = NSYMSDECODED + 1;
2415                     continue;
2416                 }
2417                 TOTWIDTH = TOTWIDTH + SYMWIDTH;
2418             }
2419             if(SDREFAGG == 0) {
2420                 JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
2421                 pGRD->MMR = 0;
2422                 pGRD->GBW = SYMWIDTH;
2423                 pGRD->GBH = HCHEIGHT;
2424                 pGRD->GBTEMPLATE = SDTEMPLATE;
2425                 pGRD->TPGDON = 0;
2426                 pGRD->USESKIP = 0;
2427                 pGRD->GBAT[0] = SDAT[0];
2428                 pGRD->GBAT[1] = SDAT[1];
2429                 pGRD->GBAT[2] = SDAT[2];
2430                 pGRD->GBAT[3] = SDAT[3];
2431                 pGRD->GBAT[4] = SDAT[4];
2432                 pGRD->GBAT[5] = SDAT[5];
2433                 pGRD->GBAT[6] = SDAT[6];
2434                 pGRD->GBAT[7] = SDAT[7];
2435                 BS = pGRD->decode_Arith(pArithDecoder, gbContext);
2436                 if(BS == NULL) {
2437                     delete pGRD;
2438                     goto failed;
2439                 }
2440                 delete pGRD;
2441             } else {
2442                 if(IAAI->decode(pArithDecoder, (int*)&REFAGGNINST) == -1) {
2443                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2444                     goto failed;
2445                 }
2446                 if(REFAGGNINST > 1) {
2447                     CJBig2_TRDProc *pDecoder;
2448                     JBIG2_ALLOC(pDecoder, CJBig2_TRDProc());
2449                     pDecoder->SBHUFF = SDHUFF;
2450                     pDecoder->SBREFINE = 1;
2451                     pDecoder->SBW = SYMWIDTH;
2452                     pDecoder->SBH = HCHEIGHT;
2453                     pDecoder->SBNUMINSTANCES = REFAGGNINST;
2454                     pDecoder->SBSTRIPS = 1;
2455                     pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
2456                     SBNUMSYMS = pDecoder->SBNUMSYMS;
2457                     nTmp = 0;
2458                     while((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
2459                         nTmp ++;
2460                     }
2461                     SBSYMCODELEN = (FX_BYTE)nTmp;
2462                     pDecoder->SBSYMCODELEN = SBSYMCODELEN;
2463                     SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(CJBig2_Image*));
2464                     JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2465                     JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*));
2466                     pDecoder->SBSYMS = SBSYMS;
2467                     pDecoder->SBDEFPIXEL = 0;
2468                     pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
2469                     pDecoder->TRANSPOSED = 0;
2470                     pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
2471                     pDecoder->SBDSOFFSET = 0;
2472                     JBIG2_ALLOC(SBHUFFFS, CJBig2_HuffmanTable(HuffmanTable_B6,
2473                                 sizeof(HuffmanTable_B6) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B6));
2474                     JBIG2_ALLOC(SBHUFFDS, CJBig2_HuffmanTable(HuffmanTable_B8,
2475                                 sizeof(HuffmanTable_B8) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B8));
2476                     JBIG2_ALLOC(SBHUFFDT, CJBig2_HuffmanTable(HuffmanTable_B11,
2477                                 sizeof(HuffmanTable_B11) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B11));
2478                     JBIG2_ALLOC(SBHUFFRDW, CJBig2_HuffmanTable(HuffmanTable_B15,
2479                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2480                     JBIG2_ALLOC(SBHUFFRDH, CJBig2_HuffmanTable(HuffmanTable_B15,
2481                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2482                     JBIG2_ALLOC(SBHUFFRDX, CJBig2_HuffmanTable(HuffmanTable_B15,
2483                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2484                     JBIG2_ALLOC(SBHUFFRDY, CJBig2_HuffmanTable(HuffmanTable_B15,
2485                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2486                     JBIG2_ALLOC(SBHUFFRSIZE, CJBig2_HuffmanTable(HuffmanTable_B1,
2487                                 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
2488                     pDecoder->SBHUFFFS = SBHUFFFS;
2489                     pDecoder->SBHUFFDS = SBHUFFDS;
2490                     pDecoder->SBHUFFDT = SBHUFFDT;
2491                     pDecoder->SBHUFFRDW = SBHUFFRDW;
2492                     pDecoder->SBHUFFRDH = SBHUFFRDH;
2493                     pDecoder->SBHUFFRDX = SBHUFFRDX;
2494                     pDecoder->SBHUFFRDY = SBHUFFRDY;
2495                     pDecoder->SBHUFFRSIZE = SBHUFFRSIZE;
2496                     pDecoder->SBRTEMPLATE = SDRTEMPLATE;
2497                     pDecoder->SBRAT[0] = SDRAT[0];
2498                     pDecoder->SBRAT[1] = SDRAT[1];
2499                     pDecoder->SBRAT[2] = SDRAT[2];
2500                     pDecoder->SBRAT[3] = SDRAT[3];
2501                     JBig2IntDecoderState ids;
2502                     ids.IADT = IADT;
2503                     ids.IAFS = IAFS;
2504                     ids.IADS = IADS;
2505                     ids.IAIT = IAIT;
2506                     ids.IARI = IARI;
2507                     ids.IARDW = IARDW;
2508                     ids.IARDH = IARDH;
2509                     ids.IARDX = IARDX;
2510                     ids.IARDY = IARDY;
2511                     ids.IAID = IAID;
2512                     BS = pDecoder->decode_Arith(pArithDecoder, grContext, &ids);
2513                     if(BS == NULL) {
2514                         m_pModule->JBig2_Free(SBSYMS);
2515                         delete SBHUFFFS;
2516                         delete SBHUFFDS;
2517                         delete SBHUFFDT;
2518                         delete SBHUFFRDW;
2519                         delete SBHUFFRDH;
2520                         delete SBHUFFRDX;
2521                         delete SBHUFFRDY;
2522                         delete SBHUFFRSIZE;
2523                         delete pDecoder;
2524                         goto failed;
2525                     }
2526                     m_pModule->JBig2_Free(SBSYMS);
2527                     delete SBHUFFFS;
2528                     delete SBHUFFDS;
2529                     delete SBHUFFDT;
2530                     delete SBHUFFRDW;
2531                     delete SBHUFFRDH;
2532                     delete SBHUFFRDX;
2533                     delete SBHUFFRDY;
2534                     delete SBHUFFRSIZE;
2535                     delete pDecoder;
2536                 } else if(REFAGGNINST == 1) {
2537                     SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
2538                     if(IAID->decode(pArithDecoder, (int*)&IDI) == -1) {
2539                         m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2540                         goto failed;
2541                     }
2542                     if((IARDX->decode(pArithDecoder, &RDXI) == -1)
2543                             || (IARDY->decode(pArithDecoder, &RDYI) == -1)) {
2544                         m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2545                         goto failed;
2546                     }
2547                     if (IDI >= SBNUMSYMS) {
2548                         m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith):"
2549                                                " refinement references unknown symbol %d", IDI);
2550                         goto failed;
2551                     }
2552                     SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(CJBig2_Image*));
2553                     JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2554                     JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*));
2555                     if (!SBSYMS[IDI]) {
2556                         m_pModule->JBig2_Free(SBSYMS);
2557                         goto failed;
2558                     }
2559                     JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
2560                     pGRRD->GRW = SYMWIDTH;
2561                     pGRRD->GRH = HCHEIGHT;
2562                     pGRRD->GRTEMPLATE = SDRTEMPLATE;
2563                     pGRRD->GRREFERENCE = SBSYMS[IDI];
2564                     pGRRD->GRREFERENCEDX = RDXI;
2565                     pGRRD->GRREFERENCEDY = RDYI;
2566                     pGRRD->TPGRON = 0;
2567                     pGRRD->GRAT[0] = SDRAT[0];
2568                     pGRRD->GRAT[1] = SDRAT[1];
2569                     pGRRD->GRAT[2] = SDRAT[2];
2570                     pGRRD->GRAT[3] = SDRAT[3];
2571                     BS = pGRRD->decode(pArithDecoder, grContext);
2572                     if(BS == NULL) {
2573                         m_pModule->JBig2_Free(SBSYMS);
2574                         delete pGRRD;
2575                         goto failed;
2576                     }
2577                     m_pModule->JBig2_Free(SBSYMS);
2578                     delete pGRRD;
2579                 }
2580             }
2581             SDNEWSYMS[NSYMSDECODED] = BS;
2582             BS = NULL;
2583             NSYMSDECODED = NSYMSDECODED + 1;
2584         }
2585     }
2586     EXINDEX = 0;
2587     CUREXFLAG = 0;
2588     EXFLAGS = (FX_BOOL*)m_pModule->JBig2_Malloc2(sizeof(FX_BOOL), (SDNUMINSYMS + SDNUMNEWSYMS));
2589     while(EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
2590         if(IAEX->decode(pArithDecoder, (int*)&EXRUNLENGTH) == -1) {
2591             m_pModule->JBig2_Free(EXFLAGS);
2592             m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): too short.");
2593             goto failed;
2594         }
2595         if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) {
2596             m_pModule->JBig2_Free(EXFLAGS);
2597             m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): Invalid EXRUNLENGTH value.");
2598             goto failed;
2599         }
2600         if(EXRUNLENGTH != 0) {
2601             for(I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) {
2602                 EXFLAGS[I] = CUREXFLAG;
2603             }
2604         }
2605         EXINDEX = EXINDEX + EXRUNLENGTH;
2606         CUREXFLAG = !CUREXFLAG;
2607     }
2608     JBIG2_ALLOC(pDict, CJBig2_SymbolDict());
2609     pDict->SDNUMEXSYMS = SDNUMEXSYMS;
2610     pDict->SDEXSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), SDNUMEXSYMS);
2611     I = J = 0;
2612     for(I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
2613         if(EXFLAGS[I] && J < SDNUMEXSYMS) {
2614             if(I < SDNUMINSYMS) {
2615                 JBIG2_ALLOC(pDict->SDEXSYMS[J], CJBig2_Image(*SDINSYMS[I]));
2616             } else {
2617                 pDict->SDEXSYMS[J] = SDNEWSYMS[I - SDNUMINSYMS];
2618             }
2619             J = J + 1;
2620         } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
2621             delete SDNEWSYMS[I - SDNUMINSYMS];
2622         }
2623     }
2624     if (J < SDNUMEXSYMS) {
2625         pDict->SDNUMEXSYMS = J;
2626     }
2627     m_pModule->JBig2_Free(EXFLAGS);
2628     m_pModule->JBig2_Free(SDNEWSYMS);
2629     delete IADH;
2630     delete IADW;
2631     delete IAAI;
2632     delete IARDX;
2633     delete IARDY;
2634     delete IAEX;
2635     delete IAID;
2636     delete IADT;
2637     delete IAFS;
2638     delete IADS;
2639     delete IAIT;
2640     delete IARI;
2641     delete IARDW;
2642     delete IARDH;
2643     return pDict;
2644 failed:
2645     for(I = 0; I < NSYMSDECODED; I++) {
2646         if (SDNEWSYMS[I]) {
2647             delete SDNEWSYMS[I];
2648             SDNEWSYMS[I] = NULL;
2649         }
2650     }
2651     m_pModule->JBig2_Free(SDNEWSYMS);
2652     delete IADH;
2653     delete IADW;
2654     delete IAAI;
2655     delete IARDX;
2656     delete IARDY;
2657     delete IAEX;
2658     delete IAID;
2659     delete IADT;
2660     delete IAFS;
2661     delete IADS;
2662     delete IAIT;
2663     delete IARI;
2664     delete IARDW;
2665     delete IARDH;
2666     return NULL;
2667 }
decode_Huffman(CJBig2_BitStream * pStream,JBig2ArithCtx * gbContext,JBig2ArithCtx * grContext,IFX_Pause * pPause)2668 CJBig2_SymbolDict *CJBig2_SDDProc::decode_Huffman(CJBig2_BitStream *pStream,
2669         JBig2ArithCtx *gbContext, JBig2ArithCtx *grContext, IFX_Pause* pPause)
2670 {
2671     CJBig2_Image **SDNEWSYMS;
2672     FX_DWORD *SDNEWSYMWIDTHS;
2673     FX_DWORD HCHEIGHT, NSYMSDECODED;
2674     FX_INT32 HCDH;
2675     FX_DWORD SYMWIDTH, TOTWIDTH, HCFIRSTSYM;
2676     FX_INT32 DW;
2677     CJBig2_Image *BS, *BHC;
2678     FX_DWORD I, J, REFAGGNINST;
2679     FX_BOOL *EXFLAGS;
2680     FX_DWORD EXINDEX;
2681     FX_BOOL CUREXFLAG;
2682     FX_DWORD EXRUNLENGTH;
2683     FX_INT32 nVal, nBits;
2684     FX_DWORD nTmp;
2685     FX_DWORD SBNUMSYMS;
2686     FX_BYTE SBSYMCODELEN;
2687     JBig2HuffmanCode *SBSYMCODES;
2688     FX_DWORD IDI;
2689     FX_INT32 RDXI, RDYI;
2690     FX_DWORD BMSIZE;
2691     FX_DWORD stride;
2692     CJBig2_Image **SBSYMS;
2693     CJBig2_HuffmanTable *SBHUFFFS, *SBHUFFDS, *SBHUFFDT, *SBHUFFRDW, *SBHUFFRDH, *SBHUFFRDX, *SBHUFFRDY,
2694                         *SBHUFFRSIZE, *pTable;
2695     CJBig2_HuffmanDecoder *pHuffmanDecoder;
2696     CJBig2_GRRDProc *pGRRD;
2697     CJBig2_ArithDecoder *pArithDecoder;
2698     CJBig2_GRDProc *pGRD;
2699     CJBig2_SymbolDict *pDict;
2700     JBIG2_ALLOC(pHuffmanDecoder, CJBig2_HuffmanDecoder(pStream));
2701     SDNEWSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SDNUMNEWSYMS, sizeof(CJBig2_Image*));
2702     FXSYS_memset32(SDNEWSYMS, 0 , SDNUMNEWSYMS * sizeof(CJBig2_Image*));
2703     SDNEWSYMWIDTHS = NULL;
2704     BHC = NULL;
2705     if(SDREFAGG == 0) {
2706         SDNEWSYMWIDTHS = (FX_DWORD *)m_pModule->JBig2_Malloc2(SDNUMNEWSYMS, sizeof(FX_DWORD));
2707         FXSYS_memset32(SDNEWSYMWIDTHS, 0 , SDNUMNEWSYMS * sizeof(FX_DWORD));
2708     }
2709     HCHEIGHT = 0;
2710     NSYMSDECODED = 0;
2711     BS = NULL;
2712     while(NSYMSDECODED < SDNUMNEWSYMS) {
2713         if(pHuffmanDecoder->decodeAValue(SDHUFFDH, &HCDH) != 0) {
2714             m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2715             goto failed;
2716         }
2717         HCHEIGHT = HCHEIGHT + HCDH;
2718         if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
2719             m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): invalid HCHEIGHT value.");
2720             goto failed;
2721         }
2722         SYMWIDTH = 0;
2723         TOTWIDTH = 0;
2724         HCFIRSTSYM = NSYMSDECODED;
2725         for(;;) {
2726             nVal = pHuffmanDecoder->decodeAValue(SDHUFFDW, &DW);
2727             if(nVal == JBIG2_OOB) {
2728                 break;
2729             } else if(nVal != 0) {
2730                 m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2731                 goto failed;
2732             } else {
2733                 if (NSYMSDECODED >= SDNUMNEWSYMS) {
2734                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): NSYMSDECODED >= SDNUMNEWSYMS.");
2735                     goto failed;
2736                 }
2737                 SYMWIDTH = SYMWIDTH + DW;
2738                 if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) {
2739                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): invalid SYMWIDTH value.");
2740                     goto failed;
2741                 } else if (HCHEIGHT == 0 || SYMWIDTH == 0) {
2742                     TOTWIDTH = TOTWIDTH + SYMWIDTH;
2743                     SDNEWSYMS[NSYMSDECODED] = NULL;
2744                     NSYMSDECODED = NSYMSDECODED + 1;
2745                     continue;
2746                 }
2747                 TOTWIDTH = TOTWIDTH + SYMWIDTH;
2748             }
2749             if(SDREFAGG == 1) {
2750                 if(pHuffmanDecoder->decodeAValue(SDHUFFAGGINST, (int*)&REFAGGNINST) != 0) {
2751                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2752                     goto failed;
2753                 }
2754                 BS = NULL;
2755                 if(REFAGGNINST > 1) {
2756                     CJBig2_TRDProc *pDecoder;
2757                     JBIG2_ALLOC(pDecoder, CJBig2_TRDProc());
2758                     pDecoder->SBHUFF = SDHUFF;
2759                     pDecoder->SBREFINE = 1;
2760                     pDecoder->SBW = SYMWIDTH;
2761                     pDecoder->SBH = HCHEIGHT;
2762                     pDecoder->SBNUMINSTANCES = REFAGGNINST;
2763                     pDecoder->SBSTRIPS = 1;
2764                     pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
2765                     SBNUMSYMS = pDecoder->SBNUMSYMS;
2766                     SBSYMCODES = (JBig2HuffmanCode*)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(JBig2HuffmanCode));
2767                     nTmp = 1;
2768                     while((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
2769                         nTmp ++;
2770                     }
2771                     for(I = 0; I < SBNUMSYMS; I++) {
2772                         SBSYMCODES[I].codelen = nTmp;
2773                         SBSYMCODES[I].code = I;
2774                     }
2775                     pDecoder->SBSYMCODES = SBSYMCODES;
2776                     SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(CJBig2_Image*));
2777                     JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2778                     JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*));
2779                     pDecoder->SBSYMS = SBSYMS;
2780                     pDecoder->SBDEFPIXEL = 0;
2781                     pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
2782                     pDecoder->TRANSPOSED = 0;
2783                     pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
2784                     pDecoder->SBDSOFFSET = 0;
2785                     JBIG2_ALLOC(SBHUFFFS, CJBig2_HuffmanTable(HuffmanTable_B6,
2786                                 sizeof(HuffmanTable_B6) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B6));
2787                     JBIG2_ALLOC(SBHUFFDS, CJBig2_HuffmanTable(HuffmanTable_B8,
2788                                 sizeof(HuffmanTable_B8) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B8));
2789                     JBIG2_ALLOC(SBHUFFDT, CJBig2_HuffmanTable(HuffmanTable_B11,
2790                                 sizeof(HuffmanTable_B11) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B11));
2791                     JBIG2_ALLOC(SBHUFFRDW, CJBig2_HuffmanTable(HuffmanTable_B15,
2792                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2793                     JBIG2_ALLOC(SBHUFFRDH, CJBig2_HuffmanTable(HuffmanTable_B15,
2794                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2795                     JBIG2_ALLOC(SBHUFFRDX, CJBig2_HuffmanTable(HuffmanTable_B15,
2796                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2797                     JBIG2_ALLOC(SBHUFFRDY, CJBig2_HuffmanTable(HuffmanTable_B15,
2798                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2799                     JBIG2_ALLOC(SBHUFFRSIZE, CJBig2_HuffmanTable(HuffmanTable_B1,
2800                                 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
2801                     pDecoder->SBHUFFFS = SBHUFFFS;
2802                     pDecoder->SBHUFFDS = SBHUFFDS;
2803                     pDecoder->SBHUFFDT = SBHUFFDT;
2804                     pDecoder->SBHUFFRDW = SBHUFFRDW;
2805                     pDecoder->SBHUFFRDH = SBHUFFRDH;
2806                     pDecoder->SBHUFFRDX = SBHUFFRDX;
2807                     pDecoder->SBHUFFRDY = SBHUFFRDY;
2808                     pDecoder->SBHUFFRSIZE = SBHUFFRSIZE;
2809                     pDecoder->SBRTEMPLATE = SDRTEMPLATE;
2810                     pDecoder->SBRAT[0] = SDRAT[0];
2811                     pDecoder->SBRAT[1] = SDRAT[1];
2812                     pDecoder->SBRAT[2] = SDRAT[2];
2813                     pDecoder->SBRAT[3] = SDRAT[3];
2814                     BS = pDecoder->decode_Huffman(pStream, grContext);
2815                     if(BS == NULL) {
2816                         m_pModule->JBig2_Free(SBSYMCODES);
2817                         m_pModule->JBig2_Free(SBSYMS);
2818                         delete SBHUFFFS;
2819                         delete SBHUFFDS;
2820                         delete SBHUFFDT;
2821                         delete SBHUFFRDW;
2822                         delete SBHUFFRDH;
2823                         delete SBHUFFRDX;
2824                         delete SBHUFFRDY;
2825                         delete SBHUFFRSIZE;
2826                         delete pDecoder;
2827                         goto failed;
2828                     }
2829                     m_pModule->JBig2_Free(SBSYMCODES);
2830                     m_pModule->JBig2_Free(SBSYMS);
2831                     delete SBHUFFFS;
2832                     delete SBHUFFDS;
2833                     delete SBHUFFDT;
2834                     delete SBHUFFRDW;
2835                     delete SBHUFFRDH;
2836                     delete SBHUFFRDX;
2837                     delete SBHUFFRDY;
2838                     delete SBHUFFRSIZE;
2839                     delete pDecoder;
2840                 } else if(REFAGGNINST == 1) {
2841                     SBNUMSYMS = SDNUMINSYMS + SDNUMNEWSYMS;
2842                     nTmp = 1;
2843                     while((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
2844                         nTmp ++;
2845                     }
2846                     SBSYMCODELEN = (FX_BYTE)nTmp;
2847                     SBSYMCODES = (JBig2HuffmanCode*)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(JBig2HuffmanCode));
2848                     for(I = 0; I < SBNUMSYMS; I++) {
2849                         SBSYMCODES[I].codelen = SBSYMCODELEN;
2850                         SBSYMCODES[I].code = I;
2851                     }
2852                     nVal = 0;
2853                     nBits = 0;
2854                     for(;;) {
2855                         if(pStream->read1Bit(&nTmp) != 0) {
2856                             m_pModule->JBig2_Free(SBSYMCODES);
2857                             m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2858                             goto failed;
2859                         }
2860                         nVal = (nVal << 1) | nTmp;
2861                         for(IDI = 0; IDI < SBNUMSYMS; IDI++) {
2862                             if((nVal == SBSYMCODES[IDI].code)
2863                                     && (nBits == SBSYMCODES[IDI].codelen)) {
2864                                 break;
2865                             }
2866                         }
2867                         if(IDI < SBNUMSYMS) {
2868                             break;
2869                         }
2870                     }
2871                     m_pModule->JBig2_Free(SBSYMCODES);
2872                     JBIG2_ALLOC(SBHUFFRDX, CJBig2_HuffmanTable(HuffmanTable_B15,
2873                                 sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
2874                     JBIG2_ALLOC(SBHUFFRSIZE, CJBig2_HuffmanTable(HuffmanTable_B1,
2875                                 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
2876                     if((pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0)
2877                             || (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDYI) != 0)
2878                             || (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
2879                         delete SBHUFFRDX;
2880                         delete SBHUFFRSIZE;
2881                         m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2882                         goto failed;
2883                     }
2884                     delete SBHUFFRDX;
2885                     delete SBHUFFRSIZE;
2886                     pStream->alignByte();
2887                     nTmp = pStream->getOffset();
2888                     SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(SBNUMSYMS, sizeof(CJBig2_Image*));
2889                     JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
2890                     JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*));
2891                     JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
2892                     pGRRD->GRW = SYMWIDTH;
2893                     pGRRD->GRH = HCHEIGHT;
2894                     pGRRD->GRTEMPLATE = SDRTEMPLATE;
2895                     pGRRD->GRREFERENCE = SBSYMS[IDI];
2896                     pGRRD->GRREFERENCEDX = RDXI;
2897                     pGRRD->GRREFERENCEDY = RDYI;
2898                     pGRRD->TPGRON = 0;
2899                     pGRRD->GRAT[0] = SDRAT[0];
2900                     pGRRD->GRAT[1] = SDRAT[1];
2901                     pGRRD->GRAT[2] = SDRAT[2];
2902                     pGRRD->GRAT[3] = SDRAT[3];
2903                     JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(pStream));
2904                     BS = pGRRD->decode(pArithDecoder, grContext);
2905                     if(BS == NULL) {
2906                         m_pModule->JBig2_Free(SBSYMS);
2907                         delete pGRRD;
2908                         delete pArithDecoder;
2909                         goto failed;
2910                     }
2911                     pStream->alignByte();
2912                     pStream->offset(2);
2913                     if((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
2914                         delete BS;
2915                         m_pModule->JBig2_Free(SBSYMS);
2916                         delete pGRRD;
2917                         delete pArithDecoder;
2918                         m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman):"
2919                                                "bytes processed by generic refinement region decoding procedure doesn't equal SBHUFFRSIZE.");
2920                         goto failed;
2921                     }
2922                     m_pModule->JBig2_Free(SBSYMS);
2923                     delete pGRRD;
2924                     delete pArithDecoder;
2925                 }
2926                 SDNEWSYMS[NSYMSDECODED] = BS;
2927             }
2928             if(SDREFAGG == 0) {
2929                 SDNEWSYMWIDTHS[NSYMSDECODED] = SYMWIDTH;
2930             }
2931             NSYMSDECODED = NSYMSDECODED + 1;
2932         }
2933         if(SDREFAGG == 0) {
2934             if(pHuffmanDecoder->decodeAValue(SDHUFFBMSIZE, (FX_INT32*)&BMSIZE) != 0) {
2935                 m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2936                 goto failed;
2937             }
2938             pStream->alignByte();
2939             if(BMSIZE == 0) {
2940                 stride = (TOTWIDTH + 7) >> 3;
2941                 if(pStream->getByteLeft() >= stride * HCHEIGHT) {
2942                     JBIG2_ALLOC(BHC, CJBig2_Image(TOTWIDTH, HCHEIGHT));
2943                     for(I = 0; I < HCHEIGHT; I ++) {
2944                         JBIG2_memcpy(BHC->m_pData + I * BHC->m_nStride, pStream->getPointer(), stride);
2945                         pStream->offset(stride);
2946                     }
2947                 } else {
2948                     m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2949                     goto failed;
2950                 }
2951             } else {
2952                 JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
2953                 pGRD->MMR = 1;
2954                 pGRD->GBW = TOTWIDTH;
2955                 pGRD->GBH = HCHEIGHT;
2956                 FXCODEC_STATUS status = pGRD->Start_decode_MMR(&BHC, pStream);
2957                 while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
2958                     pGRD->Continue_decode(pPause);
2959                 }
2960                 delete pGRD;
2961                 pStream->alignByte();
2962             }
2963             nTmp = 0;
2964             if (!BHC) {
2965                 continue;
2966             }
2967             for(I = HCFIRSTSYM; I < NSYMSDECODED; I++) {
2968                 SDNEWSYMS[I] = BHC->subImage(nTmp, 0, SDNEWSYMWIDTHS[I], HCHEIGHT);
2969                 nTmp += SDNEWSYMWIDTHS[I];
2970             }
2971             delete BHC;
2972             BHC = NULL;
2973         }
2974     }
2975     EXINDEX = 0;
2976     CUREXFLAG = 0;
2977     JBIG2_ALLOC(pTable, CJBig2_HuffmanTable(HuffmanTable_B1,
2978                                             sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
2979     EXFLAGS = (FX_BOOL*)m_pModule->JBig2_Malloc2(sizeof(FX_BOOL), (SDNUMINSYMS + SDNUMNEWSYMS));
2980     while(EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
2981         if(pHuffmanDecoder->decodeAValue(pTable, (int*)&EXRUNLENGTH) != 0) {
2982             delete pTable;
2983             m_pModule->JBig2_Free(EXFLAGS);
2984             m_pModule->JBig2_Error("symbol dictionary decoding procedure (huffman): too short.");
2985             goto failed;
2986         }
2987         if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) {
2988             delete pTable;
2989             m_pModule->JBig2_Free(EXFLAGS);
2990             m_pModule->JBig2_Error("symbol dictionary decoding procedure (arith): Invalid EXRUNLENGTH value.");
2991             goto failed;
2992         }
2993         if(EXRUNLENGTH != 0) {
2994             for(I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) {
2995                 EXFLAGS[I] = CUREXFLAG;
2996             }
2997         }
2998         EXINDEX = EXINDEX + EXRUNLENGTH;
2999         CUREXFLAG = !CUREXFLAG;
3000     }
3001     delete pTable;
3002     JBIG2_ALLOC(pDict, CJBig2_SymbolDict());
3003     pDict->SDNUMEXSYMS = SDNUMEXSYMS;
3004     pDict->SDEXSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), SDNUMEXSYMS);
3005     I = J = 0;
3006     for(I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
3007         if(EXFLAGS[I] && J < SDNUMEXSYMS) {
3008             if(I < SDNUMINSYMS) {
3009                 JBIG2_ALLOC(pDict->SDEXSYMS[J], CJBig2_Image(*SDINSYMS[I]));
3010             } else {
3011                 pDict->SDEXSYMS[J] = SDNEWSYMS[I - SDNUMINSYMS];
3012             }
3013             J = J + 1;
3014         } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
3015             delete SDNEWSYMS[I - SDNUMINSYMS];
3016         }
3017     }
3018     if (J < SDNUMEXSYMS) {
3019         pDict->SDNUMEXSYMS = J;
3020     }
3021     m_pModule->JBig2_Free(EXFLAGS);
3022     m_pModule->JBig2_Free(SDNEWSYMS);
3023     if(SDREFAGG == 0) {
3024         m_pModule->JBig2_Free(SDNEWSYMWIDTHS);
3025     }
3026     delete pHuffmanDecoder;
3027     return pDict;
3028 failed:
3029     for(I = 0; I < NSYMSDECODED; I++) {
3030         if (SDNEWSYMS[I]) {
3031             delete SDNEWSYMS[I];
3032         }
3033     }
3034     m_pModule->JBig2_Free(SDNEWSYMS);
3035     if(SDREFAGG == 0) {
3036         m_pModule->JBig2_Free(SDNEWSYMWIDTHS);
3037     }
3038     delete pHuffmanDecoder;
3039     return NULL;
3040 }
decode_Arith(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)3041 CJBig2_Image *CJBig2_HTRDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder,
3042         JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3043 {
3044     FX_DWORD ng, mg;
3045     FX_INT32 x, y;
3046     CJBig2_Image *HSKIP;
3047     FX_DWORD HBPP;
3048     FX_DWORD *GI;
3049     CJBig2_Image *HTREG;
3050     CJBig2_GSIDProc *pGID;
3051     JBIG2_ALLOC(HTREG, CJBig2_Image(HBW, HBH));
3052     HTREG->fill(HDEFPIXEL);
3053     HSKIP = NULL;
3054     if(HENABLESKIP == 1) {
3055         JBIG2_ALLOC(HSKIP, CJBig2_Image(HGW, HGH));
3056         for(mg = 0; mg < HGH; mg++) {
3057             for(ng = 0; ng < HGW; ng++) {
3058                 x = (HGX + mg * HRY + ng * HRX) >> 8;
3059                 y = (HGY + mg * HRX - ng * HRY) >> 8;
3060                 if((x + HPW <= 0) | (x >= (FX_INT32)HBW)
3061                         | (y + HPH <= 0) | (y >= (FX_INT32)HPH)) {
3062                     HSKIP->setPixel(ng, mg, 1);
3063                 } else {
3064                     HSKIP->setPixel(ng, mg, 0);
3065                 }
3066             }
3067         }
3068     }
3069     HBPP = 1;
3070     while((FX_DWORD)(1 << HBPP) < HNUMPATS) {
3071         HBPP ++;
3072     }
3073     JBIG2_ALLOC(pGID, CJBig2_GSIDProc());
3074     pGID->GSMMR = HMMR;
3075     pGID->GSW = HGW;
3076     pGID->GSH = HGH;
3077     pGID->GSBPP = (FX_BYTE)HBPP;
3078     pGID->GSUSESKIP = HENABLESKIP;
3079     pGID->GSKIP = HSKIP;
3080     pGID->GSTEMPLATE = HTEMPLATE;
3081     GI = pGID->decode_Arith(pArithDecoder, gbContext, pPause);
3082     if(GI == NULL) {
3083         goto failed;
3084     }
3085     for(mg = 0; mg < HGH; mg++) {
3086         for(ng = 0; ng < HGW; ng++) {
3087             x = (HGX + mg * HRY + ng * HRX) >> 8;
3088             y = (HGY + mg * HRX - ng * HRY) >> 8;
3089             FX_DWORD pat_index = GI[mg * HGW + ng];
3090             if (pat_index >= HNUMPATS) {
3091                 pat_index = HNUMPATS - 1;
3092             }
3093             HTREG->composeFrom(x, y, HPATS[pat_index], HCOMBOP);
3094         }
3095     }
3096     m_pModule->JBig2_Free(GI);
3097     if(HSKIP) {
3098         delete HSKIP;
3099     }
3100     delete pGID;
3101     return HTREG;
3102 failed:
3103     if(HSKIP) {
3104         delete HSKIP;
3105     }
3106     delete pGID;
3107     delete HTREG;
3108     return NULL;
3109 }
decode_MMR(CJBig2_BitStream * pStream,IFX_Pause * pPause)3110 CJBig2_Image *CJBig2_HTRDProc::decode_MMR(CJBig2_BitStream *pStream, IFX_Pause* pPause)
3111 {
3112     FX_DWORD ng, mg;
3113     FX_INT32 x, y;
3114     FX_DWORD HBPP;
3115     FX_DWORD *GI;
3116     CJBig2_Image *HTREG;
3117     CJBig2_GSIDProc *pGID;
3118     JBIG2_ALLOC(HTREG, CJBig2_Image(HBW, HBH));
3119     HTREG->fill(HDEFPIXEL);
3120     HBPP = 1;
3121     while((FX_DWORD)(1 << HBPP) < HNUMPATS) {
3122         HBPP ++;
3123     }
3124     JBIG2_ALLOC(pGID, CJBig2_GSIDProc());
3125     pGID->GSMMR = HMMR;
3126     pGID->GSW = HGW;
3127     pGID->GSH = HGH;
3128     pGID->GSBPP = (FX_BYTE)HBPP;
3129     pGID->GSUSESKIP = 0;
3130     GI = pGID->decode_MMR(pStream, pPause);
3131     if(GI == NULL) {
3132         goto failed;
3133     }
3134     for(mg = 0; mg < HGH; mg++) {
3135         for(ng = 0; ng < HGW; ng++) {
3136             x = (HGX + mg * HRY + ng * HRX) >> 8;
3137             y = (HGY + mg * HRX - ng * HRY) >> 8;
3138             FX_DWORD pat_index = GI[mg * HGW + ng];
3139             if (pat_index >= HNUMPATS) {
3140                 pat_index = HNUMPATS - 1;
3141             }
3142             HTREG->composeFrom(x, y, HPATS[pat_index], HCOMBOP);
3143         }
3144     }
3145     m_pModule->JBig2_Free(GI);
3146     delete pGID;
3147     return HTREG;
3148 failed:
3149     delete pGID;
3150     delete HTREG;
3151     return NULL;
3152 }
decode_Arith(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)3153 CJBig2_PatternDict *CJBig2_PDDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder,
3154         JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3155 {
3156     FX_DWORD GRAY;
3157     CJBig2_Image *BHDC = NULL;
3158     CJBig2_PatternDict *pDict;
3159     CJBig2_GRDProc *pGRD;
3160     JBIG2_ALLOC(pDict, CJBig2_PatternDict());
3161     pDict->NUMPATS = GRAYMAX + 1;
3162     pDict->HDPATS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), pDict->NUMPATS);
3163     JBIG2_memset(pDict->HDPATS, 0, sizeof(CJBig2_Image*)*pDict->NUMPATS);
3164     JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
3165     pGRD->MMR = HDMMR;
3166     pGRD->GBW = (GRAYMAX + 1) * HDPW;
3167     pGRD->GBH = HDPH;
3168     pGRD->GBTEMPLATE = HDTEMPLATE;
3169     pGRD->TPGDON = 0;
3170     pGRD->USESKIP = 0;
3171     pGRD->GBAT[0] = -(FX_INT32)HDPW;
3172     pGRD->GBAT[1] = 0;
3173     if(pGRD->GBTEMPLATE == 0) {
3174         pGRD->GBAT[2] = -3;
3175         pGRD->GBAT[3] = -1;
3176         pGRD->GBAT[4] = 2;
3177         pGRD->GBAT[5] = -2;
3178         pGRD->GBAT[6] = -2;
3179         pGRD->GBAT[7] = -2;
3180     }
3181     FXCODEC_STATUS status = pGRD->Start_decode_Arith(&BHDC, pArithDecoder, gbContext);
3182     while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3183         pGRD->Continue_decode(pPause);
3184     }
3185     if(BHDC == NULL) {
3186         delete pGRD;
3187         goto failed;
3188     }
3189     delete pGRD;
3190     GRAY = 0;
3191     while(GRAY <= GRAYMAX) {
3192         pDict->HDPATS[GRAY] = BHDC->subImage(HDPW * GRAY, 0, HDPW, HDPH);
3193         GRAY = GRAY + 1;
3194     }
3195     delete BHDC;
3196     return pDict;
3197 failed:
3198     delete pDict;
3199     return NULL;
3200 }
3201 
decode_MMR(CJBig2_BitStream * pStream,IFX_Pause * pPause)3202 CJBig2_PatternDict *CJBig2_PDDProc::decode_MMR(CJBig2_BitStream *pStream, IFX_Pause* pPause)
3203 {
3204     FX_DWORD GRAY;
3205     CJBig2_Image *BHDC = NULL;
3206     CJBig2_PatternDict *pDict;
3207     CJBig2_GRDProc *pGRD;
3208     JBIG2_ALLOC(pDict, CJBig2_PatternDict());
3209     pDict->NUMPATS = GRAYMAX + 1;
3210     pDict->HDPATS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), pDict->NUMPATS);
3211     JBIG2_memset(pDict->HDPATS, 0, sizeof(CJBig2_Image*)*pDict->NUMPATS);
3212     JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
3213     pGRD->MMR = HDMMR;
3214     pGRD->GBW = (GRAYMAX + 1) * HDPW;
3215     pGRD->GBH = HDPH;
3216     FXCODEC_STATUS status = pGRD->Start_decode_MMR(&BHDC, pStream);
3217     while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3218         pGRD->Continue_decode(pPause);
3219     }
3220     if(BHDC == NULL) {
3221         delete pGRD;
3222         goto failed;
3223     }
3224     delete pGRD;
3225     GRAY = 0;
3226     while(GRAY <= GRAYMAX) {
3227         pDict->HDPATS[GRAY] = BHDC->subImage(HDPW * GRAY, 0, HDPW, HDPH);
3228         GRAY = GRAY + 1;
3229     }
3230     delete BHDC;
3231     return pDict;
3232 failed:
3233     delete pDict;
3234     return NULL;
3235 }
decode_Arith(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)3236 FX_DWORD *CJBig2_GSIDProc::decode_Arith(CJBig2_ArithDecoder *pArithDecoder,
3237                                         JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3238 {
3239     CJBig2_Image **GSPLANES;
3240     FX_INT32 J, K;
3241     FX_DWORD x, y;
3242     FX_DWORD *GSVALS;
3243     CJBig2_GRDProc *pGRD;
3244     GSPLANES = (CJBig2_Image **)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), GSBPP);
3245     if (!GSPLANES) {
3246         return NULL;
3247     }
3248     GSVALS = (FX_DWORD*)m_pModule->JBig2_Malloc3(sizeof(FX_DWORD), GSW, GSH);
3249     if (!GSVALS) {
3250         m_pModule->JBig2_Free(GSPLANES);
3251         return NULL;
3252     }
3253     JBIG2_memset(GSPLANES, 0, sizeof(CJBig2_Image*)*GSBPP);
3254     JBIG2_memset(GSVALS, 0, sizeof(FX_DWORD)*GSW * GSH);
3255     JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
3256     pGRD->MMR = GSMMR;
3257     pGRD->GBW = GSW;
3258     pGRD->GBH = GSH;
3259     pGRD->GBTEMPLATE = GSTEMPLATE;
3260     pGRD->TPGDON = 0;
3261     pGRD->USESKIP = GSUSESKIP;
3262     pGRD->SKIP = GSKIP;
3263     if(GSTEMPLATE <= 1) {
3264         pGRD->GBAT[0] = 3;
3265     } else {
3266         pGRD->GBAT[0] = 2;
3267     }
3268     pGRD->GBAT[1] = -1;
3269     if(pGRD->GBTEMPLATE == 0) {
3270         pGRD->GBAT[2] = -3;
3271         pGRD->GBAT[3] = -1;
3272         pGRD->GBAT[4] = 2;
3273         pGRD->GBAT[5] = -2;
3274         pGRD->GBAT[6] = -2;
3275         pGRD->GBAT[7] = -2;
3276     }
3277     FXCODEC_STATUS status = pGRD->Start_decode_Arith(&GSPLANES[GSBPP - 1], pArithDecoder, gbContext);
3278     while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3279         pGRD->Continue_decode(pPause);
3280     }
3281     if(GSPLANES[GSBPP - 1] == NULL) {
3282         goto failed;
3283     }
3284     J = GSBPP - 2;
3285     while(J >= 0) {
3286         FXCODEC_STATUS status = pGRD->Start_decode_Arith(&GSPLANES[J], pArithDecoder, gbContext);
3287         while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3288             pGRD->Continue_decode(pPause);
3289         }
3290         if(GSPLANES[J] == NULL) {
3291             for(K = GSBPP - 1; K > J; K--) {
3292                 delete GSPLANES[K];
3293                 goto failed;
3294             }
3295         }
3296         GSPLANES[J]->composeFrom(0, 0, GSPLANES[J + 1], JBIG2_COMPOSE_XOR);
3297         J = J - 1;
3298     }
3299     for(y = 0; y < GSH; y++) {
3300         for(x = 0; x < GSW; x++) {
3301             for(J = 0; J < GSBPP; J++) {
3302                 GSVALS[y * GSW + x] |= GSPLANES[J]->getPixel(x, y) << J;
3303             }
3304         }
3305     }
3306     for(J = 0; J < GSBPP; J++) {
3307         delete GSPLANES[J];
3308     }
3309     m_pModule->JBig2_Free(GSPLANES);
3310     delete pGRD;
3311     return GSVALS;
3312 failed:
3313     m_pModule->JBig2_Free(GSPLANES);
3314     delete pGRD;
3315     m_pModule->JBig2_Free(GSVALS);
3316     return NULL;
3317 }
decode_MMR(CJBig2_BitStream * pStream,IFX_Pause * pPause)3318 FX_DWORD *CJBig2_GSIDProc::decode_MMR(CJBig2_BitStream *pStream, IFX_Pause* pPause)
3319 {
3320     CJBig2_Image **GSPLANES;
3321     FX_INT32 J, K;
3322     FX_DWORD x, y;
3323     FX_DWORD *GSVALS;
3324     CJBig2_GRDProc *pGRD;
3325     GSPLANES = (CJBig2_Image **)m_pModule->JBig2_Malloc2(sizeof(CJBig2_Image*), GSBPP);
3326     if (!GSPLANES) {
3327         return NULL;
3328     }
3329     GSVALS = (FX_DWORD*)m_pModule->JBig2_Malloc3(sizeof(FX_DWORD), GSW, GSH);
3330     if (!GSVALS) {
3331         if (GSPLANES) {
3332             m_pModule->JBig2_Free(GSPLANES);
3333         }
3334         return NULL;
3335     }
3336     JBIG2_memset(GSPLANES, 0, sizeof(CJBig2_Image*)*GSBPP);
3337     JBIG2_memset(GSVALS, 0, sizeof(FX_DWORD)*GSW * GSH);
3338     JBIG2_ALLOC(pGRD, CJBig2_GRDProc());
3339     pGRD->MMR = GSMMR;
3340     pGRD->GBW = GSW;
3341     pGRD->GBH = GSH;
3342     FXCODEC_STATUS status = pGRD->Start_decode_MMR(&GSPLANES[GSBPP - 1], pStream);
3343     while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3344         pGRD->Continue_decode(pPause);
3345     }
3346     if(GSPLANES[GSBPP - 1] == NULL) {
3347         goto failed;
3348     }
3349     pStream->alignByte();
3350     pStream->offset(3);
3351     J = GSBPP - 2;
3352     while(J >= 0) {
3353         FXCODEC_STATUS status = pGRD->Start_decode_MMR(&GSPLANES[J], pStream);
3354         while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3355             pGRD->Continue_decode(pPause);
3356         }
3357         if(GSPLANES[J] == NULL) {
3358             for(K = GSBPP - 1; K > J; K--) {
3359                 delete GSPLANES[K];
3360                 goto failed;
3361             }
3362         }
3363         pStream->alignByte();
3364         pStream->offset(3);
3365         GSPLANES[J]->composeFrom(0, 0, GSPLANES[J + 1], JBIG2_COMPOSE_XOR);
3366         J = J - 1;
3367     }
3368     for(y = 0; y < GSH; y++) {
3369         for(x = 0; x < GSW; x++) {
3370             for(J = 0; J < GSBPP; J++) {
3371                 GSVALS[y * GSW + x] |= GSPLANES[J]->getPixel(x, y) << J;
3372             }
3373         }
3374     }
3375     for(J = 0; J < GSBPP; J++) {
3376         delete GSPLANES[J];
3377     }
3378     m_pModule->JBig2_Free(GSPLANES);
3379     delete pGRD;
3380     return GSVALS;
3381 failed:
3382     m_pModule->JBig2_Free(GSPLANES);
3383     delete pGRD;
3384     m_pModule->JBig2_Free(GSVALS);
3385     return NULL;
3386 }
Start_decode_Arith(CJBig2_Image ** pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)3387 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_Arith(CJBig2_Image** pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3388 {
3389     if (GBW == 0 || GBH == 0) {
3390         m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3391         return FXCODEC_STATUS_DECODE_FINISH;
3392     }
3393     m_ProssiveStatus = FXCODEC_STATUS_DECODE_READY;
3394     m_pPause = pPause;
3395     if(*pImage == NULL) {
3396         JBIG2_ALLOC((*pImage), CJBig2_Image(GBW, GBH));
3397     }
3398     if ((*pImage)->m_pData == NULL) {
3399         delete *pImage;
3400         *pImage = NULL;
3401         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
3402         m_ProssiveStatus = FXCODEC_STATUS_ERROR;
3403         return FXCODEC_STATUS_ERROR;
3404     }
3405     m_DecodeType = 1;
3406     m_pImage = pImage;
3407     (*m_pImage)->fill(0);
3408     m_pArithDecoder = pArithDecoder;
3409     m_gbContext = gbContext;
3410     LTP = 0;
3411     m_pLine = NULL;
3412     m_loopIndex = 0;
3413     return decode_Arith(pPause);
3414 }
decode_Arith(IFX_Pause * pPause)3415 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith(IFX_Pause* pPause)
3416 {
3417     int iline = m_loopIndex;
3418     CJBig2_Image* pImage = *m_pImage;
3419     if(GBTEMPLATE == 0) {
3420         if((GBAT[0] == 3) && (GBAT[1] == (signed char) - 1)
3421                 && (GBAT[2] == (signed char) - 3) && (GBAT[3] == (signed char) - 1)
3422                 && (GBAT[4] == 2) && (GBAT[5] == (signed char) - 2)
3423                 && (GBAT[6] == (signed char) - 2) && (GBAT[7] == (signed char) - 2)) {
3424             m_ProssiveStatus = decode_Arith_Template0_opt3(pImage, m_pArithDecoder, m_gbContext, pPause);
3425         } else {
3426             m_ProssiveStatus = decode_Arith_Template0_unopt(pImage, m_pArithDecoder, m_gbContext, pPause);
3427         }
3428     } else if(GBTEMPLATE == 1) {
3429         if((GBAT[0] == 3) && (GBAT[1] == (signed char) - 1)) {
3430             m_ProssiveStatus = decode_Arith_Template1_opt3(pImage, m_pArithDecoder, m_gbContext, pPause);
3431         } else {
3432             m_ProssiveStatus = decode_Arith_Template1_unopt(pImage, m_pArithDecoder, m_gbContext, pPause);
3433         }
3434     } else if(GBTEMPLATE == 2) {
3435         if((GBAT[0] == 2) && (GBAT[1] == (signed char) - 1)) {
3436             m_ProssiveStatus =  decode_Arith_Template2_opt3(pImage, m_pArithDecoder, m_gbContext, pPause);
3437         } else {
3438             m_ProssiveStatus =  decode_Arith_Template2_unopt(pImage, m_pArithDecoder, m_gbContext, pPause);
3439         }
3440     } else {
3441         if((GBAT[0] == 2) && (GBAT[1] == (signed char) - 1)) {
3442             m_ProssiveStatus = decode_Arith_Template3_opt3(pImage, m_pArithDecoder, m_gbContext, pPause);
3443         } else {
3444             m_ProssiveStatus = decode_Arith_Template3_unopt(pImage, m_pArithDecoder, m_gbContext, pPause);
3445         }
3446     }
3447     m_ReplaceRect.left = 0;
3448     m_ReplaceRect.right = pImage->m_nWidth;
3449     m_ReplaceRect.top = iline;
3450     m_ReplaceRect.bottom = m_loopIndex;
3451     if(m_ProssiveStatus == FXCODEC_STATUS_DECODE_FINISH) {
3452         m_loopIndex = 0;
3453     }
3454     return m_ProssiveStatus;
3455 }
Start_decode_Arith_V2(CJBig2_Image ** pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)3456 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_Arith_V2(CJBig2_Image** pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3457 {
3458     if(GBW == 0 || GBH == 0) {
3459         * pImage = NULL;
3460         m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3461         return FXCODEC_STATUS_DECODE_FINISH;
3462     }
3463     if(*pImage == NULL) {
3464         JBIG2_ALLOC((*pImage), CJBig2_Image(GBW, GBH));
3465     }
3466     if ((*pImage)->m_pData == NULL) {
3467         delete *pImage;
3468         *pImage = NULL;
3469         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
3470         m_ProssiveStatus = FXCODEC_STATUS_ERROR;
3471         return FXCODEC_STATUS_ERROR;
3472     }
3473     m_ProssiveStatus = FXCODEC_STATUS_DECODE_READY;
3474     m_DecodeType = 2;
3475     m_pPause = pPause;
3476     m_pImage = pImage;
3477     (*m_pImage)->fill(0);
3478     LTP = 0;
3479     m_loopIndex = 0;
3480     m_pArithDecoder = pArithDecoder;
3481     m_gbContext = gbContext;
3482     return decode_Arith_V2(pPause);
3483 }
decode_Arith_V2(IFX_Pause * pPause)3484 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_V2(IFX_Pause* pPause)
3485 {
3486     FX_BOOL SLTP, bVal;
3487     FX_DWORD CONTEXT;
3488     CJBig2_Image *GBREG = *m_pImage;
3489     FX_DWORD line1, line2, line3;
3490     LTP = 0;
3491     JBIG2_ALLOC(GBREG, CJBig2_Image(GBW, GBH));
3492     GBREG->fill(0);
3493     for(; m_loopIndex < GBH; m_loopIndex++) {
3494         if(TPGDON) {
3495             switch(GBTEMPLATE) {
3496                 case 0:
3497                     CONTEXT = 0x9b25;
3498                     break;
3499                 case 1:
3500                     CONTEXT = 0x0795;
3501                     break;
3502                 case 2:
3503                     CONTEXT = 0x00e5;
3504                     break;
3505                 case 3:
3506                     CONTEXT = 0x0195;
3507                     break;
3508             }
3509             SLTP = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3510             LTP = LTP ^ SLTP;
3511         }
3512         if(LTP == 1) {
3513             GBREG->copyLine(m_loopIndex, m_loopIndex - 1);
3514         } else {
3515             switch(GBTEMPLATE) {
3516                 case 0: {
3517                         line1 = GBREG->getPixel(1, m_loopIndex - 2);
3518                         line1 |= GBREG->getPixel(0, m_loopIndex - 2) << 1;
3519                         line2 = GBREG->getPixel(2, m_loopIndex - 1);
3520                         line2 |= GBREG->getPixel(1, m_loopIndex - 1) << 1;
3521                         line2 |= GBREG->getPixel(0, m_loopIndex - 1) << 2;
3522                         line3 = 0;
3523                         for(FX_DWORD w = 0; w < GBW; w++) {
3524                             if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3525                                 bVal = 0;
3526                             } else {
3527                                 CONTEXT = line3;
3528                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
3529                                 CONTEXT |= line2 << 5;
3530                                 CONTEXT |= GBREG->getPixel(w + GBAT[2], m_loopIndex + GBAT[3]) << 10;
3531                                 CONTEXT |= GBREG->getPixel(w + GBAT[4], m_loopIndex + GBAT[5]) << 11;
3532                                 CONTEXT |= line1 << 12;
3533                                 CONTEXT |= GBREG->getPixel(w + GBAT[6], m_loopIndex + GBAT[7]) << 15;
3534                                 bVal = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3535                             }
3536                             if(bVal) {
3537                                 GBREG->setPixel(w, m_loopIndex, bVal);
3538                             }
3539                             line1 = ((line1 << 1) | GBREG->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
3540                             line2 = ((line2 << 1) | GBREG->getPixel(w + 3, m_loopIndex - 1)) & 0x1f;
3541                             line3 = ((line3 << 1) | bVal) & 0x0f;
3542                         }
3543                     }
3544                     break;
3545                 case 1: {
3546                         line1 = GBREG->getPixel(2, m_loopIndex - 2);
3547                         line1 |= GBREG->getPixel(1, m_loopIndex - 2) << 1;
3548                         line1 |= GBREG->getPixel(0, m_loopIndex - 2) << 2;
3549                         line2 = GBREG->getPixel(2, m_loopIndex - 1);
3550                         line2 |= GBREG->getPixel(1, m_loopIndex - 1) << 1;
3551                         line2 |= GBREG->getPixel(0, m_loopIndex - 1) << 2;
3552                         line3 = 0;
3553                         for(FX_DWORD w = 0; w < GBW; w++) {
3554                             if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3555                                 bVal = 0;
3556                             } else {
3557                                 CONTEXT = line3;
3558                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 3;
3559                                 CONTEXT |= line2 << 4;
3560                                 CONTEXT |= line1 << 9;
3561                                 bVal = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3562                             }
3563                             if(bVal) {
3564                                 GBREG->setPixel(w, m_loopIndex, bVal);
3565                             }
3566                             line1 = ((line1 << 1) | GBREG->getPixel(w + 3, m_loopIndex - 2)) & 0x0f;
3567                             line2 = ((line2 << 1) | GBREG->getPixel(w + 3, m_loopIndex - 1)) & 0x1f;
3568                             line3 = ((line3 << 1) | bVal) & 0x07;
3569                         }
3570                     }
3571                     break;
3572                 case 2: {
3573                         line1 = GBREG->getPixel(1, m_loopIndex - 2);
3574                         line1 |= GBREG->getPixel(0, m_loopIndex - 2) << 1;
3575                         line2 = GBREG->getPixel(1, m_loopIndex - 1);
3576                         line2 |= GBREG->getPixel(0, m_loopIndex - 1) << 1;
3577                         line3 = 0;
3578                         for(FX_DWORD w = 0; w < GBW; w++) {
3579                             if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3580                                 bVal = 0;
3581                             } else {
3582                                 CONTEXT = line3;
3583                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 2;
3584                                 CONTEXT |= line2 << 3;
3585                                 CONTEXT |= line1 << 7;
3586                                 bVal = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3587                             }
3588                             if(bVal) {
3589                                 GBREG->setPixel(w, m_loopIndex, bVal);
3590                             }
3591                             line1 = ((line1 << 1) | GBREG->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
3592                             line2 = ((line2 << 1) | GBREG->getPixel(w + 2, m_loopIndex - 1)) & 0x0f;
3593                             line3 = ((line3 << 1) | bVal) & 0x03;
3594                         }
3595                     }
3596                     break;
3597                 case 3: {
3598                         line1 = GBREG->getPixel(1, m_loopIndex - 1);
3599                         line1 |= GBREG->getPixel(0, m_loopIndex - 1) << 1;
3600                         line2 = 0;
3601                         for(FX_DWORD w = 0; w < GBW; w++) {
3602                             if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3603                                 bVal = 0;
3604                             } else {
3605                                 CONTEXT = line2;
3606                                 CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
3607                                 CONTEXT |= line1 << 5;
3608                                 bVal = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3609                             }
3610                             if(bVal) {
3611                                 GBREG->setPixel(w, m_loopIndex, bVal);
3612                             }
3613                             line1 = ((line1 << 1) | GBREG->getPixel(w + 2, m_loopIndex - 1)) & 0x1f;
3614                             line2 = ((line2 << 1) | bVal) & 0x0f;
3615                         }
3616                     }
3617                     break;
3618             }
3619         }
3620         if(pPause && pPause->NeedToPauseNow()) {
3621             m_loopIndex ++;
3622             m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3623             return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3624         }
3625     }
3626     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3627     return FXCODEC_STATUS_DECODE_FINISH;
3628 }
Start_decode_Arith_V1(CJBig2_Image ** pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)3629 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_Arith_V1(CJBig2_Image** pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3630 {
3631     if(GBW == 0 || GBH == 0) {
3632         * pImage = NULL;
3633         m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3634         return FXCODEC_STATUS_DECODE_FINISH;
3635     }
3636     if(*pImage == NULL) {
3637         JBIG2_ALLOC((*pImage), CJBig2_Image(GBW, GBH));
3638     }
3639     if ((*pImage)->m_pData == NULL) {
3640         delete *pImage;
3641         *pImage = NULL;
3642         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
3643         m_ProssiveStatus = FXCODEC_STATUS_ERROR;
3644         return FXCODEC_STATUS_ERROR;
3645     }
3646     m_ProssiveStatus = FXCODEC_STATUS_DECODE_READY;
3647     m_pPause = pPause;
3648     m_pImage = pImage;
3649     m_DecodeType = 3;
3650     (*m_pImage)->fill(0);
3651     LTP = 0;
3652     m_loopIndex = 0;
3653     m_pArithDecoder = pArithDecoder;
3654     m_gbContext = gbContext;
3655     return decode_Arith_V1(pPause);
3656 }
decode_Arith_V1(IFX_Pause * pPause)3657 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_V1(IFX_Pause* pPause)
3658 {
3659     FX_BOOL SLTP, bVal;
3660     FX_DWORD CONTEXT = 0;
3661     CJBig2_Image *GBREG = (*m_pImage);
3662     for(; m_loopIndex < GBH; m_loopIndex++) {
3663         if(TPGDON) {
3664             switch(GBTEMPLATE) {
3665                 case 0:
3666                     CONTEXT = 0x9b25;
3667                     break;
3668                 case 1:
3669                     CONTEXT = 0x0795;
3670                     break;
3671                 case 2:
3672                     CONTEXT = 0x00e5;
3673                     break;
3674                 case 3:
3675                     CONTEXT = 0x0195;
3676                     break;
3677             }
3678             SLTP = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3679             LTP = LTP ^ SLTP;
3680         }
3681         if(LTP == 1) {
3682             for(FX_DWORD w = 0; w < GBW; w++) {
3683                 GBREG->setPixel(w, m_loopIndex, GBREG->getPixel(w, m_loopIndex - 1));
3684             }
3685         } else {
3686             for(FX_DWORD w = 0; w < GBW; w++) {
3687                 if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3688                     GBREG->setPixel(w, m_loopIndex, 0);
3689                 } else {
3690                     CONTEXT = 0;
3691                     switch(GBTEMPLATE) {
3692                         case 0:
3693                             CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex);
3694                             CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex) << 1;
3695                             CONTEXT |= GBREG->getPixel(w - 3, m_loopIndex) << 2;
3696                             CONTEXT |= GBREG->getPixel(w - 4, m_loopIndex) << 3;
3697                             CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
3698                             CONTEXT |= GBREG->getPixel(w + 2, m_loopIndex - 1) << 5;
3699                             CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 1) << 6;
3700                             CONTEXT |= GBREG->getPixel(w, m_loopIndex - 1) << 7;
3701                             CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 1) << 8;
3702                             CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex - 1) << 9;
3703                             CONTEXT |= GBREG->getPixel(w + GBAT[2], m_loopIndex + GBAT[3]) << 10;
3704                             CONTEXT |= GBREG->getPixel(w + GBAT[4], m_loopIndex + GBAT[5]) << 11;
3705                             CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 2) << 12;
3706                             CONTEXT |= GBREG->getPixel(w, m_loopIndex - 2) << 13;
3707                             CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 2) << 14;
3708                             CONTEXT |= GBREG->getPixel(w + GBAT[6], m_loopIndex + GBAT[7]) << 15;
3709                             break;
3710                         case 1:
3711                             CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex);
3712                             CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex) << 1;
3713                             CONTEXT |= GBREG->getPixel(w - 3, m_loopIndex) << 2;
3714                             CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 3;
3715                             CONTEXT |= GBREG->getPixel(w + 2, m_loopIndex - 1) << 4;
3716                             CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 1) << 5;
3717                             CONTEXT |= GBREG->getPixel(w, m_loopIndex - 1) << 6;
3718                             CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 1) << 7;
3719                             CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex - 1) << 8;
3720                             CONTEXT |= GBREG->getPixel(w + 2, m_loopIndex - 2) << 9;
3721                             CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 2) << 10;
3722                             CONTEXT |= GBREG->getPixel(w, m_loopIndex - 2) << 11;
3723                             CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 2) << 12;
3724                             break;
3725                         case 2:
3726                             CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex);
3727                             CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex) << 1;
3728                             CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 2;
3729                             CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 1) << 3;
3730                             CONTEXT |= GBREG->getPixel(w, m_loopIndex - 1) << 4;
3731                             CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 1) << 5;
3732                             CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex - 1) << 6;
3733                             CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 2) << 7;
3734                             CONTEXT |= GBREG->getPixel(w, m_loopIndex - 2) << 8;
3735                             CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 2) << 9;
3736                             break;
3737                         case 3:
3738                             CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex);
3739                             CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex) << 1;
3740                             CONTEXT |= GBREG->getPixel(w - 3, m_loopIndex) << 2;
3741                             CONTEXT |= GBREG->getPixel(w - 4, m_loopIndex) << 3;
3742                             CONTEXT |= GBREG->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
3743                             CONTEXT |= GBREG->getPixel(w + 1, m_loopIndex - 1) << 5;
3744                             CONTEXT |= GBREG->getPixel(w, m_loopIndex - 1) << 6;
3745                             CONTEXT |= GBREG->getPixel(w - 1, m_loopIndex - 1) << 7;
3746                             CONTEXT |= GBREG->getPixel(w - 2, m_loopIndex - 1) << 8;
3747                             CONTEXT |= GBREG->getPixel(w - 3, m_loopIndex - 1) << 9;
3748                             break;
3749                     }
3750                     bVal = m_pArithDecoder->DECODE(&m_gbContext[CONTEXT]);
3751                     GBREG->setPixel(w, m_loopIndex, bVal);
3752                 }
3753             }
3754         }
3755         if(pPause && pPause->NeedToPauseNow()) {
3756             m_loopIndex ++;
3757             m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3758             return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3759         }
3760     }
3761     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3762     return FXCODEC_STATUS_DECODE_FINISH;
3763 }
Start_decode_MMR(CJBig2_Image ** pImage,CJBig2_BitStream * pStream,IFX_Pause * pPause)3764 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_MMR(CJBig2_Image** pImage, CJBig2_BitStream *pStream, IFX_Pause* pPause)
3765 {
3766     int bitpos, i;
3767     JBIG2_ALLOC((* pImage), CJBig2_Image(GBW, GBH));
3768     if ((* pImage)->m_pData == NULL) {
3769         delete (* pImage);
3770         (* pImage) = NULL;
3771         m_pModule->JBig2_Error("Generic region decoding procedure: Create Image Failed with width = %d, height = %d\n", GBW, GBH);
3772         m_ProssiveStatus = FXCODEC_STATUS_ERROR;
3773         return m_ProssiveStatus;
3774     }
3775     bitpos = (int)pStream->getBitPos();
3776     _FaxG4Decode(m_pModule, pStream->getBuf(), pStream->getLength(), &bitpos, (* pImage)->m_pData, GBW, GBH, (* pImage)->m_nStride);
3777     pStream->setBitPos(bitpos);
3778     for(i = 0; (FX_DWORD)i < (* pImage)->m_nStride * GBH; i++) {
3779         (* pImage)->m_pData[i] = ~(* pImage)->m_pData[i];
3780     }
3781     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3782     return m_ProssiveStatus;
3783 }
decode_MMR()3784 FXCODEC_STATUS CJBig2_GRDProc::decode_MMR()
3785 {
3786     return m_ProssiveStatus;
3787 }
Continue_decode(IFX_Pause * pPause)3788 FXCODEC_STATUS CJBig2_GRDProc::Continue_decode(IFX_Pause* pPause)
3789 {
3790     if(m_ProssiveStatus != FXCODEC_STATUS_DECODE_TOBECONTINUE) {
3791         return m_ProssiveStatus;
3792     }
3793     switch (m_DecodeType) {
3794         case 1:
3795             return decode_Arith(pPause);
3796         case 2:
3797             return decode_Arith_V2(pPause);
3798         case 3:
3799             return decode_Arith_V1(pPause);
3800         case 4:
3801             return decode_MMR();
3802     }
3803     m_ProssiveStatus = FXCODEC_STATUS_ERROR;
3804     return m_ProssiveStatus;
3805 }
decode_Arith_Template0_opt3(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)3806 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3(CJBig2_Image *pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3807 {
3808     FX_BOOL SLTP, bVal;
3809     FX_DWORD CONTEXT;
3810     FX_DWORD line1, line2;
3811     FX_BYTE *pLine1, *pLine2, cVal;
3812     FX_INT32 nStride, nStride2, k;
3813     FX_INT32 nLineBytes, nBitsLeft, cc;
3814     if(m_pLine == NULL) {
3815         m_pLine = pImage->m_pData;
3816     }
3817     nStride = pImage->m_nStride;
3818     nStride2 = nStride << 1;
3819     nLineBytes = ((GBW + 7) >> 3) - 1;
3820     nBitsLeft = GBW - (nLineBytes << 3);
3821     FX_DWORD height = GBH & 0x7fffffff;
3822     for(; m_loopIndex < height; m_loopIndex++) {
3823         if(TPGDON) {
3824             SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
3825             LTP = LTP ^ SLTP;
3826         }
3827         if(LTP == 1) {
3828             pImage->copyLine(m_loopIndex, m_loopIndex - 1);
3829         } else {
3830             if(m_loopIndex > 1) {
3831                 pLine1 = m_pLine - nStride2;
3832                 pLine2 = m_pLine - nStride;
3833                 line1 = (*pLine1++) << 6;
3834                 line2 = *pLine2++;
3835                 CONTEXT = ((line1 & 0xf800) | (line2 & 0x07f0));
3836                 for(cc = 0; cc < nLineBytes; cc++) {
3837                     line1 = (line1 << 8) | ((*pLine1++) << 6);
3838                     line2 = (line2 << 8) | (*pLine2++);
3839                     cVal = 0;
3840                     for(k = 7; k >= 0; k--) {
3841                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3842                         cVal |= bVal << k;
3843                         CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
3844                                    | ((line1 >> k) & 0x0800)
3845                                    | ((line2 >> k) & 0x0010));
3846                     }
3847                     m_pLine[cc] = cVal;
3848                 }
3849                 line1 <<= 8;
3850                 line2 <<= 8;
3851                 cVal = 0;
3852                 for(k = 0; k < nBitsLeft; k++) {
3853                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3854                     cVal |= bVal << (7 - k);
3855                     CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
3856                                | ((line1 >> (7 - k)) & 0x0800)
3857                                | ((line2 >> (7 - k)) & 0x0010));
3858                 }
3859                 m_pLine[nLineBytes] = cVal;
3860             } else {
3861                 pLine2 = m_pLine - nStride;
3862                 line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
3863                 CONTEXT = (line2 & 0x07f0);
3864                 for(cc = 0; cc < nLineBytes; cc++) {
3865                     if(m_loopIndex & 1) {
3866                         line2 = (line2 << 8) | (*pLine2++);
3867                     }
3868                     cVal = 0;
3869                     for(k = 7; k >= 0; k--) {
3870                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3871                         cVal |= bVal << k;
3872                         CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
3873                                    | ((line2 >> k) & 0x0010));
3874                     }
3875                     m_pLine[cc] = cVal;
3876                 }
3877                 line2 <<= 8;
3878                 cVal = 0;
3879                 for(k = 0; k < nBitsLeft; k++) {
3880                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3881                     cVal |= bVal << (7 - k);
3882                     CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal
3883                                | ((line2 >> (7 - k)) & 0x0010));
3884                 }
3885                 m_pLine[nLineBytes] = cVal;
3886             }
3887         }
3888         m_pLine += nStride;
3889         if(pPause && pPause->NeedToPauseNow()) {
3890             m_loopIndex++;
3891             m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3892             return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3893         }
3894     }
3895     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3896     return FXCODEC_STATUS_DECODE_FINISH;
3897 }
decode_Arith_Template0_unopt(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)3898 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_unopt(CJBig2_Image * pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3899 {
3900     FX_BOOL SLTP, bVal;
3901     FX_DWORD CONTEXT;
3902     FX_DWORD line1, line2, line3;
3903     for(; m_loopIndex < GBH; m_loopIndex++) {
3904         if(TPGDON) {
3905             SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
3906             LTP = LTP ^ SLTP;
3907         }
3908         if(LTP == 1) {
3909             pImage->copyLine(m_loopIndex, m_loopIndex - 1);
3910         } else {
3911             line1 = pImage->getPixel(1, m_loopIndex - 2);
3912             line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
3913             line2 = pImage->getPixel(2, m_loopIndex - 1);
3914             line2 |= pImage->getPixel(1, m_loopIndex - 1) << 1;
3915             line2 |= pImage->getPixel(0, m_loopIndex - 1) << 2;
3916             line3 = 0;
3917             for(FX_DWORD w = 0; w < GBW; w++) {
3918                 if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
3919                     bVal = 0;
3920                 } else {
3921                     CONTEXT = line3;
3922                     CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
3923                     CONTEXT |= line2 << 5;
3924                     CONTEXT |= pImage->getPixel(w + GBAT[2], m_loopIndex + GBAT[3]) << 10;
3925                     CONTEXT |= pImage->getPixel(w + GBAT[4], m_loopIndex + GBAT[5]) << 11;
3926                     CONTEXT |= line1 << 12;
3927                     CONTEXT |= pImage->getPixel(w + GBAT[6], m_loopIndex + GBAT[7]) << 15;
3928                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3929                 }
3930                 if(bVal) {
3931                     pImage->setPixel(w, m_loopIndex, bVal);
3932                 }
3933                 line1 = ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
3934                 line2 = ((line2 << 1) | pImage->getPixel(w + 3, m_loopIndex - 1)) & 0x1f;
3935                 line3 = ((line3 << 1) | bVal) & 0x0f;
3936             }
3937         }
3938         if(pPause && pPause->NeedToPauseNow()) {
3939             m_loopIndex++;
3940             m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
3941             return FXCODEC_STATUS_DECODE_TOBECONTINUE;
3942         }
3943     }
3944     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
3945     return FXCODEC_STATUS_DECODE_FINISH;
3946 }
decode_Arith_Template1_opt3(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)3947 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3(CJBig2_Image *pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
3948 {
3949     FX_BOOL SLTP, bVal;
3950     FX_DWORD CONTEXT;
3951     FX_DWORD line1, line2;
3952     FX_BYTE *pLine1, *pLine2, cVal;
3953     FX_INT32 nStride, nStride2, k;
3954     FX_INT32 nLineBytes, nBitsLeft, cc;
3955     if (!m_pLine) {
3956         m_pLine = pImage->m_pData;
3957     }
3958     nStride = pImage->m_nStride;
3959     nStride2 = nStride << 1;
3960     nLineBytes = ((GBW + 7) >> 3) - 1;
3961     nBitsLeft = GBW - (nLineBytes << 3);
3962     for(; m_loopIndex < GBH; m_loopIndex++) {
3963         if(TPGDON) {
3964             SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
3965             LTP = LTP ^ SLTP;
3966         }
3967         if(LTP == 1) {
3968             pImage->copyLine(m_loopIndex, m_loopIndex - 1);
3969         } else {
3970             if(m_loopIndex > 1) {
3971                 pLine1 = m_pLine - nStride2;
3972                 pLine2 = m_pLine - nStride;
3973                 line1 = (*pLine1++) << 4;
3974                 line2 = *pLine2++;
3975                 CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
3976                 for(cc = 0; cc < nLineBytes; cc++) {
3977                     line1 = (line1 << 8) | ((*pLine1++) << 4);
3978                     line2 = (line2 << 8) | (*pLine2++);
3979                     cVal = 0;
3980                     for(k = 7; k >= 0; k--) {
3981                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3982                         cVal |= bVal << k;
3983                         CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
3984                                   | ((line1 >> k) & 0x0200)
3985                                   | ((line2 >> (k + 1)) & 0x0008);
3986                     }
3987                     m_pLine[cc] = cVal;
3988                 }
3989                 line1 <<= 8;
3990                 line2 <<= 8;
3991                 cVal = 0;
3992                 for(k = 0; k < nBitsLeft; k++) {
3993                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
3994                     cVal |= bVal << (7 - k);
3995                     CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
3996                               | ((line1 >> (7 - k)) & 0x0200)
3997                               | ((line2 >> (8 - k)) & 0x0008);
3998                 }
3999                 m_pLine[nLineBytes] = cVal;
4000             } else {
4001                 pLine2 = m_pLine - nStride;
4002                 line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
4003                 CONTEXT = (line2 >> 1) & 0x01f8;
4004                 for(cc = 0; cc < nLineBytes; cc++) {
4005                     if(m_loopIndex & 1) {
4006                         line2 = (line2 << 8) | (*pLine2++);
4007                     }
4008                     cVal = 0;
4009                     for(k = 7; k >= 0; k--) {
4010                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4011                         cVal |= bVal << k;
4012                         CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
4013                                   | ((line2 >> (k + 1)) & 0x0008);
4014                     }
4015                     m_pLine[cc] = cVal;
4016                 }
4017                 line2 <<= 8;
4018                 cVal = 0;
4019                 for(k = 0; k < nBitsLeft; k++) {
4020                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4021                     cVal |= bVal << (7 - k);
4022                     CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal
4023                               | ((line2 >> (8 - k)) & 0x0008);
4024                 }
4025                 m_pLine[nLineBytes] = cVal;
4026             }
4027         }
4028         m_pLine += nStride;
4029         if(pPause && pPause->NeedToPauseNow()) {
4030             m_loopIndex++;
4031             m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
4032             return FXCODEC_STATUS_DECODE_TOBECONTINUE;
4033         }
4034     }
4035     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
4036     return FXCODEC_STATUS_DECODE_FINISH;
4037 }
decode_Arith_Template1_unopt(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)4038 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_unopt(CJBig2_Image * pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
4039 {
4040     FX_BOOL SLTP, bVal;
4041     FX_DWORD CONTEXT;
4042     FX_DWORD line1, line2, line3;
4043     for(FX_DWORD h = 0; h < GBH; h++) {
4044         if(TPGDON) {
4045             SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
4046             LTP = LTP ^ SLTP;
4047         }
4048         if(LTP == 1) {
4049             pImage->copyLine(h, h - 1);
4050         } else {
4051             line1 = pImage->getPixel(2, h - 2);
4052             line1 |= pImage->getPixel(1, h - 2) << 1;
4053             line1 |= pImage->getPixel(0, h - 2) << 2;
4054             line2 = pImage->getPixel(2, h - 1);
4055             line2 |= pImage->getPixel(1, h - 1) << 1;
4056             line2 |= pImage->getPixel(0, h - 1) << 2;
4057             line3 = 0;
4058             for(FX_DWORD w = 0; w < GBW; w++) {
4059                 if(USESKIP && SKIP->getPixel(w, h)) {
4060                     bVal = 0;
4061                 } else {
4062                     CONTEXT = line3;
4063                     CONTEXT |= pImage->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
4064                     CONTEXT |= line2 << 4;
4065                     CONTEXT |= line1 << 9;
4066                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4067                 }
4068                 if(bVal) {
4069                     pImage->setPixel(w, h, bVal);
4070                 }
4071                 line1 = ((line1 << 1) | pImage->getPixel(w + 3, h - 2)) & 0x0f;
4072                 line2 = ((line2 << 1) | pImage->getPixel(w + 3, h - 1)) & 0x1f;
4073                 line3 = ((line3 << 1) | bVal) & 0x07;
4074             }
4075         }
4076         if(pPause && pPause->NeedToPauseNow()) {
4077             m_loopIndex++;
4078             m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
4079             return FXCODEC_STATUS_DECODE_TOBECONTINUE;
4080         }
4081     }
4082     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
4083     return FXCODEC_STATUS_DECODE_FINISH;
4084 }
decode_Arith_Template2_opt3(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)4085 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3(CJBig2_Image *pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
4086 {
4087     FX_BOOL SLTP, bVal;
4088     FX_DWORD CONTEXT;
4089     FX_DWORD line1, line2;
4090     FX_BYTE *pLine1, *pLine2, cVal;
4091     FX_INT32 nStride, nStride2, k;
4092     FX_INT32 nLineBytes, nBitsLeft, cc;
4093     if(!m_pLine) {
4094         m_pLine = pImage->m_pData;
4095     }
4096     nStride = pImage->m_nStride;
4097     nStride2 = nStride << 1;
4098     nLineBytes = ((GBW + 7) >> 3) - 1;
4099     nBitsLeft = GBW - (nLineBytes << 3);
4100     for(; m_loopIndex < GBH; m_loopIndex++) {
4101         if(TPGDON) {
4102             SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
4103             LTP = LTP ^ SLTP;
4104         }
4105         if(LTP == 1) {
4106             pImage->copyLine(m_loopIndex, m_loopIndex - 1);
4107         } else {
4108             if(m_loopIndex > 1) {
4109                 pLine1 = m_pLine - nStride2;
4110                 pLine2 = m_pLine - nStride;
4111                 line1 = (*pLine1++) << 1;
4112                 line2 = *pLine2++;
4113                 CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
4114                 for(cc = 0; cc < nLineBytes; cc++) {
4115                     line1 = (line1 << 8) | ((*pLine1++) << 1);
4116                     line2 = (line2 << 8) | (*pLine2++);
4117                     cVal = 0;
4118                     for(k = 7; k >= 0; k--) {
4119                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4120                         cVal |= bVal << k;
4121                         CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
4122                                   | ((line1 >> k) & 0x0080)
4123                                   | ((line2 >> (k + 3)) & 0x0004);
4124                     }
4125                     m_pLine[cc] = cVal;
4126                 }
4127                 line1 <<= 8;
4128                 line2 <<= 8;
4129                 cVal = 0;
4130                 for(k = 0; k < nBitsLeft; k++) {
4131                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4132                     cVal |= bVal << (7 - k);
4133                     CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
4134                               | ((line1 >> (7 - k)) & 0x0080)
4135                               | ((line2 >> (10 - k)) & 0x0004);
4136                 }
4137                 m_pLine[nLineBytes] = cVal;
4138             } else {
4139                 pLine2 = m_pLine - nStride;
4140                 line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
4141                 CONTEXT = (line2 >> 3) & 0x007c;
4142                 for(cc = 0; cc < nLineBytes; cc++) {
4143                     if(m_loopIndex & 1) {
4144                         line2 = (line2 << 8) | (*pLine2++);
4145                     }
4146                     cVal = 0;
4147                     for(k = 7; k >= 0; k--) {
4148                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4149                         cVal |= bVal << k;
4150                         CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
4151                                   | ((line2 >> (k + 3)) & 0x0004);
4152                     }
4153                     m_pLine[cc] = cVal;
4154                 }
4155                 line2 <<= 8;
4156                 cVal = 0;
4157                 for(k = 0; k < nBitsLeft; k++) {
4158                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4159                     cVal |= bVal << (7 - k);
4160                     CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal
4161                               | (((line2 >> (10 - k))) & 0x0004);
4162                 }
4163                 m_pLine[nLineBytes] = cVal;
4164             }
4165         }
4166         m_pLine += nStride;
4167         if(pPause && m_loopIndex % 50 == 0 && pPause->NeedToPauseNow()) {
4168             m_loopIndex++;
4169             m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
4170             return FXCODEC_STATUS_DECODE_TOBECONTINUE;
4171         }
4172     }
4173     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
4174     return FXCODEC_STATUS_DECODE_FINISH;
4175 }
decode_Arith_Template2_unopt(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)4176 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_unopt(CJBig2_Image * pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
4177 {
4178     FX_BOOL SLTP, bVal;
4179     FX_DWORD CONTEXT;
4180     FX_DWORD line1, line2, line3;
4181     for(; m_loopIndex < GBH; m_loopIndex++) {
4182         if(TPGDON) {
4183             SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
4184             LTP = LTP ^ SLTP;
4185         }
4186         if(LTP == 1) {
4187             pImage->copyLine(m_loopIndex, m_loopIndex - 1);
4188         } else {
4189             line1 = pImage->getPixel(1, m_loopIndex - 2);
4190             line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
4191             line2 = pImage->getPixel(1, m_loopIndex - 1);
4192             line2 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
4193             line3 = 0;
4194             for(FX_DWORD w = 0; w < GBW; w++) {
4195                 if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
4196                     bVal = 0;
4197                 } else {
4198                     CONTEXT = line3;
4199                     CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 2;
4200                     CONTEXT |= line2 << 3;
4201                     CONTEXT |= line1 << 7;
4202                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4203                 }
4204                 if(bVal) {
4205                     pImage->setPixel(w, m_loopIndex, bVal);
4206                 }
4207                 line1 = ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
4208                 line2 = ((line2 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x0f;
4209                 line3 = ((line3 << 1) | bVal) & 0x03;
4210             }
4211         }
4212         if(pPause && pPause->NeedToPauseNow()) {
4213             m_loopIndex++;
4214             m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
4215             return FXCODEC_STATUS_DECODE_TOBECONTINUE;
4216         }
4217     }
4218     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
4219     return FXCODEC_STATUS_DECODE_FINISH;
4220 }
decode_Arith_Template3_opt3(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)4221 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3(CJBig2_Image *pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
4222 {
4223     FX_BOOL SLTP, bVal;
4224     FX_DWORD CONTEXT;
4225     FX_DWORD line1;
4226     FX_BYTE *pLine1, cVal;
4227     FX_INT32 nStride, k;
4228     FX_INT32 nLineBytes, nBitsLeft, cc;
4229     if (!m_pLine) {
4230         m_pLine = pImage->m_pData;
4231     }
4232     nStride = pImage->m_nStride;
4233     nLineBytes = ((GBW + 7) >> 3) - 1;
4234     nBitsLeft = GBW - (nLineBytes << 3);
4235     for(; m_loopIndex < GBH; m_loopIndex++) {
4236         if(TPGDON) {
4237             SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
4238             LTP = LTP ^ SLTP;
4239         }
4240         if(LTP == 1) {
4241             pImage->copyLine(m_loopIndex, m_loopIndex - 1);
4242         } else {
4243             if(m_loopIndex > 0) {
4244                 pLine1 = m_pLine - nStride;
4245                 line1 = *pLine1++;
4246                 CONTEXT = (line1 >> 1) & 0x03f0;
4247                 for(cc = 0; cc < nLineBytes; cc++) {
4248                     line1 = (line1 << 8) | (*pLine1++);
4249                     cVal = 0;
4250                     for(k = 7; k >= 0; k--) {
4251                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4252                         cVal |= bVal << k;
4253                         CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
4254                                   | ((line1 >> (k + 1)) & 0x0010);
4255                     }
4256                     m_pLine[cc] = cVal;
4257                 }
4258                 line1 <<= 8;
4259                 cVal = 0;
4260                 for(k = 0; k < nBitsLeft; k++) {
4261                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4262                     cVal |= bVal << (7 - k);
4263                     CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal
4264                               | ((line1 >> (8 - k)) & 0x0010);
4265                 }
4266                 m_pLine[nLineBytes] = cVal;
4267             } else {
4268                 CONTEXT = 0;
4269                 for(cc = 0; cc < nLineBytes; cc++) {
4270                     cVal = 0;
4271                     for(k = 7; k >= 0; k--) {
4272                         bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4273                         cVal |= bVal << k;
4274                         CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
4275                     }
4276                     m_pLine[cc] = cVal;
4277                 }
4278                 cVal = 0;
4279                 for(k = 0; k < nBitsLeft; k++) {
4280                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4281                     cVal |= bVal << (7 - k);
4282                     CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
4283                 }
4284                 m_pLine[nLineBytes] = cVal;
4285             }
4286         }
4287         m_pLine += nStride;
4288         if(pPause && pPause->NeedToPauseNow()) {
4289             m_loopIndex++;
4290             m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
4291             return FXCODEC_STATUS_DECODE_TOBECONTINUE;
4292         }
4293     }
4294     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
4295     return FXCODEC_STATUS_DECODE_FINISH;
4296 }
decode_Arith_Template3_unopt(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)4297 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_unopt(CJBig2_Image * pImage, CJBig2_ArithDecoder *pArithDecoder, JBig2ArithCtx *gbContext, IFX_Pause* pPause)
4298 {
4299     FX_BOOL SLTP, bVal;
4300     FX_DWORD CONTEXT;
4301     FX_DWORD line1, line2;
4302     for(; m_loopIndex < GBH; m_loopIndex++) {
4303         if(TPGDON) {
4304             SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
4305             LTP = LTP ^ SLTP;
4306         }
4307         if(LTP == 1) {
4308             pImage->copyLine(m_loopIndex, m_loopIndex - 1);
4309         } else {
4310             line1 = pImage->getPixel(1, m_loopIndex - 1);
4311             line1 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
4312             line2 = 0;
4313             for(FX_DWORD w = 0; w < GBW; w++) {
4314                 if(USESKIP && SKIP->getPixel(w, m_loopIndex)) {
4315                     bVal = 0;
4316                 } else {
4317                     CONTEXT = line2;
4318                     CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
4319                     CONTEXT |= line1 << 5;
4320                     bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
4321                 }
4322                 if(bVal) {
4323                     pImage->setPixel(w, m_loopIndex, bVal);
4324                 }
4325                 line1 = ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x1f;
4326                 line2 = ((line2 << 1) | bVal) & 0x0f;
4327             }
4328         }
4329         if(pPause && pPause->NeedToPauseNow()) {
4330             m_loopIndex++;
4331             m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
4332             return FXCODEC_STATUS_DECODE_TOBECONTINUE;
4333         }
4334     }
4335     m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
4336     return FXCODEC_STATUS_DECODE_FINISH;
4337 }
4338