• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/check_op.h"
13 #include "core/fxcrt/data_vector.h"
14 #include "core/fxcrt/fixed_size_data_vector.h"
15 #include "core/fxcrt/fx_coordinates.h"
16 #include "core/fxcrt/fx_system.h"
17 #include "core/fxcrt/raw_span.h"
18 #include "core/fxcrt/retain_ptr.h"
19 #include "core/fxcrt/unowned_ptr.h"
20 #include "core/fxge/dib/fx_dib.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 
PixelFromFixed(uint32_t fixed)35   static inline uint8_t PixelFromFixed(uint32_t fixed) {
36     return static_cast<uint8_t>(fixed >> kFixedPointBits);
37   }
38 
39   // Indicates whether to manually set interpolate bilinear option to true to
40   // achieve a smoother rendering results.
41   static bool UseInterpolateBilinear(const FXDIB_ResampleOptions& options,
42                                      int dest_width,
43                                      int dest_height,
44                                      int src_width,
45                                      int src_height);
46 
47   struct PixelWeight {
SetStartEndPixelWeight48     void SetStartEnd(int src_start, int src_end, size_t weight_count) {
49       CHECK_LT(src_end - src_start, static_cast<int>(weight_count));
50       m_SrcStart = src_start;
51       m_SrcEnd = src_end;
52     }
53 
GetWeightForPositionPixelWeight54     uint32_t GetWeightForPosition(int position) const {
55       CHECK_GE(position, m_SrcStart);
56       CHECK_LE(position, m_SrcEnd);
57       // SAFETY: enforced by checks above.
58       return UNSAFE_BUFFERS(m_Weights[position - m_SrcStart]);
59     }
60 
SetWeightForPositionPixelWeight61     void SetWeightForPosition(int position, uint32_t weight) {
62       CHECK_GE(position, m_SrcStart);
63       CHECK_LE(position, m_SrcEnd);
64       // SAFETY: enforced by checks above.
65       UNSAFE_BUFFERS(m_Weights[position - m_SrcStart] = weight);
66     }
67 
68     // NOTE: relies on defined behaviour for unsigned overflow to
69     // decrement the previous position, as needed.
RemoveLastWeightAndAdjustPixelWeight70     void RemoveLastWeightAndAdjust(uint32_t weight_change) {
71       CHECK_GT(m_SrcEnd, m_SrcStart);
72       --m_SrcEnd;
73       // SAFETY: enforced by checks above.
74       UNSAFE_BUFFERS(m_Weights[m_SrcEnd - m_SrcStart] += weight_change);
75     }
76 
77     int m_SrcStart;
78     int m_SrcEnd;           // Note: inclusive, [0, -1] for empty range at 0.
79     uint32_t m_Weights[1];  // Not really 1, variable size.
80   };
81 
82   class WeightTable {
83    public:
84     WeightTable();
85     ~WeightTable();
86 
87     // Accepts a negative `dest_len` argument, producing a "mirror
88     // image" of the result if `dest_len` is negative.
89     bool CalculateWeights(int dest_len,
90                           int dest_min,
91                           int dest_max,
92                           int src_len,
93                           int src_min,
94                           int src_max,
95                           const FXDIB_ResampleOptions& options);
96 
97     const PixelWeight* GetPixelWeight(int pixel) const;
98     PixelWeight* GetPixelWeight(int pixel);
99 
100    private:
101     int m_DestMin = 0;
102     size_t m_ItemSizeBytes = 0;
103     size_t m_WeightTablesSizeBytes = 0;
104     DataVector<uint8_t> m_WeightTables;
105   };
106 
107   CStretchEngine(ScanlineComposerIface* pDestBitmap,
108                  FXDIB_Format dest_format,
109                  int dest_width,
110                  int dest_height,
111                  const FX_RECT& clip_rect,
112                  const RetainPtr<const CFX_DIBBase>& pSrcBitmap,
113                  const FXDIB_ResampleOptions& options);
114   ~CStretchEngine();
115 
116   bool Continue(PauseIndicatorIface* pPause);
117   bool StartStretchHorz();
118   bool ContinueStretchHorz(PauseIndicatorIface* pPause);
119   void StretchVert();
120 
GetResampleOptionsForTest()121   const FXDIB_ResampleOptions& GetResampleOptionsForTest() const {
122     return m_ResampleOptions;
123   }
124 
125  private:
126   enum class State : uint8_t { kInitial, kHorizontal, kVertical };
127 
128   enum class TransformMethod : uint8_t {
129     k1BppTo8Bpp,
130     k1BppToManyBpp,
131     k8BppTo8Bpp,
132     k8BppToManyBpp,
133     kManyBpptoManyBpp,
134     kManyBpptoManyBppWithAlpha
135   };
136 
137   const FXDIB_Format m_DestFormat;
138   const int m_DestBpp;
139   const int m_SrcBpp;
140   const bool m_bHasAlpha;
141   RetainPtr<const CFX_DIBBase> const m_pSource;
142   pdfium::raw_span<const uint32_t> m_pSrcPalette;
143   const int m_SrcWidth;
144   const int m_SrcHeight;
145   UnownedPtr<ScanlineComposerIface> const m_pDestBitmap;
146   const int m_DestWidth;
147   const int m_DestHeight;
148   const FX_RECT m_DestClip;
149   DataVector<uint8_t> m_DestScanline;
150   FixedSizeDataVector<uint8_t> m_InterBuf;
151   FX_RECT m_SrcClip;
152   int m_InterPitch;
153   int m_ExtraMaskPitch;
154   FXDIB_ResampleOptions m_ResampleOptions;
155   TransformMethod m_TransMethod;
156   State m_State = State::kInitial;
157   int m_CurRow = 0;
158   WeightTable m_WeightTable;
159 };
160 
161 #endif  // CORE_FXGE_DIB_CSTRETCHENGINE_H_
162