• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef CORE_FXGE_DIB_FX_DIB_H_
8 #define CORE_FXGE_DIB_FX_DIB_H_
9 
10 #include <stdint.h>
11 
12 #include <utility>
13 
14 #include "core/fxcrt/compiler_specific.h"
15 
16 // Encoding:
17 // - Bits-per-pixel: value & 0xFF
18 // - Is mask: value & 0x100
19 // - Has alpha: value & 0x200
20 // - Is premultiplied-alpha: value & 0x400
21 enum class FXDIB_Format : uint16_t {
22   kInvalid = 0,
23   k1bppRgb = 0x001,
24   k8bppRgb = 0x008,
25   kBgr = 0x018,
26   kBgrx = 0x020,
27   k1bppMask = 0x101,
28   k8bppMask = 0x108,
29   kBgra = 0x220,
30 #if defined(PDF_USE_SKIA)
31   kBgraPremul = 0x620,
32 #endif
33 };
34 
35 // Endian-dependent (in theory).
36 using FX_ARGB = uint32_t;  // A in high bits, ..., B in low bits.
37 using FX_CMYK = uint32_t;  // C in high bits, ..., K in low bits.
38 
39 // FX_COLORREF, like win32 COLORREF, is BGR. i.e. 0x00BBGGRR.
40 // Note that while the non-existent alpha component should be set to 0, some
41 // parts of the codebase use 0xFFFFFFFF as a sentinel value to indicate error.
42 using FX_COLORREF = uint32_t;
43 
44 // Endian-independent, name-ordered by increasing address.
45 template <typename T>
46 struct FX_RGB_STRUCT {
47   T red = 0;
48   T green = 0;
49   T blue = 0;
50 };
51 
52 template <typename T>
53 struct FX_BGR_STRUCT {
54   T blue = 0;
55   T green = 0;
56   T red = 0;
57 };
58 
59 template <typename T>
60 struct FX_ARGB_STRUCT {
61   T alpha = 0;
62   T red = 0;
63   T green = 0;
64   T blue = 0;
65 };
66 
67 template <typename T>
68 struct FX_ABGR_STRUCT {
69   T alpha = 0;
70   T blue = 0;
71   T green = 0;
72   T red = 0;
73 };
74 
75 template <typename T>
76 struct FX_RGBA_STRUCT {
77   T red = 0;
78   T green = 0;
79   T blue = 0;
80   T alpha = 0;
81 };
82 
83 template <typename T>
84 struct FX_BGRA_STRUCT {
85   T blue = 0;
86   T green = 0;
87   T red = 0;
88   T alpha = 0;
89 };
90 
91 template <typename T>
92 struct FX_CMYK_STRUCT {
93   T cyan = 0;
94   T magenta = 0;
95   T yellow = 0;
96   T key = 0;
97 };
98 
99 template <typename T>
100 struct FX_LAB_STRUCT {
101   T lightness_star = 0;
102   T a_star = 0;
103   T b_star = 0;
104 };
105 
106 struct FXDIB_ResampleOptions {
107   FXDIB_ResampleOptions();
108 
109   bool HasAnyOptions() const;
110 
111   bool bInterpolateBilinear = false;
112   bool bHalftone = false;
113   bool bNoSmoothing = false;
114   bool bLossy = false;
115 };
116 
117 // See PDF 1.7 spec, table 7.2 and 7.3. The enum values need to be in the same
118 // order as listed in the spec.
119 enum class BlendMode {
120   kNormal = 0,
121   kMultiply,
122   kScreen,
123   kOverlay,
124   kDarken,
125   kLighten,
126   kColorDodge,
127   kColorBurn,
128   kHardLight,
129   kSoftLight,
130   kDifference,
131   kExclusion,
132   kHue,
133   kSaturation,
134   kColor,
135   kLuminosity,
136   kLast = kLuminosity,
137 };
138 
FXSYS_BGR(uint8_t b,uint8_t g,uint8_t r)139 constexpr uint32_t FXSYS_BGR(uint8_t b, uint8_t g, uint8_t r) {
140   return (b << 16) | (g << 8) | r;
141 }
142 
FXSYS_GetRValue(uint32_t bgr)143 constexpr uint8_t FXSYS_GetRValue(uint32_t bgr) {
144   return bgr & 0xff;
145 }
146 
FXSYS_GetGValue(uint32_t bgr)147 constexpr uint8_t FXSYS_GetGValue(uint32_t bgr) {
148   return (bgr >> 8) & 0xff;
149 }
150 
FXSYS_GetBValue(uint32_t bgr)151 constexpr uint8_t FXSYS_GetBValue(uint32_t bgr) {
152   return (bgr >> 16) & 0xff;
153 }
154 
FXSYS_GetUnsignedAlpha(float alpha)155 constexpr unsigned int FXSYS_GetUnsignedAlpha(float alpha) {
156   return static_cast<unsigned int>(alpha * 255.f + 0.5f);
157 }
158 
159 // Bits per pixel, not bytes.
GetBppFromFormat(FXDIB_Format format)160 inline int GetBppFromFormat(FXDIB_Format format) {
161   return static_cast<uint16_t>(format) & 0xff;
162 }
163 
164 // AKA bytes per pixel, assuming 8-bits per component.
GetCompsFromFormat(FXDIB_Format format)165 inline int GetCompsFromFormat(FXDIB_Format format) {
166   return (static_cast<uint16_t>(format) & 0xff) / 8;
167 }
168 
GetIsMaskFromFormat(FXDIB_Format format)169 inline bool GetIsMaskFromFormat(FXDIB_Format format) {
170   return !!(static_cast<uint16_t>(format) & 0x100);
171 }
172 
GetIsAlphaFromFormat(FXDIB_Format format)173 inline bool GetIsAlphaFromFormat(FXDIB_Format format) {
174   return !!(static_cast<uint16_t>(format) & 0x200);
175 }
176 
177 FX_BGRA_STRUCT<uint8_t> ArgbToBGRAStruct(FX_ARGB argb);
178 
179 // Ignores alpha.
180 FX_BGR_STRUCT<uint8_t> ArgbToBGRStruct(FX_ARGB argb);
181 
182 // Returns (a, FX_COLORREF)
183 std::pair<uint8_t, FX_COLORREF> ArgbToAlphaAndColorRef(FX_ARGB argb);
184 
185 FX_COLORREF ArgbToColorRef(FX_ARGB argb);
186 FX_ARGB AlphaAndColorRefToArgb(int a, FX_COLORREF colorref);
187 
ArgbEncode(uint32_t a,uint32_t r,uint32_t g,uint32_t b)188 constexpr FX_ARGB ArgbEncode(uint32_t a, uint32_t r, uint32_t g, uint32_t b) {
189   return (a << 24) | (r << 16) | (g << 8) | b;
190 }
191 
CmykEncode(uint32_t c,uint32_t m,uint32_t y,uint32_t k)192 constexpr FX_CMYK CmykEncode(uint32_t c, uint32_t m, uint32_t y, uint32_t k) {
193   return (c << 24) | (m << 16) | (y << 8) | k;
194 }
195 
196 #define FXARGB_A(argb) ((uint8_t)((argb) >> 24))
197 #define FXARGB_R(argb) ((uint8_t)((argb) >> 16))
198 #define FXARGB_G(argb) ((uint8_t)((argb) >> 8))
199 #define FXARGB_B(argb) ((uint8_t)(argb))
200 #define FXARGB_MUL_ALPHA(argb, alpha) \
201   (((((argb) >> 24) * (alpha) / 255) << 24) | ((argb)&0xffffff))
202 
203 #define FXRGB2GRAY(r, g, b) (((b)*11 + (g)*59 + (r)*30) / 100)
204 #define FXDIB_ALPHA_MERGE(backdrop, source, source_alpha) \
205   (((backdrop) * (255 - (source_alpha)) + (source) * (source_alpha)) / 255)
206 
207 #define FXCMYK_TODIB(cmyk)                                    \
208   ((uint8_t)((cmyk) >> 24) | ((uint8_t)((cmyk) >> 16)) << 8 | \
209    ((uint8_t)((cmyk) >> 8)) << 16 | ((uint8_t)(cmyk) << 24))
210 #define FXARGB_TOBGRORDERDIB(argb)                       \
211   ((uint8_t)(argb >> 16) | ((uint8_t)(argb >> 8)) << 8 | \
212    ((uint8_t)(argb)) << 16 | ((uint8_t)(argb >> 24) << 24))
213 
214 // SAFETY: Caller must ensure 4 valid bytes at `p`.
FXARGB_GetDIB(const uint8_t * p)215 UNSAFE_BUFFER_USAGE inline FX_ARGB FXARGB_GetDIB(const uint8_t* p) {
216   return ArgbEncode(UNSAFE_BUFFERS(p[3]), UNSAFE_BUFFERS(p[2]),
217                     UNSAFE_BUFFERS(p[1]), UNSAFE_BUFFERS(p[0]));
218 }
219 
220 // SAFETY: Caller must ensure 4 valid bytes at `p`.
FXARGB_SetDIB(uint8_t * p,uint32_t argb)221 UNSAFE_BUFFER_USAGE inline void FXARGB_SetDIB(uint8_t* p, uint32_t argb) {
222   UNSAFE_BUFFERS(p[0]) = FXARGB_B(argb);
223   UNSAFE_BUFFERS(p[1]) = FXARGB_G(argb);
224   UNSAFE_BUFFERS(p[2]) = FXARGB_R(argb);
225   UNSAFE_BUFFERS(p[3]) = FXARGB_A(argb);
226 }
227 
228 // SAFETY: Caller must ensure 4 valid bytes at `p`.
FXARGB_SetRGBOrderDIB(uint8_t * p,uint32_t argb)229 UNSAFE_BUFFER_USAGE inline void FXARGB_SetRGBOrderDIB(uint8_t* p,
230                                                       uint32_t argb) {
231   UNSAFE_BUFFERS(p[0]) = FXARGB_R(argb);
232   UNSAFE_BUFFERS(p[1]) = FXARGB_G(argb);
233   UNSAFE_BUFFERS(p[2]) = FXARGB_B(argb);
234   UNSAFE_BUFFERS(p[3]) = FXARGB_A(argb);
235 }
236 
237 // SAFETY: Caller must ensure 3 valid bytes at `dest` and `src`.
ReverseCopy3Bytes(uint8_t * dest,const uint8_t * src)238 UNSAFE_BUFFER_USAGE inline void ReverseCopy3Bytes(uint8_t* dest,
239                                                   const uint8_t* src) {
240   UNSAFE_BUFFERS(dest[2] = src[0]);
241   UNSAFE_BUFFERS(dest[1] = src[1]);
242   UNSAFE_BUFFERS(dest[0] = src[2]);
243 }
244 
245 #if defined(PDF_USE_SKIA)
246 template <typename T>
PreMultiplyColor(const T & input)247 T PreMultiplyColor(const T& input) {
248   if (input.alpha == 255) {
249     return input;
250   }
251 
252   T output;
253   output.alpha = input.alpha;
254   output.blue = static_cast<float>(input.blue) * input.alpha / 255.0f;
255   output.green = static_cast<float>(input.green) * input.alpha / 255.0f;
256   output.red = static_cast<float>(input.red) * input.alpha / 255.0f;
257   return output;
258 }
259 
260 template <typename T>
UnPreMultiplyColor(const T & input)261 T UnPreMultiplyColor(const T& input) {
262   if (input.alpha == 255) {
263     return input;
264   }
265 
266   T output;
267   output.alpha = input.alpha;
268   if (input.alpha == 0) {
269     output.blue = 0;
270     output.green = 0;
271     output.red = 0;
272   } else {
273     output.blue = static_cast<float>(input.blue) * 255.0f / input.alpha;
274     output.green = static_cast<float>(input.green) * 255.0f / input.alpha;
275     output.red = static_cast<float>(input.red) * 255.0f / input.alpha;
276   }
277   return output;
278 }
279 #endif  // defined(PDF_USE_SKIA)
280 
281 #endif  // CORE_FXGE_DIB_FX_DIB_H_
282