1 // Copyright 2015 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_GrdProc.h"
8
9 #include <memory>
10
11 #include "JBig2_ArithDecoder.h"
12 #include "JBig2_BitStream.h"
13 #include "JBig2_Image.h"
14 #include "core/include/fxcodec/fx_codec.h"
15
CJBig2_GRDProc()16 CJBig2_GRDProc::CJBig2_GRDProc()
17 : m_loopIndex(0),
18 m_pLine(nullptr),
19 m_pPause(nullptr),
20 m_DecodeType(0),
21 LTP(0) {
22 m_ReplaceRect.left = 0;
23 m_ReplaceRect.bottom = 0;
24 m_ReplaceRect.top = 0;
25 m_ReplaceRect.right = 0;
26 }
27
UseTemplate0Opt3() const28 bool CJBig2_GRDProc::UseTemplate0Opt3() const {
29 return (GBAT[0] == 3) && (GBAT[1] == -1) && (GBAT[2] == -3) &&
30 (GBAT[3] == -1) && (GBAT[4] == 2) && (GBAT[5] == -2) &&
31 (GBAT[6] == -2) && (GBAT[7] == -2);
32 }
33
UseTemplate1Opt3() const34 bool CJBig2_GRDProc::UseTemplate1Opt3() const {
35 return (GBAT[0] == 3) && (GBAT[1] == -1);
36 }
37
UseTemplate23Opt3() const38 bool CJBig2_GRDProc::UseTemplate23Opt3() const {
39 return (GBAT[0] == 2) && (GBAT[1] == -1);
40 }
41
decode_Arith(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)42 CJBig2_Image* CJBig2_GRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
43 JBig2ArithCtx* gbContext) {
44 if (GBW == 0 || GBH == 0)
45 return new CJBig2_Image(GBW, GBH);
46
47 if (GBTEMPLATE == 0) {
48 if (UseTemplate0Opt3())
49 return decode_Arith_Template0_opt3(pArithDecoder, gbContext);
50 return decode_Arith_Template0_unopt(pArithDecoder, gbContext);
51 } else if (GBTEMPLATE == 1) {
52 if (UseTemplate1Opt3())
53 return decode_Arith_Template1_opt3(pArithDecoder, gbContext);
54 return decode_Arith_Template1_unopt(pArithDecoder, gbContext);
55 } else if (GBTEMPLATE == 2) {
56 if (UseTemplate23Opt3())
57 return decode_Arith_Template2_opt3(pArithDecoder, gbContext);
58 return decode_Arith_Template2_unopt(pArithDecoder, gbContext);
59 } else {
60 if (UseTemplate23Opt3())
61 return decode_Arith_Template3_opt3(pArithDecoder, gbContext);
62 return decode_Arith_Template3_unopt(pArithDecoder, gbContext);
63 }
64 }
decode_Arith_Template0_opt3(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)65 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_opt3(
66 CJBig2_ArithDecoder* pArithDecoder,
67 JBig2ArithCtx* gbContext) {
68 FX_BOOL LTP, SLTP, bVal;
69 FX_DWORD CONTEXT;
70 FX_DWORD line1, line2;
71 uint8_t* pLine, *pLine1, *pLine2, cVal;
72 int32_t nStride, nStride2, k;
73 int32_t nLineBytes, nBitsLeft, cc;
74 LTP = 0;
75 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
76 if (!GBREG->m_pData)
77 return nullptr;
78
79 pLine = GBREG->m_pData;
80 nStride = GBREG->m_nStride;
81 nStride2 = nStride << 1;
82 nLineBytes = ((GBW + 7) >> 3) - 1;
83 nBitsLeft = GBW - (nLineBytes << 3);
84 FX_DWORD height = GBH & 0x7fffffff;
85 for (FX_DWORD h = 0; h < height; h++) {
86 if (TPGDON) {
87 SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
88 LTP = LTP ^ SLTP;
89 }
90 if (LTP == 1) {
91 GBREG->copyLine(h, h - 1);
92 } else {
93 if (h > 1) {
94 pLine1 = pLine - nStride2;
95 pLine2 = pLine - nStride;
96 line1 = (*pLine1++) << 6;
97 line2 = *pLine2++;
98 CONTEXT = ((line1 & 0xf800) | (line2 & 0x07f0));
99 for (cc = 0; cc < nLineBytes; cc++) {
100 line1 = (line1 << 8) | ((*pLine1++) << 6);
101 line2 = (line2 << 8) | (*pLine2++);
102 cVal = 0;
103 for (k = 7; k >= 0; k--) {
104 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
105 cVal |= bVal << k;
106 CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
107 ((line1 >> k) & 0x0800) | ((line2 >> k) & 0x0010));
108 }
109 pLine[cc] = cVal;
110 }
111 line1 <<= 8;
112 line2 <<= 8;
113 cVal = 0;
114 for (k = 0; k < nBitsLeft; k++) {
115 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
116 cVal |= bVal << (7 - k);
117 CONTEXT =
118 (((CONTEXT & 0x7bf7) << 1) | bVal |
119 ((line1 >> (7 - k)) & 0x0800) | ((line2 >> (7 - k)) & 0x0010));
120 }
121 pLine[nLineBytes] = cVal;
122 } else {
123 pLine2 = pLine - nStride;
124 line2 = (h & 1) ? (*pLine2++) : 0;
125 CONTEXT = (line2 & 0x07f0);
126 for (cc = 0; cc < nLineBytes; cc++) {
127 if (h & 1) {
128 line2 = (line2 << 8) | (*pLine2++);
129 }
130 cVal = 0;
131 for (k = 7; k >= 0; k--) {
132 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
133 cVal |= bVal << k;
134 CONTEXT =
135 (((CONTEXT & 0x7bf7) << 1) | bVal | ((line2 >> k) & 0x0010));
136 }
137 pLine[cc] = cVal;
138 }
139 line2 <<= 8;
140 cVal = 0;
141 for (k = 0; k < nBitsLeft; k++) {
142 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
143 cVal |= bVal << (7 - k);
144 CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
145 (((line2 >> (7 - k))) & 0x0010));
146 }
147 pLine[nLineBytes] = cVal;
148 }
149 }
150 pLine += nStride;
151 }
152 return GBREG.release();
153 }
154
decode_Arith_Template0_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)155 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template0_unopt(
156 CJBig2_ArithDecoder* pArithDecoder,
157 JBig2ArithCtx* gbContext) {
158 FX_BOOL LTP, SLTP, bVal;
159 FX_DWORD CONTEXT;
160 FX_DWORD line1, line2, line3;
161 LTP = 0;
162 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
163 GBREG->fill(0);
164 for (FX_DWORD h = 0; h < GBH; h++) {
165 if (TPGDON) {
166 SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
167 LTP = LTP ^ SLTP;
168 }
169 if (LTP == 1) {
170 GBREG->copyLine(h, h - 1);
171 } else {
172 line1 = GBREG->getPixel(1, h - 2);
173 line1 |= GBREG->getPixel(0, h - 2) << 1;
174 line2 = GBREG->getPixel(2, h - 1);
175 line2 |= GBREG->getPixel(1, h - 1) << 1;
176 line2 |= GBREG->getPixel(0, h - 1) << 2;
177 line3 = 0;
178 for (FX_DWORD w = 0; w < GBW; w++) {
179 if (USESKIP && SKIP->getPixel(w, h)) {
180 bVal = 0;
181 } else {
182 CONTEXT = line3;
183 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
184 CONTEXT |= line2 << 5;
185 CONTEXT |= GBREG->getPixel(w + GBAT[2], h + GBAT[3]) << 10;
186 CONTEXT |= GBREG->getPixel(w + GBAT[4], h + GBAT[5]) << 11;
187 CONTEXT |= line1 << 12;
188 CONTEXT |= GBREG->getPixel(w + GBAT[6], h + GBAT[7]) << 15;
189 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
190 }
191 if (bVal) {
192 GBREG->setPixel(w, h, bVal);
193 }
194 line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
195 line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
196 line3 = ((line3 << 1) | bVal) & 0x0f;
197 }
198 }
199 }
200 return GBREG.release();
201 }
202
decode_Arith_Template1_opt3(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)203 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_opt3(
204 CJBig2_ArithDecoder* pArithDecoder,
205 JBig2ArithCtx* gbContext) {
206 FX_BOOL LTP, SLTP, bVal;
207 FX_DWORD CONTEXT;
208 FX_DWORD line1, line2;
209 uint8_t* pLine, *pLine1, *pLine2, cVal;
210 int32_t nStride, nStride2, k;
211 int32_t nLineBytes, nBitsLeft, cc;
212 LTP = 0;
213 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
214 if (!GBREG->m_pData)
215 return nullptr;
216
217 pLine = GBREG->m_pData;
218 nStride = GBREG->m_nStride;
219 nStride2 = nStride << 1;
220 nLineBytes = ((GBW + 7) >> 3) - 1;
221 nBitsLeft = GBW - (nLineBytes << 3);
222 for (FX_DWORD h = 0; h < GBH; h++) {
223 if (TPGDON) {
224 SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
225 LTP = LTP ^ SLTP;
226 }
227 if (LTP == 1) {
228 GBREG->copyLine(h, h - 1);
229 } else {
230 if (h > 1) {
231 pLine1 = pLine - nStride2;
232 pLine2 = pLine - nStride;
233 line1 = (*pLine1++) << 4;
234 line2 = *pLine2++;
235 CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
236 for (cc = 0; cc < nLineBytes; cc++) {
237 line1 = (line1 << 8) | ((*pLine1++) << 4);
238 line2 = (line2 << 8) | (*pLine2++);
239 cVal = 0;
240 for (k = 7; k >= 0; k--) {
241 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
242 cVal |= bVal << k;
243 CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
244 ((line1 >> k) & 0x0200) | ((line2 >> (k + 1)) & 0x0008);
245 }
246 pLine[cc] = cVal;
247 }
248 line1 <<= 8;
249 line2 <<= 8;
250 cVal = 0;
251 for (k = 0; k < nBitsLeft; k++) {
252 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
253 cVal |= bVal << (7 - k);
254 CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
255 ((line1 >> (7 - k)) & 0x0200) |
256 ((line2 >> (8 - k)) & 0x0008);
257 }
258 pLine[nLineBytes] = cVal;
259 } else {
260 pLine2 = pLine - nStride;
261 line2 = (h & 1) ? (*pLine2++) : 0;
262 CONTEXT = (line2 >> 1) & 0x01f8;
263 for (cc = 0; cc < nLineBytes; cc++) {
264 if (h & 1) {
265 line2 = (line2 << 8) | (*pLine2++);
266 }
267 cVal = 0;
268 for (k = 7; k >= 0; k--) {
269 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
270 cVal |= bVal << k;
271 CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
272 ((line2 >> (k + 1)) & 0x0008);
273 }
274 pLine[cc] = cVal;
275 }
276 line2 <<= 8;
277 cVal = 0;
278 for (k = 0; k < nBitsLeft; k++) {
279 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
280 cVal |= bVal << (7 - k);
281 CONTEXT =
282 ((CONTEXT & 0x0efb) << 1) | bVal | ((line2 >> (8 - k)) & 0x0008);
283 }
284 pLine[nLineBytes] = cVal;
285 }
286 }
287 pLine += nStride;
288 }
289 return GBREG.release();
290 }
291
decode_Arith_Template1_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)292 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template1_unopt(
293 CJBig2_ArithDecoder* pArithDecoder,
294 JBig2ArithCtx* gbContext) {
295 FX_BOOL LTP, SLTP, bVal;
296 FX_DWORD CONTEXT;
297 FX_DWORD line1, line2, line3;
298 LTP = 0;
299 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
300 GBREG->fill(0);
301 for (FX_DWORD h = 0; h < GBH; h++) {
302 if (TPGDON) {
303 SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
304 LTP = LTP ^ SLTP;
305 }
306 if (LTP == 1) {
307 GBREG->copyLine(h, h - 1);
308 } else {
309 line1 = GBREG->getPixel(2, h - 2);
310 line1 |= GBREG->getPixel(1, h - 2) << 1;
311 line1 |= GBREG->getPixel(0, h - 2) << 2;
312 line2 = GBREG->getPixel(2, h - 1);
313 line2 |= GBREG->getPixel(1, h - 1) << 1;
314 line2 |= GBREG->getPixel(0, h - 1) << 2;
315 line3 = 0;
316 for (FX_DWORD w = 0; w < GBW; w++) {
317 if (USESKIP && SKIP->getPixel(w, h)) {
318 bVal = 0;
319 } else {
320 CONTEXT = line3;
321 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
322 CONTEXT |= line2 << 4;
323 CONTEXT |= line1 << 9;
324 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
325 }
326 if (bVal) {
327 GBREG->setPixel(w, h, bVal);
328 }
329 line1 = ((line1 << 1) | GBREG->getPixel(w + 3, h - 2)) & 0x0f;
330 line2 = ((line2 << 1) | GBREG->getPixel(w + 3, h - 1)) & 0x1f;
331 line3 = ((line3 << 1) | bVal) & 0x07;
332 }
333 }
334 }
335 return GBREG.release();
336 }
decode_Arith_Template2_opt3(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)337 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_opt3(
338 CJBig2_ArithDecoder* pArithDecoder,
339 JBig2ArithCtx* gbContext) {
340 FX_BOOL LTP, SLTP, bVal;
341 FX_DWORD CONTEXT;
342 FX_DWORD line1, line2;
343 uint8_t* pLine, *pLine1, *pLine2, cVal;
344 int32_t nStride, nStride2, k;
345 int32_t nLineBytes, nBitsLeft, cc;
346 LTP = 0;
347 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
348 if (!GBREG->m_pData)
349 return nullptr;
350
351 pLine = GBREG->m_pData;
352 nStride = GBREG->m_nStride;
353 nStride2 = nStride << 1;
354 nLineBytes = ((GBW + 7) >> 3) - 1;
355 nBitsLeft = GBW - (nLineBytes << 3);
356 for (FX_DWORD h = 0; h < GBH; h++) {
357 if (TPGDON) {
358 SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
359 LTP = LTP ^ SLTP;
360 }
361 if (LTP == 1) {
362 GBREG->copyLine(h, h - 1);
363 } else {
364 if (h > 1) {
365 pLine1 = pLine - nStride2;
366 pLine2 = pLine - nStride;
367 line1 = (*pLine1++) << 1;
368 line2 = *pLine2++;
369 CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
370 for (cc = 0; cc < nLineBytes; cc++) {
371 line1 = (line1 << 8) | ((*pLine1++) << 1);
372 line2 = (line2 << 8) | (*pLine2++);
373 cVal = 0;
374 for (k = 7; k >= 0; k--) {
375 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
376 cVal |= bVal << k;
377 CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
378 ((line1 >> k) & 0x0080) | ((line2 >> (k + 3)) & 0x0004);
379 }
380 pLine[cc] = cVal;
381 }
382 line1 <<= 8;
383 line2 <<= 8;
384 cVal = 0;
385 for (k = 0; k < nBitsLeft; k++) {
386 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
387 cVal |= bVal << (7 - k);
388 CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
389 ((line1 >> (7 - k)) & 0x0080) |
390 ((line2 >> (10 - k)) & 0x0004);
391 }
392 pLine[nLineBytes] = cVal;
393 } else {
394 pLine2 = pLine - nStride;
395 line2 = (h & 1) ? (*pLine2++) : 0;
396 CONTEXT = (line2 >> 3) & 0x007c;
397 for (cc = 0; cc < nLineBytes; cc++) {
398 if (h & 1) {
399 line2 = (line2 << 8) | (*pLine2++);
400 }
401 cVal = 0;
402 for (k = 7; k >= 0; k--) {
403 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
404 cVal |= bVal << k;
405 CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
406 ((line2 >> (k + 3)) & 0x0004);
407 }
408 pLine[cc] = cVal;
409 }
410 line2 <<= 8;
411 cVal = 0;
412 for (k = 0; k < nBitsLeft; k++) {
413 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
414 cVal |= bVal << (7 - k);
415 CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
416 (((line2 >> (10 - k))) & 0x0004);
417 }
418 pLine[nLineBytes] = cVal;
419 }
420 }
421 pLine += nStride;
422 }
423 return GBREG.release();
424 }
425
decode_Arith_Template2_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)426 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template2_unopt(
427 CJBig2_ArithDecoder* pArithDecoder,
428 JBig2ArithCtx* gbContext) {
429 FX_BOOL LTP, SLTP, bVal;
430 FX_DWORD CONTEXT;
431 FX_DWORD line1, line2, line3;
432 LTP = 0;
433 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
434 GBREG->fill(0);
435 for (FX_DWORD h = 0; h < GBH; h++) {
436 if (TPGDON) {
437 SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
438 LTP = LTP ^ SLTP;
439 }
440 if (LTP == 1) {
441 GBREG->copyLine(h, h - 1);
442 } else {
443 line1 = GBREG->getPixel(1, h - 2);
444 line1 |= GBREG->getPixel(0, h - 2) << 1;
445 line2 = GBREG->getPixel(1, h - 1);
446 line2 |= GBREG->getPixel(0, h - 1) << 1;
447 line3 = 0;
448 for (FX_DWORD w = 0; w < GBW; w++) {
449 if (USESKIP && SKIP->getPixel(w, h)) {
450 bVal = 0;
451 } else {
452 CONTEXT = line3;
453 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 2;
454 CONTEXT |= line2 << 3;
455 CONTEXT |= line1 << 7;
456 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
457 }
458 if (bVal) {
459 GBREG->setPixel(w, h, bVal);
460 }
461 line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 2)) & 0x07;
462 line2 = ((line2 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x0f;
463 line3 = ((line3 << 1) | bVal) & 0x03;
464 }
465 }
466 }
467 return GBREG.release();
468 }
469
decode_Arith_Template3_opt3(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)470 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_opt3(
471 CJBig2_ArithDecoder* pArithDecoder,
472 JBig2ArithCtx* gbContext) {
473 FX_BOOL LTP, SLTP, bVal;
474 FX_DWORD CONTEXT;
475 FX_DWORD line1;
476 uint8_t* pLine, *pLine1, cVal;
477 int32_t nStride, k;
478 int32_t nLineBytes, nBitsLeft, cc;
479 LTP = 0;
480 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
481 if (!GBREG->m_pData)
482 return nullptr;
483
484 pLine = GBREG->m_pData;
485 nStride = GBREG->m_nStride;
486 nLineBytes = ((GBW + 7) >> 3) - 1;
487 nBitsLeft = GBW - (nLineBytes << 3);
488 for (FX_DWORD h = 0; h < GBH; h++) {
489 if (TPGDON) {
490 SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
491 LTP = LTP ^ SLTP;
492 }
493 if (LTP == 1) {
494 GBREG->copyLine(h, h - 1);
495 } else {
496 if (h > 0) {
497 pLine1 = pLine - nStride;
498 line1 = *pLine1++;
499 CONTEXT = (line1 >> 1) & 0x03f0;
500 for (cc = 0; cc < nLineBytes; cc++) {
501 line1 = (line1 << 8) | (*pLine1++);
502 cVal = 0;
503 for (k = 7; k >= 0; k--) {
504 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
505 cVal |= bVal << k;
506 CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal |
507 ((line1 >> (k + 1)) & 0x0010);
508 }
509 pLine[cc] = cVal;
510 }
511 line1 <<= 8;
512 cVal = 0;
513 for (k = 0; k < nBitsLeft; k++) {
514 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
515 cVal |= bVal << (7 - k);
516 CONTEXT =
517 ((CONTEXT & 0x01f7) << 1) | bVal | ((line1 >> (8 - k)) & 0x0010);
518 }
519 pLine[nLineBytes] = cVal;
520 } else {
521 CONTEXT = 0;
522 for (cc = 0; cc < nLineBytes; cc++) {
523 cVal = 0;
524 for (k = 7; k >= 0; k--) {
525 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
526 cVal |= bVal << k;
527 CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
528 }
529 pLine[cc] = cVal;
530 }
531 cVal = 0;
532 for (k = 0; k < nBitsLeft; k++) {
533 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
534 cVal |= bVal << (7 - k);
535 CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
536 }
537 pLine[nLineBytes] = cVal;
538 }
539 }
540 pLine += nStride;
541 }
542 return GBREG.release();
543 }
544
decode_Arith_Template3_unopt(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext)545 CJBig2_Image* CJBig2_GRDProc::decode_Arith_Template3_unopt(
546 CJBig2_ArithDecoder* pArithDecoder,
547 JBig2ArithCtx* gbContext) {
548 FX_BOOL LTP, SLTP, bVal;
549 FX_DWORD CONTEXT;
550 FX_DWORD line1, line2;
551 LTP = 0;
552 std::unique_ptr<CJBig2_Image> GBREG(new CJBig2_Image(GBW, GBH));
553 GBREG->fill(0);
554 for (FX_DWORD h = 0; h < GBH; h++) {
555 if (TPGDON) {
556 SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
557 LTP = LTP ^ SLTP;
558 }
559 if (LTP == 1) {
560 GBREG->copyLine(h, h - 1);
561 } else {
562 line1 = GBREG->getPixel(1, h - 1);
563 line1 |= GBREG->getPixel(0, h - 1) << 1;
564 line2 = 0;
565 for (FX_DWORD w = 0; w < GBW; w++) {
566 if (USESKIP && SKIP->getPixel(w, h)) {
567 bVal = 0;
568 } else {
569 CONTEXT = line2;
570 CONTEXT |= GBREG->getPixel(w + GBAT[0], h + GBAT[1]) << 4;
571 CONTEXT |= line1 << 5;
572 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
573 }
574 if (bVal) {
575 GBREG->setPixel(w, h, bVal);
576 }
577 line1 = ((line1 << 1) | GBREG->getPixel(w + 2, h - 1)) & 0x1f;
578 line2 = ((line2 << 1) | bVal) & 0x0f;
579 }
580 }
581 }
582 return GBREG.release();
583 }
584
Start_decode_Arith(CJBig2_Image ** pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)585 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_Arith(
586 CJBig2_Image** pImage,
587 CJBig2_ArithDecoder* pArithDecoder,
588 JBig2ArithCtx* gbContext,
589 IFX_Pause* pPause) {
590 if (GBW == 0 || GBH == 0) {
591 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
592 return FXCODEC_STATUS_DECODE_FINISH;
593 }
594 m_ProssiveStatus = FXCODEC_STATUS_DECODE_READY;
595 m_pPause = pPause;
596 if (!*pImage)
597 *pImage = new CJBig2_Image(GBW, GBH);
598 if (!(*pImage)->m_pData) {
599 delete *pImage;
600 *pImage = nullptr;
601 m_ProssiveStatus = FXCODEC_STATUS_ERROR;
602 return FXCODEC_STATUS_ERROR;
603 }
604 m_DecodeType = 1;
605 m_pImage = pImage;
606 (*m_pImage)->fill(0);
607 m_pArithDecoder = pArithDecoder;
608 m_gbContext = gbContext;
609 LTP = 0;
610 m_pLine = nullptr;
611 m_loopIndex = 0;
612 return decode_Arith(pPause);
613 }
614
decode_Arith(IFX_Pause * pPause)615 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith(IFX_Pause* pPause) {
616 int iline = m_loopIndex;
617 CJBig2_Image* pImage = *m_pImage;
618 if (GBTEMPLATE == 0) {
619 if (UseTemplate0Opt3()) {
620 m_ProssiveStatus = decode_Arith_Template0_opt3(pImage, m_pArithDecoder,
621 m_gbContext, pPause);
622 } else {
623 m_ProssiveStatus = decode_Arith_Template0_unopt(pImage, m_pArithDecoder,
624 m_gbContext, pPause);
625 }
626 } else if (GBTEMPLATE == 1) {
627 if (UseTemplate1Opt3()) {
628 m_ProssiveStatus = decode_Arith_Template1_opt3(pImage, m_pArithDecoder,
629 m_gbContext, pPause);
630 } else {
631 m_ProssiveStatus = decode_Arith_Template1_unopt(pImage, m_pArithDecoder,
632 m_gbContext, pPause);
633 }
634 } else if (GBTEMPLATE == 2) {
635 if (UseTemplate23Opt3()) {
636 m_ProssiveStatus = decode_Arith_Template2_opt3(pImage, m_pArithDecoder,
637 m_gbContext, pPause);
638 } else {
639 m_ProssiveStatus = decode_Arith_Template2_unopt(pImage, m_pArithDecoder,
640 m_gbContext, pPause);
641 }
642 } else {
643 if (UseTemplate23Opt3()) {
644 m_ProssiveStatus = decode_Arith_Template3_opt3(pImage, m_pArithDecoder,
645 m_gbContext, pPause);
646 } else {
647 m_ProssiveStatus = decode_Arith_Template3_unopt(pImage, m_pArithDecoder,
648 m_gbContext, pPause);
649 }
650 }
651 m_ReplaceRect.left = 0;
652 m_ReplaceRect.right = pImage->m_nWidth;
653 m_ReplaceRect.top = iline;
654 m_ReplaceRect.bottom = m_loopIndex;
655 if (m_ProssiveStatus == FXCODEC_STATUS_DECODE_FINISH) {
656 m_loopIndex = 0;
657 }
658 return m_ProssiveStatus;
659 }
660
Start_decode_MMR(CJBig2_Image ** pImage,CJBig2_BitStream * pStream,IFX_Pause * pPause)661 FXCODEC_STATUS CJBig2_GRDProc::Start_decode_MMR(CJBig2_Image** pImage,
662 CJBig2_BitStream* pStream,
663 IFX_Pause* pPause) {
664 int bitpos, i;
665 *pImage = new CJBig2_Image(GBW, GBH);
666 if (!(*pImage)->m_pData) {
667 delete (*pImage);
668 (*pImage) = nullptr;
669 m_ProssiveStatus = FXCODEC_STATUS_ERROR;
670 return m_ProssiveStatus;
671 }
672 bitpos = (int)pStream->getBitPos();
673 FaxG4Decode(pStream->getBuf(), pStream->getLength(), &bitpos,
674 (*pImage)->m_pData, GBW, GBH, (*pImage)->m_nStride);
675 pStream->setBitPos(bitpos);
676 for (i = 0; (FX_DWORD)i < (*pImage)->m_nStride * GBH; i++) {
677 (*pImage)->m_pData[i] = ~(*pImage)->m_pData[i];
678 }
679 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
680 return m_ProssiveStatus;
681 }
682
Continue_decode(IFX_Pause * pPause)683 FXCODEC_STATUS CJBig2_GRDProc::Continue_decode(IFX_Pause* pPause) {
684 if (m_ProssiveStatus != FXCODEC_STATUS_DECODE_TOBECONTINUE)
685 return m_ProssiveStatus;
686
687 if (m_DecodeType != 1) {
688 m_ProssiveStatus = FXCODEC_STATUS_ERROR;
689 return m_ProssiveStatus;
690 }
691
692 return decode_Arith(pPause);
693 }
694
decode_Arith_Template0_opt3(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)695 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_opt3(
696 CJBig2_Image* pImage,
697 CJBig2_ArithDecoder* pArithDecoder,
698 JBig2ArithCtx* gbContext,
699 IFX_Pause* pPause) {
700 FX_BOOL SLTP, bVal;
701 FX_DWORD CONTEXT;
702 FX_DWORD line1, line2;
703 uint8_t* pLine1, *pLine2, cVal;
704 int32_t nStride, nStride2, k;
705 int32_t nLineBytes, nBitsLeft, cc;
706 if (!m_pLine) {
707 m_pLine = pImage->m_pData;
708 }
709 nStride = pImage->m_nStride;
710 nStride2 = nStride << 1;
711 nLineBytes = ((GBW + 7) >> 3) - 1;
712 nBitsLeft = GBW - (nLineBytes << 3);
713 FX_DWORD height = GBH & 0x7fffffff;
714 for (; m_loopIndex < height; m_loopIndex++) {
715 if (TPGDON) {
716 SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
717 LTP = LTP ^ SLTP;
718 }
719 if (LTP == 1) {
720 pImage->copyLine(m_loopIndex, m_loopIndex - 1);
721 } else {
722 if (m_loopIndex > 1) {
723 pLine1 = m_pLine - nStride2;
724 pLine2 = m_pLine - nStride;
725 line1 = (*pLine1++) << 6;
726 line2 = *pLine2++;
727 CONTEXT = ((line1 & 0xf800) | (line2 & 0x07f0));
728 for (cc = 0; cc < nLineBytes; cc++) {
729 line1 = (line1 << 8) | ((*pLine1++) << 6);
730 line2 = (line2 << 8) | (*pLine2++);
731 cVal = 0;
732 for (k = 7; k >= 0; k--) {
733 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
734 cVal |= bVal << k;
735 CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
736 ((line1 >> k) & 0x0800) | ((line2 >> k) & 0x0010));
737 }
738 m_pLine[cc] = cVal;
739 }
740 line1 <<= 8;
741 line2 <<= 8;
742 cVal = 0;
743 for (k = 0; k < nBitsLeft; k++) {
744 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
745 cVal |= bVal << (7 - k);
746 CONTEXT =
747 (((CONTEXT & 0x7bf7) << 1) | bVal |
748 ((line1 >> (7 - k)) & 0x0800) | ((line2 >> (7 - k)) & 0x0010));
749 }
750 m_pLine[nLineBytes] = cVal;
751 } else {
752 pLine2 = m_pLine - nStride;
753 line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
754 CONTEXT = (line2 & 0x07f0);
755 for (cc = 0; cc < nLineBytes; cc++) {
756 if (m_loopIndex & 1) {
757 line2 = (line2 << 8) | (*pLine2++);
758 }
759 cVal = 0;
760 for (k = 7; k >= 0; k--) {
761 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
762 cVal |= bVal << k;
763 CONTEXT =
764 (((CONTEXT & 0x7bf7) << 1) | bVal | ((line2 >> k) & 0x0010));
765 }
766 m_pLine[cc] = cVal;
767 }
768 line2 <<= 8;
769 cVal = 0;
770 for (k = 0; k < nBitsLeft; k++) {
771 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
772 cVal |= bVal << (7 - k);
773 CONTEXT = (((CONTEXT & 0x7bf7) << 1) | bVal |
774 ((line2 >> (7 - k)) & 0x0010));
775 }
776 m_pLine[nLineBytes] = cVal;
777 }
778 }
779 m_pLine += nStride;
780 if (pPause && pPause->NeedToPauseNow()) {
781 m_loopIndex++;
782 m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
783 return FXCODEC_STATUS_DECODE_TOBECONTINUE;
784 }
785 }
786 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
787 return FXCODEC_STATUS_DECODE_FINISH;
788 }
789
decode_Arith_Template0_unopt(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)790 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template0_unopt(
791 CJBig2_Image* pImage,
792 CJBig2_ArithDecoder* pArithDecoder,
793 JBig2ArithCtx* gbContext,
794 IFX_Pause* pPause) {
795 FX_BOOL SLTP, bVal;
796 FX_DWORD CONTEXT;
797 FX_DWORD line1, line2, line3;
798 for (; m_loopIndex < GBH; m_loopIndex++) {
799 if (TPGDON) {
800 SLTP = pArithDecoder->DECODE(&gbContext[0x9b25]);
801 LTP = LTP ^ SLTP;
802 }
803 if (LTP == 1) {
804 pImage->copyLine(m_loopIndex, m_loopIndex - 1);
805 } else {
806 line1 = pImage->getPixel(1, m_loopIndex - 2);
807 line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
808 line2 = pImage->getPixel(2, m_loopIndex - 1);
809 line2 |= pImage->getPixel(1, m_loopIndex - 1) << 1;
810 line2 |= pImage->getPixel(0, m_loopIndex - 1) << 2;
811 line3 = 0;
812 for (FX_DWORD w = 0; w < GBW; w++) {
813 if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
814 bVal = 0;
815 } else {
816 CONTEXT = line3;
817 CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
818 CONTEXT |= line2 << 5;
819 CONTEXT |= pImage->getPixel(w + GBAT[2], m_loopIndex + GBAT[3]) << 10;
820 CONTEXT |= pImage->getPixel(w + GBAT[4], m_loopIndex + GBAT[5]) << 11;
821 CONTEXT |= line1 << 12;
822 CONTEXT |= pImage->getPixel(w + GBAT[6], m_loopIndex + GBAT[7]) << 15;
823 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
824 }
825 if (bVal) {
826 pImage->setPixel(w, m_loopIndex, bVal);
827 }
828 line1 =
829 ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
830 line2 =
831 ((line2 << 1) | pImage->getPixel(w + 3, m_loopIndex - 1)) & 0x1f;
832 line3 = ((line3 << 1) | bVal) & 0x0f;
833 }
834 }
835 if (pPause && pPause->NeedToPauseNow()) {
836 m_loopIndex++;
837 m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
838 return FXCODEC_STATUS_DECODE_TOBECONTINUE;
839 }
840 }
841 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
842 return FXCODEC_STATUS_DECODE_FINISH;
843 }
844
decode_Arith_Template1_opt3(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)845 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_opt3(
846 CJBig2_Image* pImage,
847 CJBig2_ArithDecoder* pArithDecoder,
848 JBig2ArithCtx* gbContext,
849 IFX_Pause* pPause) {
850 FX_BOOL SLTP, bVal;
851 FX_DWORD CONTEXT;
852 FX_DWORD line1, line2;
853 uint8_t* pLine1, *pLine2, cVal;
854 int32_t nStride, nStride2, k;
855 int32_t nLineBytes, nBitsLeft, cc;
856 if (!m_pLine) {
857 m_pLine = pImage->m_pData;
858 }
859 nStride = pImage->m_nStride;
860 nStride2 = nStride << 1;
861 nLineBytes = ((GBW + 7) >> 3) - 1;
862 nBitsLeft = GBW - (nLineBytes << 3);
863 for (; m_loopIndex < GBH; m_loopIndex++) {
864 if (TPGDON) {
865 SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
866 LTP = LTP ^ SLTP;
867 }
868 if (LTP == 1) {
869 pImage->copyLine(m_loopIndex, m_loopIndex - 1);
870 } else {
871 if (m_loopIndex > 1) {
872 pLine1 = m_pLine - nStride2;
873 pLine2 = m_pLine - nStride;
874 line1 = (*pLine1++) << 4;
875 line2 = *pLine2++;
876 CONTEXT = (line1 & 0x1e00) | ((line2 >> 1) & 0x01f8);
877 for (cc = 0; cc < nLineBytes; cc++) {
878 line1 = (line1 << 8) | ((*pLine1++) << 4);
879 line2 = (line2 << 8) | (*pLine2++);
880 cVal = 0;
881 for (k = 7; k >= 0; k--) {
882 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
883 cVal |= bVal << k;
884 CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
885 ((line1 >> k) & 0x0200) | ((line2 >> (k + 1)) & 0x0008);
886 }
887 m_pLine[cc] = cVal;
888 }
889 line1 <<= 8;
890 line2 <<= 8;
891 cVal = 0;
892 for (k = 0; k < nBitsLeft; k++) {
893 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
894 cVal |= bVal << (7 - k);
895 CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
896 ((line1 >> (7 - k)) & 0x0200) |
897 ((line2 >> (8 - k)) & 0x0008);
898 }
899 m_pLine[nLineBytes] = cVal;
900 } else {
901 pLine2 = m_pLine - nStride;
902 line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
903 CONTEXT = (line2 >> 1) & 0x01f8;
904 for (cc = 0; cc < nLineBytes; cc++) {
905 if (m_loopIndex & 1) {
906 line2 = (line2 << 8) | (*pLine2++);
907 }
908 cVal = 0;
909 for (k = 7; k >= 0; k--) {
910 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
911 cVal |= bVal << k;
912 CONTEXT = ((CONTEXT & 0x0efb) << 1) | bVal |
913 ((line2 >> (k + 1)) & 0x0008);
914 }
915 m_pLine[cc] = cVal;
916 }
917 line2 <<= 8;
918 cVal = 0;
919 for (k = 0; k < nBitsLeft; k++) {
920 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
921 cVal |= bVal << (7 - k);
922 CONTEXT =
923 ((CONTEXT & 0x0efb) << 1) | bVal | ((line2 >> (8 - k)) & 0x0008);
924 }
925 m_pLine[nLineBytes] = cVal;
926 }
927 }
928 m_pLine += nStride;
929 if (pPause && pPause->NeedToPauseNow()) {
930 m_loopIndex++;
931 m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
932 return FXCODEC_STATUS_DECODE_TOBECONTINUE;
933 }
934 }
935 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
936 return FXCODEC_STATUS_DECODE_FINISH;
937 }
938
decode_Arith_Template1_unopt(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)939 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template1_unopt(
940 CJBig2_Image* pImage,
941 CJBig2_ArithDecoder* pArithDecoder,
942 JBig2ArithCtx* gbContext,
943 IFX_Pause* pPause) {
944 FX_BOOL SLTP, bVal;
945 FX_DWORD CONTEXT;
946 FX_DWORD line1, line2, line3;
947 for (FX_DWORD h = 0; h < GBH; h++) {
948 if (TPGDON) {
949 SLTP = pArithDecoder->DECODE(&gbContext[0x0795]);
950 LTP = LTP ^ SLTP;
951 }
952 if (LTP == 1) {
953 pImage->copyLine(h, h - 1);
954 } else {
955 line1 = pImage->getPixel(2, h - 2);
956 line1 |= pImage->getPixel(1, h - 2) << 1;
957 line1 |= pImage->getPixel(0, h - 2) << 2;
958 line2 = pImage->getPixel(2, h - 1);
959 line2 |= pImage->getPixel(1, h - 1) << 1;
960 line2 |= pImage->getPixel(0, h - 1) << 2;
961 line3 = 0;
962 for (FX_DWORD w = 0; w < GBW; w++) {
963 if (USESKIP && SKIP->getPixel(w, h)) {
964 bVal = 0;
965 } else {
966 CONTEXT = line3;
967 CONTEXT |= pImage->getPixel(w + GBAT[0], h + GBAT[1]) << 3;
968 CONTEXT |= line2 << 4;
969 CONTEXT |= line1 << 9;
970 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
971 }
972 if (bVal) {
973 pImage->setPixel(w, h, bVal);
974 }
975 line1 = ((line1 << 1) | pImage->getPixel(w + 3, h - 2)) & 0x0f;
976 line2 = ((line2 << 1) | pImage->getPixel(w + 3, h - 1)) & 0x1f;
977 line3 = ((line3 << 1) | bVal) & 0x07;
978 }
979 }
980 if (pPause && pPause->NeedToPauseNow()) {
981 m_loopIndex++;
982 m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
983 return FXCODEC_STATUS_DECODE_TOBECONTINUE;
984 }
985 }
986 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
987 return FXCODEC_STATUS_DECODE_FINISH;
988 }
989
decode_Arith_Template2_opt3(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)990 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_opt3(
991 CJBig2_Image* pImage,
992 CJBig2_ArithDecoder* pArithDecoder,
993 JBig2ArithCtx* gbContext,
994 IFX_Pause* pPause) {
995 FX_BOOL SLTP, bVal;
996 FX_DWORD CONTEXT;
997 FX_DWORD line1, line2;
998 uint8_t* pLine1, *pLine2, cVal;
999 int32_t nStride, nStride2, k;
1000 int32_t nLineBytes, nBitsLeft, cc;
1001 if (!m_pLine) {
1002 m_pLine = pImage->m_pData;
1003 }
1004 nStride = pImage->m_nStride;
1005 nStride2 = nStride << 1;
1006 nLineBytes = ((GBW + 7) >> 3) - 1;
1007 nBitsLeft = GBW - (nLineBytes << 3);
1008 for (; m_loopIndex < GBH; m_loopIndex++) {
1009 if (TPGDON) {
1010 SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
1011 LTP = LTP ^ SLTP;
1012 }
1013 if (LTP == 1) {
1014 pImage->copyLine(m_loopIndex, m_loopIndex - 1);
1015 } else {
1016 if (m_loopIndex > 1) {
1017 pLine1 = m_pLine - nStride2;
1018 pLine2 = m_pLine - nStride;
1019 line1 = (*pLine1++) << 1;
1020 line2 = *pLine2++;
1021 CONTEXT = (line1 & 0x0380) | ((line2 >> 3) & 0x007c);
1022 for (cc = 0; cc < nLineBytes; cc++) {
1023 line1 = (line1 << 8) | ((*pLine1++) << 1);
1024 line2 = (line2 << 8) | (*pLine2++);
1025 cVal = 0;
1026 for (k = 7; k >= 0; k--) {
1027 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1028 cVal |= bVal << k;
1029 CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
1030 ((line1 >> k) & 0x0080) | ((line2 >> (k + 3)) & 0x0004);
1031 }
1032 m_pLine[cc] = cVal;
1033 }
1034 line1 <<= 8;
1035 line2 <<= 8;
1036 cVal = 0;
1037 for (k = 0; k < nBitsLeft; k++) {
1038 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1039 cVal |= bVal << (7 - k);
1040 CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
1041 ((line1 >> (7 - k)) & 0x0080) |
1042 ((line2 >> (10 - k)) & 0x0004);
1043 }
1044 m_pLine[nLineBytes] = cVal;
1045 } else {
1046 pLine2 = m_pLine - nStride;
1047 line2 = (m_loopIndex & 1) ? (*pLine2++) : 0;
1048 CONTEXT = (line2 >> 3) & 0x007c;
1049 for (cc = 0; cc < nLineBytes; cc++) {
1050 if (m_loopIndex & 1) {
1051 line2 = (line2 << 8) | (*pLine2++);
1052 }
1053 cVal = 0;
1054 for (k = 7; k >= 0; k--) {
1055 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1056 cVal |= bVal << k;
1057 CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
1058 ((line2 >> (k + 3)) & 0x0004);
1059 }
1060 m_pLine[cc] = cVal;
1061 }
1062 line2 <<= 8;
1063 cVal = 0;
1064 for (k = 0; k < nBitsLeft; k++) {
1065 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1066 cVal |= bVal << (7 - k);
1067 CONTEXT = ((CONTEXT & 0x01bd) << 1) | bVal |
1068 (((line2 >> (10 - k))) & 0x0004);
1069 }
1070 m_pLine[nLineBytes] = cVal;
1071 }
1072 }
1073 m_pLine += nStride;
1074 if (pPause && m_loopIndex % 50 == 0 && pPause->NeedToPauseNow()) {
1075 m_loopIndex++;
1076 m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
1077 return FXCODEC_STATUS_DECODE_TOBECONTINUE;
1078 }
1079 }
1080 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
1081 return FXCODEC_STATUS_DECODE_FINISH;
1082 }
1083
decode_Arith_Template2_unopt(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)1084 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template2_unopt(
1085 CJBig2_Image* pImage,
1086 CJBig2_ArithDecoder* pArithDecoder,
1087 JBig2ArithCtx* gbContext,
1088 IFX_Pause* pPause) {
1089 FX_BOOL SLTP, bVal;
1090 FX_DWORD CONTEXT;
1091 FX_DWORD line1, line2, line3;
1092 for (; m_loopIndex < GBH; m_loopIndex++) {
1093 if (TPGDON) {
1094 SLTP = pArithDecoder->DECODE(&gbContext[0x00e5]);
1095 LTP = LTP ^ SLTP;
1096 }
1097 if (LTP == 1) {
1098 pImage->copyLine(m_loopIndex, m_loopIndex - 1);
1099 } else {
1100 line1 = pImage->getPixel(1, m_loopIndex - 2);
1101 line1 |= pImage->getPixel(0, m_loopIndex - 2) << 1;
1102 line2 = pImage->getPixel(1, m_loopIndex - 1);
1103 line2 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
1104 line3 = 0;
1105 for (FX_DWORD w = 0; w < GBW; w++) {
1106 if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
1107 bVal = 0;
1108 } else {
1109 CONTEXT = line3;
1110 CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 2;
1111 CONTEXT |= line2 << 3;
1112 CONTEXT |= line1 << 7;
1113 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1114 }
1115 if (bVal) {
1116 pImage->setPixel(w, m_loopIndex, bVal);
1117 }
1118 line1 =
1119 ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 2)) & 0x07;
1120 line2 =
1121 ((line2 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x0f;
1122 line3 = ((line3 << 1) | bVal) & 0x03;
1123 }
1124 }
1125 if (pPause && pPause->NeedToPauseNow()) {
1126 m_loopIndex++;
1127 m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
1128 return FXCODEC_STATUS_DECODE_TOBECONTINUE;
1129 }
1130 }
1131 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
1132 return FXCODEC_STATUS_DECODE_FINISH;
1133 }
1134
decode_Arith_Template3_opt3(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)1135 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_opt3(
1136 CJBig2_Image* pImage,
1137 CJBig2_ArithDecoder* pArithDecoder,
1138 JBig2ArithCtx* gbContext,
1139 IFX_Pause* pPause) {
1140 FX_BOOL SLTP, bVal;
1141 FX_DWORD CONTEXT;
1142 FX_DWORD line1;
1143 uint8_t* pLine1, cVal;
1144 int32_t nStride, k;
1145 int32_t nLineBytes, nBitsLeft, cc;
1146 if (!m_pLine) {
1147 m_pLine = pImage->m_pData;
1148 }
1149 nStride = pImage->m_nStride;
1150 nLineBytes = ((GBW + 7) >> 3) - 1;
1151 nBitsLeft = GBW - (nLineBytes << 3);
1152 for (; m_loopIndex < GBH; m_loopIndex++) {
1153 if (TPGDON) {
1154 SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
1155 LTP = LTP ^ SLTP;
1156 }
1157 if (LTP == 1) {
1158 pImage->copyLine(m_loopIndex, m_loopIndex - 1);
1159 } else {
1160 if (m_loopIndex > 0) {
1161 pLine1 = m_pLine - nStride;
1162 line1 = *pLine1++;
1163 CONTEXT = (line1 >> 1) & 0x03f0;
1164 for (cc = 0; cc < nLineBytes; cc++) {
1165 line1 = (line1 << 8) | (*pLine1++);
1166 cVal = 0;
1167 for (k = 7; k >= 0; k--) {
1168 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1169 cVal |= bVal << k;
1170 CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal |
1171 ((line1 >> (k + 1)) & 0x0010);
1172 }
1173 m_pLine[cc] = cVal;
1174 }
1175 line1 <<= 8;
1176 cVal = 0;
1177 for (k = 0; k < nBitsLeft; k++) {
1178 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1179 cVal |= bVal << (7 - k);
1180 CONTEXT =
1181 ((CONTEXT & 0x01f7) << 1) | bVal | ((line1 >> (8 - k)) & 0x0010);
1182 }
1183 m_pLine[nLineBytes] = cVal;
1184 } else {
1185 CONTEXT = 0;
1186 for (cc = 0; cc < nLineBytes; cc++) {
1187 cVal = 0;
1188 for (k = 7; k >= 0; k--) {
1189 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1190 cVal |= bVal << k;
1191 CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
1192 }
1193 m_pLine[cc] = cVal;
1194 }
1195 cVal = 0;
1196 for (k = 0; k < nBitsLeft; k++) {
1197 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1198 cVal |= bVal << (7 - k);
1199 CONTEXT = ((CONTEXT & 0x01f7) << 1) | bVal;
1200 }
1201 m_pLine[nLineBytes] = cVal;
1202 }
1203 }
1204 m_pLine += nStride;
1205 if (pPause && pPause->NeedToPauseNow()) {
1206 m_loopIndex++;
1207 m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
1208 return FXCODEC_STATUS_DECODE_TOBECONTINUE;
1209 }
1210 }
1211 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
1212 return FXCODEC_STATUS_DECODE_FINISH;
1213 }
1214
decode_Arith_Template3_unopt(CJBig2_Image * pImage,CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)1215 FXCODEC_STATUS CJBig2_GRDProc::decode_Arith_Template3_unopt(
1216 CJBig2_Image* pImage,
1217 CJBig2_ArithDecoder* pArithDecoder,
1218 JBig2ArithCtx* gbContext,
1219 IFX_Pause* pPause) {
1220 FX_BOOL SLTP, bVal;
1221 FX_DWORD CONTEXT;
1222 FX_DWORD line1, line2;
1223 for (; m_loopIndex < GBH; m_loopIndex++) {
1224 if (TPGDON) {
1225 SLTP = pArithDecoder->DECODE(&gbContext[0x0195]);
1226 LTP = LTP ^ SLTP;
1227 }
1228 if (LTP == 1) {
1229 pImage->copyLine(m_loopIndex, m_loopIndex - 1);
1230 } else {
1231 line1 = pImage->getPixel(1, m_loopIndex - 1);
1232 line1 |= pImage->getPixel(0, m_loopIndex - 1) << 1;
1233 line2 = 0;
1234 for (FX_DWORD w = 0; w < GBW; w++) {
1235 if (USESKIP && SKIP->getPixel(w, m_loopIndex)) {
1236 bVal = 0;
1237 } else {
1238 CONTEXT = line2;
1239 CONTEXT |= pImage->getPixel(w + GBAT[0], m_loopIndex + GBAT[1]) << 4;
1240 CONTEXT |= line1 << 5;
1241 bVal = pArithDecoder->DECODE(&gbContext[CONTEXT]);
1242 }
1243 if (bVal) {
1244 pImage->setPixel(w, m_loopIndex, bVal);
1245 }
1246 line1 =
1247 ((line1 << 1) | pImage->getPixel(w + 2, m_loopIndex - 1)) & 0x1f;
1248 line2 = ((line2 << 1) | bVal) & 0x0f;
1249 }
1250 }
1251 if (pPause && pPause->NeedToPauseNow()) {
1252 m_loopIndex++;
1253 m_ProssiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
1254 return FXCODEC_STATUS_DECODE_TOBECONTINUE;
1255 }
1256 }
1257 m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
1258 return FXCODEC_STATUS_DECODE_FINISH;
1259 }
1260