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