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