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