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 19CJBig2_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 30CJBig2_GRDProc::~CJBig2_GRDProc() {} 31 32bool 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 38bool CJBig2_GRDProc::UseTemplate1Opt3() const { 39 return (GBAT[0] == 3) && (GBAT[1] == -1); 40} 41 42bool CJBig2_GRDProc::UseTemplate23Opt3() const { 43 return (GBAT[0] == 2) && (GBAT[1] == -1); 44} 45 46std::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 73std::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 171std::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 222std::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 319std::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 368std::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 465std::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 512std::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 597std::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 640FXCODEC_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 668FXCODEC_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 715FXCODEC_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 736FXCODEC_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 749FXCODEC_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 852FXCODEC_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 910FXCODEC_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 1011FXCODEC_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 1065FXCODEC_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 1166FXCODEC_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 1220FXCODEC_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 1307FXCODEC_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