e6e0aba40b52a5bb365441d23e6aac3487c10b2d
[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_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); \
114       in_ofs /= 2; \
115       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
116       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
117
118 // yuv422p  2x1
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); \
126
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; \
130     in_rofs /= 2; \
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); \
136       in_ofs /= 2; \
137       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
138       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
139
140 // yuv444p  1x1
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); \
147
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); \
158
159 // yuv411p  4x1
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); \
167
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; \
171     in_rofs /= 4; \
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); \
177       in_ofs /= 4; \
178       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
179       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
180
181 // yuv410p  4x4
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); \
189
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); \
199       in_ofs /= 4; \
200       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
201       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
202
203 // rgb_floatp
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); \
210
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; \
216
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); \
223
224 #define xfer_rgb_floatp_row_out(oty_t) \
225   xfer_rgb_fltp_row_out(oty_t) \
226
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); \
230
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) \
234
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); \
240
241
242 class BC_Xfer {
243   BC_Xfer(const BC_Xfer&) {}
244 public:
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,
254     int bg_color);
255   ~BC_Xfer();
256
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;
264   int scale;
265   int out_pixelsize, in_pixelsize;
266   int *row_table, *column_table;
267   uint32_t bg_r, bg_g, bg_b;
268
269   void xfer();
270   void xfer_slices(int slices);
271   typedef void (BC_Xfer::*xfer_fn)(unsigned y0, unsigned y1);
272   xfer_fn xfn;
273
274   class Slicer : public ListItem<Slicer>, public Thread {
275   public:
276     Condition *init, *complete;
277     Slicer(BC_Xfer *xp);
278     ~Slicer();
279     void slice(BC_Xfer *xp, unsigned y0, unsigned y1);
280     void run();
281     BC_Xfer *xp;
282     int done, y0, y1;
283   };
284
285   class SlicerList : public List<Slicer>, public Mutex {
286   public:
287     int count;
288     Slicer *get_slicer(BC_Xfer *xp);
289     void reset();
290     SlicerList();
291     ~SlicerList();
292   };
293   static SlicerList slicers;
294
295   static void init();
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];
311
312   void init(
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,
317     int bg_color);
318
319 // generated code concatentated here