clipboard rework, C41/titler fixes, displayinfo tweak
[goodguy/history.git] / cinelerra-5.1 / guicast / xfer.h
1 #include "bccmodels.h"
2 #include "bcresources.h"
3 #include "condition.h"
4 #include "linklist.h"
5 #include "mutex.h"
6 #include "thread.h"
7 #include "clip.h"
8
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;
12 }
13
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;
17 }
18
19 #include <stdint.h>
20
21 #define ZTYP(ty) typedef ty z_##ty __attribute__ ((__unused__))
22 ZTYP(int);
23 ZTYP(float);
24
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) \
28 { \
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); \
33 }
34
35 // y -> 0 - 1 float
36 // u, v, -> 8 bits
37 // r, g, b -> float
38 #define YUV_TO_FLOAT(y, u, v, r, g, b) \
39 { \
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]; \
43 }
44
45 // y -> 0 - 1 float
46 // u, v, -> 16 bits
47 // r, g, b -> float
48 #define YUV16_TO_RGB_FLOAT(y, u, v, r, g, b) \
49 { \
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]; \
53 }
54
55 // y -> 24 bits   u, v-> 16 bits
56 #define YUV_TO_RGB16(y, u, v, r, g, b) \
57 { \
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); \
62 }
63
64
65
66
67 #define RGB_TO_YUV(y, u, v, r, g, b) \
68 { \
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); \
73 }
74
75 // r, g, b -> 16 bits
76 #define RGB_TO_YUV16(y, u, v, r, g, b) \
77 { \
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); \
82 }
83
84
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); \
88
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]); \
93
94 #define xfer_end } }
95
96 // yuv420p  2x2
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); \
104
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); \
115       in_ofs /= 2; \
116       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
117       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
118
119 // yuv420pi  2x2
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); \
128
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); \
140       in_ofs /= 2; \
141       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
142       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
143
144 // yuv422p  2x1
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); \
152
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; \
156     in_rofs /= 2; \
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); \
162       in_ofs /= 2; \
163       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
164       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
165
166 // yuv444p  1x1
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); \
173
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); \
184
185 // yuv411p  4x1
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); \
193
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; \
197     in_rofs /= 4; \
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); \
203       in_ofs /= 4; \
204       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
205       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
206
207 // yuv410p  4x4
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); \
215
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); \
225       in_ofs /= 4; \
226       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
227       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
228
229 // rgb_floatp
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); \
236
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; \
242
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); \
249
250 #define xfer_rgb_floatp_row_out(oty_t) \
251   xfer_rgb_fltp_row_out(oty_t) \
252
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); \
256
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) \
260
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); \
266
267
268 class BC_Xfer {
269   BC_Xfer(const BC_Xfer&) {}
270 public:
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,
280     int bg_color);
281   ~BC_Xfer();
282
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;
290   int scale;
291   int out_pixelsize, in_pixelsize;
292   int *row_table, *column_table;
293   uint32_t bg_r, bg_g, bg_b;
294
295   void xfer();
296   void xfer_slices(int slices);
297   typedef void (BC_Xfer::*xfer_fn)(unsigned y0, unsigned y1);
298   xfer_fn xfn;
299
300   class Slicer : public ListItem<Slicer>, public Thread {
301   public:
302     Condition *init, *complete;
303     Slicer(BC_Xfer *xp);
304     ~Slicer();
305     void slice(BC_Xfer *xp, unsigned y0, unsigned y1);
306     void run();
307     BC_Xfer *xp;
308     int done, y0, y1;
309   };
310
311   class SlicerList : public List<Slicer>, public Mutex {
312   public:
313     int count;
314     Slicer *get_slicer(BC_Xfer *xp);
315     void reset();
316     SlicerList();
317     ~SlicerList();
318   };
319   static SlicerList slicers;
320
321   static void init();
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];
337
338   void init(
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,
343     int bg_color);
344
345 // generated code concatentated here