| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 FXSYS_memset(m_pDestScanline, 255, size); | 301 FXSYS_memset(m_pDestScanline, 255, size); |
| 302 } | 302 } |
| 303 m_InterPitch = (m_DestClip.Width() * m_DestBpp + 31) / 32 * 4; | 303 m_InterPitch = (m_DestClip.Width() * m_DestBpp + 31) / 32 * 4; |
| 304 m_ExtraMaskPitch = (m_DestClip.Width() * 8 + 31) / 32 * 4; | 304 m_ExtraMaskPitch = (m_DestClip.Width() * 8 + 31) / 32 * 4; |
| 305 m_pInterBuf = nullptr; | 305 m_pInterBuf = nullptr; |
| 306 m_pSource = pSrcBitmap; | 306 m_pSource = pSrcBitmap; |
| 307 m_SrcWidth = pSrcBitmap->GetWidth(); | 307 m_SrcWidth = pSrcBitmap->GetWidth(); |
| 308 m_SrcHeight = pSrcBitmap->GetHeight(); | 308 m_SrcHeight = pSrcBitmap->GetHeight(); |
| 309 m_SrcPitch = (m_SrcWidth * m_SrcBpp + 31) / 32 * 4; | 309 m_SrcPitch = (m_SrcWidth * m_SrcBpp + 31) / 32 * 4; |
| 310 if ((flags & FXDIB_NOSMOOTH) == 0) { | 310 if ((flags & FXDIB_NOSMOOTH) == 0) { |
| 311 FX_BOOL bInterpol = | 311 bool bInterpol = flags & FXDIB_INTERPOL || flags & FXDIB_BICUBIC_INTERPOL; |
| 312 flags & FXDIB_INTERPOL || flags & FXDIB_BICUBIC_INTERPOL; | |
| 313 if (!bInterpol && FXSYS_abs(dest_width) != 0 && | 312 if (!bInterpol && FXSYS_abs(dest_width) != 0 && |
| 314 FXSYS_abs(dest_height) / 8 < static_cast<long long>(m_SrcWidth) * | 313 FXSYS_abs(dest_height) / 8 < static_cast<long long>(m_SrcWidth) * |
| 315 m_SrcHeight / FXSYS_abs(dest_width)) { | 314 m_SrcHeight / FXSYS_abs(dest_width)) { |
| 316 flags = FXDIB_INTERPOL; | 315 flags = FXDIB_INTERPOL; |
| 317 } | 316 } |
| 318 m_Flags = flags; | 317 m_Flags = flags; |
| 319 } else { | 318 } else { |
| 320 m_Flags = FXDIB_NOSMOOTH; | 319 m_Flags = FXDIB_NOSMOOTH; |
| 321 if (flags & FXDIB_DOWNSAMPLE) { | 320 if (flags & FXDIB_DOWNSAMPLE) { |
| 322 m_Flags |= FXDIB_DOWNSAMPLE; | 321 m_Flags |= FXDIB_DOWNSAMPLE; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 } | 374 } |
| 376 } | 375 } |
| 377 | 376 |
| 378 CStretchEngine::~CStretchEngine() { | 377 CStretchEngine::~CStretchEngine() { |
| 379 FX_Free(m_pDestScanline); | 378 FX_Free(m_pDestScanline); |
| 380 FX_Free(m_pInterBuf); | 379 FX_Free(m_pInterBuf); |
| 381 FX_Free(m_pExtraAlphaBuf); | 380 FX_Free(m_pExtraAlphaBuf); |
| 382 FX_Free(m_pDestMaskScanline); | 381 FX_Free(m_pDestMaskScanline); |
| 383 } | 382 } |
| 384 | 383 |
| 385 FX_BOOL CStretchEngine::Continue(IFX_Pause* pPause) { | 384 bool CStretchEngine::Continue(IFX_Pause* pPause) { |
| 386 while (m_State == 1) { | 385 while (m_State == 1) { |
| 387 if (ContinueStretchHorz(pPause)) { | 386 if (ContinueStretchHorz(pPause)) { |
| 388 return TRUE; | 387 return true; |
| 389 } | 388 } |
| 390 m_State = 2; | 389 m_State = 2; |
| 391 StretchVert(); | 390 StretchVert(); |
| 392 } | 391 } |
| 393 return FALSE; | 392 return false; |
| 394 } | 393 } |
| 395 | 394 |
| 396 FX_BOOL CStretchEngine::StartStretchHorz() { | 395 bool CStretchEngine::StartStretchHorz() { |
| 397 if (m_DestWidth == 0 || m_InterPitch == 0 || !m_pDestScanline) | 396 if (m_DestWidth == 0 || m_InterPitch == 0 || !m_pDestScanline) |
| 398 return FALSE; | 397 return false; |
| 399 | 398 |
| 400 if (m_SrcClip.Height() == 0 || | 399 if (m_SrcClip.Height() == 0 || |
| 401 m_SrcClip.Height() > (1 << 29) / m_InterPitch) { | 400 m_SrcClip.Height() > (1 << 29) / m_InterPitch) { |
| 402 return FALSE; | 401 return false; |
| 403 } | 402 } |
| 404 | 403 |
| 405 m_pInterBuf = FX_TryAlloc(unsigned char, m_SrcClip.Height() * m_InterPitch); | 404 m_pInterBuf = FX_TryAlloc(unsigned char, m_SrcClip.Height() * m_InterPitch); |
| 406 if (!m_pInterBuf) | 405 if (!m_pInterBuf) |
| 407 return FALSE; | 406 return false; |
| 408 | 407 |
| 409 if (m_pSource && m_bHasAlpha && m_pSource->m_pAlphaMask) { | 408 if (m_pSource && m_bHasAlpha && m_pSource->m_pAlphaMask) { |
| 410 m_pExtraAlphaBuf = | 409 m_pExtraAlphaBuf = |
| 411 FX_Alloc2D(unsigned char, m_SrcClip.Height(), m_ExtraMaskPitch); | 410 FX_Alloc2D(unsigned char, m_SrcClip.Height(), m_ExtraMaskPitch); |
| 412 uint32_t size = (m_DestClip.Width() * 8 + 31) / 32 * 4; | 411 uint32_t size = (m_DestClip.Width() * 8 + 31) / 32 * 4; |
| 413 m_pDestMaskScanline = FX_TryAlloc(unsigned char, size); | 412 m_pDestMaskScanline = FX_TryAlloc(unsigned char, size); |
| 414 if (!m_pDestMaskScanline) | 413 if (!m_pDestMaskScanline) |
| 415 return FALSE; | 414 return false; |
| 416 } | 415 } |
| 417 bool ret = | 416 bool ret = |
| 418 m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, | 417 m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, |
| 419 m_SrcWidth, m_SrcClip.left, m_SrcClip.right, m_Flags); | 418 m_SrcWidth, m_SrcClip.left, m_SrcClip.right, m_Flags); |
| 420 if (!ret) | 419 if (!ret) |
| 421 return FALSE; | 420 return false; |
| 422 | 421 |
| 423 m_CurRow = m_SrcClip.top; | 422 m_CurRow = m_SrcClip.top; |
| 424 m_State = 1; | 423 m_State = 1; |
| 425 return TRUE; | 424 return true; |
| 426 } | 425 } |
| 427 | 426 |
| 428 FX_BOOL CStretchEngine::ContinueStretchHorz(IFX_Pause* pPause) { | 427 bool CStretchEngine::ContinueStretchHorz(IFX_Pause* pPause) { |
| 429 if (!m_DestWidth) | 428 if (!m_DestWidth) |
| 430 return FALSE; | 429 return false; |
| 431 | 430 |
| 432 if (m_pSource->SkipToScanline(m_CurRow, pPause)) | 431 if (m_pSource->SkipToScanline(m_CurRow, pPause)) |
| 433 return TRUE; | 432 return true; |
| 434 | 433 |
| 435 int Bpp = m_DestBpp / 8; | 434 int Bpp = m_DestBpp / 8; |
| 436 static const int kStrechPauseRows = 10; | 435 static const int kStrechPauseRows = 10; |
| 437 int rows_to_go = kStrechPauseRows; | 436 int rows_to_go = kStrechPauseRows; |
| 438 for (; m_CurRow < m_SrcClip.bottom; m_CurRow++) { | 437 for (; m_CurRow < m_SrcClip.bottom; m_CurRow++) { |
| 439 if (rows_to_go == 0) { | 438 if (rows_to_go == 0) { |
| 440 if (pPause && pPause->NeedToPauseNow()) | 439 if (pPause && pPause->NeedToPauseNow()) |
| 441 return TRUE; | 440 return true; |
| 442 | 441 |
| 443 rows_to_go = kStrechPauseRows; | 442 rows_to_go = kStrechPauseRows; |
| 444 } | 443 } |
| 445 | 444 |
| 446 const uint8_t* src_scan = m_pSource->GetScanline(m_CurRow); | 445 const uint8_t* src_scan = m_pSource->GetScanline(m_CurRow); |
| 447 uint8_t* dest_scan = | 446 uint8_t* dest_scan = |
| 448 m_pInterBuf + (m_CurRow - m_SrcClip.top) * m_InterPitch; | 447 m_pInterBuf + (m_CurRow - m_SrcClip.top) * m_InterPitch; |
| 449 const uint8_t* src_scan_mask = nullptr; | 448 const uint8_t* src_scan_mask = nullptr; |
| 450 uint8_t* dest_scan_mask = nullptr; | 449 uint8_t* dest_scan_mask = nullptr; |
| 451 if (m_pExtraAlphaBuf) { | 450 if (m_pExtraAlphaBuf) { |
| 452 src_scan_mask = m_pSource->m_pAlphaMask->GetScanline(m_CurRow); | 451 src_scan_mask = m_pSource->m_pAlphaMask->GetScanline(m_CurRow); |
| 453 dest_scan_mask = | 452 dest_scan_mask = |
| 454 m_pExtraAlphaBuf + (m_CurRow - m_SrcClip.top) * m_ExtraMaskPitch; | 453 m_pExtraAlphaBuf + (m_CurRow - m_SrcClip.top) * m_ExtraMaskPitch; |
| 455 } | 454 } |
| 456 switch (m_TransMethod) { | 455 switch (m_TransMethod) { |
| 457 case 1: | 456 case 1: |
| 458 case 2: { | 457 case 2: { |
| 459 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 458 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
| 460 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 459 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
| 461 int dest_a = 0; | 460 int dest_a = 0; |
| 462 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 461 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
| 463 j++) { | 462 j++) { |
| 464 int* pWeight = | 463 int* pWeight = |
| 465 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); | 464 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 466 if (!pWeight) | 465 if (!pWeight) |
| 467 return FALSE; | 466 return false; |
| 468 | 467 |
| 469 int pixel_weight = *pWeight; | 468 int pixel_weight = *pWeight; |
| 470 if (src_scan[j / 8] & (1 << (7 - j % 8))) { | 469 if (src_scan[j / 8] & (1 << (7 - j % 8))) { |
| 471 dest_a += pixel_weight * 255; | 470 dest_a += pixel_weight * 255; |
| 472 } | 471 } |
| 473 } | 472 } |
| 474 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { | 473 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { |
| 475 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; | 474 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; |
| 476 } | 475 } |
| 477 *dest_scan++ = (uint8_t)(dest_a >> 16); | 476 *dest_scan++ = (uint8_t)(dest_a >> 16); |
| 478 } | 477 } |
| 479 break; | 478 break; |
| 480 } | 479 } |
| 481 case 3: { | 480 case 3: { |
| 482 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 481 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
| 483 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 482 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
| 484 int dest_a = 0; | 483 int dest_a = 0; |
| 485 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 484 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
| 486 j++) { | 485 j++) { |
| 487 int* pWeight = | 486 int* pWeight = |
| 488 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); | 487 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 489 if (!pWeight) | 488 if (!pWeight) |
| 490 return FALSE; | 489 return false; |
| 491 | 490 |
| 492 int pixel_weight = *pWeight; | 491 int pixel_weight = *pWeight; |
| 493 dest_a += pixel_weight * src_scan[j]; | 492 dest_a += pixel_weight * src_scan[j]; |
| 494 } | 493 } |
| 495 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { | 494 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { |
| 496 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; | 495 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; |
| 497 } | 496 } |
| 498 *dest_scan++ = (uint8_t)(dest_a >> 16); | 497 *dest_scan++ = (uint8_t)(dest_a >> 16); |
| 499 } | 498 } |
| 500 break; | 499 break; |
| 501 } | 500 } |
| 502 case 4: { | 501 case 4: { |
| 503 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 502 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
| 504 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 503 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
| 505 int dest_a = 0, dest_r = 0; | 504 int dest_a = 0, dest_r = 0; |
| 506 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 505 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
| 507 j++) { | 506 j++) { |
| 508 int* pWeight = | 507 int* pWeight = |
| 509 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); | 508 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 510 if (!pWeight) | 509 if (!pWeight) |
| 511 return FALSE; | 510 return false; |
| 512 | 511 |
| 513 int pixel_weight = *pWeight; | 512 int pixel_weight = *pWeight; |
| 514 pixel_weight = pixel_weight * src_scan_mask[j] / 255; | 513 pixel_weight = pixel_weight * src_scan_mask[j] / 255; |
| 515 dest_r += pixel_weight * src_scan[j]; | 514 dest_r += pixel_weight * src_scan[j]; |
| 516 dest_a += pixel_weight; | 515 dest_a += pixel_weight; |
| 517 } | 516 } |
| 518 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { | 517 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { |
| 519 dest_r = dest_r < 0 ? 0 : dest_r > 16711680 ? 16711680 : dest_r; | 518 dest_r = dest_r < 0 ? 0 : dest_r > 16711680 ? 16711680 : dest_r; |
| 520 dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a; | 519 dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a; |
| 521 } | 520 } |
| 522 *dest_scan++ = (uint8_t)(dest_r >> 16); | 521 *dest_scan++ = (uint8_t)(dest_r >> 16); |
| 523 *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); | 522 *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); |
| 524 } | 523 } |
| 525 break; | 524 break; |
| 526 } | 525 } |
| 527 case 5: { | 526 case 5: { |
| 528 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 527 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
| 529 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 528 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
| 530 int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; | 529 int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; |
| 531 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 530 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
| 532 j++) { | 531 j++) { |
| 533 int* pWeight = | 532 int* pWeight = |
| 534 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); | 533 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 535 if (!pWeight) | 534 if (!pWeight) |
| 536 return FALSE; | 535 return false; |
| 537 | 536 |
| 538 int pixel_weight = *pWeight; | 537 int pixel_weight = *pWeight; |
| 539 unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; | 538 unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; |
| 540 if (m_DestFormat == FXDIB_Rgb) { | 539 if (m_DestFormat == FXDIB_Rgb) { |
| 541 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); | 540 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); |
| 542 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); | 541 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); |
| 543 dest_b_c += pixel_weight * (uint8_t)argb_cmyk; | 542 dest_b_c += pixel_weight * (uint8_t)argb_cmyk; |
| 544 } else { | 543 } else { |
| 545 dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); | 544 dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); |
| 546 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 16); | 545 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 16); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 563 } | 562 } |
| 564 case 6: { | 563 case 6: { |
| 565 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 564 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
| 566 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 565 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
| 567 int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; | 566 int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; |
| 568 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 567 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
| 569 j++) { | 568 j++) { |
| 570 int* pWeight = | 569 int* pWeight = |
| 571 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); | 570 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 572 if (!pWeight) | 571 if (!pWeight) |
| 573 return FALSE; | 572 return false; |
| 574 | 573 |
| 575 int pixel_weight = *pWeight; | 574 int pixel_weight = *pWeight; |
| 576 pixel_weight = pixel_weight * src_scan_mask[j] / 255; | 575 pixel_weight = pixel_weight * src_scan_mask[j] / 255; |
| 577 unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; | 576 unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; |
| 578 if (m_DestFormat == FXDIB_Rgba) { | 577 if (m_DestFormat == FXDIB_Rgba) { |
| 579 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); | 578 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); |
| 580 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); | 579 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); |
| 581 dest_b_c += pixel_weight * (uint8_t)argb_cmyk; | 580 dest_b_c += pixel_weight * (uint8_t)argb_cmyk; |
| 582 } else { | 581 } else { |
| 583 dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); | 582 dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 604 } | 603 } |
| 605 case 7: { | 604 case 7: { |
| 606 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 605 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
| 607 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 606 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
| 608 int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; | 607 int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; |
| 609 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 608 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
| 610 j++) { | 609 j++) { |
| 611 int* pWeight = | 610 int* pWeight = |
| 612 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); | 611 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 613 if (!pWeight) | 612 if (!pWeight) |
| 614 return FALSE; | 613 return false; |
| 615 | 614 |
| 616 int pixel_weight = *pWeight; | 615 int pixel_weight = *pWeight; |
| 617 const uint8_t* src_pixel = src_scan + j * Bpp; | 616 const uint8_t* src_pixel = src_scan + j * Bpp; |
| 618 dest_b_c += pixel_weight * (*src_pixel++); | 617 dest_b_c += pixel_weight * (*src_pixel++); |
| 619 dest_g_m += pixel_weight * (*src_pixel++); | 618 dest_g_m += pixel_weight * (*src_pixel++); |
| 620 dest_r_y += pixel_weight * (*src_pixel); | 619 dest_r_y += pixel_weight * (*src_pixel); |
| 621 } | 620 } |
| 622 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { | 621 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { |
| 623 dest_b_c = | 622 dest_b_c = |
| 624 dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; | 623 dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 636 } | 635 } |
| 637 case 8: { | 636 case 8: { |
| 638 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 637 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
| 639 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 638 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
| 640 int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; | 639 int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; |
| 641 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 640 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
| 642 j++) { | 641 j++) { |
| 643 int* pWeight = | 642 int* pWeight = |
| 644 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); | 643 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 645 if (!pWeight) | 644 if (!pWeight) |
| 646 return FALSE; | 645 return false; |
| 647 | 646 |
| 648 int pixel_weight = *pWeight; | 647 int pixel_weight = *pWeight; |
| 649 const uint8_t* src_pixel = src_scan + j * Bpp; | 648 const uint8_t* src_pixel = src_scan + j * Bpp; |
| 650 if (m_DestFormat == FXDIB_Argb) { | 649 if (m_DestFormat == FXDIB_Argb) { |
| 651 pixel_weight = pixel_weight * src_pixel[3] / 255; | 650 pixel_weight = pixel_weight * src_pixel[3] / 255; |
| 652 } else { | 651 } else { |
| 653 pixel_weight = pixel_weight * src_scan_mask[j] / 255; | 652 pixel_weight = pixel_weight * src_scan_mask[j] / 255; |
| 654 } | 653 } |
| 655 dest_b_c += pixel_weight * (*src_pixel++); | 654 dest_b_c += pixel_weight * (*src_pixel++); |
| 656 dest_g_m += pixel_weight * (*src_pixel++); | 655 dest_g_m += pixel_weight * (*src_pixel++); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 675 if (dest_scan_mask) { | 674 if (dest_scan_mask) { |
| 676 *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); | 675 *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); |
| 677 } | 676 } |
| 678 dest_scan += Bpp - 3; | 677 dest_scan += Bpp - 3; |
| 679 } | 678 } |
| 680 break; | 679 break; |
| 681 } | 680 } |
| 682 } | 681 } |
| 683 rows_to_go--; | 682 rows_to_go--; |
| 684 } | 683 } |
| 685 return FALSE; | 684 return false; |
| 686 } | 685 } |
| 687 | 686 |
| 688 void CStretchEngine::StretchVert() { | 687 void CStretchEngine::StretchVert() { |
| 689 if (m_DestHeight == 0) | 688 if (m_DestHeight == 0) |
| 690 return; | 689 return; |
| 691 | 690 |
| 692 CWeightTable table; | 691 CWeightTable table; |
| 693 bool ret = table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, | 692 bool ret = table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, |
| 694 m_SrcHeight, m_SrcClip.top, m_SrcClip.bottom, m_Flags); | 693 m_SrcHeight, m_SrcClip.top, m_SrcClip.bottom, m_Flags); |
| 695 if (!ret) | 694 if (!ret) |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 | 857 |
| 859 CFX_ImageStretcher::CFX_ImageStretcher(IFX_ScanlineComposer* pDest, | 858 CFX_ImageStretcher::CFX_ImageStretcher(IFX_ScanlineComposer* pDest, |
| 860 const CFX_DIBSource* pSource, | 859 const CFX_DIBSource* pSource, |
| 861 int dest_width, | 860 int dest_width, |
| 862 int dest_height, | 861 int dest_height, |
| 863 const FX_RECT& bitmap_rect, | 862 const FX_RECT& bitmap_rect, |
| 864 uint32_t flags) | 863 uint32_t flags) |
| 865 : m_pDest(pDest), | 864 : m_pDest(pDest), |
| 866 m_pSource(pSource), | 865 m_pSource(pSource), |
| 867 m_Flags(flags), | 866 m_Flags(flags), |
| 868 m_bFlipX(FALSE), | 867 m_bFlipX(false), |
| 869 m_bFlipY(FALSE), | 868 m_bFlipY(false), |
| 870 m_DestWidth(dest_width), | 869 m_DestWidth(dest_width), |
| 871 m_DestHeight(dest_height), | 870 m_DestHeight(dest_height), |
| 872 m_ClipRect(bitmap_rect), | 871 m_ClipRect(bitmap_rect), |
| 873 m_DestFormat(GetStretchedFormat(*pSource)), | 872 m_DestFormat(GetStretchedFormat(*pSource)), |
| 874 m_DestBPP(m_DestFormat & 0xff), | 873 m_DestBPP(m_DestFormat & 0xff), |
| 875 m_LineIndex(0) {} | 874 m_LineIndex(0) {} |
| 876 | 875 |
| 877 CFX_ImageStretcher::~CFX_ImageStretcher() { | 876 CFX_ImageStretcher::~CFX_ImageStretcher() { |
| 878 } | 877 } |
| 879 | 878 |
| 880 FX_BOOL CFX_ImageStretcher::Start() { | 879 bool CFX_ImageStretcher::Start() { |
| 881 if (m_DestWidth == 0 || m_DestHeight == 0) | 880 if (m_DestWidth == 0 || m_DestHeight == 0) |
| 882 return FALSE; | 881 return false; |
| 883 | 882 |
| 884 if (m_pSource->GetFormat() == FXDIB_1bppRgb && m_pSource->GetPalette()) { | 883 if (m_pSource->GetFormat() == FXDIB_1bppRgb && m_pSource->GetPalette()) { |
| 885 FX_ARGB pal[256]; | 884 FX_ARGB pal[256]; |
| 886 int a0, r0, g0, b0, a1, r1, g1, b1; | 885 int a0, r0, g0, b0, a1, r1, g1, b1; |
| 887 ArgbDecode(m_pSource->GetPaletteEntry(0), a0, r0, g0, b0); | 886 ArgbDecode(m_pSource->GetPaletteEntry(0), a0, r0, g0, b0); |
| 888 ArgbDecode(m_pSource->GetPaletteEntry(1), a1, r1, g1, b1); | 887 ArgbDecode(m_pSource->GetPaletteEntry(1), a1, r1, g1, b1); |
| 889 for (int i = 0; i < 256; i++) { | 888 for (int i = 0; i < 256; i++) { |
| 890 int a = a0 + (a1 - a0) * i / 255; | 889 int a = a0 + (a1 - a0) * i / 255; |
| 891 int r = r0 + (r1 - r0) * i / 255; | 890 int r = r0 + (r1 - r0) * i / 255; |
| 892 int g = g0 + (g1 - g0) * i / 255; | 891 int g = g0 + (g1 - g0) * i / 255; |
| 893 int b = b0 + (b1 - b0) * i / 255; | 892 int b = b0 + (b1 - b0) * i / 255; |
| 894 pal[i] = ArgbEncode(a, r, g, b); | 893 pal[i] = ArgbEncode(a, r, g, b); |
| 895 } | 894 } |
| 896 if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), m_DestFormat, | 895 if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), m_DestFormat, |
| 897 pal)) { | 896 pal)) { |
| 898 return FALSE; | 897 return false; |
| 899 } | 898 } |
| 900 } else if (m_pSource->GetFormat() == FXDIB_1bppCmyk && | 899 } else if (m_pSource->GetFormat() == FXDIB_1bppCmyk && |
| 901 m_pSource->GetPalette()) { | 900 m_pSource->GetPalette()) { |
| 902 FX_CMYK pal[256]; | 901 FX_CMYK pal[256]; |
| 903 int c0, m0, y0, k0, c1, m1, y1, k1; | 902 int c0, m0, y0, k0, c1, m1, y1, k1; |
| 904 CmykDecode(m_pSource->GetPaletteEntry(0), c0, m0, y0, k0); | 903 CmykDecode(m_pSource->GetPaletteEntry(0), c0, m0, y0, k0); |
| 905 CmykDecode(m_pSource->GetPaletteEntry(1), c1, m1, y1, k1); | 904 CmykDecode(m_pSource->GetPaletteEntry(1), c1, m1, y1, k1); |
| 906 for (int i = 0; i < 256; i++) { | 905 for (int i = 0; i < 256; i++) { |
| 907 int c = c0 + (c1 - c0) * i / 255; | 906 int c = c0 + (c1 - c0) * i / 255; |
| 908 int m = m0 + (m1 - m0) * i / 255; | 907 int m = m0 + (m1 - m0) * i / 255; |
| 909 int y = y0 + (y1 - y0) * i / 255; | 908 int y = y0 + (y1 - y0) * i / 255; |
| 910 int k = k0 + (k1 - k0) * i / 255; | 909 int k = k0 + (k1 - k0) * i / 255; |
| 911 pal[i] = CmykEncode(c, m, y, k); | 910 pal[i] = CmykEncode(c, m, y, k); |
| 912 } | 911 } |
| 913 if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), m_DestFormat, | 912 if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), m_DestFormat, |
| 914 pal)) { | 913 pal)) { |
| 915 return FALSE; | 914 return false; |
| 916 } | 915 } |
| 917 } else if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), | 916 } else if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), |
| 918 m_DestFormat, nullptr)) { | 917 m_DestFormat, nullptr)) { |
| 919 return FALSE; | 918 return false; |
| 920 } | 919 } |
| 921 | 920 |
| 922 if (m_Flags & FXDIB_DOWNSAMPLE) | 921 if (m_Flags & FXDIB_DOWNSAMPLE) |
| 923 return StartQuickStretch(); | 922 return StartQuickStretch(); |
| 924 return StartStretch(); | 923 return StartStretch(); |
| 925 } | 924 } |
| 926 | 925 |
| 927 FX_BOOL CFX_ImageStretcher::Continue(IFX_Pause* pPause) { | 926 bool CFX_ImageStretcher::Continue(IFX_Pause* pPause) { |
| 928 if (m_Flags & FXDIB_DOWNSAMPLE) | 927 if (m_Flags & FXDIB_DOWNSAMPLE) |
| 929 return ContinueQuickStretch(pPause); | 928 return ContinueQuickStretch(pPause); |
| 930 return ContinueStretch(pPause); | 929 return ContinueStretch(pPause); |
| 931 } | 930 } |
| 932 | 931 |
| 933 FX_BOOL CFX_ImageStretcher::StartStretch() { | 932 bool CFX_ImageStretcher::StartStretch() { |
| 934 m_pStretchEngine = pdfium::MakeUnique<CStretchEngine>( | 933 m_pStretchEngine = pdfium::MakeUnique<CStretchEngine>( |
| 935 m_pDest, m_DestFormat, m_DestWidth, m_DestHeight, m_ClipRect, m_pSource, | 934 m_pDest, m_DestFormat, m_DestWidth, m_DestHeight, m_ClipRect, m_pSource, |
| 936 m_Flags); | 935 m_Flags); |
| 937 m_pStretchEngine->StartStretchHorz(); | 936 m_pStretchEngine->StartStretchHorz(); |
| 938 if (SourceSizeWithinLimit(m_pSource->GetWidth(), m_pSource->GetHeight())) { | 937 if (SourceSizeWithinLimit(m_pSource->GetWidth(), m_pSource->GetHeight())) { |
| 939 m_pStretchEngine->Continue(nullptr); | 938 m_pStretchEngine->Continue(nullptr); |
| 940 return FALSE; | 939 return false; |
| 941 } | 940 } |
| 942 return TRUE; | 941 return true; |
| 943 } | 942 } |
| 944 | 943 |
| 945 FX_BOOL CFX_ImageStretcher::ContinueStretch(IFX_Pause* pPause) { | 944 bool CFX_ImageStretcher::ContinueStretch(IFX_Pause* pPause) { |
| 946 return m_pStretchEngine && m_pStretchEngine->Continue(pPause); | 945 return m_pStretchEngine && m_pStretchEngine->Continue(pPause); |
| 947 } | 946 } |
| 948 | 947 |
| 949 FX_BOOL CFX_ImageStretcher::StartQuickStretch() { | 948 bool CFX_ImageStretcher::StartQuickStretch() { |
| 950 if (m_DestWidth < 0) { | 949 if (m_DestWidth < 0) { |
| 951 m_bFlipX = TRUE; | 950 m_bFlipX = true; |
| 952 m_DestWidth = -m_DestWidth; | 951 m_DestWidth = -m_DestWidth; |
| 953 } | 952 } |
| 954 if (m_DestHeight < 0) { | 953 if (m_DestHeight < 0) { |
| 955 m_bFlipY = TRUE; | 954 m_bFlipY = true; |
| 956 m_DestHeight = -m_DestHeight; | 955 m_DestHeight = -m_DestHeight; |
| 957 } | 956 } |
| 958 uint32_t size = m_ClipRect.Width(); | 957 uint32_t size = m_ClipRect.Width(); |
| 959 if (size && m_DestBPP > (int)(INT_MAX / size)) { | 958 if (size && m_DestBPP > (int)(INT_MAX / size)) { |
| 960 return FALSE; | 959 return false; |
| 961 } | 960 } |
| 962 size *= m_DestBPP; | 961 size *= m_DestBPP; |
| 963 m_pScanline.reset(FX_Alloc(uint8_t, (size / 8 + 3) / 4 * 4)); | 962 m_pScanline.reset(FX_Alloc(uint8_t, (size / 8 + 3) / 4 * 4)); |
| 964 if (m_pSource->m_pAlphaMask) | 963 if (m_pSource->m_pAlphaMask) |
| 965 m_pMaskScanline.reset(FX_Alloc(uint8_t, (m_ClipRect.Width() + 3) / 4 * 4)); | 964 m_pMaskScanline.reset(FX_Alloc(uint8_t, (m_ClipRect.Width() + 3) / 4 * 4)); |
| 966 | 965 |
| 967 if (SourceSizeWithinLimit(m_pSource->GetWidth(), m_pSource->GetHeight())) { | 966 if (SourceSizeWithinLimit(m_pSource->GetWidth(), m_pSource->GetHeight())) { |
| 968 ContinueQuickStretch(nullptr); | 967 ContinueQuickStretch(nullptr); |
| 969 return FALSE; | 968 return false; |
| 970 } | 969 } |
| 971 return TRUE; | 970 return true; |
| 972 } | 971 } |
| 973 | 972 |
| 974 FX_BOOL CFX_ImageStretcher::ContinueQuickStretch(IFX_Pause* pPause) { | 973 bool CFX_ImageStretcher::ContinueQuickStretch(IFX_Pause* pPause) { |
| 975 if (!m_pScanline) | 974 if (!m_pScanline) |
| 976 return FALSE; | 975 return false; |
| 977 | 976 |
| 978 int result_width = m_ClipRect.Width(); | 977 int result_width = m_ClipRect.Width(); |
| 979 int result_height = m_ClipRect.Height(); | 978 int result_height = m_ClipRect.Height(); |
| 980 int src_height = m_pSource->GetHeight(); | 979 int src_height = m_pSource->GetHeight(); |
| 981 for (; m_LineIndex < result_height; m_LineIndex++) { | 980 for (; m_LineIndex < result_height; m_LineIndex++) { |
| 982 int dest_y; | 981 int dest_y; |
| 983 int src_y; | 982 int src_y; |
| 984 if (m_bFlipY) { | 983 if (m_bFlipY) { |
| 985 dest_y = result_height - m_LineIndex - 1; | 984 dest_y = result_height - m_LineIndex - 1; |
| 986 src_y = (m_DestHeight - (dest_y + m_ClipRect.top) - 1) * src_height / | 985 src_y = (m_DestHeight - (dest_y + m_ClipRect.top) - 1) * src_height / |
| 987 m_DestHeight; | 986 m_DestHeight; |
| 988 } else { | 987 } else { |
| 989 dest_y = m_LineIndex; | 988 dest_y = m_LineIndex; |
| 990 src_y = (dest_y + m_ClipRect.top) * src_height / m_DestHeight; | 989 src_y = (dest_y + m_ClipRect.top) * src_height / m_DestHeight; |
| 991 } | 990 } |
| 992 src_y = std::max(std::min(src_y, src_height - 1), 0); | 991 src_y = std::max(std::min(src_y, src_height - 1), 0); |
| 993 | 992 |
| 994 if (m_pSource->SkipToScanline(src_y, pPause)) | 993 if (m_pSource->SkipToScanline(src_y, pPause)) |
| 995 return TRUE; | 994 return true; |
| 996 | 995 |
| 997 m_pSource->DownSampleScanline(src_y, m_pScanline.get(), m_DestBPP, | 996 m_pSource->DownSampleScanline(src_y, m_pScanline.get(), m_DestBPP, |
| 998 m_DestWidth, m_bFlipX, m_ClipRect.left, | 997 m_DestWidth, m_bFlipX, m_ClipRect.left, |
| 999 result_width); | 998 result_width); |
| 1000 if (m_pMaskScanline) { | 999 if (m_pMaskScanline) { |
| 1001 m_pSource->m_pAlphaMask->DownSampleScanline( | 1000 m_pSource->m_pAlphaMask->DownSampleScanline( |
| 1002 src_y, m_pMaskScanline.get(), 1, m_DestWidth, m_bFlipX, | 1001 src_y, m_pMaskScanline.get(), 1, m_DestWidth, m_bFlipX, |
| 1003 m_ClipRect.left, result_width); | 1002 m_ClipRect.left, result_width); |
| 1004 } | 1003 } |
| 1005 m_pDest->ComposeScanline(dest_y, m_pScanline.get(), m_pMaskScanline.get()); | 1004 m_pDest->ComposeScanline(dest_y, m_pScanline.get(), m_pMaskScanline.get()); |
| 1006 } | 1005 } |
| 1007 return FALSE; | 1006 return false; |
| 1008 } | 1007 } |
| OLD | NEW |