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