2 #include "bcresources.h"
9 static inline float clp(const int n, float v) {
10 v *= ((float)(n*(1-1./0x1000000)));
11 return v < 0 ? 0 : v >= n ? n-1 : v;
14 static inline float fclp(float v, const int n) {
15 v /= ((float)(n*(1-1./0x1000000)));
16 return v < 0 ? 0 : v > 1 ? 1 : v;
21 #define ZTYP(ty) typedef ty z_##ty __attribute__ ((__unused__))
25 // All variables are unsigned
26 // y -> 24 bits u, v, -> 8 bits r, g, b -> 8 bits
27 #define YUV_TO_RGB(y, u, v, r, g, b) \
29 (r) = ((y + vtor_tab[v]) >> 16); \
30 (g) = ((y + utog_tab[u] + vtog_tab[v]) >> 16); \
31 (b) = ((y + utob_tab[u]) >> 16); \
32 CLAMP(r, 0, 0xff); CLAMP(g, 0, 0xff); CLAMP(b, 0, 0xff); \
38 #define YUV_TO_FLOAT(y, u, v, r, g, b) \
40 (r) = y + vtor_float_tab[v]; \
41 (g) = y + utog_float_tab[u] + vtog_float_tab[v]; \
42 (b) = y + utob_float_tab[u]; \
48 #define YUV16_TO_RGB_FLOAT(y, u, v, r, g, b) \
50 (r) = y + v16tor_float_tab[v]; \
51 (g) = y + u16tog_float_tab[u] + v16tog_float_tab[v]; \
52 (b) = y + u16tob_float_tab[u]; \
55 // y -> 24 bits u, v-> 16 bits
56 #define YUV_TO_RGB16(y, u, v, r, g, b) \
58 (r) = ((y + vtor_tab16[v]) >> 8); \
59 (g) = ((y + utog_tab16[u] + vtog_tab16[v]) >> 8); \
60 (b) = ((y + utob_tab16[u]) >> 8); \
61 CLAMP(r, 0, 0xffff); CLAMP(g, 0, 0xffff); CLAMP(b, 0, 0xffff); \
67 #define RGB_TO_YUV(y, u, v, r, g, b) \
69 y = ((rtoy_tab[r] + gtoy_tab[g] + btoy_tab[b]) >> 16); \
70 u = ((rtou_tab[r] + gtou_tab[g] + btou_tab[b]) >> 16); \
71 v = ((rtov_tab[r] + gtov_tab[g] + btov_tab[b]) >> 16); \
72 CLAMP(y, 0, 0xff); CLAMP(u, 0, 0xff); CLAMP(v, 0, 0xff); \
76 #define RGB_TO_YUV16(y, u, v, r, g, b) \
78 y = ((rtoy_tab16[r] + gtoy_tab16[g] + btoy_tab16[b]) >> 8); \
79 u = ((rtou_tab16[r] + gtou_tab16[g] + btou_tab16[b]) >> 8); \
80 v = ((rtov_tab16[r] + gtov_tab16[g] + btov_tab16[b]) >> 8); \
81 CLAMP(y, 0, 0xffff); CLAMP(u, 0, 0xffff); CLAMP(v, 0, 0xffff); \
85 #define xfer_flat_row_out(oty_t) \
86 for( unsigned i=y0; i<y1; ++i ) { \
87 oty_t *out = (oty_t *)(output_rows[i + out_y] + out_x * out_pixelsize); \
89 #define xfer_flat_row_in(ity_t) \
90 uint8_t *inp_row = input_rows[row_table[i]]; \
91 for( unsigned j=0; j<out_w; ++j ) { \
92 ity_t *inp = (ity_t *)(inp_row + column_table[j]); \
97 #define xfer_yuv420p_row_out(oty_t) \
98 for( unsigned i=y0; i<y1; ++i ) { \
99 int out_rofs = i * total_out_w + out_x; \
100 oty_t *yop = (oty_t *)(out_yp + out_rofs); \
101 out_rofs = i / 2 * total_out_w / 2 + out_x / 2; \
102 oty_t *uop = (oty_t *)(out_up + out_rofs); \
103 oty_t *vop = (oty_t *)(out_vp + out_rofs); \
105 #define xfer_yuv420p_row_in(ity_t) \
106 int in_rofs = row_table[i] * total_in_w; \
107 uint8_t *yip_row = in_yp + in_rofs; \
108 in_rofs = row_table[i] / 2 * total_in_w / 2; \
109 uint8_t *uip_row = in_up + in_rofs; \
110 uint8_t *vip_row = in_vp + in_rofs; \
111 for( unsigned j=0; j<out_w; ++j ) { \
112 int in_ofs = column_table[j]; \
113 ity_t *yip = (ity_t *)(yip_row + in_ofs); \
115 ity_t *uip = (ity_t *)(uip_row + in_ofs); \
116 ity_t *vip = (ity_t *)(vip_row + in_ofs); \
119 #define xfer_yuv422p_row_out(oty_t) \
120 for( unsigned i=y0; i<y1; ++i ) { \
121 int out_rofs = i * total_out_w + out_x; \
122 oty_t *yop = (oty_t *)(out_yp + out_rofs); \
123 out_rofs = i * total_out_w / 2 + out_x / 2; \
124 oty_t *uop = (oty_t *)(out_up + out_rofs); \
125 oty_t *vop = (oty_t *)(out_vp + out_rofs); \
127 #define xfer_yuv422p_row_in(ity_t) \
128 int in_rofs = row_table[i] * total_in_w; \
129 uint8_t *yip_row = in_yp + in_rofs; \
131 uint8_t *uip_row = in_up + in_rofs; \
132 uint8_t *vip_row = in_vp + in_rofs; \
133 for( unsigned j=0; j<out_w; ++j ) { \
134 int in_ofs = column_table[j]; \
135 ity_t *yip = (ity_t *)(yip_row + in_ofs); \
137 ity_t *uip = (ity_t *)(uip_row + in_ofs); \
138 ity_t *vip = (ity_t *)(vip_row + in_ofs); \
141 #define xfer_yuv444p_row_out(oty_t) \
142 for( unsigned i=y0; i<y1; ++i ) { \
143 int out_rofs = i * total_out_w + out_x; \
144 oty_t *yop = (oty_t *)((oty_t *)(out_yp + out_rofs)); \
145 oty_t *uop = (oty_t *)(out_up + out_rofs); \
146 oty_t *vop = (oty_t *)(out_vp + out_rofs); \
148 #define xfer_yuv444p_row_in(ity_t) \
149 int in_rofs = row_table[i] * total_in_w; \
150 uint8_t *yip_row = in_yp + in_rofs; \
151 uint8_t *uip_row = in_up + in_rofs; \
152 uint8_t *vip_row = in_vp + in_rofs; \
153 for( unsigned j=0; j<out_w; ++j ) { \
154 int in_ofs = column_table[j]; \
155 ity_t *yip = (ity_t *)(yip_row + in_ofs); \
156 ity_t *uip = (ity_t *)(uip_row + in_ofs); \
157 ity_t *vip = (ity_t *)(vip_row + in_ofs); \
160 #define xfer_yuv411p_row_out(oty_t) \
161 for( unsigned i=y0; i<y1; ++i ) { \
162 int out_rofs = i * total_out_w + out_x; \
163 oty_t *yop = (oty_t *)(out_yp + out_rofs); \
164 out_rofs = i * total_out_w / 4 + out_x / 4; \
165 oty_t *uop = (oty_t *)(out_up + out_rofs); \
166 oty_t *vop = (oty_t *)(out_vp + out_rofs); \
168 #define xfer_yuv411p_row_in(ity_t) \
169 int in_rofs = row_table[i] * total_in_w; \
170 uint8_t *yip_row = in_yp + in_rofs; \
172 uint8_t *uip_row = in_up + in_rofs; \
173 uint8_t *vip_row = in_vp + in_rofs; \
174 for( unsigned j=0; j<out_w; ++j ) { \
175 int in_ofs = column_table[j]; \
176 ity_t *yip = (ity_t *)(yip_row + in_ofs); \
178 ity_t *uip = (ity_t *)(uip_row + in_ofs); \
179 ity_t *vip = (ity_t *)(vip_row + in_ofs); \
182 #define xfer_yuv410p_row_out(oty_t) \
183 for( unsigned i=y0; i<y1; ++i ) { \
184 int out_rofs = i * total_out_w + out_x; \
185 oty_t *yop = (oty_t *)(out_yp + out_rofs); \
186 out_rofs = i / 4 * total_out_w / 4 + out_x / 4; \
187 oty_t *uop = (oty_t *)(out_up + out_rofs); \
188 oty_t *vop = (oty_t *)(out_vp + out_rofs); \
190 #define xfer_yuv410p_row_in(ity_t) \
191 int in_rofs = row_table[i] * total_in_w; \
192 uint8_t *yip_row = in_yp + in_rofs; \
193 in_rofs = row_table[i] / 4 * total_in_w / 4; \
194 uint8_t *uip_row = in_up + in_rofs; \
195 uint8_t *vip_row = in_vp + in_rofs; \
196 for( unsigned j=0; j<out_w; ++j ) { \
197 int in_ofs = column_table[j]; \
198 ity_t *yip = (ity_t *)(yip_row + in_ofs); \
200 ity_t *uip = (ity_t *)(uip_row + in_ofs); \
201 ity_t *vip = (ity_t *)(vip_row + in_ofs); \
204 #define xfer_rgb_fltp_row_out(oty_t) \
205 for( unsigned i=y0; i<y1; ++i ) { \
206 int out_rofs = i * total_out_w + out_x; \
207 oty_t *rop = (oty_t *)(out_yp + out_rofs); \
208 oty_t *gop = (oty_t *)(out_up + out_rofs); \
209 oty_t *bop = (oty_t *)(out_vp + out_rofs); \
211 #define xfer_rgb_fltp_row_in(ity_t) \
212 int in_rofs = row_table[i] * total_in_w; \
213 uint8_t *rip_row = in_yp + in_rofs; \
214 uint8_t *gip_row = in_up + in_rofs; \
215 uint8_t *bip_row = in_vp + in_rofs; \
217 #define xfer_rgb_fltp_col_in(ity_t) \
218 for( unsigned j=0; j<out_w; ++j ) { \
219 int in_ofs = column_table[j]; \
220 ity_t *rip = (ity_t *)(rip_row + in_ofs); \
221 ity_t *gip = (ity_t *)(gip_row + in_ofs); \
222 ity_t *bip = (ity_t *)(bip_row + in_ofs); \
224 #define xfer_rgb_floatp_row_out(oty_t) \
225 xfer_rgb_fltp_row_out(oty_t) \
227 #define xfer_rgba_floatp_row_out(oty_t) \
228 xfer_rgb_fltp_row_out(oty_t) \
229 oty_t *aop = (oty_t *)(out_ap + out_rofs); \
231 #define xfer_rgb_floatp_row_in(ity_t) \
232 xfer_rgb_fltp_row_in(ity_t) \
233 xfer_rgb_fltp_col_in(ity_t) \
235 #define xfer_rgba_floatp_row_in(ity_t) \
236 xfer_rgb_fltp_row_in(ity_t) \
237 uint8_t *aip_row = in_ap + in_rofs; \
238 xfer_rgb_fltp_col_in(ity_t) \
239 ity_t *aip = (ity_t *)(aip_row + in_ofs); \
243 BC_Xfer(const BC_Xfer&) {}
245 BC_Xfer(uint8_t **output_rows, uint8_t **input_rows,
246 uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp,
247 uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp,
248 int in_x, int in_y, int in_w, int in_h, int out_x, int out_y, int out_w, int out_h,
249 int in_colormodel, int out_colormodel, int bg_color, int in_rowspan, int out_rowspan);
250 BC_Xfer(uint8_t **output_ptrs, int out_colormodel,
251 int out_x, int out_y, int out_w, int out_h, int out_rowspan,
252 uint8_t **input_ptrs, int in_colormodel,
253 int in_x, int in_y, int in_w, int in_h, int in_rowspan,
257 uint8_t **output_rows, **input_rows;
258 uint8_t *out_yp, *out_up, *out_vp, *out_ap;
259 uint8_t *in_yp, *in_up, *in_vp, *in_ap;
260 int in_x, in_y; unsigned in_w, in_h;
261 int out_x, out_y; unsigned out_w, out_h;
262 int in_colormodel, out_colormodel;
263 uint32_t bg_color, total_in_w, total_out_w;
265 int out_pixelsize, in_pixelsize;
266 int *row_table, *column_table;
267 uint32_t bg_r, bg_g, bg_b;
270 void xfer_slices(int slices);
271 typedef void (BC_Xfer::*xfer_fn)(unsigned y0, unsigned y1);
274 class Slicer : public ListItem<Slicer>, public Thread {
276 Condition *init, *complete;
279 void slice(BC_Xfer *xp, unsigned y0, unsigned y1);
285 class SlicerList : public List<Slicer>, public Mutex {
288 Slicer *get_slicer(BC_Xfer *xp);
293 static SlicerList slicers;
296 static class Tables { public: Tables() { init(); } } tables;
297 static int rtoy_tab[0x100], gtoy_tab[0x100], btoy_tab[0x100];
298 static int rtou_tab[0x100], gtou_tab[0x100], btou_tab[0x100];
299 static int rtov_tab[0x100], gtov_tab[0x100], btov_tab[0x100];
300 static int vtor_tab[0x100], vtog_tab[0x100];
301 static int utog_tab[0x100], utob_tab[0x100];
302 static float vtor_float_tab[0x100], vtog_float_tab[0x100];
303 static float utog_float_tab[0x100], utob_float_tab[0x100];
304 static int rtoy_tab16[0x10000], gtoy_tab16[0x10000], btoy_tab16[0x10000];
305 static int rtou_tab16[0x10000], gtou_tab16[0x10000], btou_tab16[0x10000];
306 static int rtov_tab16[0x10000], gtov_tab16[0x10000], btov_tab16[0x10000];
307 static int vtor_tab16[0x10000], vtog_tab16[0x10000];
308 static int utog_tab16[0x10000], utob_tab16[0x10000];
309 static float v16tor_float_tab[0x10000], v16tog_float_tab[0x10000];
310 static float u16tog_float_tab[0x10000], u16tob_float_tab[0x10000];
313 uint8_t **output_rows, int out_colormodel, int out_x, int out_y, int out_w, int out_h,
314 uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp, uint8_t *out_ap, int out_rowspan,
315 uint8_t **input_rows, int in_colormodel, int in_x, int in_y, int in_w, int in_h,
316 uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp, uint8_t *in_ap, int in_rowspan,
319 // generated code concatentated here