version update
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / bcxfer.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
26 #define xfer_flat_row_out(oty_t) \
27   for( unsigned i=y0; i<y1; ++i ) { \
28     oty_t *out = (oty_t *)(output_rows[i + out_y] + out_x * out_pixelsize); \
29
30 #define xfer_flat_row_in(ity_t) \
31     uint8_t *inp_row = input_rows[row_table[i]]; \
32     for( unsigned j=0; j<out_w; ++j ) { \
33       ity_t *inp = (ity_t *)(inp_row + column_table[j]); \
34
35 #define xfer_clear(s) \
36     for( unsigned j=0; j<out_w; ++j ) { \
37
38 #define xfer_end } }
39
40 // yuv420p  2x2
41 #define xfer_yuv420p_row_out(oty_t) \
42   for( unsigned i=y0; i<y1; ++i ) { \
43     int out_rofs = i * total_out_w + out_x; \
44     oty_t *yop = (oty_t *)(out_yp + out_rofs); \
45     out_rofs = i / 2 * total_out_w / 2 + out_x / 2; \
46     oty_t *uop = (oty_t *)(out_up + out_rofs); \
47     oty_t *vop = (oty_t *)(out_vp + out_rofs); \
48
49 #define xfer_yuv420p_row_in(ity_t) \
50     int in_r = row_table[i]; \
51     int in_rofs = in_r * total_in_w; \
52     uint8_t *yip_row = in_yp + in_rofs; \
53     in_rofs = in_r / 2 * total_in_w / 2; \
54     uint8_t *uip_row = in_up + in_rofs; \
55     uint8_t *vip_row = in_vp + in_rofs; \
56     for( unsigned j=0; j<out_w; ++j ) { \
57       int in_ofs = column_table[j]; \
58       ity_t *yip = (ity_t *)(yip_row + in_ofs); \
59       in_ofs /= 2; \
60       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
61       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
62
63 // yuv420pi  2x2
64 #define xfer_yuv420pi_row_out(oty_t) \
65   for( unsigned i=y0; i<y1; ++i ) { \
66     int out_rofs = i * total_out_w + out_x; \
67     oty_t *yop = (oty_t *)(out_yp + out_rofs); \
68     int ot_k = ((i/4)<<1) + (i&1); \
69     out_rofs = ot_k * total_out_w / 2 + out_x / 2; \
70     oty_t *uop = (oty_t *)(out_up + out_rofs); \
71     oty_t *vop = (oty_t *)(out_vp + out_rofs); \
72
73 #define xfer_yuv420pi_row_in(ity_t) \
74     int in_r = row_table[i]; \
75     int in_rofs = in_r * total_in_w; \
76     uint8_t *yip_row = in_yp + in_rofs; \
77     int in_k = ((in_r/4)<<1) + (in_r&1); \
78     in_rofs = in_k * total_in_w / 2; \
79     uint8_t *uip_row = in_up + in_rofs; \
80     uint8_t *vip_row = in_vp + in_rofs; \
81     for( unsigned j=0; j<out_w; ++j ) { \
82       int in_ofs = column_table[j]; \
83       ity_t *yip = (ity_t *)(yip_row + in_ofs); \
84       in_ofs /= 2; \
85       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
86       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
87
88 // yuv422p  2x1
89 #define xfer_yuv422p_row_out(oty_t) \
90   for( unsigned i=y0; i<y1; ++i ) { \
91     int out_rofs = i * total_out_w + out_x; \
92     oty_t *yop = (oty_t *)(out_yp + out_rofs); \
93     out_rofs = i * total_out_w / 2 + out_x / 2; \
94     oty_t *uop = (oty_t *)(out_up + out_rofs); \
95     oty_t *vop = (oty_t *)(out_vp + out_rofs); \
96
97 #define xfer_yuv422p_row_in(ity_t) \
98     int in_rofs = row_table[i] * total_in_w; \
99     uint8_t *yip_row = in_yp + in_rofs; \
100     in_rofs /= 2; \
101     uint8_t *uip_row = in_up + in_rofs; \
102     uint8_t *vip_row = in_vp + in_rofs; \
103     for( unsigned j=0; j<out_w; ++j ) { \
104       int in_ofs = column_table[j]; \
105       ity_t *yip = (ity_t *)(yip_row + in_ofs); \
106       in_ofs /= 2; \
107       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
108       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
109
110 // yuv444p  1x1
111 #define xfer_yuv444p_row_out(oty_t) \
112   for( unsigned i=y0; i<y1; ++i ) { \
113     int out_rofs = i * total_out_w + out_x; \
114     oty_t *yop = (oty_t *)((oty_t *)(out_yp + out_rofs)); \
115     oty_t *uop = (oty_t *)(out_up + out_rofs); \
116     oty_t *vop = (oty_t *)(out_vp + out_rofs); \
117
118 #define xfer_yuv444p_row_in(ity_t) \
119     int in_rofs = row_table[i] * total_in_w; \
120     uint8_t *yip_row = in_yp + in_rofs; \
121     uint8_t *uip_row = in_up + in_rofs; \
122     uint8_t *vip_row = in_vp + in_rofs; \
123     for( unsigned j=0; j<out_w; ++j ) { \
124       int in_ofs = column_table[j]; \
125       ity_t *yip = (ity_t *)(yip_row + in_ofs); \
126       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
127       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
128
129 // yuv411p  4x1
130 #define xfer_yuv411p_row_out(oty_t) \
131   for( unsigned i=y0; i<y1; ++i ) { \
132     int out_rofs = i * total_out_w + out_x; \
133     oty_t *yop = (oty_t *)(out_yp + out_rofs); \
134     out_rofs = i * total_out_w / 4 + out_x / 4; \
135     oty_t *uop = (oty_t *)(out_up + out_rofs); \
136     oty_t *vop = (oty_t *)(out_vp + out_rofs); \
137
138 #define xfer_yuv411p_row_in(ity_t) \
139     int in_rofs = row_table[i] * total_in_w; \
140     uint8_t *yip_row = in_yp + in_rofs; \
141     in_rofs /= 4; \
142     uint8_t *uip_row = in_up + in_rofs; \
143     uint8_t *vip_row = in_vp + in_rofs; \
144     for( unsigned j=0; j<out_w; ++j ) { \
145       int in_ofs = column_table[j]; \
146       ity_t *yip = (ity_t *)(yip_row + in_ofs); \
147       in_ofs /= 4; \
148       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
149       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
150
151 // yuv410p  4x4
152 #define xfer_yuv410p_row_out(oty_t) \
153   for( unsigned i=y0; i<y1; ++i ) { \
154     int out_rofs = i * total_out_w + out_x; \
155     oty_t *yop = (oty_t *)(out_yp + out_rofs); \
156     out_rofs = i / 4 * total_out_w / 4 + out_x / 4; \
157     oty_t *uop = (oty_t *)(out_up + out_rofs); \
158     oty_t *vop = (oty_t *)(out_vp + out_rofs); \
159
160 #define xfer_yuv410p_row_in(ity_t) \
161     int in_rofs = row_table[i] * total_in_w; \
162     uint8_t *yip_row = in_yp + in_rofs; \
163     in_rofs = row_table[i] / 4 * total_in_w / 4; \
164     uint8_t *uip_row = in_up + in_rofs; \
165     uint8_t *vip_row = in_vp + in_rofs; \
166     for( unsigned j=0; j<out_w; ++j ) { \
167       int in_ofs = column_table[j]; \
168       ity_t *yip = (ity_t *)(yip_row + in_ofs); \
169       in_ofs /= 4; \
170       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
171       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
172
173 // rgb planar
174 #define xfer_rgbp_row_out(oty_t) \
175   for( unsigned i=y0; i<y1; ++i ) { \
176     int out_rofs = i * total_out_w + out_x; \
177     oty_t *rop = (oty_t *)(out_yp + out_rofs); \
178     oty_t *gop = (oty_t *)(out_up + out_rofs); \
179     oty_t *bop = (oty_t *)(out_vp + out_rofs); \
180
181 #define xfer_rgbap_row_out(oty_t) \
182   xfer_rgbp_row_out(oty_t) \
183     oty_t *aop = (oty_t *)(out_ap + out_rofs); \
184
185
186 #define xfer_row_in_rgbp(ity_t) \
187     int in_rofs = row_table[i] * total_in_w; \
188     uint8_t *rip_row = in_yp + in_rofs; \
189     uint8_t *gip_row = in_up + in_rofs; \
190     uint8_t *bip_row = in_vp + in_rofs; \
191
192 #define xfer_row_in_rgbap(oty_t) \
193   xfer_row_in_rgbp(ity_t) \
194     uint8_t *aip_row = in_ap + in_rofs; \
195
196
197 #define xfer_col_in_rgbp(ity_t) \
198     for( unsigned j=0; j<out_w; ++j ) { \
199       int in_ofs = column_table[j]; \
200       ity_t *rip = (ity_t *)(rip_row + in_ofs); \
201       ity_t *gip = (ity_t *)(gip_row + in_ofs); \
202       ity_t *bip = (ity_t *)(bip_row + in_ofs); \
203
204 #define xfer_col_in_rgbap(ity_t) \
205   xfer_col_in_rgbp(ity_t) \
206     ity_t *aip = (ity_t *)(aip_row + in_ofs); \
207
208
209 #define xfer_rgbp_row_in(ity_t) \
210   xfer_row_in_rgbp(ity_t) \
211     xfer_col_in_rgbp(ity_t) \
212
213 #define xfer_rgbap_row_in(ity_t) \
214   xfer_row_in_rgbap(ity_t) \
215     xfer_col_in_rgbap(ity_t) \
216
217
218 class BC_Xfer {
219   BC_Xfer(const BC_Xfer&) {}
220 public:
221   BC_Xfer(uint8_t **output_rows, uint8_t **input_rows,
222   uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp,
223   uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp,
224   int in_x, int in_y, int in_w, int in_h, int out_x, int out_y, int out_w, int out_h,
225   int in_colormodel, int out_colormodel, int bg_color, int bg_alpha,
226   int in_rowspan, int out_rowspan);
227   BC_Xfer(uint8_t **output_ptrs, int out_colormodel,
228       int out_x, int out_y, int out_w, int out_h, int out_rowspan,
229     uint8_t **input_ptrs, int in_colormodel,
230       int in_x, int in_y, int in_w, int in_h, int in_rowspan,
231     int bg_color, int bg_alpha);
232   ~BC_Xfer();
233
234   uint8_t **output_rows, **input_rows;
235   uint8_t *out_yp, *out_up, *out_vp, *out_ap;
236   uint8_t *in_yp, *in_up, *in_vp, *in_ap;
237   int in_x, in_y; unsigned in_w, in_h;
238   int out_x, out_y; unsigned out_w, out_h;
239   int in_colormodel, out_colormodel;
240   uint32_t total_in_w, total_out_w;
241   int scale;
242   int out_pixelsize, in_pixelsize;
243   int *row_table, *column_table;
244   uint32_t bg_r, bg_g, bg_b, bg_a;
245   float bg_fr, bg_fg, bg_fb, bg_fa;
246
247   int xfer();
248   int xfer_slices(int slices);
249   typedef void (BC_Xfer::*xfer_fn)(unsigned y0, unsigned y1);
250   xfer_fn xfn;
251
252   class Slicer : public ListItem<Slicer>, public Thread {
253   public:
254     Condition *init, *complete;
255     Slicer(BC_Xfer *xp);
256     ~Slicer();
257     void slice(BC_Xfer *xp, unsigned y0, unsigned y1);
258     void run();
259     BC_Xfer *xp;
260     int done, y0, y1;
261   };
262
263   class SlicerList : public List<Slicer>, public Mutex {
264   public:
265     int count;
266     Slicer *get_slicer(BC_Xfer *xp);
267     void reset();
268     SlicerList();
269     ~SlicerList();
270   };
271   static SlicerList slicers;
272
273   void init(
274     uint8_t **output_rows, int out_colormodel, int out_x, int out_y, int out_w, int out_h,
275       uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp, uint8_t *out_ap, int out_rowspan,
276     uint8_t **input_rows, int in_colormodel, int in_x, int in_y, int in_w, int in_h,
277       uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp, uint8_t *in_ap, int in_rowspan,
278     int bg_color, int bg_alpha);
279
280 // generated code concatentated here