summaryrefslogtreecommitdiff
path: root/core/fxge/dib
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxge/dib')
-rw-r--r--core/fxge/dib/cfx_dibbase.cpp14
-rw-r--r--core/fxge/dib/cfx_dibbase.h2
-rw-r--r--core/fxge/dib/cfx_dibitmap.cpp10
-rw-r--r--core/fxge/dib/cfx_imagerenderer.cpp9
-rw-r--r--core/fxge/dib/cfx_imagerenderer.h2
-rw-r--r--core/fxge/dib/cfx_imagestretcher.cpp11
-rw-r--r--core/fxge/dib/cfx_imagestretcher.h4
-rw-r--r--core/fxge/dib/cfx_imagetransformer.cpp21
-rw-r--r--core/fxge/dib/cfx_imagetransformer.h10
-rw-r--r--core/fxge/dib/cstretchengine.cpp62
-rw-r--r--core/fxge/dib/cstretchengine.h6
-rw-r--r--core/fxge/dib/cstretchengine_unittest.cpp9
-rw-r--r--core/fxge/dib/fx_dib_main.cpp23
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,