root/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tpg_set_font
  2. tpg_init
  3. tpg_alloc
  4. tpg_free
  5. tpg_s_fourcc
  6. tpg_s_crop_compose
  7. tpg_reset_source
  8. tpg_get_textbg_color
  9. tpg_get_textfg_color
  10. rec709_to_linear
  11. linear_to_rec709
  12. color_to_hsv
  13. rgb2ycbcr
  14. color_to_ycbcr
  15. ycbcr2rgb
  16. ycbcr_to_color
  17. precalculate_color
  18. tpg_precalculate_colors
  19. gen_twopix
  20. tpg_g_interleaved_plane
  21. tpg_get_pat_lines
  22. tpg_get_pat_line
  23. tpg_get_color
  24. tpg_calculate_square_border
  25. tpg_precalculate_line
  26. tpg_print_str_2
  27. tpg_print_str_4
  28. tpg_print_str_6
  29. tpg_print_str_8
  30. tpg_gen_text
  31. tpg_update_mv_step
  32. tpg_calc_frameline
  33. tpg_calc_buffer_line
  34. tpg_recalc
  35. tpg_calc_text_basep
  36. tpg_pattern_avg
  37. tpg_color_enc_str
  38. tpg_log_status
  39. tpg_fill_params_pattern
  40. tpg_fill_params_extras
  41. tpg_fill_plane_extras
  42. tpg_fill_plane_pattern
  43. tpg_fill_plane_buffer
  44. tpg_fillbuffer

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

/* [<][>][^][v][top][bottom][index][help] */