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