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