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