linux/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
<<
>>
Prefs
   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 */
  15const 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};
  40EXPORT_SYMBOL_GPL(tpg_pattern_strings);
  41
  42/* Must remain in sync with enum tpg_aspect */
  43const char * const tpg_aspect_strings[] = {
  44        "Source Width x Height",
  45        "4x3",
  46        "14x9",
  47        "16x9",
  48        "16x9 Anamorphic",
  49        NULL
  50};
  51EXPORT_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 */
  58static 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 */
  81static const u8 *font8x16;
  82
  83void tpg_set_font(const u8 *f)
  84{
  85        font8x16 = f;
  86}
  87EXPORT_SYMBOL_GPL(tpg_set_font);
  88
  89void 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}
 110EXPORT_SYMBOL_GPL(tpg_init);
 111
 112int 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}
 152EXPORT_SYMBOL_GPL(tpg_alloc);
 153
 154void 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}
 177EXPORT_SYMBOL_GPL(tpg_free);
 178
 179bool 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                fallthrough;
 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                fallthrough;
 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                fallthrough;
 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                fallthrough;
 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                fallthrough;
 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}
 469EXPORT_SYMBOL_GPL(tpg_s_fourcc);
 470
 471void 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}
 485EXPORT_SYMBOL_GPL(tpg_s_crop_compose);
 486
 487void 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}
 510EXPORT_SYMBOL_GPL(tpg_reset_source);
 511
 512static 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
 524static 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
 537static inline int rec709_to_linear(int v)
 538{
 539        v = clamp(v, 0, 0xff0);
 540        return tpg_rec709_to_linear[v];
 541}
 542
 543static inline int linear_to_rec709(int v)
 544{
 545        v = clamp(v, 0, 0xff0);
 546        return tpg_linear_to_rec709[v];
 547}
 548
 549static 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
 614static 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
 622static 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
 722static 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
 736static 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 */
 847static 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
1088static 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. */
1097static 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                fallthrough;
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                fallthrough;
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                fallthrough;
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                fallthrough;
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                fallthrough;
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                fallthrough;
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                fallthrough;
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                fallthrough;
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                fallthrough;
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                fallthrough;
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                fallthrough;
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                fallthrough;
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                fallthrough;
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
1507unsigned 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}
1531EXPORT_SYMBOL_GPL(tpg_g_interleaved_plane);
1532
1533/* Return how many pattern lines are used by the current pattern. */
1534static 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. */
1556static 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 */
1586static 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 */
1672static 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
1752static 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 */
1872typedef 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
1928static 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, const char *text, unsigned len)
1931{
1932        PRINTSTR(u8);
1933}
1934
1935static 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, const char *text, unsigned len)
1938{
1939        PRINTSTR(u16);
1940}
1941
1942static 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, const char *text, unsigned len)
1945{
1946        PRINTSTR(x24);
1947}
1948
1949static 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, const char *text, unsigned len)
1952{
1953        PRINTSTR(u32);
1954}
1955
1956void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1957                  int y, int x, const 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;
1963        unsigned p;
1964
1965        if (font8x16 == NULL || basep == NULL || text == NULL)
1966                return;
1967
1968        len = strlen(text);
1969
1970        /* Checks if it is possible to show string */
1971        if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width)
1972                return;
1973
1974        if (len > (tpg->compose.width - x) / 8)
1975                len = (tpg->compose.width - x) / 8;
1976        if (tpg->vflip)
1977                y = tpg->compose.height - y - 16;
1978        if (tpg->hflip)
1979                x = tpg->compose.width - x - 8;
1980        y += tpg->compose.top;
1981        x += tpg->compose.left;
1982        if (tpg->field == V4L2_FIELD_BOTTOM)
1983                first = 1;
1984        else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT)
1985                div = 2;
1986
1987        for (p = 0; p < tpg->planes; p++) {
1988                /* Print text */
1989                switch (tpg->twopixelsize[p]) {
1990                case 2:
1991                        tpg_print_str_2(tpg, basep, p, first, div, step, y, x,
1992                                        text, len);
1993                        break;
1994                case 4:
1995                        tpg_print_str_4(tpg, basep, p, first, div, step, y, x,
1996                                        text, len);
1997                        break;
1998                case 6:
1999                        tpg_print_str_6(tpg, basep, p, first, div, step, y, x,
2000                                        text, len);
2001                        break;
2002                case 8:
2003                        tpg_print_str_8(tpg, basep, p, first, div, step, y, x,
2004                                        text, len);
2005                        break;
2006                }
2007        }
2008}
2009EXPORT_SYMBOL_GPL(tpg_gen_text);
2010
2011const char *tpg_g_color_order(const struct tpg_data *tpg)
2012{
2013        switch (tpg->pattern) {
2014        case TPG_PAT_75_COLORBAR:
2015        case TPG_PAT_100_COLORBAR:
2016        case TPG_PAT_CSC_COLORBAR:
2017        case TPG_PAT_100_HCOLORBAR:
2018                return "White, yellow, cyan, green, magenta, red, blue, black";
2019        case TPG_PAT_BLACK:
2020                return "Black";
2021        case TPG_PAT_WHITE:
2022                return "White";
2023        case TPG_PAT_RED:
2024                return "Red";
2025        case TPG_PAT_GREEN:
2026                return "Green";
2027        case TPG_PAT_BLUE:
2028                return "Blue";
2029        default:
2030                return NULL;
2031        }
2032}
2033EXPORT_SYMBOL_GPL(tpg_g_color_order);
2034
2035void tpg_update_mv_step(struct tpg_data *tpg)
2036{
2037        int factor = tpg->mv_hor_mode > TPG_MOVE_NONE ? -1 : 1;
2038
2039        if (tpg->hflip)
2040                factor = -factor;
2041        switch (tpg->mv_hor_mode) {
2042        case TPG_MOVE_NEG_FAST:
2043        case TPG_MOVE_POS_FAST:
2044                tpg->mv_hor_step = ((tpg->src_width + 319) / 320) * 4;
2045                break;
2046        case TPG_MOVE_NEG:
2047        case TPG_MOVE_POS:
2048                tpg->mv_hor_step = ((tpg->src_width + 639) / 640) * 4;
2049                break;
2050        case TPG_MOVE_NEG_SLOW:
2051        case TPG_MOVE_POS_SLOW:
2052                tpg->mv_hor_step = 2;
2053                break;
2054        case TPG_MOVE_NONE:
2055                tpg->mv_hor_step = 0;
2056                break;
2057        }
2058        if (factor < 0)
2059                tpg->mv_hor_step = tpg->src_width - tpg->mv_hor_step;
2060
2061        factor = tpg->mv_vert_mode > TPG_MOVE_NONE ? -1 : 1;
2062        switch (tpg->mv_vert_mode) {
2063        case TPG_MOVE_NEG_FAST:
2064        case TPG_MOVE_POS_FAST:
2065                tpg->mv_vert_step = ((tpg->src_width + 319) / 320) * 4;
2066                break;
2067        case TPG_MOVE_NEG:
2068        case TPG_MOVE_POS:
2069                tpg->mv_vert_step = ((tpg->src_width + 639) / 640) * 4;
2070                break;
2071        case TPG_MOVE_NEG_SLOW:
2072        case TPG_MOVE_POS_SLOW:
2073                tpg->mv_vert_step = 1;
2074                break;
2075        case TPG_MOVE_NONE:
2076                tpg->mv_vert_step = 0;
2077                break;
2078        }
2079        if (factor < 0)
2080                tpg->mv_vert_step = tpg->src_height - tpg->mv_vert_step;
2081}
2082EXPORT_SYMBOL_GPL(tpg_update_mv_step);
2083
2084/* Map the line number relative to the crop rectangle to a frame line number */
2085static unsigned tpg_calc_frameline(const struct tpg_data *tpg, unsigned src_y,
2086                                    unsigned field)
2087{
2088        switch (field) {
2089        case V4L2_FIELD_TOP:
2090                return tpg->crop.top + src_y * 2;
2091        case V4L2_FIELD_BOTTOM:
2092                return tpg->crop.top + src_y * 2 + 1;
2093        default:
2094                return src_y + tpg->crop.top;
2095        }
2096}
2097
2098/*
2099 * Map the line number relative to the compose rectangle to a destination
2100 * buffer line number.
2101 */
2102static unsigned tpg_calc_buffer_line(const struct tpg_data *tpg, unsigned y,
2103                                    unsigned field)
2104{
2105        y += tpg->compose.top;
2106        switch (field) {
2107        case V4L2_FIELD_SEQ_TB:
2108                if (y & 1)
2109                        return tpg->buf_height / 2 + y / 2;
2110                return y / 2;
2111        case V4L2_FIELD_SEQ_BT:
2112                if (y & 1)
2113                        return y / 2;
2114                return tpg->buf_height / 2 + y / 2;
2115        default:
2116                return y;
2117        }
2118}
2119
2120static void tpg_recalc(struct tpg_data *tpg)
2121{
2122        if (tpg->recalc_colors) {
2123                tpg->recalc_colors = false;
2124                tpg->recalc_lines = true;
2125                tpg->real_xfer_func = tpg->xfer_func;
2126                tpg->real_ycbcr_enc = tpg->ycbcr_enc;
2127                tpg->real_hsv_enc = tpg->hsv_enc;
2128                tpg->real_quantization = tpg->quantization;
2129
2130                if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT)
2131                        tpg->real_xfer_func =
2132                                V4L2_MAP_XFER_FUNC_DEFAULT(tpg->colorspace);
2133
2134                if (tpg->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
2135                        tpg->real_ycbcr_enc =
2136                                V4L2_MAP_YCBCR_ENC_DEFAULT(tpg->colorspace);
2137
2138                if (tpg->quantization == V4L2_QUANTIZATION_DEFAULT)
2139                        tpg->real_quantization =
2140                                V4L2_MAP_QUANTIZATION_DEFAULT(
2141                                        tpg->color_enc != TGP_COLOR_ENC_YCBCR,
2142                                        tpg->colorspace, tpg->real_ycbcr_enc);
2143
2144                tpg_precalculate_colors(tpg);
2145        }
2146        if (tpg->recalc_square_border) {
2147                tpg->recalc_square_border = false;
2148                tpg_calculate_square_border(tpg);
2149        }
2150        if (tpg->recalc_lines) {
2151                tpg->recalc_lines = false;
2152                tpg_precalculate_line(tpg);
2153        }
2154}
2155
2156void tpg_calc_text_basep(struct tpg_data *tpg,
2157                u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf)
2158{
2159        unsigned stride = tpg->bytesperline[p];
2160        unsigned h = tpg->buf_height;
2161
2162        tpg_recalc(tpg);
2163
2164        basep[p][0] = vbuf;
2165        basep[p][1] = vbuf;
2166        h /= tpg->vdownsampling[p];
2167        if (tpg->field == V4L2_FIELD_SEQ_TB)
2168                basep[p][1] += h * stride / 2;
2169        else if (tpg->field == V4L2_FIELD_SEQ_BT)
2170                basep[p][0] += h * stride / 2;
2171        if (p == 0 && tpg->interleaved)
2172                tpg_calc_text_basep(tpg, basep, 1, vbuf);
2173}
2174EXPORT_SYMBOL_GPL(tpg_calc_text_basep);
2175
2176static int tpg_pattern_avg(const struct tpg_data *tpg,
2177                           unsigned pat1, unsigned pat2)
2178{
2179        unsigned pat_lines = tpg_get_pat_lines(tpg);
2180
2181        if (pat1 == (pat2 + 1) % pat_lines)
2182                return pat2;
2183        if (pat2 == (pat1 + 1) % pat_lines)
2184                return pat1;
2185        return -1;
2186}
2187
2188static const char *tpg_color_enc_str(enum tgp_color_enc
2189                                                 color_enc)
2190{
2191        switch (color_enc) {
2192        case TGP_COLOR_ENC_HSV:
2193                return "HSV";
2194        case TGP_COLOR_ENC_YCBCR:
2195                return "Y'CbCr";
2196        case TGP_COLOR_ENC_LUMA:
2197                return "Luma";
2198        case TGP_COLOR_ENC_RGB:
2199        default:
2200                return "R'G'B";
2201
2202        }
2203}
2204
2205void tpg_log_status(struct tpg_data *tpg)
2206{
2207        pr_info("tpg source WxH: %ux%u (%s)\n",
2208                tpg->src_width, tpg->src_height,
2209                tpg_color_enc_str(tpg->color_enc));
2210        pr_info("tpg field: %u\n", tpg->field);
2211        pr_info("tpg crop: %ux%u@%dx%d\n", tpg->crop.width, tpg->crop.height,
2212                        tpg->crop.left, tpg->crop.top);
2213        pr_info("tpg compose: %ux%u@%dx%d\n", tpg->compose.width, tpg->compose.height,
2214                        tpg->compose.left, tpg->compose.top);
2215        pr_info("tpg colorspace: %d\n", tpg->colorspace);
2216        pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func);
2217        if (tpg->color_enc == TGP_COLOR_ENC_HSV)
2218                pr_info("tpg HSV encoding: %d/%d\n",
2219                        tpg->hsv_enc, tpg->real_hsv_enc);
2220        else if (tpg->color_enc == TGP_COLOR_ENC_YCBCR)
2221                pr_info("tpg Y'CbCr encoding: %d/%d\n",
2222                        tpg->ycbcr_enc, tpg->real_ycbcr_enc);
2223        pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization);
2224        pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range);
2225}
2226EXPORT_SYMBOL_GPL(tpg_log_status);
2227
2228/*
2229 * This struct contains common parameters used by both the drawing of the
2230 * test pattern and the drawing of the extras (borders, square, etc.)
2231 */
2232struct tpg_draw_params {
2233        /* common data */
2234        bool is_tv;
2235        bool is_60hz;
2236        unsigned twopixsize;
2237        unsigned img_width;
2238        unsigned stride;
2239        unsigned hmax;
2240        unsigned frame_line;
2241        unsigned frame_line_next;
2242
2243        /* test pattern */
2244        unsigned mv_hor_old;
2245        unsigned mv_hor_new;
2246        unsigned mv_vert_old;
2247        unsigned mv_vert_new;
2248
2249        /* extras */
2250        unsigned wss_width;
2251        unsigned wss_random_offset;
2252        unsigned sav_eav_f;
2253        unsigned left_pillar_width;
2254        unsigned right_pillar_start;
2255};
2256
2257static void tpg_fill_params_pattern(const struct tpg_data *tpg, unsigned p,
2258                                    struct tpg_draw_params *params)
2259{
2260        params->mv_hor_old =
2261                tpg_hscale_div(tpg, p, tpg->mv_hor_count % tpg->src_width);
2262        params->mv_hor_new =
2263                tpg_hscale_div(tpg, p, (tpg->mv_hor_count + tpg->mv_hor_step) %
2264                               tpg->src_width);
2265        params->mv_vert_old = tpg->mv_vert_count % tpg->src_height;
2266        params->mv_vert_new =
2267                (tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height;
2268}
2269
2270static void tpg_fill_params_extras(const struct tpg_data *tpg,
2271                                   unsigned p,
2272                                   struct tpg_draw_params *params)
2273{
2274        unsigned left_pillar_width = 0;
2275        unsigned right_pillar_start = params->img_width;
2276
2277        params->wss_width = tpg->crop.left < tpg->src_width / 2 ?
2278                tpg->src_width / 2 - tpg->crop.left : 0;
2279        if (params->wss_width > tpg->crop.width)
2280                params->wss_width = tpg->crop.width;
2281        params->wss_width = tpg_hscale_div(tpg, p, params->wss_width);
2282        params->wss_random_offset =
2283                params->twopixsize * prandom_u32_max(tpg->src_width / 2);
2284
2285        if (tpg->crop.left < tpg->border.left) {
2286                left_pillar_width = tpg->border.left - tpg->crop.left;
2287                if (left_pillar_width > tpg->crop.width)
2288                        left_pillar_width = tpg->crop.width;
2289                left_pillar_width = tpg_hscale_div(tpg, p, left_pillar_width);
2290        }
2291        params->left_pillar_width = left_pillar_width;
2292
2293        if (tpg->crop.left + tpg->crop.width >
2294            tpg->border.left + tpg->border.width) {
2295                right_pillar_start =
2296                        tpg->border.left + tpg->border.width - tpg->crop.left;
2297                right_pillar_start =
2298                        tpg_hscale_div(tpg, p, right_pillar_start);
2299                if (right_pillar_start > params->img_width)
2300                        right_pillar_start = params->img_width;
2301        }
2302        params->right_pillar_start = right_pillar_start;
2303
2304        params->sav_eav_f = tpg->field ==
2305                        (params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
2306}
2307
2308static void tpg_fill_plane_extras(const struct tpg_data *tpg,
2309                                  const struct tpg_draw_params *params,
2310                                  unsigned p, unsigned h, u8 *vbuf)
2311{
2312        unsigned twopixsize = params->twopixsize;
2313        unsigned img_width = params->img_width;
2314        unsigned frame_line = params->frame_line;
2315        const struct v4l2_rect *sq = &tpg->square;
2316        const struct v4l2_rect *b = &tpg->border;
2317        const struct v4l2_rect *c = &tpg->crop;
2318
2319        if (params->is_tv && !params->is_60hz &&
2320            frame_line == 0 && params->wss_width) {
2321                /*
2322                 * Replace the first half of the top line of a 50 Hz frame
2323                 * with random data to simulate a WSS signal.
2324                 */
2325                u8 *wss = tpg->random_line[p] + params->wss_random_offset;
2326
2327                memcpy(vbuf, wss, params->wss_width);
2328        }
2329
2330        if (tpg->show_border && frame_line >= b->top &&
2331            frame_line < b->top + b->height) {
2332                unsigned bottom = b->top + b->height - 1;
2333                unsigned left = params->left_pillar_width;
2334                unsigned right = params->right_pillar_start;
2335
2336                if (frame_line == b->top || frame_line == b->top + 1 ||
2337                    frame_line == bottom || frame_line == bottom - 1) {
2338                        memcpy(vbuf + left, tpg->contrast_line[p],
2339                                        right - left);
2340                } else {
2341                        if (b->left >= c->left &&
2342                            b->left < c->left + c->width)
2343                                memcpy(vbuf + left,
2344                                        tpg->contrast_line[p], twopixsize);
2345                        if (b->left + b->width > c->left &&
2346                            b->left + b->width <= c->left + c->width)
2347                                memcpy(vbuf + right - twopixsize,
2348                                        tpg->contrast_line[p], twopixsize);
2349                }
2350        }
2351        if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top &&
2352            frame_line < b->top + b->height) {
2353                memcpy(vbuf, tpg->black_line[p], params->left_pillar_width);
2354                memcpy(vbuf + params->right_pillar_start, tpg->black_line[p],
2355                       img_width - params->right_pillar_start);
2356        }
2357        if (tpg->show_square && frame_line >= sq->top &&
2358            frame_line < sq->top + sq->height &&
2359            sq->left < c->left + c->width &&
2360            sq->left + sq->width >= c->left) {
2361                unsigned left = sq->left;
2362                unsigned width = sq->width;
2363
2364                if (c->left > left) {
2365                        width -= c->left - left;
2366                        left = c->left;
2367                }
2368                if (c->left + c->width < left + width)
2369                        width -= left + width - c->left - c->width;
2370                left -= c->left;
2371                left = tpg_hscale_div(tpg, p, left);
2372                width = tpg_hscale_div(tpg, p, width);
2373                memcpy(vbuf + left, tpg->contrast_line[p], width);
2374        }
2375        if (tpg->insert_sav) {
2376                unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width / 3);
2377                u8 *p = vbuf + offset;
2378                unsigned vact = 0, hact = 0;
2379
2380                p[0] = 0xff;
2381                p[1] = 0;
2382                p[2] = 0;
2383                p[3] = 0x80 | (params->sav_eav_f << 6) |
2384                        (vact << 5) | (hact << 4) |
2385                        ((hact ^ vact) << 3) |
2386                        ((hact ^ params->sav_eav_f) << 2) |
2387                        ((params->sav_eav_f ^ vact) << 1) |
2388                        (hact ^ vact ^ params->sav_eav_f);
2389        }
2390        if (tpg->insert_eav) {
2391                unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width * 2 / 3);
2392                u8 *p = vbuf + offset;
2393                unsigned vact = 0, hact = 1;
2394
2395                p[0] = 0xff;
2396                p[1] = 0;
2397                p[2] = 0;
2398                p[3] = 0x80 | (params->sav_eav_f << 6) |
2399                        (vact << 5) | (hact << 4) |
2400                        ((hact ^ vact) << 3) |
2401                        ((hact ^ params->sav_eav_f) << 2) |
2402                        ((params->sav_eav_f ^ vact) << 1) |
2403                        (hact ^ vact ^ params->sav_eav_f);
2404        }
2405}
2406
2407static void tpg_fill_plane_pattern(const struct tpg_data *tpg,
2408                                   const struct tpg_draw_params *params,
2409                                   unsigned p, unsigned h, u8 *vbuf)
2410{
2411        unsigned twopixsize = params->twopixsize;
2412        unsigned img_width = params->img_width;
2413        unsigned mv_hor_old = params->mv_hor_old;
2414        unsigned mv_hor_new = params->mv_hor_new;
2415        unsigned mv_vert_old = params->mv_vert_old;
2416        unsigned mv_vert_new = params->mv_vert_new;
2417        unsigned frame_line = params->frame_line;
2418        unsigned frame_line_next = params->frame_line_next;
2419        unsigned line_offset = tpg_hscale_div(tpg, p, tpg->crop.left);
2420        bool even;
2421        bool fill_blank = false;
2422        unsigned pat_line_old;
2423        unsigned pat_line_new;
2424        u8 *linestart_older;
2425        u8 *linestart_newer;
2426        u8 *linestart_top;
2427        u8 *linestart_bottom;
2428
2429        even = !(frame_line & 1);
2430
2431        if (h >= params->hmax) {
2432                if (params->hmax == tpg->compose.height)
2433                        return;
2434                if (!tpg->perc_fill_blank)
2435                        return;
2436                fill_blank = true;
2437        }
2438
2439        if (tpg->vflip) {
2440                frame_line = tpg->src_height - frame_line - 1;
2441                frame_line_next = tpg->src_height - frame_line_next - 1;
2442        }
2443
2444        if (fill_blank) {
2445                linestart_older = tpg->contrast_line[p];
2446                linestart_newer = tpg->contrast_line[p];
2447        } else if (tpg->qual != TPG_QUAL_NOISE &&
2448                   (frame_line < tpg->border.top ||
2449                    frame_line >= tpg->border.top + tpg->border.height)) {
2450                linestart_older = tpg->black_line[p];
2451                linestart_newer = tpg->black_line[p];
2452        } else if (tpg->pattern == TPG_PAT_NOISE || tpg->qual == TPG_QUAL_NOISE) {
2453                linestart_older = tpg->random_line[p] +
2454                                  twopixsize * prandom_u32_max(tpg->src_width / 2);
2455                linestart_newer = tpg->random_line[p] +
2456                                  twopixsize * prandom_u32_max(tpg->src_width / 2);
2457        } else {
2458                unsigned frame_line_old =
2459                        (frame_line + mv_vert_old) % tpg->src_height;
2460                unsigned frame_line_new =
2461                        (frame_line + mv_vert_new) % tpg->src_height;
2462                unsigned pat_line_next_old;
2463                unsigned pat_line_next_new;
2464
2465                pat_line_old = tpg_get_pat_line(tpg, frame_line_old);
2466                pat_line_new = tpg_get_pat_line(tpg, frame_line_new);
2467                linestart_older = tpg->lines[pat_line_old][p] + mv_hor_old;
2468                linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new;
2469
2470                if (tpg->vdownsampling[p] > 1 && frame_line != frame_line_next) {
2471                        int avg_pat;
2472
2473                        /*
2474                         * Now decide whether we need to use downsampled_lines[].
2475                         * That's necessary if the two lines use different patterns.
2476                         */
2477                        pat_line_next_old = tpg_get_pat_line(tpg,
2478                                        (frame_line_next + mv_vert_old) % tpg->src_height);
2479                        pat_line_next_new = tpg_get_pat_line(tpg,
2480                                        (frame_line_next + mv_vert_new) % tpg->src_height);
2481
2482                        switch (tpg->field) {
2483                        case V4L2_FIELD_INTERLACED:
2484                        case V4L2_FIELD_INTERLACED_BT:
2485                        case V4L2_FIELD_INTERLACED_TB:
2486                                avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_new);
2487                                if (avg_pat < 0)
2488                                        break;
2489                                linestart_older = tpg->downsampled_lines[avg_pat][p] + mv_hor_old;
2490                                linestart_newer = linestart_older;
2491                                break;
2492                        case V4L2_FIELD_NONE:
2493                        case V4L2_FIELD_TOP:
2494                        case V4L2_FIELD_BOTTOM:
2495                        case V4L2_FIELD_SEQ_BT:
2496                        case V4L2_FIELD_SEQ_TB:
2497                                avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_next_old);
2498                                if (avg_pat >= 0)
2499                                        linestart_older = tpg->downsampled_lines[avg_pat][p] +
2500                                                mv_hor_old;
2501                                avg_pat = tpg_pattern_avg(tpg, pat_line_new, pat_line_next_new);
2502                                if (avg_pat >= 0)
2503                                        linestart_newer = tpg->downsampled_lines[avg_pat][p] +
2504                                                mv_hor_new;
2505                                break;
2506                        }
2507                }
2508                linestart_older += line_offset;
2509                linestart_newer += line_offset;
2510        }
2511        if (tpg->field_alternate) {
2512                linestart_top = linestart_bottom = linestart_older;
2513        } else if (params->is_60hz) {
2514                linestart_top = linestart_newer;
2515                linestart_bottom = linestart_older;
2516        } else {
2517                linestart_top = linestart_older;
2518                linestart_bottom = linestart_newer;
2519        }
2520
2521        switch (tpg->field) {
2522        case V4L2_FIELD_INTERLACED:
2523        case V4L2_FIELD_INTERLACED_TB:
2524        case V4L2_FIELD_SEQ_TB:
2525        case V4L2_FIELD_SEQ_BT:
2526                if (even)
2527                        memcpy(vbuf, linestart_top, img_width);
2528                else
2529                        memcpy(vbuf, linestart_bottom, img_width);
2530                break;
2531        case V4L2_FIELD_INTERLACED_BT:
2532                if (even)
2533                        memcpy(vbuf, linestart_bottom, img_width);
2534                else
2535                        memcpy(vbuf, linestart_top, img_width);
2536                break;
2537        case V4L2_FIELD_TOP:
2538                memcpy(vbuf, linestart_top, img_width);
2539                break;
2540        case V4L2_FIELD_BOTTOM:
2541                memcpy(vbuf, linestart_bottom, img_width);
2542                break;
2543        case V4L2_FIELD_NONE:
2544        default:
2545                memcpy(vbuf, linestart_older, img_width);
2546                break;
2547        }
2548}
2549
2550void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
2551                           unsigned p, u8 *vbuf)
2552{
2553        struct tpg_draw_params params;
2554        unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
2555
2556        /* Coarse scaling with Bresenham */
2557        unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height;
2558        unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height;
2559        unsigned src_y = 0;
2560        unsigned error = 0;
2561        unsigned h;
2562
2563        tpg_recalc(tpg);
2564
2565        params.is_tv = std;
2566        params.is_60hz = std & V4L2_STD_525_60;
2567        params.twopixsize = tpg->twopixelsize[p];
2568        params.img_width = tpg_hdiv(tpg, p, tpg->compose.width);
2569        params.stride = tpg->bytesperline[p];
2570        params.hmax = (tpg->compose.height * tpg->perc_fill) / 100;
2571
2572        tpg_fill_params_pattern(tpg, p, &params);
2573        tpg_fill_params_extras(tpg, p, &params);
2574
2575        vbuf += tpg_hdiv(tpg, p, tpg->compose.left);
2576
2577        for (h = 0; h < tpg->compose.height; h++) {
2578                unsigned buf_line;
2579
2580                params.frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
2581                params.frame_line_next = params.frame_line;
2582                buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
2583                src_y += int_part;
2584                error += fract_part;
2585                if (error >= tpg->compose.height) {
2586                        error -= tpg->compose.height;
2587                        src_y++;
2588                }
2589
2590                /*
2591                 * For line-interleaved formats determine the 'plane'
2592                 * based on the buffer line.
2593                 */
2594                if (tpg_g_interleaved(tpg))
2595                        p = tpg_g_interleaved_plane(tpg, buf_line);
2596
2597                if (tpg->vdownsampling[p] > 1) {
2598                        /*
2599                         * When doing vertical downsampling the field setting
2600                         * matters: for SEQ_BT/TB we downsample each field
2601                         * separately (i.e. lines 0+2 are combined, as are
2602                         * lines 1+3), for the other field settings we combine
2603                         * odd and even lines. Doing that for SEQ_BT/TB would
2604                         * be really weird.
2605                         */
2606                        if (tpg->field == V4L2_FIELD_SEQ_BT ||
2607                            tpg->field == V4L2_FIELD_SEQ_TB) {
2608                                unsigned next_src_y = src_y;
2609
2610                                if ((h & 3) >= 2)
2611                                        continue;
2612                                next_src_y += int_part;
2613                                if (error + fract_part >= tpg->compose.height)
2614                                        next_src_y++;
2615                                params.frame_line_next =
2616                                        tpg_calc_frameline(tpg, next_src_y, tpg->field);
2617                        } else {
2618                                if (h & 1)
2619                                        continue;
2620                                params.frame_line_next =
2621                                        tpg_calc_frameline(tpg, src_y, tpg->field);
2622                        }
2623
2624                        buf_line /= tpg->vdownsampling[p];
2625                }
2626                tpg_fill_plane_pattern(tpg, &params, p, h,
2627                                vbuf + buf_line * params.stride);
2628                tpg_fill_plane_extras(tpg, &params, p, h,
2629                                vbuf + buf_line * params.stride);
2630        }
2631}
2632EXPORT_SYMBOL_GPL(tpg_fill_plane_buffer);
2633
2634void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
2635{
2636        unsigned offset = 0;
2637        unsigned i;
2638
2639        if (tpg->buffers > 1) {
2640                tpg_fill_plane_buffer(tpg, std, p, vbuf);
2641                return;
2642        }
2643
2644        for (i = 0; i < tpg_g_planes(tpg); i++) {
2645                tpg_fill_plane_buffer(tpg, std, i, vbuf + offset);
2646                offset += tpg_calc_plane_size(tpg, i);
2647        }
2648}
2649EXPORT_SYMBOL_GPL(tpg_fillbuffer);
2650
2651MODULE_DESCRIPTION("V4L2 Test Pattern Generator");
2652MODULE_AUTHOR("Hans Verkuil");
2653MODULE_LICENSE("GPL");
2654