summaryrefslogtreecommitdiff
path: root/core/fxge/dib/cfx_imagetransformer.cpp
diff options
context:
space:
mode:
authorNicolas Pena <npm@chromium.org>2017-03-31 15:39:44 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-03-31 20:16:52 +0000
commitbdbb0bd92bfca52e574106c4ce5f93d9d34d3373 (patch)
tree9fa4af5211b7bc655d73d7410af36a3e14e3cbb6 /core/fxge/dib/cfx_imagetransformer.cpp
parenteb39cdb2efbc66e4566ba1f150cab7983362e13f (diff)
downloadpdfium-bdbb0bd92bfca52e574106c4ce5f93d9d34d3373.tar.xz
Split fx_dib part 3
Moved CFX_ImageRenderer, CFX_ImageTransformer to their own files. Change-Id: Ic98403f62bea317600a933f79946a2a9bad30eeb Reviewed-on: https://pdfium-review.googlesource.com/3551 Commit-Queue: Nicolás Peña <npm@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org>
Diffstat (limited to 'core/fxge/dib/cfx_imagetransformer.cpp')
-rw-r--r--core/fxge/dib/cfx_imagetransformer.cpp766
1 files changed, 766 insertions, 0 deletions
diff --git a/core/fxge/dib/cfx_imagetransformer.cpp b/core/fxge/dib/cfx_imagetransformer.cpp
new file mode 100644
index 0000000000..7a519adebf
--- /dev/null
+++ b/core/fxge/dib/cfx_imagetransformer.cpp
@@ -0,0 +1,766 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fxge/dib/cfx_imagetransformer.h"
+
+#include <memory>
+#include <utility>
+
+#include "core/fxge/fx_dib.h"
+#include "third_party/base/ptr_util.h"
+
+namespace {
+
+uint8_t bilinear_interpol(const uint8_t* buf,
+ int row_offset_l,
+ int row_offset_r,
+ int src_col_l,
+ int src_col_r,
+ int res_x,
+ int res_y,
+ int bpp,
+ int c_offset) {
+ int i_resx = 255 - res_x;
+ int col_bpp_l = src_col_l * bpp;
+ int col_bpp_r = src_col_r * bpp;
+ const uint8_t* buf_u = buf + row_offset_l + c_offset;
+ const uint8_t* buf_d = buf + row_offset_r + c_offset;
+ const uint8_t* src_pos0 = buf_u + col_bpp_l;
+ const uint8_t* src_pos1 = buf_u + col_bpp_r;
+ const uint8_t* src_pos2 = buf_d + col_bpp_l;
+ const uint8_t* src_pos3 = buf_d + col_bpp_r;
+ uint8_t r_pos_0 = (*src_pos0 * i_resx + *src_pos1 * res_x) >> 8;
+ uint8_t r_pos_1 = (*src_pos2 * i_resx + *src_pos3 * res_x) >> 8;
+ return (r_pos_0 * (255 - res_y) + r_pos_1 * res_y) >> 8;
+}
+
+uint8_t bicubic_interpol(const uint8_t* buf,
+ int pitch,
+ int pos_pixel[],
+ int u_w[],
+ int v_w[],
+ int res_x,
+ int res_y,
+ int bpp,
+ int c_offset) {
+ int s_result = 0;
+ 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));
+ }
+ s_result += a_result * v_w[i];
+ }
+ s_result >>= 16;
+ return (uint8_t)(s_result < 0 ? 0 : s_result > 255 ? 255 : s_result);
+}
+
+void bicubic_get_pos_weight(int pos_pixel[],
+ int u_w[],
+ int v_w[],
+ int src_col_l,
+ int src_row_l,
+ int res_x,
+ int res_y,
+ int stretch_width,
+ int stretch_height) {
+ pos_pixel[0] = src_col_l - 1;
+ pos_pixel[1] = src_col_l;
+ pos_pixel[2] = src_col_l + 1;
+ pos_pixel[3] = src_col_l + 2;
+ pos_pixel[4] = src_row_l - 1;
+ pos_pixel[5] = src_row_l;
+ 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;
+ }
+ }
+ u_w[0] = SDP_Table[256 + res_x];
+ u_w[1] = SDP_Table[res_x];
+ u_w[2] = SDP_Table[256 - res_x];
+ u_w[3] = SDP_Table[512 - res_x];
+ v_w[0] = SDP_Table[256 + res_y];
+ v_w[1] = SDP_Table[res_y];
+ v_w[2] = SDP_Table[256 - res_y];
+ v_w[3] = SDP_Table[512 - res_y];
+}
+
+FXDIB_Format GetTransformedFormat(const CFX_RetainPtr<CFX_DIBSource>& pDrc) {
+ 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;
+ } else {
+ format = FXDIB_Rgba;
+ }
+ return format;
+}
+
+class CFX_BilinearMatrix : public CPDF_FixedMatrix {
+ public:
+ CFX_BilinearMatrix(const CFX_Matrix& src, int bits)
+ : CPDF_FixedMatrix(src, bits) {}
+ inline void Transform(int x,
+ int y,
+ int& x1,
+ int& y1,
+ int& res_x,
+ int& res_y) {
+ x1 = a * x + c * y + e + base / 2;
+ y1 = b * x + d * y + f + base / 2;
+ res_x = x1 % base;
+ res_y = y1 % base;
+ if (res_x < 0 && res_x > -base) {
+ res_x = base + res_x;
+ }
+ if (res_y < 0 && res_x > -base) {
+ res_y = base + res_y;
+ }
+ x1 /= base;
+ y1 /= base;
+ }
+};
+
+#define FIX16_005 0.05f
+
+} // namespace
+
+CFX_ImageTransformer::CFX_ImageTransformer(
+ const CFX_RetainPtr<CFX_DIBSource>& pSrc,
+ const CFX_Matrix* pMatrix,
+ int flags,
+ const FX_RECT* pClip)
+ : m_pSrc(pSrc),
+ m_pMatrix(pMatrix),
+ m_pClip(pClip),
+ m_Flags(flags),
+ m_Status(0) {}
+
+CFX_ImageTransformer::~CFX_ImageTransformer() {}
+
+bool CFX_ImageTransformer::Start() {
+ CFX_FloatRect unit_rect = m_pMatrix->GetUnitRect();
+ FX_RECT result_rect = unit_rect.GetClosestRect();
+ FX_RECT result_clip = result_rect;
+ if (m_pClip)
+ result_clip.Intersect(*m_pClip);
+
+ if (result_clip.IsEmpty())
+ return false;
+
+ m_result = result_clip;
+ if (FXSYS_fabs(m_pMatrix->a) < FXSYS_fabs(m_pMatrix->b) / 20 &&
+ FXSYS_fabs(m_pMatrix->d) < FXSYS_fabs(m_pMatrix->c) / 20 &&
+ FXSYS_fabs(m_pMatrix->a) < 0.5f && FXSYS_fabs(m_pMatrix->d) < 0.5f) {
+ int dest_width = result_rect.Width();
+ int dest_height = result_rect.Height();
+ result_clip.Offset(-result_rect.left, -result_rect.top);
+ result_clip = FXDIB_SwapClipBox(result_clip, dest_width, dest_height,
+ m_pMatrix->c > 0, m_pMatrix->b < 0);
+ m_Stretcher = pdfium::MakeUnique<CFX_ImageStretcher>(
+ &m_Storer, m_pSrc, dest_height, dest_width, result_clip, m_Flags);
+ m_Stretcher->Start();
+ m_Status = 1;
+ return true;
+ }
+ if (FXSYS_fabs(m_pMatrix->b) < FIX16_005 &&
+ FXSYS_fabs(m_pMatrix->c) < FIX16_005) {
+ int dest_width = m_pMatrix->a > 0 ? (int)FXSYS_ceil(m_pMatrix->a)
+ : (int)FXSYS_floor(m_pMatrix->a);
+ int dest_height = m_pMatrix->d > 0 ? (int)-FXSYS_ceil(m_pMatrix->d)
+ : (int)-FXSYS_floor(m_pMatrix->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_Stretcher->Start();
+ m_Status = 2;
+ return true;
+ }
+ int stretch_width = (int)FXSYS_ceil(FXSYS_sqrt2(m_pMatrix->a, m_pMatrix->b));
+ int stretch_height = (int)FXSYS_ceil(FXSYS_sqrt2(m_pMatrix->c, m_pMatrix->d));
+ CFX_Matrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
+ (float)(stretch_height));
+ stretch2dest.Concat(
+ CFX_Matrix(m_pMatrix->a / stretch_width, m_pMatrix->b / stretch_width,
+ m_pMatrix->c / stretch_height, m_pMatrix->d / stretch_height,
+ m_pMatrix->e, m_pMatrix->f));
+ m_dest2stretch.SetReverse(stretch2dest);
+
+ CFX_FloatRect clip_rect_f(result_clip);
+ m_dest2stretch.TransformRect(clip_rect_f);
+ m_StretchClip = clip_rect_f.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_Stretcher->Start();
+ m_Status = 3;
+ return true;
+}
+
+bool CFX_ImageTransformer::Continue(IFX_Pause* pPause) {
+ if (m_Status == 1) {
+ if (m_Stretcher->Continue(pPause))
+ return true;
+
+ if (m_Storer.GetBitmap()) {
+ m_Storer.Replace(
+ m_Storer.GetBitmap()->SwapXY(m_pMatrix->c > 0, m_pMatrix->b < 0));
+ }
+ return false;
+ }
+
+ if (m_Status == 2)
+ return m_Stretcher->Continue(pPause);
+
+ if (m_Status != 3)
+ return false;
+
+ if (m_Stretcher->Continue(pPause))
+ return true;
+
+ int stretch_width = m_StretchClip.Width();
+ int stretch_height = m_StretchClip.Height();
+ if (!m_Storer.GetBitmap())
+ return false;
+
+ const uint8_t* stretch_buf = m_Storer.GetBitmap()->GetBuffer();
+ const uint8_t* stretch_buf_mask = nullptr;
+ if (m_Storer.GetBitmap()->m_pAlphaMask)
+ stretch_buf_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetBuffer();
+
+ int stretch_pitch = m_Storer.GetBitmap()->GetPitch();
+ auto pTransformed = pdfium::MakeRetain<CFX_DIBitmap>();
+ FXDIB_Format transformF = GetTransformedFormat(m_Stretcher->source());
+ if (!pTransformed->Create(m_result.Width(), m_result.Height(), transformF))
+ return false;
+
+ pTransformed->Clear(0);
+ if (pTransformed->m_pAlphaMask)
+ pTransformed->m_pAlphaMask->Clear(0);
+
+ CFX_Matrix result2stretch(1.0f, 0.0f, 0.0f, 1.0f, (float)(m_result.left),
+ (float)(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) {
+ int stretch_pitch_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetPitch();
+ if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_pos_mask =
+ (uint8_t*)pTransformed->m_pAlphaMask->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x,
+ res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 &&
+ src_row_l <= stretch_height) {
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ int src_col_r = src_col_l + 1;
+ int src_row_r = src_row_l + 1;
+ if (src_col_r == stretch_width) {
+ src_col_r--;
+ }
+ if (src_row_r == stretch_height) {
+ src_row_r--;
+ }
+ int row_offset_l = src_row_l * stretch_pitch_mask;
+ int row_offset_r = src_row_r * stretch_pitch_mask;
+ *dest_pos_mask =
+ bilinear_interpol(stretch_buf_mask, row_offset_l, row_offset_r,
+ src_col_l, src_col_r, res_x, res_y, 1, 0);
+ }
+ dest_pos_mask++;
+ }
+ }
+ } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_pos_mask =
+ (uint8_t*)pTransformed->m_pAlphaMask->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x,
+ res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 &&
+ src_row_l <= stretch_height) {
+ int pos_pixel[8];
+ int u_w[4], v_w[4];
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ 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(stretch_buf_mask, stretch_pitch_mask,
+ pos_pixel, u_w, v_w, res_x, res_y, 1, 0);
+ }
+ dest_pos_mask++;
+ }
+ }
+ } else {
+ CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_pos_mask =
+ (uint8_t*)pTransformed->m_pAlphaMask->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col, src_row;
+ result2stretch_fix.Transform(col, row, src_col, src_row);
+ if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 &&
+ src_row <= stretch_height) {
+ if (src_col == stretch_width) {
+ src_col--;
+ }
+ if (src_row == stretch_height) {
+ src_row--;
+ }
+ *dest_pos_mask =
+ stretch_buf_mask[src_row * stretch_pitch_mask + src_col];
+ }
+ dest_pos_mask++;
+ }
+ }
+ }
+ }
+ if (m_Storer.GetBitmap()->IsAlphaMask()) {
+ if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_scan = (uint8_t*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x,
+ res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 &&
+ src_row_l <= stretch_height) {
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ int src_col_r = src_col_l + 1;
+ int src_row_r = src_row_l + 1;
+ if (src_col_r == stretch_width) {
+ src_col_r--;
+ }
+ if (src_row_r == stretch_height) {
+ src_row_r--;
+ }
+ int row_offset_l = src_row_l * stretch_pitch;
+ int row_offset_r = src_row_r * stretch_pitch;
+ *dest_scan =
+ bilinear_interpol(stretch_buf, row_offset_l, row_offset_r,
+ src_col_l, src_col_r, res_x, res_y, 1, 0);
+ }
+ dest_scan++;
+ }
+ }
+ } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_scan = (uint8_t*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x,
+ res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 &&
+ src_row_l <= stretch_height) {
+ int pos_pixel[8];
+ int u_w[4], v_w[4];
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ 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(stretch_buf, stretch_pitch, pos_pixel,
+ u_w, v_w, res_x, res_y, 1, 0);
+ }
+ dest_scan++;
+ }
+ }
+ } else {
+ CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_scan = (uint8_t*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col, src_row;
+ result2stretch_fix.Transform(col, row, src_col, src_row);
+ if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 &&
+ src_row <= stretch_height) {
+ if (src_col == stretch_width) {
+ src_col--;
+ }
+ if (src_row == stretch_height) {
+ src_row--;
+ }
+ const uint8_t* src_pixel =
+ stretch_buf + stretch_pitch * src_row + src_col;
+ *dest_scan = *src_pixel;
+ }
+ dest_scan++;
+ }
+ }
+ }
+ } else {
+ int Bpp = m_Storer.GetBitmap()->GetBPP() / 8;
+ if (Bpp == 1) {
+ uint32_t argb[256];
+ FX_ARGB* pPal = m_Storer.GetBitmap()->GetPalette();
+ if (pPal) {
+ for (int i = 0; i < 256; i++) {
+ argb[i] = pPal[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);
+ }
+ }
+ }
+ int destBpp = pTransformed->GetBPP() / 8;
+ if (!(m_Flags & FXDIB_DOWNSAMPLE) &&
+ !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x,
+ res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width &&
+ src_row_l >= 0 && src_row_l <= stretch_height) {
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ int src_col_r = src_col_l + 1;
+ int src_row_r = src_row_l + 1;
+ if (src_col_r == stretch_width) {
+ src_col_r--;
+ }
+ if (src_row_r == stretch_height) {
+ src_row_r--;
+ }
+ int row_offset_l = src_row_l * stretch_pitch;
+ int row_offset_r = src_row_r * stretch_pitch;
+ uint32_t r_bgra_cmyk = argb[bilinear_interpol(
+ stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r,
+ res_x, res_y, 1, 0)];
+ if (transformF == 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;
+ }
+ }
+ } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x,
+ res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width &&
+ src_row_l >= 0 && src_row_l <= stretch_height) {
+ int pos_pixel[8];
+ int u_w[4], v_w[4];
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ 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(stretch_buf, stretch_pitch, pos_pixel,
+ u_w, v_w, res_x, res_y, 1, 0)];
+ if (transformF == 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;
+ }
+ }
+ } else {
+ CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col, src_row;
+ result2stretch_fix.Transform(col, row, src_col, src_row);
+ if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 &&
+ src_row <= stretch_height) {
+ if (src_col == stretch_width) {
+ src_col--;
+ }
+ if (src_row == stretch_height) {
+ src_row--;
+ }
+ uint32_t r_bgra_cmyk =
+ argb[stretch_buf[src_row * stretch_pitch + src_col]];
+ if (transformF == 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;
+ }
+ }
+ }
+ } else {
+ bool bHasAlpha = m_Storer.GetBitmap()->HasAlpha();
+ int destBpp = pTransformed->GetBPP() / 8;
+ if (!(m_Flags & FXDIB_DOWNSAMPLE) &&
+ !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col_l, src_row_l, res_x, res_y, r_pos_k_r = 0;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x,
+ res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width &&
+ src_row_l >= 0 && src_row_l <= stretch_height) {
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ int src_col_r = src_col_l + 1;
+ int src_row_r = src_row_l + 1;
+ if (src_col_r == stretch_width) {
+ src_col_r--;
+ }
+ if (src_row_r == stretch_height) {
+ src_row_r--;
+ }
+ int row_offset_l = src_row_l * stretch_pitch;
+ int row_offset_r = src_row_r * stretch_pitch;
+ uint8_t r_pos_red_y_r =
+ bilinear_interpol(stretch_buf, row_offset_l, row_offset_r,
+ src_col_l, src_col_r, res_x, res_y, Bpp, 2);
+ uint8_t r_pos_green_m_r =
+ bilinear_interpol(stretch_buf, row_offset_l, row_offset_r,
+ src_col_l, src_col_r, res_x, res_y, Bpp, 1);
+ uint8_t r_pos_blue_c_r =
+ bilinear_interpol(stretch_buf, row_offset_l, row_offset_r,
+ src_col_l, src_col_r, res_x, res_y, Bpp, 0);
+ if (bHasAlpha) {
+ if (transformF != FXDIB_Argb) {
+ if (transformF == 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 = bilinear_interpol(
+ stretch_buf, row_offset_l, row_offset_r, src_col_l,
+ src_col_r, 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 = bilinear_interpol(
+ stretch_buf, row_offset_l, row_offset_r, src_col_l,
+ src_col_r, 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));
+ }
+ } else {
+ r_pos_k_r = 0xff;
+ if (transformF == FXDIB_Cmyka) {
+ r_pos_k_r = bilinear_interpol(
+ stretch_buf, row_offset_l, row_offset_r, src_col_l,
+ src_col_r, 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));
+ }
+ }
+ }
+ dest_pos += destBpp;
+ }
+ }
+ } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col_l, src_row_l, res_x, res_y, r_pos_k_r = 0;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x,
+ res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width &&
+ src_row_l >= 0 && src_row_l <= stretch_height) {
+ int pos_pixel[8];
+ int u_w[4], v_w[4];
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ 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(stretch_buf, stretch_pitch, pos_pixel, u_w,
+ v_w, res_x, res_y, Bpp, 2);
+ uint8_t r_pos_green_m_r =
+ bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w,
+ v_w, res_x, res_y, Bpp, 1);
+ uint8_t r_pos_blue_c_r =
+ bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w,
+ v_w, res_x, res_y, Bpp, 0);
+ if (bHasAlpha) {
+ if (transformF != FXDIB_Argb) {
+ if (transformF == 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(stretch_buf, stretch_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(stretch_buf, stretch_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));
+ }
+ } else {
+ r_pos_k_r = 0xff;
+ if (transformF == FXDIB_Cmyka) {
+ r_pos_k_r =
+ bicubic_interpol(stretch_buf, stretch_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));
+ }
+ }
+ }
+ dest_pos += destBpp;
+ }
+ }
+ } else {
+ CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_result.Height(); row++) {
+ uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_result.Width(); col++) {
+ int src_col, src_row;
+ result2stretch_fix.Transform(col, row, src_col, src_row);
+ if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 &&
+ src_row <= stretch_height) {
+ if (src_col == stretch_width) {
+ src_col--;
+ }
+ if (src_row == stretch_height) {
+ src_row--;
+ }
+ const uint8_t* src_pos =
+ stretch_buf + src_row * stretch_pitch + src_col * Bpp;
+ if (bHasAlpha) {
+ if (transformF != FXDIB_Argb) {
+ if (transformF == FXDIB_Rgba) {
+ dest_pos[0] = src_pos[0];
+ dest_pos[1] = src_pos[1];
+ dest_pos[2] = src_pos[2];
+ } else {
+ *(uint32_t*)dest_pos = FXCMYK_TODIB(CmykEncode(
+ src_pos[0], src_pos[1], src_pos[2], src_pos[3]));
+ }
+ } else {
+ *(uint32_t*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(
+ src_pos[3], src_pos[2], src_pos[1], src_pos[0]));
+ }
+ } else {
+ if (transformF == FXDIB_Cmyka) {
+ *(uint32_t*)dest_pos = FXCMYK_TODIB(CmykEncode(
+ src_pos[0], src_pos[1], src_pos[2], src_pos[3]));
+ } else {
+ *(uint32_t*)dest_pos = FXARGB_TODIB(
+ FXARGB_MAKE(0xff, src_pos[2], src_pos[1], src_pos[0]));
+ }
+ }
+ }
+ dest_pos += destBpp;
+ }
+ }
+ }
+ }
+ }
+ m_Storer.Replace(std::move(pTransformed));
+ return false;
+}
+
+CFX_RetainPtr<CFX_DIBitmap> CFX_ImageTransformer::DetachBitmap() {
+ return m_Storer.Detach();
+}