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