diff options
author | Lei Zhang <thestig@chromium.org> | 2018-10-26 22:52:48 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-10-26 22:52:48 +0000 |
commit | 5883300439287ab46559231ce8aed11e92bbc97c (patch) | |
tree | 2c3499da9df5a2c4e2fb9d13f99bde13b7bebb42 /core/fxge/dib | |
parent | 9590dee526c514d87dc1f47569d1136ffcf539ad (diff) | |
download | pdfium-5883300439287ab46559231ce8aed11e92bbc97c.tar.xz |
Replace int flags with struct FXDIB_ResampleOptions.
Using bit values in an int may not be reliable, since different parts of
the code can interpret the bits differently. e.g. FXDIB_DOWNSAMPLE and
RENDER_FORCE_DOWNSAMPLE are defined in different places, but can be used
interchangeably because they just happen to have the same value. It
works but is rather fragile.
Instead, use a struct of bools to explicitly define what different bits
mean. Remove FXDIB_DOWNSAMPLE and friends.
Change-Id: I9cf0c8f94d1ed27edf8dba22b0ab0ee67f2722cc
Reviewed-on: https://pdfium-review.googlesource.com/c/44650
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Diffstat (limited to 'core/fxge/dib')
-rw-r--r-- | core/fxge/dib/cfx_dibbase.cpp | 14 | ||||
-rw-r--r-- | core/fxge/dib/cfx_dibbase.h | 2 | ||||
-rw-r--r-- | core/fxge/dib/cfx_dibitmap.cpp | 10 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagerenderer.cpp | 9 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagerenderer.h | 2 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagestretcher.cpp | 11 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagestretcher.h | 4 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagetransformer.cpp | 21 | ||||
-rw-r--r-- | core/fxge/dib/cfx_imagetransformer.h | 10 | ||||
-rw-r--r-- | core/fxge/dib/cstretchengine.cpp | 62 | ||||
-rw-r--r-- | core/fxge/dib/cstretchengine.h | 6 | ||||
-rw-r--r-- | core/fxge/dib/cstretchengine_unittest.cpp | 9 | ||||
-rw-r--r-- | core/fxge/dib/fx_dib_main.cpp | 23 |
13 files changed, 112 insertions, 71 deletions
diff --git a/core/fxge/dib/cfx_dibbase.cpp b/core/fxge/dib/cfx_dibbase.cpp index 7fc9bef9cb..1dcbcf9e17 100644 --- a/core/fxge/dib/cfx_dibbase.cpp +++ b/core/fxge/dib/cfx_dibbase.cpp @@ -1171,17 +1171,19 @@ RetainPtr<CFX_DIBitmap> CFX_DIBBase::TransformTo(const CFX_Matrix& mtDest, int* result_left, int* result_top) { RetainPtr<CFX_DIBBase> holder(this); - CFX_ImageTransformer transformer(holder, mtDest, 0, nullptr); + CFX_ImageTransformer transformer(holder, mtDest, FXDIB_ResampleOptions(), + nullptr); transformer.Continue(nullptr); *result_left = transformer.result().left; *result_top = transformer.result().top; return transformer.DetachBitmap(); } -RetainPtr<CFX_DIBitmap> CFX_DIBBase::StretchTo(int dest_width, - int dest_height, - uint32_t flags, - const FX_RECT* pClip) { +RetainPtr<CFX_DIBitmap> CFX_DIBBase::StretchTo( + int dest_width, + int dest_height, + const FXDIB_ResampleOptions& options, + const FX_RECT* pClip) { RetainPtr<CFX_DIBBase> holder(this); FX_RECT clip_rect(0, 0, abs(dest_width), abs(dest_height)); if (pClip) @@ -1195,7 +1197,7 @@ RetainPtr<CFX_DIBitmap> CFX_DIBBase::StretchTo(int dest_width, CFX_BitmapStorer storer; CFX_ImageStretcher stretcher(&storer, holder, dest_width, dest_height, - clip_rect, flags); + clip_rect, options); if (stretcher.Start()) stretcher.Continue(nullptr); diff --git a/core/fxge/dib/cfx_dibbase.h b/core/fxge/dib/cfx_dibbase.h index 81b0691563..23d65a3cda 100644 --- a/core/fxge/dib/cfx_dibbase.h +++ b/core/fxge/dib/cfx_dibbase.h @@ -80,7 +80,7 @@ class CFX_DIBBase : public Retainable { RetainPtr<CFX_DIBitmap> CloneConvert(FXDIB_Format format); RetainPtr<CFX_DIBitmap> StretchTo(int dest_width, int dest_height, - uint32_t flags, + const FXDIB_ResampleOptions& options, const FX_RECT* pClip); RetainPtr<CFX_DIBitmap> TransformTo(const CFX_Matrix& mtDest, int* left, diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp index dcf5fdc7ab..011270494c 100644 --- a/core/fxge/dib/cfx_dibitmap.cpp +++ b/core/fxge/dib/cfx_dibitmap.cpp @@ -329,7 +329,8 @@ bool CFX_DIBitmap::LoadChannelFromAlpha( if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_Height) { if (pAlphaMask) { - pAlphaMask = pAlphaMask->StretchTo(m_Width, m_Height, 0, nullptr); + pAlphaMask = pAlphaMask->StretchTo(m_Width, m_Height, + FXDIB_ResampleOptions(), nullptr); if (!pAlphaMask) return false; } @@ -338,8 +339,8 @@ bool CFX_DIBitmap::LoadChannelFromAlpha( srcOffset = 0; } else if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_Height) { - RetainPtr<CFX_DIBitmap> pSrcMatched = - pSrcClone->StretchTo(m_Width, m_Height, 0, nullptr); + RetainPtr<CFX_DIBitmap> pSrcMatched = pSrcClone->StretchTo( + m_Width, m_Height, FXDIB_ResampleOptions(), nullptr); if (!pSrcMatched) return false; @@ -437,7 +438,8 @@ bool CFX_DIBitmap::MultiplyAlpha(const RetainPtr<CFX_DIBBase>& pSrcBitmap) { RetainPtr<CFX_DIBitmap> pSrcClone = pSrcBitmap.As<CFX_DIBitmap>(); if (pSrcBitmap->GetWidth() != m_Width || pSrcBitmap->GetHeight() != m_Height) { - pSrcClone = pSrcBitmap->StretchTo(m_Width, m_Height, 0, nullptr); + pSrcClone = pSrcBitmap->StretchTo(m_Width, m_Height, + FXDIB_ResampleOptions(), nullptr); if (!pSrcClone) return false; } diff --git a/core/fxge/dib/cfx_imagerenderer.cpp b/core/fxge/dib/cfx_imagerenderer.cpp index 6eadb05997..408bec1a09 100644 --- a/core/fxge/dib/cfx_imagerenderer.cpp +++ b/core/fxge/dib/cfx_imagerenderer.cpp @@ -20,7 +20,7 @@ CFX_ImageRenderer::CFX_ImageRenderer(const RetainPtr<CFX_DIBitmap>& pDevice, int bitmap_alpha, uint32_t mask_color, const CFX_Matrix& matrix, - uint32_t dib_flags, + const FXDIB_ResampleOptions& options, bool bRgbByteOrder) : m_pDevice(pDevice), m_pClipRgn(pClipRgn), @@ -50,15 +50,14 @@ CFX_ImageRenderer::CFX_ImageRenderer(const RetainPtr<CFX_DIBitmap>& pDevice, true, m_Matrix.c > 0, m_Matrix.b < 0, m_bRgbByteOrder, 0, BlendMode::kNormal); m_Stretcher = pdfium::MakeUnique<CFX_ImageStretcher>( - &m_Composer, pSource, dest_height, dest_width, bitmap_clip, - dib_flags); + &m_Composer, pSource, dest_height, dest_width, bitmap_clip, options); if (m_Stretcher->Start()) m_Status = 1; return; } m_Status = 2; m_pTransformer = pdfium::MakeUnique<CFX_ImageTransformer>( - pSource, m_Matrix, dib_flags, &m_ClipBox); + pSource, m_Matrix, options, &m_ClipBox); return; } @@ -80,7 +79,7 @@ CFX_ImageRenderer::CFX_ImageRenderer(const RetainPtr<CFX_DIBitmap>& pDevice, BlendMode::kNormal); m_Status = 1; m_Stretcher = pdfium::MakeUnique<CFX_ImageStretcher>( - &m_Composer, pSource, dest_width, dest_height, bitmap_clip, dib_flags); + &m_Composer, pSource, dest_width, dest_height, bitmap_clip, options); m_Stretcher->Start(); } diff --git a/core/fxge/dib/cfx_imagerenderer.h b/core/fxge/dib/cfx_imagerenderer.h index 01eec3a947..d97c01843f 100644 --- a/core/fxge/dib/cfx_imagerenderer.h +++ b/core/fxge/dib/cfx_imagerenderer.h @@ -28,7 +28,7 @@ class CFX_ImageRenderer { int bitmap_alpha, uint32_t mask_color, const CFX_Matrix& matrix, - uint32_t dib_flags, + const FXDIB_ResampleOptions& options, bool bRgbByteOrder); ~CFX_ImageRenderer(); diff --git a/core/fxge/dib/cfx_imagestretcher.cpp b/core/fxge/dib/cfx_imagestretcher.cpp index 763c1db5d2..54d14f7d9d 100644 --- a/core/fxge/dib/cfx_imagestretcher.cpp +++ b/core/fxge/dib/cfx_imagestretcher.cpp @@ -48,10 +48,10 @@ CFX_ImageStretcher::CFX_ImageStretcher(ScanlineComposerIface* pDest, int dest_width, int dest_height, const FX_RECT& bitmap_rect, - uint32_t flags) + const FXDIB_ResampleOptions& options) : m_pDest(pDest), m_pSource(pSource), - m_Flags(flags), + m_ResampleOptions(options), m_bFlipX(false), m_bFlipY(false), m_DestWidth(dest_width), @@ -119,14 +119,13 @@ bool CFX_ImageStretcher::Start() { return false; } - if (m_Flags & FXDIB_DOWNSAMPLE) + if (m_ResampleOptions.bInterpolateDownsample) return StartQuickStretch(); - return StartStretch(); } bool CFX_ImageStretcher::Continue(PauseIndicatorIface* pPause) { - if (m_Flags & FXDIB_DOWNSAMPLE) + if (m_ResampleOptions.bInterpolateDownsample) return ContinueQuickStretch(pPause); return ContinueStretch(pPause); } @@ -138,7 +137,7 @@ RetainPtr<CFX_DIBBase> CFX_ImageStretcher::source() { bool CFX_ImageStretcher::StartStretch() { m_pStretchEngine = pdfium::MakeUnique<CStretchEngine>( m_pDest.Get(), m_DestFormat, m_DestWidth, m_DestHeight, m_ClipRect, - m_pSource, m_Flags); + m_pSource, m_ResampleOptions); m_pStretchEngine->StartStretchHorz(); if (SourceSizeWithinLimit(m_pSource->GetWidth(), m_pSource->GetHeight())) { m_pStretchEngine->Continue(nullptr); diff --git a/core/fxge/dib/cfx_imagestretcher.h b/core/fxge/dib/cfx_imagestretcher.h index 9f4e44b0d0..45544cbfbc 100644 --- a/core/fxge/dib/cfx_imagestretcher.h +++ b/core/fxge/dib/cfx_imagestretcher.h @@ -27,7 +27,7 @@ class CFX_ImageStretcher { int dest_width, int dest_height, const FX_RECT& bitmap_rect, - uint32_t flags); + const FXDIB_ResampleOptions& options); ~CFX_ImageStretcher(); bool Start(); @@ -46,7 +46,7 @@ class CFX_ImageStretcher { 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; + const FXDIB_ResampleOptions m_ResampleOptions; bool m_bFlipX; bool m_bFlipY; int m_DestWidth; diff --git a/core/fxge/dib/cfx_imagetransformer.cpp b/core/fxge/dib/cfx_imagetransformer.cpp index 29d22f4f77..9bbbaa644c 100644 --- a/core/fxge/dib/cfx_imagetransformer.cpp +++ b/core/fxge/dib/cfx_imagetransformer.cpp @@ -204,9 +204,9 @@ class CFX_BilinearMatrix final : public CPDF_FixedMatrix { CFX_ImageTransformer::CFX_ImageTransformer(const RetainPtr<CFX_DIBBase>& pSrc, const CFX_Matrix& matrix, - uint32_t flags, + const FXDIB_ResampleOptions& options, const FX_RECT* pClip) - : m_pSrc(pSrc), m_matrix(matrix), m_Flags(flags) { + : m_pSrc(pSrc), m_matrix(matrix), m_ResampleOptions(options) { FX_RECT result_rect = m_matrix.GetUnitRect().GetClosestRect(); FX_RECT result_clip = result_rect; if (pClip) @@ -225,7 +225,8 @@ CFX_ImageTransformer::CFX_ImageTransformer(const RetainPtr<CFX_DIBBase>& pSrc, result_clip = FXDIB_SwapClipBox(result_clip, dest_width, dest_height, m_matrix.c > 0, m_matrix.b < 0); m_Stretcher = pdfium::MakeUnique<CFX_ImageStretcher>( - &m_Storer, m_pSrc, dest_height, dest_width, result_clip, m_Flags); + &m_Storer, m_pSrc, dest_height, dest_width, result_clip, + m_ResampleOptions); m_Stretcher->Start(); m_Status = 1; return; @@ -237,7 +238,8 @@ CFX_ImageTransformer::CFX_ImageTransformer(const RetainPtr<CFX_DIBBase>& pSrc, : -floor(m_matrix.d)); result_clip.Offset(-result_rect.left, -result_rect.top); m_Stretcher = pdfium::MakeUnique<CFX_ImageStretcher>( - &m_Storer, m_pSrc, dest_width, dest_height, result_clip, m_Flags); + &m_Storer, m_pSrc, dest_width, dest_height, result_clip, + m_ResampleOptions); m_Stretcher->Start(); m_Status = 2; return; @@ -257,7 +259,8 @@ CFX_ImageTransformer::CFX_ImageTransformer(const RetainPtr<CFX_DIBBase>& pSrc, m_dest2stretch.TransformRect(CFX_FloatRect(result_clip)).GetOuterRect(); m_StretchClip.Intersect(0, 0, stretch_width, stretch_height); m_Stretcher = pdfium::MakeUnique<CFX_ImageStretcher>( - &m_Storer, m_pSrc, stretch_width, stretch_height, m_StretchClip, m_Flags); + &m_Storer, m_pSrc, stretch_width, stretch_height, m_StretchClip, + m_ResampleOptions); m_Stretcher->Start(); m_Status = 3; } @@ -463,6 +466,14 @@ void CFX_ImageTransformer::CalcColor(const CalcData& cdata, } } +bool CFX_ImageTransformer::IsBilinear() const { + return !m_ResampleOptions.bInterpolateDownsample && !IsBiCubic(); +} + +bool CFX_ImageTransformer::IsBiCubic() const { + return m_ResampleOptions.bInterpolateBicubic; +} + void CFX_ImageTransformer::AdjustCoords(int* col, int* row) const { int& src_col = *col; int& src_row = *row; diff --git a/core/fxge/dib/cfx_imagetransformer.h b/core/fxge/dib/cfx_imagetransformer.h index 052df941d4..b0b854c333 100644 --- a/core/fxge/dib/cfx_imagetransformer.h +++ b/core/fxge/dib/cfx_imagetransformer.h @@ -23,7 +23,7 @@ class CFX_ImageTransformer { public: CFX_ImageTransformer(const RetainPtr<CFX_DIBBase>& pSrc, const CFX_Matrix& matrix, - uint32_t flags, + const FXDIB_ResampleOptions& options, const FX_RECT* pClip); ~CFX_ImageTransformer(); @@ -73,10 +73,8 @@ class CFX_ImageTransformer { void CalcMono(const CalcData& cdata, FXDIB_Format format); void CalcColor(const CalcData& cdata, FXDIB_Format format, int Bpp); - bool IsBilinear() const { - return !(m_Flags & FXDIB_DOWNSAMPLE) && !IsBiCubic(); - } - bool IsBiCubic() const { return !!(m_Flags & FXDIB_BICUBIC_INTERPOL); } + bool IsBilinear() const; + bool IsBiCubic() const; int stretch_width() const { return m_StretchClip.Width(); } int stretch_height() const { return m_StretchClip.Height(); } @@ -106,7 +104,7 @@ class CFX_ImageTransformer { CFX_Matrix m_dest2stretch; std::unique_ptr<CFX_ImageStretcher> m_Stretcher; CFX_BitmapStorer m_Storer; - const uint32_t m_Flags; + const FXDIB_ResampleOptions m_ResampleOptions; int m_Status = 0; }; diff --git a/core/fxge/dib/cstretchengine.cpp b/core/fxge/dib/cstretchengine.cpp index 969ab03667..7a582b537f 100644 --- a/core/fxge/dib/cstretchengine.cpp +++ b/core/fxge/dib/cstretchengine.cpp @@ -43,12 +43,12 @@ bool CStretchEngine::CWeightTable::Calc(int dest_len, int src_len, int src_min, int src_max, - int flags) { + const FXDIB_ResampleOptions& options) { m_WeightTables.clear(); m_dwWeightTablesSize = 0; const double scale = static_cast<float>(src_len) / dest_len; const double base = dest_len < 0 ? src_len : 0; - const int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1; + const int ext_size = options.bInterpolateBicubic ? 3 : 1; m_ItemSize = sizeof(int) * 2 + static_cast<int>(sizeof(int) * @@ -60,11 +60,11 @@ bool CStretchEngine::CWeightTable::Calc(int dest_len, m_dwWeightTablesSize = (dest_max - dest_min) * m_ItemSize + 4; m_WeightTables.resize(m_dwWeightTablesSize); - if ((flags & FXDIB_NOSMOOTH) != 0 || fabs(static_cast<float>(scale)) < 1.0f) { + if (options.bNoSmoothing || fabs(static_cast<float>(scale)) < 1.0f) { for (int dest_pixel = dest_min; dest_pixel < dest_max; ++dest_pixel) { PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); double src_pos = dest_pixel * scale + scale / 2 + base; - if (flags & FXDIB_INTERPOL) { + if (options.bInterpolateBilinear) { pixel_weights.m_SrcStart = static_cast<int>(floor(static_cast<float>(src_pos) - 1.0f / 2)); pixel_weights.m_SrcEnd = @@ -80,7 +80,7 @@ bool CStretchEngine::CWeightTable::Calc(int dest_len, 65536); pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1]; } - } else if (flags & FXDIB_BICUBIC_INTERPOL) { + } else if (options.bInterpolateBicubic) { pixel_weights.m_SrcStart = static_cast<int>(floor(static_cast<float>(src_pos) - 1.0f / 2)); pixel_weights.m_SrcEnd = @@ -229,7 +229,7 @@ CStretchEngine::CStretchEngine(ScanlineComposerIface* pDestBitmap, int dest_height, const FX_RECT& clip_rect, const RetainPtr<CFX_DIBBase>& pSrcBitmap, - int flags) + const FXDIB_ResampleOptions& options) : m_DestFormat(dest_format), m_DestBpp(GetBppFromFormat(dest_format)), m_SrcBpp(GetBppFromFormat(pSrcBitmap->GetFormat())), @@ -256,18 +256,19 @@ CStretchEngine::CStretchEngine(ScanlineComposerIface* pDestBitmap, std::fill(m_DestScanline.begin(), m_DestScanline.end(), 255); m_InterPitch = GetPitchRoundUpTo4Bytes(m_DestClip.Width() * m_DestBpp); m_ExtraMaskPitch = GetPitchRoundUpTo4Bytes(m_DestClip.Width() * 8); - if ((flags & FXDIB_NOSMOOTH) == 0) { - bool bInterpol = flags & FXDIB_INTERPOL || flags & FXDIB_BICUBIC_INTERPOL; + if (options.bNoSmoothing) { + m_ResampleOptions.bNoSmoothing = true; + m_ResampleOptions.bInterpolateDownsample = options.bInterpolateDownsample; + } else { + bool bInterpol = + options.bInterpolateBilinear || options.bInterpolateBicubic; if (!bInterpol && abs(dest_width) != 0 && abs(dest_height) / 8 < static_cast<long long>(m_SrcWidth) * m_SrcHeight / abs(dest_width)) { - flags = FXDIB_INTERPOL; + m_ResampleOptions.bInterpolateBilinear = true; + } else { + m_ResampleOptions = options; } - m_Flags = flags; - } else { - m_Flags = FXDIB_NOSMOOTH; - if (flags & FXDIB_DOWNSAMPLE) - m_Flags |= FXDIB_DOWNSAMPLE; } double scale_x = static_cast<float>(m_SrcWidth) / m_DestWidth; double scale_y = static_cast<float>(m_SrcHeight) / m_DestHeight; @@ -336,9 +337,9 @@ bool CStretchEngine::StartStretchHorz() { m_ExtraAlphaBuf.resize(m_SrcClip.Height(), m_ExtraMaskPitch); m_DestMaskScanline.resize(m_ExtraMaskPitch); } - bool ret = - m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, - m_SrcWidth, m_SrcClip.left, m_SrcClip.right, m_Flags); + bool ret = m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, + m_SrcWidth, m_SrcClip.left, m_SrcClip.right, + m_ResampleOptions); if (!ret) return false; @@ -390,7 +391,7 @@ bool CStretchEngine::ContinueStretchHorz(PauseIndicatorIface* pPause) { if (src_scan[j / 8] & (1 << (7 - j % 8))) dest_a += pixel_weight * 255; } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) + if (m_ResampleOptions.bInterpolateBicubic) dest_a = pdfium::clamp(dest_a, 0, kMaxDestValue); *dest_scan++ = static_cast<uint8_t>(dest_a >> 16); } @@ -408,7 +409,7 @@ bool CStretchEngine::ContinueStretchHorz(PauseIndicatorIface* pPause) { int pixel_weight = *pWeight; dest_a += pixel_weight * src_scan[j]; } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) + if (m_ResampleOptions.bInterpolateBicubic) dest_a = pdfium::clamp(dest_a, 0, kMaxDestValue); *dest_scan++ = static_cast<uint8_t>(dest_a >> 16); } @@ -429,7 +430,7 @@ bool CStretchEngine::ContinueStretchHorz(PauseIndicatorIface* pPause) { dest_r += pixel_weight * src_scan[j]; dest_a += pixel_weight; } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + if (m_ResampleOptions.bInterpolateBicubic) { dest_r = pdfium::clamp(dest_r, 0, kMaxDestValue); dest_a = pdfium::clamp(dest_a, 0, 65536); } @@ -461,7 +462,7 @@ bool CStretchEngine::ContinueStretchHorz(PauseIndicatorIface* pPause) { dest_r_y += pixel_weight * static_cast<uint8_t>(argb_cmyk >> 8); } } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + if (m_ResampleOptions.bInterpolateBicubic) { dest_r_y = pdfium::clamp(dest_r_y, 0, kMaxDestValue); dest_g_m = pdfium::clamp(dest_g_m, 0, kMaxDestValue); dest_b_c = pdfium::clamp(dest_b_c, 0, kMaxDestValue); @@ -498,7 +499,7 @@ bool CStretchEngine::ContinueStretchHorz(PauseIndicatorIface* pPause) { } dest_a += pixel_weight; } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + if (m_ResampleOptions.bInterpolateBicubic) { dest_b_c = pdfium::clamp(dest_b_c, 0, kMaxDestValue); dest_g_m = pdfium::clamp(dest_g_m, 0, kMaxDestValue); dest_r_y = pdfium::clamp(dest_r_y, 0, kMaxDestValue); @@ -528,7 +529,7 @@ bool CStretchEngine::ContinueStretchHorz(PauseIndicatorIface* pPause) { dest_g_m += pixel_weight * (*src_pixel++); dest_r_y += pixel_weight * (*src_pixel); } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + if (m_ResampleOptions.bInterpolateBicubic) { dest_b_c = pdfium::clamp(dest_b_c, 0, kMaxDestValue); dest_g_m = pdfium::clamp(dest_g_m, 0, kMaxDestValue); dest_r_y = pdfium::clamp(dest_r_y, 0, kMaxDestValue); @@ -564,7 +565,7 @@ bool CStretchEngine::ContinueStretchHorz(PauseIndicatorIface* pPause) { dest_r_y += pixel_weight * (*src_pixel); dest_a += pixel_weight; } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + if (m_ResampleOptions.bInterpolateBicubic) { dest_r_y = pdfium::clamp(dest_r_y, 0, kMaxDestValue); dest_g_m = pdfium::clamp(dest_g_m, 0, kMaxDestValue); dest_b_c = pdfium::clamp(dest_b_c, 0, kMaxDestValue); @@ -592,8 +593,9 @@ void CStretchEngine::StretchVert() { return; CWeightTable table; - bool ret = table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, - m_SrcHeight, m_SrcClip.top, m_SrcClip.bottom, m_Flags); + bool ret = + table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, m_SrcHeight, + m_SrcClip.top, m_SrcClip.bottom, m_ResampleOptions); if (!ret) return; @@ -619,7 +621,7 @@ void CStretchEngine::StretchVert() { dest_a += pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch]; } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) + if (m_ResampleOptions.bInterpolateBicubic) dest_a = pdfium::clamp(dest_a, 0, kMaxDestValue); *dest_scan = static_cast<uint8_t>(dest_a >> 16); dest_scan += DestBpp; @@ -645,7 +647,7 @@ void CStretchEngine::StretchVert() { dest_a += pixel_weight * src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch]; } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + if (m_ResampleOptions.bInterpolateBicubic) { dest_k = pdfium::clamp(dest_k, 0, kMaxDestValue); dest_a = pdfium::clamp(dest_a, 0, kMaxDestValue); } @@ -675,7 +677,7 @@ void CStretchEngine::StretchVert() { dest_g_m += pixel_weight * (*src_pixel++); dest_r_y += pixel_weight * (*src_pixel); } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + if (m_ResampleOptions.bInterpolateBicubic) { dest_r_y = pdfium::clamp(dest_r_y, 0, kMaxDestValue); dest_g_m = pdfium::clamp(dest_g_m, 0, kMaxDestValue); dest_b_c = pdfium::clamp(dest_b_c, 0, kMaxDestValue); @@ -718,7 +720,7 @@ void CStretchEngine::StretchVert() { else dest_a += pixel_weight * mask_v; } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + if (m_ResampleOptions.bInterpolateBicubic) { dest_r_y = pdfium::clamp(dest_r_y, 0, kMaxDestValue); dest_g_m = pdfium::clamp(dest_g_m, 0, kMaxDestValue); dest_b_c = pdfium::clamp(dest_b_c, 0, kMaxDestValue); diff --git a/core/fxge/dib/cstretchengine.h b/core/fxge/dib/cstretchengine.h index 6bb07c662c..c2aaca687f 100644 --- a/core/fxge/dib/cstretchengine.h +++ b/core/fxge/dib/cstretchengine.h @@ -26,7 +26,7 @@ class CStretchEngine { int dest_height, const FX_RECT& clip_rect, const RetainPtr<CFX_DIBBase>& pSrcBitmap, - int flags); + const FXDIB_ResampleOptions& options); ~CStretchEngine(); bool Continue(PauseIndicatorIface* pPause); @@ -46,7 +46,7 @@ class CStretchEngine { int src_len, int src_min, int src_max, - int flags); + const FXDIB_ResampleOptions& options); const PixelWeight* GetPixelWeight(int pixel) const; PixelWeight* GetPixelWeight(int pixel) { @@ -96,7 +96,7 @@ class CStretchEngine { FX_RECT m_SrcClip; int m_InterPitch; int m_ExtraMaskPitch; - int m_Flags; + FXDIB_ResampleOptions m_ResampleOptions; TransformMethod m_TransMethod; State m_State = State::kInitial; int m_CurRow; diff --git a/core/fxge/dib/cstretchengine_unittest.cpp b/core/fxge/dib/cstretchengine_unittest.cpp index 8169cae328..a79945c67d 100644 --- a/core/fxge/dib/cstretchengine_unittest.cpp +++ b/core/fxge/dib/cstretchengine_unittest.cpp @@ -27,6 +27,11 @@ TEST(CStretchEngine, OverflowInCtor) { auto dib_source = pdfium::MakeRetain<CPDF_DIBBase>(); dib_source->Load(nullptr, stream.get()); CStretchEngine engine(nullptr, FXDIB_8bppRgb, 500, 500, clip_rect, dib_source, - 0); - EXPECT_EQ(FXDIB_INTERPOL, engine.m_Flags); + FXDIB_ResampleOptions()); + EXPECT_FALSE(engine.m_ResampleOptions.bInterpolateDownsample); + EXPECT_TRUE(engine.m_ResampleOptions.bInterpolateBilinear); + EXPECT_FALSE(engine.m_ResampleOptions.bInterpolateBicubic); + EXPECT_FALSE(engine.m_ResampleOptions.bHalftone); + EXPECT_FALSE(engine.m_ResampleOptions.bNoSmoothing); + EXPECT_FALSE(engine.m_ResampleOptions.bLossy); } diff --git a/core/fxge/dib/fx_dib_main.cpp b/core/fxge/dib/fx_dib_main.cpp index 8df1322e97..dfdf7ec909 100644 --- a/core/fxge/dib/fx_dib_main.cpp +++ b/core/fxge/dib/fx_dib_main.cpp @@ -54,6 +54,29 @@ const int16_t SDP_Table[513] = { 0, 0, 0, }; +FXDIB_ResampleOptions::FXDIB_ResampleOptions() = default; + +FXDIB_ResampleOptions::FXDIB_ResampleOptions(bool downsample, + bool bilinear, + bool bicubic, + bool halftone, + bool no_smoothing, + bool lossy) + : bInterpolateDownsample(downsample), + bInterpolateBilinear(bilinear), + bInterpolateBicubic(bicubic), + bHalftone(halftone), + bNoSmoothing(no_smoothing), + bLossy(lossy) {} + +bool FXDIB_ResampleOptions::HasAnyOptions() const { + return bInterpolateDownsample || bInterpolateBilinear || + bInterpolateBicubic || bHalftone || bNoSmoothing || bLossy; +} + +const FXDIB_ResampleOptions kBilinearInterpolation = { + false, /*bilinear=*/true, false, false, false, false}; + FX_RECT FXDIB_SwapClipBox(const FX_RECT& clip, int width, int height, |