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