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