]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/media/platform/vivid/vivid-tpg.c
Merge remote-tracking branch 'v4l-dvb/master'
[karo-tx-linux.git] / drivers / media / platform / vivid / vivid-tpg.c
1 /*
2  * vivid-tpg.c - Test Pattern Generator
3  *
4  * Note: gen_twopix and tpg_gen_text are based on code from vivi.c. See the
5  * vivi.c source for the copyright information of those functions.
6  *
7  * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
8  *
9  * This program is free software; you may redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; version 2 of the License.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
17  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22
23 #include "vivid-tpg.h"
24
25 /* Must remain in sync with enum tpg_pattern */
26 const char * const tpg_pattern_strings[] = {
27         "75% Colorbar",
28         "100% Colorbar",
29         "CSC Colorbar",
30         "Horizontal 100% Colorbar",
31         "100% Color Squares",
32         "100% Black",
33         "100% White",
34         "100% Red",
35         "100% Green",
36         "100% Blue",
37         "16x16 Checkers",
38         "2x2 Checkers",
39         "1x1 Checkers",
40         "2x2 Red/Green Checkers",
41         "1x1 Red/Green Checkers",
42         "Alternating Hor Lines",
43         "Alternating Vert Lines",
44         "One Pixel Wide Cross",
45         "Two Pixels Wide Cross",
46         "Ten Pixels Wide Cross",
47         "Gray Ramp",
48         "Noise",
49         NULL
50 };
51
52 /* Must remain in sync with enum tpg_aspect */
53 const char * const tpg_aspect_strings[] = {
54         "Source Width x Height",
55         "4x3",
56         "14x9",
57         "16x9",
58         "16x9 Anamorphic",
59         NULL
60 };
61
62 /*
63  * Sine table: sin[0] = 127 * sin(-180 degrees)
64  *             sin[128] = 127 * sin(0 degrees)
65  *             sin[256] = 127 * sin(180 degrees)
66  */
67 static const s8 sin[257] = {
68            0,   -4,   -7,  -11,  -13,  -18,  -20,  -22,  -26,  -29,  -33,  -35,  -37,  -41,  -43,  -48,
69          -50,  -52,  -56,  -58,  -62,  -63,  -65,  -69,  -71,  -75,  -76,  -78,  -82,  -83,  -87,  -88,
70          -90,  -93,  -94,  -97,  -99, -101, -103, -104, -107, -108, -110, -111, -112, -114, -115, -117,
71         -118, -119, -120, -121, -122, -123, -123, -124, -125, -125, -126, -126, -127, -127, -127, -127,
72         -127, -127, -127, -127, -126, -126, -125, -125, -124, -124, -123, -122, -121, -120, -119, -118,
73         -117, -116, -114, -113, -111, -110, -109, -107, -105, -103, -101, -100,  -97,  -96,  -93,  -91,
74          -90,  -87,  -85,  -82,  -80,  -76,  -75,  -73,  -69,  -67,  -63,  -62,  -60,  -56,  -54,  -50,
75          -48,  -46,  -41,  -39,  -35,  -33,  -31,  -26,  -24,  -20,  -18,  -15,  -11,   -9,   -4,   -2,
76            0,    2,    4,    9,   11,   15,   18,   20,   24,   26,   31,   33,   35,   39,   41,   46,
77           48,   50,   54,   56,   60,   62,   64,   67,   69,   73,   75,   76,   80,   82,   85,   87,
78           90,   91,   93,   96,   97,  100,  101,  103,  105,  107,  109,  110,  111,  113,  114,  116,
79          117,  118,  119,  120,  121,  122,  123,  124,  124,  125,  125,  126,  126,  127,  127,  127,
80          127,  127,  127,  127,  127,  126,  126,  125,  125,  124,  123,  123,  122,  121,  120,  119,
81          118,  117,  115,  114,  112,  111,  110,  108,  107,  104,  103,  101,   99,   97,   94,   93,
82           90,   88,   87,   83,   82,   78,   76,   75,   71,   69,   65,   64,   62,   58,   56,   52,
83           50,   48,   43,   41,   37,   35,   33,   29,   26,   22,   20,   18,   13,   11,    7,    4,
84            0,
85 };
86
87 #define cos(idx) sin[((idx) + 64) % sizeof(sin)]
88
89 /* Global font descriptor */
90 static const u8 *font8x16;
91
92 void tpg_set_font(const u8 *f)
93 {
94         font8x16 = f;
95 }
96
97 void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h)
98 {
99         memset(tpg, 0, sizeof(*tpg));
100         tpg->scaled_width = tpg->src_width = w;
101         tpg->src_height = tpg->buf_height = h;
102         tpg->crop.width = tpg->compose.width = w;
103         tpg->crop.height = tpg->compose.height = h;
104         tpg->recalc_colors = true;
105         tpg->recalc_square_border = true;
106         tpg->brightness = 128;
107         tpg->contrast = 128;
108         tpg->saturation = 128;
109         tpg->hue = 0;
110         tpg->mv_hor_mode = TPG_MOVE_NONE;
111         tpg->mv_vert_mode = TPG_MOVE_NONE;
112         tpg->field = V4L2_FIELD_NONE;
113         tpg_s_fourcc(tpg, V4L2_PIX_FMT_RGB24);
114         tpg->colorspace = V4L2_COLORSPACE_SRGB;
115         tpg->perc_fill = 100;
116 }
117
118 int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
119 {
120         unsigned pat;
121         unsigned plane;
122
123         tpg->max_line_width = max_w;
124         for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
125                 for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
126                         unsigned pixelsz = plane ? 2 : 4;
127
128                         tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
129                         if (!tpg->lines[pat][plane])
130                                 return -ENOMEM;
131                         if (plane == 0)
132                                 continue;
133                         tpg->downsampled_lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
134                         if (!tpg->downsampled_lines[pat][plane])
135                                 return -ENOMEM;
136                 }
137         }
138         for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
139                 unsigned pixelsz = plane ? 2 : 4;
140
141                 tpg->contrast_line[plane] = vzalloc(max_w * pixelsz);
142                 if (!tpg->contrast_line[plane])
143                         return -ENOMEM;
144                 tpg->black_line[plane] = vzalloc(max_w * pixelsz);
145                 if (!tpg->black_line[plane])
146                         return -ENOMEM;
147                 tpg->random_line[plane] = vzalloc(max_w * 2 * pixelsz);
148                 if (!tpg->random_line[plane])
149                         return -ENOMEM;
150         }
151         return 0;
152 }
153
154 void tpg_free(struct tpg_data *tpg)
155 {
156         unsigned pat;
157         unsigned plane;
158
159         for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
160                 for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
161                         vfree(tpg->lines[pat][plane]);
162                         tpg->lines[pat][plane] = NULL;
163                         if (plane == 0)
164                                 continue;
165                         vfree(tpg->downsampled_lines[pat][plane]);
166                         tpg->downsampled_lines[pat][plane] = NULL;
167                 }
168         for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
169                 vfree(tpg->contrast_line[plane]);
170                 vfree(tpg->black_line[plane]);
171                 vfree(tpg->random_line[plane]);
172                 tpg->contrast_line[plane] = NULL;
173                 tpg->black_line[plane] = NULL;
174                 tpg->random_line[plane] = NULL;
175         }
176 }
177
178 bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
179 {
180         tpg->fourcc = fourcc;
181         tpg->planes = 1;
182         tpg->buffers = 1;
183         tpg->recalc_colors = true;
184         tpg->interleaved = false;
185         tpg->vdownsampling[0] = 1;
186         tpg->hdownsampling[0] = 1;
187         tpg->hmask[0] = ~0;
188         tpg->hmask[1] = ~0;
189         tpg->hmask[2] = ~0;
190
191         switch (fourcc) {
192         case V4L2_PIX_FMT_SBGGR8:
193         case V4L2_PIX_FMT_SGBRG8:
194         case V4L2_PIX_FMT_SGRBG8:
195         case V4L2_PIX_FMT_SRGGB8:
196         case V4L2_PIX_FMT_SBGGR10:
197         case V4L2_PIX_FMT_SGBRG10:
198         case V4L2_PIX_FMT_SGRBG10:
199         case V4L2_PIX_FMT_SRGGB10:
200         case V4L2_PIX_FMT_SBGGR12:
201         case V4L2_PIX_FMT_SGBRG12:
202         case V4L2_PIX_FMT_SGRBG12:
203         case V4L2_PIX_FMT_SRGGB12:
204                 tpg->interleaved = true;
205                 tpg->vdownsampling[1] = 1;
206                 tpg->hdownsampling[1] = 1;
207                 tpg->planes = 2;
208                 /* fall through */
209         case V4L2_PIX_FMT_RGB332:
210         case V4L2_PIX_FMT_RGB565:
211         case V4L2_PIX_FMT_RGB565X:
212         case V4L2_PIX_FMT_RGB444:
213         case V4L2_PIX_FMT_XRGB444:
214         case V4L2_PIX_FMT_ARGB444:
215         case V4L2_PIX_FMT_RGB555:
216         case V4L2_PIX_FMT_XRGB555:
217         case V4L2_PIX_FMT_ARGB555:
218         case V4L2_PIX_FMT_RGB555X:
219         case V4L2_PIX_FMT_XRGB555X:
220         case V4L2_PIX_FMT_ARGB555X:
221         case V4L2_PIX_FMT_BGR666:
222         case V4L2_PIX_FMT_RGB24:
223         case V4L2_PIX_FMT_BGR24:
224         case V4L2_PIX_FMT_RGB32:
225         case V4L2_PIX_FMT_BGR32:
226         case V4L2_PIX_FMT_XRGB32:
227         case V4L2_PIX_FMT_XBGR32:
228         case V4L2_PIX_FMT_ARGB32:
229         case V4L2_PIX_FMT_ABGR32:
230         case V4L2_PIX_FMT_GREY:
231         case V4L2_PIX_FMT_Y16:
232         case V4L2_PIX_FMT_Y16_BE:
233                 tpg->is_yuv = false;
234                 break;
235         case V4L2_PIX_FMT_YUV444:
236         case V4L2_PIX_FMT_YUV555:
237         case V4L2_PIX_FMT_YUV565:
238         case V4L2_PIX_FMT_YUV32:
239                 tpg->is_yuv = true;
240                 break;
241         case V4L2_PIX_FMT_YUV420M:
242         case V4L2_PIX_FMT_YVU420M:
243                 tpg->buffers = 3;
244                 /* fall through */
245         case V4L2_PIX_FMT_YUV420:
246         case V4L2_PIX_FMT_YVU420:
247                 tpg->vdownsampling[1] = 2;
248                 tpg->vdownsampling[2] = 2;
249                 tpg->hdownsampling[1] = 2;
250                 tpg->hdownsampling[2] = 2;
251                 tpg->planes = 3;
252                 tpg->is_yuv = true;
253                 break;
254         case V4L2_PIX_FMT_YUV422P:
255                 tpg->vdownsampling[1] = 1;
256                 tpg->vdownsampling[2] = 1;
257                 tpg->hdownsampling[1] = 2;
258                 tpg->hdownsampling[2] = 2;
259                 tpg->planes = 3;
260                 tpg->is_yuv = true;
261                 break;
262         case V4L2_PIX_FMT_NV16M:
263         case V4L2_PIX_FMT_NV61M:
264                 tpg->buffers = 2;
265                 /* fall through */
266         case V4L2_PIX_FMT_NV16:
267         case V4L2_PIX_FMT_NV61:
268                 tpg->vdownsampling[1] = 1;
269                 tpg->hdownsampling[1] = 1;
270                 tpg->hmask[1] = ~1;
271                 tpg->planes = 2;
272                 tpg->is_yuv = true;
273                 break;
274         case V4L2_PIX_FMT_NV12M:
275         case V4L2_PIX_FMT_NV21M:
276                 tpg->buffers = 2;
277                 /* fall through */
278         case V4L2_PIX_FMT_NV12:
279         case V4L2_PIX_FMT_NV21:
280                 tpg->vdownsampling[1] = 2;
281                 tpg->hdownsampling[1] = 1;
282                 tpg->hmask[1] = ~1;
283                 tpg->planes = 2;
284                 tpg->is_yuv = true;
285                 break;
286         case V4L2_PIX_FMT_NV24:
287         case V4L2_PIX_FMT_NV42:
288                 tpg->vdownsampling[1] = 1;
289                 tpg->hdownsampling[1] = 1;
290                 tpg->planes = 2;
291                 tpg->is_yuv = true;
292                 break;
293         case V4L2_PIX_FMT_YUYV:
294         case V4L2_PIX_FMT_UYVY:
295         case V4L2_PIX_FMT_YVYU:
296         case V4L2_PIX_FMT_VYUY:
297                 tpg->hmask[0] = ~1;
298                 tpg->is_yuv = true;
299                 break;
300         default:
301                 return false;
302         }
303
304         switch (fourcc) {
305         case V4L2_PIX_FMT_GREY:
306         case V4L2_PIX_FMT_RGB332:
307                 tpg->twopixelsize[0] = 2;
308                 break;
309         case V4L2_PIX_FMT_RGB565:
310         case V4L2_PIX_FMT_RGB565X:
311         case V4L2_PIX_FMT_RGB444:
312         case V4L2_PIX_FMT_XRGB444:
313         case V4L2_PIX_FMT_ARGB444:
314         case V4L2_PIX_FMT_RGB555:
315         case V4L2_PIX_FMT_XRGB555:
316         case V4L2_PIX_FMT_ARGB555:
317         case V4L2_PIX_FMT_RGB555X:
318         case V4L2_PIX_FMT_XRGB555X:
319         case V4L2_PIX_FMT_ARGB555X:
320         case V4L2_PIX_FMT_YUYV:
321         case V4L2_PIX_FMT_UYVY:
322         case V4L2_PIX_FMT_YVYU:
323         case V4L2_PIX_FMT_VYUY:
324         case V4L2_PIX_FMT_YUV444:
325         case V4L2_PIX_FMT_YUV555:
326         case V4L2_PIX_FMT_YUV565:
327         case V4L2_PIX_FMT_Y16:
328         case V4L2_PIX_FMT_Y16_BE:
329                 tpg->twopixelsize[0] = 2 * 2;
330                 break;
331         case V4L2_PIX_FMT_RGB24:
332         case V4L2_PIX_FMT_BGR24:
333                 tpg->twopixelsize[0] = 2 * 3;
334                 break;
335         case V4L2_PIX_FMT_BGR666:
336         case V4L2_PIX_FMT_RGB32:
337         case V4L2_PIX_FMT_BGR32:
338         case V4L2_PIX_FMT_XRGB32:
339         case V4L2_PIX_FMT_XBGR32:
340         case V4L2_PIX_FMT_ARGB32:
341         case V4L2_PIX_FMT_ABGR32:
342         case V4L2_PIX_FMT_YUV32:
343                 tpg->twopixelsize[0] = 2 * 4;
344                 break;
345         case V4L2_PIX_FMT_NV12:
346         case V4L2_PIX_FMT_NV21:
347         case V4L2_PIX_FMT_NV12M:
348         case V4L2_PIX_FMT_NV21M:
349         case V4L2_PIX_FMT_NV16:
350         case V4L2_PIX_FMT_NV61:
351         case V4L2_PIX_FMT_NV16M:
352         case V4L2_PIX_FMT_NV61M:
353         case V4L2_PIX_FMT_SBGGR8:
354         case V4L2_PIX_FMT_SGBRG8:
355         case V4L2_PIX_FMT_SGRBG8:
356         case V4L2_PIX_FMT_SRGGB8:
357                 tpg->twopixelsize[0] = 2;
358                 tpg->twopixelsize[1] = 2;
359                 break;
360         case V4L2_PIX_FMT_SRGGB10:
361         case V4L2_PIX_FMT_SGRBG10:
362         case V4L2_PIX_FMT_SGBRG10:
363         case V4L2_PIX_FMT_SBGGR10:
364         case V4L2_PIX_FMT_SRGGB12:
365         case V4L2_PIX_FMT_SGRBG12:
366         case V4L2_PIX_FMT_SGBRG12:
367         case V4L2_PIX_FMT_SBGGR12:
368                 tpg->twopixelsize[0] = 4;
369                 tpg->twopixelsize[1] = 4;
370                 break;
371         case V4L2_PIX_FMT_YUV422P:
372         case V4L2_PIX_FMT_YUV420:
373         case V4L2_PIX_FMT_YVU420:
374         case V4L2_PIX_FMT_YUV420M:
375         case V4L2_PIX_FMT_YVU420M:
376                 tpg->twopixelsize[0] = 2;
377                 tpg->twopixelsize[1] = 2;
378                 tpg->twopixelsize[2] = 2;
379                 break;
380         case V4L2_PIX_FMT_NV24:
381         case V4L2_PIX_FMT_NV42:
382                 tpg->twopixelsize[0] = 2;
383                 tpg->twopixelsize[1] = 4;
384                 break;
385         }
386         return true;
387 }
388
389 void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
390                 const struct v4l2_rect *compose)
391 {
392         tpg->crop = *crop;
393         tpg->compose = *compose;
394         tpg->scaled_width = (tpg->src_width * tpg->compose.width +
395                                  tpg->crop.width - 1) / tpg->crop.width;
396         tpg->scaled_width &= ~1;
397         if (tpg->scaled_width > tpg->max_line_width)
398                 tpg->scaled_width = tpg->max_line_width;
399         if (tpg->scaled_width < 2)
400                 tpg->scaled_width = 2;
401         tpg->recalc_lines = true;
402 }
403
404 void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
405                        u32 field)
406 {
407         unsigned p;
408
409         tpg->src_width = width;
410         tpg->src_height = height;
411         tpg->field = field;
412         tpg->buf_height = height;
413         if (V4L2_FIELD_HAS_T_OR_B(field))
414                 tpg->buf_height /= 2;
415         tpg->scaled_width = width;
416         tpg->crop.top = tpg->crop.left = 0;
417         tpg->crop.width = width;
418         tpg->crop.height = height;
419         tpg->compose.top = tpg->compose.left = 0;
420         tpg->compose.width = width;
421         tpg->compose.height = tpg->buf_height;
422         for (p = 0; p < tpg->planes; p++)
423                 tpg->bytesperline[p] = (width * tpg->twopixelsize[p]) /
424                                        (2 * tpg->hdownsampling[p]);
425         tpg->recalc_square_border = true;
426 }
427
428 static enum tpg_color tpg_get_textbg_color(struct tpg_data *tpg)
429 {
430         switch (tpg->pattern) {
431         case TPG_PAT_BLACK:
432                 return TPG_COLOR_100_WHITE;
433         case TPG_PAT_CSC_COLORBAR:
434                 return TPG_COLOR_CSC_BLACK;
435         default:
436                 return TPG_COLOR_100_BLACK;
437         }
438 }
439
440 static enum tpg_color tpg_get_textfg_color(struct tpg_data *tpg)
441 {
442         switch (tpg->pattern) {
443         case TPG_PAT_75_COLORBAR:
444         case TPG_PAT_CSC_COLORBAR:
445                 return TPG_COLOR_CSC_WHITE;
446         case TPG_PAT_BLACK:
447                 return TPG_COLOR_100_BLACK;
448         default:
449                 return TPG_COLOR_100_WHITE;
450         }
451 }
452
453 static inline int rec709_to_linear(int v)
454 {
455         v = clamp(v, 0, 0xff0);
456         return tpg_rec709_to_linear[v];
457 }
458
459 static inline int linear_to_rec709(int v)
460 {
461         v = clamp(v, 0, 0xff0);
462         return tpg_linear_to_rec709[v];
463 }
464
465 static void rgb2ycbcr(const int m[3][3], int r, int g, int b,
466                         int y_offset, int *y, int *cb, int *cr)
467 {
468         *y  = ((m[0][0] * r + m[0][1] * g + m[0][2] * b) >> 16) + (y_offset << 4);
469         *cb = ((m[1][0] * r + m[1][1] * g + m[1][2] * b) >> 16) + (128 << 4);
470         *cr = ((m[2][0] * r + m[2][1] * g + m[2][2] * b) >> 16) + (128 << 4);
471 }
472
473 static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b,
474                            int *y, int *cb, int *cr)
475 {
476 #define COEFF(v, r) ((int)(0.5 + (v) * (r) * 256.0))
477
478         static const int bt601[3][3] = {
479                 { COEFF(0.299, 219),  COEFF(0.587, 219),  COEFF(0.114, 219)  },
480                 { COEFF(-0.169, 224), COEFF(-0.331, 224), COEFF(0.5, 224)    },
481                 { COEFF(0.5, 224),    COEFF(-0.419, 224), COEFF(-0.081, 224) },
482         };
483         static const int bt601_full[3][3] = {
484                 { COEFF(0.299, 255),  COEFF(0.587, 255),  COEFF(0.114, 255)  },
485                 { COEFF(-0.169, 255), COEFF(-0.331, 255), COEFF(0.5, 255)    },
486                 { COEFF(0.5, 255),    COEFF(-0.419, 255), COEFF(-0.081, 255) },
487         };
488         static const int rec709[3][3] = {
489                 { COEFF(0.2126, 219),  COEFF(0.7152, 219),  COEFF(0.0722, 219)  },
490                 { COEFF(-0.1146, 224), COEFF(-0.3854, 224), COEFF(0.5, 224)     },
491                 { COEFF(0.5, 224),     COEFF(-0.4542, 224), COEFF(-0.0458, 224) },
492         };
493         static const int rec709_full[3][3] = {
494                 { COEFF(0.2126, 255),  COEFF(0.7152, 255),  COEFF(0.0722, 255)  },
495                 { COEFF(-0.1146, 255), COEFF(-0.3854, 255), COEFF(0.5, 255)     },
496                 { COEFF(0.5, 255),     COEFF(-0.4542, 255), COEFF(-0.0458, 255) },
497         };
498         static const int smpte240m[3][3] = {
499                 { COEFF(0.212, 219),  COEFF(0.701, 219),  COEFF(0.087, 219)  },
500                 { COEFF(-0.116, 224), COEFF(-0.384, 224), COEFF(0.5, 224)    },
501                 { COEFF(0.5, 224),    COEFF(-0.445, 224), COEFF(-0.055, 224) },
502         };
503         static const int smpte240m_full[3][3] = {
504                 { COEFF(0.212, 255),  COEFF(0.701, 255),  COEFF(0.087, 255)  },
505                 { COEFF(-0.116, 255), COEFF(-0.384, 255), COEFF(0.5, 255)    },
506                 { COEFF(0.5, 255),    COEFF(-0.445, 255), COEFF(-0.055, 255) },
507         };
508         static const int bt2020[3][3] = {
509                 { COEFF(0.2627, 219),  COEFF(0.6780, 219),  COEFF(0.0593, 219)  },
510                 { COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224)     },
511                 { COEFF(0.5, 224),     COEFF(-0.4598, 224), COEFF(-0.0402, 224) },
512         };
513         static const int bt2020_full[3][3] = {
514                 { COEFF(0.2627, 255),  COEFF(0.6780, 255),  COEFF(0.0593, 255)  },
515                 { COEFF(-0.1396, 255), COEFF(-0.3604, 255), COEFF(0.5, 255)     },
516                 { COEFF(0.5, 255),     COEFF(-0.4698, 255), COEFF(-0.0402, 255) },
517         };
518         static const int bt2020c[4] = {
519                 COEFF(1.0 / 1.9404, 224), COEFF(1.0 / 1.5816, 224),
520                 COEFF(1.0 / 1.7184, 224), COEFF(1.0 / 0.9936, 224),
521         };
522         static const int bt2020c_full[4] = {
523                 COEFF(1.0 / 1.9404, 255), COEFF(1.0 / 1.5816, 255),
524                 COEFF(1.0 / 1.7184, 255), COEFF(1.0 / 0.9936, 255),
525         };
526
527         bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
528         unsigned y_offset = full ? 0 : 16;
529         int lin_y, yc;
530
531         switch (tpg->real_ycbcr_enc) {
532         case V4L2_YCBCR_ENC_601:
533         case V4L2_YCBCR_ENC_SYCC:
534                 rgb2ycbcr(full ? bt601_full : bt601, r, g, b, y_offset, y, cb, cr);
535                 break;
536         case V4L2_YCBCR_ENC_XV601:
537                 /* Ignore quantization range, there is only one possible
538                  * Y'CbCr encoding. */
539                 rgb2ycbcr(bt601, r, g, b, 16, y, cb, cr);
540                 break;
541         case V4L2_YCBCR_ENC_XV709:
542                 /* Ignore quantization range, there is only one possible
543                  * Y'CbCr encoding. */
544                 rgb2ycbcr(rec709, r, g, b, 16, y, cb, cr);
545                 break;
546         case V4L2_YCBCR_ENC_BT2020:
547                 rgb2ycbcr(full ? bt2020_full : bt2020, r, g, b, y_offset, y, cb, cr);
548                 break;
549         case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
550                 lin_y = (COEFF(0.2627, 255) * rec709_to_linear(r) +
551                          COEFF(0.6780, 255) * rec709_to_linear(g) +
552                          COEFF(0.0593, 255) * rec709_to_linear(b)) >> 16;
553                 yc = linear_to_rec709(lin_y);
554                 *y = full ? yc : (yc * 219) / 255 + (16 << 4);
555                 if (b <= yc)
556                         *cb = (((b - yc) * (full ? bt2020c_full[0] : bt2020c[0])) >> 16) + (128 << 4);
557                 else
558                         *cb = (((b - yc) * (full ? bt2020c_full[1] : bt2020c[1])) >> 16) + (128 << 4);
559                 if (r <= yc)
560                         *cr = (((r - yc) * (full ? bt2020c_full[2] : bt2020c[2])) >> 16) + (128 << 4);
561                 else
562                         *cr = (((r - yc) * (full ? bt2020c_full[3] : bt2020c[3])) >> 16) + (128 << 4);
563                 break;
564         case V4L2_YCBCR_ENC_SMPTE240M:
565                 rgb2ycbcr(full ? smpte240m_full : smpte240m, r, g, b, y_offset, y, cb, cr);
566                 break;
567         case V4L2_YCBCR_ENC_709:
568         default:
569                 rgb2ycbcr(full ? rec709_full : rec709, r, g, b, y_offset, y, cb, cr);
570                 break;
571         }
572 }
573
574 static void ycbcr2rgb(const int m[3][3], int y, int cb, int cr,
575                         int y_offset, int *r, int *g, int *b)
576 {
577         y -= y_offset << 4;
578         cb -= 128 << 4;
579         cr -= 128 << 4;
580         *r = m[0][0] * y + m[0][1] * cb + m[0][2] * cr;
581         *g = m[1][0] * y + m[1][1] * cb + m[1][2] * cr;
582         *b = m[2][0] * y + m[2][1] * cb + m[2][2] * cr;
583         *r = clamp(*r >> 12, 0, 0xff0);
584         *g = clamp(*g >> 12, 0, 0xff0);
585         *b = clamp(*b >> 12, 0, 0xff0);
586 }
587
588 static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr,
589                            int *r, int *g, int *b)
590 {
591 #undef COEFF
592 #define COEFF(v, r) ((int)(0.5 + (v) * ((255.0 * 255.0 * 16.0) / (r))))
593         static const int bt601[3][3] = {
594                 { COEFF(1, 219), COEFF(0, 224),       COEFF(1.4020, 224)  },
595                 { COEFF(1, 219), COEFF(-0.3441, 224), COEFF(-0.7141, 224) },
596                 { COEFF(1, 219), COEFF(1.7720, 224),  COEFF(0, 224)       },
597         };
598         static const int bt601_full[3][3] = {
599                 { COEFF(1, 255), COEFF(0, 255),       COEFF(1.4020, 255)  },
600                 { COEFF(1, 255), COEFF(-0.3441, 255), COEFF(-0.7141, 255) },
601                 { COEFF(1, 255), COEFF(1.7720, 255),  COEFF(0, 255)       },
602         };
603         static const int rec709[3][3] = {
604                 { COEFF(1, 219), COEFF(0, 224),       COEFF(1.5748, 224)  },
605                 { COEFF(1, 219), COEFF(-0.1873, 224), COEFF(-0.4681, 224) },
606                 { COEFF(1, 219), COEFF(1.8556, 224),  COEFF(0, 224)       },
607         };
608         static const int rec709_full[3][3] = {
609                 { COEFF(1, 255), COEFF(0, 255),       COEFF(1.5748, 255)  },
610                 { COEFF(1, 255), COEFF(-0.1873, 255), COEFF(-0.4681, 255) },
611                 { COEFF(1, 255), COEFF(1.8556, 255),  COEFF(0, 255)       },
612         };
613         static const int smpte240m[3][3] = {
614                 { COEFF(1, 219), COEFF(0, 224),       COEFF(1.5756, 224)  },
615                 { COEFF(1, 219), COEFF(-0.2253, 224), COEFF(-0.4767, 224) },
616                 { COEFF(1, 219), COEFF(1.8270, 224),  COEFF(0, 224)       },
617         };
618         static const int smpte240m_full[3][3] = {
619                 { COEFF(1, 255), COEFF(0, 255),       COEFF(1.5756, 255)  },
620                 { COEFF(1, 255), COEFF(-0.2253, 255), COEFF(-0.4767, 255) },
621                 { COEFF(1, 255), COEFF(1.8270, 255),  COEFF(0, 255)       },
622         };
623         static const int bt2020[3][3] = {
624                 { COEFF(1, 219), COEFF(0, 224),       COEFF(1.4746, 224)  },
625                 { COEFF(1, 219), COEFF(-0.1646, 224), COEFF(-0.5714, 224) },
626                 { COEFF(1, 219), COEFF(1.8814, 224),  COEFF(0, 224)       },
627         };
628         static const int bt2020_full[3][3] = {
629                 { COEFF(1, 255), COEFF(0, 255),       COEFF(1.4746, 255)  },
630                 { COEFF(1, 255), COEFF(-0.1646, 255), COEFF(-0.5714, 255) },
631                 { COEFF(1, 255), COEFF(1.8814, 255),  COEFF(0, 255)       },
632         };
633         static const int bt2020c[4] = {
634                 COEFF(1.9404, 224), COEFF(1.5816, 224),
635                 COEFF(1.7184, 224), COEFF(0.9936, 224),
636         };
637         static const int bt2020c_full[4] = {
638                 COEFF(1.9404, 255), COEFF(1.5816, 255),
639                 COEFF(1.7184, 255), COEFF(0.9936, 255),
640         };
641
642         bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
643         unsigned y_offset = full ? 0 : 16;
644         int y_fac = full ? COEFF(1.0, 255) : COEFF(1.0, 219);
645         int lin_r, lin_g, lin_b, lin_y;
646
647         switch (tpg->real_ycbcr_enc) {
648         case V4L2_YCBCR_ENC_601:
649         case V4L2_YCBCR_ENC_SYCC:
650                 ycbcr2rgb(full ? bt601_full : bt601, y, cb, cr, y_offset, r, g, b);
651                 break;
652         case V4L2_YCBCR_ENC_XV601:
653                 /* Ignore quantization range, there is only one possible
654                  * Y'CbCr encoding. */
655                 ycbcr2rgb(bt601, y, cb, cr, 16, r, g, b);
656                 break;
657         case V4L2_YCBCR_ENC_XV709:
658                 /* Ignore quantization range, there is only one possible
659                  * Y'CbCr encoding. */
660                 ycbcr2rgb(rec709, y, cb, cr, 16, r, g, b);
661                 break;
662         case V4L2_YCBCR_ENC_BT2020:
663                 ycbcr2rgb(full ? bt2020_full : bt2020, y, cb, cr, y_offset, r, g, b);
664                 break;
665         case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
666                 y -= full ? 0 : 16 << 4;
667                 cb -= 128 << 4;
668                 cr -= 128 << 4;
669
670                 if (cb <= 0)
671                         *b = y_fac * y + (full ? bt2020c_full[0] : bt2020c[0]) * cb;
672                 else
673                         *b = y_fac * y + (full ? bt2020c_full[1] : bt2020c[1]) * cb;
674                 *b = *b >> 12;
675                 if (cr <= 0)
676                         *r = y_fac * y + (full ? bt2020c_full[2] : bt2020c[2]) * cr;
677                 else
678                         *r = y_fac * y + (full ? bt2020c_full[3] : bt2020c[3]) * cr;
679                 *r = *r >> 12;
680                 lin_r = rec709_to_linear(*r);
681                 lin_b = rec709_to_linear(*b);
682                 lin_y = rec709_to_linear((y * 255) / (full ? 255 : 219));
683
684                 lin_g = COEFF(1.0 / 0.6780, 255) * lin_y -
685                         COEFF(0.2627 / 0.6780, 255) * lin_r -
686                         COEFF(0.0593 / 0.6780, 255) * lin_b;
687                 *g = linear_to_rec709(lin_g >> 12);
688                 break;
689         case V4L2_YCBCR_ENC_SMPTE240M:
690                 ycbcr2rgb(full ? smpte240m_full : smpte240m, y, cb, cr, y_offset, r, g, b);
691                 break;
692         case V4L2_YCBCR_ENC_709:
693         default:
694                 ycbcr2rgb(full ? rec709_full : rec709, y, cb, cr, y_offset, r, g, b);
695                 break;
696         }
697 }
698
699 /* precalculate color bar values to speed up rendering */
700 static void precalculate_color(struct tpg_data *tpg, int k)
701 {
702         int col = k;
703         int r = tpg_colors[col].r;
704         int g = tpg_colors[col].g;
705         int b = tpg_colors[col].b;
706
707         if (k == TPG_COLOR_TEXTBG) {
708                 col = tpg_get_textbg_color(tpg);
709
710                 r = tpg_colors[col].r;
711                 g = tpg_colors[col].g;
712                 b = tpg_colors[col].b;
713         } else if (k == TPG_COLOR_TEXTFG) {
714                 col = tpg_get_textfg_color(tpg);
715
716                 r = tpg_colors[col].r;
717                 g = tpg_colors[col].g;
718                 b = tpg_colors[col].b;
719         } else if (tpg->pattern == TPG_PAT_NOISE) {
720                 r = g = b = prandom_u32_max(256);
721         } else if (k == TPG_COLOR_RANDOM) {
722                 r = g = b = tpg->qual_offset + prandom_u32_max(196);
723         } else if (k >= TPG_COLOR_RAMP) {
724                 r = g = b = k - TPG_COLOR_RAMP;
725         }
726
727         if (tpg->pattern == TPG_PAT_CSC_COLORBAR && col <= TPG_COLOR_CSC_BLACK) {
728                 r = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].r;
729                 g = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].g;
730                 b = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].b;
731         } else {
732                 r <<= 4;
733                 g <<= 4;
734                 b <<= 4;
735         }
736         if (tpg->qual == TPG_QUAL_GRAY || tpg->fourcc == V4L2_PIX_FMT_GREY ||
737             tpg->fourcc == V4L2_PIX_FMT_Y16 ||
738             tpg->fourcc == V4L2_PIX_FMT_Y16_BE) {
739                 /* Rec. 709 Luma function */
740                 /* (0.2126, 0.7152, 0.0722) * (255 * 256) */
741                 r = g = b = (13879 * r + 46688 * g + 4713 * b) >> 16;
742         }
743
744         /*
745          * The assumption is that the RGB output is always full range,
746          * so only if the rgb_range overrides the 'real' rgb range do
747          * we need to convert the RGB values.
748          *
749          * Remember that r, g and b are still in the 0 - 0xff0 range.
750          */
751         if (tpg->real_rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
752             tpg->rgb_range == V4L2_DV_RGB_RANGE_FULL) {
753                 /*
754                  * Convert from full range (which is what r, g and b are)
755                  * to limited range (which is the 'real' RGB range), which
756                  * is then interpreted as full range.
757                  */
758                 r = (r * 219) / 255 + (16 << 4);
759                 g = (g * 219) / 255 + (16 << 4);
760                 b = (b * 219) / 255 + (16 << 4);
761         } else if (tpg->real_rgb_range != V4L2_DV_RGB_RANGE_LIMITED &&
762                    tpg->rgb_range == V4L2_DV_RGB_RANGE_LIMITED) {
763                 /*
764                  * Clamp r, g and b to the limited range and convert to full
765                  * range since that's what we deliver.
766                  */
767                 r = clamp(r, 16 << 4, 235 << 4);
768                 g = clamp(g, 16 << 4, 235 << 4);
769                 b = clamp(b, 16 << 4, 235 << 4);
770                 r = (r - (16 << 4)) * 255 / 219;
771                 g = (g - (16 << 4)) * 255 / 219;
772                 b = (b - (16 << 4)) * 255 / 219;
773         }
774
775         if (tpg->brightness != 128 || tpg->contrast != 128 ||
776             tpg->saturation != 128 || tpg->hue) {
777                 /* Implement these operations */
778                 int y, cb, cr;
779                 int tmp_cb, tmp_cr;
780
781                 /* First convert to YCbCr */
782
783                 color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
784
785                 y = (16 << 4) + ((y - (16 << 4)) * tpg->contrast) / 128;
786                 y += (tpg->brightness << 4) - (128 << 4);
787
788                 cb -= 128 << 4;
789                 cr -= 128 << 4;
790                 tmp_cb = (cb * cos(128 + tpg->hue)) / 127 + (cr * sin[128 + tpg->hue]) / 127;
791                 tmp_cr = (cr * cos(128 + tpg->hue)) / 127 - (cb * sin[128 + tpg->hue]) / 127;
792
793                 cb = (128 << 4) + (tmp_cb * tpg->contrast * tpg->saturation) / (128 * 128);
794                 cr = (128 << 4) + (tmp_cr * tpg->contrast * tpg->saturation) / (128 * 128);
795                 if (tpg->is_yuv) {
796                         tpg->colors[k][0] = clamp(y >> 4, 1, 254);
797                         tpg->colors[k][1] = clamp(cb >> 4, 1, 254);
798                         tpg->colors[k][2] = clamp(cr >> 4, 1, 254);
799                         return;
800                 }
801                 ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b);
802         }
803
804         if (tpg->is_yuv) {
805                 /* Convert to YCbCr */
806                 int y, cb, cr;
807
808                 color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
809
810                 if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
811                         y = clamp(y, 16 << 4, 235 << 4);
812                         cb = clamp(cb, 16 << 4, 240 << 4);
813                         cr = clamp(cr, 16 << 4, 240 << 4);
814                 }
815                 y = clamp(y >> 4, 1, 254);
816                 cb = clamp(cb >> 4, 1, 254);
817                 cr = clamp(cr >> 4, 1, 254);
818                 switch (tpg->fourcc) {
819                 case V4L2_PIX_FMT_YUV444:
820                         y >>= 4;
821                         cb >>= 4;
822                         cr >>= 4;
823                         break;
824                 case V4L2_PIX_FMT_YUV555:
825                         y >>= 3;
826                         cb >>= 3;
827                         cr >>= 3;
828                         break;
829                 case V4L2_PIX_FMT_YUV565:
830                         y >>= 3;
831                         cb >>= 2;
832                         cr >>= 3;
833                         break;
834                 }
835                 tpg->colors[k][0] = y;
836                 tpg->colors[k][1] = cb;
837                 tpg->colors[k][2] = cr;
838         } else {
839                 if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
840                         r = (r * 219) / 255 + (16 << 4);
841                         g = (g * 219) / 255 + (16 << 4);
842                         b = (b * 219) / 255 + (16 << 4);
843                 }
844                 switch (tpg->fourcc) {
845                 case V4L2_PIX_FMT_RGB332:
846                         r >>= 9;
847                         g >>= 9;
848                         b >>= 10;
849                         break;
850                 case V4L2_PIX_FMT_RGB565:
851                 case V4L2_PIX_FMT_RGB565X:
852                         r >>= 7;
853                         g >>= 6;
854                         b >>= 7;
855                         break;
856                 case V4L2_PIX_FMT_RGB444:
857                 case V4L2_PIX_FMT_XRGB444:
858                 case V4L2_PIX_FMT_ARGB444:
859                         r >>= 8;
860                         g >>= 8;
861                         b >>= 8;
862                         break;
863                 case V4L2_PIX_FMT_RGB555:
864                 case V4L2_PIX_FMT_XRGB555:
865                 case V4L2_PIX_FMT_ARGB555:
866                 case V4L2_PIX_FMT_RGB555X:
867                 case V4L2_PIX_FMT_XRGB555X:
868                 case V4L2_PIX_FMT_ARGB555X:
869                         r >>= 7;
870                         g >>= 7;
871                         b >>= 7;
872                         break;
873                 case V4L2_PIX_FMT_BGR666:
874                         r >>= 6;
875                         g >>= 6;
876                         b >>= 6;
877                         break;
878                 default:
879                         r >>= 4;
880                         g >>= 4;
881                         b >>= 4;
882                         break;
883                 }
884
885                 tpg->colors[k][0] = r;
886                 tpg->colors[k][1] = g;
887                 tpg->colors[k][2] = b;
888         }
889 }
890
891 static void tpg_precalculate_colors(struct tpg_data *tpg)
892 {
893         int k;
894
895         for (k = 0; k < TPG_COLOR_MAX; k++)
896                 precalculate_color(tpg, k);
897 }
898
899 /* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
900 static void gen_twopix(struct tpg_data *tpg,
901                 u8 buf[TPG_MAX_PLANES][8], int color, bool odd)
902 {
903         unsigned offset = odd * tpg->twopixelsize[0] / 2;
904         u8 alpha = tpg->alpha_component;
905         u8 r_y, g_u, b_v;
906
907         if (tpg->alpha_red_only && color != TPG_COLOR_CSC_RED &&
908                                    color != TPG_COLOR_100_RED &&
909                                    color != TPG_COLOR_75_RED)
910                 alpha = 0;
911         if (color == TPG_COLOR_RANDOM)
912                 precalculate_color(tpg, color);
913         r_y = tpg->colors[color][0]; /* R or precalculated Y */
914         g_u = tpg->colors[color][1]; /* G or precalculated U */
915         b_v = tpg->colors[color][2]; /* B or precalculated V */
916
917         switch (tpg->fourcc) {
918         case V4L2_PIX_FMT_GREY:
919                 buf[0][offset] = r_y;
920                 break;
921         case V4L2_PIX_FMT_Y16:
922                 /*
923                  * Ideally both bytes should be set to r_y, but then you won't
924                  * be able to detect endian problems. So keep it 0 except for
925                  * the corner case where r_y is 0xff so white really will be
926                  * white (0xffff).
927                  */
928                 buf[0][offset] = r_y == 0xff ? r_y : 0;
929                 buf[0][offset+1] = r_y;
930                 break;
931         case V4L2_PIX_FMT_Y16_BE:
932                 /* See comment for V4L2_PIX_FMT_Y16 above */
933                 buf[0][offset] = r_y;
934                 buf[0][offset+1] = r_y == 0xff ? r_y : 0;
935                 break;
936         case V4L2_PIX_FMT_YUV422P:
937         case V4L2_PIX_FMT_YUV420:
938         case V4L2_PIX_FMT_YUV420M:
939                 buf[0][offset] = r_y;
940                 if (odd) {
941                         buf[1][0] = (buf[1][0] + g_u) / 2;
942                         buf[2][0] = (buf[2][0] + b_v) / 2;
943                         buf[1][1] = buf[1][0];
944                         buf[2][1] = buf[2][0];
945                         break;
946                 }
947                 buf[1][0] = g_u;
948                 buf[2][0] = b_v;
949                 break;
950         case V4L2_PIX_FMT_YVU420:
951         case V4L2_PIX_FMT_YVU420M:
952                 buf[0][offset] = r_y;
953                 if (odd) {
954                         buf[1][0] = (buf[1][0] + b_v) / 2;
955                         buf[2][0] = (buf[2][0] + g_u) / 2;
956                         buf[1][1] = buf[1][0];
957                         buf[2][1] = buf[2][0];
958                         break;
959                 }
960                 buf[1][0] = b_v;
961                 buf[2][0] = g_u;
962                 break;
963
964         case V4L2_PIX_FMT_NV12:
965         case V4L2_PIX_FMT_NV12M:
966         case V4L2_PIX_FMT_NV16:
967         case V4L2_PIX_FMT_NV16M:
968                 buf[0][offset] = r_y;
969                 if (odd) {
970                         buf[1][0] = (buf[1][0] + g_u) / 2;
971                         buf[1][1] = (buf[1][1] + b_v) / 2;
972                         break;
973                 }
974                 buf[1][0] = g_u;
975                 buf[1][1] = b_v;
976                 break;
977         case V4L2_PIX_FMT_NV21:
978         case V4L2_PIX_FMT_NV21M:
979         case V4L2_PIX_FMT_NV61:
980         case V4L2_PIX_FMT_NV61M:
981                 buf[0][offset] = r_y;
982                 if (odd) {
983                         buf[1][0] = (buf[1][0] + b_v) / 2;
984                         buf[1][1] = (buf[1][1] + g_u) / 2;
985                         break;
986                 }
987                 buf[1][0] = b_v;
988                 buf[1][1] = g_u;
989                 break;
990
991         case V4L2_PIX_FMT_NV24:
992                 buf[0][offset] = r_y;
993                 buf[1][2 * offset] = g_u;
994                 buf[1][2 * offset + 1] = b_v;
995                 break;
996
997         case V4L2_PIX_FMT_NV42:
998                 buf[0][offset] = r_y;
999                 buf[1][2 * offset] = b_v;
1000                 buf[1][2 * offset + 1] = g_u;
1001                 break;
1002
1003         case V4L2_PIX_FMT_YUYV:
1004                 buf[0][offset] = r_y;
1005                 if (odd) {
1006                         buf[0][1] = (buf[0][1] + g_u) / 2;
1007                         buf[0][3] = (buf[0][3] + b_v) / 2;
1008                         break;
1009                 }
1010                 buf[0][1] = g_u;
1011                 buf[0][3] = b_v;
1012                 break;
1013         case V4L2_PIX_FMT_UYVY:
1014                 buf[0][offset + 1] = r_y;
1015                 if (odd) {
1016                         buf[0][0] = (buf[0][0] + g_u) / 2;
1017                         buf[0][2] = (buf[0][2] + b_v) / 2;
1018                         break;
1019                 }
1020                 buf[0][0] = g_u;
1021                 buf[0][2] = b_v;
1022                 break;
1023         case V4L2_PIX_FMT_YVYU:
1024                 buf[0][offset] = r_y;
1025                 if (odd) {
1026                         buf[0][1] = (buf[0][1] + b_v) / 2;
1027                         buf[0][3] = (buf[0][3] + g_u) / 2;
1028                         break;
1029                 }
1030                 buf[0][1] = b_v;
1031                 buf[0][3] = g_u;
1032                 break;
1033         case V4L2_PIX_FMT_VYUY:
1034                 buf[0][offset + 1] = r_y;
1035                 if (odd) {
1036                         buf[0][0] = (buf[0][0] + b_v) / 2;
1037                         buf[0][2] = (buf[0][2] + g_u) / 2;
1038                         break;
1039                 }
1040                 buf[0][0] = b_v;
1041                 buf[0][2] = g_u;
1042                 break;
1043         case V4L2_PIX_FMT_RGB332:
1044                 buf[0][offset] = (r_y << 5) | (g_u << 2) | b_v;
1045                 break;
1046         case V4L2_PIX_FMT_YUV565:
1047         case V4L2_PIX_FMT_RGB565:
1048                 buf[0][offset] = (g_u << 5) | b_v;
1049                 buf[0][offset + 1] = (r_y << 3) | (g_u >> 3);
1050                 break;
1051         case V4L2_PIX_FMT_RGB565X:
1052                 buf[0][offset] = (r_y << 3) | (g_u >> 3);
1053                 buf[0][offset + 1] = (g_u << 5) | b_v;
1054                 break;
1055         case V4L2_PIX_FMT_RGB444:
1056         case V4L2_PIX_FMT_XRGB444:
1057                 alpha = 0;
1058                 /* fall through */
1059         case V4L2_PIX_FMT_YUV444:
1060         case V4L2_PIX_FMT_ARGB444:
1061                 buf[0][offset] = (g_u << 4) | b_v;
1062                 buf[0][offset + 1] = (alpha & 0xf0) | r_y;
1063                 break;
1064         case V4L2_PIX_FMT_RGB555:
1065         case V4L2_PIX_FMT_XRGB555:
1066                 alpha = 0;
1067                 /* fall through */
1068         case V4L2_PIX_FMT_YUV555:
1069         case V4L2_PIX_FMT_ARGB555:
1070                 buf[0][offset] = (g_u << 5) | b_v;
1071                 buf[0][offset + 1] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
1072                 break;
1073         case V4L2_PIX_FMT_RGB555X:
1074         case V4L2_PIX_FMT_XRGB555X:
1075                 alpha = 0;
1076                 /* fall through */
1077         case V4L2_PIX_FMT_ARGB555X:
1078                 buf[0][offset] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
1079                 buf[0][offset + 1] = (g_u << 5) | b_v;
1080                 break;
1081         case V4L2_PIX_FMT_RGB24:
1082                 buf[0][offset] = r_y;
1083                 buf[0][offset + 1] = g_u;
1084                 buf[0][offset + 2] = b_v;
1085                 break;
1086         case V4L2_PIX_FMT_BGR24:
1087                 buf[0][offset] = b_v;
1088                 buf[0][offset + 1] = g_u;
1089                 buf[0][offset + 2] = r_y;
1090                 break;
1091         case V4L2_PIX_FMT_BGR666:
1092                 buf[0][offset] = (b_v << 2) | (g_u >> 4);
1093                 buf[0][offset + 1] = (g_u << 4) | (r_y >> 2);
1094                 buf[0][offset + 2] = r_y << 6;
1095                 buf[0][offset + 3] = 0;
1096                 break;
1097         case V4L2_PIX_FMT_RGB32:
1098         case V4L2_PIX_FMT_XRGB32:
1099                 alpha = 0;
1100                 /* fall through */
1101         case V4L2_PIX_FMT_YUV32:
1102         case V4L2_PIX_FMT_ARGB32:
1103                 buf[0][offset] = alpha;
1104                 buf[0][offset + 1] = r_y;
1105                 buf[0][offset + 2] = g_u;
1106                 buf[0][offset + 3] = b_v;
1107                 break;
1108         case V4L2_PIX_FMT_BGR32:
1109         case V4L2_PIX_FMT_XBGR32:
1110                 alpha = 0;
1111                 /* fall through */
1112         case V4L2_PIX_FMT_ABGR32:
1113                 buf[0][offset] = b_v;
1114                 buf[0][offset + 1] = g_u;
1115                 buf[0][offset + 2] = r_y;
1116                 buf[0][offset + 3] = alpha;
1117                 break;
1118         case V4L2_PIX_FMT_SBGGR8:
1119                 buf[0][offset] = odd ? g_u : b_v;
1120                 buf[1][offset] = odd ? r_y : g_u;
1121                 break;
1122         case V4L2_PIX_FMT_SGBRG8:
1123                 buf[0][offset] = odd ? b_v : g_u;
1124                 buf[1][offset] = odd ? g_u : r_y;
1125                 break;
1126         case V4L2_PIX_FMT_SGRBG8:
1127                 buf[0][offset] = odd ? r_y : g_u;
1128                 buf[1][offset] = odd ? g_u : b_v;
1129                 break;
1130         case V4L2_PIX_FMT_SRGGB8:
1131                 buf[0][offset] = odd ? g_u : r_y;
1132                 buf[1][offset] = odd ? b_v : g_u;
1133                 break;
1134         case V4L2_PIX_FMT_SBGGR10:
1135                 buf[0][offset] = odd ? g_u << 2 : b_v << 2;
1136                 buf[0][offset + 1] = odd ? g_u >> 6 : b_v >> 6;
1137                 buf[1][offset] = odd ? r_y << 2 : g_u << 2;
1138                 buf[1][offset + 1] = odd ? r_y >> 6 : g_u >> 6;
1139                 buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1140                 buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1141                 break;
1142         case V4L2_PIX_FMT_SGBRG10:
1143                 buf[0][offset] = odd ? b_v << 2 : g_u << 2;
1144                 buf[0][offset + 1] = odd ? b_v >> 6 : g_u >> 6;
1145                 buf[1][offset] = odd ? g_u << 2 : r_y << 2;
1146                 buf[1][offset + 1] = odd ? g_u >> 6 : r_y >> 6;
1147                 buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1148                 buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1149                 break;
1150         case V4L2_PIX_FMT_SGRBG10:
1151                 buf[0][offset] = odd ? r_y << 2 : g_u << 2;
1152                 buf[0][offset + 1] = odd ? r_y >> 6 : g_u >> 6;
1153                 buf[1][offset] = odd ? g_u << 2 : b_v << 2;
1154                 buf[1][offset + 1] = odd ? g_u >> 6 : b_v >> 6;
1155                 buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1156                 buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1157                 break;
1158         case V4L2_PIX_FMT_SRGGB10:
1159                 buf[0][offset] = odd ? g_u << 2 : r_y << 2;
1160                 buf[0][offset + 1] = odd ? g_u >> 6 : r_y >> 6;
1161                 buf[1][offset] = odd ? b_v << 2 : g_u << 2;
1162                 buf[1][offset + 1] = odd ? b_v >> 6 : g_u >> 6;
1163                 buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1164                 buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1165                 break;
1166         case V4L2_PIX_FMT_SBGGR12:
1167                 buf[0][offset] = odd ? g_u << 4 : b_v << 4;
1168                 buf[0][offset + 1] = odd ? g_u >> 4 : b_v >> 4;
1169                 buf[1][offset] = odd ? r_y << 4 : g_u << 4;
1170                 buf[1][offset + 1] = odd ? r_y >> 4 : g_u >> 4;
1171                 buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1172                 buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1173                 break;
1174         case V4L2_PIX_FMT_SGBRG12:
1175                 buf[0][offset] = odd ? b_v << 4 : g_u << 4;
1176                 buf[0][offset + 1] = odd ? b_v >> 4 : g_u >> 4;
1177                 buf[1][offset] = odd ? g_u << 4 : r_y << 4;
1178                 buf[1][offset + 1] = odd ? g_u >> 4 : r_y >> 4;
1179                 buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1180                 buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1181                 break;
1182         case V4L2_PIX_FMT_SGRBG12:
1183                 buf[0][offset] = odd ? r_y << 4 : g_u << 4;
1184                 buf[0][offset + 1] = odd ? r_y >> 4 : g_u >> 4;
1185                 buf[1][offset] = odd ? g_u << 4 : b_v << 4;
1186                 buf[1][offset + 1] = odd ? g_u >> 4 : b_v >> 4;
1187                 buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1188                 buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1189                 break;
1190         case V4L2_PIX_FMT_SRGGB12:
1191                 buf[0][offset] = odd ? g_u << 4 : r_y << 4;
1192                 buf[0][offset + 1] = odd ? g_u >> 4 : r_y >> 4;
1193                 buf[1][offset] = odd ? b_v << 4 : g_u << 4;
1194                 buf[1][offset + 1] = odd ? b_v >> 4 : g_u >> 4;
1195                 buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1196                 buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1197                 break;
1198         }
1199 }
1200
1201 unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line)
1202 {
1203         switch (tpg->fourcc) {
1204         case V4L2_PIX_FMT_SBGGR8:
1205         case V4L2_PIX_FMT_SGBRG8:
1206         case V4L2_PIX_FMT_SGRBG8:
1207         case V4L2_PIX_FMT_SRGGB8:
1208         case V4L2_PIX_FMT_SBGGR10:
1209         case V4L2_PIX_FMT_SGBRG10:
1210         case V4L2_PIX_FMT_SGRBG10:
1211         case V4L2_PIX_FMT_SRGGB10:
1212         case V4L2_PIX_FMT_SBGGR12:
1213         case V4L2_PIX_FMT_SGBRG12:
1214         case V4L2_PIX_FMT_SGRBG12:
1215         case V4L2_PIX_FMT_SRGGB12:
1216                 return buf_line & 1;
1217         default:
1218                 return 0;
1219         }
1220 }
1221
1222 /* Return how many pattern lines are used by the current pattern. */
1223 static unsigned tpg_get_pat_lines(const struct tpg_data *tpg)
1224 {
1225         switch (tpg->pattern) {
1226         case TPG_PAT_CHECKERS_16X16:
1227         case TPG_PAT_CHECKERS_2X2:
1228         case TPG_PAT_CHECKERS_1X1:
1229         case TPG_PAT_COLOR_CHECKERS_2X2:
1230         case TPG_PAT_COLOR_CHECKERS_1X1:
1231         case TPG_PAT_ALTERNATING_HLINES:
1232         case TPG_PAT_CROSS_1_PIXEL:
1233         case TPG_PAT_CROSS_2_PIXELS:
1234         case TPG_PAT_CROSS_10_PIXELS:
1235                 return 2;
1236         case TPG_PAT_100_COLORSQUARES:
1237         case TPG_PAT_100_HCOLORBAR:
1238                 return 8;
1239         default:
1240                 return 1;
1241         }
1242 }
1243
1244 /* Which pattern line should be used for the given frame line. */
1245 static unsigned tpg_get_pat_line(const struct tpg_data *tpg, unsigned line)
1246 {
1247         switch (tpg->pattern) {
1248         case TPG_PAT_CHECKERS_16X16:
1249                 return (line >> 4) & 1;
1250         case TPG_PAT_CHECKERS_1X1:
1251         case TPG_PAT_COLOR_CHECKERS_1X1:
1252         case TPG_PAT_ALTERNATING_HLINES:
1253                 return line & 1;
1254         case TPG_PAT_CHECKERS_2X2:
1255         case TPG_PAT_COLOR_CHECKERS_2X2:
1256                 return (line & 2) >> 1;
1257         case TPG_PAT_100_COLORSQUARES:
1258         case TPG_PAT_100_HCOLORBAR:
1259                 return (line * 8) / tpg->src_height;
1260         case TPG_PAT_CROSS_1_PIXEL:
1261                 return line == tpg->src_height / 2;
1262         case TPG_PAT_CROSS_2_PIXELS:
1263                 return (line + 1) / 2 == tpg->src_height / 4;
1264         case TPG_PAT_CROSS_10_PIXELS:
1265                 return (line + 10) / 20 == tpg->src_height / 40;
1266         default:
1267                 return 0;
1268         }
1269 }
1270
1271 /*
1272  * Which color should be used for the given pattern line and X coordinate.
1273  * Note: x is in the range 0 to 2 * tpg->src_width.
1274  */
1275 static enum tpg_color tpg_get_color(const struct tpg_data *tpg,
1276                                     unsigned pat_line, unsigned x)
1277 {
1278         /* Maximum number of bars are TPG_COLOR_MAX - otherwise, the input print code
1279            should be modified */
1280         static const enum tpg_color bars[3][8] = {
1281                 /* Standard ITU-R 75% color bar sequence */
1282                 { TPG_COLOR_CSC_WHITE,   TPG_COLOR_75_YELLOW,
1283                   TPG_COLOR_75_CYAN,     TPG_COLOR_75_GREEN,
1284                   TPG_COLOR_75_MAGENTA,  TPG_COLOR_75_RED,
1285                   TPG_COLOR_75_BLUE,     TPG_COLOR_100_BLACK, },
1286                 /* Standard ITU-R 100% color bar sequence */
1287                 { TPG_COLOR_100_WHITE,   TPG_COLOR_100_YELLOW,
1288                   TPG_COLOR_100_CYAN,    TPG_COLOR_100_GREEN,
1289                   TPG_COLOR_100_MAGENTA, TPG_COLOR_100_RED,
1290                   TPG_COLOR_100_BLUE,    TPG_COLOR_100_BLACK, },
1291                 /* Color bar sequence suitable to test CSC */
1292                 { TPG_COLOR_CSC_WHITE,   TPG_COLOR_CSC_YELLOW,
1293                   TPG_COLOR_CSC_CYAN,    TPG_COLOR_CSC_GREEN,
1294                   TPG_COLOR_CSC_MAGENTA, TPG_COLOR_CSC_RED,
1295                   TPG_COLOR_CSC_BLUE,    TPG_COLOR_CSC_BLACK, },
1296         };
1297
1298         switch (tpg->pattern) {
1299         case TPG_PAT_75_COLORBAR:
1300         case TPG_PAT_100_COLORBAR:
1301         case TPG_PAT_CSC_COLORBAR:
1302                 return bars[tpg->pattern][((x * 8) / tpg->src_width) % 8];
1303         case TPG_PAT_100_COLORSQUARES:
1304                 return bars[1][(pat_line + (x * 8) / tpg->src_width) % 8];
1305         case TPG_PAT_100_HCOLORBAR:
1306                 return bars[1][pat_line];
1307         case TPG_PAT_BLACK:
1308                 return TPG_COLOR_100_BLACK;
1309         case TPG_PAT_WHITE:
1310                 return TPG_COLOR_100_WHITE;
1311         case TPG_PAT_RED:
1312                 return TPG_COLOR_100_RED;
1313         case TPG_PAT_GREEN:
1314                 return TPG_COLOR_100_GREEN;
1315         case TPG_PAT_BLUE:
1316                 return TPG_COLOR_100_BLUE;
1317         case TPG_PAT_CHECKERS_16X16:
1318                 return (((x >> 4) & 1) ^ (pat_line & 1)) ?
1319                         TPG_COLOR_100_BLACK : TPG_COLOR_100_WHITE;
1320         case TPG_PAT_CHECKERS_1X1:
1321                 return ((x & 1) ^ (pat_line & 1)) ?
1322                         TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1323         case TPG_PAT_COLOR_CHECKERS_1X1:
1324                 return ((x & 1) ^ (pat_line & 1)) ?
1325                         TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
1326         case TPG_PAT_CHECKERS_2X2:
1327                 return (((x >> 1) & 1) ^ (pat_line & 1)) ?
1328                         TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1329         case TPG_PAT_COLOR_CHECKERS_2X2:
1330                 return (((x >> 1) & 1) ^ (pat_line & 1)) ?
1331                         TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
1332         case TPG_PAT_ALTERNATING_HLINES:
1333                 return pat_line ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1334         case TPG_PAT_ALTERNATING_VLINES:
1335                 return (x & 1) ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1336         case TPG_PAT_CROSS_1_PIXEL:
1337                 if (pat_line || (x % tpg->src_width) == tpg->src_width / 2)
1338                         return TPG_COLOR_100_BLACK;
1339                 return TPG_COLOR_100_WHITE;
1340         case TPG_PAT_CROSS_2_PIXELS:
1341                 if (pat_line || ((x % tpg->src_width) + 1) / 2 == tpg->src_width / 4)
1342                         return TPG_COLOR_100_BLACK;
1343                 return TPG_COLOR_100_WHITE;
1344         case TPG_PAT_CROSS_10_PIXELS:
1345                 if (pat_line || ((x % tpg->src_width) + 10) / 20 == tpg->src_width / 40)
1346                         return TPG_COLOR_100_BLACK;
1347                 return TPG_COLOR_100_WHITE;
1348         case TPG_PAT_GRAY_RAMP:
1349                 return TPG_COLOR_RAMP + ((x % tpg->src_width) * 256) / tpg->src_width;
1350         default:
1351                 return TPG_COLOR_100_RED;
1352         }
1353 }
1354
1355 /*
1356  * Given the pixel aspect ratio and video aspect ratio calculate the
1357  * coordinates of a centered square and the coordinates of the border of
1358  * the active video area. The coordinates are relative to the source
1359  * frame rectangle.
1360  */
1361 static void tpg_calculate_square_border(struct tpg_data *tpg)
1362 {
1363         unsigned w = tpg->src_width;
1364         unsigned h = tpg->src_height;
1365         unsigned sq_w, sq_h;
1366
1367         sq_w = (w * 2 / 5) & ~1;
1368         if (((w - sq_w) / 2) & 1)
1369                 sq_w += 2;
1370         sq_h = sq_w;
1371         tpg->square.width = sq_w;
1372         if (tpg->vid_aspect == TPG_VIDEO_ASPECT_16X9_ANAMORPHIC) {
1373                 unsigned ana_sq_w = (sq_w / 4) * 3;
1374
1375                 if (((w - ana_sq_w) / 2) & 1)
1376                         ana_sq_w += 2;
1377                 tpg->square.width = ana_sq_w;
1378         }
1379         tpg->square.left = (w - tpg->square.width) / 2;
1380         if (tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC)
1381                 sq_h = sq_w * 10 / 11;
1382         else if (tpg->pix_aspect == TPG_PIXEL_ASPECT_PAL)
1383                 sq_h = sq_w * 59 / 54;
1384         tpg->square.height = sq_h;
1385         tpg->square.top = (h - sq_h) / 2;
1386         tpg->border.left = 0;
1387         tpg->border.width = w;
1388         tpg->border.top = 0;
1389         tpg->border.height = h;
1390         switch (tpg->vid_aspect) {
1391         case TPG_VIDEO_ASPECT_4X3:
1392                 if (tpg->pix_aspect)
1393                         return;
1394                 if (3 * w >= 4 * h) {
1395                         tpg->border.width = ((4 * h) / 3) & ~1;
1396                         if (((w - tpg->border.width) / 2) & ~1)
1397                                 tpg->border.width -= 2;
1398                         tpg->border.left = (w - tpg->border.width) / 2;
1399                         break;
1400                 }
1401                 tpg->border.height = ((3 * w) / 4) & ~1;
1402                 tpg->border.top = (h - tpg->border.height) / 2;
1403                 break;
1404         case TPG_VIDEO_ASPECT_14X9_CENTRE:
1405                 if (tpg->pix_aspect) {
1406                         tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 420 : 506;
1407                         tpg->border.top = (h - tpg->border.height) / 2;
1408                         break;
1409                 }
1410                 if (9 * w >= 14 * h) {
1411                         tpg->border.width = ((14 * h) / 9) & ~1;
1412                         if (((w - tpg->border.width) / 2) & ~1)
1413                                 tpg->border.width -= 2;
1414                         tpg->border.left = (w - tpg->border.width) / 2;
1415                         break;
1416                 }
1417                 tpg->border.height = ((9 * w) / 14) & ~1;
1418                 tpg->border.top = (h - tpg->border.height) / 2;
1419                 break;
1420         case TPG_VIDEO_ASPECT_16X9_CENTRE:
1421                 if (tpg->pix_aspect) {
1422                         tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 368 : 442;
1423                         tpg->border.top = (h - tpg->border.height) / 2;
1424                         break;
1425                 }
1426                 if (9 * w >= 16 * h) {
1427                         tpg->border.width = ((16 * h) / 9) & ~1;
1428                         if (((w - tpg->border.width) / 2) & ~1)
1429                                 tpg->border.width -= 2;
1430                         tpg->border.left = (w - tpg->border.width) / 2;
1431                         break;
1432                 }
1433                 tpg->border.height = ((9 * w) / 16) & ~1;
1434                 tpg->border.top = (h - tpg->border.height) / 2;
1435                 break;
1436         default:
1437                 break;
1438         }
1439 }
1440
1441 static void tpg_precalculate_line(struct tpg_data *tpg)
1442 {
1443         enum tpg_color contrast;
1444         u8 pix[TPG_MAX_PLANES][8];
1445         unsigned pat;
1446         unsigned p;
1447         unsigned x;
1448
1449         switch (tpg->pattern) {
1450         case TPG_PAT_GREEN:
1451                 contrast = TPG_COLOR_100_RED;
1452                 break;
1453         case TPG_PAT_CSC_COLORBAR:
1454                 contrast = TPG_COLOR_CSC_GREEN;
1455                 break;
1456         default:
1457                 contrast = TPG_COLOR_100_GREEN;
1458                 break;
1459         }
1460
1461         for (pat = 0; pat < tpg_get_pat_lines(tpg); pat++) {
1462                 /* Coarse scaling with Bresenham */
1463                 unsigned int_part = tpg->src_width / tpg->scaled_width;
1464                 unsigned fract_part = tpg->src_width % tpg->scaled_width;
1465                 unsigned src_x = 0;
1466                 unsigned error = 0;
1467
1468                 for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1469                         unsigned real_x = src_x;
1470                         enum tpg_color color1, color2;
1471
1472                         real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
1473                         color1 = tpg_get_color(tpg, pat, real_x);
1474
1475                         src_x += int_part;
1476                         error += fract_part;
1477                         if (error >= tpg->scaled_width) {
1478                                 error -= tpg->scaled_width;
1479                                 src_x++;
1480                         }
1481
1482                         real_x = src_x;
1483                         real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
1484                         color2 = tpg_get_color(tpg, pat, real_x);
1485
1486                         src_x += int_part;
1487                         error += fract_part;
1488                         if (error >= tpg->scaled_width) {
1489                                 error -= tpg->scaled_width;
1490                                 src_x++;
1491                         }
1492
1493                         gen_twopix(tpg, pix, tpg->hflip ? color2 : color1, 0);
1494                         gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1);
1495                         for (p = 0; p < tpg->planes; p++) {
1496                                 unsigned twopixsize = tpg->twopixelsize[p];
1497                                 unsigned hdiv = tpg->hdownsampling[p];
1498                                 u8 *pos = tpg->lines[pat][p] + tpg_hdiv(tpg, p, x);
1499
1500                                 memcpy(pos, pix[p], twopixsize / hdiv);
1501                         }
1502                 }
1503         }
1504
1505         if (tpg->vdownsampling[tpg->planes - 1] > 1) {
1506                 unsigned pat_lines = tpg_get_pat_lines(tpg);
1507
1508                 for (pat = 0; pat < pat_lines; pat++) {
1509                         unsigned next_pat = (pat + 1) % pat_lines;
1510
1511                         for (p = 1; p < tpg->planes; p++) {
1512                                 unsigned w = tpg_hdiv(tpg, p, tpg->scaled_width * 2);
1513                                 u8 *pos1 = tpg->lines[pat][p];
1514                                 u8 *pos2 = tpg->lines[next_pat][p];
1515                                 u8 *dest = tpg->downsampled_lines[pat][p];
1516
1517                                 for (x = 0; x < w; x++, pos1++, pos2++, dest++)
1518                                         *dest = ((u16)*pos1 + (u16)*pos2) / 2;
1519                         }
1520                 }
1521         }
1522
1523         gen_twopix(tpg, pix, contrast, 0);
1524         gen_twopix(tpg, pix, contrast, 1);
1525         for (p = 0; p < tpg->planes; p++) {
1526                 unsigned twopixsize = tpg->twopixelsize[p];
1527                 u8 *pos = tpg->contrast_line[p];
1528
1529                 for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1530                         memcpy(pos, pix[p], twopixsize);
1531         }
1532
1533         gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 0);
1534         gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 1);
1535         for (p = 0; p < tpg->planes; p++) {
1536                 unsigned twopixsize = tpg->twopixelsize[p];
1537                 u8 *pos = tpg->black_line[p];
1538
1539                 for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1540                         memcpy(pos, pix[p], twopixsize);
1541         }
1542
1543         for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1544                 gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 0);
1545                 gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 1);
1546                 for (p = 0; p < tpg->planes; p++) {
1547                         unsigned twopixsize = tpg->twopixelsize[p];
1548                         u8 *pos = tpg->random_line[p] + x * twopixsize / 2;
1549
1550                         memcpy(pos, pix[p], twopixsize);
1551                 }
1552         }
1553
1554         gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 0);
1555         gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 1);
1556         gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 0);
1557         gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 1);
1558 }
1559
1560 /* need this to do rgb24 rendering */
1561 typedef struct { u16 __; u8 _; } __packed x24;
1562
1563 #define PRINTSTR(PIXTYPE) do {  \
1564         unsigned vdiv = tpg->vdownsampling[p]; \
1565         unsigned hdiv = tpg->hdownsampling[p]; \
1566         int line;       \
1567         PIXTYPE fg;     \
1568         PIXTYPE bg;     \
1569         memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE));   \
1570         memcpy(&bg, tpg->textbg[p], sizeof(PIXTYPE));   \
1571         \
1572         for (line = first; line < 16; line += vdiv * step) {    \
1573                 int l = tpg->vflip ? 15 - line : line; \
1574                 PIXTYPE *pos = (PIXTYPE *)(basep[p][(line / vdiv) & 1] + \
1575                                ((y * step + l) / (vdiv * div)) * tpg->bytesperline[p] + \
1576                                (x / hdiv) * sizeof(PIXTYPE));   \
1577                 unsigned s;     \
1578         \
1579                 for (s = 0; s < len; s++) {     \
1580                         u8 chr = font8x16[text[s] * 16 + line]; \
1581         \
1582                         if (hdiv == 2 && tpg->hflip) { \
1583                                 pos[3] = (chr & (0x01 << 6) ? fg : bg); \
1584                                 pos[2] = (chr & (0x01 << 4) ? fg : bg); \
1585                                 pos[1] = (chr & (0x01 << 2) ? fg : bg); \
1586                                 pos[0] = (chr & (0x01 << 0) ? fg : bg); \
1587                         } else if (hdiv == 2) { \
1588                                 pos[0] = (chr & (0x01 << 7) ? fg : bg); \
1589                                 pos[1] = (chr & (0x01 << 5) ? fg : bg); \
1590                                 pos[2] = (chr & (0x01 << 3) ? fg : bg); \
1591                                 pos[3] = (chr & (0x01 << 1) ? fg : bg); \
1592                         } else if (tpg->hflip) { \
1593                                 pos[7] = (chr & (0x01 << 7) ? fg : bg); \
1594                                 pos[6] = (chr & (0x01 << 6) ? fg : bg); \
1595                                 pos[5] = (chr & (0x01 << 5) ? fg : bg); \
1596                                 pos[4] = (chr & (0x01 << 4) ? fg : bg); \
1597                                 pos[3] = (chr & (0x01 << 3) ? fg : bg); \
1598                                 pos[2] = (chr & (0x01 << 2) ? fg : bg); \
1599                                 pos[1] = (chr & (0x01 << 1) ? fg : bg); \
1600                                 pos[0] = (chr & (0x01 << 0) ? fg : bg); \
1601                         } else { \
1602                                 pos[0] = (chr & (0x01 << 7) ? fg : bg); \
1603                                 pos[1] = (chr & (0x01 << 6) ? fg : bg); \
1604                                 pos[2] = (chr & (0x01 << 5) ? fg : bg); \
1605                                 pos[3] = (chr & (0x01 << 4) ? fg : bg); \
1606                                 pos[4] = (chr & (0x01 << 3) ? fg : bg); \
1607                                 pos[5] = (chr & (0x01 << 2) ? fg : bg); \
1608                                 pos[6] = (chr & (0x01 << 1) ? fg : bg); \
1609                                 pos[7] = (chr & (0x01 << 0) ? fg : bg); \
1610                         } \
1611         \
1612                         pos += (tpg->hflip ? -8 : 8) / hdiv;    \
1613                 }       \
1614         }       \
1615 } while (0)
1616
1617 static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1618                         unsigned p, unsigned first, unsigned div, unsigned step,
1619                         int y, int x, char *text, unsigned len)
1620 {
1621         PRINTSTR(u8);
1622 }
1623
1624 static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1625                         unsigned p, unsigned first, unsigned div, unsigned step,
1626                         int y, int x, char *text, unsigned len)
1627 {
1628         PRINTSTR(u16);
1629 }
1630
1631 static noinline void tpg_print_str_6(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1632                         unsigned p, unsigned first, unsigned div, unsigned step,
1633                         int y, int x, char *text, unsigned len)
1634 {
1635         PRINTSTR(x24);
1636 }
1637
1638 static noinline void tpg_print_str_8(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1639                         unsigned p, unsigned first, unsigned div, unsigned step,
1640                         int y, int x, char *text, unsigned len)
1641 {
1642         PRINTSTR(u32);
1643 }
1644
1645 void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1646                   int y, int x, char *text)
1647 {
1648         unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
1649         unsigned div = step;
1650         unsigned first = 0;
1651         unsigned len = strlen(text);
1652         unsigned p;
1653
1654         if (font8x16 == NULL || basep == NULL)
1655                 return;
1656
1657         /* Checks if it is possible to show string */
1658         if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width)
1659                 return;
1660
1661         if (len > (tpg->compose.width - x) / 8)
1662                 len = (tpg->compose.width - x) / 8;
1663         if (tpg->vflip)
1664                 y = tpg->compose.height - y - 16;
1665         if (tpg->hflip)
1666                 x = tpg->compose.width - x - 8;
1667         y += tpg->compose.top;
1668         x += tpg->compose.left;
1669         if (tpg->field == V4L2_FIELD_BOTTOM)
1670                 first = 1;
1671         else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT)
1672                 div = 2;
1673
1674         for (p = 0; p < tpg->planes; p++) {
1675                 /* Print text */
1676                 switch (tpg->twopixelsize[p]) {
1677                 case 2:
1678                         tpg_print_str_2(tpg, basep, p, first, div, step, y, x,
1679                                         text, len);
1680                         break;
1681                 case 4:
1682                         tpg_print_str_4(tpg, basep, p, first, div, step, y, x,
1683                                         text, len);
1684                         break;
1685                 case 6:
1686                         tpg_print_str_6(tpg, basep, p, first, div, step, y, x,
1687                                         text, len);
1688                         break;
1689                 case 8:
1690                         tpg_print_str_8(tpg, basep, p, first, div, step, y, x,
1691                                         text, len);
1692                         break;
1693                 }
1694         }
1695 }
1696
1697 void tpg_update_mv_step(struct tpg_data *tpg)
1698 {
1699         int factor = tpg->mv_hor_mode > TPG_MOVE_NONE ? -1 : 1;
1700
1701         if (tpg->hflip)
1702                 factor = -factor;
1703         switch (tpg->mv_hor_mode) {
1704         case TPG_MOVE_NEG_FAST:
1705         case TPG_MOVE_POS_FAST:
1706                 tpg->mv_hor_step = ((tpg->src_width + 319) / 320) * 4;
1707                 break;
1708         case TPG_MOVE_NEG:
1709         case TPG_MOVE_POS:
1710                 tpg->mv_hor_step = ((tpg->src_width + 639) / 640) * 4;
1711                 break;
1712         case TPG_MOVE_NEG_SLOW:
1713         case TPG_MOVE_POS_SLOW:
1714                 tpg->mv_hor_step = 2;
1715                 break;
1716         case TPG_MOVE_NONE:
1717                 tpg->mv_hor_step = 0;
1718                 break;
1719         }
1720         if (factor < 0)
1721                 tpg->mv_hor_step = tpg->src_width - tpg->mv_hor_step;
1722
1723         factor = tpg->mv_vert_mode > TPG_MOVE_NONE ? -1 : 1;
1724         switch (tpg->mv_vert_mode) {
1725         case TPG_MOVE_NEG_FAST:
1726         case TPG_MOVE_POS_FAST:
1727                 tpg->mv_vert_step = ((tpg->src_width + 319) / 320) * 4;
1728                 break;
1729         case TPG_MOVE_NEG:
1730         case TPG_MOVE_POS:
1731                 tpg->mv_vert_step = ((tpg->src_width + 639) / 640) * 4;
1732                 break;
1733         case TPG_MOVE_NEG_SLOW:
1734         case TPG_MOVE_POS_SLOW:
1735                 tpg->mv_vert_step = 1;
1736                 break;
1737         case TPG_MOVE_NONE:
1738                 tpg->mv_vert_step = 0;
1739                 break;
1740         }
1741         if (factor < 0)
1742                 tpg->mv_vert_step = tpg->src_height - tpg->mv_vert_step;
1743 }
1744
1745 /* Map the line number relative to the crop rectangle to a frame line number */
1746 static unsigned tpg_calc_frameline(const struct tpg_data *tpg, unsigned src_y,
1747                                     unsigned field)
1748 {
1749         switch (field) {
1750         case V4L2_FIELD_TOP:
1751                 return tpg->crop.top + src_y * 2;
1752         case V4L2_FIELD_BOTTOM:
1753                 return tpg->crop.top + src_y * 2 + 1;
1754         default:
1755                 return src_y + tpg->crop.top;
1756         }
1757 }
1758
1759 /*
1760  * Map the line number relative to the compose rectangle to a destination
1761  * buffer line number.
1762  */
1763 static unsigned tpg_calc_buffer_line(const struct tpg_data *tpg, unsigned y,
1764                                     unsigned field)
1765 {
1766         y += tpg->compose.top;
1767         switch (field) {
1768         case V4L2_FIELD_SEQ_TB:
1769                 if (y & 1)
1770                         return tpg->buf_height / 2 + y / 2;
1771                 return y / 2;
1772         case V4L2_FIELD_SEQ_BT:
1773                 if (y & 1)
1774                         return y / 2;
1775                 return tpg->buf_height / 2 + y / 2;
1776         default:
1777                 return y;
1778         }
1779 }
1780
1781 static void tpg_recalc(struct tpg_data *tpg)
1782 {
1783         if (tpg->recalc_colors) {
1784                 tpg->recalc_colors = false;
1785                 tpg->recalc_lines = true;
1786                 tpg->real_xfer_func = tpg->xfer_func;
1787                 tpg->real_ycbcr_enc = tpg->ycbcr_enc;
1788                 tpg->real_quantization = tpg->quantization;
1789
1790                 if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT)
1791                         tpg->real_xfer_func =
1792                                 V4L2_MAP_XFER_FUNC_DEFAULT(tpg->colorspace);
1793
1794                 if (tpg->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
1795                         tpg->real_ycbcr_enc =
1796                                 V4L2_MAP_YCBCR_ENC_DEFAULT(tpg->colorspace);
1797
1798                 if (tpg->quantization == V4L2_QUANTIZATION_DEFAULT)
1799                         tpg->real_quantization =
1800                                 V4L2_MAP_QUANTIZATION_DEFAULT(!tpg->is_yuv,
1801                                         tpg->colorspace, tpg->real_ycbcr_enc);
1802
1803                 tpg_precalculate_colors(tpg);
1804         }
1805         if (tpg->recalc_square_border) {
1806                 tpg->recalc_square_border = false;
1807                 tpg_calculate_square_border(tpg);
1808         }
1809         if (tpg->recalc_lines) {
1810                 tpg->recalc_lines = false;
1811                 tpg_precalculate_line(tpg);
1812         }
1813 }
1814
1815 void tpg_calc_text_basep(struct tpg_data *tpg,
1816                 u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf)
1817 {
1818         unsigned stride = tpg->bytesperline[p];
1819         unsigned h = tpg->buf_height;
1820
1821         tpg_recalc(tpg);
1822
1823         basep[p][0] = vbuf;
1824         basep[p][1] = vbuf;
1825         h /= tpg->vdownsampling[p];
1826         if (tpg->field == V4L2_FIELD_SEQ_TB)
1827                 basep[p][1] += h * stride / 2;
1828         else if (tpg->field == V4L2_FIELD_SEQ_BT)
1829                 basep[p][0] += h * stride / 2;
1830         if (p == 0 && tpg->interleaved)
1831                 tpg_calc_text_basep(tpg, basep, 1, vbuf);
1832 }
1833
1834 static int tpg_pattern_avg(const struct tpg_data *tpg,
1835                            unsigned pat1, unsigned pat2)
1836 {
1837         unsigned pat_lines = tpg_get_pat_lines(tpg);
1838
1839         if (pat1 == (pat2 + 1) % pat_lines)
1840                 return pat2;
1841         if (pat2 == (pat1 + 1) % pat_lines)
1842                 return pat1;
1843         return -1;
1844 }
1845
1846 void tpg_log_status(struct tpg_data *tpg)
1847 {
1848         pr_info("tpg source WxH: %ux%u (%s)\n",
1849                         tpg->src_width, tpg->src_height,
1850                         tpg->is_yuv ? "YCbCr" : "RGB");
1851         pr_info("tpg field: %u\n", tpg->field);
1852         pr_info("tpg crop: %ux%u@%dx%d\n", tpg->crop.width, tpg->crop.height,
1853                         tpg->crop.left, tpg->crop.top);
1854         pr_info("tpg compose: %ux%u@%dx%d\n", tpg->compose.width, tpg->compose.height,
1855                         tpg->compose.left, tpg->compose.top);
1856         pr_info("tpg colorspace: %d\n", tpg->colorspace);
1857         pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func);
1858         pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc);
1859         pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization);
1860         pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range);
1861 }
1862
1863 /*
1864  * This struct contains common parameters used by both the drawing of the
1865  * test pattern and the drawing of the extras (borders, square, etc.)
1866  */
1867 struct tpg_draw_params {
1868         /* common data */
1869         bool is_tv;
1870         bool is_60hz;
1871         unsigned twopixsize;
1872         unsigned img_width;
1873         unsigned stride;
1874         unsigned hmax;
1875         unsigned frame_line;
1876         unsigned frame_line_next;
1877
1878         /* test pattern */
1879         unsigned mv_hor_old;
1880         unsigned mv_hor_new;
1881         unsigned mv_vert_old;
1882         unsigned mv_vert_new;
1883
1884         /* extras */
1885         unsigned wss_width;
1886         unsigned wss_random_offset;
1887         unsigned sav_eav_f;
1888         unsigned left_pillar_width;
1889         unsigned right_pillar_start;
1890 };
1891
1892 static void tpg_fill_params_pattern(const struct tpg_data *tpg, unsigned p,
1893                                     struct tpg_draw_params *params)
1894 {
1895         params->mv_hor_old =
1896                 tpg_hscale_div(tpg, p, tpg->mv_hor_count % tpg->src_width);
1897         params->mv_hor_new =
1898                 tpg_hscale_div(tpg, p, (tpg->mv_hor_count + tpg->mv_hor_step) %
1899                                tpg->src_width);
1900         params->mv_vert_old = tpg->mv_vert_count % tpg->src_height;
1901         params->mv_vert_new =
1902                 (tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height;
1903 }
1904
1905 static void tpg_fill_params_extras(const struct tpg_data *tpg,
1906                                    unsigned p,
1907                                    struct tpg_draw_params *params)
1908 {
1909         unsigned left_pillar_width = 0;
1910         unsigned right_pillar_start = params->img_width;
1911
1912         params->wss_width = tpg->crop.left < tpg->src_width / 2 ?
1913                 tpg->src_width / 2 - tpg->crop.left : 0;
1914         if (params->wss_width > tpg->crop.width)
1915                 params->wss_width = tpg->crop.width;
1916         params->wss_width = tpg_hscale_div(tpg, p, params->wss_width);
1917         params->wss_random_offset =
1918                 params->twopixsize * prandom_u32_max(tpg->src_width / 2);
1919
1920         if (tpg->crop.left < tpg->border.left) {
1921                 left_pillar_width = tpg->border.left - tpg->crop.left;
1922                 if (left_pillar_width > tpg->crop.width)
1923                         left_pillar_width = tpg->crop.width;
1924                 left_pillar_width = tpg_hscale_div(tpg, p, left_pillar_width);
1925         }
1926         params->left_pillar_width = left_pillar_width;
1927
1928         if (tpg->crop.left + tpg->crop.width >
1929             tpg->border.left + tpg->border.width) {
1930                 right_pillar_start =
1931                         tpg->border.left + tpg->border.width - tpg->crop.left;
1932                 right_pillar_start =
1933                         tpg_hscale_div(tpg, p, right_pillar_start);
1934                 if (right_pillar_start > params->img_width)
1935                         right_pillar_start = params->img_width;
1936         }
1937         params->right_pillar_start = right_pillar_start;
1938
1939         params->sav_eav_f = tpg->field ==
1940                         (params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
1941 }
1942
1943 static void tpg_fill_plane_extras(const struct tpg_data *tpg,
1944                                   const struct tpg_draw_params *params,
1945                                   unsigned p, unsigned h, u8 *vbuf)
1946 {
1947         unsigned twopixsize = params->twopixsize;
1948         unsigned img_width = params->img_width;
1949         unsigned frame_line = params->frame_line;
1950         const struct v4l2_rect *sq = &tpg->square;
1951         const struct v4l2_rect *b = &tpg->border;
1952         const struct v4l2_rect *c = &tpg->crop;
1953
1954         if (params->is_tv && !params->is_60hz &&
1955             frame_line == 0 && params->wss_width) {
1956                 /*
1957                  * Replace the first half of the top line of a 50 Hz frame
1958                  * with random data to simulate a WSS signal.
1959                  */
1960                 u8 *wss = tpg->random_line[p] + params->wss_random_offset;
1961
1962                 memcpy(vbuf, wss, params->wss_width);
1963         }
1964
1965         if (tpg->show_border && frame_line >= b->top &&
1966             frame_line < b->top + b->height) {
1967                 unsigned bottom = b->top + b->height - 1;
1968                 unsigned left = params->left_pillar_width;
1969                 unsigned right = params->right_pillar_start;
1970
1971                 if (frame_line == b->top || frame_line == b->top + 1 ||
1972                     frame_line == bottom || frame_line == bottom - 1) {
1973                         memcpy(vbuf + left, tpg->contrast_line[p],
1974                                         right - left);
1975                 } else {
1976                         if (b->left >= c->left &&
1977                             b->left < c->left + c->width)
1978                                 memcpy(vbuf + left,
1979                                         tpg->contrast_line[p], twopixsize);
1980                         if (b->left + b->width > c->left &&
1981                             b->left + b->width <= c->left + c->width)
1982                                 memcpy(vbuf + right - twopixsize,
1983                                         tpg->contrast_line[p], twopixsize);
1984                 }
1985         }
1986         if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top &&
1987             frame_line < b->top + b->height) {
1988                 memcpy(vbuf, tpg->black_line[p], params->left_pillar_width);
1989                 memcpy(vbuf + params->right_pillar_start, tpg->black_line[p],
1990                        img_width - params->right_pillar_start);
1991         }
1992         if (tpg->show_square && frame_line >= sq->top &&
1993             frame_line < sq->top + sq->height &&
1994             sq->left < c->left + c->width &&
1995             sq->left + sq->width >= c->left) {
1996                 unsigned left = sq->left;
1997                 unsigned width = sq->width;
1998
1999                 if (c->left > left) {
2000                         width -= c->left - left;
2001                         left = c->left;
2002                 }
2003                 if (c->left + c->width < left + width)
2004                         width -= left + width - c->left - c->width;
2005                 left -= c->left;
2006                 left = tpg_hscale_div(tpg, p, left);
2007                 width = tpg_hscale_div(tpg, p, width);
2008                 memcpy(vbuf + left, tpg->contrast_line[p], width);
2009         }
2010         if (tpg->insert_sav) {
2011                 unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width / 3);
2012                 u8 *p = vbuf + offset;
2013                 unsigned vact = 0, hact = 0;
2014
2015                 p[0] = 0xff;
2016                 p[1] = 0;
2017                 p[2] = 0;
2018                 p[3] = 0x80 | (params->sav_eav_f << 6) |
2019                         (vact << 5) | (hact << 4) |
2020                         ((hact ^ vact) << 3) |
2021                         ((hact ^ params->sav_eav_f) << 2) |
2022                         ((params->sav_eav_f ^ vact) << 1) |
2023                         (hact ^ vact ^ params->sav_eav_f);
2024         }
2025         if (tpg->insert_eav) {
2026                 unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width * 2 / 3);
2027                 u8 *p = vbuf + offset;
2028                 unsigned vact = 0, hact = 1;
2029
2030                 p[0] = 0xff;
2031                 p[1] = 0;
2032                 p[2] = 0;
2033                 p[3] = 0x80 | (params->sav_eav_f << 6) |
2034                         (vact << 5) | (hact << 4) |
2035                         ((hact ^ vact) << 3) |
2036                         ((hact ^ params->sav_eav_f) << 2) |
2037                         ((params->sav_eav_f ^ vact) << 1) |
2038                         (hact ^ vact ^ params->sav_eav_f);
2039         }
2040 }
2041
2042 static void tpg_fill_plane_pattern(const struct tpg_data *tpg,
2043                                    const struct tpg_draw_params *params,
2044                                    unsigned p, unsigned h, u8 *vbuf)
2045 {
2046         unsigned twopixsize = params->twopixsize;
2047         unsigned img_width = params->img_width;
2048         unsigned mv_hor_old = params->mv_hor_old;
2049         unsigned mv_hor_new = params->mv_hor_new;
2050         unsigned mv_vert_old = params->mv_vert_old;
2051         unsigned mv_vert_new = params->mv_vert_new;
2052         unsigned frame_line = params->frame_line;
2053         unsigned frame_line_next = params->frame_line_next;
2054         unsigned line_offset = tpg_hscale_div(tpg, p, tpg->crop.left);
2055         bool even;
2056         bool fill_blank = false;
2057         unsigned pat_line_old;
2058         unsigned pat_line_new;
2059         u8 *linestart_older;
2060         u8 *linestart_newer;
2061         u8 *linestart_top;
2062         u8 *linestart_bottom;
2063
2064         even = !(frame_line & 1);
2065
2066         if (h >= params->hmax) {
2067                 if (params->hmax == tpg->compose.height)
2068                         return;
2069                 if (!tpg->perc_fill_blank)
2070                         return;
2071                 fill_blank = true;
2072         }
2073
2074         if (tpg->vflip) {
2075                 frame_line = tpg->src_height - frame_line - 1;
2076                 frame_line_next = tpg->src_height - frame_line_next - 1;
2077         }
2078
2079         if (fill_blank) {
2080                 linestart_older = tpg->contrast_line[p];
2081                 linestart_newer = tpg->contrast_line[p];
2082         } else if (tpg->qual != TPG_QUAL_NOISE &&
2083                    (frame_line < tpg->border.top ||
2084                     frame_line >= tpg->border.top + tpg->border.height)) {
2085                 linestart_older = tpg->black_line[p];
2086                 linestart_newer = tpg->black_line[p];
2087         } else if (tpg->pattern == TPG_PAT_NOISE || tpg->qual == TPG_QUAL_NOISE) {
2088                 linestart_older = tpg->random_line[p] +
2089                                   twopixsize * prandom_u32_max(tpg->src_width / 2);
2090                 linestart_newer = tpg->random_line[p] +
2091                                   twopixsize * prandom_u32_max(tpg->src_width / 2);
2092         } else {
2093                 unsigned frame_line_old =
2094                         (frame_line + mv_vert_old) % tpg->src_height;
2095                 unsigned frame_line_new =
2096                         (frame_line + mv_vert_new) % tpg->src_height;
2097                 unsigned pat_line_next_old;
2098                 unsigned pat_line_next_new;
2099
2100                 pat_line_old = tpg_get_pat_line(tpg, frame_line_old);
2101                 pat_line_new = tpg_get_pat_line(tpg, frame_line_new);
2102                 linestart_older = tpg->lines[pat_line_old][p] + mv_hor_old;
2103                 linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new;
2104
2105                 if (tpg->vdownsampling[p] > 1 && frame_line != frame_line_next) {
2106                         int avg_pat;
2107
2108                         /*
2109                          * Now decide whether we need to use downsampled_lines[].
2110                          * That's necessary if the two lines use different patterns.
2111                          */
2112                         pat_line_next_old = tpg_get_pat_line(tpg,
2113                                         (frame_line_next + mv_vert_old) % tpg->src_height);
2114                         pat_line_next_new = tpg_get_pat_line(tpg,
2115                                         (frame_line_next + mv_vert_new) % tpg->src_height);
2116
2117                         switch (tpg->field) {
2118                         case V4L2_FIELD_INTERLACED:
2119                         case V4L2_FIELD_INTERLACED_BT:
2120                         case V4L2_FIELD_INTERLACED_TB:
2121                                 avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_new);
2122                                 if (avg_pat < 0)
2123                                         break;
2124                                 linestart_older = tpg->downsampled_lines[avg_pat][p] + mv_hor_old;
2125                                 linestart_newer = linestart_older;
2126                                 break;
2127                         case V4L2_FIELD_NONE:
2128                         case V4L2_FIELD_TOP:
2129                         case V4L2_FIELD_BOTTOM:
2130                         case V4L2_FIELD_SEQ_BT:
2131                         case V4L2_FIELD_SEQ_TB:
2132                                 avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_next_old);
2133                                 if (avg_pat >= 0)
2134                                         linestart_older = tpg->downsampled_lines[avg_pat][p] +
2135                                                 mv_hor_old;
2136                                 avg_pat = tpg_pattern_avg(tpg, pat_line_new, pat_line_next_new);
2137                                 if (avg_pat >= 0)
2138                                         linestart_newer = tpg->downsampled_lines[avg_pat][p] +
2139                                                 mv_hor_new;
2140                                 break;
2141                         }
2142                 }
2143                 linestart_older += line_offset;
2144                 linestart_newer += line_offset;
2145         }
2146         if (tpg->field_alternate) {
2147                 linestart_top = linestart_bottom = linestart_older;
2148         } else if (params->is_60hz) {
2149                 linestart_top = linestart_newer;
2150                 linestart_bottom = linestart_older;
2151         } else {
2152                 linestart_top = linestart_older;
2153                 linestart_bottom = linestart_newer;
2154         }
2155
2156         switch (tpg->field) {
2157         case V4L2_FIELD_INTERLACED:
2158         case V4L2_FIELD_INTERLACED_TB:
2159         case V4L2_FIELD_SEQ_TB:
2160         case V4L2_FIELD_SEQ_BT:
2161                 if (even)
2162                         memcpy(vbuf, linestart_top, img_width);
2163                 else
2164                         memcpy(vbuf, linestart_bottom, img_width);
2165                 break;
2166         case V4L2_FIELD_INTERLACED_BT:
2167                 if (even)
2168                         memcpy(vbuf, linestart_bottom, img_width);
2169                 else
2170                         memcpy(vbuf, linestart_top, img_width);
2171                 break;
2172         case V4L2_FIELD_TOP:
2173                 memcpy(vbuf, linestart_top, img_width);
2174                 break;
2175         case V4L2_FIELD_BOTTOM:
2176                 memcpy(vbuf, linestart_bottom, img_width);
2177                 break;
2178         case V4L2_FIELD_NONE:
2179         default:
2180                 memcpy(vbuf, linestart_older, img_width);
2181                 break;
2182         }
2183 }
2184
2185 void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
2186                            unsigned p, u8 *vbuf)
2187 {
2188         struct tpg_draw_params params;
2189         unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
2190
2191         /* Coarse scaling with Bresenham */
2192         unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height;
2193         unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height;
2194         unsigned src_y = 0;
2195         unsigned error = 0;
2196         unsigned h;
2197
2198         tpg_recalc(tpg);
2199
2200         params.is_tv = std;
2201         params.is_60hz = std & V4L2_STD_525_60;
2202         params.twopixsize = tpg->twopixelsize[p];
2203         params.img_width = tpg_hdiv(tpg, p, tpg->compose.width);
2204         params.stride = tpg->bytesperline[p];
2205         params.hmax = (tpg->compose.height * tpg->perc_fill) / 100;
2206
2207         tpg_fill_params_pattern(tpg, p, &params);
2208         tpg_fill_params_extras(tpg, p, &params);
2209
2210         vbuf += tpg_hdiv(tpg, p, tpg->compose.left);
2211
2212         for (h = 0; h < tpg->compose.height; h++) {
2213                 unsigned buf_line;
2214
2215                 params.frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
2216                 params.frame_line_next = params.frame_line;
2217                 buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
2218                 src_y += int_part;
2219                 error += fract_part;
2220                 if (error >= tpg->compose.height) {
2221                         error -= tpg->compose.height;
2222                         src_y++;
2223                 }
2224
2225                 /*
2226                  * For line-interleaved formats determine the 'plane'
2227                  * based on the buffer line.
2228                  */
2229                 if (tpg_g_interleaved(tpg))
2230                         p = tpg_g_interleaved_plane(tpg, buf_line);
2231
2232                 if (tpg->vdownsampling[p] > 1) {
2233                         /*
2234                          * When doing vertical downsampling the field setting
2235                          * matters: for SEQ_BT/TB we downsample each field
2236                          * separately (i.e. lines 0+2 are combined, as are
2237                          * lines 1+3), for the other field settings we combine
2238                          * odd and even lines. Doing that for SEQ_BT/TB would
2239                          * be really weird.
2240                          */
2241                         if (tpg->field == V4L2_FIELD_SEQ_BT ||
2242                             tpg->field == V4L2_FIELD_SEQ_TB) {
2243                                 unsigned next_src_y = src_y;
2244
2245                                 if ((h & 3) >= 2)
2246                                         continue;
2247                                 next_src_y += int_part;
2248                                 if (error + fract_part >= tpg->compose.height)
2249                                         next_src_y++;
2250                                 params.frame_line_next =
2251                                         tpg_calc_frameline(tpg, next_src_y, tpg->field);
2252                         } else {
2253                                 if (h & 1)
2254                                         continue;
2255                                 params.frame_line_next =
2256                                         tpg_calc_frameline(tpg, src_y, tpg->field);
2257                         }
2258
2259                         buf_line /= tpg->vdownsampling[p];
2260                 }
2261                 tpg_fill_plane_pattern(tpg, &params, p, h,
2262                                 vbuf + buf_line * params.stride);
2263                 tpg_fill_plane_extras(tpg, &params, p, h,
2264                                 vbuf + buf_line * params.stride);
2265         }
2266 }
2267
2268 void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
2269 {
2270         unsigned offset = 0;
2271         unsigned i;
2272
2273         if (tpg->buffers > 1) {
2274                 tpg_fill_plane_buffer(tpg, std, p, vbuf);
2275                 return;
2276         }
2277
2278         for (i = 0; i < tpg_g_planes(tpg); i++) {
2279                 tpg_fill_plane_buffer(tpg, std, i, vbuf + offset);
2280                 offset += tpg_calc_plane_size(tpg, i);
2281         }
2282 }