From 8b27918d4ecb326efb19584cd0c2daeb4a71f7db Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Mon, 4 Dec 2017 19:26:25 +0000 Subject: Refactor CFX_ImageTransformer bicubic calculations. Change-Id: I47c0ae6dbdf339ab7ade36b141c220b8a3fb2274 Reviewed-on: https://pdfium-review.googlesource.com/20257 Commit-Queue: Lei Zhang Reviewed-by: dsinclair --- core/fxge/dib/cfx_imagetransformer.cpp | 225 ++++++++++++++------------------- core/fxge/dib/cfx_imagetransformer.h | 15 +++ 2 files changed, 110 insertions(+), 130 deletions(-) (limited to 'core/fxge') 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 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 func); + void DoBicubicLoop(const CalcData& cdata, + int increment, + std::function func); const RetainPtr m_pSrc; UnownedPtr const m_pMatrix; -- cgit v1.2.3