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_r = row_table[i]; \
107 int in_rofs = in_r * total_in_w; \
108 uint8_t *yip_row = in_yp + in_rofs; \
109 in_rofs = in_r / 2 * total_in_w / 2; \
110 uint8_t *uip_row = in_up + in_rofs; \
111 uint8_t *vip_row = in_vp + in_rofs; \
112 for( unsigned j=0; j<out_w; ++j ) { \
113 int in_ofs = column_table[j]; \
114 ity_t *yip = (ity_t *)(yip_row + in_ofs); \
116 ity_t *uip = (ity_t *)(uip_row + in_ofs); \
117 ity_t *vip = (ity_t *)(vip_row + in_ofs); \
120 #define xfer_yuv420pi_row_out(oty_t) \
121 for( unsigned i=y0; i<y1; ++i ) { \
122 int out_rofs = i * total_out_w + out_x; \
123 oty_t *yop = (oty_t *)(out_yp + out_rofs); \
124 int ot_k = ((i/4)<<1) + (i&1); \
125 out_rofs = ot_k * total_out_w / 2 + out_x / 2; \
126 oty_t *uop = (oty_t *)(out_up + out_rofs); \
127 oty_t *vop = (oty_t *)(out_vp + out_rofs); \
129 #define xfer_yuv420pi_row_in(ity_t) \
130 int in_r = row_table[i]; \
131 int in_rofs = in_r * total_in_w; \
132 uint8_t *yip_row = in_yp + in_rofs; \
133 int in_k = ((in_r/4)<<1) + (in_r&1); \
134 in_rofs = in_k * total_in_w / 2; \
135 uint8_t *uip_row = in_up + in_rofs; \
136 uint8_t *vip_row = in_vp + in_rofs; \
137 for( unsigned j=0; j<out_w; ++j ) { \
138 int in_ofs = column_table[j]; \
139 ity_t *yip = (ity_t *)(yip_row + in_ofs); \
141 ity_t *uip = (ity_t *)(uip_row + in_ofs); \
142 ity_t *vip = (ity_t *)(vip_row + in_ofs); \
145 #define xfer_yuv422p_row_out(oty_t) \
146 for( unsigned i=y0; i<y1; ++i ) { \
147 int out_rofs = i * total_out_w + out_x; \
148 oty_t *yop = (oty_t *)(out_yp + out_rofs); \
149 out_rofs = i * total_out_w / 2 + out_x / 2; \
150 oty_t *uop = (oty_t *)(out_up + out_rofs); \
151 oty_t *vop = (oty_t *)(out_vp + out_rofs); \
153 #define xfer_yuv422p_row_in(ity_t) \
154 int in_rofs = row_table[i] * total_in_w; \
155 uint8_t *yip_row = in_yp + in_rofs; \
157 uint8_t *uip_row = in_up + in_rofs; \
158 uint8_t *vip_row = in_vp + in_rofs; \
159 for( unsigned j=0; j<out_w; ++j ) { \
160 int in_ofs = column_table[j]; \
161 ity_t *yip = (ity_t *)(yip_row + in_ofs); \
163 ity_t *uip = (ity_t *)(uip_row + in_ofs); \
164 ity_t *vip = (ity_t *)(vip_row + in_ofs); \
167 #define xfer_yuv444p_row_out(oty_t) \
168 for( unsigned i=y0; i<y1; ++i ) { \
169 int out_rofs = i * total_out_w + out_x; \
170 oty_t *yop = (oty_t *)((oty_t *)(out_yp + out_rofs)); \
171 oty_t *uop = (oty_t *)(out_up + out_rofs); \
172 oty_t *vop = (oty_t *)(out_vp + out_rofs); \
174 #define xfer_yuv444p_row_in(ity_t) \
175 int in_rofs = row_table[i] * total_in_w; \
176 uint8_t *yip_row = in_yp + in_rofs; \
177 uint8_t *uip_row = in_up + in_rofs; \
178 uint8_t *vip_row = in_vp + in_rofs; \
179 for( unsigned j=0; j<out_w; ++j ) { \
180 int in_ofs = column_table[j]; \
181 ity_t *yip = (ity_t *)(yip_row + in_ofs); \
182 ity_t *uip = (ity_t *)(uip_row + in_ofs); \
183 ity_t *vip = (ity_t *)(vip_row + in_ofs); \
186 #define xfer_yuv411p_row_out(oty_t) \
187 for( unsigned i=y0; i<y1; ++i ) { \
188 int out_rofs = i * total_out_w + out_x; \
189 oty_t *yop = (oty_t *)(out_yp + out_rofs); \
190 out_rofs = i * total_out_w / 4 + out_x / 4; \
191 oty_t *uop = (oty_t *)(out_up + out_rofs); \
192 oty_t *vop = (oty_t *)(out_vp + out_rofs); \
194 #define xfer_yuv411p_row_in(ity_t) \
195 int in_rofs = row_table[i] * total_in_w; \
196 uint8_t *yip_row = in_yp + in_rofs; \
198 uint8_t *uip_row = in_up + in_rofs; \
199 uint8_t *vip_row = in_vp + in_rofs; \
200 for( unsigned j=0; j<out_w; ++j ) { \
201 int in_ofs = column_table[j]; \
202 ity_t *yip = (ity_t *)(yip_row + in_ofs); \
204 ity_t *uip = (ity_t *)(uip_row + in_ofs); \
205 ity_t *vip = (ity_t *)(vip_row + in_ofs); \
208 #define xfer_yuv410p_row_out(oty_t) \
209 for( unsigned i=y0; i<y1; ++i ) { \
210 int out_rofs = i * total_out_w + out_x; \
211 oty_t *yop = (oty_t *)(out_yp + out_rofs); \
212 out_rofs = i / 4 * total_out_w / 4 + out_x / 4; \
213 oty_t *uop = (oty_t *)(out_up + out_rofs); \
214 oty_t *vop = (oty_t *)(out_vp + out_rofs); \
216 #define xfer_yuv410p_row_in(ity_t) \
217 int in_rofs = row_table[i] * total_in_w; \
218 uint8_t *yip_row = in_yp + in_rofs; \
219 in_rofs = row_table[i] / 4 * total_in_w / 4; \
220 uint8_t *uip_row = in_up + in_rofs; \
221 uint8_t *vip_row = in_vp + in_rofs; \
222 for( unsigned j=0; j<out_w; ++j ) { \
223 int in_ofs = column_table[j]; \
224 ity_t *yip = (ity_t *)(yip_row + in_ofs); \
226 ity_t *uip = (ity_t *)(uip_row + in_ofs); \
227 ity_t *vip = (ity_t *)(vip_row + in_ofs); \
230 #define xfer_rgb_fltp_row_out(oty_t) \
231 for( unsigned i=y0; i<y1; ++i ) { \
232 int out_rofs = i * total_out_w + out_x; \
233 oty_t *rop = (oty_t *)(out_yp + out_rofs); \
234 oty_t *gop = (oty_t *)(out_up + out_rofs); \
235 oty_t *bop = (oty_t *)(out_vp + out_rofs); \
237 #define xfer_rgb_fltp_row_in(ity_t) \
238 int in_rofs = row_table[i] * total_in_w; \
239 uint8_t *rip_row = in_yp + in_rofs; \
240 uint8_t *gip_row = in_up + in_rofs; \
241 uint8_t *bip_row = in_vp + in_rofs; \
243 #define xfer_rgb_fltp_col_in(ity_t) \
244 for( unsigned j=0; j<out_w; ++j ) { \
245 int in_ofs = column_table[j]; \
246 ity_t *rip = (ity_t *)(rip_row + in_ofs); \
247 ity_t *gip = (ity_t *)(gip_row + in_ofs); \
248 ity_t *bip = (ity_t *)(bip_row + in_ofs); \
250 #define xfer_rgb_floatp_row_out(oty_t) \
251 xfer_rgb_fltp_row_out(oty_t) \
253 #define xfer_rgba_floatp_row_out(oty_t) \
254 xfer_rgb_fltp_row_out(oty_t) \
255 oty_t *aop = (oty_t *)(out_ap + out_rofs); \
257 #define xfer_rgb_floatp_row_in(ity_t) \
258 xfer_rgb_fltp_row_in(ity_t) \
259 xfer_rgb_fltp_col_in(ity_t) \
261 #define xfer_rgba_floatp_row_in(ity_t) \
262 xfer_rgb_fltp_row_in(ity_t) \
263 uint8_t *aip_row = in_ap + in_rofs; \
264 xfer_rgb_fltp_col_in(ity_t) \
265 ity_t *aip = (ity_t *)(aip_row + in_ofs); \
269 BC_Xfer(const BC_Xfer&) {}
271 BC_Xfer(uint8_t **output_rows, uint8_t **input_rows,
272 uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp,
273 uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp,
274 int in_x, int in_y, int in_w, int in_h, int out_x, int out_y, int out_w, int out_h,
275 int in_colormodel, int out_colormodel, int bg_color, int in_rowspan, int out_rowspan);
276 BC_Xfer(uint8_t **output_ptrs, int out_colormodel,
277 int out_x, int out_y, int out_w, int out_h, int out_rowspan,
278 uint8_t **input_ptrs, int in_colormodel,
279 int in_x, int in_y, int in_w, int in_h, int in_rowspan,
283 uint8_t **output_rows, **input_rows;
284 uint8_t *out_yp, *out_up, *out_vp, *out_ap;
285 uint8_t *in_yp, *in_up, *in_vp, *in_ap;
286 int in_x, in_y; unsigned in_w, in_h;
287 int out_x, out_y; unsigned out_w, out_h;
288 int in_colormodel, out_colormodel;
289 uint32_t bg_color, total_in_w, total_out_w;
291 int out_pixelsize, in_pixelsize;
292 int *row_table, *column_table;
293 uint32_t bg_r, bg_g, bg_b;
296 void xfer_slices(int slices);
297 typedef void (BC_Xfer::*xfer_fn)(unsigned y0, unsigned y1);
300 class Slicer : public ListItem<Slicer>, public Thread {
302 Condition *init, *complete;
305 void slice(BC_Xfer *xp, unsigned y0, unsigned y1);
311 class SlicerList : public List<Slicer>, public Mutex {
314 Slicer *get_slicer(BC_Xfer *xp);
319 static SlicerList slicers;
322 static class Tables { public: Tables() { init(); } } tables;
323 static int rtoy_tab[0x100], gtoy_tab[0x100], btoy_tab[0x100];
324 static int rtou_tab[0x100], gtou_tab[0x100], btou_tab[0x100];
325 static int rtov_tab[0x100], gtov_tab[0x100], btov_tab[0x100];
326 static int vtor_tab[0x100], vtog_tab[0x100];
327 static int utog_tab[0x100], utob_tab[0x100];
328 static float vtor_float_tab[0x100], vtog_float_tab[0x100];
329 static float utog_float_tab[0x100], utob_float_tab[0x100];
330 static int rtoy_tab16[0x10000], gtoy_tab16[0x10000], btoy_tab16[0x10000];
331 static int rtou_tab16[0x10000], gtou_tab16[0x10000], btou_tab16[0x10000];
332 static int rtov_tab16[0x10000], gtov_tab16[0x10000], btov_tab16[0x10000];
333 static int vtor_tab16[0x10000], vtog_tab16[0x10000];
334 static int utog_tab16[0x10000], utob_tab16[0x10000];
335 static float v16tor_float_tab[0x10000], v16tog_float_tab[0x10000];
336 static float u16tog_float_tab[0x10000], u16tob_float_tab[0x10000];
339 uint8_t **output_rows, int out_colormodel, int out_x, int out_y, int out_w, int out_h,
340 uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp, uint8_t *out_ap, int out_rowspan,
341 uint8_t **input_rows, int in_colormodel, int in_x, int in_y, int in_w, int in_h,
342 uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp, uint8_t *in_ap, int in_rowspan,
345 // generated code concatentated here