de7f33654e8db80a7ec4150c65e42f9721629ac1
[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 void
1183 gst_video_test_src_zoneplate (GstVideoTestSrc * v, unsigned char *dest,
1184     int w, int h)
1185 {
1186   int i;
1187   int j;
1188   paintinfo pi = { NULL, };
1189   paintinfo *p = &pi;
1190   struct fourcc_list_struct *fourcc;
1191   struct vts_color_struct color;
1192   static guint8 sine_array[256];
1193   static int sine_array_inited = FALSE;
1194   int t = v->zoneplate_t;
1195   int xreset = -(w / 2) - v->xoffset;   /* starting values for x^2 and y^2, centering the ellipse */
1196   int yreset = -(h / 2) - v->yoffset;
1197
1198   int x, y;
1199   int accum_kx;
1200   int accum_kxt;
1201   int accum_ky;
1202   int accum_kyt;
1203   int accum_kxy;
1204   int kt;
1205   int kt2;
1206   int ky2;
1207   int delta_kxt = v->kxt * t;
1208   int delta_kxy;
1209   int scale_kxy = 0xffff / (w / 2);
1210   int scale_kx2 = 0xffff / w;
1211
1212   if (!sine_array_inited) {
1213     int black = 16;
1214     int white = 235;
1215     int range = white - black;
1216     for (i = 0; i < 256; i++) {
1217       sine_array[i] =
1218           floor (range * (0.5 + 0.5 * sin (i * 2 * M_PI / 256)) + 0.5 + black);
1219     }
1220     sine_array_inited = TRUE;
1221   }
1222
1223   videotestsrc_setup_paintinfo (v, p, w, h);
1224   fourcc = v->fourcc;
1225   if (fourcc == NULL)
1226     return;
1227
1228   fourcc->paint_setup (p, dest);
1229
1230   color = p->colors[COLOR_BLACK];
1231   p->color = &color;
1232
1233   /* Zoneplate equation:
1234    *
1235    * phase = k0 + kx*x + ky*y + kt*t
1236    *       + kxt*x*t + kyt*y*t + kxy*x*y
1237    *       + kx2*x*x + ky2*y*y + Kt2*t*t
1238    */
1239
1240 #if 0
1241   for (j = 0, y = yreset; j < h; j++, y++) {
1242     for (i = 0, x = xreset; i < w; i++, x++) {
1243
1244       /* zero order */
1245       int phase = v->k0;
1246
1247       /* first order */
1248       phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t);
1249
1250       /* cross term */
1251       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1252       /* phase = phase + (v->kxy * x * y) / (w/2); */
1253
1254       /*second order */
1255       /*normalise x/y terms to rate of change of phase at the picture edge */
1256       phase =
1257           phase + ((v->kx2 * x * x) / w) + ((v->ky2 * y * y) / h) +
1258           ((v->kt2 * t * t) >> 1);
1259
1260       color.Y = sine_array[phase & 0xff];
1261
1262       color.R = color.Y;
1263       color.G = color.Y;
1264       color.B = color.Y;
1265       p->paint_hline (p, i, j, 1);
1266     }
1267   }
1268 #endif
1269
1270   /* optimised version, with original code shown in comments */
1271   accum_ky = 0;
1272   accum_kyt = 0;
1273   kt = v->kt * t;
1274   kt2 = v->kt2 * t * t;
1275   for (j = 0, y = yreset; j < h; j++, y++) {
1276     accum_kx = 0;
1277     accum_kxt = 0;
1278     accum_ky += v->ky;
1279     accum_kyt += v->kyt * t;
1280     delta_kxy = v->kxy * y * scale_kxy;
1281     accum_kxy = delta_kxy * xreset;
1282     ky2 = (v->ky2 * y * y) / h;
1283     for (i = 0, x = xreset; i < w; i++, x++) {
1284
1285       /* zero order */
1286       int phase = v->k0;
1287
1288       /* first order */
1289       accum_kx += v->kx;
1290       /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
1291       phase = phase + accum_kx + accum_ky + kt;
1292
1293       /* cross term */
1294       accum_kxt += delta_kxt;
1295       accum_kxy += delta_kxy;
1296       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1297       phase = phase + accum_kxt + accum_kyt;
1298
1299       /* phase = phase + (v->kxy * x * y) / (w/2); */
1300       /* phase = phase + accum_kxy / (w/2); */
1301       phase = phase + (accum_kxy >> 16);
1302
1303       /*second order */
1304       /*normalise x/y terms to rate of change of phase at the picture edge */
1305       /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
1306       phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
1307
1308       videotestsrc_blend_color (&color, &p->foreground_color,
1309           &p->background_color, sine_array[phase & 0xff]);
1310
1311       p->paint_hline (p, i, j, 1);
1312     }
1313   }
1314
1315   v->zoneplate_t++;
1316 }
1317
1318 void
1319 gst_video_test_src_chromazoneplate (GstVideoTestSrc * v, unsigned char *dest,
1320     int w, int h)
1321 {
1322   int i;
1323   int j;
1324   paintinfo pi = { NULL, };
1325   paintinfo *p = &pi;
1326   struct fourcc_list_struct *fourcc;
1327   struct vts_color_struct color;
1328   static guint8 sine_array[256];
1329   static int sine_array_inited = FALSE;
1330   int t = v->zoneplate_t;
1331
1332   int xreset = -(w / 2) - v->xoffset;   /* starting values for x^2 and y^2, centering the ellipse */
1333   int yreset = -(h / 2) - v->yoffset;
1334
1335   int x, y;
1336   int accum_kx;
1337   int accum_kxt;
1338   int accum_ky;
1339   int accum_kyt;
1340   int accum_kxy;
1341   int kt;
1342   int kt2;
1343   int ky2;
1344   int delta_kxt = v->kxt * t;
1345   int delta_kxy;
1346   int scale_kxy = 0xffff / (w / 2);
1347   int scale_kx2 = 0xffff / w;
1348
1349   if (!sine_array_inited) {
1350     int black = 16;
1351     int white = 235;
1352     int range = white - black;
1353     for (i = 0; i < 256; i++) {
1354       sine_array[i] =
1355           floor (range * (0.5 + 0.5 * sin (i * 2 * M_PI / 256)) + 0.5 + black);
1356     }
1357     sine_array_inited = TRUE;
1358   }
1359
1360   videotestsrc_setup_paintinfo (v, p, w, h);
1361   fourcc = v->fourcc;
1362   if (fourcc == NULL)
1363     return;
1364
1365   fourcc->paint_setup (p, dest);
1366
1367   color = p->colors[COLOR_BLACK];
1368   p->color = &color;
1369
1370   /* Zoneplate equation:
1371    *
1372    * phase = k0 + kx*x + ky*y + kt*t
1373    *       + kxt*x*t + kyt*y*t + kxy*x*y
1374    *       + kx2*x*x + ky2*y*y + Kt2*t*t
1375    */
1376
1377   /* optimised version, with original code shown in comments */
1378   accum_ky = 0;
1379   accum_kyt = 0;
1380   kt = v->kt * t;
1381   kt2 = v->kt2 * t * t;
1382   for (j = 0, y = yreset; j < h; j++, y++) {
1383     accum_kx = 0;
1384     accum_kxt = 0;
1385     accum_ky += v->ky;
1386     accum_kyt += v->kyt * t;
1387     delta_kxy = v->kxy * y * scale_kxy;
1388     accum_kxy = delta_kxy * xreset;
1389     ky2 = (v->ky2 * y * y) / h;
1390     for (i = 0, x = xreset; i < w; i++, x++) {
1391
1392       /* zero order */
1393       int phase = v->k0;
1394
1395       /* first order */
1396       accum_kx += v->kx;
1397       /* phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t); */
1398       phase = phase + accum_kx + accum_ky + kt;
1399
1400       /* cross term */
1401       accum_kxt += delta_kxt;
1402       accum_kxy += delta_kxy;
1403       /* phase = phase + (v->kxt * i * t) + (v->kyt * j * t); */
1404       phase = phase + accum_kxt + accum_kyt;
1405
1406       /* phase = phase + (v->kxy * x * y) / (w/2); */
1407       /* phase = phase + accum_kxy / (w/2); */
1408       phase = phase + (accum_kxy >> 16);
1409
1410       /*second order */
1411       /*normalise x/y terms to rate of change of phase at the picture edge */
1412       /*phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1); */
1413       phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
1414
1415       color.Y = 128;
1416       color.U = sine_array[phase & 0xff];
1417       color.V = sine_array[phase & 0xff];
1418
1419       color.R = 128;
1420       color.G = 128;
1421       color.B = color.V;
1422
1423       color.gray = color.Y << 8;
1424       p->paint_hline (p, i, j, 1);
1425     }
1426   }
1427
1428   v->zoneplate_t++;
1429 }
1430
1431 #undef SCALE_AMPLITUDE
1432 void
1433 gst_video_test_src_circular (GstVideoTestSrc * v, unsigned char *dest,
1434     int w, int h)
1435 {
1436   int i;
1437   int j;
1438   paintinfo pi = { NULL, };
1439   paintinfo *p = &pi;
1440   struct fourcc_list_struct *fourcc;
1441   struct vts_color_struct color;
1442   static guint8 sine_array[256];
1443   static int sine_array_inited = FALSE;
1444   double freq[8];
1445
1446 #ifdef SCALE_AMPLITUDE
1447   double ampl[8];
1448 #endif
1449   int d;
1450
1451   if (!sine_array_inited) {
1452     for (i = 0; i < 256; i++) {
1453       sine_array[i] =
1454           floor (255 * (0.5 + 0.5 * sin (i * 2 * M_PI / 256)) + 0.5);
1455     }
1456     sine_array_inited = TRUE;
1457   }
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_array[d & 0xff] - 128));
1503 #else
1504         videotestsrc_blend_color (&color, &p->foreground_color,
1505             &p->background_color, sine_array[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 }