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