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