• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 PDFium Authors. All rights reserved.
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_FX_DIB_H_
8 #define CORE_FXGE_FX_DIB_H_
9 
10 #include <memory>
11 #include <vector>
12 
13 #include "core/fxcrt/cfx_shared_copy_on_write.h"
14 #include "core/fxcrt/fx_basic.h"
15 #include "core/fxcrt/fx_coordinates.h"
16 
17 enum FXDIB_Format {
18   FXDIB_Invalid = 0,
19   FXDIB_1bppMask = 0x101,
20   FXDIB_1bppRgb = 0x001,
21   FXDIB_1bppCmyk = 0x401,
22   FXDIB_8bppMask = 0x108,
23   FXDIB_8bppRgb = 0x008,
24   FXDIB_8bppRgba = 0x208,
25   FXDIB_8bppCmyk = 0x408,
26   FXDIB_8bppCmyka = 0x608,
27   FXDIB_Rgb = 0x018,
28   FXDIB_Rgba = 0x218,
29   FXDIB_Rgb32 = 0x020,
30   FXDIB_Argb = 0x220,
31   FXDIB_Cmyk = 0x420,
32   FXDIB_Cmyka = 0x620,
33 };
34 
35 enum FXDIB_Channel {
36   FXDIB_Red = 1,
37   FXDIB_Green,
38   FXDIB_Blue,
39   FXDIB_Cyan,
40   FXDIB_Magenta,
41   FXDIB_Yellow,
42   FXDIB_Black,
43   FXDIB_Alpha
44 };
45 
46 #define FXDIB_DOWNSAMPLE 0x04
47 #define FXDIB_INTERPOL 0x20
48 #define FXDIB_BICUBIC_INTERPOL 0x80
49 #define FXDIB_NOSMOOTH 0x100
50 #define FXDIB_BLEND_NORMAL 0
51 #define FXDIB_BLEND_MULTIPLY 1
52 #define FXDIB_BLEND_SCREEN 2
53 #define FXDIB_BLEND_OVERLAY 3
54 #define FXDIB_BLEND_DARKEN 4
55 #define FXDIB_BLEND_LIGHTEN 5
56 
57 #define FXDIB_BLEND_COLORDODGE 6
58 #define FXDIB_BLEND_COLORBURN 7
59 #define FXDIB_BLEND_HARDLIGHT 8
60 #define FXDIB_BLEND_SOFTLIGHT 9
61 #define FXDIB_BLEND_DIFFERENCE 10
62 #define FXDIB_BLEND_EXCLUSION 11
63 #define FXDIB_BLEND_NONSEPARABLE 21
64 #define FXDIB_BLEND_HUE 21
65 #define FXDIB_BLEND_SATURATION 22
66 #define FXDIB_BLEND_COLOR 23
67 #define FXDIB_BLEND_LUMINOSITY 24
68 #define FXDIB_BLEND_UNSUPPORTED -1
69 typedef uint32_t FX_ARGB;
70 typedef uint32_t FX_COLORREF;
71 typedef uint32_t FX_CMYK;
72 class CFX_ClipRgn;
73 class CFX_DIBSource;
74 class CFX_DIBitmap;
75 class CStretchEngine;
76 
77 #define FXSYS_RGB(r, g, b) ((r) | ((g) << 8) | ((b) << 16))
78 #define FXSYS_GetRValue(rgb) ((rgb)&0xff)
79 #define FXSYS_GetGValue(rgb) (((rgb) >> 8) & 0xff)
80 #define FXSYS_GetBValue(rgb) (((rgb) >> 16) & 0xff)
81 #define FX_CCOLOR(val) (255 - (val))
82 #define FXSYS_CMYK(c, m, y, k) (((c) << 24) | ((m) << 16) | ((y) << 8) | (k))
83 #define FXSYS_GetCValue(cmyk) ((uint8_t)((cmyk) >> 24) & 0xff)
84 #define FXSYS_GetMValue(cmyk) ((uint8_t)((cmyk) >> 16) & 0xff)
85 #define FXSYS_GetYValue(cmyk) ((uint8_t)((cmyk) >> 8) & 0xff)
86 #define FXSYS_GetKValue(cmyk) ((uint8_t)(cmyk)&0xff)
87 void CmykDecode(FX_CMYK cmyk, int& c, int& m, int& y, int& k);
CmykEncode(int c,int m,int y,int k)88 inline FX_CMYK CmykEncode(int c, int m, int y, int k) {
89   return (c << 24) | (m << 16) | (y << 8) | k;
90 }
91 void ArgbDecode(FX_ARGB argb, int& a, int& r, int& g, int& b);
92 void ArgbDecode(FX_ARGB argb, int& a, FX_COLORREF& rgb);
ArgbEncode(int a,int r,int g,int b)93 inline FX_ARGB ArgbEncode(int a, int r, int g, int b) {
94   return (a << 24) | (r << 16) | (g << 8) | b;
95 }
96 FX_ARGB ArgbEncode(int a, FX_COLORREF rgb);
97 #define FXARGB_A(argb) ((uint8_t)((argb) >> 24))
98 #define FXARGB_R(argb) ((uint8_t)((argb) >> 16))
99 #define FXARGB_G(argb) ((uint8_t)((argb) >> 8))
100 #define FXARGB_B(argb) ((uint8_t)(argb))
101 #define FXARGB_MAKE(a, r, g, b) \
102   (((uint32_t)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))
103 #define FXARGB_MUL_ALPHA(argb, alpha) \
104   (((((argb) >> 24) * (alpha) / 255) << 24) | ((argb)&0xffffff))
105 #define FXRGB2GRAY(r, g, b) (((b)*11 + (g)*59 + (r)*30) / 100)
106 #define FXCMYK2GRAY(c, m, y, k)                                       \
107   (((255 - (c)) * (255 - (k)) * 30 + (255 - (m)) * (255 - (k)) * 59 + \
108     (255 - (y)) * (255 - (k)) * 11) /                                 \
109    25500)
110 #define FXDIB_ALPHA_MERGE(backdrop, source, source_alpha) \
111   (((backdrop) * (255 - (source_alpha)) + (source) * (source_alpha)) / 255)
112 #define FXDIB_ALPHA_UNION(dest, src) ((dest) + (src) - (dest) * (src) / 255)
113 #define FXCMYK_GETDIB(p)                                    \
114   ((((uint8_t*)(p))[0] << 24 | (((uint8_t*)(p))[1] << 16) | \
115     (((uint8_t*)(p))[2] << 8) | ((uint8_t*)(p))[3]))
116 #define FXCMYK_SETDIB(p, cmyk)  ((uint8_t*)(p))[0] = (uint8_t)((cmyk) >> 24), \
117         ((uint8_t*)(p))[1] = (uint8_t)((cmyk) >> 16), \
118                               ((uint8_t*)(p))[2] = (uint8_t)((cmyk) >> 8), \
119                                       ((uint8_t*)(p))[3] = (uint8_t)(cmyk))
120 #define FXARGB_GETDIB(p)                              \
121   ((((uint8_t*)(p))[0]) | (((uint8_t*)(p))[1] << 8) | \
122    (((uint8_t*)(p))[2] << 16) | (((uint8_t*)(p))[3] << 24))
123 #define FXARGB_SETDIB(p, argb)                  \
124   ((uint8_t*)(p))[0] = (uint8_t)(argb),         \
125   ((uint8_t*)(p))[1] = (uint8_t)((argb) >> 8),  \
126   ((uint8_t*)(p))[2] = (uint8_t)((argb) >> 16), \
127   ((uint8_t*)(p))[3] = (uint8_t)((argb) >> 24)
128 #define FXARGB_COPY(dest, src)                      \
129   *(uint8_t*)(dest) = *(uint8_t*)(src),             \
130   *((uint8_t*)(dest) + 1) = *((uint8_t*)(src) + 1), \
131   *((uint8_t*)(dest) + 2) = *((uint8_t*)(src) + 2), \
132   *((uint8_t*)(dest) + 3) = *((uint8_t*)(src) + 3)
133 #define FXCMYK_COPY(dest, src)                      \
134   *(uint8_t*)(dest) = *(uint8_t*)(src),             \
135   *((uint8_t*)(dest) + 1) = *((uint8_t*)(src) + 1), \
136   *((uint8_t*)(dest) + 2) = *((uint8_t*)(src) + 2), \
137   *((uint8_t*)(dest) + 3) = *((uint8_t*)(src) + 3)
138 #define FXARGB_SETRGBORDERDIB(p, argb)          \
139   ((uint8_t*)(p))[3] = (uint8_t)(argb >> 24),   \
140   ((uint8_t*)(p))[0] = (uint8_t)((argb) >> 16), \
141   ((uint8_t*)(p))[1] = (uint8_t)((argb) >> 8),  \
142   ((uint8_t*)(p))[2] = (uint8_t)(argb)
143 #define FXARGB_GETRGBORDERDIB(p)                     \
144   (((uint8_t*)(p))[2]) | (((uint8_t*)(p))[1] << 8) | \
145       (((uint8_t*)(p))[0] << 16) | (((uint8_t*)(p))[3] << 24)
146 #define FXARGB_RGBORDERCOPY(dest, src)                                   \
147   *((uint8_t*)(dest) + 3) = *((uint8_t*)(src) + 3),                      \
148                        *(uint8_t*)(dest) = *((uint8_t*)(src) + 2),       \
149                        *((uint8_t*)(dest) + 1) = *((uint8_t*)(src) + 1), \
150                        *((uint8_t*)(dest) + 2) = *((uint8_t*)(src))
151 #define FXARGB_TODIB(argb) (argb)
152 #define FXCMYK_TODIB(cmyk)                                    \
153   ((uint8_t)((cmyk) >> 24) | ((uint8_t)((cmyk) >> 16)) << 8 | \
154    ((uint8_t)((cmyk) >> 8)) << 16 | ((uint8_t)(cmyk) << 24))
155 #define FXARGB_TOBGRORDERDIB(argb)                       \
156   ((uint8_t)(argb >> 16) | ((uint8_t)(argb >> 8)) << 8 | \
157    ((uint8_t)(argb)) << 16 | ((uint8_t)(argb >> 24) << 24))
158 #define FXGETFLAG_COLORTYPE(flag) (uint8_t)((flag) >> 8)
159 #define FXGETFLAG_ALPHA_FILL(flag) (uint8_t)(flag)
160 
161 bool ConvertBuffer(FXDIB_Format dest_format,
162                    uint8_t* dest_buf,
163                    int dest_pitch,
164                    int width,
165                    int height,
166                    const CFX_DIBSource* pSrcBitmap,
167                    int src_left,
168                    int src_top,
169                    std::unique_ptr<uint32_t, FxFreeDeleter>* pal);
170 
171 class CFX_DIBSource {
172  public:
173   virtual ~CFX_DIBSource();
174 
175   virtual uint8_t* GetBuffer() const;
176   virtual const uint8_t* GetScanline(int line) const = 0;
177   virtual bool SkipToScanline(int line, IFX_Pause* pPause) const;
178   virtual void DownSampleScanline(int line,
179                                   uint8_t* dest_scan,
180                                   int dest_bpp,
181                                   int dest_width,
182                                   bool bFlipX,
183                                   int clip_left,
184                                   int clip_width) const = 0;
185 
GetWidth()186   int GetWidth() const { return m_Width; }
GetHeight()187   int GetHeight() const { return m_Height; }
188 
GetFormat()189   FXDIB_Format GetFormat() const {
190     return (FXDIB_Format)(m_AlphaFlag * 0x100 + m_bpp);
191   }
GetPitch()192   uint32_t GetPitch() const { return m_Pitch; }
GetPalette()193   uint32_t* GetPalette() const { return m_pPalette.get(); }
GetBPP()194   int GetBPP() const { return m_bpp; }
195 
196   // TODO(thestig): Investigate this. Given the possible values of FXDIB_Format,
197   // it feels as though this should be implemented as !!(m_AlphaFlag & 1) and
198   // IsOpaqueImage() below should never be able to return true.
IsAlphaMask()199   bool IsAlphaMask() const { return m_AlphaFlag == 1; }
HasAlpha()200   bool HasAlpha() const { return !!(m_AlphaFlag & 2); }
IsOpaqueImage()201   bool IsOpaqueImage() const { return !(m_AlphaFlag & 3); }
IsCmykImage()202   bool IsCmykImage() const { return !!(m_AlphaFlag & 4); }
203 
GetPaletteSize()204   int GetPaletteSize() const {
205     return IsAlphaMask() ? 0 : (m_bpp == 1 ? 2 : (m_bpp == 8 ? 256 : 0));
206   }
207 
208   uint32_t GetPaletteEntry(int index) const;
209 
210   void SetPaletteEntry(int index, uint32_t color);
GetPaletteArgb(int index)211   uint32_t GetPaletteArgb(int index) const { return GetPaletteEntry(index); }
SetPaletteArgb(int index,uint32_t color)212   void SetPaletteArgb(int index, uint32_t color) {
213     SetPaletteEntry(index, color);
214   }
215 
216   // Copies into internally-owned palette.
217   void SetPalette(const uint32_t* pSrcPal);
218 
219   std::unique_ptr<CFX_DIBitmap> Clone(const FX_RECT* pClip = nullptr) const;
220   std::unique_ptr<CFX_DIBitmap> CloneConvert(FXDIB_Format format) const;
221   std::unique_ptr<CFX_DIBitmap> StretchTo(int dest_width,
222                                           int dest_height,
223                                           uint32_t flags = 0,
224                                           const FX_RECT* pClip = nullptr) const;
225   std::unique_ptr<CFX_DIBitmap> TransformTo(
226       const CFX_Matrix* pMatrix,
227       int& left,
228       int& top,
229       uint32_t flags = 0,
230       const FX_RECT* pClip = nullptr) const;
231   std::unique_ptr<CFX_DIBitmap> SwapXY(bool bXFlip,
232                                        bool bYFlip,
233                                        const FX_RECT* pClip = nullptr) const;
234   std::unique_ptr<CFX_DIBitmap> FlipImage(bool bXFlip, bool bYFlip) const;
235 
236   std::unique_ptr<CFX_DIBitmap> CloneAlphaMask(
237       const FX_RECT* pClip = nullptr) const;
238 
239   // Copies into internally-owned mask.
240   bool SetAlphaMask(const CFX_DIBSource* pAlphaMask,
241                     const FX_RECT* pClip = nullptr);
242 
243 
244   void GetOverlapRect(int& dest_left,
245                       int& dest_top,
246                       int& width,
247                       int& height,
248                       int src_width,
249                       int src_height,
250                       int& src_left,
251                       int& src_top,
252                       const CFX_ClipRgn* pClipRgn);
253 
254 #if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_
255   void DebugVerifyBitmapIsPreMultiplied(void* buffer = nullptr) const;
256 #endif
257 
258   CFX_DIBitmap* m_pAlphaMask;
259 
260  protected:
261   CFX_DIBSource();
262 
263   void BuildPalette();
264   bool BuildAlphaMask();
265   int FindPalette(uint32_t color) const;
266   void GetPalette(uint32_t* pal, int alpha) const;
267 
268   int m_Width;
269   int m_Height;
270   int m_bpp;
271   uint32_t m_AlphaFlag;
272   uint32_t m_Pitch;
273   // TODO(weili): Use std::vector for this.
274   std::unique_ptr<uint32_t, FxFreeDeleter> m_pPalette;
275 };
276 
277 class CFX_DIBitmap : public CFX_DIBSource {
278  public:
279   CFX_DIBitmap();
280   explicit CFX_DIBitmap(const CFX_DIBitmap& src);
281   ~CFX_DIBitmap() override;
282 
283   bool Create(int width,
284               int height,
285               FXDIB_Format format,
286               uint8_t* pBuffer = nullptr,
287               int pitch = 0);
288 
289   bool Copy(const CFX_DIBSource* pSrc);
290 
291   // CFX_DIBSource
292   uint8_t* GetBuffer() const override;
293   const uint8_t* GetScanline(int line) const override;
294   void DownSampleScanline(int line,
295                           uint8_t* dest_scan,
296                           int dest_bpp,
297                           int dest_width,
298                           bool bFlipX,
299                           int clip_left,
300                           int clip_width) const override;
301 
302   void TakeOver(CFX_DIBitmap* pSrcBitmap);
303 
304   bool ConvertFormat(FXDIB_Format format);
305 
306   void Clear(uint32_t color);
307 
308   uint32_t GetPixel(int x, int y) const;
309 
310   void SetPixel(int x, int y, uint32_t color);
311 
312   bool LoadChannel(FXDIB_Channel destChannel,
313                    CFX_DIBSource* pSrcBitmap,
314                    FXDIB_Channel srcChannel);
315 
316   bool LoadChannel(FXDIB_Channel destChannel, int value);
317 
318   bool MultiplyAlpha(int alpha);
319 
320   bool MultiplyAlpha(CFX_DIBSource* pAlphaMask);
321 
322   bool TransferBitmap(int dest_left,
323                       int dest_top,
324                       int width,
325                       int height,
326                       const CFX_DIBSource* pSrcBitmap,
327                       int src_left,
328                       int src_top);
329 
330   bool CompositeBitmap(int dest_left,
331                        int dest_top,
332                        int width,
333                        int height,
334                        const CFX_DIBSource* pSrcBitmap,
335                        int src_left,
336                        int src_top,
337                        int blend_type = FXDIB_BLEND_NORMAL,
338                        const CFX_ClipRgn* pClipRgn = nullptr,
339                        bool bRgbByteOrder = false,
340                        void* pIccTransform = nullptr);
341 
342   bool TransferMask(int dest_left,
343                     int dest_top,
344                     int width,
345                     int height,
346                     const CFX_DIBSource* pMask,
347                     uint32_t color,
348                     int src_left,
349                     int src_top,
350                     int alpha_flag = 0,
351                     void* pIccTransform = nullptr);
352 
353   bool CompositeMask(int dest_left,
354                      int dest_top,
355                      int width,
356                      int height,
357                      const CFX_DIBSource* pMask,
358                      uint32_t color,
359                      int src_left,
360                      int src_top,
361                      int blend_type = FXDIB_BLEND_NORMAL,
362                      const CFX_ClipRgn* pClipRgn = nullptr,
363                      bool bRgbByteOrder = false,
364                      int alpha_flag = 0,
365                      void* pIccTransform = nullptr);
366 
367   bool CompositeRect(int dest_left,
368                      int dest_top,
369                      int width,
370                      int height,
371                      uint32_t color,
372                      int alpha_flag = 0,
373                      void* pIccTransform = nullptr);
374 
375   bool ConvertColorScale(uint32_t forecolor, uint32_t backcolor);
376 
377 #if defined _SKIA_SUPPORT_ || _SKIA_SUPPORT_PATHS_
378   void PreMultiply();
379 #endif
380 #if defined _SKIA_SUPPORT_PATHS_
381   void UnPreMultiply();
382 #endif
383 
384  protected:
385   bool GetGrayData(void* pIccTransform = nullptr);
386 
387 #if defined _SKIA_SUPPORT_PATHS_
388   enum class Format { kCleared, kPreMultiplied, kUnPreMultiplied };
389 #endif
390 
391   uint8_t* m_pBuffer;
392 #if defined _SKIA_SUPPORT_PATHS_
393   Format m_nFormat;
394 #endif
395   bool m_bExtBuf;
396 };
397 
398 class CFX_DIBExtractor {
399  public:
400   explicit CFX_DIBExtractor(const CFX_DIBSource* pSrc);
401   ~CFX_DIBExtractor();
402 
GetBitmap()403   CFX_DIBitmap* GetBitmap() { return m_pBitmap.get(); }
404 
405  private:
406   std::unique_ptr<CFX_DIBitmap> m_pBitmap;
407 };
408 
409 typedef CFX_SharedCopyOnWrite<CFX_DIBitmap> CFX_DIBitmapRef;
410 
411 class CFX_FilteredDIB : public CFX_DIBSource {
412  public:
413   CFX_FilteredDIB();
414   ~CFX_FilteredDIB() override;
415 
416   void LoadSrc(const CFX_DIBSource* pSrc, bool bAutoDropSrc = false);
417 
418   virtual FXDIB_Format GetDestFormat() = 0;
419 
420   virtual uint32_t* GetDestPalette() = 0;
421 
422   virtual void TranslateScanline(const uint8_t* src_buf,
423                                  std::vector<uint8_t>* dest_buf) const = 0;
424 
425   virtual void TranslateDownSamples(uint8_t* dest_buf,
426                                     const uint8_t* src_buf,
427                                     int pixels,
428                                     int Bpp) const = 0;
429 
430  protected:
431   // CFX_DIBSource
432   const uint8_t* GetScanline(int line) const override;
433   void DownSampleScanline(int line,
434                           uint8_t* dest_scan,
435                           int dest_bpp,
436                           int dest_width,
437                           bool bFlipX,
438                           int clip_left,
439                           int clip_width) const override;
440 
441   const CFX_DIBSource* m_pSrc;
442   bool m_bAutoDropSrc;
443   mutable std::vector<uint8_t> m_Scanline;
444 };
445 
446 class IFX_ScanlineComposer {
447  public:
~IFX_ScanlineComposer()448   virtual ~IFX_ScanlineComposer() {}
449 
450   virtual void ComposeScanline(int line,
451                                const uint8_t* scanline,
452                                const uint8_t* scan_extra_alpha = nullptr) = 0;
453 
454   virtual bool SetInfo(int width,
455                        int height,
456                        FXDIB_Format src_format,
457                        uint32_t* pSrcPalette) = 0;
458 };
459 
460 class CFX_ScanlineCompositor {
461  public:
462   CFX_ScanlineCompositor();
463 
464   ~CFX_ScanlineCompositor();
465 
466   bool Init(FXDIB_Format dest_format,
467             FXDIB_Format src_format,
468             int32_t width,
469             uint32_t* pSrcPalette,
470             uint32_t mask_color,
471             int blend_type,
472             bool bClip,
473             bool bRgbByteOrder = false,
474             int alpha_flag = 0,
475             void* pIccTransform = nullptr);
476 
477   void CompositeRgbBitmapLine(uint8_t* dest_scan,
478                               const uint8_t* src_scan,
479                               int width,
480                               const uint8_t* clip_scan,
481                               const uint8_t* src_extra_alpha = nullptr,
482                               uint8_t* dst_extra_alpha = nullptr);
483 
484   void CompositePalBitmapLine(uint8_t* dest_scan,
485                               const uint8_t* src_scan,
486                               int src_left,
487                               int width,
488                               const uint8_t* clip_scan,
489                               const uint8_t* src_extra_alpha = nullptr,
490                               uint8_t* dst_extra_alpha = nullptr);
491 
492   void CompositeByteMaskLine(uint8_t* dest_scan,
493                              const uint8_t* src_scan,
494                              int width,
495                              const uint8_t* clip_scan,
496                              uint8_t* dst_extra_alpha = nullptr);
497 
498   void CompositeBitMaskLine(uint8_t* dest_scan,
499                             const uint8_t* src_scan,
500                             int src_left,
501                             int width,
502                             const uint8_t* clip_scan,
503                             uint8_t* dst_extra_alpha = nullptr);
504 
505  protected:
506   int m_Transparency;
507   FXDIB_Format m_SrcFormat, m_DestFormat;
508   uint32_t* m_pSrcPalette;
509 
510   int m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, m_MaskBlack;
511   int m_BlendType;
512   void* m_pIccTransform;
513   uint8_t* m_pCacheScanline;
514   int m_CacheSize;
515   bool m_bRgbByteOrder;
516 };
517 
518 class CFX_BitmapComposer : public IFX_ScanlineComposer {
519  public:
520   CFX_BitmapComposer();
521   ~CFX_BitmapComposer() override;
522 
523   void Compose(CFX_DIBitmap* pDest,
524                const CFX_ClipRgn* pClipRgn,
525                int bitmap_alpha,
526                uint32_t mask_color,
527                FX_RECT& dest_rect,
528                bool bVertical,
529                bool bFlipX,
530                bool bFlipY,
531                bool bRgbByteOrder = false,
532                int alpha_flag = 0,
533                void* pIccTransform = nullptr,
534                int blend_type = FXDIB_BLEND_NORMAL);
535 
536   // IFX_ScanlineComposer
537   bool SetInfo(int width,
538                int height,
539                FXDIB_Format src_format,
540                uint32_t* pSrcPalette) override;
541 
542   void ComposeScanline(int line,
543                        const uint8_t* scanline,
544                        const uint8_t* scan_extra_alpha) override;
545 
546  protected:
547   void DoCompose(uint8_t* dest_scan,
548                  const uint8_t* src_scan,
549                  int dest_width,
550                  const uint8_t* clip_scan,
551                  const uint8_t* src_extra_alpha = nullptr,
552                  uint8_t* dst_extra_alpha = nullptr);
553   CFX_DIBitmap* m_pBitmap;
554   const CFX_ClipRgn* m_pClipRgn;
555   FXDIB_Format m_SrcFormat;
556   int m_DestLeft, m_DestTop, m_DestWidth, m_DestHeight, m_BitmapAlpha;
557   uint32_t m_MaskColor;
558   const CFX_DIBitmap* m_pClipMask;
559   CFX_ScanlineCompositor m_Compositor;
560   bool m_bVertical, m_bFlipX, m_bFlipY;
561   int m_AlphaFlag;
562   void* m_pIccTransform;
563   bool m_bRgbByteOrder;
564   int m_BlendType;
565   void ComposeScanlineV(int line,
566                         const uint8_t* scanline,
567                         const uint8_t* scan_extra_alpha = nullptr);
568   uint8_t* m_pScanlineV;
569   uint8_t* m_pClipScanV;
570   uint8_t* m_pAddClipScan;
571   uint8_t* m_pScanlineAlphaV;
572 };
573 
574 class CFX_BitmapStorer : public IFX_ScanlineComposer {
575  public:
576   CFX_BitmapStorer();
577   ~CFX_BitmapStorer() override;
578 
579   // IFX_ScanlineComposer
580   void ComposeScanline(int line,
581                        const uint8_t* scanline,
582                        const uint8_t* scan_extra_alpha) override;
583   bool SetInfo(int width,
584                int height,
585                FXDIB_Format src_format,
586                uint32_t* pSrcPalette) override;
587 
GetBitmap()588   CFX_DIBitmap* GetBitmap() { return m_pBitmap.get(); }
589   std::unique_ptr<CFX_DIBitmap> Detach();
590   void Replace(std::unique_ptr<CFX_DIBitmap> pBitmap);
591 
592  private:
593   std::unique_ptr<CFX_DIBitmap> m_pBitmap;
594 };
595 
596 class CFX_ImageStretcher {
597  public:
598   CFX_ImageStretcher(IFX_ScanlineComposer* pDest,
599                      const CFX_DIBSource* pSource,
600                      int dest_width,
601                      int dest_height,
602                      const FX_RECT& bitmap_rect,
603                      uint32_t flags);
604   ~CFX_ImageStretcher();
605 
606   bool Start();
607   bool Continue(IFX_Pause* pPause);
608 
source()609   const CFX_DIBSource* source() { return m_pSource; }
610 
611  private:
612   bool StartQuickStretch();
613   bool StartStretch();
614   bool ContinueQuickStretch(IFX_Pause* pPause);
615   bool ContinueStretch(IFX_Pause* pPause);
616 
617   IFX_ScanlineComposer* const m_pDest;
618   const CFX_DIBSource* const m_pSource;
619   std::unique_ptr<CStretchEngine> m_pStretchEngine;
620   std::unique_ptr<uint8_t, FxFreeDeleter> m_pScanline;
621   std::unique_ptr<uint8_t, FxFreeDeleter> m_pMaskScanline;
622   const uint32_t m_Flags;
623   bool m_bFlipX;
624   bool m_bFlipY;
625   int m_DestWidth;
626   int m_DestHeight;
627   FX_RECT m_ClipRect;
628   const FXDIB_Format m_DestFormat;
629   const int m_DestBPP;
630   int m_LineIndex;
631 };
632 
633 class CFX_ImageTransformer {
634  public:
635   CFX_ImageTransformer(const CFX_DIBSource* pSrc,
636                        const CFX_Matrix* pMatrix,
637                        int flags,
638                        const FX_RECT* pClip);
639   ~CFX_ImageTransformer();
640 
641   bool Start();
642   bool Continue(IFX_Pause* pPause);
643 
result()644   const FX_RECT& result() const { return m_result; }
645   std::unique_ptr<CFX_DIBitmap> DetachBitmap();
646 
647  private:
648   const CFX_DIBSource* const m_pSrc;
649   const CFX_Matrix* const m_pMatrix;
650   const FX_RECT* const m_pClip;
651   FX_RECT m_StretchClip;
652   FX_RECT m_result;
653   CFX_Matrix m_dest2stretch;
654   std::unique_ptr<CFX_ImageStretcher> m_Stretcher;
655   CFX_BitmapStorer m_Storer;
656   const uint32_t m_Flags;
657   int m_Status;
658 };
659 
660 class CFX_ImageRenderer {
661  public:
662   CFX_ImageRenderer();
663   ~CFX_ImageRenderer();
664 
665   bool Start(CFX_DIBitmap* pDevice,
666              const CFX_ClipRgn* pClipRgn,
667              const CFX_DIBSource* pSource,
668              int bitmap_alpha,
669              uint32_t mask_color,
670              const CFX_Matrix* pMatrix,
671              uint32_t dib_flags,
672              bool bRgbByteOrder = false,
673              int alpha_flag = 0,
674              void* pIccTransform = nullptr,
675              int blend_type = FXDIB_BLEND_NORMAL);
676 
677   bool Continue(IFX_Pause* pPause);
678 
679  protected:
680   CFX_DIBitmap* m_pDevice;
681   const CFX_ClipRgn* m_pClipRgn;
682   int m_BitmapAlpha;
683   uint32_t m_MaskColor;
684   CFX_Matrix m_Matrix;
685   std::unique_ptr<CFX_ImageTransformer> m_pTransformer;
686   std::unique_ptr<CFX_ImageStretcher> m_Stretcher;
687   CFX_BitmapComposer m_Composer;
688   int m_Status;
689   FX_RECT m_ClipBox;
690   uint32_t m_Flags;
691   int m_AlphaFlag;
692   void* m_pIccTransform;
693   bool m_bRgbByteOrder;
694   int m_BlendType;
695 };
696 
697 #endif  // CORE_FXGE_FX_DIB_H_
698