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