1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
// Copyright (c) 2012-2017 VideoStitch SAS
// Copyright (c) 2018 stitchEm
static inline int clamp8(int c) { return clamp(c, 0, 255); }
/**
* Solid RGB.
*/
/**
* Get the red component for a pixel.
* @param v pixel value.
*/
static inline unsigned int Image_RGBSolid_r(uchar3 v) { return v.x; }
/**
* Get the green component for a pixel.
* @param v pixel value.
*/
static inline unsigned int Image_RGBSolid_g(uchar3 v) { return v.y; }
/**
* Get the blue component for a pixel.
* @param v pixel value.
*/
static inline unsigned int Image_RGBSolid_b(uchar3 v) { return v.z; }
/**
* Get the alpha component for a pixel.
* @param v RGBA64 packed pixel.
*/
static inline unsigned int Image_RGBSolid_a(char3 v) { return 255; }
/**
* Pack RGBA values into a 32 bits pixel as .
* @param r Red component. Between 0 and 255.
* @param g Green component. Between 0 and 255.
* @param b Blue component. Between 0 and 255.
* @param a Alpha component. Ignored.
*/
static inline uchar3 Image_RGBSolid_pack(unsigned int r, unsigned int g, unsigned int b, unsigned int a) {
uchar3 v;
v.x = (unsigned char)r;
v.y = (unsigned char)g;
v.z = (unsigned char)b;
return v;
}
/**
* RGBA format: 8 bits per component, AAAAAAAABBBBBBBBGGGGGGGGRRRRRRRR
*/
/**
* Get the red component for a pixel.
* @param v RGBA packed pixel.
*/
static inline unsigned int Image_RGBA_r(unsigned int v) { return v & (unsigned int)0xff; }
/**
* Get the green component for a pixel.
* @param v RGBA packed pixel.
*/
static inline unsigned int Image_RGBA_g(unsigned int v) { return (v >> 8) & (unsigned int)0xff; }
/**
* Get the blue component for a pixel.
* @param v RGBA packed pixel.
*/
static inline unsigned int Image_RGBA_b(unsigned int v) { return (v >> 16) & (unsigned int)0xff; }
/**
* Get the alpha component for a pixel.
* @param v RGBA packed pixel.
*/
static inline unsigned int Image_RGBA_a(unsigned int v) { return (v >> 24) & (unsigned int)0xff; }
/**
* Pack RGBA values into a 32 bits pixel as .
* @param r Red component. Between 0 and 255.
* @param g Green component. Between 0 and 255.
* @param b Blue component. Between 0 and 255.
* @param a Alpha component. Between 0 and 255.
*/
static inline unsigned int Image_RGBA_pack(unsigned int r, unsigned int g, unsigned int b, unsigned int a) {
return (a << 24) | (b << 16) | (g << 8) | r;
}
/**
* RGBASolid format: 8 bits per component, alpha always 0xff
*/
/**
* Get the red component for a pixel.
* @param v RGBA packed pixel.
*/
static inline unsigned int Image_RGBASolid_r(unsigned int v) { return v & (unsigned int)0xff; }
/**
* Get the green component for a pixel.
* @param v RGBA packed pixel.
*/
static inline unsigned int Image_RGBASolid_g(unsigned int v) { return (v >> 8) & (unsigned int)0xff; }
/**
* Get the blue component for a pixel.
* @param v RGBA packed pixel.
*/
static inline unsigned int Image_RGBASolid_b(unsigned int v) { return (v >> 16) & (unsigned int)0xff; }
/**
* Get the alpha component for a pixel.
* @param v RGBA packed pixel.
*/
static inline unsigned int Image_RGBASolid_a(unsigned int v) { return (unsigned int)0xff; }
/**
* Pack RGBA values into a 32 bits pixel as .
* @param r Red component. Between 0 and 255.
* @param g Green component. Between 0 and 255.
* @param b Blue component. Between 0 and 255.
* @param a Alpha component. Between 0 and 255.
*/
static inline unsigned int Image_RGBASolid_pack(unsigned int r, unsigned int g, unsigned int b, unsigned int a) {
return 0xff000000u | (b << 16) | (g << 8) | r;
}
/**
* RGB210 format: 1 alpha bit, 3 * signed 9-bit colors: A_RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB
* The colors are packed in an OpenGL-compatible way, as 10-bits unsigned colors.
*/
/**
* Get the red component for a packed pixel.
* @param v RGB210 packed pixel.
*/
static inline int Image_RGB210_r(unsigned int v) {
int const m = 0x200; // 1 << (10 - 1)
unsigned int x = v & (unsigned int)0x3ff;
x = (x >> 2) ^ ((0x3 & x) << 8);
return (x ^ m) - m;
}
/**
* Get the green component for a packed pixel.
* @param v RGB210 packed pixel.
*/
static inline int Image_RGB210_g(unsigned int v) {
int const m = 0x200; // 1 << (10 - 1)
unsigned int x = (v >> 10) & (unsigned int)0x3ff;
x = (x >> 2) ^ ((0x3 & x) << 8);
return (x ^ m) - m;
}
/**
* Get the blue component for a packed pixel.
* @param v RGB210 packed pixel.
*/
static inline int Image_RGB210_b(unsigned int v) {
int const m = 0x200; // 1 << (10 - 1)
unsigned int x = (v >> 20) & (unsigned int)0x3ff;
x = (x >> 2) ^ ((0x3 & x) << 8);
return (x ^ m) - m;
}
/**
* Get the alpha component for a packed pixel.
* @param v RGB210 packed pixel.
* @note This is guaranteed to return only 0 or 1.
*/
static inline int Image_RGB210_a(unsigned int v) { return (int)(v >> 31) == 0 ? 0 : 255; }
/**
* Pack RGBA values into a 32 bits pixel.
* @param r Red component. Between -511 and 511.
* @param g Green component. Between -511 and 511.
* @param b Blue component. Between -511 and 511.
* @param a Alpha component. If <= 0, transparent. Else, solid.
*/
static inline unsigned int Image_RGB210_pack(int r, int g, int b, int a) {
unsigned int packed_r = ((unsigned int)r << 2) + (((unsigned int)r & 0x300) >> 8);
unsigned int packed_g = ((unsigned int)g << 2) + (((unsigned int)g & 0x300) >> 8);
unsigned int packed_b = ((unsigned int)b << 2) + (((unsigned int)b & 0x300) >> 8);
return (((unsigned int)!!(a > 0)) * (unsigned int)0x80000000) | ((packed_b & 0x3ff) << 20) |
((packed_g & 0x3ff) << 10) | (packed_r & 0x3ff);
}
/**
* Pack RGBA values into a 32 bits pixel as 8-bit monochrome Y component.
* @param r Red component. Between 0 and (255).
* @param g Green component. Between 0 and (255).
* @param b Blue component. Between 0 and (255).
* @param a Alpha component. Ignored.
*/
static inline unsigned char Image_MonoY_pack(unsigned int r, unsigned int g, unsigned int b, unsigned int a) {
return (unsigned char)(((66 * r + 129 * g + 25 * b + 128) >> 8) + 16);
}
static inline void surface_write_i(unsigned rgba, write_only image2d_t img, int x, int y) {
const int2 coords = {x, y};
const float4 color = {Image_RGBA_r(rgba) / 255.f, Image_RGBA_g(rgba) / 255.f, Image_RGBA_b(rgba) / 255.f,
Image_RGBA_a(rgba) / 255.f};
write_imagef(img, coords, color);
}
static inline void surface_write_f(float4 color, write_only image2d_t img, int x, int y) {
const int2 coords = {x, y};
write_imagef(img, coords, color);
}