diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/fpdfapi/render/cpdf_imagerenderer.cpp | 1 | ||||
-rw-r--r-- | core/fxge/agg/fx_agg_driver.cpp | 1 | ||||
-rw-r--r-- | core/fxge/dib/cfx_bitmapcomposer.cpp (renamed from core/fxge/dib/fx_dib_composite.cpp) | 5 | ||||
-rw-r--r-- | core/fxge/dib/cfx_bitmapcomposer.h | 81 | ||||
-rw-r--r-- | core/fxge/dib/cfx_bitmapstorer.cpp | 56 | ||||
-rw-r--r-- | core/fxge/dib/cfx_bitmapstorer.h | 41 | ||||
-rw-r--r-- | core/fxge/dib/cfx_dibsource.cpp | 2 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagerenderer.cpp | 1 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagerenderer.h | 1 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagestretcher.cpp | 184 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagestretcher.h | 55 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagetransformer.cpp | 1 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagetransformer.h | 1 | ||||
-rw-r--r-- | core/fxge/dib/fx_dib_engine.cpp | 172 | ||||
-rw-r--r-- | core/fxge/dib/fx_dib_main.cpp | 46 | ||||
-rw-r--r-- | core/fxge/fx_dib.h | 122 | ||||
-rw-r--r-- | core/fxge/skia/fx_skia_device.cpp | 2 |
17 files changed, 430 insertions, 342 deletions
diff --git a/core/fpdfapi/render/cpdf_imagerenderer.cpp b/core/fpdfapi/render/cpdf_imagerenderer.cpp index 46c35d9316..858b3c83c6 100644 --- a/core/fpdfapi/render/cpdf_imagerenderer.cpp +++ b/core/fpdfapi/render/cpdf_imagerenderer.cpp @@ -29,6 +29,7 @@ #include "core/fxcrt/fx_safe_types.h" #include "core/fxge/cfx_fxgedevice.h" #include "core/fxge/cfx_pathdata.h" +#include "core/fxge/dib/cfx_imagestretcher.h" #include "core/fxge/dib/cfx_imagetransformer.h" #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" diff --git a/core/fxge/agg/fx_agg_driver.cpp b/core/fxge/agg/fx_agg_driver.cpp index a82d3cf51c..8cada7cf64 100644 --- a/core/fxge/agg/fx_agg_driver.cpp +++ b/core/fxge/agg/fx_agg_driver.cpp @@ -15,6 +15,7 @@ #include "core/fxge/cfx_graphstatedata.h" #include "core/fxge/cfx_pathdata.h" #include "core/fxge/dib/cfx_imagerenderer.h" +#include "core/fxge/dib/cfx_imagestretcher.h" #include "core/fxge/ge/cfx_cliprgn.h" #include "third_party/agg23/agg_conv_dash.h" #include "third_party/agg23/agg_conv_stroke.h" diff --git a/core/fxge/dib/fx_dib_composite.cpp b/core/fxge/dib/cfx_bitmapcomposer.cpp index e7912e5a1b..7124ba9d46 100644 --- a/core/fxge/dib/fx_dib_composite.cpp +++ b/core/fxge/dib/cfx_bitmapcomposer.cpp @@ -1,13 +1,14 @@ -// Copyright 2014 PDFium Authors. All rights reserved. +// Copyright 2017 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com -#include <algorithm> +#include "core/fxge/dib/cfx_bitmapcomposer.h" #include "core/fxcodec/fx_codec.h" #include "core/fxge/cfx_gemodule.h" +#include "core/fxge/dib/cfx_dibitmap.h" #include "core/fxge/ge/cfx_cliprgn.h" CFX_BitmapComposer::CFX_BitmapComposer() { diff --git a/core/fxge/dib/cfx_bitmapcomposer.h b/core/fxge/dib/cfx_bitmapcomposer.h new file mode 100644 index 0000000000..eeca80ed55 --- /dev/null +++ b/core/fxge/dib/cfx_bitmapcomposer.h @@ -0,0 +1,81 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FXGE_DIB_CFX_BITMAPCOMPOSER_H_ +#define CORE_FXGE_DIB_CFX_BITMAPCOMPOSER_H_ + +#include "core/fxcrt/cfx_retain_ptr.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxge/dib/cfx_scanlinecompositor.h" +#include "core/fxge/fx_dib.h" + +class CFX_ClipRgn; +class CFX_DIBitmap; + +class CFX_BitmapComposer : public IFX_ScanlineComposer { + public: + CFX_BitmapComposer(); + ~CFX_BitmapComposer() override; + + void Compose(const CFX_RetainPtr<CFX_DIBitmap>& pDest, + const CFX_ClipRgn* pClipRgn, + int bitmap_alpha, + uint32_t mask_color, + FX_RECT& dest_rect, + bool bVertical, + bool bFlipX, + bool bFlipY, + bool bRgbByteOrder = false, + int alpha_flag = 0, + void* pIccTransform = nullptr, + int blend_type = FXDIB_BLEND_NORMAL); + + // IFX_ScanlineComposer + bool SetInfo(int width, + int height, + FXDIB_Format src_format, + uint32_t* pSrcPalette) override; + + void ComposeScanline(int line, + const uint8_t* scanline, + const uint8_t* scan_extra_alpha) override; + + private: + void DoCompose(uint8_t* dest_scan, + const uint8_t* src_scan, + int dest_width, + const uint8_t* clip_scan, + const uint8_t* src_extra_alpha = nullptr, + uint8_t* dst_extra_alpha = nullptr); + void ComposeScanlineV(int line, + const uint8_t* scanline, + const uint8_t* scan_extra_alpha = nullptr); + + CFX_RetainPtr<CFX_DIBitmap> m_pBitmap; + const CFX_ClipRgn* m_pClipRgn; + FXDIB_Format m_SrcFormat; + int m_DestLeft; + int m_DestTop; + int m_DestWidth; + int m_DestHeight; + int m_BitmapAlpha; + uint32_t m_MaskColor; + CFX_RetainPtr<CFX_DIBitmap> m_pClipMask; + CFX_ScanlineCompositor m_Compositor; + bool m_bVertical; + bool m_bFlipX; + bool m_bFlipY; + int m_AlphaFlag; + void* m_pIccTransform; + bool m_bRgbByteOrder; + int m_BlendType; + uint8_t* m_pScanlineV; + uint8_t* m_pClipScanV; + uint8_t* m_pAddClipScan; + uint8_t* m_pScanlineAlphaV; +}; + +#endif // CORE_FXGE_DIB_CFX_BITMAPCOMPOSER_H_ diff --git a/core/fxge/dib/cfx_bitmapstorer.cpp b/core/fxge/dib/cfx_bitmapstorer.cpp new file mode 100644 index 0000000000..ac876b16b7 --- /dev/null +++ b/core/fxge/dib/cfx_bitmapstorer.cpp @@ -0,0 +1,56 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fxge/dib/cfx_bitmapstorer.h" + +#include <utility> + +#include "core/fxge/dib/dib_int.h" +#include "third_party/base/ptr_util.h" + +CFX_BitmapStorer::CFX_BitmapStorer() {} + +CFX_BitmapStorer::~CFX_BitmapStorer() {} + +CFX_RetainPtr<CFX_DIBitmap> CFX_BitmapStorer::Detach() { + return std::move(m_pBitmap); +} + +void CFX_BitmapStorer::Replace(CFX_RetainPtr<CFX_DIBitmap>&& pBitmap) { + m_pBitmap = std::move(pBitmap); +} + +void CFX_BitmapStorer::ComposeScanline(int line, + const uint8_t* scanline, + const uint8_t* scan_extra_alpha) { + uint8_t* dest_buf = const_cast<uint8_t*>(m_pBitmap->GetScanline(line)); + uint8_t* dest_alpha_buf = + m_pBitmap->m_pAlphaMask + ? const_cast<uint8_t*>(m_pBitmap->m_pAlphaMask->GetScanline(line)) + : nullptr; + if (dest_buf) + FXSYS_memcpy(dest_buf, scanline, m_pBitmap->GetPitch()); + + if (dest_alpha_buf) { + FXSYS_memcpy(dest_alpha_buf, scan_extra_alpha, + m_pBitmap->m_pAlphaMask->GetPitch()); + } +} + +bool CFX_BitmapStorer::SetInfo(int width, + int height, + FXDIB_Format src_format, + uint32_t* pSrcPalette) { + auto pBitmap = pdfium::MakeRetain<CFX_DIBitmap>(); + if (!pBitmap->Create(width, height, src_format)) + return false; + + if (pSrcPalette) + pBitmap->SetPalette(pSrcPalette); + + m_pBitmap = std::move(pBitmap); + return true; +} diff --git a/core/fxge/dib/cfx_bitmapstorer.h b/core/fxge/dib/cfx_bitmapstorer.h new file mode 100644 index 0000000000..478d9f7f64 --- /dev/null +++ b/core/fxge/dib/cfx_bitmapstorer.h @@ -0,0 +1,41 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FXGE_DIB_CFX_BITMAPSTORER_H_ +#define CORE_FXGE_DIB_CFX_BITMAPSTORER_H_ + +#include <memory> +#include <vector> + +#include "core/fxcrt/cfx_retain_ptr.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxge/dib/cfx_dibitmap.h" +#include "core/fxge/fx_dib.h" +#include "third_party/base/stl_util.h" + +class CFX_BitmapStorer : public IFX_ScanlineComposer { + public: + CFX_BitmapStorer(); + ~CFX_BitmapStorer() override; + + // IFX_ScanlineComposer + void ComposeScanline(int line, + const uint8_t* scanline, + const uint8_t* scan_extra_alpha) override; + bool SetInfo(int width, + int height, + FXDIB_Format src_format, + uint32_t* pSrcPalette) override; + + CFX_RetainPtr<CFX_DIBitmap> GetBitmap() { return m_pBitmap; } + CFX_RetainPtr<CFX_DIBitmap> Detach(); + void Replace(CFX_RetainPtr<CFX_DIBitmap>&& pBitmap); + + private: + CFX_RetainPtr<CFX_DIBitmap> m_pBitmap; +}; + +#endif // CORE_FXGE_DIB_CFX_BITMAPSTORER_H_ diff --git a/core/fxge/dib/cfx_dibsource.cpp b/core/fxge/dib/cfx_dibsource.cpp index f1ea4adfa9..4cdedd1051 100644 --- a/core/fxge/dib/cfx_dibsource.cpp +++ b/core/fxge/dib/cfx_dibsource.cpp @@ -10,7 +10,9 @@ #include <memory> #include <utility> +#include "core/fxge/dib/cfx_bitmapstorer.h" #include "core/fxge/dib/cfx_dibitmap.h" +#include "core/fxge/dib/cfx_imagestretcher.h" #include "core/fxge/dib/cfx_imagetransformer.h" #include "core/fxge/ge/cfx_cliprgn.h" #include "third_party/base/ptr_util.h" diff --git a/core/fxge/dib/cfx_imagerenderer.cpp b/core/fxge/dib/cfx_imagerenderer.cpp index 9eea474352..776ba92775 100644 --- a/core/fxge/dib/cfx_imagerenderer.cpp +++ b/core/fxge/dib/cfx_imagerenderer.cpp @@ -8,6 +8,7 @@ #include <memory> +#include "core/fxge/dib/cfx_imagestretcher.h" #include "core/fxge/dib/cfx_imagetransformer.h" #include "core/fxge/dib/dib_int.h" #include "core/fxge/ge/cfx_cliprgn.h" diff --git a/core/fxge/dib/cfx_imagerenderer.h b/core/fxge/dib/cfx_imagerenderer.h index 7e78bfe752..db8bd08638 100644 --- a/core/fxge/dib/cfx_imagerenderer.h +++ b/core/fxge/dib/cfx_imagerenderer.h @@ -11,6 +11,7 @@ #include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_coordinates.h" +#include "core/fxge/dib/cfx_bitmapcomposer.h" #include "core/fxge/dib/cfx_dibitmap.h" #include "core/fxge/dib/cfx_dibsource.h" #include "core/fxge/fx_dib.h" diff --git a/core/fxge/dib/cfx_imagestretcher.cpp b/core/fxge/dib/cfx_imagestretcher.cpp new file mode 100644 index 0000000000..799b44432f --- /dev/null +++ b/core/fxge/dib/cfx_imagestretcher.cpp @@ -0,0 +1,184 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fxge/dib/cfx_imagestretcher.h" + +#include <climits> + +#include "core/fxge/dib/dib_int.h" +#include "core/fxge/fx_dib.h" +#include "third_party/base/ptr_util.h" + +namespace { + +bool SourceSizeWithinLimit(int width, int height) { + const int kMaxProgressiveStretchPixels = 1000000; + return !height || width < kMaxProgressiveStretchPixels / height; +} + +FXDIB_Format GetStretchedFormat(const CFX_DIBSource& src) { + FXDIB_Format format = src.GetFormat(); + if (format == FXDIB_1bppMask) + return FXDIB_8bppMask; + if (format == FXDIB_1bppRgb) + return FXDIB_8bppRgb; + if (format == FXDIB_8bppRgb && src.GetPalette()) + return FXDIB_Rgb; + return format; +} + +} // namespace + +CFX_ImageStretcher::CFX_ImageStretcher( + IFX_ScanlineComposer* pDest, + const CFX_RetainPtr<CFX_DIBSource>& pSource, + int dest_width, + int dest_height, + const FX_RECT& bitmap_rect, + uint32_t flags) + : m_pDest(pDest), + m_pSource(pSource), + m_Flags(flags), + m_bFlipX(false), + m_bFlipY(false), + m_DestWidth(dest_width), + m_DestHeight(dest_height), + m_ClipRect(bitmap_rect), + m_DestFormat(GetStretchedFormat(*pSource)), + m_DestBPP(m_DestFormat & 0xff), + m_LineIndex(0) {} + +CFX_ImageStretcher::~CFX_ImageStretcher() {} + +bool CFX_ImageStretcher::Start() { + if (m_DestWidth == 0 || m_DestHeight == 0) + return false; + + if (m_pSource->GetFormat() == FXDIB_1bppRgb && m_pSource->GetPalette()) { + FX_ARGB pal[256]; + int a0, r0, g0, b0, a1, r1, g1, b1; + ArgbDecode(m_pSource->GetPaletteEntry(0), a0, r0, g0, b0); + ArgbDecode(m_pSource->GetPaletteEntry(1), a1, r1, g1, b1); + for (int i = 0; i < 256; i++) { + int a = a0 + (a1 - a0) * i / 255; + int r = r0 + (r1 - r0) * i / 255; + int g = g0 + (g1 - g0) * i / 255; + int b = b0 + (b1 - b0) * i / 255; + pal[i] = ArgbEncode(a, r, g, b); + } + if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), m_DestFormat, + pal)) { + return false; + } + } else if (m_pSource->GetFormat() == FXDIB_1bppCmyk && + m_pSource->GetPalette()) { + FX_CMYK pal[256]; + int c0, m0, y0, k0, c1, m1, y1, k1; + CmykDecode(m_pSource->GetPaletteEntry(0), c0, m0, y0, k0); + CmykDecode(m_pSource->GetPaletteEntry(1), c1, m1, y1, k1); + for (int i = 0; i < 256; i++) { + int c = c0 + (c1 - c0) * i / 255; + int m = m0 + (m1 - m0) * i / 255; + int y = y0 + (y1 - y0) * i / 255; + int k = k0 + (k1 - k0) * i / 255; + pal[i] = CmykEncode(c, m, y, k); + } + if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), m_DestFormat, + pal)) { + return false; + } + } else if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), + m_DestFormat, nullptr)) { + return false; + } + + if (m_Flags & FXDIB_DOWNSAMPLE) + return StartQuickStretch(); + return StartStretch(); +} + +bool CFX_ImageStretcher::Continue(IFX_Pause* pPause) { + if (m_Flags & FXDIB_DOWNSAMPLE) + return ContinueQuickStretch(pPause); + return ContinueStretch(pPause); +} + +bool CFX_ImageStretcher::StartStretch() { + m_pStretchEngine = pdfium::MakeUnique<CStretchEngine>( + m_pDest, m_DestFormat, m_DestWidth, m_DestHeight, m_ClipRect, m_pSource, + m_Flags); + m_pStretchEngine->StartStretchHorz(); + if (SourceSizeWithinLimit(m_pSource->GetWidth(), m_pSource->GetHeight())) { + m_pStretchEngine->Continue(nullptr); + return false; + } + return true; +} + +bool CFX_ImageStretcher::ContinueStretch(IFX_Pause* pPause) { + return m_pStretchEngine && m_pStretchEngine->Continue(pPause); +} + +bool CFX_ImageStretcher::StartQuickStretch() { + if (m_DestWidth < 0) { + m_bFlipX = true; + m_DestWidth = -m_DestWidth; + } + if (m_DestHeight < 0) { + m_bFlipY = true; + m_DestHeight = -m_DestHeight; + } + uint32_t size = m_ClipRect.Width(); + if (size && m_DestBPP > static_cast<int>(INT_MAX / size)) + return false; + + size *= m_DestBPP; + m_pScanline.reset(FX_Alloc(uint8_t, (size / 8 + 3) / 4 * 4)); + if (m_pSource->m_pAlphaMask) + m_pMaskScanline.reset(FX_Alloc(uint8_t, (m_ClipRect.Width() + 3) / 4 * 4)); + + if (SourceSizeWithinLimit(m_pSource->GetWidth(), m_pSource->GetHeight())) { + ContinueQuickStretch(nullptr); + return false; + } + return true; +} + +bool CFX_ImageStretcher::ContinueQuickStretch(IFX_Pause* pPause) { + if (!m_pScanline) + return false; + + int result_width = m_ClipRect.Width(); + int result_height = m_ClipRect.Height(); + int src_height = m_pSource->GetHeight(); + for (; m_LineIndex < result_height; m_LineIndex++) { + int dest_y; + int src_y; + if (m_bFlipY) { + dest_y = result_height - m_LineIndex - 1; + src_y = (m_DestHeight - (dest_y + m_ClipRect.top) - 1) * src_height / + m_DestHeight; + } else { + dest_y = m_LineIndex; + src_y = (dest_y + m_ClipRect.top) * src_height / m_DestHeight; + } + src_y = pdfium::clamp(src_y, 0, src_height - 1); + + if (m_pSource->SkipToScanline(src_y, pPause)) + return true; + + m_pSource->DownSampleScanline(src_y, m_pScanline.get(), m_DestBPP, + m_DestWidth, m_bFlipX, m_ClipRect.left, + result_width); + if (m_pMaskScanline) { + m_pSource->m_pAlphaMask->DownSampleScanline( + src_y, m_pMaskScanline.get(), 1, m_DestWidth, m_bFlipX, + m_ClipRect.left, result_width); + } + m_pDest->ComposeScanline(dest_y, m_pScanline.get(), m_pMaskScanline.get()); + } + return false; +} diff --git a/core/fxge/dib/cfx_imagestretcher.h b/core/fxge/dib/cfx_imagestretcher.h new file mode 100644 index 0000000000..785ef9b6cc --- /dev/null +++ b/core/fxge/dib/cfx_imagestretcher.h @@ -0,0 +1,55 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FXGE_DIB_CFX_IMAGESTRETCHER_H_ +#define CORE_FXGE_DIB_CFX_IMAGESTRETCHER_H_ + +#include <memory> + +#include "core/fxcrt/cfx_retain_ptr.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxge/fx_dib.h" + +class CFX_DIBSource; + +class CFX_ImageStretcher { + public: + CFX_ImageStretcher(IFX_ScanlineComposer* pDest, + const CFX_RetainPtr<CFX_DIBSource>& pSource, + int dest_width, + int dest_height, + const FX_RECT& bitmap_rect, + uint32_t flags); + ~CFX_ImageStretcher(); + + bool Start(); + bool Continue(IFX_Pause* pPause); + + CFX_RetainPtr<CFX_DIBSource> source() { return m_pSource; } + + private: + bool StartQuickStretch(); + bool StartStretch(); + bool ContinueQuickStretch(IFX_Pause* pPause); + bool ContinueStretch(IFX_Pause* pPause); + + IFX_ScanlineComposer* const m_pDest; + CFX_RetainPtr<CFX_DIBSource> m_pSource; + std::unique_ptr<CStretchEngine> m_pStretchEngine; + std::unique_ptr<uint8_t, FxFreeDeleter> m_pScanline; + std::unique_ptr<uint8_t, FxFreeDeleter> m_pMaskScanline; + const uint32_t m_Flags; + bool m_bFlipX; + bool m_bFlipY; + int m_DestWidth; + int m_DestHeight; + FX_RECT m_ClipRect; + const FXDIB_Format m_DestFormat; + const int m_DestBPP; + int m_LineIndex; +}; + +#endif // CORE_FXGE_DIB_CFX_IMAGESTRETCHER_H_ diff --git a/core/fxge/dib/cfx_imagetransformer.cpp b/core/fxge/dib/cfx_imagetransformer.cpp index 7a519adebf..d8159aabb5 100644 --- a/core/fxge/dib/cfx_imagetransformer.cpp +++ b/core/fxge/dib/cfx_imagetransformer.cpp @@ -9,6 +9,7 @@ #include <memory> #include <utility> +#include "core/fxge/dib/cfx_imagestretcher.h" #include "core/fxge/fx_dib.h" #include "third_party/base/ptr_util.h" diff --git a/core/fxge/dib/cfx_imagetransformer.h b/core/fxge/dib/cfx_imagetransformer.h index 0183a2fab1..1354c9099a 100644 --- a/core/fxge/dib/cfx_imagetransformer.h +++ b/core/fxge/dib/cfx_imagetransformer.h @@ -11,6 +11,7 @@ #include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_coordinates.h" +#include "core/fxge/dib/cfx_bitmapstorer.h" #include "core/fxge/dib/cfx_dibitmap.h" #include "core/fxge/dib/cfx_dibsource.h" #include "core/fxge/dib/dib_int.h" diff --git a/core/fxge/dib/fx_dib_engine.cpp b/core/fxge/dib/fx_dib_engine.cpp index 7aa710b795..d304a56600 100644 --- a/core/fxge/dib/fx_dib_engine.cpp +++ b/core/fxge/dib/fx_dib_engine.cpp @@ -13,26 +13,6 @@ #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" -namespace { - -bool SourceSizeWithinLimit(int width, int height) { - const int kMaxProgressiveStretchPixels = 1000000; - return !height || width < kMaxProgressiveStretchPixels / height; -} - -FXDIB_Format GetStretchedFormat(const CFX_DIBSource& src) { - FXDIB_Format format = src.GetFormat(); - if (format == FXDIB_1bppMask) - return FXDIB_8bppMask; - if (format == FXDIB_1bppRgb) - return FXDIB_8bppRgb; - if (format == FXDIB_8bppRgb && src.GetPalette()) - return FXDIB_Rgb; - return format; -} - -} // namespace - CWeightTable::CWeightTable() : m_DestMin(0), m_ItemSize(0), @@ -851,155 +831,3 @@ void CStretchEngine::StretchVert() { m_pDestMaskScanline); } } - -CFX_ImageStretcher::CFX_ImageStretcher( - IFX_ScanlineComposer* pDest, - const CFX_RetainPtr<CFX_DIBSource>& pSource, - int dest_width, - int dest_height, - const FX_RECT& bitmap_rect, - uint32_t flags) - : m_pDest(pDest), - m_pSource(pSource), - m_Flags(flags), - m_bFlipX(false), - m_bFlipY(false), - m_DestWidth(dest_width), - m_DestHeight(dest_height), - m_ClipRect(bitmap_rect), - m_DestFormat(GetStretchedFormat(*pSource)), - m_DestBPP(m_DestFormat & 0xff), - m_LineIndex(0) {} - -CFX_ImageStretcher::~CFX_ImageStretcher() { -} - -bool CFX_ImageStretcher::Start() { - if (m_DestWidth == 0 || m_DestHeight == 0) - return false; - - if (m_pSource->GetFormat() == FXDIB_1bppRgb && m_pSource->GetPalette()) { - FX_ARGB pal[256]; - int a0, r0, g0, b0, a1, r1, g1, b1; - ArgbDecode(m_pSource->GetPaletteEntry(0), a0, r0, g0, b0); - ArgbDecode(m_pSource->GetPaletteEntry(1), a1, r1, g1, b1); - for (int i = 0; i < 256; i++) { - int a = a0 + (a1 - a0) * i / 255; - int r = r0 + (r1 - r0) * i / 255; - int g = g0 + (g1 - g0) * i / 255; - int b = b0 + (b1 - b0) * i / 255; - pal[i] = ArgbEncode(a, r, g, b); - } - if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), m_DestFormat, - pal)) { - return false; - } - } else if (m_pSource->GetFormat() == FXDIB_1bppCmyk && - m_pSource->GetPalette()) { - FX_CMYK pal[256]; - int c0, m0, y0, k0, c1, m1, y1, k1; - CmykDecode(m_pSource->GetPaletteEntry(0), c0, m0, y0, k0); - CmykDecode(m_pSource->GetPaletteEntry(1), c1, m1, y1, k1); - for (int i = 0; i < 256; i++) { - int c = c0 + (c1 - c0) * i / 255; - int m = m0 + (m1 - m0) * i / 255; - int y = y0 + (y1 - y0) * i / 255; - int k = k0 + (k1 - k0) * i / 255; - pal[i] = CmykEncode(c, m, y, k); - } - if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), m_DestFormat, - pal)) { - return false; - } - } else if (!m_pDest->SetInfo(m_ClipRect.Width(), m_ClipRect.Height(), - m_DestFormat, nullptr)) { - return false; - } - - if (m_Flags & FXDIB_DOWNSAMPLE) - return StartQuickStretch(); - return StartStretch(); -} - -bool CFX_ImageStretcher::Continue(IFX_Pause* pPause) { - if (m_Flags & FXDIB_DOWNSAMPLE) - return ContinueQuickStretch(pPause); - return ContinueStretch(pPause); -} - -bool CFX_ImageStretcher::StartStretch() { - m_pStretchEngine = pdfium::MakeUnique<CStretchEngine>( - m_pDest, m_DestFormat, m_DestWidth, m_DestHeight, m_ClipRect, m_pSource, - m_Flags); - m_pStretchEngine->StartStretchHorz(); - if (SourceSizeWithinLimit(m_pSource->GetWidth(), m_pSource->GetHeight())) { - m_pStretchEngine->Continue(nullptr); - return false; - } - return true; -} - -bool CFX_ImageStretcher::ContinueStretch(IFX_Pause* pPause) { - return m_pStretchEngine && m_pStretchEngine->Continue(pPause); -} - -bool CFX_ImageStretcher::StartQuickStretch() { - if (m_DestWidth < 0) { - m_bFlipX = true; - m_DestWidth = -m_DestWidth; - } - if (m_DestHeight < 0) { - m_bFlipY = true; - m_DestHeight = -m_DestHeight; - } - uint32_t size = m_ClipRect.Width(); - if (size && m_DestBPP > (int)(INT_MAX / size)) { - return false; - } - size *= m_DestBPP; - m_pScanline.reset(FX_Alloc(uint8_t, (size / 8 + 3) / 4 * 4)); - if (m_pSource->m_pAlphaMask) - m_pMaskScanline.reset(FX_Alloc(uint8_t, (m_ClipRect.Width() + 3) / 4 * 4)); - - if (SourceSizeWithinLimit(m_pSource->GetWidth(), m_pSource->GetHeight())) { - ContinueQuickStretch(nullptr); - return false; - } - return true; -} - -bool CFX_ImageStretcher::ContinueQuickStretch(IFX_Pause* pPause) { - if (!m_pScanline) - return false; - - int result_width = m_ClipRect.Width(); - int result_height = m_ClipRect.Height(); - int src_height = m_pSource->GetHeight(); - for (; m_LineIndex < result_height; m_LineIndex++) { - int dest_y; - int src_y; - if (m_bFlipY) { - dest_y = result_height - m_LineIndex - 1; - src_y = (m_DestHeight - (dest_y + m_ClipRect.top) - 1) * src_height / - m_DestHeight; - } else { - dest_y = m_LineIndex; - src_y = (dest_y + m_ClipRect.top) * src_height / m_DestHeight; - } - src_y = pdfium::clamp(src_y, 0, src_height - 1); - - if (m_pSource->SkipToScanline(src_y, pPause)) - return true; - - m_pSource->DownSampleScanline(src_y, m_pScanline.get(), m_DestBPP, - m_DestWidth, m_bFlipX, m_ClipRect.left, - result_width); - if (m_pMaskScanline) { - m_pSource->m_pAlphaMask->DownSampleScanline( - src_y, m_pMaskScanline.get(), 1, m_DestWidth, m_bFlipX, - m_ClipRect.left, result_width); - } - m_pDest->ComposeScanline(dest_y, m_pScanline.get(), m_pMaskScanline.get()); - } - return false; -} diff --git a/core/fxge/dib/fx_dib_main.cpp b/core/fxge/dib/fx_dib_main.cpp index f3716c36b1..1214cc1f16 100644 --- a/core/fxge/dib/fx_dib_main.cpp +++ b/core/fxge/dib/fx_dib_main.cpp @@ -96,49 +96,3 @@ uint32_t ArgbEncode(int a, FX_COLORREF rgb) { return FXARGB_MAKE(a, FXSYS_GetRValue(rgb), FXSYS_GetGValue(rgb), FXSYS_GetBValue(rgb)); } - -CFX_BitmapStorer::CFX_BitmapStorer() { -} - -CFX_BitmapStorer::~CFX_BitmapStorer() { -} - -CFX_RetainPtr<CFX_DIBitmap> CFX_BitmapStorer::Detach() { - return std::move(m_pBitmap); -} - -void CFX_BitmapStorer::Replace(CFX_RetainPtr<CFX_DIBitmap>&& pBitmap) { - m_pBitmap = std::move(pBitmap); -} - -void CFX_BitmapStorer::ComposeScanline(int line, - const uint8_t* scanline, - const uint8_t* scan_extra_alpha) { - uint8_t* dest_buf = const_cast<uint8_t*>(m_pBitmap->GetScanline(line)); - uint8_t* dest_alpha_buf = - m_pBitmap->m_pAlphaMask - ? const_cast<uint8_t*>(m_pBitmap->m_pAlphaMask->GetScanline(line)) - : nullptr; - if (dest_buf) - FXSYS_memcpy(dest_buf, scanline, m_pBitmap->GetPitch()); - - if (dest_alpha_buf) { - FXSYS_memcpy(dest_alpha_buf, scan_extra_alpha, - m_pBitmap->m_pAlphaMask->GetPitch()); - } -} - -bool CFX_BitmapStorer::SetInfo(int width, - int height, - FXDIB_Format src_format, - uint32_t* pSrcPalette) { - auto pBitmap = pdfium::MakeRetain<CFX_DIBitmap>(); - if (!pBitmap->Create(width, height, src_format)) - return false; - - if (pSrcPalette) - pBitmap->SetPalette(pSrcPalette); - - m_pBitmap = std::move(pBitmap); - return true; -} diff --git a/core/fxge/fx_dib.h b/core/fxge/fx_dib.h index 3be4fc6e3b..e0018f32f5 100644 --- a/core/fxge/fx_dib.h +++ b/core/fxge/fx_dib.h @@ -132,126 +132,4 @@ class IFX_ScanlineComposer { uint32_t* pSrcPalette) = 0; }; -class CFX_BitmapComposer : public IFX_ScanlineComposer { - public: - CFX_BitmapComposer(); - ~CFX_BitmapComposer() override; - - void Compose(const CFX_RetainPtr<CFX_DIBitmap>& pDest, - const CFX_ClipRgn* pClipRgn, - int bitmap_alpha, - uint32_t mask_color, - FX_RECT& dest_rect, - bool bVertical, - bool bFlipX, - bool bFlipY, - bool bRgbByteOrder = false, - int alpha_flag = 0, - void* pIccTransform = nullptr, - int blend_type = FXDIB_BLEND_NORMAL); - - // IFX_ScanlineComposer - bool SetInfo(int width, - int height, - FXDIB_Format src_format, - uint32_t* pSrcPalette) override; - - void ComposeScanline(int line, - const uint8_t* scanline, - const uint8_t* scan_extra_alpha) override; - - protected: - void DoCompose(uint8_t* dest_scan, - const uint8_t* src_scan, - int dest_width, - const uint8_t* clip_scan, - const uint8_t* src_extra_alpha = nullptr, - uint8_t* dst_extra_alpha = nullptr); - void ComposeScanlineV(int line, - const uint8_t* scanline, - const uint8_t* scan_extra_alpha = nullptr); - - CFX_RetainPtr<CFX_DIBitmap> m_pBitmap; - const CFX_ClipRgn* m_pClipRgn; - FXDIB_Format m_SrcFormat; - int m_DestLeft; - int m_DestTop; - int m_DestWidth; - int m_DestHeight; - int m_BitmapAlpha; - uint32_t m_MaskColor; - CFX_RetainPtr<CFX_DIBitmap> m_pClipMask; - CFX_ScanlineCompositor m_Compositor; - bool m_bVertical; - bool m_bFlipX; - bool m_bFlipY; - int m_AlphaFlag; - void* m_pIccTransform; - bool m_bRgbByteOrder; - int m_BlendType; - uint8_t* m_pScanlineV; - uint8_t* m_pClipScanV; - uint8_t* m_pAddClipScan; - uint8_t* m_pScanlineAlphaV; -}; - -class CFX_BitmapStorer : public IFX_ScanlineComposer { - public: - CFX_BitmapStorer(); - ~CFX_BitmapStorer() override; - - // IFX_ScanlineComposer - void ComposeScanline(int line, - const uint8_t* scanline, - const uint8_t* scan_extra_alpha) override; - bool SetInfo(int width, - int height, - FXDIB_Format src_format, - uint32_t* pSrcPalette) override; - - CFX_RetainPtr<CFX_DIBitmap> GetBitmap() { return m_pBitmap; } - CFX_RetainPtr<CFX_DIBitmap> Detach(); - void Replace(CFX_RetainPtr<CFX_DIBitmap>&& pBitmap); - - private: - CFX_RetainPtr<CFX_DIBitmap> m_pBitmap; -}; - -class CFX_ImageStretcher { - public: - CFX_ImageStretcher(IFX_ScanlineComposer* pDest, - const CFX_RetainPtr<CFX_DIBSource>& pSource, - int dest_width, - int dest_height, - const FX_RECT& bitmap_rect, - uint32_t flags); - ~CFX_ImageStretcher(); - - bool Start(); - bool Continue(IFX_Pause* pPause); - - CFX_RetainPtr<CFX_DIBSource> source() { return m_pSource; } - - private: - bool StartQuickStretch(); - bool StartStretch(); - bool ContinueQuickStretch(IFX_Pause* pPause); - bool ContinueStretch(IFX_Pause* pPause); - - IFX_ScanlineComposer* const m_pDest; - CFX_RetainPtr<CFX_DIBSource> m_pSource; - std::unique_ptr<CStretchEngine> m_pStretchEngine; - std::unique_ptr<uint8_t, FxFreeDeleter> m_pScanline; - std::unique_ptr<uint8_t, FxFreeDeleter> m_pMaskScanline; - const uint32_t m_Flags; - bool m_bFlipX; - bool m_bFlipY; - int m_DestWidth; - int m_DestHeight; - FX_RECT m_ClipRect; - const FXDIB_Format m_DestFormat; - const int m_DestBPP; - int m_LineIndex; -}; - #endif // CORE_FXGE_FX_DIB_H_ diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp index e9dc982ce1..1dc8ab2c7b 100644 --- a/core/fxge/skia/fx_skia_device.cpp +++ b/core/fxge/skia/fx_skia_device.cpp @@ -19,7 +19,9 @@ #include "core/fxge/cfx_graphstatedata.h" #include "core/fxge/cfx_pathdata.h" #include "core/fxge/cfx_renderdevice.h" +#include "core/fxge/dib/cfx_bitmapcomposer.h" #include "core/fxge/dib/cfx_imagerenderer.h" +#include "core/fxge/dib/cfx_imagestretcher.h" #include "core/fxge/skia/fx_skia_device.h" #ifdef _SKIA_SUPPORT_PATHS_ |