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