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