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_GrrdProc.h" 8 9 #include <memory> 10 11 #include "core/fxcodec/jbig2/JBig2_ArithDecoder.h" 12 #include "core/fxcodec/jbig2/JBig2_BitStream.h" 13 #include "core/fxcodec/jbig2/JBig2_Image.h" 14 15 CJBig2_Image* CJBig2_GRRDProc::decode(CJBig2_ArithDecoder* pArithDecoder, 16 JBig2ArithCtx* grContext) { 17 if (GRW == 0 || GRH == 0) 18 return new CJBig2_Image(GRW, GRH); 19 20 if (!GRTEMPLATE) { 21 if ((GRAT[0] == -1) && (GRAT[1] == -1) && (GRAT[2] == -1) && 22 (GRAT[3] == -1) && (GRREFERENCEDX == 0) && 23 (GRW == (uint32_t)GRREFERENCE->width())) { 24 return decode_Template0_opt(pArithDecoder, grContext); 25 } 26 return decode_Template0_unopt(pArithDecoder, grContext); 27 } 28 29 if ((GRREFERENCEDX == 0) && (GRW == (uint32_t)GRREFERENCE->width())) 30 return decode_Template1_opt(pArithDecoder, grContext); 31 return decode_Template1_unopt(pArithDecoder, grContext); 32 } 33 34 CJBig2_Image* CJBig2_GRRDProc::decode_Template0_unopt( 35 CJBig2_ArithDecoder* pArithDecoder, 36 JBig2ArithCtx* grContext) { 37 int LTP = 0; 38 std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(GRW, GRH)); 39 GRREG->fill(0); 40 for (uint32_t h = 0; h < GRH; h++) { 41 if (TPGRON) 42 LTP = LTP ^ pArithDecoder->DECODE(&grContext[0x0010]); 43 if (!LTP) { 44 uint32_t line1 = GRREG->getPixel(1, h - 1); 45 line1 |= GRREG->getPixel(0, h - 1) << 1; 46 uint32_t line2 = 0; 47 uint32_t line3 = 48 GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1); 49 line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1) 50 << 1; 51 uint32_t line4 = 52 GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY); 53 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1; 54 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) 55 << 2; 56 uint32_t line5 = 57 GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1); 58 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) 59 << 1; 60 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) 61 << 2; 62 for (uint32_t w = 0; w < GRW; w++) { 63 uint32_t CONTEXT = line5; 64 CONTEXT |= line4 << 3; 65 CONTEXT |= line3 << 6; 66 CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], 67 h - GRREFERENCEDY + GRAT[3]) 68 << 8; 69 CONTEXT |= line2 << 9; 70 CONTEXT |= line1 << 10; 71 CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12; 72 int bVal = pArithDecoder->DECODE(&grContext[CONTEXT]); 73 GRREG->setPixel(w, h, bVal); 74 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03; 75 line2 = ((line2 << 1) | bVal) & 0x01; 76 line3 = ((line3 << 1) | 77 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, 78 h - GRREFERENCEDY - 1)) & 79 0x03; 80 line4 = 81 ((line4 << 1) | 82 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 83 0x07; 84 line5 = ((line5 << 1) | 85 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, 86 h - GRREFERENCEDY + 1)) & 87 0x07; 88 } 89 } else { 90 uint32_t line1 = GRREG->getPixel(1, h - 1); 91 line1 |= GRREG->getPixel(0, h - 1) << 1; 92 uint32_t line2 = 0; 93 uint32_t line3 = 94 GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY - 1); 95 line3 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1) 96 << 1; 97 uint32_t line4 = 98 GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY); 99 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1; 100 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) 101 << 2; 102 uint32_t line5 = 103 GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1); 104 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) 105 << 1; 106 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY + 1) 107 << 2; 108 for (uint32_t w = 0; w < GRW; w++) { 109 int bVal = GRREFERENCE->getPixel(w, h); 110 if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1)) && 111 (bVal == GRREFERENCE->getPixel(w, h - 1)) && 112 (bVal == GRREFERENCE->getPixel(w + 1, h - 1)) && 113 (bVal == GRREFERENCE->getPixel(w - 1, h)) && 114 (bVal == GRREFERENCE->getPixel(w + 1, h)) && 115 (bVal == GRREFERENCE->getPixel(w - 1, h + 1)) && 116 (bVal == GRREFERENCE->getPixel(w, h + 1)) && 117 (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) { 118 uint32_t CONTEXT = line5; 119 CONTEXT |= line4 << 3; 120 CONTEXT |= line3 << 6; 121 CONTEXT |= GRREFERENCE->getPixel(w - GRREFERENCEDX + GRAT[2], 122 h - GRREFERENCEDY + GRAT[3]) 123 << 8; 124 CONTEXT |= line2 << 9; 125 CONTEXT |= line1 << 10; 126 CONTEXT |= GRREG->getPixel(w + GRAT[0], h + GRAT[1]) << 12; 127 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]); 128 } 129 GRREG->setPixel(w, h, bVal); 130 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x03; 131 line2 = ((line2 << 1) | bVal) & 0x01; 132 line3 = ((line3 << 1) | 133 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, 134 h - GRREFERENCEDY - 1)) & 135 0x03; 136 line4 = 137 ((line4 << 1) | 138 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 139 0x07; 140 line5 = ((line5 << 1) | 141 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, 142 h - GRREFERENCEDY + 1)) & 143 0x07; 144 } 145 } 146 } 147 return GRREG.release(); 148 } 149 150 CJBig2_Image* CJBig2_GRRDProc::decode_Template0_opt( 151 CJBig2_ArithDecoder* pArithDecoder, 152 JBig2ArithCtx* grContext) { 153 if (!GRREFERENCE->m_pData) 154 return nullptr; 155 156 int32_t iGRW = static_cast<int32_t>(GRW); 157 int32_t iGRH = static_cast<int32_t>(GRH); 158 std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(iGRW, iGRH)); 159 if (!GRREG->m_pData) 160 return nullptr; 161 162 int LTP = 0; 163 uint8_t* pLine = GRREG->m_pData; 164 uint8_t* pLineR = GRREFERENCE->m_pData; 165 intptr_t nStride = GRREG->stride(); 166 intptr_t nStrideR = GRREFERENCE->stride(); 167 int32_t GRWR = GRREFERENCE->width(); 168 int32_t GRHR = GRREFERENCE->height(); 169 if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) 170 GRREFERENCEDY = 0; 171 intptr_t nOffset = -GRREFERENCEDY * nStrideR; 172 for (int32_t h = 0; h < iGRH; h++) { 173 if (TPGRON) 174 LTP = LTP ^ pArithDecoder->DECODE(&grContext[0x0010]); 175 uint32_t line1 = (h > 0) ? pLine[-nStride] << 4 : 0; 176 int32_t reference_h = h - GRREFERENCEDY; 177 bool line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1); 178 bool line2_r_ok = (reference_h > -1 && reference_h < GRHR); 179 bool line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1); 180 uint32_t line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0; 181 uint32_t line2_r = line2_r_ok ? pLineR[nOffset] : 0; 182 uint32_t line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0; 183 if (!LTP) { 184 uint32_t CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0) | 185 ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007); 186 for (int32_t w = 0; w < iGRW; w += 8) { 187 int32_t nBits = iGRW - w > 8 ? 8 : iGRW - w; 188 if (h > 0) { 189 line1 = (line1 << 8) | 190 (w + 8 < iGRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0); 191 } 192 if (h > GRHR + GRREFERENCEDY + 1) { 193 line1_r = 0; 194 line2_r = 0; 195 line3_r = 0; 196 } else { 197 if (line1_r_ok) { 198 line1_r = 199 (line1_r << 8) | 200 (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0); 201 } 202 if (line2_r_ok) { 203 line2_r = (line2_r << 8) | 204 (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0); 205 } 206 if (line3_r_ok) { 207 line3_r = 208 (line3_r << 8) | 209 (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0); 210 } else { 211 line3_r = 0; 212 } 213 } 214 uint8_t cVal = 0; 215 for (int32_t k = 0; k < nBits; k++) { 216 int bVal = pArithDecoder->DECODE(&grContext[CONTEXT]); 217 cVal |= bVal << (7 - k); 218 CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) | 219 ((line1 >> (7 - k)) & 0x0400) | 220 ((line1_r >> (7 - k)) & 0x0040) | 221 ((line2_r >> (10 - k)) & 0x0008) | 222 ((line3_r >> (13 - k)) & 0x0001); 223 } 224 pLine[w >> 3] = cVal; 225 } 226 } else { 227 uint32_t CONTEXT = (line1 & 0x1c00) | (line1_r & 0x01c0) | 228 ((line2_r >> 3) & 0x0038) | ((line3_r >> 6) & 0x0007); 229 for (int32_t w = 0; w < iGRW; w += 8) { 230 int32_t nBits = iGRW - w > 8 ? 8 : iGRW - w; 231 if (h > 0) { 232 line1 = (line1 << 8) | 233 (w + 8 < iGRW ? pLine[-nStride + (w >> 3) + 1] << 4 : 0); 234 } 235 if (line1_r_ok) { 236 line1_r = 237 (line1_r << 8) | 238 (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0); 239 } 240 if (line2_r_ok) { 241 line2_r = (line2_r << 8) | 242 (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0); 243 } 244 if (line3_r_ok) { 245 line3_r = 246 (line3_r << 8) | 247 (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0); 248 } else { 249 line3_r = 0; 250 } 251 uint8_t cVal = 0; 252 for (int32_t k = 0; k < nBits; k++) { 253 int bVal = GRREFERENCE->getPixel(w + k, h); 254 if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1)) && 255 (bVal == GRREFERENCE->getPixel(w + k, h - 1)) && 256 (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1)) && 257 (bVal == GRREFERENCE->getPixel(w + k - 1, h)) && 258 (bVal == GRREFERENCE->getPixel(w + k + 1, h)) && 259 (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1)) && 260 (bVal == GRREFERENCE->getPixel(w + k, h + 1)) && 261 (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) { 262 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]); 263 } 264 cVal |= bVal << (7 - k); 265 CONTEXT = ((CONTEXT & 0x0cdb) << 1) | (bVal << 9) | 266 ((line1 >> (7 - k)) & 0x0400) | 267 ((line1_r >> (7 - k)) & 0x0040) | 268 ((line2_r >> (10 - k)) & 0x0008) | 269 ((line3_r >> (13 - k)) & 0x0001); 270 } 271 pLine[w >> 3] = cVal; 272 } 273 } 274 pLine += nStride; 275 if (h < GRHR + GRREFERENCEDY) { 276 pLineR += nStrideR; 277 } 278 } 279 return GRREG.release(); 280 } 281 282 CJBig2_Image* CJBig2_GRRDProc::decode_Template1_unopt( 283 CJBig2_ArithDecoder* pArithDecoder, 284 JBig2ArithCtx* grContext) { 285 int LTP = 0; 286 std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(GRW, GRH)); 287 GRREG->fill(0); 288 for (uint32_t h = 0; h < GRH; h++) { 289 if (TPGRON) 290 LTP = LTP ^ pArithDecoder->DECODE(&grContext[0x0008]); 291 if (!LTP) { 292 uint32_t line1 = GRREG->getPixel(1, h - 1); 293 line1 |= GRREG->getPixel(0, h - 1) << 1; 294 line1 |= GRREG->getPixel(-1, h - 1) << 2; 295 uint32_t line2 = 0; 296 uint32_t line3 = 297 GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1); 298 uint32_t line4 = 299 GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY); 300 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1; 301 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) 302 << 2; 303 uint32_t line5 = 304 GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1); 305 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) 306 << 1; 307 for (uint32_t w = 0; w < GRW; w++) { 308 uint32_t CONTEXT = line5; 309 CONTEXT |= line4 << 2; 310 CONTEXT |= line3 << 5; 311 CONTEXT |= line2 << 6; 312 CONTEXT |= line1 << 7; 313 int bVal = pArithDecoder->DECODE(&grContext[CONTEXT]); 314 GRREG->setPixel(w, h, bVal); 315 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07; 316 line2 = ((line2 << 1) | bVal) & 0x01; 317 line3 = ((line3 << 1) | 318 GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, 319 h - GRREFERENCEDY - 1)) & 320 0x01; 321 line4 = 322 ((line4 << 1) | 323 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 324 0x07; 325 line5 = ((line5 << 1) | 326 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, 327 h - GRREFERENCEDY + 1)) & 328 0x03; 329 } 330 } else { 331 uint32_t line1 = GRREG->getPixel(1, h - 1); 332 line1 |= GRREG->getPixel(0, h - 1) << 1; 333 line1 |= GRREG->getPixel(-1, h - 1) << 2; 334 uint32_t line2 = 0; 335 uint32_t line3 = 336 GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY - 1); 337 uint32_t line4 = 338 GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY); 339 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY) << 1; 340 line4 |= GRREFERENCE->getPixel(-GRREFERENCEDX - 1, h - GRREFERENCEDY) 341 << 2; 342 uint32_t line5 = 343 GRREFERENCE->getPixel(-GRREFERENCEDX + 1, h - GRREFERENCEDY + 1); 344 line5 |= GRREFERENCE->getPixel(-GRREFERENCEDX, h - GRREFERENCEDY + 1) 345 << 1; 346 for (uint32_t w = 0; w < GRW; w++) { 347 int bVal = GRREFERENCE->getPixel(w, h); 348 if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w - 1, h - 1)) && 349 (bVal == GRREFERENCE->getPixel(w, h - 1)) && 350 (bVal == GRREFERENCE->getPixel(w + 1, h - 1)) && 351 (bVal == GRREFERENCE->getPixel(w - 1, h)) && 352 (bVal == GRREFERENCE->getPixel(w + 1, h)) && 353 (bVal == GRREFERENCE->getPixel(w - 1, h + 1)) && 354 (bVal == GRREFERENCE->getPixel(w, h + 1)) && 355 (bVal == GRREFERENCE->getPixel(w + 1, h + 1)))) { 356 uint32_t CONTEXT = line5; 357 CONTEXT |= line4 << 2; 358 CONTEXT |= line3 << 5; 359 CONTEXT |= line2 << 6; 360 CONTEXT |= line1 << 7; 361 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]); 362 } 363 GRREG->setPixel(w, h, bVal); 364 line1 = ((line1 << 1) | GRREG->getPixel(w + 2, h - 1)) & 0x07; 365 line2 = ((line2 << 1) | bVal) & 0x01; 366 line3 = ((line3 << 1) | 367 GRREFERENCE->getPixel(w - GRREFERENCEDX + 1, 368 h - GRREFERENCEDY - 1)) & 369 0x01; 370 line4 = 371 ((line4 << 1) | 372 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, h - GRREFERENCEDY)) & 373 0x07; 374 line5 = ((line5 << 1) | 375 GRREFERENCE->getPixel(w - GRREFERENCEDX + 2, 376 h - GRREFERENCEDY + 1)) & 377 0x03; 378 } 379 } 380 } 381 return GRREG.release(); 382 } 383 384 CJBig2_Image* CJBig2_GRRDProc::decode_Template1_opt( 385 CJBig2_ArithDecoder* pArithDecoder, 386 JBig2ArithCtx* grContext) { 387 if (!GRREFERENCE->m_pData) 388 return nullptr; 389 390 int32_t iGRW = static_cast<int32_t>(GRW); 391 int32_t iGRH = static_cast<int32_t>(GRH); 392 std::unique_ptr<CJBig2_Image> GRREG(new CJBig2_Image(iGRW, iGRH)); 393 if (!GRREG->m_pData) 394 return nullptr; 395 396 int LTP = 0; 397 uint8_t* pLine = GRREG->m_pData; 398 uint8_t* pLineR = GRREFERENCE->m_pData; 399 intptr_t nStride = GRREG->stride(); 400 intptr_t nStrideR = GRREFERENCE->stride(); 401 int32_t GRWR = GRREFERENCE->width(); 402 int32_t GRHR = GRREFERENCE->height(); 403 if (GRREFERENCEDY < -GRHR + 1 || GRREFERENCEDY > GRHR - 1) { 404 GRREFERENCEDY = 0; 405 } 406 intptr_t nOffset = -GRREFERENCEDY * nStrideR; 407 for (int32_t h = 0; h < iGRH; h++) { 408 if (TPGRON) 409 LTP = LTP ^ pArithDecoder->DECODE(&grContext[0x0008]); 410 uint32_t line1 = (h > 0) ? pLine[-nStride] << 1 : 0; 411 int32_t reference_h = h - GRREFERENCEDY; 412 bool line1_r_ok = (reference_h > 0 && reference_h < GRHR + 1); 413 bool line2_r_ok = (reference_h > -1 && reference_h < GRHR); 414 bool line3_r_ok = (reference_h > -2 && reference_h < GRHR - 1); 415 uint32_t line1_r = line1_r_ok ? pLineR[nOffset - nStrideR] : 0; 416 uint32_t line2_r = line2_r_ok ? pLineR[nOffset] : 0; 417 uint32_t line3_r = line3_r_ok ? pLineR[nOffset + nStrideR] : 0; 418 if (!LTP) { 419 uint32_t CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020) | 420 ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003); 421 for (int32_t w = 0; w < iGRW; w += 8) { 422 int32_t nBits = iGRW - w > 8 ? 8 : iGRW - w; 423 if (h > 0) 424 line1 = (line1 << 8) | 425 (w + 8 < iGRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0); 426 if (line1_r_ok) 427 line1_r = 428 (line1_r << 8) | 429 (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0); 430 if (line2_r_ok) 431 line2_r = (line2_r << 8) | 432 (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0); 433 if (line3_r_ok) { 434 line3_r = 435 (line3_r << 8) | 436 (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0); 437 } else { 438 line3_r = 0; 439 } 440 uint8_t cVal = 0; 441 for (int32_t k = 0; k < nBits; k++) { 442 int bVal = pArithDecoder->DECODE(&grContext[CONTEXT]); 443 cVal |= bVal << (7 - k); 444 CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) | 445 ((line1 >> (7 - k)) & 0x0080) | 446 ((line1_r >> (9 - k)) & 0x0020) | 447 ((line2_r >> (11 - k)) & 0x0004) | 448 ((line3_r >> (13 - k)) & 0x0001); 449 } 450 pLine[w >> 3] = cVal; 451 } 452 } else { 453 uint32_t CONTEXT = (line1 & 0x0380) | ((line1_r >> 2) & 0x0020) | 454 ((line2_r >> 4) & 0x001c) | ((line3_r >> 6) & 0x0003); 455 for (int32_t w = 0; w < iGRW; w += 8) { 456 int32_t nBits = iGRW - w > 8 ? 8 : iGRW - w; 457 if (h > 0) 458 line1 = (line1 << 8) | 459 (w + 8 < iGRW ? pLine[-nStride + (w >> 3) + 1] << 1 : 0); 460 if (line1_r_ok) 461 line1_r = 462 (line1_r << 8) | 463 (w + 8 < GRWR ? pLineR[nOffset - nStrideR + (w >> 3) + 1] : 0); 464 if (line2_r_ok) 465 line2_r = (line2_r << 8) | 466 (w + 8 < GRWR ? pLineR[nOffset + (w >> 3) + 1] : 0); 467 if (line3_r_ok) { 468 line3_r = 469 (line3_r << 8) | 470 (w + 8 < GRWR ? pLineR[nOffset + nStrideR + (w >> 3) + 1] : 0); 471 } else { 472 line3_r = 0; 473 } 474 uint8_t cVal = 0; 475 for (int32_t k = 0; k < nBits; k++) { 476 int bVal = GRREFERENCE->getPixel(w + k, h); 477 if (!(TPGRON && (bVal == GRREFERENCE->getPixel(w + k - 1, h - 1)) && 478 (bVal == GRREFERENCE->getPixel(w + k, h - 1)) && 479 (bVal == GRREFERENCE->getPixel(w + k + 1, h - 1)) && 480 (bVal == GRREFERENCE->getPixel(w + k - 1, h)) && 481 (bVal == GRREFERENCE->getPixel(w + k + 1, h)) && 482 (bVal == GRREFERENCE->getPixel(w + k - 1, h + 1)) && 483 (bVal == GRREFERENCE->getPixel(w + k, h + 1)) && 484 (bVal == GRREFERENCE->getPixel(w + k + 1, h + 1)))) { 485 bVal = pArithDecoder->DECODE(&grContext[CONTEXT]); 486 } 487 cVal |= bVal << (7 - k); 488 CONTEXT = ((CONTEXT & 0x018d) << 1) | (bVal << 6) | 489 ((line1 >> (7 - k)) & 0x0080) | 490 ((line1_r >> (9 - k)) & 0x0020) | 491 ((line2_r >> (11 - k)) & 0x0004) | 492 ((line3_r >> (13 - k)) & 0x0001); 493 } 494 pLine[w >> 3] = cVal; 495 } 496 } 497 pLine += nStride; 498 if (h < GRHR + GRREFERENCEDY) { 499 pLineR += nStrideR; 500 } 501 } 502 return GRREG.release(); 503 } 504