blob: 2ee14774ab94bed478d3bd6f4743ba8bec327a9e [file] [log] [blame]
kumarashishg826308d2023-06-23 13:21:22 +00001// Copyright 2017 The PDFium Authors
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#ifndef CORE_FXGE_DIB_CSTRETCHENGINE_H_
8#define CORE_FXGE_DIB_CSTRETCHENGINE_H_
9
kumarashishg826308d2023-06-23 13:21:22 +000010#include <stdint.h>
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070011
kumarashishg826308d2023-06-23 13:21:22 +000012#include "core/fxcrt/data_vector.h"
13#include "core/fxcrt/fixed_try_alloc_zeroed_data_vector.h"
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070014#include "core/fxcrt/fx_coordinates.h"
kumarashishg826308d2023-06-23 13:21:22 +000015#include "core/fxcrt/fx_system.h"
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070016#include "core/fxcrt/retain_ptr.h"
17#include "core/fxcrt/unowned_ptr.h"
kumarashishg826308d2023-06-23 13:21:22 +000018#include "core/fxge/dib/fx_dib.h"
19#include "third_party/base/check_op.h"
20#include "third_party/base/span.h"
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070021
Haibo Huang49cc9302020-04-27 16:14:24 -070022class CFX_DIBBase;
23class PauseIndicatorIface;
24class ScanlineComposerIface;
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070025
26class CStretchEngine {
27 public:
kumarashishg826308d2023-06-23 13:21:22 +000028 static constexpr uint32_t kFixedPointBits = 16;
29 static constexpr uint32_t kFixedPointOne = 1 << kFixedPointBits;
30
31 static inline uint32_t FixedFromDouble(double d) {
32 return static_cast<uint32_t>(FXSYS_round(d * kFixedPointOne));
33 }
34
35 static inline uint32_t FixedFromFloat(float f) {
36 return static_cast<uint32_t>(FXSYS_roundf(f * kFixedPointOne));
37 }
38
39 static inline uint8_t PixelFromFixed(uint32_t fixed) {
40 return static_cast<uint8_t>(fixed >> kFixedPointBits);
41 }
42
43 // Indicates whether to manually set interpolate bilinear option to true to
44 // achieve a smoother rendering results.
45 static bool UseInterpolateBilinear(const FXDIB_ResampleOptions& options,
46 int dest_width,
47 int dest_height,
48 int src_width,
49 int src_height);
50
51 struct PixelWeight {
52 static size_t TotalBytesForWeightCount(size_t weight_count);
53
54 void SetStartEnd(int src_start, int src_end, size_t weight_count) {
55 CHECK_LT(src_end - src_start, static_cast<int>(weight_count));
56 m_SrcStart = src_start;
57 m_SrcEnd = src_end;
58 }
59
60 uint32_t GetWeightForPosition(int position) const {
61 CHECK_GE(position, m_SrcStart);
62 CHECK_LE(position, m_SrcEnd);
63 return m_Weights[position - m_SrcStart];
64 }
65
66 void SetWeightForPosition(int position, uint32_t weight) {
67 CHECK_GE(position, m_SrcStart);
68 CHECK_LE(position, m_SrcEnd);
69 m_Weights[position - m_SrcStart] = weight;
70 }
71
72 // NOTE: relies on defined behaviour for unsigned overflow to
73 // decrement the previous position, as needed.
74 void RemoveLastWeightAndAdjust(uint32_t weight_change) {
75 CHECK_GT(m_SrcEnd, m_SrcStart);
76 --m_SrcEnd;
77 m_Weights[m_SrcEnd - m_SrcStart] += weight_change;
78 }
79
80 int m_SrcStart;
81 int m_SrcEnd; // Note: inclusive, [0, -1] for empty range at 0.
82 uint32_t m_Weights[1]; // Not really 1, variable size.
83 };
84
85 class WeightTable {
86 public:
87 WeightTable();
88 ~WeightTable();
89
90 // Accepts a negative `dest_len` argument, producing a "mirror
91 // image" of the result if `dest_len` is negative.
92 bool CalculateWeights(int dest_len,
93 int dest_min,
94 int dest_max,
95 int src_len,
96 int src_min,
97 int src_max,
98 const FXDIB_ResampleOptions& options);
99
100 const PixelWeight* GetPixelWeight(int pixel) const;
101 PixelWeight* GetPixelWeight(int pixel);
102
103 private:
104 int m_DestMin = 0;
105 size_t m_ItemSizeBytes = 0;
106 size_t m_WeightTablesSizeBytes = 0;
107 DataVector<uint8_t> m_WeightTables;
108 };
109
Haibo Huang49cc9302020-04-27 16:14:24 -0700110 CStretchEngine(ScanlineComposerIface* pDestBitmap,
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700111 FXDIB_Format dest_format,
112 int dest_width,
113 int dest_height,
114 const FX_RECT& clip_rect,
kumarashishg826308d2023-06-23 13:21:22 +0000115 const RetainPtr<const CFX_DIBBase>& pSrcBitmap,
Haibo Huang49cc9302020-04-27 16:14:24 -0700116 const FXDIB_ResampleOptions& options);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700117 ~CStretchEngine();
118
Haibo Huang49cc9302020-04-27 16:14:24 -0700119 bool Continue(PauseIndicatorIface* pPause);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700120 bool StartStretchHorz();
Haibo Huang49cc9302020-04-27 16:14:24 -0700121 bool ContinueStretchHorz(PauseIndicatorIface* pPause);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700122 void StretchVert();
123
kumarashishg826308d2023-06-23 13:21:22 +0000124 const FXDIB_ResampleOptions& GetResampleOptionsForTest() const {
125 return m_ResampleOptions;
126 }
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700127
kumarashishg826308d2023-06-23 13:21:22 +0000128 private:
Haibo Huang49cc9302020-04-27 16:14:24 -0700129 enum class State : uint8_t { kInitial, kHorizontal, kVertical };
130
131 enum class TransformMethod : uint8_t {
132 k1BppTo8Bpp,
133 k1BppToManyBpp,
134 k8BppTo8Bpp,
Haibo Huang49cc9302020-04-27 16:14:24 -0700135 k8BppToManyBpp,
Haibo Huang49cc9302020-04-27 16:14:24 -0700136 kManyBpptoManyBpp,
137 kManyBpptoManyBppWithAlpha
138 };
139
140 const FXDIB_Format m_DestFormat;
141 const int m_DestBpp;
142 const int m_SrcBpp;
kumarashishg826308d2023-06-23 13:21:22 +0000143 const bool m_bHasAlpha;
144 RetainPtr<const CFX_DIBBase> const m_pSource;
145 pdfium::span<const uint32_t> m_pSrcPalette;
Haibo Huang49cc9302020-04-27 16:14:24 -0700146 const int m_SrcWidth;
147 const int m_SrcHeight;
148 UnownedPtr<ScanlineComposerIface> const m_pDestBitmap;
149 const int m_DestWidth;
150 const int m_DestHeight;
151 const FX_RECT m_DestClip;
kumarashishg826308d2023-06-23 13:21:22 +0000152 DataVector<uint8_t> m_DestScanline;
153 FixedTryAllocZeroedDataVector<uint8_t> m_InterBuf;
Haibo Huang49cc9302020-04-27 16:14:24 -0700154 FX_RECT m_SrcClip;
155 int m_InterPitch;
156 int m_ExtraMaskPitch;
157 FXDIB_ResampleOptions m_ResampleOptions;
158 TransformMethod m_TransMethod;
159 State m_State = State::kInitial;
kumarashishg826308d2023-06-23 13:21:22 +0000160 int m_CurRow = 0;
161 WeightTable m_WeightTable;
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700162};
163
164#endif // CORE_FXGE_DIB_CSTRETCHENGINE_H_