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