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