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 */
26const 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 */
53const 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 */
67static 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 */
90static const u8 *font8x16;
91
92void tpg_set_font(const u8 *f)
93{
94	font8x16 = f;
95}
96
97void 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
118int 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
154void 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
178bool 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
389void 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
404void 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
428static 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
440static 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
453static inline int rec709_to_linear(int v)
454{
455	v = clamp(v, 0, 0xff0);
456	return tpg_rec709_to_linear[v];
457}
458
459static inline int linear_to_rec709(int v)
460{
461	v = clamp(v, 0, 0xff0);
462	return tpg_linear_to_rec709[v];
463}
464
465static 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
473static 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
574static 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
588static 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 */
700static 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
891static 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. */
900static 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
1201unsigned 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. */
1223static 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. */
1245static 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 */
1275static 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 */
1361static 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
1441static 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 */
1561typedef 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
1617static 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
1624static 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
1631static 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
1638static 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
1645void 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
1697void 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 */
1746static 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 */
1763static 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
1781static 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
1815void 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
1834static 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
1846void 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 */
1867struct 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
1892static 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
1905static 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
1943static 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
2042static 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
2185void 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
2268void 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}
2283