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