ecc83f88b4bdb707761fd00ec22577e32c7a0fcb
[platform/upstream/gstreamer.git] / gst / videotestsrc / videotestsrc.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 /* non-GST-specific stuff */
25
26 #include "gstvideotestsrc.h"
27 #include "videotestsrc.h"
28 #include "gstvideotestsrcorc.h"
29
30 #include <gst/math-compat.h>
31
32 #include <string.h>
33 #include <stdlib.h>
34
35 #define TO_16(x) (((x)<<8) | (x))
36 #define TO_10(x) (((x)<<2) | ((x)>>6))
37
38 static void paint_tmpline_ARGB (paintinfo * p, int x, int w);
39 static void paint_tmpline_AYUV (paintinfo * p, int x, int w);
40
41 static unsigned char
42 random_char (void)
43 {
44   static unsigned int state;
45
46   state *= 1103515245;
47   state += 12345;
48   return (state >> 16) & 0xff;
49 }
50
51 enum
52 {
53   COLOR_WHITE = 0,
54   COLOR_YELLOW,
55   COLOR_CYAN,
56   COLOR_GREEN,
57   COLOR_MAGENTA,
58   COLOR_RED,
59   COLOR_BLUE,
60   COLOR_BLACK,
61   COLOR_NEG_I,
62   COLOR_POS_Q,
63   COLOR_SUPER_BLACK,
64   COLOR_DARK_GREY
65 };
66
67 static const struct vts_color_struct vts_colors_bt709_ycbcr_100[] = {
68   {235, 128, 128, 255, 255, 255, 255, (235 << 8)},
69   {219, 16, 138, 255, 255, 255, 0, (219 << 8)},
70   {188, 154, 16, 255, 0, 255, 255, (188 < 8)},
71   {173, 42, 26, 255, 0, 255, 0, (173 << 8)},
72   {78, 214, 230, 255, 255, 0, 255, (78 << 8)},
73   {63, 102, 240, 255, 255, 0, 0, (64 << 8)},
74   {32, 240, 118, 255, 0, 0, 255, (32 << 8)},
75   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
76   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
77   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
78   {0, 128, 128, 255, 0, 0, 0, 0},
79   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
80 };
81
82 static const struct vts_color_struct vts_colors_bt709_ycbcr_75[] = {
83   {180, 128, 128, 255, 191, 191, 191, (180 << 8)},
84   {168, 44, 136, 255, 191, 191, 0, (168 << 8)},
85   {145, 147, 44, 255, 0, 191, 191, (145 << 8)},
86   {133, 63, 52, 255, 0, 191, 0, (133 << 8)},
87   {63, 193, 204, 255, 191, 0, 191, (63 << 8)},
88   {51, 109, 212, 255, 191, 0, 0, (51 << 8)},
89   {28, 212, 120, 255, 0, 0, 191, (28 << 8)},
90   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
91   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
92   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
93   {0, 128, 128, 255, 0, 0, 0, 0},
94   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
95 };
96
97 static const struct vts_color_struct vts_colors_bt601_ycbcr_100[] = {
98   {235, 128, 128, 255, 255, 255, 255, (235 << 8)},
99   {210, 16, 146, 255, 255, 255, 0, (219 << 8)},
100   {170, 166, 16, 255, 0, 255, 255, (188 < 8)},
101   {145, 54, 34, 255, 0, 255, 0, (173 << 8)},
102   {106, 202, 222, 255, 255, 0, 255, (78 << 8)},
103   {81, 90, 240, 255, 255, 0, 0, (64 << 8)},
104   {41, 240, 110, 255, 0, 0, 255, (32 << 8)},
105   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
106   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
107   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
108   {-0, 128, 128, 255, 0, 0, 0, 0},
109   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
110 };
111
112 static const struct vts_color_struct vts_colors_bt601_ycbcr_75[] = {
113   {180, 128, 128, 255, 191, 191, 191, (180 << 8)},
114   {162, 44, 142, 255, 191, 191, 0, (168 << 8)},
115   {131, 156, 44, 255, 0, 191, 191, (145 << 8)},
116   {112, 72, 58, 255, 0, 191, 0, (133 << 8)},
117   {84, 184, 198, 255, 191, 0, 191, (63 << 8)},
118   {65, 100, 212, 255, 191, 0, 0, (51 << 8)},
119   {35, 212, 114, 255, 0, 0, 191, (28 << 8)},
120   {16, 128, 128, 255, 0, 0, 0, (16 << 8)},
121   {16, 198, 21, 255, 0, 0, 128, (16 << 8)},     /* -I ? */
122   {16, 235, 198, 255, 0, 128, 255, (16 << 8)},  /* +Q ? */
123   {-0, 128, 128, 255, 0, 0, 0, 0},
124   {32, 128, 128, 255, 19, 19, 19, (32 << 8)},
125 };
126
127
128 static void paint_setup_I420 (paintinfo * p, unsigned char *dest);
129 static void paint_setup_YV12 (paintinfo * p, unsigned char *dest);
130 static void paint_setup_YUY2 (paintinfo * p, unsigned char *dest);
131 static void paint_setup_UYVY (paintinfo * p, unsigned char *dest);
132 static void paint_setup_YVYU (paintinfo * p, unsigned char *dest);
133 #ifdef disabled
134 static void paint_setup_IYU2 (paintinfo * p, unsigned char *dest);
135 #endif
136 static void paint_setup_Y41B (paintinfo * p, unsigned char *dest);
137 static void paint_setup_Y42B (paintinfo * p, unsigned char *dest);
138 static void paint_setup_Y444 (paintinfo * p, unsigned char *dest);
139 static void paint_setup_Y800 (paintinfo * p, unsigned char *dest);
140 static void paint_setup_AYUV (paintinfo * p, unsigned char *dest);
141 static void paint_setup_v308 (paintinfo * p, unsigned char *dest);
142 static void paint_setup_NV12 (paintinfo * p, unsigned char *dest);
143 static void paint_setup_NV21 (paintinfo * p, unsigned char *dest);
144 #ifdef disabled
145 static void paint_setup_v410 (paintinfo * p, unsigned char *dest);
146 #endif
147 static void paint_setup_v216 (paintinfo * p, unsigned char *dest);
148 static void paint_setup_v210 (paintinfo * p, unsigned char *dest);
149 static void paint_setup_UYVP (paintinfo * p, unsigned char *dest);
150 static void paint_setup_AY64 (paintinfo * p, unsigned char *dest);
151
152 static void paint_setup_YUV9 (paintinfo * p, unsigned char *dest);
153 static void paint_setup_YVU9 (paintinfo * p, unsigned char *dest);
154 static void paint_setup_ARGB8888 (paintinfo * p, unsigned char *dest);
155 static void paint_setup_ABGR8888 (paintinfo * p, unsigned char *dest);
156 static void paint_setup_RGBA8888 (paintinfo * p, unsigned char *dest);
157 static void paint_setup_BGRA8888 (paintinfo * p, unsigned char *dest);
158 static void paint_setup_xRGB8888 (paintinfo * p, unsigned char *dest);
159 static void paint_setup_xBGR8888 (paintinfo * p, unsigned char *dest);
160 static void paint_setup_RGBx8888 (paintinfo * p, unsigned char *dest);
161 static void paint_setup_BGRx8888 (paintinfo * p, unsigned char *dest);
162 static void paint_setup_RGB888 (paintinfo * p, unsigned char *dest);
163 static void paint_setup_BGR888 (paintinfo * p, unsigned char *dest);
164 static void paint_setup_RGB565 (paintinfo * p, unsigned char *dest);
165 static void paint_setup_xRGB1555 (paintinfo * p, unsigned char *dest);
166 static void paint_setup_ARGB64 (paintinfo * p, unsigned char *dest);
167
168 static void paint_setup_bayer_bggr (paintinfo * p, unsigned char *dest);
169 static void paint_setup_bayer_rggb (paintinfo * p, unsigned char *dest);
170 static void paint_setup_bayer_gbrg (paintinfo * p, unsigned char *dest);
171 static void paint_setup_bayer_grbg (paintinfo * p, unsigned char *dest);
172
173 static void convert_hline_I420 (paintinfo * p, int y);
174 static void convert_hline_NV12 (paintinfo * p, int y);
175 static void convert_hline_NV21 (paintinfo * p, int y);
176 static void convert_hline_YUY2 (paintinfo * p, int y);
177 #ifdef disabled
178 static void convert_hline_IYU2 (paintinfo * p, int y);
179 #endif
180 static void convert_hline_Y41B (paintinfo * p, int y);
181 static void convert_hline_Y42B (paintinfo * p, int y);
182 static void convert_hline_Y444 (paintinfo * p, int y);
183 static void convert_hline_Y800 (paintinfo * p, int y);
184 static void convert_hline_v308 (paintinfo * p, int y);
185 static void convert_hline_AYUV (paintinfo * p, int y);
186 #ifdef disabled
187 static void convert_hline_v410 (paintinfo * p, int y);
188 #endif
189 static void convert_hline_v216 (paintinfo * p, int y);
190 static void convert_hline_v210 (paintinfo * p, int y);
191 static void convert_hline_UYVP (paintinfo * p, int y);
192 static void convert_hline_AY64 (paintinfo * p, int y);
193
194 static void convert_hline_YUV9 (paintinfo * p, int y);
195 static void convert_hline_astr4 (paintinfo * p, int y);
196 static void convert_hline_astr8 (paintinfo * p, int y);
197 static void convert_hline_str4 (paintinfo * p, int y);
198 static void convert_hline_str3 (paintinfo * p, int y);
199 static void convert_hline_RGB565 (paintinfo * p, int y);
200 static void convert_hline_xRGB1555 (paintinfo * p, int y);
201
202 static void convert_hline_bayer (paintinfo * p, int y);
203
204 static void paint_setup_GRAY8 (paintinfo * p, unsigned char *dest);
205 static void paint_setup_GRAY16 (paintinfo * p, unsigned char *dest);
206 static void convert_hline_GRAY8 (paintinfo * p, int y);
207 static void convert_hline_GRAY16 (paintinfo * p, int y);
208
209 struct fourcc_list_struct fourcc_list[] = {
210 /* packed */
211   {VTS_YUV, "YUY2", "YUY2", 16, paint_setup_YUY2, convert_hline_YUY2},
212   {VTS_YUV, "UYVY", "UYVY", 16, paint_setup_UYVY, convert_hline_YUY2},
213 #ifdef disabled
214   {VTS_YUV, "Y422", "Y422", 16, paint_setup_UYVY, convert_hline_YUY2},
215   {VTS_YUV, "UYNV", "UYNV", 16, paint_setup_UYVY, convert_hline_YUY2},  /* FIXME: UYNV? */
216 #endif
217   {VTS_YUV, "YVYU", "YVYU", 16, paint_setup_YVYU, convert_hline_YUY2},
218   {VTS_YUV, "v308", "v308", 24, paint_setup_v308, convert_hline_v308},
219   {VTS_YUV, "AYUV", "AYUV", 32, paint_setup_AYUV, convert_hline_AYUV},
220 #ifdef disabled
221   {VTS_YUV, "v410", "v410", 32, paint_setup_v410, convert_hline_v410},
222 #endif
223   {VTS_YUV, "v210", "v210", 21, paint_setup_v210, convert_hline_v210},
224   {VTS_YUV, "v216", "v216", 32, paint_setup_v216, convert_hline_v216},
225   {VTS_YUV, "UYVP", "UYVP", 20, paint_setup_UYVP, convert_hline_UYVP},
226   {VTS_YUV, "AY64", "AY64", 64, paint_setup_AY64, convert_hline_AY64},
227
228 #ifdef disabled
229   {VTS_YUV, "IYU2", "IYU2", 24, paint_setup_IYU2, convert_hline_IYU2},
230 #endif
231
232 /* planar */
233   /* YVU9 */
234   {VTS_YUV, "YVU9", "YVU9", 9, paint_setup_YVU9, convert_hline_YUV9},
235   /* YUV9 */
236   {VTS_YUV, "YUV9", "YUV9", 9, paint_setup_YUV9, convert_hline_YUV9},
237   /* IF09 */
238   /* YV12 */
239   {VTS_YUV, "YV12", "YV12", 12, paint_setup_YV12, convert_hline_I420},
240   /* I420 */
241   {VTS_YUV, "I420", "I420", 12, paint_setup_I420, convert_hline_I420},
242   /* NV12 */
243   {VTS_YUV, "NV12", "NV12", 12, paint_setup_NV12, convert_hline_NV12},
244   /* NV21 */
245   {VTS_YUV, "NV21", "NV21", 12, paint_setup_NV21, convert_hline_NV21},
246   /* CLPL */
247   /* Y41B */
248   {VTS_YUV, "Y41B", "Y41B", 12, paint_setup_Y41B, convert_hline_Y41B},
249   /* Y42B */
250   {VTS_YUV, "Y42B", "Y42B", 16, paint_setup_Y42B, convert_hline_Y42B},
251   /* Y444 */
252   {VTS_YUV, "Y444", "Y444", 24, paint_setup_Y444, convert_hline_Y444},
253   /* Y800 grayscale */
254   {VTS_YUV, "Y800", "Y800", 8, paint_setup_Y800, convert_hline_Y800},
255
256   /* Not exactly YUV but it's the same as above */
257   {VTS_GRAY, "GRAY8", "GRAY8", 8, paint_setup_GRAY8, convert_hline_GRAY8},
258   {VTS_GRAY, "GRAY16", "GRAY16", 16, paint_setup_GRAY16, convert_hline_GRAY16},
259
260   {VTS_RGB, "RGB ", "xRGB8888", 32, paint_setup_xRGB8888, convert_hline_str4,
261         24,
262       0x00ff0000, 0x0000ff00, 0x000000ff},
263   {VTS_RGB, "RGB ", "xBGR8888", 32, paint_setup_xBGR8888, convert_hline_str4,
264         24,
265       0x000000ff, 0x0000ff00, 0x00ff0000},
266   {VTS_RGB, "RGB ", "RGBx8888", 32, paint_setup_RGBx8888, convert_hline_str4,
267         24,
268       0xff000000, 0x00ff0000, 0x0000ff00},
269   {VTS_RGB, "RGB ", "BGRx8888", 32, paint_setup_BGRx8888, convert_hline_str4,
270         24,
271       0x0000ff00, 0x00ff0000, 0xff000000},
272   {VTS_RGB, "RGB ", "ARGB8888", 32, paint_setup_ARGB8888, convert_hline_astr4,
273         32,
274       0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000},
275   {VTS_RGB, "RGB ", "ABGR8888", 32, paint_setup_ABGR8888, convert_hline_astr4,
276         32,
277       0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000},
278   {VTS_RGB, "RGB ", "RGBA8888", 32, paint_setup_RGBA8888, convert_hline_astr4,
279         32,
280       0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff},
281   {VTS_RGB, "RGB ", "BGRA8888", 32, paint_setup_BGRA8888, convert_hline_astr4,
282         32,
283       0x0000ff00, 0x00ff0000, 0xff000000, 0x000000ff},
284   {VTS_RGB, "RGB ", "RGB888", 24, paint_setup_RGB888, convert_hline_str3, 24,
285       0x00ff0000, 0x0000ff00, 0x000000ff},
286   {VTS_RGB, "RGB ", "BGR888", 24, paint_setup_BGR888, convert_hline_str3, 24,
287       0x000000ff, 0x0000ff00, 0x00ff0000},
288   {VTS_RGB, "RGB ", "RGB565", 16, paint_setup_RGB565, convert_hline_RGB565, 16,
289       0x0000f800, 0x000007e0, 0x0000001f},
290   {VTS_RGB, "RGB ", "xRGB1555", 16, paint_setup_xRGB1555,
291         convert_hline_xRGB1555,
292         15,
293       0x00007c00, 0x000003e0, 0x0000001f},
294   {VTS_RGB, "RGB ", "ARGB8888", 64, paint_setup_ARGB64, convert_hline_astr8,
295         64,
296       0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000},
297
298   {VTS_BAYER, "bggr", "Bayer", 8, paint_setup_bayer_bggr, convert_hline_bayer},
299   {VTS_BAYER, "rggb", "Bayer", 8, paint_setup_bayer_rggb, convert_hline_bayer},
300   {VTS_BAYER, "grbg", "Bayer", 8, paint_setup_bayer_grbg, convert_hline_bayer},
301   {VTS_BAYER, "gbrg", "Bayer", 8, paint_setup_bayer_gbrg, convert_hline_bayer}
302 };
303
304 int n_fourccs = G_N_ELEMENTS (fourcc_list);
305
306 struct fourcc_list_struct *
307 paintinfo_find_by_structure (const GstStructure * structure)
308 {
309   int i;
310   const char *media_type = gst_structure_get_name (structure);
311   int ret;
312
313   g_return_val_if_fail (structure, NULL);
314
315   if (strcmp (media_type, "video/x-raw-gray") == 0) {
316     gint bpp, depth, endianness = 0;
317
318     ret = gst_structure_get_int (structure, "bpp", &bpp) &&
319         gst_structure_get_int (structure, "depth", &depth);
320     if (!ret || bpp != depth || (depth != 8 && depth != 16))
321       return NULL;
322
323     ret = gst_structure_get_int (structure, "endianness", &endianness);
324     if ((!ret || endianness != G_BYTE_ORDER) && bpp == 16)
325       return NULL;
326
327     for (i = 0; i < n_fourccs; i++) {
328       if (fourcc_list[i].type == VTS_GRAY && fourcc_list[i].bitspp == bpp) {
329         return fourcc_list + i;
330       }
331     }
332   } else if (strcmp (media_type, "video/x-raw-yuv") == 0) {
333     const char *s;
334     int fourcc;
335     guint32 format;
336
337     ret = gst_structure_get_fourcc (structure, "format", &format);
338     if (!ret)
339       return NULL;
340     for (i = 0; i < n_fourccs; i++) {
341       s = fourcc_list[i].fourcc;
342       /* g_print("testing %" GST_FOURCC_FORMAT " and %s\n", GST_FOURCC_ARGS(format), s); */
343       fourcc = GST_MAKE_FOURCC (s[0], s[1], s[2], s[3]);
344       if (fourcc_list[i].type == VTS_YUV && fourcc == format) {
345         return fourcc_list + i;
346       }
347     }
348   } else if (strcmp (media_type, "video/x-raw-rgb") == 0) {
349     int red_mask;
350     int green_mask;
351     int blue_mask;
352     int alpha_mask;
353     int depth;
354     int bpp;
355
356     ret = gst_structure_get_int (structure, "red_mask", &red_mask);
357     ret &= gst_structure_get_int (structure, "green_mask", &green_mask);
358     ret &= gst_structure_get_int (structure, "blue_mask", &blue_mask);
359     ret &= gst_structure_get_int (structure, "depth", &depth);
360     ret &= gst_structure_get_int (structure, "bpp", &bpp);
361
362     if (depth == 32) {
363       ret &= gst_structure_get_int (structure, "alpha_mask", &alpha_mask);
364       ret &= (alpha_mask != 0);
365     } else {
366       alpha_mask = 0;
367     }
368
369     if (!ret) {
370       GST_WARNING ("incomplete caps structure: %" GST_PTR_FORMAT, structure);
371       return NULL;
372     }
373
374     for (i = 0; i < n_fourccs; i++) {
375       if (fourcc_list[i].type == VTS_RGB &&
376           fourcc_list[i].red_mask == red_mask &&
377           fourcc_list[i].green_mask == green_mask &&
378           fourcc_list[i].blue_mask == blue_mask &&
379           (alpha_mask == 0 || fourcc_list[i].alpha_mask == alpha_mask) &&
380           fourcc_list[i].depth == depth && fourcc_list[i].bitspp == bpp) {
381         return fourcc_list + i;
382       }
383     }
384     return NULL;
385   } else if (strcmp (media_type, "video/x-raw-bayer") == 0) {
386     const gchar *format;
387
388     format = gst_structure_get_string (structure, "format");
389     if (!format) {
390       GST_WARNING ("incomplete caps structure: %" GST_PTR_FORMAT, structure);
391       return NULL;
392     }
393
394     for (i = 0; i < n_fourccs; i++) {
395       if (fourcc_list[i].type == VTS_BAYER &&
396           g_str_equal (format, fourcc_list[i].fourcc)) {
397         return fourcc_list + i;
398       }
399     }
400     return NULL;
401   }
402
403   g_critical ("format not found for media type %s", media_type);
404
405   return NULL;
406 }
407
408 struct fourcc_list_struct *
409 paintrect_find_fourcc (int find_fourcc)
410 {
411   int i;
412
413   for (i = 0; i < n_fourccs; i++) {
414     const char *s;
415     int fourcc;
416
417     s = fourcc_list[i].fourcc;
418     fourcc = GST_MAKE_FOURCC (s[0], s[1], s[2], s[3]);
419     if (find_fourcc == fourcc) {
420       /* If YUV format, it's good */
421       if (!fourcc_list[i].type == VTS_YUV) {
422         return fourcc_list + i;
423       }
424
425       return fourcc_list + i;
426     }
427   }
428   return NULL;
429 }
430
431 struct fourcc_list_struct *
432 paintrect_find_name (const char *name)
433 {
434   int i;
435
436   for (i = 0; i < n_fourccs; i++) {
437     if (strcmp (name, fourcc_list[i].name) == 0) {
438       return fourcc_list + i;
439     }
440   }
441   return NULL;
442 }
443
444
445 GstStructure *
446 paint_get_structure (struct fourcc_list_struct * format)
447 {
448   GstStructure *structure = NULL;
449   unsigned int fourcc;
450   int endianness;
451
452   g_return_val_if_fail (format, NULL);
453
454   fourcc =
455       GST_MAKE_FOURCC (format->fourcc[0], format->fourcc[1], format->fourcc[2],
456       format->fourcc[3]);
457
458   switch (format->type) {
459     case VTS_RGB:
460       if (format->bitspp == 16) {
461         endianness = G_BYTE_ORDER;
462       } else {
463         endianness = G_BIG_ENDIAN;
464       }
465       structure = gst_structure_new ("video/x-raw-rgb",
466           "bpp", G_TYPE_INT, format->bitspp,
467           "endianness", G_TYPE_INT, endianness,
468           "depth", G_TYPE_INT, format->depth,
469           "red_mask", G_TYPE_INT, format->red_mask,
470           "green_mask", G_TYPE_INT, format->green_mask,
471           "blue_mask", G_TYPE_INT, format->blue_mask, NULL);
472       if (format->depth == 32 && format->alpha_mask > 0) {
473         gst_structure_set (structure, "alpha_mask", G_TYPE_INT,
474             format->alpha_mask, NULL);
475       }
476       break;
477     case VTS_GRAY:
478       structure = gst_structure_new ("video/x-raw-gray",
479           "bpp", G_TYPE_INT, format->bitspp, "depth", G_TYPE_INT,
480           format->bitspp, NULL);
481       if (format->bitspp == 16)
482         gst_structure_set (structure, "endianness", G_TYPE_INT, G_BYTE_ORDER,
483             NULL);
484       break;
485     case VTS_YUV:
486     {
487       GValue value_list = { 0 };
488       GValue value = { 0 };
489
490       structure = gst_structure_new ("video/x-raw-yuv",
491           "format", GST_TYPE_FOURCC, fourcc, NULL);
492
493       if (fourcc != GST_STR_FOURCC ("Y800")) {
494         g_value_init (&value_list, GST_TYPE_LIST);
495
496         g_value_init (&value, G_TYPE_STRING);
497         g_value_set_static_string (&value, "sdtv");
498         gst_value_list_append_value (&value_list, &value);
499
500         g_value_set_static_string (&value, "hdtv");
501         gst_value_list_append_value (&value_list, &value);
502
503         gst_structure_set_value (structure, "color-matrix", &value_list);
504         g_value_reset (&value_list);
505
506         if (fourcc != GST_STR_FOURCC ("AYUV") &&
507             fourcc != GST_STR_FOURCC ("v308") &&
508             fourcc != GST_STR_FOURCC ("v410") &&
509             fourcc != GST_STR_FOURCC ("Y444")) {
510           g_value_set_static_string (&value, "mpeg2");
511           gst_value_list_append_value (&value_list, &value);
512
513           g_value_set_static_string (&value, "jpeg");
514           gst_value_list_append_value (&value_list, &value);
515
516           gst_structure_set_value (structure, "chroma-site", &value_list);
517         }
518         g_value_unset (&value_list);
519       }
520     }
521       break;
522     case VTS_BAYER:
523       structure = gst_structure_new ("video/x-raw-bayer",
524           "format", G_TYPE_STRING, format->fourcc, NULL);
525       break;
526     default:
527       g_assert_not_reached ();
528       break;
529   }
530   return structure;
531 }
532
533 /* returns the size in bytes for one video frame of the given dimensions
534  * given the fourcc in GstVideoTestSrc */
535 int
536 gst_video_test_src_get_size (GstVideoTestSrc * v, int w, int h)
537 {
538   paintinfo pi = { NULL, };
539   paintinfo *p = &pi;
540   struct fourcc_list_struct *fourcc;
541
542   p->width = w;
543   p->height = h;
544   fourcc = v->fourcc;
545   if (fourcc == NULL)
546     return 0;
547
548   fourcc->paint_setup (p, NULL);
549
550   return (unsigned long) p->endptr;
551 }
552
553 #define SCALEBITS 10
554 #define ONE_HALF  (1 << (SCALEBITS - 1))
555 #define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
556
557 #define RGB_TO_Y(r, g, b) \
558 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
559   FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
560
561 #define RGB_TO_U(r1, g1, b1, shift)\
562 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
563      FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
564
565 #define RGB_TO_V(r1, g1, b1, shift)\
566 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
567    FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
568
569 #define RGB_TO_Y_CCIR(r, g, b) \
570 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
571   FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
572
573 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\
574 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
575      FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
576
577 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\
578 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
579    FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
580
581 #define RGB_TO_Y_CCIR_709(r, g, b) \
582 ((FIX(0.212600*219.0/255.0) * (r) + FIX(0.715200*219.0/255.0) * (g) + \
583   FIX(0.072200*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
584
585 #define RGB_TO_U_CCIR_709(r1, g1, b1, shift)\
586 (((- FIX(0.114572*224.0/255.0) * r1 - FIX(0.385427*224.0/255.0) * g1 +         \
587      FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
588
589 #define RGB_TO_V_CCIR_709(r1, g1, b1, shift)\
590 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.454153*224.0/255.0) * g1 -           \
591    FIX(0.045847*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
592
593 static void
594 videotestsrc_setup_paintinfo (GstVideoTestSrc * v, paintinfo * p, int w, int h)
595 {
596   int a, r, g, b;
597
598   if (v->color_spec == GST_VIDEO_TEST_SRC_BT601) {
599     p->colors = vts_colors_bt601_ycbcr_100;
600   } else {
601     p->colors = vts_colors_bt709_ycbcr_100;
602   }
603   p->width = w;
604   p->height = h;
605
606   p->convert_tmpline = v->fourcc->convert_hline;
607   if (v->fourcc->type == VTS_RGB || v->fourcc->type == VTS_BAYER) {
608     p->paint_tmpline = paint_tmpline_ARGB;
609   } else {
610     p->paint_tmpline = paint_tmpline_AYUV;
611   }
612   p->tmpline = v->tmpline;
613   p->tmpline2 = v->tmpline2;
614   p->tmpline_u8 = v->tmpline_u8;
615   p->x_offset = (v->horizontal_speed * v->n_frames) % p->width;
616   if (p->x_offset < 0)
617     p->x_offset += p->width;
618
619   a = (v->foreground_color >> 24) & 0xff;
620   r = (v->foreground_color >> 16) & 0xff;
621   g = (v->foreground_color >> 8) & 0xff;
622   b = (v->foreground_color >> 0) & 0xff;
623   p->foreground_color.A = a;
624   p->foreground_color.R = r;
625   p->foreground_color.G = g;
626   p->foreground_color.B = b;
627   if (v->color_spec == GST_VIDEO_TEST_SRC_BT601) {
628     p->foreground_color.Y = RGB_TO_Y_CCIR (r, g, b);
629     p->foreground_color.U = RGB_TO_U_CCIR (r, g, b, 0);
630     p->foreground_color.V = RGB_TO_V_CCIR (r, g, b, 0);
631   } else {
632     p->foreground_color.Y = RGB_TO_Y_CCIR_709 (r, g, b);
633     p->foreground_color.U = RGB_TO_U_CCIR_709 (r, g, b, 0);
634     p->foreground_color.V = RGB_TO_V_CCIR_709 (r, g, b, 0);
635   }
636   p->foreground_color.gray = RGB_TO_Y (r, g, b);
637
638   a = (v->background_color >> 24) & 0xff;
639   r = (v->background_color >> 16) & 0xff;
640   g = (v->background_color >> 8) & 0xff;
641   b = (v->background_color >> 0) & 0xff;
642   p->background_color.A = a;
643   p->background_color.R = r;
644   p->background_color.G = g;
645   p->background_color.B = b;
646   if (v->color_spec == GST_VIDEO_TEST_SRC_BT601) {
647     p->background_color.Y = RGB_TO_Y_CCIR (r, g, b);
648     p->background_color.U = RGB_TO_U_CCIR (r, g, b, 0);
649     p->background_color.V = RGB_TO_V_CCIR (r, g, b, 0);
650   } else {
651     p->background_color.Y = RGB_TO_Y_CCIR_709 (r, g, b);
652     p->background_color.U = RGB_TO_U_CCIR_709 (r, g, b, 0);
653     p->background_color.V = RGB_TO_V_CCIR_709 (r, g, b, 0);
654   }
655   p->background_color.gray = RGB_TO_Y (r, g, b);
656
657 }
658
659 static void
660 videotestsrc_convert_tmpline (paintinfo * p, int j)
661 {
662   int x = p->x_offset;
663   int i;
664
665   if (x != 0) {
666     memcpy (p->tmpline2, p->tmpline, p->width * 4);
667     memcpy (p->tmpline, p->tmpline2 + x * 4, (p->width - x) * 4);
668     memcpy (p->tmpline + (p->width - x) * 4, p->tmpline2, x * 4);
669   }
670
671   for (i = p->width; i < p->width + 5; i++) {
672     p->tmpline[4 * i + 0] = p->tmpline[4 * (p->width - 1) + 0];
673     p->tmpline[4 * i + 1] = p->tmpline[4 * (p->width - 1) + 1];
674     p->tmpline[4 * i + 2] = p->tmpline[4 * (p->width - 1) + 2];
675     p->tmpline[4 * i + 3] = p->tmpline[4 * (p->width - 1) + 3];
676   }
677
678   p->convert_tmpline (p, j);
679 }
680
681 #define BLEND1(a,b,x) ((a)*(x) + (b)*(255-(x)))
682 #define DIV255(x) (((x) + (((x)+128)>>8) + 128)>>8)
683 #define BLEND(a,b,x) DIV255(BLEND1(a,b,x))
684
685 #ifdef unused
686 static void
687 videotestsrc_blend_color (struct vts_color_struct *dest,
688     struct vts_color_struct *a, struct vts_color_struct *b, int x)
689 {
690   dest->Y = BLEND (a->Y, b->Y, x);
691   dest->U = BLEND (a->U, b->U, x);
692   dest->V = BLEND (a->V, b->V, x);
693   dest->R = BLEND (a->R, b->R, x);
694   dest->G = BLEND (a->G, b->G, x);
695   dest->B = BLEND (a->B, b->B, x);
696   dest->gray = BLEND (a->gray, b->gray, x);
697
698 }
699 #endif
700
701 static void
702 videotestsrc_blend_line (GstVideoTestSrc * v, guint8 * dest, guint8 * src,
703     struct vts_color_struct *a, struct vts_color_struct *b, int n)
704 {
705   int i;
706   if (v->fourcc->type == VTS_RGB || v->fourcc->type == VTS_BAYER) {
707     for (i = 0; i < n; i++) {
708       dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
709       dest[i * 4 + 1] = BLEND (a->R, b->R, src[i]);
710       dest[i * 4 + 2] = BLEND (a->G, b->G, src[i]);
711       dest[i * 4 + 3] = BLEND (a->B, b->B, src[i]);
712     }
713   } else {
714     for (i = 0; i < n; i++) {
715       dest[i * 4 + 0] = BLEND (a->A, b->A, src[i]);
716       dest[i * 4 + 1] = BLEND (a->Y, b->Y, src[i]);
717       dest[i * 4 + 2] = BLEND (a->U, b->U, src[i]);
718       dest[i * 4 + 3] = BLEND (a->V, b->V, src[i]);
719     }
720   }
721 #undef BLEND
722 }
723
724 void
725 gst_video_test_src_smpte (GstVideoTestSrc * v, unsigned char *dest, int w,
726     int h)
727 {
728   int i;
729   int y1, y2;
730   int j;
731   paintinfo pi = { NULL, };
732   paintinfo *p = &pi;
733   struct fourcc_list_struct *fourcc;
734
735   videotestsrc_setup_paintinfo (v, p, w, h);
736   fourcc = v->fourcc;
737   if (fourcc == NULL)
738     return;
739
740   fourcc->paint_setup (p, dest);
741
742   y1 = 2 * h / 3;
743   y2 = h * 0.75;
744
745   /* color bars */
746   for (j = 0; j < y1; j++) {
747     for (i = 0; i < 7; i++) {
748       int x1 = i * w / 7;
749       int x2 = (i + 1) * w / 7;
750
751       p->color = p->colors + i;
752       p->paint_tmpline (p, x1, (x2 - x1));
753     }
754     videotestsrc_convert_tmpline (p, j);
755   }
756
757   /* inverse blue bars */
758   for (j = y1; j < y2; j++) {
759     for (i = 0; i < 7; i++) {
760       int x1 = i * w / 7;
761       int x2 = (i + 1) * w / 7;
762       int k;
763
764       if (i & 1) {
765         k = 7;
766       } else {
767         k = 6 - i;
768       }
769       p->color = p->colors + k;
770       p->paint_tmpline (p, x1, (x2 - x1));
771     }
772     videotestsrc_convert_tmpline (p, j);
773   }
774
775   for (j = y2; j < h; j++) {
776     /* -I, white, Q regions */
777     for (i = 0; i < 3; i++) {
778       int x1 = i * w / 6;
779       int x2 = (i + 1) * w / 6;
780       int k;
781
782       if (i == 0) {
783         k = 8;
784       } else if (i == 1) {
785         k = 0;
786       } else
787         k = 9;
788
789       p->color = p->colors + k;
790       p->paint_tmpline (p, x1, (x2 - x1));
791     }
792
793     /* superblack, black, dark grey */
794     for (i = 0; i < 3; i++) {
795       int x1 = w / 2 + i * w / 12;
796       int x2 = w / 2 + (i + 1) * w / 12;
797       int k;
798
799       if (i == 0) {
800         k = COLOR_SUPER_BLACK;
801       } else if (i == 1) {
802         k = COLOR_BLACK;
803       } else
804         k = COLOR_DARK_GREY;
805
806       p->color = p->colors + k;
807       p->paint_tmpline (p, x1, (x2 - x1));
808     }
809
810     {
811       int x1 = w * 3 / 4;
812       struct vts_color_struct color;
813
814       color = p->colors[COLOR_BLACK];
815       p->color = &color;
816
817       for (i = x1; i < w; i++) {
818         int y = random_char ();
819         p->tmpline_u8[i] = y;
820       }
821       videotestsrc_blend_line (v, p->tmpline + x1 * 4, p->tmpline_u8 + x1,
822           &p->foreground_color, &p->background_color, w - x1);
823
824     }
825     videotestsrc_convert_tmpline (p, j);
826
827   }
828 }
829
830 void
831 gst_video_test_src_smpte75 (GstVideoTestSrc * v, unsigned char *dest, int w,
832     int h)
833 {
834   int i;
835   int j;
836   paintinfo pi = { NULL, };
837   paintinfo *p = &pi;
838   struct fourcc_list_struct *fourcc;
839
840   videotestsrc_setup_paintinfo (v, p, w, h);
841   if (v->color_spec == GST_VIDEO_TEST_SRC_BT601) {
842     p->colors = vts_colors_bt601_ycbcr_75;
843   } else {
844     p->colors = vts_colors_bt709_ycbcr_75;
845   }
846   fourcc = v->fourcc;
847   if (fourcc == NULL)
848     return;
849
850   fourcc->paint_setup (p, dest);
851
852   /* color bars */
853   for (j = 0; j < h; j++) {
854     for (i = 0; i < 7; i++) {
855       int x1 = i * w / 7;
856       int x2 = (i + 1) * w / 7;
857
858       p->color = p->colors + i;
859       p->paint_tmpline (p, x1, (x2 - x1));
860     }
861     videotestsrc_convert_tmpline (p, j);
862   }
863 }
864
865 void
866 gst_video_test_src_smpte100 (GstVideoTestSrc * v, unsigned char *dest, int w,
867     int h)
868 {
869   int i;
870   int j;
871   paintinfo pi = { NULL, };
872   paintinfo *p = &pi;
873   struct fourcc_list_struct *fourcc;
874
875   videotestsrc_setup_paintinfo (v, p, w, h);
876   fourcc = v->fourcc;
877   if (fourcc == NULL)
878     return;
879
880   fourcc->paint_setup (p, dest);
881
882   /* color bars */
883   for (j = 0; j < h; j++) {
884     for (i = 0; i < 7; i++) {
885       int x1 = i * w / 7;
886       int x2 = (i + 1) * w / 7;
887
888       p->color = p->colors + i;
889       p->paint_tmpline (p, x1, (x2 - x1));
890     }
891     videotestsrc_convert_tmpline (p, j);
892   }
893 }
894
895 void
896 gst_video_test_src_bar (GstVideoTestSrc * v, unsigned char *dest, int w, int h)
897 {
898   int j;
899   paintinfo pi = { NULL, };
900   paintinfo *p = &pi;
901   struct fourcc_list_struct *fourcc;
902
903   videotestsrc_setup_paintinfo (v, p, w, h);
904   fourcc = v->fourcc;
905   if (fourcc == NULL)
906     return;
907
908   fourcc->paint_setup (p, dest);
909
910   for (j = 0; j < h; j++) {
911     /* use fixed size for now */
912     int x2 = w / 7;
913
914     p->color = &p->foreground_color;
915     p->paint_tmpline (p, 0, x2);
916     p->color = &p->background_color;
917     p->paint_tmpline (p, x2, (w - x2));
918     videotestsrc_convert_tmpline (p, j);
919   }
920 }
921
922 void
923 gst_video_test_src_snow (GstVideoTestSrc * v, unsigned char *dest, int w, int h)
924 {
925   int i;
926   int j;
927   paintinfo pi = { NULL, };
928   paintinfo *p = &pi;
929   struct fourcc_list_struct *fourcc;
930   struct vts_color_struct color;
931
932   videotestsrc_setup_paintinfo (v, p, w, h);
933   fourcc = v->fourcc;
934   if (fourcc == NULL)
935     return;
936
937   fourcc->paint_setup (p, dest);
938
939   color = p->colors[COLOR_BLACK];
940   p->color = &color;
941
942   for (j = 0; j < h; j++) {
943     for (i = 0; i < w; i++) {
944       int y = random_char ();
945       p->tmpline_u8[i] = y;
946     }
947     videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
948         &p->foreground_color, &p->background_color, p->width);
949     videotestsrc_convert_tmpline (p, j);
950   }
951 }
952
953 static void
954 gst_video_test_src_unicolor (GstVideoTestSrc * v, unsigned char *dest, int w,
955     int h, int color_index)
956 {
957   int i;
958   paintinfo pi = { NULL, };
959   paintinfo *p = &pi;
960   struct fourcc_list_struct *fourcc;
961
962   videotestsrc_setup_paintinfo (v, p, w, h);
963   fourcc = v->fourcc;
964   if (fourcc == NULL)
965     return;
966
967   fourcc->paint_setup (p, dest);
968
969   p->color = p->colors + color_index;
970   if (color_index == COLOR_BLACK) {
971     p->color = &p->background_color;
972   }
973   if (color_index == COLOR_WHITE) {
974     p->color = &p->foreground_color;
975   }
976
977   for (i = 0; i < h; i++) {
978     p->paint_tmpline (p, 0, w);
979     videotestsrc_convert_tmpline (p, i);
980   }
981 }
982
983 void
984 gst_video_test_src_black (GstVideoTestSrc * v, guchar * dest, int w, int h)
985 {
986   gst_video_test_src_unicolor (v, dest, w, h, COLOR_BLACK);
987 }
988
989 void
990 gst_video_test_src_white (GstVideoTestSrc * v, guchar * dest, int w, int h)
991 {
992   gst_video_test_src_unicolor (v, dest, w, h, COLOR_WHITE);
993 }
994
995 void
996 gst_video_test_src_red (GstVideoTestSrc * v, guchar * dest, int w, int h)
997 {
998   gst_video_test_src_unicolor (v, dest, w, h, COLOR_RED);
999 }
1000
1001 void
1002 gst_video_test_src_green (GstVideoTestSrc * v, guchar * dest, int w, int h)
1003 {
1004   gst_video_test_src_unicolor (v, dest, w, h, COLOR_GREEN);
1005 }
1006
1007 void
1008 gst_video_test_src_blue (GstVideoTestSrc * v, guchar * dest, int w, int h)
1009 {
1010   gst_video_test_src_unicolor (v, dest, w, h, COLOR_BLUE);
1011 }
1012
1013 void
1014 gst_video_test_src_blink (GstVideoTestSrc * v, unsigned char *dest, int w,
1015     int h)
1016 {
1017   int i;
1018   paintinfo pi = { NULL, };
1019   paintinfo *p = &pi;
1020   struct fourcc_list_struct *fourcc;
1021
1022   videotestsrc_setup_paintinfo (v, p, w, h);
1023
1024   fourcc = v->fourcc;
1025   if (fourcc == NULL)
1026     return;
1027
1028   fourcc->paint_setup (p, dest);
1029
1030   if (v->n_frames & 1) {
1031     p->color = &p->foreground_color;
1032   } else {
1033     p->color = &p->background_color;
1034   }
1035
1036   for (i = 0; i < h; i++) {
1037     p->paint_tmpline (p, 0, w);
1038     videotestsrc_convert_tmpline (p, i);
1039   }
1040 }
1041
1042 void
1043 gst_video_test_src_solid (GstVideoTestSrc * v, unsigned char *dest, int w,
1044     int h)
1045 {
1046   int i;
1047   paintinfo pi = { NULL, };
1048   paintinfo *p = &pi;
1049   struct fourcc_list_struct *fourcc;
1050
1051   videotestsrc_setup_paintinfo (v, p, w, h);
1052
1053   fourcc = v->fourcc;
1054   if (fourcc == NULL)
1055     return;
1056
1057   fourcc->paint_setup (p, dest);
1058
1059   p->color = &p->foreground_color;
1060
1061   for (i = 0; i < h; i++) {
1062     p->paint_tmpline (p, 0, w);
1063     videotestsrc_convert_tmpline (p, i);
1064   }
1065 }
1066
1067 void
1068 gst_video_test_src_checkers1 (GstVideoTestSrc * v, guchar * dest, int w, int h)
1069 {
1070   int x, y;
1071   paintinfo pi = { NULL, };
1072   paintinfo *p = &pi;
1073   struct fourcc_list_struct *fourcc;
1074
1075   videotestsrc_setup_paintinfo (v, p, w, h);
1076
1077   fourcc = v->fourcc;
1078   if (fourcc == NULL)
1079     return;
1080
1081   fourcc->paint_setup (p, dest);
1082
1083   for (y = 0; y < h; y++) {
1084     for (x = 0; x < w; x++) {
1085       if ((x ^ y) & 1) {
1086         p->color = p->colors + COLOR_GREEN;
1087       } else {
1088         p->color = p->colors + COLOR_RED;
1089       }
1090       p->paint_tmpline (p, x, 1);
1091     }
1092     videotestsrc_convert_tmpline (p, y);
1093   }
1094 }
1095
1096 void
1097 gst_video_test_src_checkers2 (GstVideoTestSrc * v, guchar * dest, int w, int h)
1098 {
1099   int x, y;
1100   paintinfo pi = { NULL, };
1101   paintinfo *p = &pi;
1102   struct fourcc_list_struct *fourcc;
1103
1104   videotestsrc_setup_paintinfo (v, p, w, h);
1105   fourcc = v->fourcc;
1106   if (fourcc == NULL)
1107     return;
1108
1109   fourcc->paint_setup (p, dest);
1110
1111   for (y = 0; y < h; y++) {
1112     for (x = 0; x < w; x += 2) {
1113       guint len = MIN (2, w - x);
1114
1115       if ((x ^ y) & 2) {
1116         p->color = p->colors + COLOR_GREEN;
1117       } else {
1118         p->color = p->colors + COLOR_RED;
1119       }
1120       p->paint_tmpline (p, x, len);
1121     }
1122     videotestsrc_convert_tmpline (p, y);
1123   }
1124 }
1125
1126 void
1127 gst_video_test_src_checkers4 (GstVideoTestSrc * v, guchar * dest, int w, int h)
1128 {
1129   int x, y;
1130   paintinfo pi = { NULL, };
1131   paintinfo *p = &pi;
1132   struct fourcc_list_struct *fourcc;
1133
1134   videotestsrc_setup_paintinfo (v, p, w, h);
1135   fourcc = v->fourcc;
1136   if (fourcc == NULL)
1137     return;
1138
1139   fourcc->paint_setup (p, dest);
1140
1141   for (y = 0; y < h; y++) {
1142     for (x = 0; x < w; x += 4) {
1143       guint len = MIN (4, w - x);
1144
1145       if ((x ^ y) & 4) {
1146         p->color = p->colors + COLOR_GREEN;
1147       } else {
1148         p->color = p->colors + COLOR_RED;
1149       }
1150       p->paint_tmpline (p, x, len);
1151     }
1152     videotestsrc_convert_tmpline (p, y);
1153   }
1154 }
1155
1156 void
1157 gst_video_test_src_checkers8 (GstVideoTestSrc * v, guchar * dest, int w, int h)
1158 {
1159   int x, y;
1160   paintinfo pi = { NULL, };
1161   paintinfo *p = &pi;
1162   struct fourcc_list_struct *fourcc;
1163
1164   videotestsrc_setup_paintinfo (v, p, w, h);
1165   fourcc = v->fourcc;
1166   if (fourcc == NULL)
1167     return;
1168
1169   fourcc->paint_setup (p, dest);
1170
1171   for (y = 0; y < h; y++) {
1172     for (x = 0; x < w; x += 8) {
1173       guint len = MIN (8, w - x);
1174
1175       if ((x ^ y) & 8) {
1176         p->color = p->colors + COLOR_GREEN;
1177       } else {
1178         p->color = p->colors + COLOR_RED;
1179       }
1180       p->paint_tmpline (p, x, len);
1181     }
1182     videotestsrc_convert_tmpline (p, y);
1183   }
1184 }
1185
1186 static const guint8 sine_table[256] = {
1187   128, 131, 134, 137, 140, 143, 146, 149,
1188   152, 156, 159, 162, 165, 168, 171, 174,
1189   176, 179, 182, 185, 188, 191, 193, 196,
1190   199, 201, 204, 206, 209, 211, 213, 216,
1191   218, 220, 222, 224, 226, 228, 230, 232,
1192   234, 236, 237, 239, 240, 242, 243, 245,
1193   246, 247, 248, 249, 250, 251, 252, 252,
1194   253, 254, 254, 255, 255, 255, 255, 255,
1195   255, 255, 255, 255, 255, 255, 254, 254,
1196   253, 252, 252, 251, 250, 249, 248, 247,
1197   246, 245, 243, 242, 240, 239, 237, 236,
1198   234, 232, 230, 228, 226, 224, 222, 220,
1199   218, 216, 213, 211, 209, 206, 204, 201,
1200   199, 196, 193, 191, 188, 185, 182, 179,
1201   176, 174, 171, 168, 165, 162, 159, 156,
1202   152, 149, 146, 143, 140, 137, 134, 131,
1203   128, 124, 121, 118, 115, 112, 109, 106,
1204   103, 99, 96, 93, 90, 87, 84, 81,
1205   79, 76, 73, 70, 67, 64, 62, 59,
1206   56, 54, 51, 49, 46, 44, 42, 39,
1207   37, 35, 33, 31, 29, 27, 25, 23,
1208   21, 19, 18, 16, 15, 13, 12, 10,
1209   9, 8, 7, 6, 5, 4, 3, 3,
1210   2, 1, 1, 0, 0, 0, 0, 0,
1211   0, 0, 0, 0, 0, 0, 1, 1,
1212   2, 3, 3, 4, 5, 6, 7, 8,
1213   9, 10, 12, 13, 15, 16, 18, 19,
1214   21, 23, 25, 27, 29, 31, 33, 35,
1215   37, 39, 42, 44, 46, 49, 51, 54,
1216   56, 59, 62, 64, 67, 70, 73, 76,
1217   79, 81, 84, 87, 90, 93, 96, 99,
1218   103, 106, 109, 112, 115, 118, 121, 124
1219 };
1220
1221
1222 void
1223 gst_video_test_src_zoneplate (GstVideoTestSrc * v, unsigned char *dest,
1224     int w, int h)
1225 {
1226   int i;
1227   int j;
1228   paintinfo pi = { NULL, };
1229   paintinfo *p = &pi;
1230   struct fourcc_list_struct *fourcc;
1231   struct vts_color_struct color;
1232   int t = v->n_frames;
1233   int xreset = -(w / 2) - v->xoffset;   /* starting values for x^2 and y^2, centering the ellipse */
1234   int yreset = -(h / 2) - v->yoffset;
1235
1236   int x, y;
1237   int accum_kx;
1238   int accum_kxt;
1239   int accum_ky;
1240   int accum_kyt;
1241   int accum_kxy;
1242   int kt;
1243   int kt2;
1244   int ky2;
1245   int delta_kxt = v->kxt * t;
1246   int delta_kxy;
1247   int scale_kxy = 0xffff / (w / 2);
1248   int scale_kx2 = 0xffff / w;
1249
1250   videotestsrc_setup_paintinfo (v, p, w, h);
1251   fourcc = v->fourcc;
1252   if (fourcc == NULL)
1253     return;
1254
1255   fourcc->paint_setup (p, dest);
1256
1257   color = p->colors[COLOR_BLACK];
1258   p->color = &color;
1259
1260   /* Zoneplate equation:
1261    *
1262    * phase = k0 + kx*x + ky*y + kt*t
1263    *       + kxt*x*t + kyt*y*t + kxy*x*y
1264    *       + kx2*x*x + ky2*y*y + Kt2*t*t
1265    */
1266
1267 #if 0
1268   for (j = 0, y = yreset; j < h; j++, y++) {
1269     for (i = 0, x = xreset; i < w; i++, x++) {
1270
1271       /* zero order */
1272       int phase = v->k0;
1273
1274       /* first order */
1275       phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t);
1276
1277       /* cross term */
1278       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1279       /* phase = phase + (v->kxy * x * y) / (w/2); */
1280
1281       /*second order */
1282       /*normalise x/y terms to rate of change of phase at the picture edge */
1283       phase =
1284           phase + ((v->kx2 * x * x) / w) + ((v->ky2 * y * y) / h) +
1285           ((v->kt2 * t * t) >> 1);
1286
1287       color.Y = sine_table[phase & 0xff];
1288
1289       color.R = color.Y;
1290       color.G = color.Y;
1291       color.B = color.Y;
1292       p->paint_tmpline (p, i, 1);
1293     }
1294   }
1295 #endif
1296
1297   /* optimised version, with original code shown in comments */
1298   accum_ky = 0;
1299   accum_kyt = 0;
1300   kt = v->kt * t;
1301   kt2 = v->kt2 * t * t;
1302   for (j = 0, y = yreset; j < h; j++, y++) {
1303     accum_kx = 0;
1304     accum_kxt = 0;
1305     accum_ky += v->ky;
1306     accum_kyt += v->kyt * t;
1307     delta_kxy = v->kxy * y * scale_kxy;
1308     accum_kxy = delta_kxy * xreset;
1309     ky2 = (v->ky2 * y * y) / h;
1310     for (i = 0, x = xreset; i < w; i++, x++) {
1311
1312       /* zero order */
1313       int phase = v->k0;
1314
1315       /* first order */
1316       accum_kx += v->kx;
1317       /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
1318       phase = phase + accum_kx + accum_ky + kt;
1319
1320       /* cross term */
1321       accum_kxt += delta_kxt;
1322       accum_kxy += delta_kxy;
1323       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1324       phase = phase + accum_kxt + accum_kyt;
1325
1326       /* phase = phase + (v->kxy * x * y) / (w/2); */
1327       /* phase = phase + accum_kxy / (w/2); */
1328       phase = phase + (accum_kxy >> 16);
1329
1330       /*second order */
1331       /*normalise x/y terms to rate of change of phase at the picture edge */
1332       /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
1333       phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
1334
1335       p->tmpline_u8[i] = sine_table[phase & 0xff];
1336     }
1337     videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1338         &p->foreground_color, &p->background_color, p->width);
1339     videotestsrc_convert_tmpline (p, j);
1340   }
1341 }
1342
1343 void
1344 gst_video_test_src_chromazoneplate (GstVideoTestSrc * v, unsigned char *dest,
1345     int w, int h)
1346 {
1347   int i;
1348   int j;
1349   paintinfo pi = { NULL, };
1350   paintinfo *p = &pi;
1351   struct fourcc_list_struct *fourcc;
1352   struct vts_color_struct color;
1353   int t = v->n_frames;
1354
1355   int xreset = -(w / 2) - v->xoffset;   /* starting values for x^2 and y^2, centering the ellipse */
1356   int yreset = -(h / 2) - v->yoffset;
1357
1358   int x, y;
1359   int accum_kx;
1360   int accum_kxt;
1361   int accum_ky;
1362   int accum_kyt;
1363   int accum_kxy;
1364   int kt;
1365   int kt2;
1366   int ky2;
1367   int delta_kxt = v->kxt * t;
1368   int delta_kxy;
1369   int scale_kxy = 0xffff / (w / 2);
1370   int scale_kx2 = 0xffff / w;
1371
1372   videotestsrc_setup_paintinfo (v, p, w, h);
1373   fourcc = v->fourcc;
1374   if (fourcc == NULL)
1375     return;
1376
1377   fourcc->paint_setup (p, dest);
1378
1379   color = p->colors[COLOR_BLACK];
1380   p->color = &color;
1381
1382   /* Zoneplate equation:
1383    *
1384    * phase = k0 + kx*x + ky*y + kt*t
1385    *       + kxt*x*t + kyt*y*t + kxy*x*y
1386    *       + kx2*x*x + ky2*y*y + Kt2*t*t
1387    */
1388
1389   /* optimised version, with original code shown in comments */
1390   accum_ky = 0;
1391   accum_kyt = 0;
1392   kt = v->kt * t;
1393   kt2 = v->kt2 * t * t;
1394   for (j = 0, y = yreset; j < h; j++, y++) {
1395     accum_kx = 0;
1396     accum_kxt = 0;
1397     accum_ky += v->ky;
1398     accum_kyt += v->kyt * t;
1399     delta_kxy = v->kxy * y * scale_kxy;
1400     accum_kxy = delta_kxy * xreset;
1401     ky2 = (v->ky2 * y * y) / h;
1402     for (i = 0, x = xreset; i < w; i++, x++) {
1403
1404       /* zero order */
1405       int phase = v->k0;
1406
1407       /* first order */
1408       accum_kx += v->kx;
1409       /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
1410       phase = phase + accum_kx + accum_ky + kt;
1411
1412       /* cross term */
1413       accum_kxt += delta_kxt;
1414       accum_kxy += delta_kxy;
1415       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1416       phase = phase + accum_kxt + accum_kyt;
1417
1418       /* phase = phase + (v->kxy * x * y) / (w/2); */
1419       /* phase = phase + accum_kxy / (w/2); */
1420       phase = phase + (accum_kxy >> 16);
1421
1422       /*second order */
1423       /*normalise x/y terms to rate of change of phase at the picture edge */
1424       /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
1425       phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
1426
1427       color.Y = 128;
1428       color.U = sine_table[phase & 0xff];
1429       color.V = sine_table[phase & 0xff];
1430
1431       color.R = 128;
1432       color.G = 128;
1433       color.B = color.V;
1434
1435       color.gray = color.Y << 8;
1436       p->paint_tmpline (p, i, 1);
1437     }
1438     videotestsrc_convert_tmpline (p, j);
1439   }
1440 }
1441
1442 #undef SCALE_AMPLITUDE
1443 void
1444 gst_video_test_src_circular (GstVideoTestSrc * v, unsigned char *dest,
1445     int w, int h)
1446 {
1447   int i;
1448   int j;
1449   paintinfo pi = { NULL, };
1450   paintinfo *p = &pi;
1451   struct fourcc_list_struct *fourcc;
1452   double freq[8];
1453
1454   int d;
1455
1456   videotestsrc_setup_paintinfo (v, p, w, h);
1457   fourcc = v->fourcc;
1458   if (fourcc == NULL)
1459     return;
1460
1461   fourcc->paint_setup (p, dest);
1462
1463   for (i = 1; i < 8; i++) {
1464     freq[i] = 200 * pow (2.0, -(i - 1) / 4.0);
1465   }
1466
1467   for (j = 0; j < h; j++) {
1468     for (i = 0; i < w; i++) {
1469       double dist;
1470       int seg;
1471
1472       dist =
1473           sqrt ((2 * i - w) * (2 * i - w) + (2 * j - h) * (2 * j -
1474               h)) / (2 * w);
1475       seg = floor (dist * 16);
1476       if (seg == 0 || seg >= 8) {
1477         p->tmpline_u8[i] = 0;
1478       } else {
1479         d = floor (256 * dist * freq[seg] + 0.5);
1480         p->tmpline_u8[i] = sine_table[d & 0xff];
1481       }
1482     }
1483     videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1484         &p->foreground_color, &p->background_color, p->width);
1485     videotestsrc_convert_tmpline (p, j);
1486   }
1487 }
1488
1489 void
1490 gst_video_test_src_gamut (GstVideoTestSrc * v, guchar * dest, int w, int h)
1491 {
1492   int x, y;
1493   paintinfo pi = { NULL, };
1494   paintinfo *p = &pi;
1495   struct fourcc_list_struct *fourcc;
1496   struct vts_color_struct yuv_primary;
1497   struct vts_color_struct yuv_secondary;
1498
1499   videotestsrc_setup_paintinfo (v, p, w, h);
1500   fourcc = v->fourcc;
1501   if (fourcc == NULL)
1502     return;
1503
1504   fourcc->paint_setup (p, dest);
1505
1506   for (y = 0; y < h; y++) {
1507     int region = (y * 4) / h;
1508
1509     switch (region) {
1510       case 0:                  /* black */
1511         yuv_primary = p->colors[COLOR_BLACK];
1512         yuv_secondary = p->colors[COLOR_BLACK];
1513         yuv_secondary.Y = 0;
1514         break;
1515       case 1:
1516         yuv_primary = p->colors[COLOR_WHITE];
1517         yuv_secondary = p->colors[COLOR_WHITE];
1518         yuv_secondary.Y = 255;
1519         break;
1520       case 2:
1521         yuv_primary = p->colors[COLOR_RED];
1522         yuv_secondary = p->colors[COLOR_RED];
1523         yuv_secondary.V = 255;
1524         break;
1525       case 3:
1526         yuv_primary = p->colors[COLOR_BLUE];
1527         yuv_secondary = p->colors[COLOR_BLUE];
1528         yuv_secondary.U = 255;
1529         break;
1530     }
1531
1532     for (x = 0; x < w; x += 8) {
1533       int len = MIN (8, w - x);
1534
1535       if ((x ^ y) & (1 << 4)) {
1536         p->color = &yuv_primary;
1537       } else {
1538         p->color = &yuv_secondary;
1539       }
1540       p->paint_tmpline (p, x, len);
1541     }
1542     videotestsrc_convert_tmpline (p, y);
1543   }
1544 }
1545
1546 void
1547 gst_video_test_src_ball (GstVideoTestSrc * v, unsigned char *dest, int w, int h)
1548 {
1549   int i;
1550   paintinfo pi = { NULL, };
1551   paintinfo *p = &pi;
1552   struct fourcc_list_struct *fourcc;
1553   int t = v->n_frames;
1554   double x, y;
1555   int radius = 20;
1556
1557   videotestsrc_setup_paintinfo (v, p, w, h);
1558   fourcc = v->fourcc;
1559   if (fourcc == NULL)
1560     return;
1561
1562   fourcc->paint_setup (p, dest);
1563
1564   x = radius + (0.5 + 0.5 * sin (2 * G_PI * t / 200)) * (w - 2 * radius);
1565   y = radius + (0.5 + 0.5 * sin (2 * G_PI * sqrt (2) * t / 200)) * (h -
1566       2 * radius);
1567
1568   for (i = 0; i < h; i++) {
1569     if (i < y - radius || i > y + radius) {
1570       memset (p->tmpline_u8, 0, w);
1571     } else {
1572       int r = rint (sqrt (radius * radius - (i - y) * (i - y)));
1573       int x1, x2;
1574       int j;
1575
1576       x1 = 0;
1577       x2 = MAX (0, x - r);
1578       for (j = x1; j < x2; j++) {
1579         p->tmpline_u8[j] = 0;
1580       }
1581
1582       x1 = MAX (0, x - r);
1583       x2 = MIN (w, x + r + 1);
1584       for (j = x1; j < x2; j++) {
1585         double rr = radius - sqrt ((j - x) * (j - x) + (i - y) * (i - y));
1586
1587         rr *= 0.5;
1588         p->tmpline_u8[j] = CLAMP ((int) floor (256 * rr), 0, 255);
1589       }
1590
1591       x1 = MIN (w, x + r + 1);
1592       x2 = w;
1593       for (j = x1; j < x2; j++) {
1594         p->tmpline_u8[j] = 0;
1595       }
1596     }
1597     videotestsrc_blend_line (v, p->tmpline, p->tmpline_u8,
1598         &p->foreground_color, &p->background_color, p->width);
1599     videotestsrc_convert_tmpline (p, i);
1600   }
1601 }
1602
1603 static void
1604 paint_tmpline_ARGB (paintinfo * p, int x, int w)
1605 {
1606   int offset;
1607   guint32 value;
1608
1609 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1610   value = (p->color->A << 0) | (p->color->R << 8) |
1611       (p->color->G << 16) | (p->color->B << 24);
1612 #else
1613   value = (p->color->A << 24) | (p->color->R << 16) |
1614       (p->color->G << 8) | (p->color->B << 0);
1615 #endif
1616
1617   offset = (x * 4);
1618   gst_orc_splat_u32 (p->tmpline + offset, value, w);
1619 }
1620
1621 static void
1622 paint_tmpline_AYUV (paintinfo * p, int x, int w)
1623 {
1624   int offset;
1625   guint32 value;
1626
1627 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1628   value = (p->color->A << 0) | (p->color->Y << 8) |
1629       (p->color->U << 16) | (p->color->V << 24);
1630 #else
1631   value = (p->color->A << 24) | (p->color->Y << 16) |
1632       (p->color->U << 8) | (p->color->V << 0);
1633 #endif
1634
1635   offset = (x * 4);
1636   gst_orc_splat_u32 (p->tmpline + offset, value, w);
1637 }
1638
1639
1640 static void
1641 paint_setup_I420 (paintinfo * p, unsigned char *dest)
1642 {
1643   p->yp = dest;
1644   p->ystride = GST_ROUND_UP_4 (p->width);
1645   p->up = p->yp + p->ystride * GST_ROUND_UP_2 (p->height);
1646   p->ustride = GST_ROUND_UP_8 (p->width) / 2;
1647   p->vp = p->up + p->ustride * GST_ROUND_UP_2 (p->height) / 2;
1648   p->vstride = GST_ROUND_UP_8 (p->ystride) / 2;
1649   p->endptr = p->vp + p->vstride * GST_ROUND_UP_2 (p->height) / 2;
1650 }
1651
1652 static void
1653 paint_setup_NV12 (paintinfo * p, unsigned char *dest)
1654 {
1655   p->yp = dest;
1656   p->ystride = GST_ROUND_UP_4 (p->width);
1657   p->up = p->yp + p->ystride * GST_ROUND_UP_2 (p->height);
1658   p->vp = p->up + 1;
1659   p->ustride = p->ystride;
1660   p->vstride = p->ystride;
1661   p->endptr = p->up + (p->ystride * GST_ROUND_UP_2 (p->height)) / 2;
1662 }
1663
1664 static void
1665 paint_setup_NV21 (paintinfo * p, unsigned char *dest)
1666 {
1667   p->yp = dest;
1668   p->ystride = GST_ROUND_UP_4 (p->width);
1669   p->vp = p->yp + p->ystride * GST_ROUND_UP_2 (p->height);
1670   p->up = p->vp + 1;
1671   p->ustride = p->ystride;
1672   p->vstride = p->ystride;
1673   p->endptr = p->vp + (p->ystride * GST_ROUND_UP_2 (p->height)) / 2;
1674 }
1675
1676 static void
1677 convert_hline_I420 (paintinfo * p, int y)
1678 {
1679   int i;
1680   guint8 *Y = p->yp + y * p->ystride;
1681   guint8 *U = p->up + (y / 2) * p->ustride;
1682   guint8 *V = p->vp + (y / 2) * p->vstride;
1683   guint8 *ayuv = p->tmpline;
1684
1685   for (i = 0; i < p->width; i++) {
1686     Y[i] = ayuv[4 * i + 1];
1687   }
1688   for (i = 0; i < (p->width + 1) / 2; i++) {
1689     U[i] = (ayuv[4 * (i * 2) + 2] + ayuv[4 * (i * 2 + 1) + 2] + 1) >> 1;
1690     V[i] = (ayuv[4 * (i * 2) + 3] + ayuv[4 * (i * 2 + 1) + 3] + 1) >> 1;
1691   }
1692 }
1693
1694 static void
1695 convert_hline_NV12 (paintinfo * p, int y)
1696 {
1697   int i;
1698   guint8 *Y = p->yp + y * p->ystride;
1699   guint8 *U = p->up + (y / 2) * p->ustride;
1700   guint8 *V = p->vp + (y / 2) * p->vstride;
1701   guint8 *ayuv = p->tmpline;
1702
1703   for (i = 0; i < p->width; i++) {
1704     Y[i] = ayuv[4 * i + 1];
1705   }
1706   for (i = 0; i < (p->width + 1) / 2; i++) {
1707     U[i * 2] = (ayuv[4 * (i * 2) + 2] + ayuv[4 * (i * 2 + 1) + 2] + 1) >> 1;
1708     V[i * 2] = (ayuv[4 * (i * 2) + 3] + ayuv[4 * (i * 2 + 1) + 3] + 1) >> 1;
1709   }
1710 }
1711
1712 static void
1713 convert_hline_NV21 (paintinfo * p, int y)
1714 {
1715   int i;
1716   guint8 *Y = p->yp + y * p->ystride;
1717   guint8 *U = p->up + (y / 2) * p->ustride;
1718   guint8 *V = p->vp + (y / 2) * p->vstride;
1719   guint8 *ayuv = p->tmpline;
1720
1721   for (i = 0; i < p->width; i++) {
1722     Y[i] = ayuv[4 * i + 1];
1723   }
1724   for (i = 0; i < (p->width + 1) / 2; i++) {
1725     U[i * 2] = (ayuv[4 * (i * 2) + 2] + ayuv[4 * (i * 2 + 1) + 2] + 1) >> 1;
1726     V[i * 2] = (ayuv[4 * (i * 2) + 3] + ayuv[4 * (i * 2 + 1) + 3] + 1) >> 1;
1727   }
1728 }
1729
1730
1731 static void
1732 paint_setup_YV12 (paintinfo * p, unsigned char *dest)
1733 {
1734   p->yp = dest;
1735   p->ystride = GST_ROUND_UP_4 (p->width);
1736   p->vp = p->yp + p->ystride * GST_ROUND_UP_2 (p->height);
1737   p->vstride = GST_ROUND_UP_8 (p->ystride) / 2;
1738   p->up = p->vp + p->vstride * GST_ROUND_UP_2 (p->height) / 2;
1739   p->ustride = GST_ROUND_UP_8 (p->ystride) / 2;
1740   p->endptr = p->up + p->ustride * GST_ROUND_UP_2 (p->height) / 2;
1741 }
1742
1743 static void
1744 paint_setup_v308 (paintinfo * p, unsigned char *dest)
1745 {
1746   p->yp = dest;
1747   p->up = dest + 1;
1748   p->vp = dest + 2;
1749   p->ystride = GST_ROUND_UP_4 (p->width * 3);
1750   p->ustride = GST_ROUND_UP_4 (p->width * 3);
1751   p->vstride = GST_ROUND_UP_4 (p->width * 3);
1752   p->endptr = dest + p->ystride * p->height;
1753 }
1754
1755 static void
1756 paint_setup_AYUV (paintinfo * p, unsigned char *dest)
1757 {
1758   p->ap = dest;
1759   p->yp = dest + 1;
1760   p->up = dest + 2;
1761   p->vp = dest + 3;
1762   p->ystride = p->width * 4;
1763   p->ustride = p->width * 4;
1764   p->vstride = p->width * 4;
1765   p->endptr = dest + p->ystride * p->height;
1766 }
1767
1768 #ifdef disabled
1769 static void
1770 paint_setup_v410 (paintinfo * p, unsigned char *dest)
1771 {
1772   p->yp = dest + 0;
1773   p->up = dest + 0;
1774   p->vp = dest + 0;
1775   p->ystride = p->width * 4;
1776   p->endptr = dest + p->ystride * p->height;
1777 }
1778 #endif
1779
1780 static void
1781 paint_setup_v216 (paintinfo * p, unsigned char *dest)
1782 {
1783   p->ap = dest;
1784   p->yp = dest + 2;
1785   p->up = dest + 0;
1786   p->vp = dest + 4;
1787   p->ystride = p->width * 4;
1788   p->ustride = p->width * 4;
1789   p->vstride = p->width * 4;
1790   p->endptr = dest + p->ystride * p->height;
1791 }
1792
1793 static void
1794 paint_setup_v210 (paintinfo * p, unsigned char *dest)
1795 {
1796   p->ap = dest;
1797   p->yp = dest + 0;
1798   p->up = dest + 0;
1799   p->vp = dest + 0;
1800   p->ystride = ((p->width + 47) / 48) * 128;    /* no, really. */
1801   p->endptr = dest + p->ystride * p->height;
1802 }
1803
1804 static void
1805 paint_setup_UYVP (paintinfo * p, unsigned char *dest)
1806 {
1807   p->ap = dest;
1808   p->yp = dest + 0;
1809   p->up = dest + 0;
1810   p->vp = dest + 0;
1811   p->ystride = GST_ROUND_UP_4 ((p->width * 2 * 5 + 3) / 4);
1812   GST_ERROR ("stride %d", p->ystride);
1813   p->endptr = dest + p->ystride * p->height;
1814 }
1815
1816 static void
1817 paint_setup_YUY2 (paintinfo * p, unsigned char *dest)
1818 {
1819   p->yp = dest;
1820   p->up = dest + 1;
1821   p->vp = dest + 3;
1822   p->ystride = GST_ROUND_UP_2 (p->width) * 2;
1823   p->ustride = GST_ROUND_UP_2 (p->width) * 2;
1824   p->vstride = GST_ROUND_UP_2 (p->width) * 2;
1825   p->endptr = dest + p->ystride * p->height;
1826 }
1827
1828 static void
1829 paint_setup_UYVY (paintinfo * p, unsigned char *dest)
1830 {
1831   p->yp = dest + 1;
1832   p->up = dest;
1833   p->vp = dest + 2;
1834   p->ystride = GST_ROUND_UP_2 (p->width) * 2;
1835   p->ustride = GST_ROUND_UP_2 (p->width) * 2;
1836   p->vstride = GST_ROUND_UP_2 (p->width) * 2;
1837   p->endptr = dest + p->ystride * p->height;
1838 }
1839
1840 static void
1841 paint_setup_YVYU (paintinfo * p, unsigned char *dest)
1842 {
1843   p->yp = dest;
1844   p->up = dest + 3;
1845   p->vp = dest + 1;
1846   p->ystride = GST_ROUND_UP_2 (p->width) * 2;
1847   p->ustride = GST_ROUND_UP_2 (p->width) * 2;
1848   p->vstride = GST_ROUND_UP_2 (p->width) * 2;
1849   p->endptr = dest + p->ystride * p->height;
1850 }
1851
1852 static void
1853 paint_setup_AY64 (paintinfo * p, unsigned char *dest)
1854 {
1855   p->ap = dest;
1856   p->yp = dest + 2;
1857   p->up = dest + 4;
1858   p->vp = dest + 6;
1859   p->ystride = p->width * 8;
1860   p->ustride = p->width * 8;
1861   p->vstride = p->width * 8;
1862   p->endptr = dest + p->ystride * p->height;
1863 }
1864
1865 static void
1866 convert_hline_v308 (paintinfo * p, int y)
1867 {
1868   int i;
1869   guint8 *Y = p->yp + y * p->ystride;
1870   guint8 *U = p->up + y * p->ustride;
1871   guint8 *V = p->vp + y * p->vstride;
1872   guint8 *ayuv = p->tmpline;
1873
1874   for (i = 0; i < p->width; i++) {
1875     Y[i * 3] = ayuv[4 * i + 1];
1876     U[i * 3] = ayuv[4 * i + 2];
1877     V[i * 3] = ayuv[4 * i + 3];
1878   }
1879 }
1880
1881 static void
1882 convert_hline_AYUV (paintinfo * p, int y)
1883 {
1884   int i;
1885   guint8 *Y = p->yp + y * p->ystride;
1886   guint8 *U = p->up + y * p->ustride;
1887   guint8 *V = p->vp + y * p->vstride;
1888   guint8 *A = p->ap + y * p->ystride;
1889   guint8 *ayuv = p->tmpline;
1890
1891   for (i = 0; i < p->width; i++) {
1892     A[i * 4] = ayuv[4 * i + 0];
1893     Y[i * 4] = ayuv[4 * i + 1];
1894     U[i * 4] = ayuv[4 * i + 2];
1895     V[i * 4] = ayuv[4 * i + 3];
1896   }
1897 }
1898
1899 static void
1900 convert_hline_v216 (paintinfo * p, int y)
1901 {
1902   int i;
1903   guint8 *Y = p->yp + y * p->ystride;
1904   guint8 *U = p->up + y * p->ustride;
1905   guint8 *V = p->vp + y * p->vstride;
1906   guint8 *ayuv = p->tmpline;
1907
1908   for (i = 0; i < p->width; i++) {
1909     GST_WRITE_UINT16_LE (Y + i * 4, TO_16 (ayuv[4 * i + 1]));
1910   }
1911   for (i = 0; i < (p->width + 1) / 2; i++) {
1912     GST_WRITE_UINT16_LE (U + i * 8, TO_16 (ayuv[4 * (i * 2) + 2]));
1913     GST_WRITE_UINT16_LE (V + i * 8, TO_16 (ayuv[4 * (i * 2) + 3]));
1914   }
1915 }
1916
1917 #ifdef disabled
1918 static void
1919 convert_hline_v410 (paintinfo * p, int y)
1920 {
1921   int i;
1922   guint8 *Y = p->yp + y * p->ystride;
1923   guint8 *ayuv = p->tmpline;
1924
1925   for (i = 0; i < p->width; i++) {
1926     guint32 a;
1927
1928     a = (TO_10 (ayuv[4 * i + 2]) << 22) |
1929         (TO_10 (ayuv[4 * i + 1]) << 12) | (TO_10 (ayuv[4 * i + 3]) << 2);
1930     GST_WRITE_UINT32_LE (Y + i * 4, a);
1931   }
1932 }
1933 #endif
1934
1935 static void
1936 convert_hline_v210 (paintinfo * p, int y)
1937 {
1938   int i;
1939   guint8 *Y = p->yp + y * p->ystride;
1940   guint8 *ayuv = p->tmpline;
1941
1942   for (i = 0; i < p->width + 5; i += 6) {
1943     guint32 a0, a1, a2, a3;
1944     guint16 y0, y1, y2, y3, y4, y5;
1945     guint16 u0, u1, u2;
1946     guint16 v0, v1, v2;
1947
1948     y0 = ayuv[4 * (i + 0) + 1];
1949     y1 = ayuv[4 * (i + 1) + 1];
1950     y2 = ayuv[4 * (i + 2) + 1];
1951     y3 = ayuv[4 * (i + 3) + 1];
1952     y4 = ayuv[4 * (i + 4) + 1];
1953     y5 = ayuv[4 * (i + 5) + 1];
1954
1955     u0 = (ayuv[4 * (i + 0) + 2] + ayuv[4 * (i + 1) + 2] + 1) >> 1;
1956     u1 = (ayuv[4 * (i + 2) + 2] + ayuv[4 * (i + 3) + 2] + 1) >> 1;
1957     u2 = (ayuv[4 * (i + 4) + 2] + ayuv[4 * (i + 5) + 2] + 1) >> 1;
1958
1959     v0 = (ayuv[4 * (i + 0) + 3] + ayuv[4 * (i + 1) + 3] + 1) >> 1;
1960     v1 = (ayuv[4 * (i + 2) + 3] + ayuv[4 * (i + 3) + 3] + 1) >> 1;
1961     v2 = (ayuv[4 * (i + 4) + 3] + ayuv[4 * (i + 5) + 3] + 1) >> 1;
1962
1963 #if 0
1964     a0 = TO_10 (ayuv[4 * (i + 0) + 2]) | (TO_10 (ayuv[4 * (i + 0) + 1]) << 10)
1965         | (TO_10 (ayuv[4 * (i + 0) + 3]) << 20);
1966     a1 = TO_10 (ayuv[4 * (i + 1) + 1]) | (TO_10 (ayuv[4 * (i + 2) + 2]) << 10)
1967         | (TO_10 (ayuv[4 * (i + 2) + 1]) << 20);
1968     a2 = TO_10 (ayuv[4 * (i + 2) + 3]) | (TO_10 (ayuv[4 * (i + 3) + 1]) << 10)
1969         | (TO_10 (ayuv[4 * (i + 4) + 2]) << 20);
1970     a3 = TO_10 (ayuv[4 * (i + 4) + 1]) | (TO_10 (ayuv[4 * (i + 4) + 3]) << 10)
1971         | (TO_10 (ayuv[4 * (i + 5) + 1]) << 20);
1972 #endif
1973
1974     a0 = TO_10 (u0) | (TO_10 (y0) << 10) | (TO_10 (v0) << 20);
1975     a1 = TO_10 (y1) | (TO_10 (u1) << 10) | (TO_10 (y2) << 20);
1976     a2 = TO_10 (v1) | (TO_10 (y3) << 10) | (TO_10 (u2) << 20);
1977     a3 = TO_10 (y4) | (TO_10 (v2) << 10) | (TO_10 (y5) << 20);
1978
1979     GST_WRITE_UINT32_LE (Y + (i / 6) * 16 + 0, a0);
1980     GST_WRITE_UINT32_LE (Y + (i / 6) * 16 + 4, a1);
1981     GST_WRITE_UINT32_LE (Y + (i / 6) * 16 + 8, a2);
1982     GST_WRITE_UINT32_LE (Y + (i / 6) * 16 + 12, a3);
1983   }
1984 }
1985
1986 static void
1987 convert_hline_UYVP (paintinfo * p, int y)
1988 {
1989   int i;
1990   guint8 *Y = p->yp + y * p->ystride;
1991   guint8 *ayuv = p->tmpline;
1992
1993   for (i = 0; i < p->width; i += 2) {
1994     guint16 y0, y1;
1995     guint16 u0;
1996     guint16 v0;
1997
1998     y0 = ayuv[4 * (i + 0) + 1];
1999     y1 = ayuv[4 * (i + 1) + 1];
2000     u0 = (ayuv[4 * (i + 0) + 2] + ayuv[4 * (i + 1) + 2] + 1) >> 1;
2001     v0 = (ayuv[4 * (i + 0) + 3] + ayuv[4 * (i + 1) + 3] + 1) >> 1;
2002
2003     Y[(i / 2) * 5 + 0] = u0;
2004     Y[(i / 2) * 5 + 1] = y0 >> 2;
2005     Y[(i / 2) * 5 + 2] = (y0 << 6) | (v0 >> 4);
2006     Y[(i / 2) * 5 + 3] = (v0 << 4) | (y1 >> 2);
2007     Y[(i / 2) * 5 + 4] = (y1 << 2);
2008   }
2009 }
2010
2011 static void
2012 convert_hline_YUY2 (paintinfo * p, int y)
2013 {
2014   int i;
2015   guint8 *Y = p->yp + y * p->ystride;
2016   guint8 *U = p->up + y * p->ustride;
2017   guint8 *V = p->vp + y * p->vstride;
2018   guint8 *ayuv = p->tmpline;
2019
2020   for (i = 0; i < p->width; i++) {
2021     Y[i * 2] = ayuv[4 * i + 1];
2022   }
2023   for (i = 0; i < (p->width + 1) / 2; i++) {
2024     U[4 * i] = (ayuv[4 * (i * 2) + 2] + ayuv[4 * (i * 2 + 1) + 2] + 1) >> 1;
2025     V[4 * i] = (ayuv[4 * (i * 2) + 3] + ayuv[4 * (i * 2 + 1) + 3] + 1) >> 1;
2026   }
2027 }
2028
2029 static void
2030 convert_hline_AY64 (paintinfo * p, int y)
2031 {
2032   int i;
2033   guint16 *ayuv16 = (guint16 *) (p->ap + y * p->ystride);
2034   guint8 *ayuv = p->tmpline;
2035
2036   for (i = 0; i < p->width; i++) {
2037     GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 0, TO_16 (ayuv[4 * i + 0]));
2038     GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 1, TO_16 (ayuv[4 * i + 1]));
2039     GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 2, TO_16 (ayuv[4 * i + 2]));
2040     GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 3, TO_16 (ayuv[4 * i + 3]));
2041   }
2042 }
2043
2044 #ifdef disabled
2045 static void
2046 paint_setup_IYU2 (paintinfo * p, unsigned char *dest)
2047 {
2048   /* untested */
2049   p->yp = dest + 1;
2050   p->up = dest + 0;
2051   p->vp = dest + 2;
2052   p->ystride = GST_ROUND_UP_4 (p->width * 3);
2053   p->endptr = dest + p->ystride * p->height;
2054 }
2055
2056 static void
2057 convert_hline_IYU2 (paintinfo * p, int y)
2058 {
2059   int i;
2060   guint8 *Y = p->yp + y * p->ystride;
2061   guint8 *U = p->up + y * p->ustride;
2062   guint8 *V = p->vp + y * p->vstride;
2063   guint8 *ayuv = p->tmpline;
2064
2065   for (i = 0; i < p->width; i++) {
2066     Y[i * 3] = ayuv[4 * i + 1];
2067     U[i * 3] = ayuv[4 * i + 2];
2068     V[i * 3] = ayuv[4 * i + 3];
2069   }
2070 }
2071 #endif
2072
2073 static void
2074 paint_setup_Y41B (paintinfo * p, unsigned char *dest)
2075 {
2076   p->yp = dest;
2077   p->ystride = GST_ROUND_UP_4 (p->width);
2078   p->up = p->yp + p->ystride * p->height;
2079   p->ustride = GST_ROUND_UP_16 (p->width) / 4;
2080   p->vp = p->up + p->ustride * p->height;
2081   p->vstride = GST_ROUND_UP_16 (p->width) / 4;
2082   p->endptr = p->vp + p->vstride * p->height;
2083 }
2084
2085 static void
2086 convert_hline_Y41B (paintinfo * p, int y)
2087 {
2088   int i;
2089   guint8 *Y = p->yp + y * p->ystride;
2090   guint8 *U = p->up + y * p->ustride;
2091   guint8 *V = p->vp + y * p->vstride;
2092   guint8 *ayuv = p->tmpline;
2093
2094   for (i = 0; i < p->width; i++) {
2095     Y[i] = ayuv[4 * i + 1];
2096   }
2097   for (i = 0; i < (p->width + 3) / 4; i++) {
2098     U[i] = (ayuv[4 * (i * 4) + 2] + ayuv[4 * (i * 4 + 1) + 2] +
2099         ayuv[4 * (i * 4 + 2) + 2] + ayuv[4 * (i * 4 + 3) + 2] + 2) >> 2;
2100     V[i] = (ayuv[4 * (i * 4) + 3] + ayuv[4 * (i * 4 + 1) + 3] +
2101         ayuv[4 * (i * 4 + 2) + 3] + ayuv[4 * (i * 4 + 3) + 3] + 2) >> 2;
2102   }
2103 }
2104
2105 static void
2106 paint_setup_Y42B (paintinfo * p, unsigned char *dest)
2107 {
2108   p->yp = dest;
2109   p->ystride = GST_ROUND_UP_4 (p->width);
2110   p->up = p->yp + p->ystride * p->height;
2111   p->ustride = GST_ROUND_UP_8 (p->width) / 2;
2112   p->vp = p->up + p->ustride * p->height;
2113   p->vstride = GST_ROUND_UP_8 (p->width) / 2;
2114   p->endptr = p->vp + p->vstride * p->height;
2115 }
2116
2117 static void
2118 convert_hline_Y42B (paintinfo * p, int y)
2119 {
2120   int i;
2121   guint8 *Y = p->yp + y * p->ystride;
2122   guint8 *U = p->up + y * p->ustride;
2123   guint8 *V = p->vp + y * p->vstride;
2124   guint8 *ayuv = p->tmpline;
2125
2126   for (i = 0; i < p->width; i++) {
2127     Y[i] = ayuv[4 * i + 1];
2128   }
2129   for (i = 0; i < (p->width + 1) / 2; i++) {
2130     U[i] = (ayuv[4 * (i * 2) + 2] + ayuv[4 * (i * 2 + 1) + 2] + 1) >> 1;
2131     V[i] = (ayuv[4 * (i * 2) + 3] + ayuv[4 * (i * 2 + 1) + 3] + 1) >> 1;
2132   }
2133 }
2134
2135 static void
2136 paint_setup_Y444 (paintinfo * p, unsigned char *dest)
2137 {
2138   p->yp = dest;
2139   p->ystride = GST_ROUND_UP_4 (p->width);
2140   p->ustride = GST_ROUND_UP_4 (p->width);
2141   p->vstride = GST_ROUND_UP_4 (p->width);
2142   p->up = p->yp + p->ystride * p->height;
2143   p->vp = p->up + p->ystride * p->height;
2144   p->endptr = p->vp + p->ystride * p->height;
2145 }
2146
2147 static void
2148 convert_hline_Y444 (paintinfo * p, int y)
2149 {
2150   int i;
2151   guint8 *Y = p->yp + y * p->ystride;
2152   guint8 *U = p->up + y * p->ustride;
2153   guint8 *V = p->vp + y * p->vstride;
2154   guint8 *ayuv = p->tmpline;
2155
2156   for (i = 0; i < p->width; i++) {
2157     Y[i] = ayuv[4 * i + 1];
2158     U[i] = ayuv[4 * i + 2];
2159     V[i] = ayuv[4 * i + 3];
2160   }
2161 }
2162
2163 static void
2164 paint_setup_Y800 (paintinfo * p, unsigned char *dest)
2165 {
2166   /* untested */
2167   p->yp = dest;
2168   p->ystride = GST_ROUND_UP_4 (p->width);
2169   p->endptr = dest + p->ystride * p->height;
2170 }
2171
2172 static void
2173 convert_hline_Y800 (paintinfo * p, int y)
2174 {
2175   int i;
2176   guint8 *Y = p->yp + y * p->ystride;
2177   guint8 *ayuv = p->tmpline;
2178
2179   for (i = 0; i < p->width; i++) {
2180     Y[i] = ayuv[4 * i + 1];
2181   }
2182 }
2183
2184 static void
2185 paint_setup_YVU9 (paintinfo * p, unsigned char *dest)
2186 {
2187   int h = GST_ROUND_UP_4 (p->height);
2188
2189   p->yp = dest;
2190   p->ystride = GST_ROUND_UP_4 (p->width);
2191   p->vp = p->yp + p->ystride * h;
2192   p->vstride = GST_ROUND_UP_4 (p->ystride / 4);
2193   p->up = p->vp + p->vstride * h / 4;
2194   p->ustride = GST_ROUND_UP_4 (p->ystride / 4);
2195   p->endptr = p->up + p->ustride * h / 4;
2196 }
2197
2198 static void
2199 paint_setup_YUV9 (paintinfo * p, unsigned char *dest)
2200 {
2201   /* untested */
2202   int h = GST_ROUND_UP_4 (p->height);
2203
2204   p->yp = dest;
2205   p->ystride = GST_ROUND_UP_4 (p->width);
2206   p->up = p->yp + p->ystride * h;
2207   p->ustride = GST_ROUND_UP_4 (p->ystride / 4);
2208   p->vp = p->up + p->ustride * h / 4;
2209   p->vstride = GST_ROUND_UP_4 (p->ystride / 4);
2210   p->endptr = p->vp + p->vstride * h / 4;
2211 }
2212
2213 static void
2214 convert_hline_YUV9 (paintinfo * p, int y)
2215 {
2216   int i;
2217   guint8 *Y = p->yp + y * p->ystride;
2218   guint8 *U = p->up + (y / 4) * p->ustride;
2219   guint8 *V = p->vp + (y / 4) * p->vstride;
2220   guint8 *ayuv = p->tmpline;
2221
2222   for (i = 0; i < p->width; i++) {
2223     Y[i] = ayuv[4 * i + 1];
2224   }
2225   for (i = 0; i < (p->width + 3) / 4; i++) {
2226     U[i] = (ayuv[4 * (i * 4) + 2] + ayuv[4 * (i * 4 + 1) + 2] +
2227         ayuv[4 * (i * 4 + 2) + 2] + ayuv[4 * (i * 4 + 3) + 2] + 2) >> 2;
2228     V[i] = (ayuv[4 * (i * 4) + 3] + ayuv[4 * (i * 4 + 1) + 3] +
2229         ayuv[4 * (i * 4 + 2) + 3] + ayuv[4 * (i * 4 + 3) + 3] + 2) >> 2;
2230   }
2231 }
2232
2233 static void
2234 paint_setup_ARGB8888 (paintinfo * p, unsigned char *dest)
2235 {
2236   paint_setup_xRGB8888 (p, dest);
2237 }
2238
2239 static void
2240 paint_setup_ABGR8888 (paintinfo * p, unsigned char *dest)
2241 {
2242   paint_setup_xBGR8888 (p, dest);
2243 }
2244
2245 static void
2246 paint_setup_RGBA8888 (paintinfo * p, unsigned char *dest)
2247 {
2248   paint_setup_RGBx8888 (p, dest);
2249 }
2250
2251 static void
2252 paint_setup_BGRA8888 (paintinfo * p, unsigned char *dest)
2253 {
2254   paint_setup_BGRx8888 (p, dest);
2255 }
2256
2257 static void
2258 paint_setup_xRGB8888 (paintinfo * p, unsigned char *dest)
2259 {
2260   p->yp = dest + 1;
2261   p->up = dest + 2;
2262   p->vp = dest + 3;
2263   p->ap = dest;
2264   p->ystride = p->width * 4;
2265   p->ustride = p->width * 4;
2266   p->vstride = p->width * 4;
2267   p->endptr = p->dest + p->ystride * p->height;
2268 }
2269
2270 static void
2271 paint_setup_xBGR8888 (paintinfo * p, unsigned char *dest)
2272 {
2273   p->yp = dest + 3;
2274   p->up = dest + 2;
2275   p->vp = dest + 1;
2276   p->ap = dest;
2277   p->ystride = p->width * 4;
2278   p->ustride = p->width * 4;
2279   p->vstride = p->width * 4;
2280   p->endptr = p->dest + p->ystride * p->height;
2281 }
2282
2283 static void
2284 paint_setup_RGBx8888 (paintinfo * p, unsigned char *dest)
2285 {
2286   p->yp = dest + 0;
2287   p->up = dest + 1;
2288   p->vp = dest + 2;
2289   p->ap = dest + 3;
2290   p->ystride = p->width * 4;
2291   p->ustride = p->width * 4;
2292   p->vstride = p->width * 4;
2293   p->endptr = p->dest + p->ystride * p->height;
2294 }
2295
2296 static void
2297 paint_setup_BGRx8888 (paintinfo * p, unsigned char *dest)
2298 {
2299   p->yp = dest + 2;
2300   p->up = dest + 1;
2301   p->vp = dest + 0;
2302   p->ap = dest + 3;
2303   p->ystride = p->width * 4;
2304   p->ustride = p->width * 4;
2305   p->vstride = p->width * 4;
2306   p->endptr = p->dest + p->ystride * p->height;
2307 }
2308
2309 static void
2310 paint_setup_RGB888 (paintinfo * p, unsigned char *dest)
2311 {
2312   p->yp = dest + 0;
2313   p->up = dest + 1;
2314   p->vp = dest + 2;
2315   p->ystride = GST_ROUND_UP_4 (p->width * 3);
2316   p->ustride = GST_ROUND_UP_4 (p->width * 3);
2317   p->vstride = GST_ROUND_UP_4 (p->width * 3);
2318   p->endptr = p->dest + p->ystride * p->height;
2319 }
2320
2321 static void
2322 paint_setup_BGR888 (paintinfo * p, unsigned char *dest)
2323 {
2324   p->yp = dest + 2;
2325   p->up = dest + 1;
2326   p->vp = dest + 0;
2327   p->ystride = GST_ROUND_UP_4 (p->width * 3);
2328   p->ustride = GST_ROUND_UP_4 (p->width * 3);
2329   p->vstride = GST_ROUND_UP_4 (p->width * 3);
2330   p->endptr = p->dest + p->ystride * p->height;
2331 }
2332
2333 static void
2334 paint_setup_ARGB64 (paintinfo * p, unsigned char *dest)
2335 {
2336   p->yp = dest + 2;
2337   p->up = dest + 4;
2338   p->vp = dest + 6;
2339   p->ap = dest;
2340   p->ystride = p->width * 8;
2341   p->ustride = p->width * 8;
2342   p->vstride = p->width * 8;
2343   p->endptr = p->dest + p->ystride * p->height;
2344 }
2345
2346 static void
2347 convert_hline_str4 (paintinfo * p, int y)
2348 {
2349   int i;
2350   guint8 *A = p->ap + y * p->ystride;
2351   guint8 *R = p->yp + y * p->ystride;
2352   guint8 *G = p->up + y * p->ustride;
2353   guint8 *B = p->vp + y * p->vstride;
2354   guint8 *argb = p->tmpline;
2355
2356   for (i = 0; i < p->width; i++) {
2357     A[4 * i] = 0xff;
2358     R[4 * i] = argb[4 * i + 1];
2359     G[4 * i] = argb[4 * i + 2];
2360     B[4 * i] = argb[4 * i + 3];
2361   }
2362 }
2363
2364 static void
2365 convert_hline_astr4 (paintinfo * p, int y)
2366 {
2367   int i;
2368   guint8 *A = p->ap + y * p->ystride;
2369   guint8 *R = p->yp + y * p->ystride;
2370   guint8 *G = p->up + y * p->ustride;
2371   guint8 *B = p->vp + y * p->vstride;
2372   guint8 *argb = p->tmpline;
2373
2374   for (i = 0; i < p->width; i++) {
2375     A[4 * i] = argb[4 * i + 0];
2376     R[4 * i] = argb[4 * i + 1];
2377     G[4 * i] = argb[4 * i + 2];
2378     B[4 * i] = argb[4 * i + 3];
2379   }
2380 }
2381
2382 static void
2383 convert_hline_astr8 (paintinfo * p, int y)
2384 {
2385   int i;
2386   guint16 *A = (guint16 *) (p->ap + y * p->ystride);
2387   guint16 *R = (guint16 *) (p->yp + y * p->ystride);
2388   guint16 *G = (guint16 *) (p->up + y * p->ustride);
2389   guint16 *B = (guint16 *) (p->vp + y * p->vstride);
2390   guint8 *argb = p->tmpline;
2391
2392   for (i = 0; i < p->width; i++) {
2393     A[4 * i] = TO_16 (argb[4 * i + 0]);
2394     R[4 * i] = TO_16 (argb[4 * i + 1]);
2395     G[4 * i] = TO_16 (argb[4 * i + 2]);
2396     B[4 * i] = TO_16 (argb[4 * i + 3]);
2397   }
2398 }
2399
2400 static void
2401 convert_hline_str3 (paintinfo * p, int y)
2402 {
2403   int i;
2404   guint8 *R = p->yp + y * p->ystride;
2405   guint8 *G = p->up + y * p->ustride;
2406   guint8 *B = p->vp + y * p->vstride;
2407   guint8 *argb = p->tmpline;
2408
2409   for (i = 0; i < p->width; i++) {
2410     R[3 * i] = argb[4 * i + 1];
2411     G[3 * i] = argb[4 * i + 2];
2412     B[3 * i] = argb[4 * i + 3];
2413   }
2414 }
2415
2416 static void
2417 paint_setup_RGB565 (paintinfo * p, unsigned char *dest)
2418 {
2419   p->yp = dest;
2420   p->ystride = GST_ROUND_UP_4 (p->width * 2);
2421   p->ustride = GST_ROUND_UP_4 (p->width * 2);
2422   p->vstride = GST_ROUND_UP_4 (p->width * 2);
2423   p->endptr = p->dest + p->ystride * p->height;
2424 }
2425
2426 static void
2427 convert_hline_RGB565 (paintinfo * p, int y)
2428 {
2429   int i;
2430   guint8 *R = p->yp + y * p->ystride;
2431   guint8 *argb = p->tmpline;
2432
2433   for (i = 0; i < p->width; i++) {
2434     guint16 value = ((argb[4 * i + 1] & 0xf8) << 8) |
2435         ((argb[4 * i + 2] & 0xfc) << 3) | ((argb[4 * i + 3] & 0xf8) >> 3);
2436 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2437     GST_WRITE_UINT16_LE (R + 2 * i, value);
2438 #else
2439     GST_WRITE_UINT16_BE (R + 2 * i, value);
2440 #endif
2441   }
2442 }
2443
2444 static void
2445 convert_hline_xRGB1555 (paintinfo * p, int y)
2446 {
2447   int i;
2448   guint8 *R = p->yp + y * p->ystride;
2449   guint8 *argb = p->tmpline;
2450
2451   for (i = 0; i < p->width; i++) {
2452     guint16 value = ((argb[4 * i + 1] & 0xf8) << 7) |
2453         ((argb[4 * i + 2] & 0xf8) << 2) | ((argb[4 * i + 3] & 0xf8) >> 3);
2454 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2455     GST_WRITE_UINT16_LE (R + 2 * i, value);
2456 #else
2457     GST_WRITE_UINT16_BE (R + 2 * i, value);
2458 #endif
2459   }
2460 }
2461
2462 static void
2463 paint_setup_xRGB1555 (paintinfo * p, unsigned char *dest)
2464 {
2465   p->yp = dest;
2466   p->ystride = GST_ROUND_UP_4 (p->width * 2);
2467   p->ustride = GST_ROUND_UP_4 (p->width * 2);
2468   p->vstride = GST_ROUND_UP_4 (p->width * 2);
2469   p->endptr = p->dest + p->ystride * p->height;
2470 }
2471
2472
2473 static void
2474 paint_setup_bayer_bggr (paintinfo * p, unsigned char *dest)
2475 {
2476   p->yp = dest;
2477   p->ystride = GST_ROUND_UP_4 (p->width);
2478   p->ustride = GST_ROUND_UP_4 (p->width);
2479   p->vstride = GST_ROUND_UP_4 (p->width);
2480   p->endptr = p->dest + p->ystride * p->height;
2481   p->bayer_x_invert = 0;
2482   p->bayer_y_invert = 0;
2483 }
2484
2485 static void
2486 paint_setup_bayer_rggb (paintinfo * p, unsigned char *dest)
2487 {
2488   p->yp = dest;
2489   p->ystride = GST_ROUND_UP_4 (p->width);
2490   p->ustride = GST_ROUND_UP_4 (p->width);
2491   p->vstride = GST_ROUND_UP_4 (p->width);
2492   p->endptr = p->dest + p->ystride * p->height;
2493   p->bayer_x_invert = 1;
2494   p->bayer_y_invert = 1;
2495 }
2496
2497 static void
2498 paint_setup_bayer_grbg (paintinfo * p, unsigned char *dest)
2499 {
2500   p->yp = dest;
2501   p->ystride = GST_ROUND_UP_4 (p->width);
2502   p->ustride = GST_ROUND_UP_4 (p->width);
2503   p->vstride = GST_ROUND_UP_4 (p->width);
2504   p->endptr = p->dest + p->ystride * p->height;
2505   p->bayer_x_invert = 0;
2506   p->bayer_y_invert = 1;
2507 }
2508
2509 static void
2510 paint_setup_bayer_gbrg (paintinfo * p, unsigned char *dest)
2511 {
2512   p->yp = dest;
2513   p->ystride = GST_ROUND_UP_4 (p->width);
2514   p->ustride = GST_ROUND_UP_4 (p->width);
2515   p->vstride = GST_ROUND_UP_4 (p->width);
2516   p->endptr = p->dest + p->ystride * p->height;
2517   p->bayer_x_invert = 1;
2518   p->bayer_y_invert = 0;
2519 }
2520
2521 static void
2522 convert_hline_bayer (paintinfo * p, int y)
2523 {
2524   int i;
2525   guint8 *R = p->yp + y * p->ystride;
2526   guint8 *argb = p->tmpline;
2527   int x_inv = p->bayer_x_invert;
2528   int y_inv = p->bayer_y_invert;
2529
2530   if ((y ^ y_inv) & 1) {
2531     for (i = 0; i < p->width; i++) {
2532       if ((i ^ x_inv) & 1) {
2533         R[i] = argb[4 * i + 1];
2534       } else {
2535         R[i] = argb[4 * i + 2];
2536       }
2537     }
2538   } else {
2539     for (i = 0; i < p->width; i++) {
2540       if ((i ^ x_inv) & 1) {
2541         R[i] = argb[4 * i + 2];
2542       } else {
2543         R[i] = argb[4 * i + 3];
2544       }
2545     }
2546   }
2547 }
2548
2549 static void
2550 paint_setup_GRAY8 (paintinfo * p, unsigned char *dest)
2551 {
2552   p->yp = dest;
2553   p->ystride = GST_ROUND_UP_4 (p->width);
2554   p->endptr = dest + p->ystride * p->height;
2555 }
2556
2557 static void
2558 convert_hline_GRAY8 (paintinfo * p, int y)
2559 {
2560   int i;
2561   guint8 *Y = p->yp + y * p->ystride;
2562   guint8 *ayuv = p->tmpline;
2563
2564   /* FIXME this should use gray, not YUV */
2565   for (i = 0; i < p->width; i++) {
2566     Y[i] = ayuv[4 * i + 1];
2567   }
2568 }
2569
2570 static void
2571 paint_setup_GRAY16 (paintinfo * p, unsigned char *dest)
2572 {
2573   p->yp = dest;
2574   p->ystride = GST_ROUND_UP_4 (p->width * 2);
2575   p->endptr = dest + p->ystride * p->height;
2576 }
2577
2578 static void
2579 convert_hline_GRAY16 (paintinfo * p, int y)
2580 {
2581   int i;
2582   guint8 *Y = p->yp + y * p->ystride;
2583   guint8 *ayuv = p->tmpline;
2584
2585   /* FIXME this should use gray, not YUV */
2586   for (i = 0; i < p->width; i++) {
2587 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2588     GST_WRITE_UINT16_LE (Y + i * 2, ayuv[4 * i + 1] << 8);
2589 #else
2590     GST_WRITE_UINT16_BE (Y + i * 2, ayuv[4 * i + 1] << 8);
2591 #endif
2592   }
2593 }