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