summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/fxge/dib/cfx_imagetransformer.cpp209
1 files changed, 92 insertions, 117 deletions
diff --git a/core/fxge/dib/cfx_imagetransformer.cpp b/core/fxge/dib/cfx_imagetransformer.cpp
index e7f60c4991..6fd25689d8 100644
--- a/core/fxge/dib/cfx_imagetransformer.cpp
+++ b/core/fxge/dib/cfx_imagetransformer.cpp
@@ -15,6 +15,9 @@
namespace {
+constexpr int kBase = 256;
+constexpr float kFix16 = 0.05f;
+
uint8_t bilinear_interpol(const uint8_t* buf,
int row_offset_l,
int row_offset_r,
@@ -51,8 +54,9 @@ uint8_t bicubic_interpol(const uint8_t* buf,
for (int i = 0; i < 4; i++) {
int a_result = 0;
for (int j = 0; j < 4; j++) {
- a_result += u_w[j] * (*(uint8_t*)(buf + pos_pixel[i + 4] * pitch +
- pos_pixel[j] * bpp + c_offset));
+ uint8_t val =
+ *(buf + pos_pixel[i + 4] * pitch + pos_pixel[j] * bpp + c_offset);
+ a_result += u_w[j] * val;
}
s_result += a_result * v_w[i];
}
@@ -78,18 +82,8 @@ void bicubic_get_pos_weight(int pos_pixel[],
pos_pixel[6] = src_row_l + 1;
pos_pixel[7] = src_row_l + 2;
for (int i = 0; i < 4; i++) {
- if (pos_pixel[i] < 0) {
- pos_pixel[i] = 0;
- }
- if (pos_pixel[i] >= stretch_width) {
- pos_pixel[i] = stretch_width - 1;
- }
- if (pos_pixel[i + 4] < 0) {
- pos_pixel[i + 4] = 0;
- }
- if (pos_pixel[i + 4] >= stretch_height) {
- pos_pixel[i + 4] = stretch_height - 1;
- }
+ pos_pixel[i] = pdfium::clamp(pos_pixel[i], 0, stretch_width - 1);
+ pos_pixel[i + 4] = pdfium::clamp(pos_pixel[i + 4], 0, stretch_height - 1);
}
u_w[0] = SDP_Table[256 + res_x];
u_w[1] = SDP_Table[res_x];
@@ -102,79 +96,83 @@ void bicubic_get_pos_weight(int pos_pixel[],
}
FXDIB_Format GetTransformedFormat(const RetainPtr<CFX_DIBSource>& pDrc) {
+ if (pDrc->IsAlphaMask())
+ return FXDIB_8bppMask;
+
FXDIB_Format format = pDrc->GetFormat();
- if (pDrc->IsAlphaMask()) {
- format = FXDIB_8bppMask;
- } else if (format >= 1025) {
- format = FXDIB_Cmyka;
- } else if (format <= 32 || format == FXDIB_Argb) {
- format = FXDIB_Argb;
+ if (format >= 1025)
+ return FXDIB_Cmyka;
+ if (format <= 32 || format == FXDIB_Argb)
+ return FXDIB_Argb;
+ return FXDIB_Rgba;
+}
+
+void WriteMonoResult(uint32_t r_bgra_cmyk, FXDIB_Format format, uint8_t* dest) {
+ if (format == FXDIB_Rgba) {
+ dest[0] = static_cast<uint8_t>(r_bgra_cmyk >> 24);
+ dest[1] = static_cast<uint8_t>(r_bgra_cmyk >> 16);
+ dest[2] = static_cast<uint8_t>(r_bgra_cmyk >> 8);
} else {
- format = FXDIB_Rgba;
+ *reinterpret_cast<uint32_t*>(dest) = r_bgra_cmyk;
}
- return format;
}
class CPDF_FixedMatrix {
public:
- CPDF_FixedMatrix(const CFX_Matrix& src, int bits) {
- base = 1 << bits;
- a = FXSYS_round(src.a * base);
- b = FXSYS_round(src.b * base);
- c = FXSYS_round(src.c * base);
- d = FXSYS_round(src.d * base);
- e = FXSYS_round(src.e * base);
- f = FXSYS_round(src.f * base);
- }
-
- void Transform(int x, int y, int* x1, int* y1) {
- *x1 = (a * x + c * y + e + base / 2) / base;
- *y1 = (b * x + d * y + f + base / 2) / base;
+ explicit CPDF_FixedMatrix(const CFX_Matrix& src)
+ : a(FXSYS_round(src.a * kBase)),
+ b(FXSYS_round(src.b * kBase)),
+ c(FXSYS_round(src.c * kBase)),
+ d(FXSYS_round(src.d * kBase)),
+ e(FXSYS_round(src.e * kBase)),
+ f(FXSYS_round(src.f * kBase)) {}
+
+ void Transform(int x, int y, int* x1, int* y1) const {
+ *x1 = (a * x + c * y + e + kBase / 2) / kBase;
+ *y1 = (b * x + d * y + f + kBase / 2) / kBase;
}
- int a;
- int b;
- int c;
- int d;
- int e;
- int f;
- int base;
+ protected:
+ const int a;
+ const int b;
+ const int c;
+ const int d;
+ const int e;
+ const int f;
};
class CFX_BilinearMatrix : public CPDF_FixedMatrix {
public:
- CFX_BilinearMatrix(const CFX_Matrix& src, int bits)
- : CPDF_FixedMatrix(src, bits) {}
- void Transform(int x, int y, int* x1, int* y1, int* res_x, int* res_y) {
+ explicit CFX_BilinearMatrix(const CFX_Matrix& src) : CPDF_FixedMatrix(src) {}
+
+ void Transform(int x, int y, int* x1, int* y1, int* res_x, int* res_y) const {
pdfium::base::CheckedNumeric<int> val = a;
pdfium::base::CheckedNumeric<int> val2 = c;
val *= x;
val2 *= y;
- val += val2 + e + (base >> 1);
+ val += val2 + e + (kBase / 2);
*x1 = val.ValueOrDefault(0);
val = b;
val2 = d;
val *= x;
val2 *= y;
- val += val2 + f + (base >> 1);
+ val += val2 + f + (kBase / 2);
*y1 = val.ValueOrDefault(0);
- *res_x = *x1 % base;
- *res_y = *y1 % base;
+ *res_x = *x1 % kBase;
+ *res_y = *y1 % kBase;
- if (*res_x < 0 && *res_x > -base)
- *res_x = base + *res_x;
- if (*res_y < 0 && *res_x > -base)
- *res_y = base + *res_y;
+ if (*res_x < 0 && *res_x > -kBase)
+ *res_x = kBase + *res_x;
+ if (*res_y < 0 && *res_x > -kBase)
+ *res_y = kBase + *res_y;
- *x1 /= base;
- *y1 /= base;
+ *x1 /= kBase;
+ *y1 /= kBase;
}
};
-#define FIX16_005 0.05f
-
} // namespace
CFX_ImageTransformer::CFX_ImageTransformer(const RetainPtr<CFX_DIBSource>& pSrc,
@@ -209,7 +207,7 @@ CFX_ImageTransformer::CFX_ImageTransformer(const RetainPtr<CFX_DIBSource>& pSrc,
m_Status = 1;
return;
}
- if (fabs(m_pMatrix->b) < FIX16_005 && fabs(m_pMatrix->c) < FIX16_005) {
+ if (fabs(m_pMatrix->b) < kFix16 && fabs(m_pMatrix->c) < kFix16) {
int dest_width = static_cast<int>(m_pMatrix->a > 0 ? ceil(m_pMatrix->a)
: floor(m_pMatrix->a));
int dest_height = static_cast<int>(m_pMatrix->d > 0 ? -ceil(m_pMatrix->d)
@@ -265,28 +263,28 @@ bool CFX_ImageTransformer::Continue(IFX_PauseIndicator* pPause) {
if (!m_Storer.GetBitmap())
return false;
- const uint8_t* stretch_buf_mask = nullptr;
- if (m_Storer.GetBitmap()->m_pAlphaMask)
- stretch_buf_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetBuffer();
-
auto pTransformed = pdfium::MakeRetain<CFX_DIBitmap>();
- FXDIB_Format transformF = GetTransformedFormat(m_Stretcher->source());
- if (!pTransformed->Create(m_result.Width(), m_result.Height(), transformF))
+ FXDIB_Format format = GetTransformedFormat(m_Stretcher->source());
+ if (!pTransformed->Create(m_result.Width(), m_result.Height(), format))
return false;
+ const auto& pSrcMask = m_Storer.GetBitmap()->m_pAlphaMask;
+ const uint8_t* pSrcMaskBuf = pSrcMask ? pSrcMask->GetBuffer() : nullptr;
+
pTransformed->Clear(0);
- if (pTransformed->m_pAlphaMask)
- pTransformed->m_pAlphaMask->Clear(0);
+ auto& pDestMask = pTransformed->m_pAlphaMask;
+ if (pDestMask)
+ pDestMask->Clear(0);
- CFX_Matrix result2stretch(1.0f, 0.0f, 0.0f, 1.0f, (float)(m_result.left),
- (float)(m_result.top));
+ CFX_Matrix result2stretch(1.0f, 0.0f, 0.0f, 1.0f, m_result.left,
+ m_result.top);
result2stretch.Concat(m_dest2stretch);
result2stretch.Translate(-m_StretchClip.left, -m_StretchClip.top);
- if (!stretch_buf_mask && pTransformed->m_pAlphaMask) {
- pTransformed->m_pAlphaMask->Clear(0xff000000);
- } else if (pTransformed->m_pAlphaMask) {
+ if (!pSrcMaskBuf && pDestMask) {
+ pDestMask->Clear(0xff000000);
+ } else if (pDestMask) {
CalcData cdata = {
- pTransformed->m_pAlphaMask.Get(), result2stretch, stretch_buf_mask,
+ pDestMask.Get(), result2stretch, pSrcMaskBuf,
m_Storer.GetBitmap()->m_pAlphaMask->GetPitch(),
};
CalcMask(cdata);
@@ -300,14 +298,14 @@ bool CFX_ImageTransformer::Continue(IFX_PauseIndicator* pPause) {
} else {
int Bpp = m_Storer.GetBitmap()->GetBPP() / 8;
if (Bpp == 1) {
- CalcMono(cdata, transformF);
+ CalcMono(cdata, format);
} else {
if (IsBilinear())
- CalcColorBilinear(cdata, transformF, Bpp);
+ CalcColorBilinear(cdata, format, Bpp);
else if (IsBiCubic())
- CalcColorBicubic(cdata, transformF, Bpp);
+ CalcColorBicubic(cdata, format, Bpp);
else
- CalcColorDownSample(cdata, transformF, Bpp);
+ CalcColorDownSample(cdata, format, Bpp);
}
}
m_Storer.Replace(std::move(pTransformed));
@@ -369,19 +367,14 @@ void CFX_ImageTransformer::CalcMono(const CalcData& cdata,
uint32_t argb[256];
FX_ARGB* pPal = m_Storer.GetBitmap()->GetPalette();
if (pPal) {
- for (int i = 0; i < 256; i++) {
+ for (size_t i = 0; i < FX_ArraySize(argb); i++)
argb[i] = pPal[i];
- }
+ } else if (m_Storer.GetBitmap()->IsCmykImage()) {
+ for (size_t i = 0; i < FX_ArraySize(argb); i++)
+ argb[i] = 255 - i;
} else {
- if (m_Storer.GetBitmap()->IsCmykImage()) {
- for (int i = 0; i < 256; i++) {
- argb[i] = 255 - i;
- }
- } else {
- for (int i = 0; i < 256; i++) {
- argb[i] = 0xff000000 | (i * 0x010101);
- }
- }
+ for (size_t i = 0; i < FX_ArraySize(argb); i++)
+ argb[i] = 0xff000000 | (i * 0x010101);
}
int destBpp = cdata.bitmap->GetBPP() / 8;
if (IsBilinear()) {
@@ -391,13 +384,7 @@ void CFX_ImageTransformer::CalcMono(const CalcData& cdata,
cdata.buf, data.row_offset_l, data.row_offset_r, data.src_col_l,
data.src_col_r, data.res_x, data.res_y, 1, 0);
uint32_t r_bgra_cmyk = argb[idx];
- if (format == FXDIB_Rgba) {
- dest[0] = (uint8_t)(r_bgra_cmyk >> 24);
- dest[1] = (uint8_t)(r_bgra_cmyk >> 16);
- dest[2] = (uint8_t)(r_bgra_cmyk >> 8);
- } else {
- *(uint32_t*)dest = r_bgra_cmyk;
- }
+ WriteMonoResult(r_bgra_cmyk, format, dest);
};
DoBilinearLoop(cdata, destBpp, func);
} else if (IsBiCubic()) {
@@ -406,13 +393,7 @@ void CFX_ImageTransformer::CalcMono(const CalcData& cdata,
uint32_t r_bgra_cmyk = argb[bicubic_interpol(
cdata.buf, cdata.pitch, data.pos_pixel, data.u_w, data.v_w,
data.res_x, data.res_y, 1, 0)];
- if (format == FXDIB_Rgba) {
- dest[0] = (uint8_t)(r_bgra_cmyk >> 24);
- dest[1] = (uint8_t)(r_bgra_cmyk >> 16);
- dest[2] = (uint8_t)(r_bgra_cmyk >> 8);
- } else {
- *(uint32_t*)dest = r_bgra_cmyk;
- }
+ WriteMonoResult(r_bgra_cmyk, format, dest);
};
DoBicubicLoop(cdata, destBpp, func);
} else {
@@ -420,13 +401,7 @@ void CFX_ImageTransformer::CalcMono(const CalcData& cdata,
uint8_t* dest) {
uint32_t r_bgra_cmyk =
argb[cdata.buf[data.src_row * cdata.pitch + data.src_col]];
- if (format == FXDIB_Rgba) {
- dest[0] = (uint8_t)(r_bgra_cmyk >> 24);
- dest[1] = (uint8_t)(r_bgra_cmyk >> 16);
- dest[2] = (uint8_t)(r_bgra_cmyk >> 8);
- } else {
- *(uint32_t*)dest = r_bgra_cmyk;
- }
+ WriteMonoResult(r_bgra_cmyk, format, dest);
};
DoDownSampleLoop(cdata, destBpp, func);
}
@@ -447,7 +422,7 @@ void CFX_ImageTransformer::CalcColorBilinear(const CalcData& cdata,
uint8_t r_pos_blue_c_r = bilinear_interpol(
cdata.buf, data.row_offset_l, data.row_offset_r, data.src_col_l,
data.src_col_r, data.res_x, data.res_y, Bpp, 0);
- uint32_t* dest32 = (uint32_t*)dest;
+ uint32_t* dest32 = reinterpret_cast<uint32_t*>(dest);
if (bHasAlpha) {
if (format != FXDIB_Argb) {
if (format == FXDIB_Rgba) {
@@ -502,7 +477,7 @@ void CFX_ImageTransformer::CalcColorBicubic(const CalcData& cdata,
uint8_t r_pos_blue_c_r =
bicubic_interpol(cdata.buf, cdata.pitch, data.pos_pixel, data.u_w,
data.v_w, data.res_x, data.res_y, Bpp, 0);
- uint32_t* dest32 = (uint32_t*)dest;
+ uint32_t* dest32 = reinterpret_cast<uint32_t*>(dest);
if (bHasAlpha) {
if (format != FXDIB_Argb) {
if (format == FXDIB_Rgba) {
@@ -550,7 +525,7 @@ void CFX_ImageTransformer::CalcColorDownSample(const CalcData& cdata,
uint8_t* dest) {
const uint8_t* src_pos =
cdata.buf + data.src_row * cdata.pitch + data.src_col * Bpp;
- uint32_t* dest32 = (uint32_t*)dest;
+ uint32_t* dest32 = reinterpret_cast<uint32_t*>(dest);
if (bHasAlpha) {
if (format != FXDIB_Argb) {
if (format == FXDIB_Rgba) {
@@ -593,9 +568,9 @@ void CFX_ImageTransformer::DoBilinearLoop(
const CalcData& cdata,
int increment,
std::function<void(const BilinearData&, uint8_t*)> func) {
- CFX_BilinearMatrix matrix_fix(cdata.matrix, 8);
+ CFX_BilinearMatrix matrix_fix(cdata.matrix);
for (int row = 0; row < m_result.Height(); row++) {
- uint8_t* dest = (uint8_t*)cdata.bitmap->GetScanline(row);
+ uint8_t* dest = const_cast<uint8_t*>(cdata.bitmap->GetScanline(row));
for (int col = 0; col < m_result.Width(); col++) {
BilinearData d;
d.res_x = 0;
@@ -622,9 +597,9 @@ void CFX_ImageTransformer::DoBicubicLoop(
const CalcData& cdata,
int increment,
std::function<void(const BicubicData&, uint8_t*)> func) {
- CFX_BilinearMatrix matrix_fix(cdata.matrix, 8);
+ CFX_BilinearMatrix matrix_fix(cdata.matrix);
for (int row = 0; row < m_result.Height(); row++) {
- uint8_t* dest = (uint8_t*)cdata.bitmap->GetScanline(row);
+ uint8_t* dest = const_cast<uint8_t*>(cdata.bitmap->GetScanline(row));
for (int col = 0; col < m_result.Width(); col++) {
BicubicData d;
d.res_x = 0;
@@ -649,9 +624,9 @@ void CFX_ImageTransformer::DoDownSampleLoop(
const CalcData& cdata,
int increment,
std::function<void(const DownSampleData&, uint8_t*)> func) {
- CPDF_FixedMatrix matrix_fix(cdata.matrix, 8);
+ CPDF_FixedMatrix matrix_fix(cdata.matrix);
for (int row = 0; row < m_result.Height(); row++) {
- uint8_t* dest = (uint8_t*)cdata.bitmap->GetScanline(row);
+ uint8_t* dest = const_cast<uint8_t*>(cdata.bitmap->GetScanline(row));
for (int col = 0; col < m_result.Width(); col++) {
DownSampleData d;
d.src_col = 0;