• 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_CFX_DIBITMAP_H_
8 #define CORE_FXGE_DIB_CFX_DIBITMAP_H_
9 
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include <optional>
14 
15 #include "core/fxcrt/compiler_specific.h"
16 #include "core/fxcrt/fx_memory_wrappers.h"
17 #include "core/fxcrt/maybe_owned.h"
18 #include "core/fxcrt/retain_ptr.h"
19 #include "core/fxcrt/span.h"
20 #include "core/fxcrt/span_util.h"
21 #include "core/fxge/dib/cfx_dibbase.h"
22 #include "core/fxge/dib/fx_dib.h"
23 
24 class CFX_DIBitmap final : public CFX_DIBBase {
25  public:
26   struct PitchAndSize {
27     uint32_t pitch;
28     uint32_t size;
29   };
30 
31 #if defined(PDF_USE_SKIA)
32   // Scoper that conditionally pre-multiplies a bitmap in the ctor and
33   // un-premultiplies in the dtor if pre-multiplication was required.
34   class ScopedPremultiplier {
35    public:
36     // `bitmap` must start out un-premultiplied.
37     // ScopedPremultiplier is a no-op if `do_premultiply` is false.
38     ScopedPremultiplier(RetainPtr<CFX_DIBitmap> bitmap, bool do_premultiply);
39     ~ScopedPremultiplier();
40 
41    private:
42     RetainPtr<CFX_DIBitmap> const bitmap_;
43     const bool do_premultiply_;
44   };
45 #endif  // defined(PDF_USE_SKIA)
46 
47   CONSTRUCT_VIA_MAKE_RETAIN;
48 
49   [[nodiscard]] bool Create(int width, int height, FXDIB_Format format);
50   [[nodiscard]] bool Create(int width,
51                             int height,
52                             FXDIB_Format format,
53                             uint8_t* pBuffer,
54                             uint32_t pitch);
55 
56   bool Copy(RetainPtr<const CFX_DIBBase> source);
57 
58   // CFX_DIBBase
59   pdfium::span<const uint8_t> GetScanline(int line) const override;
60   size_t GetEstimatedImageMemoryBurden() const override;
61 #if BUILDFLAG(IS_WIN) || defined(PDF_USE_SKIA)
62   RetainPtr<const CFX_DIBitmap> RealizeIfNeeded() const override;
63 #endif
64 
65   pdfium::span<const uint8_t> GetBuffer() const;
GetWritableBuffer()66   pdfium::span<uint8_t> GetWritableBuffer() {
67     pdfium::span<const uint8_t> src = GetBuffer();
68     // SAFETY: const_cast<>() doesn't change size.
69     return UNSAFE_BUFFERS(
70         pdfium::make_span(const_cast<uint8_t*>(src.data()), src.size()));
71   }
72 
73   // Note that the returned scanline includes unused space at the end, if any.
GetWritableScanline(int line)74   pdfium::span<uint8_t> GetWritableScanline(int line) {
75     pdfium::span<const uint8_t> src = GetScanline(line);
76     // SAFETY: const_cast<>() doesn't change size.
77     return UNSAFE_BUFFERS(
78         pdfium::make_span(const_cast<uint8_t*>(src.data()), src.size()));
79   }
80 
81   // Note that the returned scanline does not include unused space at the end,
82   // if any.
83   template <typename T>
GetWritableScanlineAs(int line)84   pdfium::span<T> GetWritableScanlineAs(int line) {
85     return fxcrt::reinterpret_span<T>(GetWritableScanline(line))
86         .first(GetWidth());
87   }
88 
89   void TakeOver(RetainPtr<CFX_DIBitmap>&& pSrcBitmap);
90   bool ConvertFormat(FXDIB_Format format);
91   void Clear(uint32_t color);
92 
93 #if defined(PDF_USE_SKIA)
94   uint32_t GetPixelForTesting(int x, int y) const;
95 #endif  // defined(PDF_USE_SKIA)
96 
97   // Requires `this` to be of format `FXDIB_Format::kBgra`.
98   void SetRedFromAlpha();
99 
100   // Requires `this` to be of format `FXDIB_Format::kBgra`.
101   void SetUniformOpaqueAlpha();
102 
103   // TODO(crbug.com/pdfium/2007): Migrate callers to `CFX_RenderDevice`.
104   bool MultiplyAlpha(float alpha);
105   bool MultiplyAlphaMask(RetainPtr<const CFX_DIBitmap> mask);
106 
107   bool TransferBitmap(int width,
108                       int height,
109                       RetainPtr<const CFX_DIBBase> source,
110                       int src_left,
111                       int src_top);
112 
113   bool CompositeBitmap(int dest_left,
114                        int dest_top,
115                        int width,
116                        int height,
117                        RetainPtr<const CFX_DIBBase> source,
118                        int src_left,
119                        int src_top,
120                        BlendMode blend_type,
121                        const CFX_AggClipRgn* pClipRgn,
122                        bool bRgbByteOrder);
123 
124   bool CompositeMask(int dest_left,
125                      int dest_top,
126                      int width,
127                      int height,
128                      RetainPtr<const CFX_DIBBase> pMask,
129                      uint32_t color,
130                      int src_left,
131                      int src_top,
132                      BlendMode blend_type,
133                      const CFX_AggClipRgn* pClipRgn,
134                      bool bRgbByteOrder);
135 
136   void CompositeOneBPPMask(int dest_left,
137                            int dest_top,
138                            int width,
139                            int height,
140                            RetainPtr<const CFX_DIBBase> source,
141                            int src_left,
142                            int src_top);
143 
144   bool CompositeRect(int dest_left,
145                      int dest_top,
146                      int width,
147                      int height,
148                      uint32_t color);
149 
150   bool ConvertColorScale(uint32_t forecolor, uint32_t backcolor);
151 
152   // |width| and |height| must be greater than 0.
153   // |format| must have a valid bits per pixel count.
154   // If |pitch| is zero, then the actual pitch will be calculated based on
155   // |width| and |format|.
156   // If |pitch| is non-zero, then that be used as the actual pitch.
157   // The actual pitch will be used to calculate the size.
158   // Returns the calculated pitch and size on success, or nullopt on failure.
159   static std::optional<PitchAndSize> CalculatePitchAndSize(int width,
160                                                            int height,
161                                                            FXDIB_Format format,
162                                                            uint32_t pitch);
163 
164 #if defined(PDF_USE_SKIA)
165   // Converts from/to un-pre-multiplied alpha if necessary.
166   void PreMultiply();
167   void UnPreMultiply();
168 #endif  // defined(PDF_USE_SKIA)
169 
170  private:
171   enum class Channel : uint8_t { kRed, kAlpha };
172 
173   CFX_DIBitmap();
174   CFX_DIBitmap(const CFX_DIBitmap& src);
175   ~CFX_DIBitmap() override;
176 
177   void ConvertBGRColorScale(uint32_t forecolor, uint32_t backcolor);
178   bool TransferWithUnequalFormats(FXDIB_Format dest_format,
179                                   int dest_left,
180                                   int dest_top,
181                                   int width,
182                                   int height,
183                                   RetainPtr<const CFX_DIBBase> source,
184                                   int src_left,
185                                   int src_top);
186   void TransferWithMultipleBPP(int dest_left,
187                                int dest_top,
188                                int width,
189                                int height,
190                                RetainPtr<const CFX_DIBBase> source,
191                                int src_left,
192                                int src_top);
193   void TransferEqualFormatsOneBPP(int dest_left,
194                                   int dest_top,
195                                   int width,
196                                   int height,
197                                   RetainPtr<const CFX_DIBBase> source,
198                                   int src_left,
199                                   int src_top);
200 
201   MaybeOwned<uint8_t, FxFreeDeleter> m_pBuffer;
202 };
203 
204 #endif  // CORE_FXGE_DIB_CFX_DIBITMAP_H_
205