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