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