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