1 // Copyright 2017 The PDFium Authors 2 // 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 10 #include <stdint.h> 11 12 #include "core/fxcrt/data_vector.h" 13 #include "core/fxcrt/fixed_try_alloc_zeroed_data_vector.h" 14 #include "core/fxcrt/fx_coordinates.h" 15 #include "core/fxcrt/fx_system.h" 16 #include "core/fxcrt/retain_ptr.h" 17 #include "core/fxcrt/unowned_ptr.h" 18 #include "core/fxge/dib/fx_dib.h" 19 #include "third_party/base/check_op.h" 20 #include "third_party/base/containers/span.h" 21 22 class CFX_DIBBase; 23 class PauseIndicatorIface; 24 class ScanlineComposerIface; 25 26 class CStretchEngine { 27 public: 28 static constexpr uint32_t kFixedPointBits = 16; 29 static constexpr uint32_t kFixedPointOne = 1 << kFixedPointBits; 30 FixedFromDouble(double d)31 static inline uint32_t FixedFromDouble(double d) { 32 return static_cast<uint32_t>(FXSYS_round(d * kFixedPointOne)); 33 } 34 FixedFromFloat(float f)35 static inline uint32_t FixedFromFloat(float f) { 36 return static_cast<uint32_t>(FXSYS_roundf(f * kFixedPointOne)); 37 } 38 PixelFromFixed(uint32_t fixed)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 SetStartEndPixelWeight54 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 GetWeightForPositionPixelWeight60 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 SetWeightForPositionPixelWeight66 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. RemoveLastWeightAndAdjustPixelWeight74 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 110 CStretchEngine(ScanlineComposerIface* pDestBitmap, 111 FXDIB_Format dest_format, 112 int dest_width, 113 int dest_height, 114 const FX_RECT& clip_rect, 115 const RetainPtr<const CFX_DIBBase>& pSrcBitmap, 116 const FXDIB_ResampleOptions& options); 117 ~CStretchEngine(); 118 119 bool Continue(PauseIndicatorIface* pPause); 120 bool StartStretchHorz(); 121 bool ContinueStretchHorz(PauseIndicatorIface* pPause); 122 void StretchVert(); 123 GetResampleOptionsForTest()124 const FXDIB_ResampleOptions& GetResampleOptionsForTest() const { 125 return m_ResampleOptions; 126 } 127 128 private: 129 enum class State : uint8_t { kInitial, kHorizontal, kVertical }; 130 131 enum class TransformMethod : uint8_t { 132 k1BppTo8Bpp, 133 k1BppToManyBpp, 134 k8BppTo8Bpp, 135 k8BppToManyBpp, 136 kManyBpptoManyBpp, 137 kManyBpptoManyBppWithAlpha 138 }; 139 140 const FXDIB_Format m_DestFormat; 141 const int m_DestBpp; 142 const int m_SrcBpp; 143 const bool m_bHasAlpha; 144 RetainPtr<const CFX_DIBBase> const m_pSource; 145 pdfium::span<const uint32_t> m_pSrcPalette; 146 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; 152 DataVector<uint8_t> m_DestScanline; 153 FixedTryAllocZeroedDataVector<uint8_t> m_InterBuf; 154 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; 160 int m_CurRow = 0; 161 WeightTable m_WeightTable; 162 }; 163 164 #endif // CORE_FXGE_DIB_CSTRETCHENGINE_H_ 165