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