summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fxge/dib/cfx_imagetransformer.cpp225
-rw-r--r--core/fxge/dib/cfx_imagetransformer.h15
2 files changed, 110 insertions, 130 deletions
diff --git a/core/fxge/dib/cfx_imagetransformer.cpp b/core/fxge/dib/cfx_imagetransformer.cpp
index eda7c477f8..d1edf093ee 100644
--- a/core/fxge/dib/cfx_imagetransformer.cpp
+++ b/core/fxge/dib/cfx_imagetransformer.cpp
@@ -327,29 +327,11 @@ void CFX_ImageTransformer::CalcMask(const CalcData& cdata) {
};
DoBilinearLoop(cdata, 1, func);
} else if (IsBiCubic()) {
- CFX_BilinearMatrix result2stretch_fix(cdata.matrix, 8);
- for (int row = 0; row < m_result.Height(); row++) {
- uint8_t* dest_pos_mask = (uint8_t*)cdata.bitmap->GetScanline(row);
- for (int col = 0; col < m_result.Width(); col++) {
- int src_col_l = 0;
- int src_row_l = 0;
- int res_x = 0;
- int res_y = 0;
- result2stretch_fix.Transform(col, row, &src_col_l, &src_row_l, &res_x,
- &res_y);
- if (InStretchBounds(src_col_l, src_row_l)) {
- int pos_pixel[8];
- int u_w[4], v_w[4];
- AdjustCoords(&src_col_l, &src_row_l);
- bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l,
- res_x, res_y, stretch_width(),
- stretch_height());
- *dest_pos_mask = bicubic_interpol(cdata.buf, cdata.pitch, pos_pixel,
- u_w, v_w, res_x, res_y, 1, 0);
- }
- dest_pos_mask++;
- }
- }
+ auto func = [&cdata](const BicubicData& data, uint8_t* dest) {
+ *dest = bicubic_interpol(cdata.buf, cdata.pitch, data.pos_pixel, data.u_w,
+ data.v_w, data.res_x, data.res_y, 1, 0);
+ };
+ DoBicubicLoop(cdata, 1, func);
} else {
CPDF_FixedMatrix result2stretch_fix(cdata.matrix, 8);
for (int row = 0; row < m_result.Height(); row++) {
@@ -377,29 +359,11 @@ void CFX_ImageTransformer::CalcAlpha(const CalcData& cdata) {
};
DoBilinearLoop(cdata, 1, func);
} else if (IsBiCubic()) {
- CFX_BilinearMatrix result2stretch_fix(cdata.matrix, 8);
- for (int row = 0; row < m_result.Height(); row++) {
- uint8_t* dest_scan = (uint8_t*)cdata.bitmap->GetScanline(row);
- for (int col = 0; col < m_result.Width(); col++) {
- int src_col_l = 0;
- int src_row_l = 0;
- int res_x = 0;
- int res_y = 0;
- result2stretch_fix.Transform(col, row, &src_col_l, &src_row_l, &res_x,
- &res_y);
- if (InStretchBounds(src_col_l, src_row_l)) {
- int pos_pixel[8];
- int u_w[4], v_w[4];
- AdjustCoords(&src_col_l, &src_row_l);
- bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l,
- res_x, res_y, stretch_width(),
- stretch_height());
- *dest_scan = bicubic_interpol(cdata.buf, cdata.pitch, pos_pixel, u_w,
- v_w, res_x, res_y, 1, 0);
- }
- dest_scan++;
- }
- }
+ auto func = [&cdata](const BicubicData& data, uint8_t* dest) {
+ *dest = bicubic_interpol(cdata.buf, cdata.pitch, data.pos_pixel, data.u_w,
+ data.v_w, data.res_x, data.res_y, 1, 0);
+ };
+ DoBicubicLoop(cdata, 1, func);
} else {
CPDF_FixedMatrix result2stretch_fix(cdata.matrix, 8);
for (int row = 0; row < m_result.Height(); row++) {
@@ -457,36 +421,20 @@ void CFX_ImageTransformer::CalcMono(const CalcData& cdata,
};
DoBilinearLoop(cdata, destBpp, func);
} else if (IsBiCubic()) {
- CFX_BilinearMatrix result2stretch_fix(cdata.matrix, 8);
- for (int row = 0; row < m_result.Height(); row++) {
- uint8_t* dest_pos = (uint8_t*)cdata.bitmap->GetScanline(row);
- for (int col = 0; col < m_result.Width(); col++) {
- int src_col_l = 0;
- int src_row_l = 0;
- int res_x = 0;
- int res_y = 0;
- result2stretch_fix.Transform(col, row, &src_col_l, &src_row_l, &res_x,
- &res_y);
- if (InStretchBounds(src_col_l, src_row_l)) {
- int pos_pixel[8];
- int u_w[4], v_w[4];
- AdjustCoords(&src_col_l, &src_row_l);
- bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l,
- res_x, res_y, stretch_width(),
- stretch_height());
- uint32_t r_bgra_cmyk = argb[bicubic_interpol(
- cdata.buf, cdata.pitch, pos_pixel, u_w, v_w, res_x, res_y, 1, 0)];
- if (format == FXDIB_Rgba) {
- dest_pos[0] = (uint8_t)(r_bgra_cmyk >> 24);
- dest_pos[1] = (uint8_t)(r_bgra_cmyk >> 16);
- dest_pos[2] = (uint8_t)(r_bgra_cmyk >> 8);
- } else {
- *(uint32_t*)dest_pos = r_bgra_cmyk;
- }
- }
- dest_pos += destBpp;
+ auto func = [&cdata, format, &argb](const BicubicData& data,
+ uint8_t* dest) {
+ 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;
}
- }
+ };
+ DoBicubicLoop(cdata, destBpp, func);
} else {
CPDF_FixedMatrix result2stretch_fix(cdata.matrix, 8);
for (int row = 0; row < m_result.Height(); row++) {
@@ -572,65 +520,55 @@ void CFX_ImageTransformer::CalcColorBicubic(const CalcData& cdata,
FXDIB_Format format,
int Bpp) {
bool bHasAlpha = m_Storer.GetBitmap()->HasAlpha();
- int destBpp = cdata.bitmap->GetBPP() / 8;
- CFX_BilinearMatrix result2stretch_fix(cdata.matrix, 8);
- for (int row = 0; row < m_result.Height(); row++) {
- uint8_t* dest_pos = (uint8_t*)cdata.bitmap->GetScanline(row);
- for (int col = 0; col < m_result.Width(); col++) {
- int src_col_l = 0;
- int src_row_l = 0;
- int res_x = 0;
- int res_y = 0;
- int r_pos_k_r = 0;
- result2stretch_fix.Transform(col, row, &src_col_l, &src_row_l, &res_x,
- &res_y);
- if (InStretchBounds(src_col_l, src_row_l)) {
- int pos_pixel[8];
- int u_w[4], v_w[4];
- AdjustCoords(&src_col_l, &src_row_l);
- bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x,
- res_y, stretch_width(), stretch_height());
- uint8_t r_pos_red_y_r = bicubic_interpol(
- cdata.buf, cdata.pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 2);
- uint8_t r_pos_green_m_r = bicubic_interpol(
- cdata.buf, cdata.pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 1);
- uint8_t r_pos_blue_c_r = bicubic_interpol(
- cdata.buf, cdata.pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 0);
- if (bHasAlpha) {
- if (format != FXDIB_Argb) {
- if (format == FXDIB_Rgba) {
- dest_pos[0] = r_pos_blue_c_r;
- dest_pos[1] = r_pos_green_m_r;
- dest_pos[2] = r_pos_red_y_r;
- } else {
- r_pos_k_r = bicubic_interpol(cdata.buf, cdata.pitch, pos_pixel,
- u_w, v_w, res_x, res_y, Bpp, 3);
- *(uint32_t*)dest_pos = FXCMYK_TODIB(CmykEncode(
- r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r));
- }
- } else {
- uint8_t r_pos_a_r =
- bicubic_interpol(cdata.buf, cdata.pitch, pos_pixel, u_w, v_w,
- res_x, res_y, Bpp, 3);
- *(uint32_t*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(
- r_pos_a_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r));
- }
+ auto func = [&cdata, format, Bpp, bHasAlpha](const BicubicData& data,
+ uint8_t* dest) {
+ uint8_t r_pos_red_y_r =
+ bicubic_interpol(cdata.buf, cdata.pitch, data.pos_pixel, data.u_w,
+ data.v_w, data.res_x, data.res_y, Bpp, 2);
+ uint8_t r_pos_green_m_r =
+ bicubic_interpol(cdata.buf, cdata.pitch, data.pos_pixel, data.u_w,
+ data.v_w, data.res_x, data.res_y, Bpp, 1);
+ 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;
+ if (bHasAlpha) {
+ if (format != FXDIB_Argb) {
+ if (format == FXDIB_Rgba) {
+ dest[0] = r_pos_blue_c_r;
+ dest[1] = r_pos_green_m_r;
+ dest[2] = r_pos_red_y_r;
} else {
- r_pos_k_r = 0xff;
- if (format == FXDIB_Cmyka) {
- r_pos_k_r = bicubic_interpol(cdata.buf, cdata.pitch, pos_pixel, u_w,
- v_w, res_x, res_y, Bpp, 3);
- *(uint32_t*)dest_pos = FXCMYK_TODIB(CmykEncode(
- r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r));
- } else {
- *(uint32_t*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(
- r_pos_k_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r));
- }
+ uint8_t r_pos_k_r =
+ bicubic_interpol(cdata.buf, cdata.pitch, data.pos_pixel, data.u_w,
+ data.v_w, data.res_x, data.res_y, Bpp, 3);
+ *dest32 = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r,
+ r_pos_red_y_r, r_pos_k_r));
}
+ } else {
+ uint8_t r_pos_a_r =
+ bicubic_interpol(cdata.buf, cdata.pitch, data.pos_pixel, data.u_w,
+ data.v_w, data.res_x, data.res_y, Bpp, 3);
+ *dest32 = FXARGB_TODIB(FXARGB_MAKE(r_pos_a_r, r_pos_red_y_r,
+ r_pos_green_m_r, r_pos_blue_c_r));
+ }
+ } else {
+ if (format == FXDIB_Cmyka) {
+ uint8_t r_pos_k_r =
+ bicubic_interpol(cdata.buf, cdata.pitch, data.pos_pixel, data.u_w,
+ data.v_w, data.res_x, data.res_y, Bpp, 3);
+ *dest32 = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r,
+ r_pos_red_y_r, r_pos_k_r));
+ } else {
+ uint8_t r_pos_k_r = 0xff;
+ *dest32 = FXARGB_TODIB(FXARGB_MAKE(r_pos_k_r, r_pos_red_y_r,
+ r_pos_green_m_r, r_pos_blue_c_r));
}
- dest_pos += destBpp;
}
- }
+ };
+
+ int destBpp = cdata.bitmap->GetBPP() / 8;
+ DoBicubicLoop(cdata, destBpp, func);
}
void CFX_ImageTransformer::CalcColorDownSample(const CalcData& cdata,
@@ -715,3 +653,30 @@ void CFX_ImageTransformer::DoBilinearLoop(
}
}
}
+
+void CFX_ImageTransformer::DoBicubicLoop(
+ const CalcData& cdata,
+ int increment,
+ std::function<void(const BicubicData&, uint8_t*)> func) {
+ CFX_BilinearMatrix matrix_fix(cdata.matrix, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest = (uint8_t*)cdata.bitmap->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ BicubicData d;
+ d.res_x = 0;
+ d.res_y = 0;
+ d.src_col_l = 0;
+ d.src_row_l = 0;
+ matrix_fix.Transform(col, row, &d.src_col_l, &d.src_row_l, &d.res_x,
+ &d.res_y);
+ if (InStretchBounds(d.src_col_l, d.src_row_l)) {
+ AdjustCoords(&d.src_col_l, &d.src_row_l);
+ bicubic_get_pos_weight(d.pos_pixel, d.u_w, d.v_w, d.src_col_l,
+ d.src_row_l, d.res_x, d.res_y, stretch_width(),
+ stretch_height());
+ func(d, dest);
+ }
+ dest += increment;
+ }
+ }
+}
diff --git a/core/fxge/dib/cfx_imagetransformer.h b/core/fxge/dib/cfx_imagetransformer.h
index 2d22ebcf95..6df50d7801 100644
--- a/core/fxge/dib/cfx_imagetransformer.h
+++ b/core/fxge/dib/cfx_imagetransformer.h
@@ -43,6 +43,18 @@ class CFX_ImageTransformer {
int row_offset_r;
};
+ struct BicubicData {
+ int res_x;
+ int res_y;
+ int src_col_l;
+ int src_row_l;
+ int src_col_r;
+ int src_row_r;
+ int pos_pixel[8];
+ int u_w[4];
+ int v_w[4];
+ };
+
struct CalcData {
const CFX_DIBitmap* bitmap;
const CFX_Matrix& matrix;
@@ -75,6 +87,9 @@ class CFX_ImageTransformer {
void DoBilinearLoop(const CalcData& cdata,
int increment,
std::function<void(const BilinearData&, uint8_t*)> func);
+ void DoBicubicLoop(const CalcData& cdata,
+ int increment,
+ std::function<void(const BicubicData&, uint8_t*)> func);
const RetainPtr<CFX_DIBSource> m_pSrc;
UnownedPtr<const CFX_Matrix> const m_pMatrix;