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