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 "core/include/fxge/fx_dib.h" | 9 #include "core/include/fxge/fx_dib.h" |
10 #include "core/include/fxge/fx_ge.h" | 10 #include "core/include/fxge/fx_ge.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1; | 29 int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1; |
30 m_ItemSize = | 30 m_ItemSize = |
31 sizeof(int) * 2 + | 31 sizeof(int) * 2 + |
32 (int)(sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + ext_size)); | 32 (int)(sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + ext_size)); |
33 m_DestMin = dest_min; | 33 m_DestMin = dest_min; |
34 if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize) { | 34 if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize) { |
35 return; | 35 return; |
36 } | 36 } |
37 m_pWeightTables = | 37 m_pWeightTables = |
38 FX_TryAlloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4); | 38 FX_TryAlloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4); |
39 if (m_pWeightTables == NULL) { | 39 if (!m_pWeightTables) { |
40 return; | 40 return; |
41 } | 41 } |
42 if ((flags & FXDIB_NOSMOOTH) != 0 || FXSYS_fabs((FX_FLOAT)scale) < 1.0f) { | 42 if ((flags & FXDIB_NOSMOOTH) != 0 || FXSYS_fabs((FX_FLOAT)scale) < 1.0f) { |
43 for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { | 43 for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { |
44 PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); | 44 PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); |
45 double src_pos = dest_pixel * scale + scale / 2 + base; | 45 double src_pos = dest_pixel * scale + scale / 2 + base; |
46 if (flags & FXDIB_INTERPOL) { | 46 if (flags & FXDIB_INTERPOL) { |
47 pixel_weights.m_SrcStart = | 47 pixel_weights.m_SrcStart = |
48 (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); | 48 (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); |
49 pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); | 49 pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 if (size && m_DestBpp > (int)(INT_MAX / size)) { | 235 if (size && m_DestBpp > (int)(INT_MAX / size)) { |
236 return; | 236 return; |
237 } | 237 } |
238 size *= m_DestBpp; | 238 size *= m_DestBpp; |
239 if (size > INT_MAX - 31) { | 239 if (size > INT_MAX - 31) { |
240 return; | 240 return; |
241 } | 241 } |
242 size += 31; | 242 size += 31; |
243 size = size / 32 * 4; | 243 size = size / 32 * 4; |
244 m_pDestScanline = FX_TryAlloc(uint8_t, size); | 244 m_pDestScanline = FX_TryAlloc(uint8_t, size); |
245 if (m_pDestScanline == NULL) { | 245 if (!m_pDestScanline) { |
246 return; | 246 return; |
247 } | 247 } |
248 if (dest_format == FXDIB_Rgb32) { | 248 if (dest_format == FXDIB_Rgb32) { |
249 FXSYS_memset(m_pDestScanline, 255, size); | 249 FXSYS_memset(m_pDestScanline, 255, size); |
250 } | 250 } |
251 m_InterPitch = (m_DestClip.Width() * m_DestBpp + 31) / 32 * 4; | 251 m_InterPitch = (m_DestClip.Width() * m_DestBpp + 31) / 32 * 4; |
252 m_ExtraMaskPitch = (m_DestClip.Width() * 8 + 31) / 32 * 4; | 252 m_ExtraMaskPitch = (m_DestClip.Width() * 8 + 31) / 32 * 4; |
253 m_pInterBuf = NULL; | 253 m_pInterBuf = NULL; |
254 m_pSource = pSrcBitmap; | 254 m_pSource = pSrcBitmap; |
255 m_SrcWidth = pSrcBitmap->GetWidth(); | 255 m_SrcWidth = pSrcBitmap->GetWidth(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 } | 332 } |
333 return FALSE; | 333 return FALSE; |
334 } | 334 } |
335 CStretchEngine::~CStretchEngine() { | 335 CStretchEngine::~CStretchEngine() { |
336 FX_Free(m_pDestScanline); | 336 FX_Free(m_pDestScanline); |
337 FX_Free(m_pInterBuf); | 337 FX_Free(m_pInterBuf); |
338 FX_Free(m_pExtraAlphaBuf); | 338 FX_Free(m_pExtraAlphaBuf); |
339 FX_Free(m_pDestMaskScanline); | 339 FX_Free(m_pDestMaskScanline); |
340 } | 340 } |
341 FX_BOOL CStretchEngine::StartStretchHorz() { | 341 FX_BOOL CStretchEngine::StartStretchHorz() { |
342 if (m_DestWidth == 0 || m_pDestScanline == NULL || | 342 if (m_DestWidth == 0 || !m_pDestScanline || |
343 m_SrcClip.Height() > (int)((1U << 29) / m_InterPitch) || | 343 m_SrcClip.Height() > (int)((1U << 29) / m_InterPitch) || |
344 m_SrcClip.Height() == 0) { | 344 m_SrcClip.Height() == 0) { |
345 return FALSE; | 345 return FALSE; |
346 } | 346 } |
347 m_pInterBuf = FX_TryAlloc(unsigned char, m_SrcClip.Height() * m_InterPitch); | 347 m_pInterBuf = FX_TryAlloc(unsigned char, m_SrcClip.Height() * m_InterPitch); |
348 if (m_pInterBuf == NULL) { | 348 if (!m_pInterBuf) { |
349 return FALSE; | 349 return FALSE; |
350 } | 350 } |
351 if (m_pSource && m_bHasAlpha && m_pSource->m_pAlphaMask) { | 351 if (m_pSource && m_bHasAlpha && m_pSource->m_pAlphaMask) { |
352 m_pExtraAlphaBuf = | 352 m_pExtraAlphaBuf = |
353 FX_Alloc2D(unsigned char, m_SrcClip.Height(), m_ExtraMaskPitch); | 353 FX_Alloc2D(unsigned char, m_SrcClip.Height(), m_ExtraMaskPitch); |
354 FX_DWORD size = (m_DestClip.Width() * 8 + 31) / 32 * 4; | 354 FX_DWORD size = (m_DestClip.Width() * 8 + 31) / 32 * 4; |
355 m_pDestMaskScanline = FX_TryAlloc(unsigned char, size); | 355 m_pDestMaskScanline = FX_TryAlloc(unsigned char, size); |
356 if (!m_pDestMaskScanline) { | 356 if (!m_pDestMaskScanline) { |
357 return FALSE; | 357 return FALSE; |
358 } | 358 } |
359 } | 359 } |
360 m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, m_SrcWidth, | 360 m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, m_SrcWidth, |
361 m_SrcClip.left, m_SrcClip.right, m_Flags); | 361 m_SrcClip.left, m_SrcClip.right, m_Flags); |
362 if (m_WeightTable.m_pWeightTables == NULL) { | 362 if (!m_WeightTable.m_pWeightTables) { |
363 return FALSE; | 363 return FALSE; |
364 } | 364 } |
365 m_CurRow = m_SrcClip.top; | 365 m_CurRow = m_SrcClip.top; |
366 m_State = 1; | 366 m_State = 1; |
367 return TRUE; | 367 return TRUE; |
368 } | 368 } |
369 #define FX_STRECH_PAUSE_ROWS 10 | 369 #define FX_STRECH_PAUSE_ROWS 10 |
370 FX_BOOL CStretchEngine::ContinueStretchHorz(IFX_Pause* pPause) { | 370 FX_BOOL CStretchEngine::ContinueStretchHorz(IFX_Pause* pPause) { |
371 if (!m_DestWidth) { | 371 if (!m_DestWidth) { |
372 return 0; | 372 return 0; |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 } | 596 } |
597 return FALSE; | 597 return FALSE; |
598 } | 598 } |
599 void CStretchEngine::StretchVert() { | 599 void CStretchEngine::StretchVert() { |
600 if (m_DestHeight == 0) { | 600 if (m_DestHeight == 0) { |
601 return; | 601 return; |
602 } | 602 } |
603 CWeightTable table; | 603 CWeightTable table; |
604 table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, m_SrcHeight, | 604 table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, m_SrcHeight, |
605 m_SrcClip.top, m_SrcClip.bottom, m_Flags); | 605 m_SrcClip.top, m_SrcClip.bottom, m_Flags); |
606 if (table.m_pWeightTables == NULL) { | 606 if (!table.m_pWeightTables) { |
607 return; | 607 return; |
608 } | 608 } |
609 int DestBpp = m_DestBpp / 8; | 609 int DestBpp = m_DestBpp / 8; |
610 for (int row = m_DestClip.top; row < m_DestClip.bottom; row++) { | 610 for (int row = m_DestClip.top; row < m_DestClip.bottom; row++) { |
611 unsigned char* dest_scan = m_pDestScanline; | 611 unsigned char* dest_scan = m_pDestScanline; |
612 unsigned char* dest_sacn_mask = m_pDestMaskScanline; | 612 unsigned char* dest_sacn_mask = m_pDestMaskScanline; |
613 PixelWeight* pPixelWeights = table.GetPixelWeight(row); | 613 PixelWeight* pPixelWeights = table.GetPixelWeight(row); |
614 switch (m_TransMethod) { | 614 switch (m_TransMethod) { |
615 case 1: | 615 case 1: |
616 case 2: | 616 case 2: |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 m_ClipRect, m_pSource, m_Flags); | 842 m_ClipRect, m_pSource, m_Flags); |
843 m_pStretchEngine->StartStretchHorz(); | 843 m_pStretchEngine->StartStretchHorz(); |
844 if (m_pSource->GetWidth() * m_pSource->GetHeight() < | 844 if (m_pSource->GetWidth() * m_pSource->GetHeight() < |
845 MAX_PROGRESSIVE_STRETCH_PIXELS) { | 845 MAX_PROGRESSIVE_STRETCH_PIXELS) { |
846 m_pStretchEngine->Continue(NULL); | 846 m_pStretchEngine->Continue(NULL); |
847 return FALSE; | 847 return FALSE; |
848 } | 848 } |
849 return TRUE; | 849 return TRUE; |
850 } | 850 } |
851 FX_BOOL CFX_ImageStretcher::ContinueStretch(IFX_Pause* pPause) { | 851 FX_BOOL CFX_ImageStretcher::ContinueStretch(IFX_Pause* pPause) { |
852 if (m_pStretchEngine == NULL) { | 852 return m_pStretchEngine && m_pStretchEngine->Continue(pPause); |
853 return FALSE; | |
854 } | |
855 return m_pStretchEngine->Continue(pPause); | |
856 } | 853 } |
857 FX_BOOL CFX_ImageStretcher::StartQuickStretch() { | 854 FX_BOOL CFX_ImageStretcher::StartQuickStretch() { |
858 m_bFlipX = FALSE; | 855 m_bFlipX = FALSE; |
859 m_bFlipY = FALSE; | 856 m_bFlipY = FALSE; |
860 if (m_DestWidth < 0) { | 857 if (m_DestWidth < 0) { |
861 m_bFlipX = TRUE; | 858 m_bFlipX = TRUE; |
862 m_DestWidth = -m_DestWidth; | 859 m_DestWidth = -m_DestWidth; |
863 } | 860 } |
864 if (m_DestHeight < 0) { | 861 if (m_DestHeight < 0) { |
865 m_bFlipY = TRUE; | 862 m_bFlipY = TRUE; |
(...skipping 10 matching lines...) Expand all Loading... |
876 m_pMaskScanline = FX_Alloc(uint8_t, (m_ClipRect.Width() + 3) / 4 * 4); | 873 m_pMaskScanline = FX_Alloc(uint8_t, (m_ClipRect.Width() + 3) / 4 * 4); |
877 } | 874 } |
878 if (m_pSource->GetWidth() * m_pSource->GetHeight() < | 875 if (m_pSource->GetWidth() * m_pSource->GetHeight() < |
879 MAX_PROGRESSIVE_STRETCH_PIXELS) { | 876 MAX_PROGRESSIVE_STRETCH_PIXELS) { |
880 ContinueQuickStretch(NULL); | 877 ContinueQuickStretch(NULL); |
881 return FALSE; | 878 return FALSE; |
882 } | 879 } |
883 return TRUE; | 880 return TRUE; |
884 } | 881 } |
885 FX_BOOL CFX_ImageStretcher::ContinueQuickStretch(IFX_Pause* pPause) { | 882 FX_BOOL CFX_ImageStretcher::ContinueQuickStretch(IFX_Pause* pPause) { |
886 if (m_pScanline == NULL) { | 883 if (!m_pScanline) { |
887 return FALSE; | 884 return FALSE; |
888 } | 885 } |
889 int result_width = m_ClipRect.Width(), result_height = m_ClipRect.Height(); | 886 int result_width = m_ClipRect.Width(), result_height = m_ClipRect.Height(); |
890 int src_height = m_pSource->GetHeight(); | 887 int src_height = m_pSource->GetHeight(); |
891 for (; m_LineIndex < result_height; m_LineIndex++) { | 888 for (; m_LineIndex < result_height; m_LineIndex++) { |
892 int dest_y, src_y; | 889 int dest_y, src_y; |
893 if (m_bFlipY) { | 890 if (m_bFlipY) { |
894 dest_y = result_height - m_LineIndex - 1; | 891 dest_y = result_height - m_LineIndex - 1; |
895 src_y = (m_DestHeight - (dest_y + m_ClipRect.top) - 1) * src_height / | 892 src_y = (m_DestHeight - (dest_y + m_ClipRect.top) - 1) * src_height / |
896 m_DestHeight; | 893 m_DestHeight; |
(...skipping 14 matching lines...) Expand all Loading... |
911 m_bFlipX, m_ClipRect.left, result_width); | 908 m_bFlipX, m_ClipRect.left, result_width); |
912 if (m_pMaskScanline) { | 909 if (m_pMaskScanline) { |
913 m_pSource->m_pAlphaMask->DownSampleScanline( | 910 m_pSource->m_pAlphaMask->DownSampleScanline( |
914 src_y, m_pMaskScanline, 1, m_DestWidth, m_bFlipX, m_ClipRect.left, | 911 src_y, m_pMaskScanline, 1, m_DestWidth, m_bFlipX, m_ClipRect.left, |
915 result_width); | 912 result_width); |
916 } | 913 } |
917 m_pDest->ComposeScanline(dest_y, m_pScanline, m_pMaskScanline); | 914 m_pDest->ComposeScanline(dest_y, m_pScanline, m_pMaskScanline); |
918 } | 915 } |
919 return FALSE; | 916 return FALSE; |
920 } | 917 } |
OLD | NEW |