Home | History | Annotate | Download | only in fxge
      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);
     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);
     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 
    186   int GetWidth() const { return m_Width; }
    187   int GetHeight() const { return m_Height; }
    188 
    189   FXDIB_Format GetFormat() const {
    190     return (FXDIB_Format)(m_AlphaFlag * 0x100 + m_bpp);
    191   }
    192   uint32_t GetPitch() const { return m_Pitch; }
    193   uint32_t* GetPalette() const { return m_pPalette.get(); }
    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.
    199   bool IsAlphaMask() const { return m_AlphaFlag == 1; }
    200   bool HasAlpha() const { return !!(m_AlphaFlag & 2); }
    201   bool IsOpaqueImage() const { return !(m_AlphaFlag & 3); }
    202   bool IsCmykImage() const { return !!(m_AlphaFlag & 4); }
    203 
    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);
    211   uint32_t GetPaletteArgb(int index) const { return GetPaletteEntry(index); }
    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 
    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:
    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 
    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 
    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 
    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