1// Copyright 2014 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 <limits.h> 8#include "../../../include/fxcrt/fx_basic.h" 9#include "../../../include/fxcrt/fx_coordinates.h" 10#include "../../../src/fxcrt/fx_safe_types.h" 11#include "JBig2_Image.h" 12 13CJBig2_Image::CJBig2_Image(FX_INT32 w, FX_INT32 h) 14{ 15 m_nWidth = w; 16 m_nHeight = h; 17 if (m_nWidth <= 0 || m_nHeight <= 0 || m_nWidth > INT_MAX - 31) { 18 m_pData = NULL; 19 m_bNeedFree = FALSE; 20 return; 21 } 22 m_nStride = ((w + 31) >> 5) << 2; 23 if (m_nStride * m_nHeight > 0 && 104857600 / (int)m_nStride > m_nHeight) { 24 m_pData = (FX_BYTE *)m_pModule->JBig2_Malloc2(m_nStride, m_nHeight); 25 } else { 26 m_pData = NULL; 27 } 28 m_bNeedFree = TRUE; 29} 30CJBig2_Image::CJBig2_Image(FX_INT32 w, FX_INT32 h, FX_INT32 stride, FX_BYTE*pBuf) 31{ 32 m_nWidth = w; 33 m_nHeight = h; 34 m_nStride = stride; 35 m_pData = pBuf; 36 m_bNeedFree = FALSE; 37} 38CJBig2_Image::CJBig2_Image(CJBig2_Image &im) 39{ 40 m_pModule = im.m_pModule; 41 m_nWidth = im.m_nWidth; 42 m_nHeight = im.m_nHeight; 43 m_nStride = im.m_nStride; 44 if (im.m_pData) { 45 m_pData = (FX_BYTE*)m_pModule->JBig2_Malloc2(m_nStride, m_nHeight); 46 JBIG2_memcpy(m_pData, im.m_pData, m_nStride * m_nHeight); 47 } else { 48 m_pData = NULL; 49 } 50 m_bNeedFree = TRUE; 51} 52CJBig2_Image::~CJBig2_Image() 53{ 54 if(m_bNeedFree && m_pData) { 55 m_pModule->JBig2_Free(m_pData); 56 } 57} 58FX_BOOL CJBig2_Image::getPixel(FX_INT32 x, FX_INT32 y) 59{ 60 if (!m_pData) { 61 return 0; 62 } 63 FX_INT32 m, n; 64 if(x < 0 || x >= m_nWidth) { 65 return 0; 66 } 67 if(y < 0 || y >= m_nHeight) { 68 return 0; 69 } 70 m = y * m_nStride + (x >> 3); 71 n = x & 7; 72 return ((m_pData[m] >> (7 - n)) & 1); 73} 74 75FX_INT32 CJBig2_Image::setPixel(FX_INT32 x, FX_INT32 y, FX_BOOL v) 76{ 77 if (!m_pData) { 78 return 0; 79 } 80 FX_INT32 m, n; 81 if(x < 0 || x >= m_nWidth) { 82 return 0; 83 } 84 if(y < 0 || y >= m_nHeight) { 85 return 0; 86 } 87 m = y * m_nStride + (x >> 3); 88 n = x & 7; 89 if(v) { 90 m_pData[m] |= 1 << (7 - n); 91 } else { 92 m_pData[m] &= ~(1 << (7 - n)); 93 } 94 return 1; 95} 96void CJBig2_Image::copyLine(FX_INT32 hTo, FX_INT32 hFrom) 97{ 98 if (!m_pData) { 99 return; 100 } 101 if(hFrom < 0 || hFrom >= m_nHeight) { 102 JBIG2_memset(m_pData + hTo * m_nStride, 0, m_nStride); 103 } else { 104 JBIG2_memcpy(m_pData + hTo * m_nStride, m_pData + hFrom * m_nStride, m_nStride); 105 } 106} 107void CJBig2_Image::fill(FX_BOOL v) 108{ 109 if (!m_pData) { 110 return; 111 } 112 JBIG2_memset(m_pData, v ? 0xff : 0, m_nStride * m_nHeight); 113} 114FX_BOOL CJBig2_Image::composeTo(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op) 115{ 116 if (!m_pData) { 117 return FALSE; 118 } 119 return composeTo_opt2(pDst, x, y, op); 120} 121FX_BOOL CJBig2_Image::composeTo(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op, const FX_RECT* pSrcRect) 122{ 123 if (!m_pData) { 124 return FALSE; 125 } 126 if (NULL == pSrcRect || *pSrcRect == FX_RECT(0, 0, m_nWidth, m_nHeight)) { 127 return composeTo_opt2(pDst, x, y, op); 128 } 129 return composeTo_opt2(pDst, x, y, op, pSrcRect); 130} 131FX_BOOL CJBig2_Image::composeTo_unopt(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op) 132{ 133 FX_INT32 w, h, dx, dy; 134 FX_INT32 i, j; 135 w = m_nWidth; 136 h = m_nHeight; 137 dx = dy = 0; 138 if(x < 0) { 139 dx += -x; 140 w -= -x; 141 x = 0; 142 } 143 if(y < 0) { 144 dy += -y; 145 h -= -y; 146 y = 0; 147 } 148 if(x + w > pDst->m_nWidth) { 149 w = pDst->m_nWidth - x; 150 } 151 if(y + h > pDst->m_nHeight) { 152 h = pDst->m_nHeight - y; 153 } 154 switch(op) { 155 case JBIG2_COMPOSE_OR: 156 for(j = 0; j < h; j++) { 157 for(i = 0; i < w; i++) { 158 pDst->setPixel(x + i, y + j, 159 (getPixel(i + dx, j + dy) | pDst->getPixel(x + i, y + j)) & 1); 160 } 161 } 162 break; 163 case JBIG2_COMPOSE_AND: 164 for(j = 0; j < h; j++) { 165 for(i = 0; i < w; i++) { 166 pDst->setPixel(x + i, y + j, 167 (getPixel(i + dx, j + dy) & pDst->getPixel(x + i, y + j)) & 1); 168 } 169 } 170 break; 171 case JBIG2_COMPOSE_XOR: 172 for(j = 0; j < h; j++) { 173 for(i = 0; i < w; i++) { 174 pDst->setPixel(x + i, y + j, 175 (getPixel(i + dx, j + dy) ^ pDst->getPixel(x + i, y + j)) & 1); 176 } 177 } 178 break; 179 case JBIG2_COMPOSE_XNOR: 180 for(j = 0; j < h; j++) { 181 for(i = 0; i < w; i++) { 182 pDst->setPixel(x + i, y + j, 183 (~(getPixel(i + dx, j + dy) ^ pDst->getPixel(x + i, y + j))) & 1); 184 } 185 } 186 break; 187 case JBIG2_COMPOSE_REPLACE: 188 for(j = 0; j < h; j++) { 189 for(i = 0; i < w; i++) { 190 pDst->setPixel(x + i, y + j, getPixel(i + dx, j + dy)); 191 } 192 } 193 break; 194 } 195 return TRUE; 196} 197 198FX_BOOL CJBig2_Image::composeTo_opt(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op) 199{ 200 FX_INT32 x0, x1, y0, y1, xx, yy; 201 FX_BYTE *pLineSrc, *pLineDst, *srcPtr, *destPtr; 202 FX_DWORD src0, src1, src, dest, s1, s2, m1, m2, m3; 203 FX_BOOL oneByte; 204 if (!m_pData) { 205 return FALSE; 206 } 207 if (y < 0) { 208 y0 = -y; 209 } else { 210 y0 = 0; 211 } 212 if (y + m_nHeight > pDst->m_nHeight) { 213 y1 = pDst->m_nHeight - y; 214 } else { 215 y1 = m_nHeight; 216 } 217 if (y0 >= y1) { 218 return FALSE; 219 } 220 if (x >= 0) { 221 x0 = x & ~7; 222 } else { 223 x0 = 0; 224 } 225 x1 = x + m_nWidth; 226 if (x1 > pDst->m_nWidth) { 227 x1 = pDst->m_nWidth; 228 } 229 if (x0 >= x1) { 230 return FALSE; 231 } 232 s1 = x & 7; 233 s2 = 8 - s1; 234 m1 = 0xff >> (x1 & 7); 235 m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7)); 236 m3 = (0xff >> s1) & m2; 237 oneByte = x0 == ((x1 - 1) & ~7); 238 pLineDst = pDst->m_pData + y * pDst->m_nStride; 239 pLineSrc = m_pData + y0 * m_nStride; 240 if(oneByte) { 241 if(x >= 0) { 242 switch(op) { 243 case JBIG2_COMPOSE_OR: { 244 for (yy = y0; yy < y1; ++yy) { 245 destPtr = pLineDst + (x >> 3); 246 srcPtr = pLineSrc; 247 dest = *destPtr; 248 dest |= (*srcPtr >> s1) & m2; 249 *destPtr = (FX_BYTE)dest; 250 pLineDst += pDst->m_nStride; 251 pLineSrc += m_nStride; 252 } 253 } 254 break; 255 case JBIG2_COMPOSE_AND: { 256 for (yy = y0; yy < y1; ++yy) { 257 destPtr = pLineDst + (x >> 3); 258 srcPtr = pLineSrc; 259 dest = *destPtr; 260 dest &= ((0xff00 | *srcPtr) >> s1) | m1; 261 *destPtr = (FX_BYTE)dest; 262 pLineDst += pDst->m_nStride; 263 pLineSrc += m_nStride; 264 } 265 } 266 break; 267 case JBIG2_COMPOSE_XOR: { 268 for (yy = y0; yy < y1; ++yy) { 269 destPtr = pLineDst + (x >> 3); 270 srcPtr = pLineSrc; 271 dest = *destPtr; 272 dest ^= (*srcPtr >> s1) & m2; 273 *destPtr = (FX_BYTE)dest; 274 pLineDst += pDst->m_nStride; 275 pLineSrc += m_nStride; 276 } 277 } 278 break; 279 case JBIG2_COMPOSE_XNOR: { 280 for (yy = y0; yy < y1; ++yy) { 281 destPtr = pLineDst + (x >> 3); 282 srcPtr = pLineSrc; 283 dest = *destPtr; 284 dest ^= ((*srcPtr ^ 0xff) >> s1) & m2; 285 *destPtr = (FX_BYTE)dest; 286 pLineDst += pDst->m_nStride; 287 pLineSrc += m_nStride; 288 } 289 } 290 break; 291 case JBIG2_COMPOSE_REPLACE: { 292 for (yy = y0; yy < y1; ++yy) { 293 destPtr = pLineDst + (x >> 3); 294 srcPtr = pLineSrc; 295 dest = *destPtr; 296 dest = (dest & ~m3) | ((*srcPtr >> s1) & m3); 297 *destPtr = (FX_BYTE)dest; 298 pLineDst += pDst->m_nStride; 299 pLineSrc += m_nStride; 300 } 301 } 302 break; 303 } 304 } else { 305 switch(op) { 306 case JBIG2_COMPOSE_OR: { 307 for(yy = y0; yy < y1; ++yy) { 308 destPtr = pLineDst; 309 srcPtr = pLineSrc + (-x >> 3); 310 dest = *destPtr; 311 dest |= *srcPtr & m2; 312 *destPtr = (FX_BYTE)dest; 313 pLineDst += pDst->m_nStride; 314 pLineSrc += m_nStride; 315 } 316 } 317 break; 318 case JBIG2_COMPOSE_AND: { 319 for(yy = y0; yy < y1; ++yy) { 320 destPtr = pLineDst; 321 srcPtr = pLineSrc + (-x >> 3); 322 dest = *destPtr; 323 dest &= *srcPtr | m1; 324 *destPtr = (FX_BYTE)dest; 325 pLineDst += pDst->m_nStride; 326 pLineSrc += m_nStride; 327 } 328 } 329 break; 330 case JBIG2_COMPOSE_XOR: { 331 for(yy = y0; yy < y1; ++yy) { 332 destPtr = pLineDst; 333 srcPtr = pLineSrc + (-x >> 3); 334 dest = *destPtr; 335 dest ^= *srcPtr & m2; 336 *destPtr = (FX_BYTE)dest; 337 pLineDst += pDst->m_nStride; 338 pLineSrc += m_nStride; 339 } 340 } 341 break; 342 case JBIG2_COMPOSE_XNOR: { 343 for(yy = y0; yy < y1; ++yy) { 344 destPtr = pLineDst; 345 srcPtr = pLineSrc + (-x >> 3); 346 dest = *destPtr; 347 dest ^= (*srcPtr ^ 0xff) & m2; 348 *destPtr = (FX_BYTE)dest; 349 pLineDst += pDst->m_nStride; 350 pLineSrc += m_nStride; 351 } 352 } 353 break; 354 case JBIG2_COMPOSE_REPLACE: { 355 for(yy = y0; yy < y1; ++yy) { 356 destPtr = pLineDst; 357 srcPtr = pLineSrc + (-x >> 3); 358 dest = *destPtr; 359 dest = (*srcPtr & m2) | (dest & m1); 360 *destPtr = (FX_BYTE)dest; 361 pLineDst += pDst->m_nStride; 362 pLineSrc += m_nStride; 363 } 364 } 365 break; 366 } 367 } 368 } else { 369 if(x >= 0) { 370 switch(op) { 371 case JBIG2_COMPOSE_OR: { 372 for(yy = y0; yy < y1; ++yy) { 373 destPtr = pLineDst + (x >> 3); 374 srcPtr = pLineSrc; 375 src1 = *srcPtr++; 376 dest = *destPtr; 377 dest |= src1 >> s1; 378 *destPtr++ = (FX_BYTE)dest; 379 xx = x0 + 8; 380 for (; xx < x1 - 8; xx += 8) { 381 dest = *destPtr; 382 src0 = src1; 383 src1 = *srcPtr++; 384 src = (((src0 << 8) | src1) >> s1) & 0xff; 385 dest |= src; 386 *destPtr++ = (FX_BYTE)dest; 387 } 388 dest = *destPtr; 389 src0 = src1; 390 if(srcPtr - pLineSrc < m_nStride) { 391 src1 = *srcPtr++; 392 } else { 393 src1 = 0; 394 } 395 src = (((src0 << 8) | src1) >> s1) & 0xff; 396 dest |= src & m2; 397 *destPtr = (FX_BYTE)dest; 398 pLineDst += pDst->m_nStride; 399 pLineSrc += m_nStride; 400 } 401 } 402 break; 403 case JBIG2_COMPOSE_AND: { 404 for(yy = y0; yy < y1; ++yy) { 405 destPtr = pLineDst + (x >> 3); 406 srcPtr = pLineSrc; 407 src1 = *srcPtr++; 408 dest = *destPtr; 409 dest &= (0xff00 | src1) >> s1; 410 *destPtr++ = (FX_BYTE)dest; 411 xx = x0 + 8; 412 for (; xx < x1 - 8; xx += 8) { 413 dest = *destPtr; 414 src0 = src1; 415 src1 = *srcPtr++; 416 src = (((src0 << 8) | src1) >> s1) & 0xff; 417 dest &= src; 418 *destPtr++ = (FX_BYTE)dest; 419 } 420 dest = *destPtr; 421 src0 = src1; 422 if(srcPtr - pLineSrc < m_nStride) { 423 src1 = *srcPtr++; 424 } else { 425 src1 = 0; 426 } 427 src = (((src0 << 8) | src1) >> s1) & 0xff; 428 dest &= src | m1; 429 *destPtr = (FX_BYTE)dest; 430 pLineDst += pDst->m_nStride; 431 pLineSrc += m_nStride; 432 } 433 } 434 break; 435 case JBIG2_COMPOSE_XOR: { 436 for(yy = y0; yy < y1; ++yy) { 437 destPtr = pLineDst + (x >> 3); 438 srcPtr = pLineSrc; 439 src1 = *srcPtr++; 440 dest = *destPtr; 441 dest ^= src1 >> s1; 442 *destPtr++ = (FX_BYTE)dest; 443 xx = x0 + 8; 444 for (; xx < x1 - 8; xx += 8) { 445 dest = *destPtr; 446 src0 = src1; 447 src1 = *srcPtr++; 448 src = (((src0 << 8) | src1) >> s1) & 0xff; 449 dest ^= src; 450 *destPtr++ = (FX_BYTE)dest; 451 } 452 dest = *destPtr; 453 src0 = src1; 454 if(srcPtr - pLineSrc < m_nStride) { 455 src1 = *srcPtr++; 456 } else { 457 src1 = 0; 458 } 459 src = (((src0 << 8) | src1) >> s1) & 0xff; 460 dest ^= src & m2; 461 *destPtr = (FX_BYTE)dest; 462 pLineDst += pDst->m_nStride; 463 pLineSrc += m_nStride; 464 } 465 } 466 break; 467 case JBIG2_COMPOSE_XNOR: { 468 for(yy = y0; yy < y1; ++yy) { 469 destPtr = pLineDst + (x >> 3); 470 srcPtr = pLineSrc; 471 src1 = *srcPtr++; 472 dest = *destPtr; 473 dest ^= (src1 ^ 0xff) >> s1; 474 *destPtr++ = (FX_BYTE)dest; 475 xx = x0 + 8; 476 for (; xx < x1 - 8; xx += 8) { 477 dest = *destPtr; 478 src0 = src1; 479 src1 = *srcPtr++; 480 src = (((src0 << 8) | src1) >> s1) & 0xff; 481 dest ^= src ^ 0xff; 482 *destPtr++ = (FX_BYTE)dest; 483 } 484 dest = *destPtr; 485 src0 = src1; 486 if(srcPtr - pLineSrc < m_nStride) { 487 src1 = *srcPtr++; 488 } else { 489 src1 = 0; 490 } 491 src = (((src0 << 8) | src1) >> s1) & 0xff; 492 dest ^= (src ^ 0xff) & m2; 493 *destPtr = (FX_BYTE)dest; 494 pLineDst += pDst->m_nStride; 495 pLineSrc += m_nStride; 496 } 497 } 498 break; 499 case JBIG2_COMPOSE_REPLACE: { 500 for(yy = y0; yy < y1; ++yy) { 501 destPtr = pLineDst + (x >> 3); 502 srcPtr = pLineSrc; 503 src1 = *srcPtr++; 504 dest = *destPtr; 505 dest = (dest & (0xff << s2)) | (src1 >> s1); 506 *destPtr++ = (FX_BYTE)dest; 507 xx = x0 + 8; 508 for (; xx < x1 - 8; xx += 8) { 509 dest = *destPtr; 510 src0 = src1; 511 src1 = *srcPtr++; 512 src = (((src0 << 8) | src1) >> s1) & 0xff; 513 dest = src; 514 *destPtr++ = (FX_BYTE)dest; 515 } 516 dest = *destPtr; 517 src0 = src1; 518 if(srcPtr - pLineSrc < m_nStride) { 519 src1 = *srcPtr++; 520 } else { 521 src1 = 0; 522 } 523 src = (((src0 << 8) | src1) >> s1) & 0xff; 524 dest = (src & m2) | (dest & m1); 525 *destPtr = (FX_BYTE)dest; 526 pLineDst += pDst->m_nStride; 527 pLineSrc += m_nStride; 528 } 529 } 530 break; 531 } 532 } else { 533 switch(op) { 534 case JBIG2_COMPOSE_OR: { 535 for(yy = y0; yy < y1; ++yy) { 536 destPtr = pLineDst; 537 srcPtr = pLineSrc + (-x >> 3); 538 src1 = *srcPtr++; 539 xx = x0; 540 for (; xx < x1 - 8; xx += 8) { 541 dest = *destPtr; 542 src0 = src1; 543 src1 = *srcPtr++; 544 src = (((src0 << 8) | src1) >> s1) & 0xff; 545 dest |= src; 546 *destPtr++ = (FX_BYTE)dest; 547 } 548 dest = *destPtr; 549 src0 = src1; 550 if(srcPtr - pLineSrc < m_nStride) { 551 src1 = *srcPtr++; 552 } else { 553 src1 = 0; 554 } 555 src = (((src0 << 8) | src1) >> s1) & 0xff; 556 dest |= src & m2; 557 *destPtr = (FX_BYTE)dest; 558 pLineDst += pDst->m_nStride; 559 pLineSrc += m_nStride; 560 } 561 } 562 break; 563 case JBIG2_COMPOSE_AND: { 564 for(yy = y0; yy < y1; ++yy) { 565 destPtr = pLineDst; 566 srcPtr = pLineSrc + (-x >> 3); 567 src1 = *srcPtr++; 568 xx = x0; 569 for (; xx < x1 - 8; xx += 8) { 570 dest = *destPtr; 571 src0 = src1; 572 src1 = *srcPtr++; 573 src = (((src0 << 8) | src1) >> s1) & 0xff; 574 dest &= src; 575 *destPtr++ = (FX_BYTE)dest; 576 } 577 dest = *destPtr; 578 src0 = src1; 579 if(srcPtr - pLineSrc < m_nStride) { 580 src1 = *srcPtr++; 581 } else { 582 src1 = 0; 583 } 584 src = (((src0 << 8) | src1) >> s1) & 0xff; 585 dest &= src | m1; 586 *destPtr = (FX_BYTE)dest; 587 pLineDst += pDst->m_nStride; 588 pLineSrc += m_nStride; 589 } 590 } 591 break; 592 case JBIG2_COMPOSE_XOR: { 593 for(yy = y0; yy < y1; ++yy) { 594 destPtr = pLineDst; 595 srcPtr = pLineSrc + (-x >> 3); 596 src1 = *srcPtr++; 597 xx = x0; 598 for (; xx < x1 - 8; xx += 8) { 599 dest = *destPtr; 600 src0 = src1; 601 src1 = *srcPtr++; 602 src = (((src0 << 8) | src1) >> s1) & 0xff; 603 dest ^= src; 604 *destPtr++ = (FX_BYTE)dest; 605 } 606 dest = *destPtr; 607 src0 = src1; 608 if(srcPtr - pLineSrc < m_nStride) { 609 src1 = *srcPtr++; 610 } else { 611 src1 = 0; 612 } 613 src = (((src0 << 8) | src1) >> s1) & 0xff; 614 dest ^= src & m2; 615 *destPtr = (FX_BYTE)dest; 616 pLineDst += pDst->m_nStride; 617 pLineSrc += m_nStride; 618 } 619 } 620 break; 621 case JBIG2_COMPOSE_XNOR: { 622 for(yy = y0; yy < y1; ++yy) { 623 destPtr = pLineDst; 624 srcPtr = pLineSrc + (-x >> 3); 625 src1 = *srcPtr++; 626 xx = x0; 627 for (; xx < x1 - 8; xx += 8) { 628 dest = *destPtr; 629 src0 = src1; 630 src1 = *srcPtr++; 631 src = (((src0 << 8) | src1) >> s1) & 0xff; 632 dest ^= src ^ 0xff; 633 *destPtr++ = (FX_BYTE)dest; 634 } 635 dest = *destPtr; 636 src0 = src1; 637 if(srcPtr - pLineSrc < m_nStride) { 638 src1 = *srcPtr++; 639 } else { 640 src1 = 0; 641 } 642 src = (((src0 << 8) | src1) >> s1) & 0xff; 643 dest ^= (src ^ 0xff) & m2; 644 *destPtr = (FX_BYTE)dest; 645 pLineDst += pDst->m_nStride; 646 pLineSrc += m_nStride; 647 } 648 } 649 break; 650 case JBIG2_COMPOSE_REPLACE: { 651 for(yy = y0; yy < y1; ++yy) { 652 destPtr = pLineDst; 653 srcPtr = pLineSrc + (-x >> 3); 654 src1 = *srcPtr++; 655 xx = x0; 656 for (; xx < x1 - 8; xx += 8) { 657 dest = *destPtr; 658 src0 = src1; 659 src1 = *srcPtr++; 660 src = (((src0 << 8) | src1) >> s1) & 0xff; 661 dest = src; 662 *destPtr++ = (FX_BYTE)dest; 663 } 664 dest = *destPtr; 665 src0 = src1; 666 if(srcPtr - pLineSrc < m_nStride) { 667 src1 = *srcPtr++; 668 } else { 669 src1 = 0; 670 } 671 src = (((src0 << 8) | src1) >> s1) & 0xff; 672 dest = (src & m2) | (dest & m1); 673 *destPtr = (FX_BYTE)dest; 674 pLineDst += pDst->m_nStride; 675 pLineSrc += m_nStride; 676 } 677 } 678 break; 679 } 680 } 681 } 682 return TRUE; 683} 684FX_BOOL CJBig2_Image::composeFrom(FX_INT32 x, FX_INT32 y, CJBig2_Image *pSrc, JBig2ComposeOp op) 685{ 686 if (!m_pData) { 687 return FALSE; 688 } 689 return pSrc->composeTo(this, x, y, op); 690} 691FX_BOOL CJBig2_Image::composeFrom(FX_INT32 x, FX_INT32 y, CJBig2_Image *pSrc, JBig2ComposeOp op, const FX_RECT* pSrcRect) 692{ 693 if (!m_pData) { 694 return FALSE; 695 } 696 return pSrc->composeTo(this, x, y, op, pSrcRect); 697} 698CJBig2_Image *CJBig2_Image::subImage_unopt(FX_INT32 x, FX_INT32 y, FX_INT32 w, FX_INT32 h) 699{ 700 CJBig2_Image *pImage; 701 FX_INT32 i, j; 702 JBIG2_ALLOC(pImage, CJBig2_Image(w, h)); 703 for(j = 0; j < h; j++) { 704 for(i = 0; i < w; i++) { 705 pImage->setPixel(i, j, getPixel(x + i, y + j)); 706 } 707 } 708 return pImage; 709} 710#define JBIG2_GETDWORD(buf) ((FX_DWORD)(((buf)[0] << 24) | ((buf)[1] << 16) | ((buf)[2] << 8) | (buf)[3])) 711CJBig2_Image *CJBig2_Image::subImage(FX_INT32 x, FX_INT32 y, FX_INT32 w, FX_INT32 h) 712{ 713 CJBig2_Image *pImage; 714 FX_INT32 m, n, j; 715 FX_BYTE *pLineSrc, *pLineDst; 716 FX_DWORD wTmp; 717 FX_BYTE *pSrc, *pSrcEnd, *pDst, *pDstEnd; 718 if (w == 0 || h == 0) { 719 return NULL; 720 } 721 JBIG2_ALLOC(pImage, CJBig2_Image(w, h)); 722 if (!m_pData) { 723 pImage->fill(0); 724 return pImage; 725 } 726 if (!pImage->m_pData) { 727 return pImage; 728 } 729 pLineSrc = m_pData + m_nStride * y; 730 pLineDst = pImage->m_pData; 731 m = (x >> 5) << 2; 732 n = x & 31; 733 if(n == 0) { 734 for(j = 0; j < h; j++) { 735 pSrc = pLineSrc + m; 736 pSrcEnd = pLineSrc + m_nStride; 737 pDst = pLineDst; 738 pDstEnd = pLineDst + pImage->m_nStride; 739 for(; pDst < pDstEnd; pSrc += 4, pDst += 4) { 740 *((FX_DWORD *)pDst) = *((FX_DWORD *)pSrc); 741 } 742 pLineSrc += m_nStride; 743 pLineDst += pImage->m_nStride; 744 } 745 } else { 746 for(j = 0; j < h; j++) { 747 pSrc = pLineSrc + m; 748 pSrcEnd = pLineSrc + m_nStride; 749 pDst = pLineDst; 750 pDstEnd = pLineDst + pImage->m_nStride; 751 for(; pDst < pDstEnd; pSrc += 4, pDst += 4) { 752 if(pSrc + 4 < pSrcEnd) { 753 wTmp = (JBIG2_GETDWORD(pSrc) << n) | (JBIG2_GETDWORD(pSrc + 4) >> (32 - n)); 754 } else { 755 wTmp = JBIG2_GETDWORD(pSrc) << n; 756 } 757 pDst[0] = (FX_BYTE)(wTmp >> 24); 758 pDst[1] = (FX_BYTE)(wTmp >> 16); 759 pDst[2] = (FX_BYTE)(wTmp >> 8); 760 pDst[3] = (FX_BYTE)wTmp; 761 } 762 pLineSrc += m_nStride; 763 pLineDst += pImage->m_nStride; 764 } 765 } 766 return pImage; 767} 768void CJBig2_Image::expand(FX_INT32 h, FX_BOOL v) 769{ 770 if (!m_pData || h <= m_nHeight) { 771 return; 772 } 773 FX_DWORD dwH = pdfium::base::checked_cast<FX_DWORD>(h); 774 FX_DWORD dwStride = pdfium::base::checked_cast<FX_DWORD>(m_nStride); 775 FX_DWORD dwHeight = pdfium::base::checked_cast<FX_DWORD>(m_nHeight); 776 FX_SAFE_DWORD safeMemSize = dwH; 777 safeMemSize *= dwStride; 778 if (!safeMemSize.IsValid()) { 779 return; 780 } 781 //The guaranteed reallocated memory is to be < 4GB (unsigned int). 782 m_pData = (FX_BYTE*)m_pModule->JBig2_Realloc(m_pData, safeMemSize.ValueOrDie()); 783 //The result of dwHeight * dwStride doesn't overflow after the 784 //checking of safeMemSize. 785 //The same as the result of (dwH - dwHeight) * dwStride) because 786 //dwH - dwHeight is always less than dwH(h) which is checked in 787 //the calculation of dwH * dwStride. 788 JBIG2_memset(m_pData + dwHeight * dwStride, v ? 0xff : 0, (dwH - dwHeight) * dwStride); 789 m_nHeight = h; 790} 791FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op) 792{ 793 FX_INT32 xs0 = 0, ys0 = 0, xs1 = 0, ys1 = 0, xd0 = 0, yd0 = 0, xd1 = 0, 794 yd1 = 0, xx = 0, yy = 0, w = 0, h = 0, middleDwords = 0, lineLeft = 0; 795 796 FX_DWORD s1 = 0, d1 = 0, d2 = 0, shift = 0, shift1 = 0, shift2 = 0, 797 tmp = 0, tmp1 = 0, tmp2 = 0, maskL = 0, maskR = 0, maskM = 0; 798 799 FX_BYTE *lineSrc = NULL, *lineDst = NULL, *sp = NULL, *dp = NULL; 800 801 if (!m_pData) { 802 return FALSE; 803 } 804 if (x < -1048576 || x > 1048576 || y < -1048576 || y > 1048576) { 805 return FALSE; 806 } 807 if(y < 0) { 808 ys0 = -y; 809 } 810 if(y + m_nHeight > pDst->m_nHeight) { 811 ys1 = pDst->m_nHeight - y; 812 } else { 813 ys1 = m_nHeight; 814 } 815 if(x < 0) { 816 xs0 = -x; 817 } 818 if(x + m_nWidth > pDst->m_nWidth) { 819 xs1 = pDst->m_nWidth - x; 820 } else { 821 xs1 = m_nWidth; 822 } 823 if((ys0 >= ys1) || (xs0 >= xs1)) { 824 return 0; 825 } 826 w = xs1 - xs0; 827 h = ys1 - ys0; 828 if(y >= 0) { 829 yd0 = y; 830 } 831 if(x >= 0) { 832 xd0 = x; 833 } 834 xd1 = xd0 + w; 835 yd1 = yd0 + h; 836 d1 = xd0 & 31; 837 d2 = xd1 & 31; 838 s1 = xs0 & 31; 839 maskL = 0xffffffff >> d1; 840 maskR = 0xffffffff << ((32 - (xd1 & 31)) % 32); 841 maskM = maskL & maskR; 842 lineSrc = m_pData + ys0 * m_nStride + ((xs0 >> 5) << 2); 843 lineLeft = m_nStride - ((xs0 >> 5) << 2); 844 lineDst = pDst->m_pData + yd0 * pDst->m_nStride + ((xd0 >> 5) << 2); 845 if((xd0 & ~31) == ((xd1 - 1) & ~31)) { 846 if((xs0 & ~31) == ((xs1 - 1) & ~31)) { 847 if(s1 > d1) { 848 shift = s1 - d1; 849 for(yy = yd0; yy < yd1; yy++) { 850 tmp1 = JBIG2_GETDWORD(lineSrc) << shift; 851 tmp2 = JBIG2_GETDWORD(lineDst); 852 switch(op) { 853 case JBIG2_COMPOSE_OR: 854 tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM); 855 break; 856 case JBIG2_COMPOSE_AND: 857 tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM); 858 break; 859 case JBIG2_COMPOSE_XOR: 860 tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM); 861 break; 862 case JBIG2_COMPOSE_XNOR: 863 tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM); 864 break; 865 case JBIG2_COMPOSE_REPLACE: 866 tmp = (tmp2 & ~maskM) | (tmp1 & maskM); 867 break; 868 } 869 lineDst[0] = (FX_BYTE)(tmp >> 24); 870 lineDst[1] = (FX_BYTE)(tmp >> 16); 871 lineDst[2] = (FX_BYTE)(tmp >> 8); 872 lineDst[3] = (FX_BYTE)tmp; 873 lineSrc += m_nStride; 874 lineDst += pDst->m_nStride; 875 } 876 } else { 877 shift = d1 - s1; 878 for(yy = yd0; yy < yd1; yy++) { 879 tmp1 = JBIG2_GETDWORD(lineSrc) >> shift; 880 tmp2 = JBIG2_GETDWORD(lineDst); 881 switch(op) { 882 case JBIG2_COMPOSE_OR: 883 tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM); 884 break; 885 case JBIG2_COMPOSE_AND: 886 tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM); 887 break; 888 case JBIG2_COMPOSE_XOR: 889 tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM); 890 break; 891 case JBIG2_COMPOSE_XNOR: 892 tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM); 893 break; 894 case JBIG2_COMPOSE_REPLACE: 895 tmp = (tmp2 & ~maskM) | (tmp1 & maskM); 896 break; 897 } 898 lineDst[0] = (FX_BYTE)(tmp >> 24); 899 lineDst[1] = (FX_BYTE)(tmp >> 16); 900 lineDst[2] = (FX_BYTE)(tmp >> 8); 901 lineDst[3] = (FX_BYTE)tmp; 902 lineSrc += m_nStride; 903 lineDst += pDst->m_nStride; 904 } 905 } 906 } else { 907 shift1 = s1 - d1; 908 shift2 = 32 - shift1; 909 for(yy = yd0; yy < yd1; yy++) { 910 tmp1 = (JBIG2_GETDWORD(lineSrc) << shift1) | (JBIG2_GETDWORD(lineSrc + 4) >> shift2); 911 tmp2 = JBIG2_GETDWORD(lineDst); 912 switch(op) { 913 case JBIG2_COMPOSE_OR: 914 tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM); 915 break; 916 case JBIG2_COMPOSE_AND: 917 tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM); 918 break; 919 case JBIG2_COMPOSE_XOR: 920 tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM); 921 break; 922 case JBIG2_COMPOSE_XNOR: 923 tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM); 924 break; 925 case JBIG2_COMPOSE_REPLACE: 926 tmp = (tmp2 & ~maskM) | (tmp1 & maskM); 927 break; 928 } 929 lineDst[0] = (FX_BYTE)(tmp >> 24); 930 lineDst[1] = (FX_BYTE)(tmp >> 16); 931 lineDst[2] = (FX_BYTE)(tmp >> 8); 932 lineDst[3] = (FX_BYTE)tmp; 933 lineSrc += m_nStride; 934 lineDst += pDst->m_nStride; 935 } 936 } 937 } else { 938 if(s1 > d1) { 939 shift1 = s1 - d1; 940 shift2 = 32 - shift1; 941 middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5); 942 for(yy = yd0; yy < yd1; yy++) { 943 sp = lineSrc; 944 dp = lineDst; 945 if(d1 != 0) { 946 tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2); 947 tmp2 = JBIG2_GETDWORD(dp); 948 switch(op) { 949 case JBIG2_COMPOSE_OR: 950 tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL); 951 break; 952 case JBIG2_COMPOSE_AND: 953 tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL); 954 break; 955 case JBIG2_COMPOSE_XOR: 956 tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL); 957 break; 958 case JBIG2_COMPOSE_XNOR: 959 tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL); 960 break; 961 case JBIG2_COMPOSE_REPLACE: 962 tmp = (tmp2 & ~maskL) | (tmp1 & maskL); 963 break; 964 } 965 dp[0] = (FX_BYTE)(tmp >> 24); 966 dp[1] = (FX_BYTE)(tmp >> 16); 967 dp[2] = (FX_BYTE)(tmp >> 8); 968 dp[3] = (FX_BYTE)tmp; 969 sp += 4; 970 dp += 4; 971 } 972 for(xx = 0; xx < middleDwords; xx++) { 973 tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2); 974 tmp2 = JBIG2_GETDWORD(dp); 975 switch(op) { 976 case JBIG2_COMPOSE_OR: 977 tmp = tmp1 | tmp2; 978 break; 979 case JBIG2_COMPOSE_AND: 980 tmp = tmp1 & tmp2; 981 break; 982 case JBIG2_COMPOSE_XOR: 983 tmp = tmp1 ^ tmp2; 984 break; 985 case JBIG2_COMPOSE_XNOR: 986 tmp = ~(tmp1 ^ tmp2); 987 break; 988 case JBIG2_COMPOSE_REPLACE: 989 tmp = tmp1; 990 break; 991 } 992 dp[0] = (FX_BYTE)(tmp >> 24); 993 dp[1] = (FX_BYTE)(tmp >> 16); 994 dp[2] = (FX_BYTE)(tmp >> 8); 995 dp[3] = (FX_BYTE)tmp; 996 sp += 4; 997 dp += 4; 998 } 999 if(d2 != 0) { 1000 tmp1 = (JBIG2_GETDWORD(sp) << shift1) | ( 1001 ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift2); 1002 tmp2 = JBIG2_GETDWORD(dp); 1003 switch(op) { 1004 case JBIG2_COMPOSE_OR: 1005 tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR); 1006 break; 1007 case JBIG2_COMPOSE_AND: 1008 tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR); 1009 break; 1010 case JBIG2_COMPOSE_XOR: 1011 tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR); 1012 break; 1013 case JBIG2_COMPOSE_XNOR: 1014 tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR); 1015 break; 1016 case JBIG2_COMPOSE_REPLACE: 1017 tmp = (tmp2 & ~maskR) | (tmp1 & maskR); 1018 break; 1019 } 1020 dp[0] = (FX_BYTE)(tmp >> 24); 1021 dp[1] = (FX_BYTE)(tmp >> 16); 1022 dp[2] = (FX_BYTE)(tmp >> 8); 1023 dp[3] = (FX_BYTE)tmp; 1024 } 1025 lineSrc += m_nStride; 1026 lineDst += pDst->m_nStride; 1027 } 1028 } else if(s1 == d1) { 1029 middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5); 1030 for(yy = yd0; yy < yd1; yy++) { 1031 sp = lineSrc; 1032 dp = lineDst; 1033 if(d1 != 0) { 1034 tmp1 = JBIG2_GETDWORD(sp); 1035 tmp2 = JBIG2_GETDWORD(dp); 1036 switch(op) { 1037 case JBIG2_COMPOSE_OR: 1038 tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL); 1039 break; 1040 case JBIG2_COMPOSE_AND: 1041 tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL); 1042 break; 1043 case JBIG2_COMPOSE_XOR: 1044 tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL); 1045 break; 1046 case JBIG2_COMPOSE_XNOR: 1047 tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL); 1048 break; 1049 case JBIG2_COMPOSE_REPLACE: 1050 tmp = (tmp2 & ~maskL) | (tmp1 & maskL); 1051 break; 1052 } 1053 dp[0] = (FX_BYTE)(tmp >> 24); 1054 dp[1] = (FX_BYTE)(tmp >> 16); 1055 dp[2] = (FX_BYTE)(tmp >> 8); 1056 dp[3] = (FX_BYTE)tmp; 1057 sp += 4; 1058 dp += 4; 1059 } 1060 for(xx = 0; xx < middleDwords; xx++) { 1061 tmp1 = JBIG2_GETDWORD(sp); 1062 tmp2 = JBIG2_GETDWORD(dp); 1063 switch(op) { 1064 case JBIG2_COMPOSE_OR: 1065 tmp = tmp1 | tmp2; 1066 break; 1067 case JBIG2_COMPOSE_AND: 1068 tmp = tmp1 & tmp2; 1069 break; 1070 case JBIG2_COMPOSE_XOR: 1071 tmp = tmp1 ^ tmp2; 1072 break; 1073 case JBIG2_COMPOSE_XNOR: 1074 tmp = ~(tmp1 ^ tmp2); 1075 break; 1076 case JBIG2_COMPOSE_REPLACE: 1077 tmp = tmp1; 1078 break; 1079 } 1080 dp[0] = (FX_BYTE)(tmp >> 24); 1081 dp[1] = (FX_BYTE)(tmp >> 16); 1082 dp[2] = (FX_BYTE)(tmp >> 8); 1083 dp[3] = (FX_BYTE)tmp; 1084 sp += 4; 1085 dp += 4; 1086 } 1087 if(d2 != 0) { 1088 tmp1 = JBIG2_GETDWORD(sp); 1089 tmp2 = JBIG2_GETDWORD(dp); 1090 switch(op) { 1091 case JBIG2_COMPOSE_OR: 1092 tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR); 1093 break; 1094 case JBIG2_COMPOSE_AND: 1095 tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR); 1096 break; 1097 case JBIG2_COMPOSE_XOR: 1098 tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR); 1099 break; 1100 case JBIG2_COMPOSE_XNOR: 1101 tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR); 1102 break; 1103 case JBIG2_COMPOSE_REPLACE: 1104 tmp = (tmp2 & ~maskR) | (tmp1 & maskR); 1105 break; 1106 } 1107 dp[0] = (FX_BYTE)(tmp >> 24); 1108 dp[1] = (FX_BYTE)(tmp >> 16); 1109 dp[2] = (FX_BYTE)(tmp >> 8); 1110 dp[3] = (FX_BYTE)tmp; 1111 } 1112 lineSrc += m_nStride; 1113 lineDst += pDst->m_nStride; 1114 } 1115 } else { 1116 shift1 = d1 - s1; 1117 shift2 = 32 - shift1; 1118 middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5); 1119 for(yy = yd0; yy < yd1; yy++) { 1120 sp = lineSrc; 1121 dp = lineDst; 1122 if(d1 != 0) { 1123 tmp1 = JBIG2_GETDWORD(sp) >> shift1; 1124 tmp2 = JBIG2_GETDWORD(dp); 1125 switch(op) { 1126 case JBIG2_COMPOSE_OR: 1127 tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL); 1128 break; 1129 case JBIG2_COMPOSE_AND: 1130 tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL); 1131 break; 1132 case JBIG2_COMPOSE_XOR: 1133 tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL); 1134 break; 1135 case JBIG2_COMPOSE_XNOR: 1136 tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL); 1137 break; 1138 case JBIG2_COMPOSE_REPLACE: 1139 tmp = (tmp2 & ~maskL) | (tmp1 & maskL); 1140 break; 1141 } 1142 dp[0] = (FX_BYTE)(tmp >> 24); 1143 dp[1] = (FX_BYTE)(tmp >> 16); 1144 dp[2] = (FX_BYTE)(tmp >> 8); 1145 dp[3] = (FX_BYTE)tmp; 1146 dp += 4; 1147 } 1148 for(xx = 0; xx < middleDwords; xx++) { 1149 tmp1 = (JBIG2_GETDWORD(sp) << shift2) | ((JBIG2_GETDWORD(sp + 4)) >> shift1); 1150 tmp2 = JBIG2_GETDWORD(dp); 1151 switch(op) { 1152 case JBIG2_COMPOSE_OR: 1153 tmp = tmp1 | tmp2; 1154 break; 1155 case JBIG2_COMPOSE_AND: 1156 tmp = tmp1 & tmp2; 1157 break; 1158 case JBIG2_COMPOSE_XOR: 1159 tmp = tmp1 ^ tmp2; 1160 break; 1161 case JBIG2_COMPOSE_XNOR: 1162 tmp = ~(tmp1 ^ tmp2); 1163 break; 1164 case JBIG2_COMPOSE_REPLACE: 1165 tmp = tmp1; 1166 break; 1167 } 1168 dp[0] = (FX_BYTE)(tmp >> 24); 1169 dp[1] = (FX_BYTE)(tmp >> 16); 1170 dp[2] = (FX_BYTE)(tmp >> 8); 1171 dp[3] = (FX_BYTE)tmp; 1172 sp += 4; 1173 dp += 4; 1174 } 1175 if(d2 != 0) { 1176 tmp1 = (JBIG2_GETDWORD(sp) << shift2) | ( 1177 ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift1); 1178 tmp2 = JBIG2_GETDWORD(dp); 1179 switch(op) { 1180 case JBIG2_COMPOSE_OR: 1181 tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR); 1182 break; 1183 case JBIG2_COMPOSE_AND: 1184 tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR); 1185 break; 1186 case JBIG2_COMPOSE_XOR: 1187 tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR); 1188 break; 1189 case JBIG2_COMPOSE_XNOR: 1190 tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR); 1191 break; 1192 case JBIG2_COMPOSE_REPLACE: 1193 tmp = (tmp2 & ~maskR) | (tmp1 & maskR); 1194 break; 1195 } 1196 dp[0] = (FX_BYTE)(tmp >> 24); 1197 dp[1] = (FX_BYTE)(tmp >> 16); 1198 dp[2] = (FX_BYTE)(tmp >> 8); 1199 dp[3] = (FX_BYTE)tmp; 1200 } 1201 lineSrc += m_nStride; 1202 lineDst += pDst->m_nStride; 1203 } 1204 } 1205 } 1206 return 1; 1207} 1208FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op, const FX_RECT* pSrcRect) 1209{ 1210 FX_INT32 xs0, ys0, xs1, ys1, xd0, yd0, xd1, yd1, xx, yy, w, h, middleDwords, lineLeft; 1211 FX_DWORD s1, d1, d2, shift, shift1, shift2, tmp, tmp1, tmp2, maskL, maskR, maskM; 1212 FX_BYTE *lineSrc, *lineDst, *sp, *dp; 1213 FX_INT32 sw, sh; 1214 if (!m_pData) { 1215 return FALSE; 1216 } 1217 if (x < -1048576 || x > 1048576 || y < -1048576 || y > 1048576) { 1218 return FALSE; 1219 } 1220 sw = pSrcRect->Width(); 1221 sh = pSrcRect->Height(); 1222 if(y < 0) { 1223 ys0 = -y; 1224 } else { 1225 ys0 = 0; 1226 } 1227 if(y + sh > pDst->m_nHeight) { 1228 ys1 = pDst->m_nHeight - y; 1229 } else { 1230 ys1 = sh; 1231 } 1232 if(x < 0) { 1233 xs0 = -x; 1234 } else { 1235 xs0 = 0; 1236 } 1237 if(x + sw > pDst->m_nWidth) { 1238 xs1 = pDst->m_nWidth - x; 1239 } else { 1240 xs1 = sw; 1241 } 1242 if((ys0 >= ys1) || (xs0 >= xs1)) { 1243 return 0; 1244 } 1245 w = xs1 - xs0; 1246 h = ys1 - ys0; 1247 if(y < 0) { 1248 yd0 = 0; 1249 } else { 1250 yd0 = y; 1251 } 1252 if(x < 0) { 1253 xd0 = 0; 1254 } else { 1255 xd0 = x; 1256 } 1257 xd1 = xd0 + w; 1258 yd1 = yd0 + h; 1259 d1 = xd0 & 31; 1260 d2 = xd1 & 31; 1261 s1 = xs0 & 31; 1262 maskL = 0xffffffff >> d1; 1263 maskR = 0xffffffff << ((32 - (xd1 & 31)) % 32); 1264 maskM = maskL & maskR; 1265 lineSrc = m_pData + (pSrcRect->top + ys0) * m_nStride + (((xs0 + pSrcRect->left) >> 5) << 2); 1266 lineLeft = m_nStride - ((xs0 >> 5) << 2); 1267 lineDst = pDst->m_pData + yd0 * pDst->m_nStride + ((xd0 >> 5) << 2); 1268 if((xd0 & ~31) == ((xd1 - 1) & ~31)) { 1269 if((xs0 & ~31) == ((xs1 - 1) & ~31)) { 1270 if(s1 > d1) { 1271 shift = s1 - d1; 1272 for(yy = yd0; yy < yd1; yy++) { 1273 tmp1 = JBIG2_GETDWORD(lineSrc) << shift; 1274 tmp2 = JBIG2_GETDWORD(lineDst); 1275 switch(op) { 1276 case JBIG2_COMPOSE_OR: 1277 tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM); 1278 break; 1279 case JBIG2_COMPOSE_AND: 1280 tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM); 1281 break; 1282 case JBIG2_COMPOSE_XOR: 1283 tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM); 1284 break; 1285 case JBIG2_COMPOSE_XNOR: 1286 tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM); 1287 break; 1288 case JBIG2_COMPOSE_REPLACE: 1289 tmp = (tmp2 & ~maskM) | (tmp1 & maskM); 1290 break; 1291 } 1292 lineDst[0] = (FX_BYTE)(tmp >> 24); 1293 lineDst[1] = (FX_BYTE)(tmp >> 16); 1294 lineDst[2] = (FX_BYTE)(tmp >> 8); 1295 lineDst[3] = (FX_BYTE)tmp; 1296 lineSrc += m_nStride; 1297 lineDst += pDst->m_nStride; 1298 } 1299 } else { 1300 shift = d1 - s1; 1301 for(yy = yd0; yy < yd1; yy++) { 1302 tmp1 = JBIG2_GETDWORD(lineSrc) >> shift; 1303 tmp2 = JBIG2_GETDWORD(lineDst); 1304 switch(op) { 1305 case JBIG2_COMPOSE_OR: 1306 tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM); 1307 break; 1308 case JBIG2_COMPOSE_AND: 1309 tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM); 1310 break; 1311 case JBIG2_COMPOSE_XOR: 1312 tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM); 1313 break; 1314 case JBIG2_COMPOSE_XNOR: 1315 tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM); 1316 break; 1317 case JBIG2_COMPOSE_REPLACE: 1318 tmp = (tmp2 & ~maskM) | (tmp1 & maskM); 1319 break; 1320 } 1321 lineDst[0] = (FX_BYTE)(tmp >> 24); 1322 lineDst[1] = (FX_BYTE)(tmp >> 16); 1323 lineDst[2] = (FX_BYTE)(tmp >> 8); 1324 lineDst[3] = (FX_BYTE)tmp; 1325 lineSrc += m_nStride; 1326 lineDst += pDst->m_nStride; 1327 } 1328 } 1329 } else { 1330 shift1 = s1 - d1; 1331 shift2 = 32 - shift1; 1332 for(yy = yd0; yy < yd1; yy++) { 1333 tmp1 = (JBIG2_GETDWORD(lineSrc) << shift1) | (JBIG2_GETDWORD(lineSrc + 4) >> shift2); 1334 tmp2 = JBIG2_GETDWORD(lineDst); 1335 switch(op) { 1336 case JBIG2_COMPOSE_OR: 1337 tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM); 1338 break; 1339 case JBIG2_COMPOSE_AND: 1340 tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM); 1341 break; 1342 case JBIG2_COMPOSE_XOR: 1343 tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM); 1344 break; 1345 case JBIG2_COMPOSE_XNOR: 1346 tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM); 1347 break; 1348 case JBIG2_COMPOSE_REPLACE: 1349 tmp = (tmp2 & ~maskM) | (tmp1 & maskM); 1350 break; 1351 } 1352 lineDst[0] = (FX_BYTE)(tmp >> 24); 1353 lineDst[1] = (FX_BYTE)(tmp >> 16); 1354 lineDst[2] = (FX_BYTE)(tmp >> 8); 1355 lineDst[3] = (FX_BYTE)tmp; 1356 lineSrc += m_nStride; 1357 lineDst += pDst->m_nStride; 1358 } 1359 } 1360 } else { 1361 if(s1 > d1) { 1362 shift1 = s1 - d1; 1363 shift2 = 32 - shift1; 1364 middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5); 1365 for(yy = yd0; yy < yd1; yy++) { 1366 sp = lineSrc; 1367 dp = lineDst; 1368 if(d1 != 0) { 1369 tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2); 1370 tmp2 = JBIG2_GETDWORD(dp); 1371 switch(op) { 1372 case JBIG2_COMPOSE_OR: 1373 tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL); 1374 break; 1375 case JBIG2_COMPOSE_AND: 1376 tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL); 1377 break; 1378 case JBIG2_COMPOSE_XOR: 1379 tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL); 1380 break; 1381 case JBIG2_COMPOSE_XNOR: 1382 tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL); 1383 break; 1384 case JBIG2_COMPOSE_REPLACE: 1385 tmp = (tmp2 & ~maskL) | (tmp1 & maskL); 1386 break; 1387 } 1388 dp[0] = (FX_BYTE)(tmp >> 24); 1389 dp[1] = (FX_BYTE)(tmp >> 16); 1390 dp[2] = (FX_BYTE)(tmp >> 8); 1391 dp[3] = (FX_BYTE)tmp; 1392 sp += 4; 1393 dp += 4; 1394 } 1395 for(xx = 0; xx < middleDwords; xx++) { 1396 tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2); 1397 tmp2 = JBIG2_GETDWORD(dp); 1398 switch(op) { 1399 case JBIG2_COMPOSE_OR: 1400 tmp = tmp1 | tmp2; 1401 break; 1402 case JBIG2_COMPOSE_AND: 1403 tmp = tmp1 & tmp2; 1404 break; 1405 case JBIG2_COMPOSE_XOR: 1406 tmp = tmp1 ^ tmp2; 1407 break; 1408 case JBIG2_COMPOSE_XNOR: 1409 tmp = ~(tmp1 ^ tmp2); 1410 break; 1411 case JBIG2_COMPOSE_REPLACE: 1412 tmp = tmp1; 1413 break; 1414 } 1415 dp[0] = (FX_BYTE)(tmp >> 24); 1416 dp[1] = (FX_BYTE)(tmp >> 16); 1417 dp[2] = (FX_BYTE)(tmp >> 8); 1418 dp[3] = (FX_BYTE)tmp; 1419 sp += 4; 1420 dp += 4; 1421 } 1422 if(d2 != 0) { 1423 tmp1 = (JBIG2_GETDWORD(sp) << shift1) | ( 1424 ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift2); 1425 tmp2 = JBIG2_GETDWORD(dp); 1426 switch(op) { 1427 case JBIG2_COMPOSE_OR: 1428 tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR); 1429 break; 1430 case JBIG2_COMPOSE_AND: 1431 tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR); 1432 break; 1433 case JBIG2_COMPOSE_XOR: 1434 tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR); 1435 break; 1436 case JBIG2_COMPOSE_XNOR: 1437 tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR); 1438 break; 1439 case JBIG2_COMPOSE_REPLACE: 1440 tmp = (tmp2 & ~maskR) | (tmp1 & maskR); 1441 break; 1442 } 1443 dp[0] = (FX_BYTE)(tmp >> 24); 1444 dp[1] = (FX_BYTE)(tmp >> 16); 1445 dp[2] = (FX_BYTE)(tmp >> 8); 1446 dp[3] = (FX_BYTE)tmp; 1447 } 1448 lineSrc += m_nStride; 1449 lineDst += pDst->m_nStride; 1450 } 1451 } else if(s1 == d1) { 1452 middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5); 1453 for(yy = yd0; yy < yd1; yy++) { 1454 sp = lineSrc; 1455 dp = lineDst; 1456 if(d1 != 0) { 1457 tmp1 = JBIG2_GETDWORD(sp); 1458 tmp2 = JBIG2_GETDWORD(dp); 1459 switch(op) { 1460 case JBIG2_COMPOSE_OR: 1461 tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL); 1462 break; 1463 case JBIG2_COMPOSE_AND: 1464 tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL); 1465 break; 1466 case JBIG2_COMPOSE_XOR: 1467 tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL); 1468 break; 1469 case JBIG2_COMPOSE_XNOR: 1470 tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL); 1471 break; 1472 case JBIG2_COMPOSE_REPLACE: 1473 tmp = (tmp2 & ~maskL) | (tmp1 & maskL); 1474 break; 1475 } 1476 dp[0] = (FX_BYTE)(tmp >> 24); 1477 dp[1] = (FX_BYTE)(tmp >> 16); 1478 dp[2] = (FX_BYTE)(tmp >> 8); 1479 dp[3] = (FX_BYTE)tmp; 1480 sp += 4; 1481 dp += 4; 1482 } 1483 for(xx = 0; xx < middleDwords; xx++) { 1484 tmp1 = JBIG2_GETDWORD(sp); 1485 tmp2 = JBIG2_GETDWORD(dp); 1486 switch(op) { 1487 case JBIG2_COMPOSE_OR: 1488 tmp = tmp1 | tmp2; 1489 break; 1490 case JBIG2_COMPOSE_AND: 1491 tmp = tmp1 & tmp2; 1492 break; 1493 case JBIG2_COMPOSE_XOR: 1494 tmp = tmp1 ^ tmp2; 1495 break; 1496 case JBIG2_COMPOSE_XNOR: 1497 tmp = ~(tmp1 ^ tmp2); 1498 break; 1499 case JBIG2_COMPOSE_REPLACE: 1500 tmp = tmp1; 1501 break; 1502 } 1503 dp[0] = (FX_BYTE)(tmp >> 24); 1504 dp[1] = (FX_BYTE)(tmp >> 16); 1505 dp[2] = (FX_BYTE)(tmp >> 8); 1506 dp[3] = (FX_BYTE)tmp; 1507 sp += 4; 1508 dp += 4; 1509 } 1510 if(d2 != 0) { 1511 tmp1 = JBIG2_GETDWORD(sp); 1512 tmp2 = JBIG2_GETDWORD(dp); 1513 switch(op) { 1514 case JBIG2_COMPOSE_OR: 1515 tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR); 1516 break; 1517 case JBIG2_COMPOSE_AND: 1518 tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR); 1519 break; 1520 case JBIG2_COMPOSE_XOR: 1521 tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR); 1522 break; 1523 case JBIG2_COMPOSE_XNOR: 1524 tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR); 1525 break; 1526 case JBIG2_COMPOSE_REPLACE: 1527 tmp = (tmp2 & ~maskR) | (tmp1 & maskR); 1528 break; 1529 } 1530 dp[0] = (FX_BYTE)(tmp >> 24); 1531 dp[1] = (FX_BYTE)(tmp >> 16); 1532 dp[2] = (FX_BYTE)(tmp >> 8); 1533 dp[3] = (FX_BYTE)tmp; 1534 } 1535 lineSrc += m_nStride; 1536 lineDst += pDst->m_nStride; 1537 } 1538 } else { 1539 shift1 = d1 - s1; 1540 shift2 = 32 - shift1; 1541 middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5); 1542 for(yy = yd0; yy < yd1; yy++) { 1543 sp = lineSrc; 1544 dp = lineDst; 1545 if(d1 != 0) { 1546 tmp1 = JBIG2_GETDWORD(sp) >> shift1; 1547 tmp2 = JBIG2_GETDWORD(dp); 1548 switch(op) { 1549 case JBIG2_COMPOSE_OR: 1550 tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL); 1551 break; 1552 case JBIG2_COMPOSE_AND: 1553 tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL); 1554 break; 1555 case JBIG2_COMPOSE_XOR: 1556 tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL); 1557 break; 1558 case JBIG2_COMPOSE_XNOR: 1559 tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL); 1560 break; 1561 case JBIG2_COMPOSE_REPLACE: 1562 tmp = (tmp2 & ~maskL) | (tmp1 & maskL); 1563 break; 1564 } 1565 dp[0] = (FX_BYTE)(tmp >> 24); 1566 dp[1] = (FX_BYTE)(tmp >> 16); 1567 dp[2] = (FX_BYTE)(tmp >> 8); 1568 dp[3] = (FX_BYTE)tmp; 1569 dp += 4; 1570 } 1571 for(xx = 0; xx < middleDwords; xx++) { 1572 tmp1 = (JBIG2_GETDWORD(sp) << shift2) | ((JBIG2_GETDWORD(sp + 4)) >> shift1); 1573 tmp2 = JBIG2_GETDWORD(dp); 1574 switch(op) { 1575 case JBIG2_COMPOSE_OR: 1576 tmp = tmp1 | tmp2; 1577 break; 1578 case JBIG2_COMPOSE_AND: 1579 tmp = tmp1 & tmp2; 1580 break; 1581 case JBIG2_COMPOSE_XOR: 1582 tmp = tmp1 ^ tmp2; 1583 break; 1584 case JBIG2_COMPOSE_XNOR: 1585 tmp = ~(tmp1 ^ tmp2); 1586 break; 1587 case JBIG2_COMPOSE_REPLACE: 1588 tmp = tmp1; 1589 break; 1590 } 1591 dp[0] = (FX_BYTE)(tmp >> 24); 1592 dp[1] = (FX_BYTE)(tmp >> 16); 1593 dp[2] = (FX_BYTE)(tmp >> 8); 1594 dp[3] = (FX_BYTE)tmp; 1595 sp += 4; 1596 dp += 4; 1597 } 1598 if(d2 != 0) { 1599 tmp1 = (JBIG2_GETDWORD(sp) << shift2) | ( 1600 ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift1); 1601 tmp2 = JBIG2_GETDWORD(dp); 1602 switch(op) { 1603 case JBIG2_COMPOSE_OR: 1604 tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR); 1605 break; 1606 case JBIG2_COMPOSE_AND: 1607 tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR); 1608 break; 1609 case JBIG2_COMPOSE_XOR: 1610 tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR); 1611 break; 1612 case JBIG2_COMPOSE_XNOR: 1613 tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR); 1614 break; 1615 case JBIG2_COMPOSE_REPLACE: 1616 tmp = (tmp2 & ~maskR) | (tmp1 & maskR); 1617 break; 1618 } 1619 dp[0] = (FX_BYTE)(tmp >> 24); 1620 dp[1] = (FX_BYTE)(tmp >> 16); 1621 dp[2] = (FX_BYTE)(tmp >> 8); 1622 dp[3] = (FX_BYTE)tmp; 1623 } 1624 lineSrc += m_nStride; 1625 lineDst += pDst->m_nStride; 1626 } 1627 } 1628 } 1629 return 1; 1630} 1631