rework keyframe hide popup, keyframe auto render, textbox set_selection wide text
[goodguy/history.git] / cinelerra-5.1 / guicast / xfer.h
1 #include "bccmodels.h"
2 #include "clip.h"
3
4 static inline float clp(const int n, float v) {
5  v *= ((float)(n*(1-1./0x1000000)));
6  return v < 0 ? 0 : v >= n ? n-1 : v;
7 }
8
9 static inline float fclp(float v, const int n) {
10  v /= ((float)(n*(1-1./0x1000000)));
11  return v < 0 ? 0 : v > 1 ? 1 : v;
12 }
13
14 #include <stdint.h>
15
16 #define ZTYP(ty) typedef ty z_##ty __attribute__ ((__unused__))
17 ZTYP(int);
18 ZTYP(float);
19
20 // All variables are unsigned
21 // y -> 24 bits u, v, -> 8 bits r, g, b -> 8 bits
22 #define YUV_TO_RGB(y, u, v, r, g, b) \
23 { \
24         (r) = ((y + vtor_tab[v]) >> 16); \
25         (g) = ((y + utog_tab[u] + vtog_tab[v]) >> 16); \
26         (b) = ((y + utob_tab[u]) >> 16); \
27         CLAMP(r, 0, 0xff); CLAMP(g, 0, 0xff); CLAMP(b, 0, 0xff); \
28 }
29
30 // y -> 0 - 1 float
31 // u, v, -> 8 bits
32 // r, g, b -> float
33 #define YUV_TO_FLOAT(y, u, v, r, g, b) \
34 { \
35         (r) = y + vtor_float_tab[v]; \
36         (g) = y + utog_float_tab[u] + vtog_float_tab[v]; \
37         (b) = y + utob_float_tab[u]; \
38 }
39
40 // y -> 0 - 1 float
41 // u, v, -> 16 bits
42 // r, g, b -> float
43 #define YUV16_TO_RGB_FLOAT(y, u, v, r, g, b) \
44 { \
45         (r) = y + v16tor_float_tab[v]; \
46         (g) = y + u16tog_float_tab[u] + v16tog_float_tab[v]; \
47         (b) = y + u16tob_float_tab[u]; \
48 }
49
50 // y -> 24 bits   u, v-> 16 bits
51 #define YUV_TO_RGB16(y, u, v, r, g, b) \
52 { \
53         (r) = ((y + vtor_tab16[v]) >> 8); \
54         (g) = ((y + utog_tab16[u] + vtog_tab16[v]) >> 8); \
55         (b) = ((y + utob_tab16[u]) >> 8); \
56         CLAMP(r, 0, 0xffff); CLAMP(g, 0, 0xffff); CLAMP(b, 0, 0xffff); \
57 }
58
59
60
61
62 #define RGB_TO_YUV(y, u, v, r, g, b) \
63 { \
64         y = ((rtoy_tab[r] + gtoy_tab[g] + btoy_tab[b]) >> 16); \
65         u = ((rtou_tab[r] + gtou_tab[g] + btou_tab[b]) >> 16); \
66         v = ((rtov_tab[r] + gtov_tab[g] + btov_tab[b]) >> 16); \
67         CLAMP(y, 0, 0xff); CLAMP(u, 0, 0xff); CLAMP(v, 0, 0xff); \
68 }
69
70 // r, g, b -> 16 bits
71 #define RGB_TO_YUV16(y, u, v, r, g, b) \
72 { \
73         y = ((rtoy_tab16[r] + gtoy_tab16[g] + btoy_tab16[b]) >> 8); \
74         u = ((rtou_tab16[r] + gtou_tab16[g] + btou_tab16[b]) >> 8); \
75         v = ((rtov_tab16[r] + gtov_tab16[g] + btov_tab16[b]) >> 8); \
76         CLAMP(y, 0, 0xffff); CLAMP(u, 0, 0xffff); CLAMP(v, 0, 0xffff); \
77 }
78
79
80 #define xfer_flat_row_out(oty_t) \
81   for( unsigned i=0; i<out_h; ++i ) { \
82     oty_t *out = (oty_t *)(output_rows[i + out_y] + out_x * out_pixelsize); \
83
84 #define xfer_flat_row_in(ity_t) \
85     uint8_t *inp_row = input_rows[row_table[i]]; \
86     for( unsigned j=0; j<out_w; ++j ) { \
87       ity_t *inp = (ity_t *)(inp_row + column_table[j]); \
88
89 #define xfer_end } }
90
91 // yuv420p  2x2
92 #define xfer_yuv420p_row_out(oty_t) \
93   for( unsigned i=0; i<out_h; ++i ) { \
94     int out_rofs = i * total_out_w + out_x; \
95     oty_t *yop = (oty_t *)(out_yp + out_rofs); \
96     out_rofs = i / 2 * total_out_w / 2 + out_x / 2; \
97     oty_t *uop = (oty_t *)(out_up + out_rofs); \
98     oty_t *vop = (oty_t *)(out_vp + out_rofs); \
99
100 #define xfer_yuv420p_row_in(ity_t) \
101     int in_rofs = row_table[i] * total_in_w; \
102     uint8_t *yip_row = in_yp + in_rofs; \
103     in_rofs = row_table[i] / 2 * total_in_w / 2; \
104     uint8_t *uip_row = in_up + in_rofs; \
105     uint8_t *vip_row = in_vp + in_rofs; \
106     for( unsigned j=0; j<out_w; ++j ) { \
107       int in_ofs = column_table[j]; \
108       ity_t *yip = (ity_t *)(yip_row + in_ofs); \
109       in_ofs /= 2; \
110       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
111       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
112
113 // yuv422p  2x1
114 #define xfer_yuv422p_row_out(oty_t) \
115   for( unsigned i=0; i<out_h; ++i ) { \
116     int out_rofs = i * total_out_w + out_x; \
117     oty_t *yop = (oty_t *)(out_yp + out_rofs); \
118     out_rofs = i * total_out_w / 2 + out_x / 2; \
119     oty_t *uop = (oty_t *)(out_up + out_rofs); \
120     oty_t *vop = (oty_t *)(out_vp + out_rofs); \
121
122 #define xfer_yuv422p_row_in(ity_t) \
123     int in_rofs = row_table[i] * total_in_w; \
124     uint8_t *yip_row = in_yp + in_rofs; \
125     in_rofs /= 2; \
126     uint8_t *uip_row = in_up + in_rofs; \
127     uint8_t *vip_row = in_vp + in_rofs; \
128     for( unsigned j=0; j<out_w; ++j ) { \
129       int in_ofs = column_table[j]; \
130       ity_t *yip = (ity_t *)(yip_row + in_ofs); \
131       in_ofs /= 2; \
132       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
133       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
134
135 // yuv444p  1x1
136 #define xfer_yuv444p_row_out(oty_t) \
137   for( unsigned i=0; i<out_h; ++i ) { \
138     int out_rofs = i * total_out_w + out_x; \
139     oty_t *yop = (oty_t *)((oty_t *)(out_yp + out_rofs)); \
140     oty_t *uop = (oty_t *)(out_up + out_rofs); \
141     oty_t *vop = (oty_t *)(out_vp + out_rofs); \
142
143 #define xfer_yuv444p_row_in(ity_t) \
144     int in_rofs = row_table[i] * total_in_w; \
145     uint8_t *yip_row = in_yp + in_rofs; \
146     uint8_t *uip_row = in_up + in_rofs; \
147     uint8_t *vip_row = in_vp + in_rofs; \
148     for( unsigned j=0; j<out_w; ++j ) { \
149       int in_ofs = column_table[j]; \
150       ity_t *yip = (ity_t *)(yip_row + in_ofs); \
151       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
152       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
153
154 // yuv411p  4x1
155 #define xfer_yuv411p_row_out(oty_t) \
156   for( unsigned i=0; i<out_h; ++i ) { \
157     int out_rofs = i * total_out_w + out_x; \
158     oty_t *yop = (oty_t *)(out_yp + out_rofs); \
159     out_rofs = i * total_out_w / 4 + out_x / 4; \
160     oty_t *uop = (oty_t *)(out_up + out_rofs); \
161     oty_t *vop = (oty_t *)(out_vp + out_rofs); \
162
163 #define xfer_yuv411p_row_in(ity_t) \
164     int in_rofs = row_table[i] * total_in_w; \
165     uint8_t *yip_row = in_yp + in_rofs; \
166     in_rofs /= 4; \
167     uint8_t *uip_row = in_up + in_rofs; \
168     uint8_t *vip_row = in_vp + in_rofs; \
169     for( unsigned j=0; j<out_w; ++j ) { \
170       int in_ofs = column_table[j]; \
171       ity_t *yip = (ity_t *)(yip_row + in_ofs); \
172       in_ofs /= 4; \
173       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
174       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
175
176 // yuv410p  4x4
177 #define xfer_yuv410p_row_out(oty_t) \
178   for( unsigned i=0; i<out_h; ++i ) { \
179     int out_rofs = i * total_out_w + out_x; \
180     oty_t *yop = (oty_t *)(out_yp + out_rofs); \
181     out_rofs = i / 4 * total_out_w / 4 + out_x / 4; \
182     oty_t *uop = (oty_t *)(out_up + out_rofs); \
183     oty_t *vop = (oty_t *)(out_vp + out_rofs); \
184
185 #define xfer_yuv410p_row_in(ity_t) \
186     int in_rofs = row_table[i] * total_in_w; \
187     uint8_t *yip_row = in_yp + in_rofs; \
188     in_rofs = row_table[i] / 4 * total_in_w / 4; \
189     uint8_t *uip_row = in_up + in_rofs; \
190     uint8_t *vip_row = in_vp + in_rofs; \
191     for( unsigned j=0; j<out_w; ++j ) { \
192       int in_ofs = column_table[j]; \
193       ity_t *yip = (ity_t *)(yip_row + in_ofs); \
194       in_ofs /= 4; \
195       ity_t *uip = (ity_t *)(uip_row + in_ofs); \
196       ity_t *vip = (ity_t *)(vip_row + in_ofs); \
197
198 // rgb_floatp
199 #define xfer_rgb_fltp_row_out(oty_t) \
200   for( unsigned i=0; i<out_h; ++i ) { \
201     int out_rofs = i * total_out_w + out_x; \
202     oty_t *rop = (oty_t *)(out_yp + out_rofs); \
203     oty_t *gop = (oty_t *)(out_up + out_rofs); \
204     oty_t *bop = (oty_t *)(out_vp + out_rofs); \
205
206 #define xfer_rgb_fltp_row_in(ity_t) \
207     int in_rofs = row_table[i] * total_in_w; \
208     uint8_t *rip_row = in_yp + in_rofs; \
209     uint8_t *gip_row = in_up + in_rofs; \
210     uint8_t *bip_row = in_vp + in_rofs; \
211
212 #define xfer_rgb_fltp_col_in(ity_t) \
213     for( unsigned j=0; j<out_w; ++j ) { \
214       int in_ofs = column_table[j]; \
215       ity_t *rip = (ity_t *)(rip_row + in_ofs); \
216       ity_t *gip = (ity_t *)(gip_row + in_ofs); \
217       ity_t *bip = (ity_t *)(bip_row + in_ofs); \
218
219 #define xfer_rgb_floatp_row_out(oty_t) \
220   xfer_rgb_fltp_row_out(oty_t) \
221
222 #define xfer_rgba_floatp_row_out(oty_t) \
223   xfer_rgb_fltp_row_out(oty_t) \
224     oty_t *aop = (oty_t *)(out_ap + out_rofs); \
225
226 #define xfer_rgb_floatp_row_in(ity_t) \
227   xfer_rgb_fltp_row_in(ity_t) \
228    xfer_rgb_fltp_col_in(ity_t) \
229
230 #define xfer_rgba_floatp_row_in(ity_t) \
231   xfer_rgb_fltp_row_in(ity_t) \
232     uint8_t *aip_row = in_ap + in_rofs; \
233     xfer_rgb_fltp_col_in(ity_t) \
234       ity_t *aip = (ity_t *)(aip_row + in_ofs); \
235
236
237 class BC_Xfer {
238   BC_Xfer(const BC_Xfer&) {}
239 public:
240   BC_Xfer(uint8_t **output_rows, uint8_t **input_rows,
241     uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp,
242     uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp,
243     int in_x, int in_y, int in_w, int in_h, int out_x, int out_y, int out_w, int out_h,
244     int in_colormodel, int out_colormodel, int bg_color, int in_rowspan, int out_rowspan);
245   BC_Xfer(uint8_t **output_ptrs, int out_colormodel,
246       int out_x, int out_y, int out_w, int out_h, int out_rowspan,
247     uint8_t **input_ptrs, int in_colormodel,
248       int in_x, int in_y, int in_w, int in_h, int in_rowspan,
249     int bg_color);
250   ~BC_Xfer();
251
252   uint8_t **output_rows, **input_rows;
253   uint8_t *out_yp, *out_up, *out_vp, *out_ap;
254   uint8_t *in_yp, *in_up, *in_vp, *in_ap;
255   int in_x, in_y; unsigned in_w, in_h;
256   int out_x, out_y; unsigned out_w, out_h;
257   int in_colormodel, out_colormodel;
258   uint32_t bg_color, total_in_w, total_out_w;
259   int scale;
260   int out_pixelsize, in_pixelsize;
261   int *row_table, *column_table;
262   uint32_t bg_r, bg_g, bg_b;
263
264   void xfer();
265
266   static void init();
267   static class Tables { public: Tables() { init(); } } tables;
268   static int rtoy_tab[0x100], gtoy_tab[0x100], btoy_tab[0x100];
269   static int rtou_tab[0x100], gtou_tab[0x100], btou_tab[0x100];
270   static int rtov_tab[0x100], gtov_tab[0x100], btov_tab[0x100];
271   static int vtor_tab[0x100], vtog_tab[0x100];
272   static int utog_tab[0x100], utob_tab[0x100];
273   static float vtor_float_tab[0x100], vtog_float_tab[0x100];
274   static float utog_float_tab[0x100], utob_float_tab[0x100];
275   static int rtoy_tab16[0x10000], gtoy_tab16[0x10000], btoy_tab16[0x10000];
276   static int rtou_tab16[0x10000], gtou_tab16[0x10000], btou_tab16[0x10000];
277   static int rtov_tab16[0x10000], gtov_tab16[0x10000], btov_tab16[0x10000];
278   static int vtor_tab16[0x10000], vtog_tab16[0x10000];
279   static int utog_tab16[0x10000], utob_tab16[0x10000];
280   static float v16tor_float_tab[0x10000], v16tog_float_tab[0x10000];
281   static float u16tog_float_tab[0x10000], u16tob_float_tab[0x10000];
282
283   void init(
284     uint8_t **output_rows, int out_colormodel, int out_x, int out_y, int out_w, int out_h,
285       uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp, uint8_t *out_ap, int out_rowspan,
286     uint8_t **input_rows, int in_colormodel, int in_x, int in_y, int in_w, int in_h,
287       uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp, uint8_t *in_ap, int in_rowspan,
288     int bg_color);
289
290 // generated code concatentated here