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