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