1 | // [Blend2D] |
2 | // 2D Vector Graphics Powered by a JIT Compiler. |
3 | // |
4 | // [License] |
5 | // Zlib - See LICENSE.md file in the package. |
6 | |
7 | #ifndef BLEND2D_BLPIXELOPS_P_H |
8 | #define BLEND2D_BLPIXELOPS_P_H |
9 | |
10 | #include "./blapi-internal_p.h" |
11 | #include "./blrgba_p.h" |
12 | #include "./blsimd_p.h" |
13 | #include "./bltables_p.h" |
14 | |
15 | //! \cond INTERNAL |
16 | //! \addtogroup blend2d_internal |
17 | //! \{ |
18 | |
19 | namespace { |
20 | |
21 | // ============================================================================ |
22 | // [PixelOps - Conversion] |
23 | // ============================================================================ |
24 | |
25 | static BL_INLINE uint32_t bl_xrgb32_0888_from_xrgb16_0555(uint32_t src) noexcept { |
26 | uint32_t t0 = src; // [00000000] [00000000] [XRRRRRGG] [GGGBBBBB] |
27 | uint32_t t1; |
28 | uint32_t t2; |
29 | |
30 | t0 = (t0 * 0x00080008u); // [RRRGGGGG] [BBBBBXRR] [RRRGGGGG] [BBBBB000] |
31 | t0 = (t0 & 0x1F03E0F8u); // [000GGGGG] [000000RR] [RRR00000] [BBBBB000] |
32 | t0 = (t0 | (t0 >> 5)); // [000GGGGG] [GGGGG0RR] [RRRRRRRR] [BBBBBBBB] |
33 | |
34 | t1 = t0 >> 13; // [00000000] [00000000] [GGGGGGGG] [GG0RRRRR] |
35 | t2 = t0 << 6; // [GGGGGGG0] [RRRRRRRR] [RRBBBBBB] [BB000000] |
36 | |
37 | t0 &= 0x000000FFu; // [00000000] [00000000] [00000000] [BBBBBBBB] |
38 | t1 &= 0x0000FF00u; // [00000000] [00000000] [GGGGGGGG] [00000000] |
39 | t2 &= 0x00FF0000u; // [00000000] [RRRRRRRR] [00000000] [00000000] |
40 | |
41 | return 0xFF000000u | t0 | t1 | t2; |
42 | } |
43 | |
44 | static BL_INLINE uint32_t bl_xrgb32_0888_from_xrgb16_0565(uint32_t src) noexcept { |
45 | uint32_t t0 = src; // [00000000] [00000000] [RRRRRGGG] [GGGBBBBB] |
46 | uint32_t t1 = src; |
47 | uint32_t t2; |
48 | |
49 | t0 = (t0 & 0x0000F81Fu); // [00000000] [00000000] [RRRRR000] [000BBBBB] |
50 | t1 = (t1 & 0x000007E0u); // [00000000] [00000000] [00000GGG] [GGG00000] |
51 | |
52 | t0 = (t0 * 0x21u); // [00000000] [000RRRRR] [RRRRR0BB] [BBBBBBBB] |
53 | t1 = (t1 * 0x41u); // [00000000] [0000000G] [GGGGGGGG] [GGG00000] |
54 | |
55 | t2 = (t0 << 3); // [00000000] [RRRRRRRR] [RR0BBBBB] [BBBBB000] |
56 | t0 = (t0 >> 2); // [00000000] [00000RRR] [RRRRRRR0] [BBBBBBBB] |
57 | t1 = (t1 >> 1); // [00000000] [00000000] [GGGGGGGG] [GGGG0000] |
58 | |
59 | t0 = t0 & 0x000000FFu; // [00000000] [00000000] [00000000] [BBBBBBBB] |
60 | t1 = t1 & 0x0000FF00u; // [00000000] [00000000] [GGGGGGGG] [00000000] |
61 | t2 = t2 & 0x00FF0000u; // [00000000] [RRRRRRRR] [00000000] [00000000] |
62 | |
63 | return 0xFF000000u | t0 | t1 | t2; |
64 | } |
65 | |
66 | static BL_INLINE uint32_t bl_argb32_8888_from_argb16_4444(uint32_t src) noexcept { |
67 | uint32_t t0 = src; // [00000000] [00000000] [AAAARRRR] [GGGGBBBB] |
68 | uint32_t t1; |
69 | uint32_t t2; |
70 | |
71 | t1 = t0 << 12; // [0000AAAA] [RRRRGGGG] [BBBB0000] [00000000] |
72 | t2 = t0 << 4; // [00000000] [0000AAAA] [RRRRGGGG] [BBBB0000] |
73 | |
74 | t0 = t0 | t1; // [0000AAAA] [RRRRGGGG] [XXXXRRRR] [GGGGBBBB] |
75 | t1 = t2 << 4; // [00000000] [AAAARRRR] [GGGGBBBB] [00000000] |
76 | |
77 | t0 &= 0x0F00000Fu; // [0000AAAA] [00000000] [00000000] [0000BBBB] |
78 | t1 &= 0x000F0000u; // [00000000] [0000RRRR] [00000000] [00000000] |
79 | t2 &= 0x00000F00u; // [00000000] [00000000] [0000GGGG] [00000000] |
80 | |
81 | t0 += t1; // [0000AAAA] [0000RRRR] [00000000] [0000BBBB] |
82 | t0 += t2; // [0000AAAA] [0000RRRR] [0000GGGG] [0000BBBB] |
83 | |
84 | return t0 * 0x11u; // [AAAAAAAA] [RRRRRRRR] [GGGGGGGG] [BBBBBBBB] |
85 | } |
86 | |
87 | // -------------------------------------------------------------------------- |
88 | // [Premultiply / Demultiply] |
89 | // -------------------------------------------------------------------------- |
90 | |
91 | static BL_INLINE uint32_t bl_prgb32_8888_from_argb32_8888(uint32_t val32, uint32_t _a) noexcept { |
92 | #if BL_TARGET_SIMD_I |
93 | using namespace SIMD; |
94 | |
95 | I128 p0 = vcvtu32i128(val32); |
96 | I128 a0 = vcvtu32i128(_a | 0x00FF0000u); |
97 | |
98 | p0 = vmovli64u8u16(p0); |
99 | a0 = vswizli16<1, 0, 0, 0>(a0); |
100 | p0 = vdiv255u16(vmuli16(p0, a0)); |
101 | p0 = vpackzzwb(p0); |
102 | return vcvti128u32(p0); |
103 | #else |
104 | uint32_t rb = val32; |
105 | uint32_t ag = val32; |
106 | |
107 | ag |= 0xFF000000u; |
108 | ag >>= 8; |
109 | |
110 | rb = (rb & 0x00FF00FFu) * _a; |
111 | ag = (ag & 0x00FF00FFu) * _a; |
112 | |
113 | rb += 0x00800080u; |
114 | ag += 0x00800080u; |
115 | |
116 | rb = (rb + ((rb >> 8) & 0x00FF00FFu)) & 0xFF00FF00u; |
117 | ag = (ag + ((ag >> 8) & 0x00FF00FFu)) & 0xFF00FF00u; |
118 | |
119 | rb >>= 8; |
120 | return ag | rb; |
121 | #endif |
122 | } |
123 | |
124 | static BL_INLINE uint32_t bl_prgb32_8888_from_argb32_8888(uint32_t val32) noexcept { |
125 | #if BL_TARGET_SIMD_I |
126 | using namespace SIMD; |
127 | |
128 | I128 p0 = vmovli64u8u16(vcvtu32i128(val32)); |
129 | I128 a0 = vswizli16<3, 3, 3, 3>(p0); |
130 | |
131 | p0 = vor(p0, v_const_as<I128>(blCommonTable.i128_00FF000000000000)); |
132 | p0 = vdiv255u16(vmuli16(p0, a0)); |
133 | p0 = vpackzzwb(p0); |
134 | return vcvti128u32(p0); |
135 | #else |
136 | return bl_prgb32_8888_from_argb32_8888(val32, val32 >> 24); |
137 | #endif |
138 | } |
139 | |
140 | static BL_INLINE uint32_t bl_argb32_8888_from_prgb32_8888(uint32_t val32) noexcept { |
141 | uint32_t a, r, g, b; |
142 | a = ((val32 >> 24)); |
143 | r = ((val32 >> 16) & 0xFFu); |
144 | g = ((val32 >> 8) & 0xFFu); |
145 | b = ((val32 ) & 0xFFu); |
146 | |
147 | uint32_t recip = blCommonTable.div24bit[a]; |
148 | r = (r * recip) >> 16; |
149 | g = (g * recip) >> 16; |
150 | b = (b * recip) >> 16; |
151 | |
152 | return (a << 24) | (r << 16) | (g << 8) | b; |
153 | } |
154 | |
155 | static BL_INLINE uint32_t bl_abgr32_8888_from_prgb32_8888(uint32_t val32) noexcept { |
156 | uint32_t a, r, g, b; |
157 | a = ((val32 >> 24)); |
158 | r = ((val32 >> 16) & 0xFFu); |
159 | g = ((val32 >> 8) & 0xFFu); |
160 | b = ((val32 ) & 0xFFu); |
161 | |
162 | uint32_t recip = blCommonTable.div24bit[a]; |
163 | r = (r * recip) >> 16; |
164 | g = (g * recip) >> 16; |
165 | b = (b * recip) >> 16; |
166 | |
167 | return (a << 24) | (b << 16) | (g << 8) | r; |
168 | } |
169 | |
170 | } // {anonymous} |
171 | |
172 | //! \} |
173 | //! \endcond |
174 | |
175 | #endif // BLEND2D_BLPIXELOPS_P_H |
176 | |