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