Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * v4l2-tpg-core.c - Test Pattern Generator
0004  *
0005  * Note: gen_twopix and tpg_gen_text are based on code from vivi.c. See the
0006  * vivi.c source for the copyright information of those functions.
0007  *
0008  * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <media/tpg/v4l2-tpg.h>
0013 
0014 /* Must remain in sync with enum tpg_pattern */
0015 const char * const tpg_pattern_strings[] = {
0016     "75% Colorbar",
0017     "100% Colorbar",
0018     "CSC Colorbar",
0019     "Horizontal 100% Colorbar",
0020     "100% Color Squares",
0021     "100% Black",
0022     "100% White",
0023     "100% Red",
0024     "100% Green",
0025     "100% Blue",
0026     "16x16 Checkers",
0027     "2x2 Checkers",
0028     "1x1 Checkers",
0029     "2x2 Red/Green Checkers",
0030     "1x1 Red/Green Checkers",
0031     "Alternating Hor Lines",
0032     "Alternating Vert Lines",
0033     "One Pixel Wide Cross",
0034     "Two Pixels Wide Cross",
0035     "Ten Pixels Wide Cross",
0036     "Gray Ramp",
0037     "Noise",
0038     NULL
0039 };
0040 EXPORT_SYMBOL_GPL(tpg_pattern_strings);
0041 
0042 /* Must remain in sync with enum tpg_aspect */
0043 const char * const tpg_aspect_strings[] = {
0044     "Source Width x Height",
0045     "4x3",
0046     "14x9",
0047     "16x9",
0048     "16x9 Anamorphic",
0049     NULL
0050 };
0051 EXPORT_SYMBOL_GPL(tpg_aspect_strings);
0052 
0053 /*
0054  * Sine table: sin[0] = 127 * sin(-180 degrees)
0055  *             sin[128] = 127 * sin(0 degrees)
0056  *             sin[256] = 127 * sin(180 degrees)
0057  */
0058 static const s8 sin[257] = {
0059        0,   -4,   -7,  -11,  -13,  -18,  -20,  -22,  -26,  -29,  -33,  -35,  -37,  -41,  -43,  -48,
0060      -50,  -52,  -56,  -58,  -62,  -63,  -65,  -69,  -71,  -75,  -76,  -78,  -82,  -83,  -87,  -88,
0061      -90,  -93,  -94,  -97,  -99, -101, -103, -104, -107, -108, -110, -111, -112, -114, -115, -117,
0062     -118, -119, -120, -121, -122, -123, -123, -124, -125, -125, -126, -126, -127, -127, -127, -127,
0063     -127, -127, -127, -127, -126, -126, -125, -125, -124, -124, -123, -122, -121, -120, -119, -118,
0064     -117, -116, -114, -113, -111, -110, -109, -107, -105, -103, -101, -100,  -97,  -96,  -93,  -91,
0065      -90,  -87,  -85,  -82,  -80,  -76,  -75,  -73,  -69,  -67,  -63,  -62,  -60,  -56,  -54,  -50,
0066      -48,  -46,  -41,  -39,  -35,  -33,  -31,  -26,  -24,  -20,  -18,  -15,  -11,   -9,   -4,   -2,
0067        0,    2,    4,    9,   11,   15,   18,   20,   24,   26,   31,   33,   35,   39,   41,   46,
0068       48,   50,   54,   56,   60,   62,   64,   67,   69,   73,   75,   76,   80,   82,   85,   87,
0069       90,   91,   93,   96,   97,  100,  101,  103,  105,  107,  109,  110,  111,  113,  114,  116,
0070      117,  118,  119,  120,  121,  122,  123,  124,  124,  125,  125,  126,  126,  127,  127,  127,
0071      127,  127,  127,  127,  127,  126,  126,  125,  125,  124,  123,  123,  122,  121,  120,  119,
0072      118,  117,  115,  114,  112,  111,  110,  108,  107,  104,  103,  101,   99,   97,   94,   93,
0073       90,   88,   87,   83,   82,   78,   76,   75,   71,   69,   65,   64,   62,   58,   56,   52,
0074       50,   48,   43,   41,   37,   35,   33,   29,   26,   22,   20,   18,   13,   11,    7,    4,
0075        0,
0076 };
0077 
0078 #define cos(idx) sin[((idx) + 64) % sizeof(sin)]
0079 
0080 /* Global font descriptor */
0081 static const u8 *font8x16;
0082 
0083 void tpg_set_font(const u8 *f)
0084 {
0085     font8x16 = f;
0086 }
0087 EXPORT_SYMBOL_GPL(tpg_set_font);
0088 
0089 void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h)
0090 {
0091     memset(tpg, 0, sizeof(*tpg));
0092     tpg->scaled_width = tpg->src_width = w;
0093     tpg->src_height = tpg->buf_height = h;
0094     tpg->crop.width = tpg->compose.width = w;
0095     tpg->crop.height = tpg->compose.height = h;
0096     tpg->recalc_colors = true;
0097     tpg->recalc_square_border = true;
0098     tpg->brightness = 128;
0099     tpg->contrast = 128;
0100     tpg->saturation = 128;
0101     tpg->hue = 0;
0102     tpg->mv_hor_mode = TPG_MOVE_NONE;
0103     tpg->mv_vert_mode = TPG_MOVE_NONE;
0104     tpg->field = V4L2_FIELD_NONE;
0105     tpg_s_fourcc(tpg, V4L2_PIX_FMT_RGB24);
0106     tpg->colorspace = V4L2_COLORSPACE_SRGB;
0107     tpg->perc_fill = 100;
0108     tpg->hsv_enc = V4L2_HSV_ENC_180;
0109 }
0110 EXPORT_SYMBOL_GPL(tpg_init);
0111 
0112 int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
0113 {
0114     unsigned pat;
0115     unsigned plane;
0116 
0117     tpg->max_line_width = max_w;
0118     for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
0119         for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
0120             unsigned pixelsz = plane ? 2 : 4;
0121 
0122             tpg->lines[pat][plane] =
0123                 vzalloc(array3_size(max_w, 2, pixelsz));
0124             if (!tpg->lines[pat][plane])
0125                 return -ENOMEM;
0126             if (plane == 0)
0127                 continue;
0128             tpg->downsampled_lines[pat][plane] =
0129                 vzalloc(array3_size(max_w, 2, pixelsz));
0130             if (!tpg->downsampled_lines[pat][plane])
0131                 return -ENOMEM;
0132         }
0133     }
0134     for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
0135         unsigned pixelsz = plane ? 2 : 4;
0136 
0137         tpg->contrast_line[plane] =
0138             vzalloc(array_size(pixelsz, max_w));
0139         if (!tpg->contrast_line[plane])
0140             return -ENOMEM;
0141         tpg->black_line[plane] =
0142             vzalloc(array_size(pixelsz, max_w));
0143         if (!tpg->black_line[plane])
0144             return -ENOMEM;
0145         tpg->random_line[plane] =
0146             vzalloc(array3_size(max_w, 2, pixelsz));
0147         if (!tpg->random_line[plane])
0148             return -ENOMEM;
0149     }
0150     return 0;
0151 }
0152 EXPORT_SYMBOL_GPL(tpg_alloc);
0153 
0154 void tpg_free(struct tpg_data *tpg)
0155 {
0156     unsigned pat;
0157     unsigned plane;
0158 
0159     for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
0160         for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
0161             vfree(tpg->lines[pat][plane]);
0162             tpg->lines[pat][plane] = NULL;
0163             if (plane == 0)
0164                 continue;
0165             vfree(tpg->downsampled_lines[pat][plane]);
0166             tpg->downsampled_lines[pat][plane] = NULL;
0167         }
0168     for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
0169         vfree(tpg->contrast_line[plane]);
0170         vfree(tpg->black_line[plane]);
0171         vfree(tpg->random_line[plane]);
0172         tpg->contrast_line[plane] = NULL;
0173         tpg->black_line[plane] = NULL;
0174         tpg->random_line[plane] = NULL;
0175     }
0176 }
0177 EXPORT_SYMBOL_GPL(tpg_free);
0178 
0179 bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
0180 {
0181     tpg->fourcc = fourcc;
0182     tpg->planes = 1;
0183     tpg->buffers = 1;
0184     tpg->recalc_colors = true;
0185     tpg->interleaved = false;
0186     tpg->vdownsampling[0] = 1;
0187     tpg->hdownsampling[0] = 1;
0188     tpg->hmask[0] = ~0;
0189     tpg->hmask[1] = ~0;
0190     tpg->hmask[2] = ~0;
0191 
0192     switch (fourcc) {
0193     case V4L2_PIX_FMT_SBGGR8:
0194     case V4L2_PIX_FMT_SGBRG8:
0195     case V4L2_PIX_FMT_SGRBG8:
0196     case V4L2_PIX_FMT_SRGGB8:
0197     case V4L2_PIX_FMT_SBGGR10:
0198     case V4L2_PIX_FMT_SGBRG10:
0199     case V4L2_PIX_FMT_SGRBG10:
0200     case V4L2_PIX_FMT_SRGGB10:
0201     case V4L2_PIX_FMT_SBGGR12:
0202     case V4L2_PIX_FMT_SGBRG12:
0203     case V4L2_PIX_FMT_SGRBG12:
0204     case V4L2_PIX_FMT_SRGGB12:
0205     case V4L2_PIX_FMT_SBGGR16:
0206     case V4L2_PIX_FMT_SGBRG16:
0207     case V4L2_PIX_FMT_SGRBG16:
0208     case V4L2_PIX_FMT_SRGGB16:
0209         tpg->interleaved = true;
0210         tpg->vdownsampling[1] = 1;
0211         tpg->hdownsampling[1] = 1;
0212         tpg->planes = 2;
0213         fallthrough;
0214     case V4L2_PIX_FMT_RGB332:
0215     case V4L2_PIX_FMT_RGB565:
0216     case V4L2_PIX_FMT_RGB565X:
0217     case V4L2_PIX_FMT_RGB444:
0218     case V4L2_PIX_FMT_XRGB444:
0219     case V4L2_PIX_FMT_ARGB444:
0220     case V4L2_PIX_FMT_RGBX444:
0221     case V4L2_PIX_FMT_RGBA444:
0222     case V4L2_PIX_FMT_XBGR444:
0223     case V4L2_PIX_FMT_ABGR444:
0224     case V4L2_PIX_FMT_BGRX444:
0225     case V4L2_PIX_FMT_BGRA444:
0226     case V4L2_PIX_FMT_RGB555:
0227     case V4L2_PIX_FMT_XRGB555:
0228     case V4L2_PIX_FMT_ARGB555:
0229     case V4L2_PIX_FMT_RGBX555:
0230     case V4L2_PIX_FMT_RGBA555:
0231     case V4L2_PIX_FMT_XBGR555:
0232     case V4L2_PIX_FMT_ABGR555:
0233     case V4L2_PIX_FMT_BGRX555:
0234     case V4L2_PIX_FMT_BGRA555:
0235     case V4L2_PIX_FMT_RGB555X:
0236     case V4L2_PIX_FMT_XRGB555X:
0237     case V4L2_PIX_FMT_ARGB555X:
0238     case V4L2_PIX_FMT_BGR666:
0239     case V4L2_PIX_FMT_RGB24:
0240     case V4L2_PIX_FMT_BGR24:
0241     case V4L2_PIX_FMT_RGB32:
0242     case V4L2_PIX_FMT_BGR32:
0243     case V4L2_PIX_FMT_XRGB32:
0244     case V4L2_PIX_FMT_XBGR32:
0245     case V4L2_PIX_FMT_ARGB32:
0246     case V4L2_PIX_FMT_ABGR32:
0247     case V4L2_PIX_FMT_RGBX32:
0248     case V4L2_PIX_FMT_BGRX32:
0249     case V4L2_PIX_FMT_RGBA32:
0250     case V4L2_PIX_FMT_BGRA32:
0251         tpg->color_enc = TGP_COLOR_ENC_RGB;
0252         break;
0253     case V4L2_PIX_FMT_GREY:
0254     case V4L2_PIX_FMT_Y10:
0255     case V4L2_PIX_FMT_Y12:
0256     case V4L2_PIX_FMT_Y16:
0257     case V4L2_PIX_FMT_Y16_BE:
0258     case V4L2_PIX_FMT_Z16:
0259         tpg->color_enc = TGP_COLOR_ENC_LUMA;
0260         break;
0261     case V4L2_PIX_FMT_YUV444:
0262     case V4L2_PIX_FMT_YUV555:
0263     case V4L2_PIX_FMT_YUV565:
0264     case V4L2_PIX_FMT_YUV32:
0265     case V4L2_PIX_FMT_AYUV32:
0266     case V4L2_PIX_FMT_XYUV32:
0267     case V4L2_PIX_FMT_VUYA32:
0268     case V4L2_PIX_FMT_VUYX32:
0269     case V4L2_PIX_FMT_YUVA32:
0270     case V4L2_PIX_FMT_YUVX32:
0271         tpg->color_enc = TGP_COLOR_ENC_YCBCR;
0272         break;
0273     case V4L2_PIX_FMT_YUV420M:
0274     case V4L2_PIX_FMT_YVU420M:
0275         tpg->buffers = 3;
0276         fallthrough;
0277     case V4L2_PIX_FMT_YUV420:
0278     case V4L2_PIX_FMT_YVU420:
0279         tpg->vdownsampling[1] = 2;
0280         tpg->vdownsampling[2] = 2;
0281         tpg->hdownsampling[1] = 2;
0282         tpg->hdownsampling[2] = 2;
0283         tpg->planes = 3;
0284         tpg->color_enc = TGP_COLOR_ENC_YCBCR;
0285         break;
0286     case V4L2_PIX_FMT_YUV422M:
0287     case V4L2_PIX_FMT_YVU422M:
0288         tpg->buffers = 3;
0289         fallthrough;
0290     case V4L2_PIX_FMT_YUV422P:
0291         tpg->vdownsampling[1] = 1;
0292         tpg->vdownsampling[2] = 1;
0293         tpg->hdownsampling[1] = 2;
0294         tpg->hdownsampling[2] = 2;
0295         tpg->planes = 3;
0296         tpg->color_enc = TGP_COLOR_ENC_YCBCR;
0297         break;
0298     case V4L2_PIX_FMT_NV16M:
0299     case V4L2_PIX_FMT_NV61M:
0300         tpg->buffers = 2;
0301         fallthrough;
0302     case V4L2_PIX_FMT_NV16:
0303     case V4L2_PIX_FMT_NV61:
0304         tpg->vdownsampling[1] = 1;
0305         tpg->hdownsampling[1] = 1;
0306         tpg->hmask[1] = ~1;
0307         tpg->planes = 2;
0308         tpg->color_enc = TGP_COLOR_ENC_YCBCR;
0309         break;
0310     case V4L2_PIX_FMT_NV12M:
0311     case V4L2_PIX_FMT_NV21M:
0312         tpg->buffers = 2;
0313         fallthrough;
0314     case V4L2_PIX_FMT_NV12:
0315     case V4L2_PIX_FMT_NV21:
0316         tpg->vdownsampling[1] = 2;
0317         tpg->hdownsampling[1] = 1;
0318         tpg->hmask[1] = ~1;
0319         tpg->planes = 2;
0320         tpg->color_enc = TGP_COLOR_ENC_YCBCR;
0321         break;
0322     case V4L2_PIX_FMT_YUV444M:
0323     case V4L2_PIX_FMT_YVU444M:
0324         tpg->buffers = 3;
0325         tpg->planes = 3;
0326         tpg->vdownsampling[1] = 1;
0327         tpg->vdownsampling[2] = 1;
0328         tpg->hdownsampling[1] = 1;
0329         tpg->hdownsampling[2] = 1;
0330         tpg->color_enc = TGP_COLOR_ENC_YCBCR;
0331         break;
0332     case V4L2_PIX_FMT_NV24:
0333     case V4L2_PIX_FMT_NV42:
0334         tpg->vdownsampling[1] = 1;
0335         tpg->hdownsampling[1] = 1;
0336         tpg->planes = 2;
0337         tpg->color_enc = TGP_COLOR_ENC_YCBCR;
0338         break;
0339     case V4L2_PIX_FMT_YUYV:
0340     case V4L2_PIX_FMT_UYVY:
0341     case V4L2_PIX_FMT_YVYU:
0342     case V4L2_PIX_FMT_VYUY:
0343         tpg->hmask[0] = ~1;
0344         tpg->color_enc = TGP_COLOR_ENC_YCBCR;
0345         break;
0346     case V4L2_PIX_FMT_HSV24:
0347     case V4L2_PIX_FMT_HSV32:
0348         tpg->color_enc = TGP_COLOR_ENC_HSV;
0349         break;
0350     default:
0351         return false;
0352     }
0353 
0354     switch (fourcc) {
0355     case V4L2_PIX_FMT_GREY:
0356     case V4L2_PIX_FMT_RGB332:
0357         tpg->twopixelsize[0] = 2;
0358         break;
0359     case V4L2_PIX_FMT_RGB565:
0360     case V4L2_PIX_FMT_RGB565X:
0361     case V4L2_PIX_FMT_RGB444:
0362     case V4L2_PIX_FMT_XRGB444:
0363     case V4L2_PIX_FMT_ARGB444:
0364     case V4L2_PIX_FMT_RGBX444:
0365     case V4L2_PIX_FMT_RGBA444:
0366     case V4L2_PIX_FMT_XBGR444:
0367     case V4L2_PIX_FMT_ABGR444:
0368     case V4L2_PIX_FMT_BGRX444:
0369     case V4L2_PIX_FMT_BGRA444:
0370     case V4L2_PIX_FMT_RGB555:
0371     case V4L2_PIX_FMT_XRGB555:
0372     case V4L2_PIX_FMT_ARGB555:
0373     case V4L2_PIX_FMT_RGBX555:
0374     case V4L2_PIX_FMT_RGBA555:
0375     case V4L2_PIX_FMT_XBGR555:
0376     case V4L2_PIX_FMT_ABGR555:
0377     case V4L2_PIX_FMT_BGRX555:
0378     case V4L2_PIX_FMT_BGRA555:
0379     case V4L2_PIX_FMT_RGB555X:
0380     case V4L2_PIX_FMT_XRGB555X:
0381     case V4L2_PIX_FMT_ARGB555X:
0382     case V4L2_PIX_FMT_YUYV:
0383     case V4L2_PIX_FMT_UYVY:
0384     case V4L2_PIX_FMT_YVYU:
0385     case V4L2_PIX_FMT_VYUY:
0386     case V4L2_PIX_FMT_YUV444:
0387     case V4L2_PIX_FMT_YUV555:
0388     case V4L2_PIX_FMT_YUV565:
0389     case V4L2_PIX_FMT_Y10:
0390     case V4L2_PIX_FMT_Y12:
0391     case V4L2_PIX_FMT_Y16:
0392     case V4L2_PIX_FMT_Y16_BE:
0393     case V4L2_PIX_FMT_Z16:
0394         tpg->twopixelsize[0] = 2 * 2;
0395         break;
0396     case V4L2_PIX_FMT_RGB24:
0397     case V4L2_PIX_FMT_BGR24:
0398     case V4L2_PIX_FMT_HSV24:
0399         tpg->twopixelsize[0] = 2 * 3;
0400         break;
0401     case V4L2_PIX_FMT_BGR666:
0402     case V4L2_PIX_FMT_RGB32:
0403     case V4L2_PIX_FMT_BGR32:
0404     case V4L2_PIX_FMT_XRGB32:
0405     case V4L2_PIX_FMT_XBGR32:
0406     case V4L2_PIX_FMT_ARGB32:
0407     case V4L2_PIX_FMT_ABGR32:
0408     case V4L2_PIX_FMT_RGBX32:
0409     case V4L2_PIX_FMT_BGRX32:
0410     case V4L2_PIX_FMT_RGBA32:
0411     case V4L2_PIX_FMT_BGRA32:
0412     case V4L2_PIX_FMT_YUV32:
0413     case V4L2_PIX_FMT_AYUV32:
0414     case V4L2_PIX_FMT_XYUV32:
0415     case V4L2_PIX_FMT_VUYA32:
0416     case V4L2_PIX_FMT_VUYX32:
0417     case V4L2_PIX_FMT_YUVA32:
0418     case V4L2_PIX_FMT_YUVX32:
0419     case V4L2_PIX_FMT_HSV32:
0420         tpg->twopixelsize[0] = 2 * 4;
0421         break;
0422     case V4L2_PIX_FMT_NV12:
0423     case V4L2_PIX_FMT_NV21:
0424     case V4L2_PIX_FMT_NV12M:
0425     case V4L2_PIX_FMT_NV21M:
0426     case V4L2_PIX_FMT_NV16:
0427     case V4L2_PIX_FMT_NV61:
0428     case V4L2_PIX_FMT_NV16M:
0429     case V4L2_PIX_FMT_NV61M:
0430     case V4L2_PIX_FMT_SBGGR8:
0431     case V4L2_PIX_FMT_SGBRG8:
0432     case V4L2_PIX_FMT_SGRBG8:
0433     case V4L2_PIX_FMT_SRGGB8:
0434         tpg->twopixelsize[0] = 2;
0435         tpg->twopixelsize[1] = 2;
0436         break;
0437     case V4L2_PIX_FMT_SRGGB10:
0438     case V4L2_PIX_FMT_SGRBG10:
0439     case V4L2_PIX_FMT_SGBRG10:
0440     case V4L2_PIX_FMT_SBGGR10:
0441     case V4L2_PIX_FMT_SRGGB12:
0442     case V4L2_PIX_FMT_SGRBG12:
0443     case V4L2_PIX_FMT_SGBRG12:
0444     case V4L2_PIX_FMT_SBGGR12:
0445     case V4L2_PIX_FMT_SRGGB16:
0446     case V4L2_PIX_FMT_SGRBG16:
0447     case V4L2_PIX_FMT_SGBRG16:
0448     case V4L2_PIX_FMT_SBGGR16:
0449         tpg->twopixelsize[0] = 4;
0450         tpg->twopixelsize[1] = 4;
0451         break;
0452     case V4L2_PIX_FMT_YUV444M:
0453     case V4L2_PIX_FMT_YVU444M:
0454     case V4L2_PIX_FMT_YUV422M:
0455     case V4L2_PIX_FMT_YVU422M:
0456     case V4L2_PIX_FMT_YUV422P:
0457     case V4L2_PIX_FMT_YUV420:
0458     case V4L2_PIX_FMT_YVU420:
0459     case V4L2_PIX_FMT_YUV420M:
0460     case V4L2_PIX_FMT_YVU420M:
0461         tpg->twopixelsize[0] = 2;
0462         tpg->twopixelsize[1] = 2;
0463         tpg->twopixelsize[2] = 2;
0464         break;
0465     case V4L2_PIX_FMT_NV24:
0466     case V4L2_PIX_FMT_NV42:
0467         tpg->twopixelsize[0] = 2;
0468         tpg->twopixelsize[1] = 4;
0469         break;
0470     }
0471     return true;
0472 }
0473 EXPORT_SYMBOL_GPL(tpg_s_fourcc);
0474 
0475 void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
0476         const struct v4l2_rect *compose)
0477 {
0478     tpg->crop = *crop;
0479     tpg->compose = *compose;
0480     tpg->scaled_width = (tpg->src_width * tpg->compose.width +
0481                  tpg->crop.width - 1) / tpg->crop.width;
0482     tpg->scaled_width &= ~1;
0483     if (tpg->scaled_width > tpg->max_line_width)
0484         tpg->scaled_width = tpg->max_line_width;
0485     if (tpg->scaled_width < 2)
0486         tpg->scaled_width = 2;
0487     tpg->recalc_lines = true;
0488 }
0489 EXPORT_SYMBOL_GPL(tpg_s_crop_compose);
0490 
0491 void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
0492                u32 field)
0493 {
0494     unsigned p;
0495 
0496     tpg->src_width = width;
0497     tpg->src_height = height;
0498     tpg->field = field;
0499     tpg->buf_height = height;
0500     if (V4L2_FIELD_HAS_T_OR_B(field))
0501         tpg->buf_height /= 2;
0502     tpg->scaled_width = width;
0503     tpg->crop.top = tpg->crop.left = 0;
0504     tpg->crop.width = width;
0505     tpg->crop.height = height;
0506     tpg->compose.top = tpg->compose.left = 0;
0507     tpg->compose.width = width;
0508     tpg->compose.height = tpg->buf_height;
0509     for (p = 0; p < tpg->planes; p++)
0510         tpg->bytesperline[p] = (width * tpg->twopixelsize[p]) /
0511                        (2 * tpg->hdownsampling[p]);
0512     tpg->recalc_square_border = true;
0513 }
0514 EXPORT_SYMBOL_GPL(tpg_reset_source);
0515 
0516 static enum tpg_color tpg_get_textbg_color(struct tpg_data *tpg)
0517 {
0518     switch (tpg->pattern) {
0519     case TPG_PAT_BLACK:
0520         return TPG_COLOR_100_WHITE;
0521     case TPG_PAT_CSC_COLORBAR:
0522         return TPG_COLOR_CSC_BLACK;
0523     default:
0524         return TPG_COLOR_100_BLACK;
0525     }
0526 }
0527 
0528 static enum tpg_color tpg_get_textfg_color(struct tpg_data *tpg)
0529 {
0530     switch (tpg->pattern) {
0531     case TPG_PAT_75_COLORBAR:
0532     case TPG_PAT_CSC_COLORBAR:
0533         return TPG_COLOR_CSC_WHITE;
0534     case TPG_PAT_BLACK:
0535         return TPG_COLOR_100_BLACK;
0536     default:
0537         return TPG_COLOR_100_WHITE;
0538     }
0539 }
0540 
0541 static inline int rec709_to_linear(int v)
0542 {
0543     v = clamp(v, 0, 0xff0);
0544     return tpg_rec709_to_linear[v];
0545 }
0546 
0547 static inline int linear_to_rec709(int v)
0548 {
0549     v = clamp(v, 0, 0xff0);
0550     return tpg_linear_to_rec709[v];
0551 }
0552 
0553 static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b,
0554                int *h, int *s, int *v)
0555 {
0556     int max_rgb, min_rgb, diff_rgb;
0557     int aux;
0558     int third;
0559     int third_size;
0560 
0561     r >>= 4;
0562     g >>= 4;
0563     b >>= 4;
0564 
0565     /* Value */
0566     max_rgb = max3(r, g, b);
0567     *v = max_rgb;
0568     if (!max_rgb) {
0569         *h = 0;
0570         *s = 0;
0571         return;
0572     }
0573 
0574     /* Saturation */
0575     min_rgb = min3(r, g, b);
0576     diff_rgb = max_rgb - min_rgb;
0577     aux = 255 * diff_rgb;
0578     aux += max_rgb / 2;
0579     aux /= max_rgb;
0580     *s = aux;
0581     if (!aux) {
0582         *h = 0;
0583         return;
0584     }
0585 
0586     third_size = (tpg->real_hsv_enc == V4L2_HSV_ENC_180) ? 60 : 85;
0587 
0588     /* Hue */
0589     if (max_rgb == r) {
0590         aux =  g - b;
0591         third = 0;
0592     } else if (max_rgb == g) {
0593         aux =  b - r;
0594         third = third_size;
0595     } else {
0596         aux =  r - g;
0597         third = third_size * 2;
0598     }
0599 
0600     aux *= third_size / 2;
0601     aux += diff_rgb / 2;
0602     aux /= diff_rgb;
0603     aux += third;
0604 
0605     /* Clamp Hue */
0606     if (tpg->real_hsv_enc == V4L2_HSV_ENC_180) {
0607         if (aux < 0)
0608             aux += 180;
0609         else if (aux > 180)
0610             aux -= 180;
0611     } else {
0612         aux = aux & 0xff;
0613     }
0614 
0615     *h = aux;
0616 }
0617 
0618 static void rgb2ycbcr(const int m[3][3], int r, int g, int b,
0619             int y_offset, int *y, int *cb, int *cr)
0620 {
0621     *y  = ((m[0][0] * r + m[0][1] * g + m[0][2] * b) >> 16) + (y_offset << 4);
0622     *cb = ((m[1][0] * r + m[1][1] * g + m[1][2] * b) >> 16) + (128 << 4);
0623     *cr = ((m[2][0] * r + m[2][1] * g + m[2][2] * b) >> 16) + (128 << 4);
0624 }
0625 
0626 static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b,
0627                int *y, int *cb, int *cr)
0628 {
0629 #define COEFF(v, r) ((int)(0.5 + (v) * (r) * 256.0))
0630 
0631     static const int bt601[3][3] = {
0632         { COEFF(0.299, 219),   COEFF(0.587, 219),   COEFF(0.114, 219)   },
0633         { COEFF(-0.1687, 224), COEFF(-0.3313, 224), COEFF(0.5, 224)     },
0634         { COEFF(0.5, 224),     COEFF(-0.4187, 224), COEFF(-0.0813, 224) },
0635     };
0636     static const int bt601_full[3][3] = {
0637         { COEFF(0.299, 255),   COEFF(0.587, 255),   COEFF(0.114, 255)   },
0638         { COEFF(-0.1687, 255), COEFF(-0.3313, 255), COEFF(0.5, 255)     },
0639         { COEFF(0.5, 255),     COEFF(-0.4187, 255), COEFF(-0.0813, 255) },
0640     };
0641     static const int rec709[3][3] = {
0642         { COEFF(0.2126, 219),  COEFF(0.7152, 219),  COEFF(0.0722, 219)  },
0643         { COEFF(-0.1146, 224), COEFF(-0.3854, 224), COEFF(0.5, 224)     },
0644         { COEFF(0.5, 224),     COEFF(-0.4542, 224), COEFF(-0.0458, 224) },
0645     };
0646     static const int rec709_full[3][3] = {
0647         { COEFF(0.2126, 255),  COEFF(0.7152, 255),  COEFF(0.0722, 255)  },
0648         { COEFF(-0.1146, 255), COEFF(-0.3854, 255), COEFF(0.5, 255)     },
0649         { COEFF(0.5, 255),     COEFF(-0.4542, 255), COEFF(-0.0458, 255) },
0650     };
0651     static const int smpte240m[3][3] = {
0652         { COEFF(0.212, 219),  COEFF(0.701, 219),  COEFF(0.087, 219)  },
0653         { COEFF(-0.116, 224), COEFF(-0.384, 224), COEFF(0.5, 224)    },
0654         { COEFF(0.5, 224),    COEFF(-0.445, 224), COEFF(-0.055, 224) },
0655     };
0656     static const int smpte240m_full[3][3] = {
0657         { COEFF(0.212, 255),  COEFF(0.701, 255),  COEFF(0.087, 255)  },
0658         { COEFF(-0.116, 255), COEFF(-0.384, 255), COEFF(0.5, 255)    },
0659         { COEFF(0.5, 255),    COEFF(-0.445, 255), COEFF(-0.055, 255) },
0660     };
0661     static const int bt2020[3][3] = {
0662         { COEFF(0.2627, 219),  COEFF(0.6780, 219),  COEFF(0.0593, 219)  },
0663         { COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224)     },
0664         { COEFF(0.5, 224),     COEFF(-0.4598, 224), COEFF(-0.0402, 224) },
0665     };
0666     static const int bt2020_full[3][3] = {
0667         { COEFF(0.2627, 255),  COEFF(0.6780, 255),  COEFF(0.0593, 255)  },
0668         { COEFF(-0.1396, 255), COEFF(-0.3604, 255), COEFF(0.5, 255)     },
0669         { COEFF(0.5, 255),     COEFF(-0.4598, 255), COEFF(-0.0402, 255) },
0670     };
0671     static const int bt2020c[4] = {
0672         COEFF(1.0 / 1.9404, 224), COEFF(1.0 / 1.5816, 224),
0673         COEFF(1.0 / 1.7184, 224), COEFF(1.0 / 0.9936, 224),
0674     };
0675     static const int bt2020c_full[4] = {
0676         COEFF(1.0 / 1.9404, 255), COEFF(1.0 / 1.5816, 255),
0677         COEFF(1.0 / 1.7184, 255), COEFF(1.0 / 0.9936, 255),
0678     };
0679 
0680     bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
0681     unsigned y_offset = full ? 0 : 16;
0682     int lin_y, yc;
0683 
0684     switch (tpg->real_ycbcr_enc) {
0685     case V4L2_YCBCR_ENC_601:
0686         rgb2ycbcr(full ? bt601_full : bt601, r, g, b, y_offset, y, cb, cr);
0687         break;
0688     case V4L2_YCBCR_ENC_XV601:
0689         /* Ignore quantization range, there is only one possible
0690          * Y'CbCr encoding. */
0691         rgb2ycbcr(bt601, r, g, b, 16, y, cb, cr);
0692         break;
0693     case V4L2_YCBCR_ENC_XV709:
0694         /* Ignore quantization range, there is only one possible
0695          * Y'CbCr encoding. */
0696         rgb2ycbcr(rec709, r, g, b, 16, y, cb, cr);
0697         break;
0698     case V4L2_YCBCR_ENC_BT2020:
0699         rgb2ycbcr(full ? bt2020_full : bt2020, r, g, b, y_offset, y, cb, cr);
0700         break;
0701     case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
0702         lin_y = (COEFF(0.2627, 255) * rec709_to_linear(r) +
0703              COEFF(0.6780, 255) * rec709_to_linear(g) +
0704              COEFF(0.0593, 255) * rec709_to_linear(b)) >> 16;
0705         yc = linear_to_rec709(lin_y);
0706         *y = full ? yc : (yc * 219) / 255 + (16 << 4);
0707         if (b <= yc)
0708             *cb = (((b - yc) * (full ? bt2020c_full[0] : bt2020c[0])) >> 16) + (128 << 4);
0709         else
0710             *cb = (((b - yc) * (full ? bt2020c_full[1] : bt2020c[1])) >> 16) + (128 << 4);
0711         if (r <= yc)
0712             *cr = (((r - yc) * (full ? bt2020c_full[2] : bt2020c[2])) >> 16) + (128 << 4);
0713         else
0714             *cr = (((r - yc) * (full ? bt2020c_full[3] : bt2020c[3])) >> 16) + (128 << 4);
0715         break;
0716     case V4L2_YCBCR_ENC_SMPTE240M:
0717         rgb2ycbcr(full ? smpte240m_full : smpte240m, r, g, b, y_offset, y, cb, cr);
0718         break;
0719     case V4L2_YCBCR_ENC_709:
0720     default:
0721         rgb2ycbcr(full ? rec709_full : rec709, r, g, b, y_offset, y, cb, cr);
0722         break;
0723     }
0724 }
0725 
0726 static void ycbcr2rgb(const int m[3][3], int y, int cb, int cr,
0727             int y_offset, int *r, int *g, int *b)
0728 {
0729     y -= y_offset << 4;
0730     cb -= 128 << 4;
0731     cr -= 128 << 4;
0732     *r = m[0][0] * y + m[0][1] * cb + m[0][2] * cr;
0733     *g = m[1][0] * y + m[1][1] * cb + m[1][2] * cr;
0734     *b = m[2][0] * y + m[2][1] * cb + m[2][2] * cr;
0735     *r = clamp(*r >> 12, 0, 0xff0);
0736     *g = clamp(*g >> 12, 0, 0xff0);
0737     *b = clamp(*b >> 12, 0, 0xff0);
0738 }
0739 
0740 static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr,
0741                int *r, int *g, int *b)
0742 {
0743 #undef COEFF
0744 #define COEFF(v, r) ((int)(0.5 + (v) * ((255.0 * 255.0 * 16.0) / (r))))
0745     static const int bt601[3][3] = {
0746         { COEFF(1, 219), COEFF(0, 224),       COEFF(1.4020, 224)  },
0747         { COEFF(1, 219), COEFF(-0.3441, 224), COEFF(-0.7141, 224) },
0748         { COEFF(1, 219), COEFF(1.7720, 224),  COEFF(0, 224)       },
0749     };
0750     static const int bt601_full[3][3] = {
0751         { COEFF(1, 255), COEFF(0, 255),       COEFF(1.4020, 255)  },
0752         { COEFF(1, 255), COEFF(-0.3441, 255), COEFF(-0.7141, 255) },
0753         { COEFF(1, 255), COEFF(1.7720, 255),  COEFF(0, 255)       },
0754     };
0755     static const int rec709[3][3] = {
0756         { COEFF(1, 219), COEFF(0, 224),       COEFF(1.5748, 224)  },
0757         { COEFF(1, 219), COEFF(-0.1873, 224), COEFF(-0.4681, 224) },
0758         { COEFF(1, 219), COEFF(1.8556, 224),  COEFF(0, 224)       },
0759     };
0760     static const int rec709_full[3][3] = {
0761         { COEFF(1, 255), COEFF(0, 255),       COEFF(1.5748, 255)  },
0762         { COEFF(1, 255), COEFF(-0.1873, 255), COEFF(-0.4681, 255) },
0763         { COEFF(1, 255), COEFF(1.8556, 255),  COEFF(0, 255)       },
0764     };
0765     static const int smpte240m[3][3] = {
0766         { COEFF(1, 219), COEFF(0, 224),       COEFF(1.5756, 224)  },
0767         { COEFF(1, 219), COEFF(-0.2253, 224), COEFF(-0.4767, 224) },
0768         { COEFF(1, 219), COEFF(1.8270, 224),  COEFF(0, 224)       },
0769     };
0770     static const int smpte240m_full[3][3] = {
0771         { COEFF(1, 255), COEFF(0, 255),       COEFF(1.5756, 255)  },
0772         { COEFF(1, 255), COEFF(-0.2253, 255), COEFF(-0.4767, 255) },
0773         { COEFF(1, 255), COEFF(1.8270, 255),  COEFF(0, 255)       },
0774     };
0775     static const int bt2020[3][3] = {
0776         { COEFF(1, 219), COEFF(0, 224),       COEFF(1.4746, 224)  },
0777         { COEFF(1, 219), COEFF(-0.1646, 224), COEFF(-0.5714, 224) },
0778         { COEFF(1, 219), COEFF(1.8814, 224),  COEFF(0, 224)       },
0779     };
0780     static const int bt2020_full[3][3] = {
0781         { COEFF(1, 255), COEFF(0, 255),       COEFF(1.4746, 255)  },
0782         { COEFF(1, 255), COEFF(-0.1646, 255), COEFF(-0.5714, 255) },
0783         { COEFF(1, 255), COEFF(1.8814, 255),  COEFF(0, 255)       },
0784     };
0785     static const int bt2020c[4] = {
0786         COEFF(1.9404, 224), COEFF(1.5816, 224),
0787         COEFF(1.7184, 224), COEFF(0.9936, 224),
0788     };
0789     static const int bt2020c_full[4] = {
0790         COEFF(1.9404, 255), COEFF(1.5816, 255),
0791         COEFF(1.7184, 255), COEFF(0.9936, 255),
0792     };
0793 
0794     bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
0795     unsigned y_offset = full ? 0 : 16;
0796     int y_fac = full ? COEFF(1.0, 255) : COEFF(1.0, 219);
0797     int lin_r, lin_g, lin_b, lin_y;
0798 
0799     switch (tpg->real_ycbcr_enc) {
0800     case V4L2_YCBCR_ENC_601:
0801         ycbcr2rgb(full ? bt601_full : bt601, y, cb, cr, y_offset, r, g, b);
0802         break;
0803     case V4L2_YCBCR_ENC_XV601:
0804         /* Ignore quantization range, there is only one possible
0805          * Y'CbCr encoding. */
0806         ycbcr2rgb(bt601, y, cb, cr, 16, r, g, b);
0807         break;
0808     case V4L2_YCBCR_ENC_XV709:
0809         /* Ignore quantization range, there is only one possible
0810          * Y'CbCr encoding. */
0811         ycbcr2rgb(rec709, y, cb, cr, 16, r, g, b);
0812         break;
0813     case V4L2_YCBCR_ENC_BT2020:
0814         ycbcr2rgb(full ? bt2020_full : bt2020, y, cb, cr, y_offset, r, g, b);
0815         break;
0816     case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
0817         y -= full ? 0 : 16 << 4;
0818         cb -= 128 << 4;
0819         cr -= 128 << 4;
0820 
0821         if (cb <= 0)
0822             *b = y_fac * y + (full ? bt2020c_full[0] : bt2020c[0]) * cb;
0823         else
0824             *b = y_fac * y + (full ? bt2020c_full[1] : bt2020c[1]) * cb;
0825         *b = *b >> 12;
0826         if (cr <= 0)
0827             *r = y_fac * y + (full ? bt2020c_full[2] : bt2020c[2]) * cr;
0828         else
0829             *r = y_fac * y + (full ? bt2020c_full[3] : bt2020c[3]) * cr;
0830         *r = *r >> 12;
0831         lin_r = rec709_to_linear(*r);
0832         lin_b = rec709_to_linear(*b);
0833         lin_y = rec709_to_linear((y * 255) / (full ? 255 : 219));
0834 
0835         lin_g = COEFF(1.0 / 0.6780, 255) * lin_y -
0836             COEFF(0.2627 / 0.6780, 255) * lin_r -
0837             COEFF(0.0593 / 0.6780, 255) * lin_b;
0838         *g = linear_to_rec709(lin_g >> 12);
0839         break;
0840     case V4L2_YCBCR_ENC_SMPTE240M:
0841         ycbcr2rgb(full ? smpte240m_full : smpte240m, y, cb, cr, y_offset, r, g, b);
0842         break;
0843     case V4L2_YCBCR_ENC_709:
0844     default:
0845         ycbcr2rgb(full ? rec709_full : rec709, y, cb, cr, y_offset, r, g, b);
0846         break;
0847     }
0848 }
0849 
0850 /* precalculate color bar values to speed up rendering */
0851 static void precalculate_color(struct tpg_data *tpg, int k)
0852 {
0853     int col = k;
0854     int r = tpg_colors[col].r;
0855     int g = tpg_colors[col].g;
0856     int b = tpg_colors[col].b;
0857     int y, cb, cr;
0858     bool ycbcr_valid = false;
0859 
0860     if (k == TPG_COLOR_TEXTBG) {
0861         col = tpg_get_textbg_color(tpg);
0862 
0863         r = tpg_colors[col].r;
0864         g = tpg_colors[col].g;
0865         b = tpg_colors[col].b;
0866     } else if (k == TPG_COLOR_TEXTFG) {
0867         col = tpg_get_textfg_color(tpg);
0868 
0869         r = tpg_colors[col].r;
0870         g = tpg_colors[col].g;
0871         b = tpg_colors[col].b;
0872     } else if (tpg->pattern == TPG_PAT_NOISE) {
0873         r = g = b = prandom_u32_max(256);
0874     } else if (k == TPG_COLOR_RANDOM) {
0875         r = g = b = tpg->qual_offset + prandom_u32_max(196);
0876     } else if (k >= TPG_COLOR_RAMP) {
0877         r = g = b = k - TPG_COLOR_RAMP;
0878     }
0879 
0880     if (tpg->pattern == TPG_PAT_CSC_COLORBAR && col <= TPG_COLOR_CSC_BLACK) {
0881         r = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].r;
0882         g = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].g;
0883         b = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].b;
0884     } else {
0885         r <<= 4;
0886         g <<= 4;
0887         b <<= 4;
0888     }
0889 
0890     if (tpg->qual == TPG_QUAL_GRAY ||
0891         tpg->color_enc ==  TGP_COLOR_ENC_LUMA) {
0892         /* Rec. 709 Luma function */
0893         /* (0.2126, 0.7152, 0.0722) * (255 * 256) */
0894         r = g = b = (13879 * r + 46688 * g + 4713 * b) >> 16;
0895     }
0896 
0897     /*
0898      * The assumption is that the RGB output is always full range,
0899      * so only if the rgb_range overrides the 'real' rgb range do
0900      * we need to convert the RGB values.
0901      *
0902      * Remember that r, g and b are still in the 0 - 0xff0 range.
0903      */
0904     if (tpg->real_rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
0905         tpg->rgb_range == V4L2_DV_RGB_RANGE_FULL &&
0906         tpg->color_enc == TGP_COLOR_ENC_RGB) {
0907         /*
0908          * Convert from full range (which is what r, g and b are)
0909          * to limited range (which is the 'real' RGB range), which
0910          * is then interpreted as full range.
0911          */
0912         r = (r * 219) / 255 + (16 << 4);
0913         g = (g * 219) / 255 + (16 << 4);
0914         b = (b * 219) / 255 + (16 << 4);
0915     } else if (tpg->real_rgb_range != V4L2_DV_RGB_RANGE_LIMITED &&
0916            tpg->rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
0917            tpg->color_enc == TGP_COLOR_ENC_RGB) {
0918 
0919         /*
0920          * Clamp r, g and b to the limited range and convert to full
0921          * range since that's what we deliver.
0922          */
0923         r = clamp(r, 16 << 4, 235 << 4);
0924         g = clamp(g, 16 << 4, 235 << 4);
0925         b = clamp(b, 16 << 4, 235 << 4);
0926         r = (r - (16 << 4)) * 255 / 219;
0927         g = (g - (16 << 4)) * 255 / 219;
0928         b = (b - (16 << 4)) * 255 / 219;
0929     }
0930 
0931     if ((tpg->brightness != 128 || tpg->contrast != 128 ||
0932          tpg->saturation != 128 || tpg->hue) &&
0933         tpg->color_enc != TGP_COLOR_ENC_LUMA) {
0934         /* Implement these operations */
0935         int tmp_cb, tmp_cr;
0936 
0937         /* First convert to YCbCr */
0938 
0939         color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
0940 
0941         y = (16 << 4) + ((y - (16 << 4)) * tpg->contrast) / 128;
0942         y += (tpg->brightness << 4) - (128 << 4);
0943 
0944         cb -= 128 << 4;
0945         cr -= 128 << 4;
0946         tmp_cb = (cb * cos(128 + tpg->hue)) / 127 + (cr * sin[128 + tpg->hue]) / 127;
0947         tmp_cr = (cr * cos(128 + tpg->hue)) / 127 - (cb * sin[128 + tpg->hue]) / 127;
0948 
0949         cb = (128 << 4) + (tmp_cb * tpg->contrast * tpg->saturation) / (128 * 128);
0950         cr = (128 << 4) + (tmp_cr * tpg->contrast * tpg->saturation) / (128 * 128);
0951         if (tpg->color_enc == TGP_COLOR_ENC_YCBCR)
0952             ycbcr_valid = true;
0953         else
0954             ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b);
0955     } else if ((tpg->brightness != 128 || tpg->contrast != 128) &&
0956            tpg->color_enc == TGP_COLOR_ENC_LUMA) {
0957         r = (16 << 4) + ((r - (16 << 4)) * tpg->contrast) / 128;
0958         r += (tpg->brightness << 4) - (128 << 4);
0959     }
0960 
0961     switch (tpg->color_enc) {
0962     case TGP_COLOR_ENC_HSV:
0963     {
0964         int h, s, v;
0965 
0966         color_to_hsv(tpg, r, g, b, &h, &s, &v);
0967         tpg->colors[k][0] = h;
0968         tpg->colors[k][1] = s;
0969         tpg->colors[k][2] = v;
0970         break;
0971     }
0972     case TGP_COLOR_ENC_YCBCR:
0973     {
0974         /* Convert to YCbCr */
0975         if (!ycbcr_valid)
0976             color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
0977 
0978         y >>= 4;
0979         cb >>= 4;
0980         cr >>= 4;
0981         /*
0982          * XV601/709 use the header/footer margins to encode R', G'
0983          * and B' values outside the range [0-1]. So do not clamp
0984          * XV601/709 values.
0985          */
0986         if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE &&
0987             tpg->real_ycbcr_enc != V4L2_YCBCR_ENC_XV601 &&
0988             tpg->real_ycbcr_enc != V4L2_YCBCR_ENC_XV709) {
0989             y = clamp(y, 16, 235);
0990             cb = clamp(cb, 16, 240);
0991             cr = clamp(cr, 16, 240);
0992         } else {
0993             y = clamp(y, 1, 254);
0994             cb = clamp(cb, 1, 254);
0995             cr = clamp(cr, 1, 254);
0996         }
0997         switch (tpg->fourcc) {
0998         case V4L2_PIX_FMT_YUV444:
0999             y >>= 4;
1000             cb >>= 4;
1001             cr >>= 4;
1002             break;
1003         case V4L2_PIX_FMT_YUV555:
1004             y >>= 3;
1005             cb >>= 3;
1006             cr >>= 3;
1007             break;
1008         case V4L2_PIX_FMT_YUV565:
1009             y >>= 3;
1010             cb >>= 2;
1011             cr >>= 3;
1012             break;
1013         }
1014         tpg->colors[k][0] = y;
1015         tpg->colors[k][1] = cb;
1016         tpg->colors[k][2] = cr;
1017         break;
1018     }
1019     case TGP_COLOR_ENC_LUMA:
1020     {
1021         tpg->colors[k][0] = r >> 4;
1022         break;
1023     }
1024     case TGP_COLOR_ENC_RGB:
1025     {
1026         if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
1027             r = (r * 219) / 255 + (16 << 4);
1028             g = (g * 219) / 255 + (16 << 4);
1029             b = (b * 219) / 255 + (16 << 4);
1030         }
1031         switch (tpg->fourcc) {
1032         case V4L2_PIX_FMT_RGB332:
1033             r >>= 9;
1034             g >>= 9;
1035             b >>= 10;
1036             break;
1037         case V4L2_PIX_FMT_RGB565:
1038         case V4L2_PIX_FMT_RGB565X:
1039             r >>= 7;
1040             g >>= 6;
1041             b >>= 7;
1042             break;
1043         case V4L2_PIX_FMT_RGB444:
1044         case V4L2_PIX_FMT_XRGB444:
1045         case V4L2_PIX_FMT_ARGB444:
1046         case V4L2_PIX_FMT_RGBX444:
1047         case V4L2_PIX_FMT_RGBA444:
1048         case V4L2_PIX_FMT_XBGR444:
1049         case V4L2_PIX_FMT_ABGR444:
1050         case V4L2_PIX_FMT_BGRX444:
1051         case V4L2_PIX_FMT_BGRA444:
1052             r >>= 8;
1053             g >>= 8;
1054             b >>= 8;
1055             break;
1056         case V4L2_PIX_FMT_RGB555:
1057         case V4L2_PIX_FMT_XRGB555:
1058         case V4L2_PIX_FMT_ARGB555:
1059         case V4L2_PIX_FMT_RGBX555:
1060         case V4L2_PIX_FMT_RGBA555:
1061         case V4L2_PIX_FMT_XBGR555:
1062         case V4L2_PIX_FMT_ABGR555:
1063         case V4L2_PIX_FMT_BGRX555:
1064         case V4L2_PIX_FMT_BGRA555:
1065         case V4L2_PIX_FMT_RGB555X:
1066         case V4L2_PIX_FMT_XRGB555X:
1067         case V4L2_PIX_FMT_ARGB555X:
1068             r >>= 7;
1069             g >>= 7;
1070             b >>= 7;
1071             break;
1072         case V4L2_PIX_FMT_BGR666:
1073             r >>= 6;
1074             g >>= 6;
1075             b >>= 6;
1076             break;
1077         default:
1078             r >>= 4;
1079             g >>= 4;
1080             b >>= 4;
1081             break;
1082         }
1083 
1084         tpg->colors[k][0] = r;
1085         tpg->colors[k][1] = g;
1086         tpg->colors[k][2] = b;
1087         break;
1088     }
1089     }
1090 }
1091 
1092 static void tpg_precalculate_colors(struct tpg_data *tpg)
1093 {
1094     int k;
1095 
1096     for (k = 0; k < TPG_COLOR_MAX; k++)
1097         precalculate_color(tpg, k);
1098 }
1099 
1100 /* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
1101 static void gen_twopix(struct tpg_data *tpg,
1102         u8 buf[TPG_MAX_PLANES][8], int color, bool odd)
1103 {
1104     unsigned offset = odd * tpg->twopixelsize[0] / 2;
1105     u8 alpha = tpg->alpha_component;
1106     u8 r_y_h, g_u_s, b_v;
1107 
1108     if (tpg->alpha_red_only && color != TPG_COLOR_CSC_RED &&
1109                    color != TPG_COLOR_100_RED &&
1110                    color != TPG_COLOR_75_RED)
1111         alpha = 0;
1112     if (color == TPG_COLOR_RANDOM)
1113         precalculate_color(tpg, color);
1114     r_y_h = tpg->colors[color][0]; /* R or precalculated Y, H */
1115     g_u_s = tpg->colors[color][1]; /* G or precalculated U, V */
1116     b_v = tpg->colors[color][2]; /* B or precalculated V */
1117 
1118     switch (tpg->fourcc) {
1119     case V4L2_PIX_FMT_GREY:
1120         buf[0][offset] = r_y_h;
1121         break;
1122     case V4L2_PIX_FMT_Y10:
1123         buf[0][offset] = (r_y_h << 2) & 0xff;
1124         buf[0][offset+1] = r_y_h >> 6;
1125         break;
1126     case V4L2_PIX_FMT_Y12:
1127         buf[0][offset] = (r_y_h << 4) & 0xff;
1128         buf[0][offset+1] = r_y_h >> 4;
1129         break;
1130     case V4L2_PIX_FMT_Y16:
1131     case V4L2_PIX_FMT_Z16:
1132         /*
1133          * Ideally both bytes should be set to r_y_h, but then you won't
1134          * be able to detect endian problems. So keep it 0 except for
1135          * the corner case where r_y_h is 0xff so white really will be
1136          * white (0xffff).
1137          */
1138         buf[0][offset] = r_y_h == 0xff ? r_y_h : 0;
1139         buf[0][offset+1] = r_y_h;
1140         break;
1141     case V4L2_PIX_FMT_Y16_BE:
1142         /* See comment for V4L2_PIX_FMT_Y16 above */
1143         buf[0][offset] = r_y_h;
1144         buf[0][offset+1] = r_y_h == 0xff ? r_y_h : 0;
1145         break;
1146     case V4L2_PIX_FMT_YUV422M:
1147     case V4L2_PIX_FMT_YUV422P:
1148     case V4L2_PIX_FMT_YUV420:
1149     case V4L2_PIX_FMT_YUV420M:
1150         buf[0][offset] = r_y_h;
1151         if (odd) {
1152             buf[1][0] = (buf[1][0] + g_u_s) / 2;
1153             buf[2][0] = (buf[2][0] + b_v) / 2;
1154             buf[1][1] = buf[1][0];
1155             buf[2][1] = buf[2][0];
1156             break;
1157         }
1158         buf[1][0] = g_u_s;
1159         buf[2][0] = b_v;
1160         break;
1161     case V4L2_PIX_FMT_YVU422M:
1162     case V4L2_PIX_FMT_YVU420:
1163     case V4L2_PIX_FMT_YVU420M:
1164         buf[0][offset] = r_y_h;
1165         if (odd) {
1166             buf[1][0] = (buf[1][0] + b_v) / 2;
1167             buf[2][0] = (buf[2][0] + g_u_s) / 2;
1168             buf[1][1] = buf[1][0];
1169             buf[2][1] = buf[2][0];
1170             break;
1171         }
1172         buf[1][0] = b_v;
1173         buf[2][0] = g_u_s;
1174         break;
1175 
1176     case V4L2_PIX_FMT_NV12:
1177     case V4L2_PIX_FMT_NV12M:
1178     case V4L2_PIX_FMT_NV16:
1179     case V4L2_PIX_FMT_NV16M:
1180         buf[0][offset] = r_y_h;
1181         if (odd) {
1182             buf[1][0] = (buf[1][0] + g_u_s) / 2;
1183             buf[1][1] = (buf[1][1] + b_v) / 2;
1184             break;
1185         }
1186         buf[1][0] = g_u_s;
1187         buf[1][1] = b_v;
1188         break;
1189     case V4L2_PIX_FMT_NV21:
1190     case V4L2_PIX_FMT_NV21M:
1191     case V4L2_PIX_FMT_NV61:
1192     case V4L2_PIX_FMT_NV61M:
1193         buf[0][offset] = r_y_h;
1194         if (odd) {
1195             buf[1][0] = (buf[1][0] + b_v) / 2;
1196             buf[1][1] = (buf[1][1] + g_u_s) / 2;
1197             break;
1198         }
1199         buf[1][0] = b_v;
1200         buf[1][1] = g_u_s;
1201         break;
1202 
1203     case V4L2_PIX_FMT_YUV444M:
1204         buf[0][offset] = r_y_h;
1205         buf[1][offset] = g_u_s;
1206         buf[2][offset] = b_v;
1207         break;
1208 
1209     case V4L2_PIX_FMT_YVU444M:
1210         buf[0][offset] = r_y_h;
1211         buf[1][offset] = b_v;
1212         buf[2][offset] = g_u_s;
1213         break;
1214 
1215     case V4L2_PIX_FMT_NV24:
1216         buf[0][offset] = r_y_h;
1217         buf[1][2 * offset] = g_u_s;
1218         buf[1][(2 * offset + 1) % 8] = b_v;
1219         break;
1220 
1221     case V4L2_PIX_FMT_NV42:
1222         buf[0][offset] = r_y_h;
1223         buf[1][2 * offset] = b_v;
1224         buf[1][(2 * offset + 1) % 8] = g_u_s;
1225         break;
1226 
1227     case V4L2_PIX_FMT_YUYV:
1228         buf[0][offset] = r_y_h;
1229         if (odd) {
1230             buf[0][1] = (buf[0][1] + g_u_s) / 2;
1231             buf[0][3] = (buf[0][3] + b_v) / 2;
1232             break;
1233         }
1234         buf[0][1] = g_u_s;
1235         buf[0][3] = b_v;
1236         break;
1237     case V4L2_PIX_FMT_UYVY:
1238         buf[0][offset + 1] = r_y_h;
1239         if (odd) {
1240             buf[0][0] = (buf[0][0] + g_u_s) / 2;
1241             buf[0][2] = (buf[0][2] + b_v) / 2;
1242             break;
1243         }
1244         buf[0][0] = g_u_s;
1245         buf[0][2] = b_v;
1246         break;
1247     case V4L2_PIX_FMT_YVYU:
1248         buf[0][offset] = r_y_h;
1249         if (odd) {
1250             buf[0][1] = (buf[0][1] + b_v) / 2;
1251             buf[0][3] = (buf[0][3] + g_u_s) / 2;
1252             break;
1253         }
1254         buf[0][1] = b_v;
1255         buf[0][3] = g_u_s;
1256         break;
1257     case V4L2_PIX_FMT_VYUY:
1258         buf[0][offset + 1] = r_y_h;
1259         if (odd) {
1260             buf[0][0] = (buf[0][0] + b_v) / 2;
1261             buf[0][2] = (buf[0][2] + g_u_s) / 2;
1262             break;
1263         }
1264         buf[0][0] = b_v;
1265         buf[0][2] = g_u_s;
1266         break;
1267     case V4L2_PIX_FMT_RGB332:
1268         buf[0][offset] = (r_y_h << 5) | (g_u_s << 2) | b_v;
1269         break;
1270     case V4L2_PIX_FMT_YUV565:
1271     case V4L2_PIX_FMT_RGB565:
1272         buf[0][offset] = (g_u_s << 5) | b_v;
1273         buf[0][offset + 1] = (r_y_h << 3) | (g_u_s >> 3);
1274         break;
1275     case V4L2_PIX_FMT_RGB565X:
1276         buf[0][offset] = (r_y_h << 3) | (g_u_s >> 3);
1277         buf[0][offset + 1] = (g_u_s << 5) | b_v;
1278         break;
1279     case V4L2_PIX_FMT_RGB444:
1280     case V4L2_PIX_FMT_XRGB444:
1281         alpha = 0;
1282         fallthrough;
1283     case V4L2_PIX_FMT_YUV444:
1284     case V4L2_PIX_FMT_ARGB444:
1285         buf[0][offset] = (g_u_s << 4) | b_v;
1286         buf[0][offset + 1] = (alpha & 0xf0) | r_y_h;
1287         break;
1288     case V4L2_PIX_FMT_RGBX444:
1289         alpha = 0;
1290         fallthrough;
1291     case V4L2_PIX_FMT_RGBA444:
1292         buf[0][offset] = (b_v << 4) | (alpha >> 4);
1293         buf[0][offset + 1] = (r_y_h << 4) | g_u_s;
1294         break;
1295     case V4L2_PIX_FMT_XBGR444:
1296         alpha = 0;
1297         fallthrough;
1298     case V4L2_PIX_FMT_ABGR444:
1299         buf[0][offset] = (g_u_s << 4) | r_y_h;
1300         buf[0][offset + 1] = (alpha & 0xf0) | b_v;
1301         break;
1302     case V4L2_PIX_FMT_BGRX444:
1303         alpha = 0;
1304         fallthrough;
1305     case V4L2_PIX_FMT_BGRA444:
1306         buf[0][offset] = (r_y_h << 4) | (alpha >> 4);
1307         buf[0][offset + 1] = (b_v << 4) | g_u_s;
1308         break;
1309     case V4L2_PIX_FMT_RGB555:
1310     case V4L2_PIX_FMT_XRGB555:
1311         alpha = 0;
1312         fallthrough;
1313     case V4L2_PIX_FMT_YUV555:
1314     case V4L2_PIX_FMT_ARGB555:
1315         buf[0][offset] = (g_u_s << 5) | b_v;
1316         buf[0][offset + 1] = (alpha & 0x80) | (r_y_h << 2)
1317                             | (g_u_s >> 3);
1318         break;
1319     case V4L2_PIX_FMT_RGBX555:
1320         alpha = 0;
1321         fallthrough;
1322     case V4L2_PIX_FMT_RGBA555:
1323         buf[0][offset] = (g_u_s << 6) | (b_v << 1) |
1324                  ((alpha & 0x80) >> 7);
1325         buf[0][offset + 1] = (r_y_h << 3) | (g_u_s >> 2);
1326         break;
1327     case V4L2_PIX_FMT_XBGR555:
1328         alpha = 0;
1329         fallthrough;
1330     case V4L2_PIX_FMT_ABGR555:
1331         buf[0][offset] = (g_u_s << 5) | r_y_h;
1332         buf[0][offset + 1] = (alpha & 0x80) | (b_v << 2)
1333                             | (g_u_s >> 3);
1334         break;
1335     case V4L2_PIX_FMT_BGRX555:
1336         alpha = 0;
1337         fallthrough;
1338     case V4L2_PIX_FMT_BGRA555:
1339         buf[0][offset] = (g_u_s << 6) | (r_y_h << 1) |
1340                  ((alpha & 0x80) >> 7);
1341         buf[0][offset + 1] = (b_v << 3) | (g_u_s >> 2);
1342         break;
1343     case V4L2_PIX_FMT_RGB555X:
1344     case V4L2_PIX_FMT_XRGB555X:
1345         alpha = 0;
1346         fallthrough;
1347     case V4L2_PIX_FMT_ARGB555X:
1348         buf[0][offset] = (alpha & 0x80) | (r_y_h << 2) | (g_u_s >> 3);
1349         buf[0][offset + 1] = (g_u_s << 5) | b_v;
1350         break;
1351     case V4L2_PIX_FMT_RGB24:
1352     case V4L2_PIX_FMT_HSV24:
1353         buf[0][offset] = r_y_h;
1354         buf[0][offset + 1] = g_u_s;
1355         buf[0][offset + 2] = b_v;
1356         break;
1357     case V4L2_PIX_FMT_BGR24:
1358         buf[0][offset] = b_v;
1359         buf[0][offset + 1] = g_u_s;
1360         buf[0][offset + 2] = r_y_h;
1361         break;
1362     case V4L2_PIX_FMT_BGR666:
1363         buf[0][offset] = (b_v << 2) | (g_u_s >> 4);
1364         buf[0][offset + 1] = (g_u_s << 4) | (r_y_h >> 2);
1365         buf[0][offset + 2] = r_y_h << 6;
1366         buf[0][offset + 3] = 0;
1367         break;
1368     case V4L2_PIX_FMT_RGB32:
1369     case V4L2_PIX_FMT_XRGB32:
1370     case V4L2_PIX_FMT_HSV32:
1371     case V4L2_PIX_FMT_XYUV32:
1372         alpha = 0;
1373         fallthrough;
1374     case V4L2_PIX_FMT_YUV32:
1375     case V4L2_PIX_FMT_ARGB32:
1376     case V4L2_PIX_FMT_AYUV32:
1377         buf[0][offset] = alpha;
1378         buf[0][offset + 1] = r_y_h;
1379         buf[0][offset + 2] = g_u_s;
1380         buf[0][offset + 3] = b_v;
1381         break;
1382     case V4L2_PIX_FMT_RGBX32:
1383     case V4L2_PIX_FMT_YUVX32:
1384         alpha = 0;
1385         fallthrough;
1386     case V4L2_PIX_FMT_RGBA32:
1387     case V4L2_PIX_FMT_YUVA32:
1388         buf[0][offset] = r_y_h;
1389         buf[0][offset + 1] = g_u_s;
1390         buf[0][offset + 2] = b_v;
1391         buf[0][offset + 3] = alpha;
1392         break;
1393     case V4L2_PIX_FMT_BGR32:
1394     case V4L2_PIX_FMT_XBGR32:
1395     case V4L2_PIX_FMT_VUYX32:
1396         alpha = 0;
1397         fallthrough;
1398     case V4L2_PIX_FMT_ABGR32:
1399     case V4L2_PIX_FMT_VUYA32:
1400         buf[0][offset] = b_v;
1401         buf[0][offset + 1] = g_u_s;
1402         buf[0][offset + 2] = r_y_h;
1403         buf[0][offset + 3] = alpha;
1404         break;
1405     case V4L2_PIX_FMT_BGRX32:
1406         alpha = 0;
1407         fallthrough;
1408     case V4L2_PIX_FMT_BGRA32:
1409         buf[0][offset] = alpha;
1410         buf[0][offset + 1] = b_v;
1411         buf[0][offset + 2] = g_u_s;
1412         buf[0][offset + 3] = r_y_h;
1413         break;
1414     case V4L2_PIX_FMT_SBGGR8:
1415         buf[0][offset] = odd ? g_u_s : b_v;
1416         buf[1][offset] = odd ? r_y_h : g_u_s;
1417         break;
1418     case V4L2_PIX_FMT_SGBRG8:
1419         buf[0][offset] = odd ? b_v : g_u_s;
1420         buf[1][offset] = odd ? g_u_s : r_y_h;
1421         break;
1422     case V4L2_PIX_FMT_SGRBG8:
1423         buf[0][offset] = odd ? r_y_h : g_u_s;
1424         buf[1][offset] = odd ? g_u_s : b_v;
1425         break;
1426     case V4L2_PIX_FMT_SRGGB8:
1427         buf[0][offset] = odd ? g_u_s : r_y_h;
1428         buf[1][offset] = odd ? b_v : g_u_s;
1429         break;
1430     case V4L2_PIX_FMT_SBGGR10:
1431         buf[0][offset] = odd ? g_u_s << 2 : b_v << 2;
1432         buf[0][offset + 1] = odd ? g_u_s >> 6 : b_v >> 6;
1433         buf[1][offset] = odd ? r_y_h << 2 : g_u_s << 2;
1434         buf[1][offset + 1] = odd ? r_y_h >> 6 : g_u_s >> 6;
1435         buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1436         buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1437         break;
1438     case V4L2_PIX_FMT_SGBRG10:
1439         buf[0][offset] = odd ? b_v << 2 : g_u_s << 2;
1440         buf[0][offset + 1] = odd ? b_v >> 6 : g_u_s >> 6;
1441         buf[1][offset] = odd ? g_u_s << 2 : r_y_h << 2;
1442         buf[1][offset + 1] = odd ? g_u_s >> 6 : r_y_h >> 6;
1443         buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1444         buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1445         break;
1446     case V4L2_PIX_FMT_SGRBG10:
1447         buf[0][offset] = odd ? r_y_h << 2 : g_u_s << 2;
1448         buf[0][offset + 1] = odd ? r_y_h >> 6 : g_u_s >> 6;
1449         buf[1][offset] = odd ? g_u_s << 2 : b_v << 2;
1450         buf[1][offset + 1] = odd ? g_u_s >> 6 : b_v >> 6;
1451         buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1452         buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1453         break;
1454     case V4L2_PIX_FMT_SRGGB10:
1455         buf[0][offset] = odd ? g_u_s << 2 : r_y_h << 2;
1456         buf[0][offset + 1] = odd ? g_u_s >> 6 : r_y_h >> 6;
1457         buf[1][offset] = odd ? b_v << 2 : g_u_s << 2;
1458         buf[1][offset + 1] = odd ? b_v >> 6 : g_u_s >> 6;
1459         buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1460         buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1461         break;
1462     case V4L2_PIX_FMT_SBGGR12:
1463         buf[0][offset] = odd ? g_u_s << 4 : b_v << 4;
1464         buf[0][offset + 1] = odd ? g_u_s >> 4 : b_v >> 4;
1465         buf[1][offset] = odd ? r_y_h << 4 : g_u_s << 4;
1466         buf[1][offset + 1] = odd ? r_y_h >> 4 : g_u_s >> 4;
1467         buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1468         buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1469         break;
1470     case V4L2_PIX_FMT_SGBRG12:
1471         buf[0][offset] = odd ? b_v << 4 : g_u_s << 4;
1472         buf[0][offset + 1] = odd ? b_v >> 4 : g_u_s >> 4;
1473         buf[1][offset] = odd ? g_u_s << 4 : r_y_h << 4;
1474         buf[1][offset + 1] = odd ? g_u_s >> 4 : r_y_h >> 4;
1475         buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1476         buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1477         break;
1478     case V4L2_PIX_FMT_SGRBG12:
1479         buf[0][offset] = odd ? r_y_h << 4 : g_u_s << 4;
1480         buf[0][offset + 1] = odd ? r_y_h >> 4 : g_u_s >> 4;
1481         buf[1][offset] = odd ? g_u_s << 4 : b_v << 4;
1482         buf[1][offset + 1] = odd ? g_u_s >> 4 : b_v >> 4;
1483         buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1484         buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1485         break;
1486     case V4L2_PIX_FMT_SRGGB12:
1487         buf[0][offset] = odd ? g_u_s << 4 : r_y_h << 4;
1488         buf[0][offset + 1] = odd ? g_u_s >> 4 : r_y_h >> 4;
1489         buf[1][offset] = odd ? b_v << 4 : g_u_s << 4;
1490         buf[1][offset + 1] = odd ? b_v >> 4 : g_u_s >> 4;
1491         buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1492         buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1493         break;
1494     case V4L2_PIX_FMT_SBGGR16:
1495         buf[0][offset] = buf[0][offset + 1] = odd ? g_u_s : b_v;
1496         buf[1][offset] = buf[1][offset + 1] = odd ? r_y_h : g_u_s;
1497         break;
1498     case V4L2_PIX_FMT_SGBRG16:
1499         buf[0][offset] = buf[0][offset + 1] = odd ? b_v : g_u_s;
1500         buf[1][offset] = buf[1][offset + 1] = odd ? g_u_s : r_y_h;
1501         break;
1502     case V4L2_PIX_FMT_SGRBG16:
1503         buf[0][offset] = buf[0][offset + 1] = odd ? r_y_h : g_u_s;
1504         buf[1][offset] = buf[1][offset + 1] = odd ? g_u_s : b_v;
1505         break;
1506     case V4L2_PIX_FMT_SRGGB16:
1507         buf[0][offset] = buf[0][offset + 1] = odd ? g_u_s : r_y_h;
1508         buf[1][offset] = buf[1][offset + 1] = odd ? b_v : g_u_s;
1509         break;
1510     }
1511 }
1512 
1513 unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line)
1514 {
1515     switch (tpg->fourcc) {
1516     case V4L2_PIX_FMT_SBGGR8:
1517     case V4L2_PIX_FMT_SGBRG8:
1518     case V4L2_PIX_FMT_SGRBG8:
1519     case V4L2_PIX_FMT_SRGGB8:
1520     case V4L2_PIX_FMT_SBGGR10:
1521     case V4L2_PIX_FMT_SGBRG10:
1522     case V4L2_PIX_FMT_SGRBG10:
1523     case V4L2_PIX_FMT_SRGGB10:
1524     case V4L2_PIX_FMT_SBGGR12:
1525     case V4L2_PIX_FMT_SGBRG12:
1526     case V4L2_PIX_FMT_SGRBG12:
1527     case V4L2_PIX_FMT_SRGGB12:
1528     case V4L2_PIX_FMT_SBGGR16:
1529     case V4L2_PIX_FMT_SGBRG16:
1530     case V4L2_PIX_FMT_SGRBG16:
1531     case V4L2_PIX_FMT_SRGGB16:
1532         return buf_line & 1;
1533     default:
1534         return 0;
1535     }
1536 }
1537 EXPORT_SYMBOL_GPL(tpg_g_interleaved_plane);
1538 
1539 /* Return how many pattern lines are used by the current pattern. */
1540 static unsigned tpg_get_pat_lines(const struct tpg_data *tpg)
1541 {
1542     switch (tpg->pattern) {
1543     case TPG_PAT_CHECKERS_16X16:
1544     case TPG_PAT_CHECKERS_2X2:
1545     case TPG_PAT_CHECKERS_1X1:
1546     case TPG_PAT_COLOR_CHECKERS_2X2:
1547     case TPG_PAT_COLOR_CHECKERS_1X1:
1548     case TPG_PAT_ALTERNATING_HLINES:
1549     case TPG_PAT_CROSS_1_PIXEL:
1550     case TPG_PAT_CROSS_2_PIXELS:
1551     case TPG_PAT_CROSS_10_PIXELS:
1552         return 2;
1553     case TPG_PAT_100_COLORSQUARES:
1554     case TPG_PAT_100_HCOLORBAR:
1555         return 8;
1556     default:
1557         return 1;
1558     }
1559 }
1560 
1561 /* Which pattern line should be used for the given frame line. */
1562 static unsigned tpg_get_pat_line(const struct tpg_data *tpg, unsigned line)
1563 {
1564     switch (tpg->pattern) {
1565     case TPG_PAT_CHECKERS_16X16:
1566         return (line >> 4) & 1;
1567     case TPG_PAT_CHECKERS_1X1:
1568     case TPG_PAT_COLOR_CHECKERS_1X1:
1569     case TPG_PAT_ALTERNATING_HLINES:
1570         return line & 1;
1571     case TPG_PAT_CHECKERS_2X2:
1572     case TPG_PAT_COLOR_CHECKERS_2X2:
1573         return (line & 2) >> 1;
1574     case TPG_PAT_100_COLORSQUARES:
1575     case TPG_PAT_100_HCOLORBAR:
1576         return (line * 8) / tpg->src_height;
1577     case TPG_PAT_CROSS_1_PIXEL:
1578         return line == tpg->src_height / 2;
1579     case TPG_PAT_CROSS_2_PIXELS:
1580         return (line + 1) / 2 == tpg->src_height / 4;
1581     case TPG_PAT_CROSS_10_PIXELS:
1582         return (line + 10) / 20 == tpg->src_height / 40;
1583     default:
1584         return 0;
1585     }
1586 }
1587 
1588 /*
1589  * Which color should be used for the given pattern line and X coordinate.
1590  * Note: x is in the range 0 to 2 * tpg->src_width.
1591  */
1592 static enum tpg_color tpg_get_color(const struct tpg_data *tpg,
1593                     unsigned pat_line, unsigned x)
1594 {
1595     /* Maximum number of bars are TPG_COLOR_MAX - otherwise, the input print code
1596        should be modified */
1597     static const enum tpg_color bars[3][8] = {
1598         /* Standard ITU-R 75% color bar sequence */
1599         { TPG_COLOR_CSC_WHITE,   TPG_COLOR_75_YELLOW,
1600           TPG_COLOR_75_CYAN,     TPG_COLOR_75_GREEN,
1601           TPG_COLOR_75_MAGENTA,  TPG_COLOR_75_RED,
1602           TPG_COLOR_75_BLUE,     TPG_COLOR_100_BLACK, },
1603         /* Standard ITU-R 100% color bar sequence */
1604         { TPG_COLOR_100_WHITE,   TPG_COLOR_100_YELLOW,
1605           TPG_COLOR_100_CYAN,    TPG_COLOR_100_GREEN,
1606           TPG_COLOR_100_MAGENTA, TPG_COLOR_100_RED,
1607           TPG_COLOR_100_BLUE,    TPG_COLOR_100_BLACK, },
1608         /* Color bar sequence suitable to test CSC */
1609         { TPG_COLOR_CSC_WHITE,   TPG_COLOR_CSC_YELLOW,
1610           TPG_COLOR_CSC_CYAN,    TPG_COLOR_CSC_GREEN,
1611           TPG_COLOR_CSC_MAGENTA, TPG_COLOR_CSC_RED,
1612           TPG_COLOR_CSC_BLUE,    TPG_COLOR_CSC_BLACK, },
1613     };
1614 
1615     switch (tpg->pattern) {
1616     case TPG_PAT_75_COLORBAR:
1617     case TPG_PAT_100_COLORBAR:
1618     case TPG_PAT_CSC_COLORBAR:
1619         return bars[tpg->pattern][((x * 8) / tpg->src_width) % 8];
1620     case TPG_PAT_100_COLORSQUARES:
1621         return bars[1][(pat_line + (x * 8) / tpg->src_width) % 8];
1622     case TPG_PAT_100_HCOLORBAR:
1623         return bars[1][pat_line];
1624     case TPG_PAT_BLACK:
1625         return TPG_COLOR_100_BLACK;
1626     case TPG_PAT_WHITE:
1627         return TPG_COLOR_100_WHITE;
1628     case TPG_PAT_RED:
1629         return TPG_COLOR_100_RED;
1630     case TPG_PAT_GREEN:
1631         return TPG_COLOR_100_GREEN;
1632     case TPG_PAT_BLUE:
1633         return TPG_COLOR_100_BLUE;
1634     case TPG_PAT_CHECKERS_16X16:
1635         return (((x >> 4) & 1) ^ (pat_line & 1)) ?
1636             TPG_COLOR_100_BLACK : TPG_COLOR_100_WHITE;
1637     case TPG_PAT_CHECKERS_1X1:
1638         return ((x & 1) ^ (pat_line & 1)) ?
1639             TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1640     case TPG_PAT_COLOR_CHECKERS_1X1:
1641         return ((x & 1) ^ (pat_line & 1)) ?
1642             TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
1643     case TPG_PAT_CHECKERS_2X2:
1644         return (((x >> 1) & 1) ^ (pat_line & 1)) ?
1645             TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1646     case TPG_PAT_COLOR_CHECKERS_2X2:
1647         return (((x >> 1) & 1) ^ (pat_line & 1)) ?
1648             TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
1649     case TPG_PAT_ALTERNATING_HLINES:
1650         return pat_line ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1651     case TPG_PAT_ALTERNATING_VLINES:
1652         return (x & 1) ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1653     case TPG_PAT_CROSS_1_PIXEL:
1654         if (pat_line || (x % tpg->src_width) == tpg->src_width / 2)
1655             return TPG_COLOR_100_BLACK;
1656         return TPG_COLOR_100_WHITE;
1657     case TPG_PAT_CROSS_2_PIXELS:
1658         if (pat_line || ((x % tpg->src_width) + 1) / 2 == tpg->src_width / 4)
1659             return TPG_COLOR_100_BLACK;
1660         return TPG_COLOR_100_WHITE;
1661     case TPG_PAT_CROSS_10_PIXELS:
1662         if (pat_line || ((x % tpg->src_width) + 10) / 20 == tpg->src_width / 40)
1663             return TPG_COLOR_100_BLACK;
1664         return TPG_COLOR_100_WHITE;
1665     case TPG_PAT_GRAY_RAMP:
1666         return TPG_COLOR_RAMP + ((x % tpg->src_width) * 256) / tpg->src_width;
1667     default:
1668         return TPG_COLOR_100_RED;
1669     }
1670 }
1671 
1672 /*
1673  * Given the pixel aspect ratio and video aspect ratio calculate the
1674  * coordinates of a centered square and the coordinates of the border of
1675  * the active video area. The coordinates are relative to the source
1676  * frame rectangle.
1677  */
1678 static void tpg_calculate_square_border(struct tpg_data *tpg)
1679 {
1680     unsigned w = tpg->src_width;
1681     unsigned h = tpg->src_height;
1682     unsigned sq_w, sq_h;
1683 
1684     sq_w = (w * 2 / 5) & ~1;
1685     if (((w - sq_w) / 2) & 1)
1686         sq_w += 2;
1687     sq_h = sq_w;
1688     tpg->square.width = sq_w;
1689     if (tpg->vid_aspect == TPG_VIDEO_ASPECT_16X9_ANAMORPHIC) {
1690         unsigned ana_sq_w = (sq_w / 4) * 3;
1691 
1692         if (((w - ana_sq_w) / 2) & 1)
1693             ana_sq_w += 2;
1694         tpg->square.width = ana_sq_w;
1695     }
1696     tpg->square.left = (w - tpg->square.width) / 2;
1697     if (tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC)
1698         sq_h = sq_w * 10 / 11;
1699     else if (tpg->pix_aspect == TPG_PIXEL_ASPECT_PAL)
1700         sq_h = sq_w * 59 / 54;
1701     tpg->square.height = sq_h;
1702     tpg->square.top = (h - sq_h) / 2;
1703     tpg->border.left = 0;
1704     tpg->border.width = w;
1705     tpg->border.top = 0;
1706     tpg->border.height = h;
1707     switch (tpg->vid_aspect) {
1708     case TPG_VIDEO_ASPECT_4X3:
1709         if (tpg->pix_aspect)
1710             return;
1711         if (3 * w >= 4 * h) {
1712             tpg->border.width = ((4 * h) / 3) & ~1;
1713             if (((w - tpg->border.width) / 2) & ~1)
1714                 tpg->border.width -= 2;
1715             tpg->border.left = (w - tpg->border.width) / 2;
1716             break;
1717         }
1718         tpg->border.height = ((3 * w) / 4) & ~1;
1719         tpg->border.top = (h - tpg->border.height) / 2;
1720         break;
1721     case TPG_VIDEO_ASPECT_14X9_CENTRE:
1722         if (tpg->pix_aspect) {
1723             tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 420 : 506;
1724             tpg->border.top = (h - tpg->border.height) / 2;
1725             break;
1726         }
1727         if (9 * w >= 14 * h) {
1728             tpg->border.width = ((14 * h) / 9) & ~1;
1729             if (((w - tpg->border.width) / 2) & ~1)
1730                 tpg->border.width -= 2;
1731             tpg->border.left = (w - tpg->border.width) / 2;
1732             break;
1733         }
1734         tpg->border.height = ((9 * w) / 14) & ~1;
1735         tpg->border.top = (h - tpg->border.height) / 2;
1736         break;
1737     case TPG_VIDEO_ASPECT_16X9_CENTRE:
1738         if (tpg->pix_aspect) {
1739             tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 368 : 442;
1740             tpg->border.top = (h - tpg->border.height) / 2;
1741             break;
1742         }
1743         if (9 * w >= 16 * h) {
1744             tpg->border.width = ((16 * h) / 9) & ~1;
1745             if (((w - tpg->border.width) / 2) & ~1)
1746                 tpg->border.width -= 2;
1747             tpg->border.left = (w - tpg->border.width) / 2;
1748             break;
1749         }
1750         tpg->border.height = ((9 * w) / 16) & ~1;
1751         tpg->border.top = (h - tpg->border.height) / 2;
1752         break;
1753     default:
1754         break;
1755     }
1756 }
1757 
1758 static void tpg_precalculate_line(struct tpg_data *tpg)
1759 {
1760     enum tpg_color contrast;
1761     u8 pix[TPG_MAX_PLANES][8];
1762     unsigned pat;
1763     unsigned p;
1764     unsigned x;
1765 
1766     switch (tpg->pattern) {
1767     case TPG_PAT_GREEN:
1768         contrast = TPG_COLOR_100_RED;
1769         break;
1770     case TPG_PAT_CSC_COLORBAR:
1771         contrast = TPG_COLOR_CSC_GREEN;
1772         break;
1773     default:
1774         contrast = TPG_COLOR_100_GREEN;
1775         break;
1776     }
1777 
1778     for (pat = 0; pat < tpg_get_pat_lines(tpg); pat++) {
1779         /* Coarse scaling with Bresenham */
1780         unsigned int_part = tpg->src_width / tpg->scaled_width;
1781         unsigned fract_part = tpg->src_width % tpg->scaled_width;
1782         unsigned src_x = 0;
1783         unsigned error = 0;
1784 
1785         for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1786             unsigned real_x = src_x;
1787             enum tpg_color color1, color2;
1788 
1789             real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
1790             color1 = tpg_get_color(tpg, pat, real_x);
1791 
1792             src_x += int_part;
1793             error += fract_part;
1794             if (error >= tpg->scaled_width) {
1795                 error -= tpg->scaled_width;
1796                 src_x++;
1797             }
1798 
1799             real_x = src_x;
1800             real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
1801             color2 = tpg_get_color(tpg, pat, real_x);
1802 
1803             src_x += int_part;
1804             error += fract_part;
1805             if (error >= tpg->scaled_width) {
1806                 error -= tpg->scaled_width;
1807                 src_x++;
1808             }
1809 
1810             gen_twopix(tpg, pix, tpg->hflip ? color2 : color1, 0);
1811             gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1);
1812             for (p = 0; p < tpg->planes; p++) {
1813                 unsigned twopixsize = tpg->twopixelsize[p];
1814                 unsigned hdiv = tpg->hdownsampling[p];
1815                 u8 *pos = tpg->lines[pat][p] + tpg_hdiv(tpg, p, x);
1816 
1817                 memcpy(pos, pix[p], twopixsize / hdiv);
1818             }
1819         }
1820     }
1821 
1822     if (tpg->vdownsampling[tpg->planes - 1] > 1) {
1823         unsigned pat_lines = tpg_get_pat_lines(tpg);
1824 
1825         for (pat = 0; pat < pat_lines; pat++) {
1826             unsigned next_pat = (pat + 1) % pat_lines;
1827 
1828             for (p = 1; p < tpg->planes; p++) {
1829                 unsigned w = tpg_hdiv(tpg, p, tpg->scaled_width * 2);
1830                 u8 *pos1 = tpg->lines[pat][p];
1831                 u8 *pos2 = tpg->lines[next_pat][p];
1832                 u8 *dest = tpg->downsampled_lines[pat][p];
1833 
1834                 for (x = 0; x < w; x++, pos1++, pos2++, dest++)
1835                     *dest = ((u16)*pos1 + (u16)*pos2) / 2;
1836             }
1837         }
1838     }
1839 
1840     gen_twopix(tpg, pix, contrast, 0);
1841     gen_twopix(tpg, pix, contrast, 1);
1842     for (p = 0; p < tpg->planes; p++) {
1843         unsigned twopixsize = tpg->twopixelsize[p];
1844         u8 *pos = tpg->contrast_line[p];
1845 
1846         for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1847             memcpy(pos, pix[p], twopixsize);
1848     }
1849 
1850     gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 0);
1851     gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 1);
1852     for (p = 0; p < tpg->planes; p++) {
1853         unsigned twopixsize = tpg->twopixelsize[p];
1854         u8 *pos = tpg->black_line[p];
1855 
1856         for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1857             memcpy(pos, pix[p], twopixsize);
1858     }
1859 
1860     for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1861         gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 0);
1862         gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 1);
1863         for (p = 0; p < tpg->planes; p++) {
1864             unsigned twopixsize = tpg->twopixelsize[p];
1865             u8 *pos = tpg->random_line[p] + x * twopixsize / 2;
1866 
1867             memcpy(pos, pix[p], twopixsize);
1868         }
1869     }
1870 
1871     gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 0);
1872     gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 1);
1873     gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 0);
1874     gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 1);
1875 }
1876 
1877 /* need this to do rgb24 rendering */
1878 typedef struct { u16 __; u8 _; } __packed x24;
1879 
1880 #define PRINTSTR(PIXTYPE) do {  \
1881     unsigned vdiv = tpg->vdownsampling[p]; \
1882     unsigned hdiv = tpg->hdownsampling[p]; \
1883     int line;   \
1884     PIXTYPE fg; \
1885     PIXTYPE bg; \
1886     memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE));   \
1887     memcpy(&bg, tpg->textbg[p], sizeof(PIXTYPE));   \
1888     \
1889     for (line = first; line < 16; line += vdiv * step) {    \
1890         int l = tpg->vflip ? 15 - line : line; \
1891         PIXTYPE *pos = (PIXTYPE *)(basep[p][(line / vdiv) & 1] + \
1892                    ((y * step + l) / (vdiv * div)) * tpg->bytesperline[p] + \
1893                    (x / hdiv) * sizeof(PIXTYPE));   \
1894         unsigned s; \
1895     \
1896         for (s = 0; s < len; s++) { \
1897             u8 chr = font8x16[(u8)text[s] * 16 + line]; \
1898     \
1899             if (hdiv == 2 && tpg->hflip) { \
1900                 pos[3] = (chr & (0x01 << 6) ? fg : bg); \
1901                 pos[2] = (chr & (0x01 << 4) ? fg : bg); \
1902                 pos[1] = (chr & (0x01 << 2) ? fg : bg); \
1903                 pos[0] = (chr & (0x01 << 0) ? fg : bg); \
1904             } else if (hdiv == 2) { \
1905                 pos[0] = (chr & (0x01 << 7) ? fg : bg); \
1906                 pos[1] = (chr & (0x01 << 5) ? fg : bg); \
1907                 pos[2] = (chr & (0x01 << 3) ? fg : bg); \
1908                 pos[3] = (chr & (0x01 << 1) ? fg : bg); \
1909             } else if (tpg->hflip) { \
1910                 pos[7] = (chr & (0x01 << 7) ? fg : bg); \
1911                 pos[6] = (chr & (0x01 << 6) ? fg : bg); \
1912                 pos[5] = (chr & (0x01 << 5) ? fg : bg); \
1913                 pos[4] = (chr & (0x01 << 4) ? fg : bg); \
1914                 pos[3] = (chr & (0x01 << 3) ? fg : bg); \
1915                 pos[2] = (chr & (0x01 << 2) ? fg : bg); \
1916                 pos[1] = (chr & (0x01 << 1) ? fg : bg); \
1917                 pos[0] = (chr & (0x01 << 0) ? fg : bg); \
1918             } else { \
1919                 pos[0] = (chr & (0x01 << 7) ? fg : bg); \
1920                 pos[1] = (chr & (0x01 << 6) ? fg : bg); \
1921                 pos[2] = (chr & (0x01 << 5) ? fg : bg); \
1922                 pos[3] = (chr & (0x01 << 4) ? fg : bg); \
1923                 pos[4] = (chr & (0x01 << 3) ? fg : bg); \
1924                 pos[5] = (chr & (0x01 << 2) ? fg : bg); \
1925                 pos[6] = (chr & (0x01 << 1) ? fg : bg); \
1926                 pos[7] = (chr & (0x01 << 0) ? fg : bg); \
1927             } \
1928     \
1929             pos += (tpg->hflip ? -8 : 8) / (int)hdiv;   \
1930         }   \
1931     }   \
1932 } while (0)
1933 
1934 static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1935             unsigned p, unsigned first, unsigned div, unsigned step,
1936             int y, int x, const char *text, unsigned len)
1937 {
1938     PRINTSTR(u8);
1939 }
1940 
1941 static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1942             unsigned p, unsigned first, unsigned div, unsigned step,
1943             int y, int x, const char *text, unsigned len)
1944 {
1945     PRINTSTR(u16);
1946 }
1947 
1948 static noinline void tpg_print_str_6(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1949             unsigned p, unsigned first, unsigned div, unsigned step,
1950             int y, int x, const char *text, unsigned len)
1951 {
1952     PRINTSTR(x24);
1953 }
1954 
1955 static noinline void tpg_print_str_8(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1956             unsigned p, unsigned first, unsigned div, unsigned step,
1957             int y, int x, const char *text, unsigned len)
1958 {
1959     PRINTSTR(u32);
1960 }
1961 
1962 void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1963           int y, int x, const char *text)
1964 {
1965     unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
1966     unsigned div = step;
1967     unsigned first = 0;
1968     unsigned len;
1969     unsigned p;
1970 
1971     if (font8x16 == NULL || basep == NULL || text == NULL)
1972         return;
1973 
1974     len = strlen(text);
1975 
1976     /* Checks if it is possible to show string */
1977     if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width)
1978         return;
1979 
1980     if (len > (tpg->compose.width - x) / 8)
1981         len = (tpg->compose.width - x) / 8;
1982     if (tpg->vflip)
1983         y = tpg->compose.height - y - 16;
1984     if (tpg->hflip)
1985         x = tpg->compose.width - x - 8;
1986     y += tpg->compose.top;
1987     x += tpg->compose.left;
1988     if (tpg->field == V4L2_FIELD_BOTTOM)
1989         first = 1;
1990     else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT)
1991         div = 2;
1992 
1993     for (p = 0; p < tpg->planes; p++) {
1994         /* Print text */
1995         switch (tpg->twopixelsize[p]) {
1996         case 2:
1997             tpg_print_str_2(tpg, basep, p, first, div, step, y, x,
1998                     text, len);
1999             break;
2000         case 4:
2001             tpg_print_str_4(tpg, basep, p, first, div, step, y, x,
2002                     text, len);
2003             break;
2004         case 6:
2005             tpg_print_str_6(tpg, basep, p, first, div, step, y, x,
2006                     text, len);
2007             break;
2008         case 8:
2009             tpg_print_str_8(tpg, basep, p, first, div, step, y, x,
2010                     text, len);
2011             break;
2012         }
2013     }
2014 }
2015 EXPORT_SYMBOL_GPL(tpg_gen_text);
2016 
2017 const char *tpg_g_color_order(const struct tpg_data *tpg)
2018 {
2019     switch (tpg->pattern) {
2020     case TPG_PAT_75_COLORBAR:
2021     case TPG_PAT_100_COLORBAR:
2022     case TPG_PAT_CSC_COLORBAR:
2023     case TPG_PAT_100_HCOLORBAR:
2024         return "White, yellow, cyan, green, magenta, red, blue, black";
2025     case TPG_PAT_BLACK:
2026         return "Black";
2027     case TPG_PAT_WHITE:
2028         return "White";
2029     case TPG_PAT_RED:
2030         return "Red";
2031     case TPG_PAT_GREEN:
2032         return "Green";
2033     case TPG_PAT_BLUE:
2034         return "Blue";
2035     default:
2036         return NULL;
2037     }
2038 }
2039 EXPORT_SYMBOL_GPL(tpg_g_color_order);
2040 
2041 void tpg_update_mv_step(struct tpg_data *tpg)
2042 {
2043     int factor = tpg->mv_hor_mode > TPG_MOVE_NONE ? -1 : 1;
2044 
2045     if (tpg->hflip)
2046         factor = -factor;
2047     switch (tpg->mv_hor_mode) {
2048     case TPG_MOVE_NEG_FAST:
2049     case TPG_MOVE_POS_FAST:
2050         tpg->mv_hor_step = ((tpg->src_width + 319) / 320) * 4;
2051         break;
2052     case TPG_MOVE_NEG:
2053     case TPG_MOVE_POS:
2054         tpg->mv_hor_step = ((tpg->src_width + 639) / 640) * 4;
2055         break;
2056     case TPG_MOVE_NEG_SLOW:
2057     case TPG_MOVE_POS_SLOW:
2058         tpg->mv_hor_step = 2;
2059         break;
2060     case TPG_MOVE_NONE:
2061         tpg->mv_hor_step = 0;
2062         break;
2063     }
2064     if (factor < 0)
2065         tpg->mv_hor_step = tpg->src_width - tpg->mv_hor_step;
2066 
2067     factor = tpg->mv_vert_mode > TPG_MOVE_NONE ? -1 : 1;
2068     switch (tpg->mv_vert_mode) {
2069     case TPG_MOVE_NEG_FAST:
2070     case TPG_MOVE_POS_FAST:
2071         tpg->mv_vert_step = ((tpg->src_width + 319) / 320) * 4;
2072         break;
2073     case TPG_MOVE_NEG:
2074     case TPG_MOVE_POS:
2075         tpg->mv_vert_step = ((tpg->src_width + 639) / 640) * 4;
2076         break;
2077     case TPG_MOVE_NEG_SLOW:
2078     case TPG_MOVE_POS_SLOW:
2079         tpg->mv_vert_step = 1;
2080         break;
2081     case TPG_MOVE_NONE:
2082         tpg->mv_vert_step = 0;
2083         break;
2084     }
2085     if (factor < 0)
2086         tpg->mv_vert_step = tpg->src_height - tpg->mv_vert_step;
2087 }
2088 EXPORT_SYMBOL_GPL(tpg_update_mv_step);
2089 
2090 /* Map the line number relative to the crop rectangle to a frame line number */
2091 static unsigned tpg_calc_frameline(const struct tpg_data *tpg, unsigned src_y,
2092                     unsigned field)
2093 {
2094     switch (field) {
2095     case V4L2_FIELD_TOP:
2096         return tpg->crop.top + src_y * 2;
2097     case V4L2_FIELD_BOTTOM:
2098         return tpg->crop.top + src_y * 2 + 1;
2099     default:
2100         return src_y + tpg->crop.top;
2101     }
2102 }
2103 
2104 /*
2105  * Map the line number relative to the compose rectangle to a destination
2106  * buffer line number.
2107  */
2108 static unsigned tpg_calc_buffer_line(const struct tpg_data *tpg, unsigned y,
2109                     unsigned field)
2110 {
2111     y += tpg->compose.top;
2112     switch (field) {
2113     case V4L2_FIELD_SEQ_TB:
2114         if (y & 1)
2115             return tpg->buf_height / 2 + y / 2;
2116         return y / 2;
2117     case V4L2_FIELD_SEQ_BT:
2118         if (y & 1)
2119             return y / 2;
2120         return tpg->buf_height / 2 + y / 2;
2121     default:
2122         return y;
2123     }
2124 }
2125 
2126 static void tpg_recalc(struct tpg_data *tpg)
2127 {
2128     if (tpg->recalc_colors) {
2129         tpg->recalc_colors = false;
2130         tpg->recalc_lines = true;
2131         tpg->real_xfer_func = tpg->xfer_func;
2132         tpg->real_ycbcr_enc = tpg->ycbcr_enc;
2133         tpg->real_hsv_enc = tpg->hsv_enc;
2134         tpg->real_quantization = tpg->quantization;
2135 
2136         if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT)
2137             tpg->real_xfer_func =
2138                 V4L2_MAP_XFER_FUNC_DEFAULT(tpg->colorspace);
2139 
2140         if (tpg->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
2141             tpg->real_ycbcr_enc =
2142                 V4L2_MAP_YCBCR_ENC_DEFAULT(tpg->colorspace);
2143 
2144         if (tpg->quantization == V4L2_QUANTIZATION_DEFAULT)
2145             tpg->real_quantization =
2146                 V4L2_MAP_QUANTIZATION_DEFAULT(
2147                     tpg->color_enc != TGP_COLOR_ENC_YCBCR,
2148                     tpg->colorspace, tpg->real_ycbcr_enc);
2149 
2150         tpg_precalculate_colors(tpg);
2151     }
2152     if (tpg->recalc_square_border) {
2153         tpg->recalc_square_border = false;
2154         tpg_calculate_square_border(tpg);
2155     }
2156     if (tpg->recalc_lines) {
2157         tpg->recalc_lines = false;
2158         tpg_precalculate_line(tpg);
2159     }
2160 }
2161 
2162 void tpg_calc_text_basep(struct tpg_data *tpg,
2163         u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf)
2164 {
2165     unsigned stride = tpg->bytesperline[p];
2166     unsigned h = tpg->buf_height;
2167 
2168     tpg_recalc(tpg);
2169 
2170     basep[p][0] = vbuf;
2171     basep[p][1] = vbuf;
2172     h /= tpg->vdownsampling[p];
2173     if (tpg->field == V4L2_FIELD_SEQ_TB)
2174         basep[p][1] += h * stride / 2;
2175     else if (tpg->field == V4L2_FIELD_SEQ_BT)
2176         basep[p][0] += h * stride / 2;
2177     if (p == 0 && tpg->interleaved)
2178         tpg_calc_text_basep(tpg, basep, 1, vbuf);
2179 }
2180 EXPORT_SYMBOL_GPL(tpg_calc_text_basep);
2181 
2182 static int tpg_pattern_avg(const struct tpg_data *tpg,
2183                unsigned pat1, unsigned pat2)
2184 {
2185     unsigned pat_lines = tpg_get_pat_lines(tpg);
2186 
2187     if (pat1 == (pat2 + 1) % pat_lines)
2188         return pat2;
2189     if (pat2 == (pat1 + 1) % pat_lines)
2190         return pat1;
2191     return -1;
2192 }
2193 
2194 static const char *tpg_color_enc_str(enum tgp_color_enc
2195                          color_enc)
2196 {
2197     switch (color_enc) {
2198     case TGP_COLOR_ENC_HSV:
2199         return "HSV";
2200     case TGP_COLOR_ENC_YCBCR:
2201         return "Y'CbCr";
2202     case TGP_COLOR_ENC_LUMA:
2203         return "Luma";
2204     case TGP_COLOR_ENC_RGB:
2205     default:
2206         return "R'G'B";
2207 
2208     }
2209 }
2210 
2211 void tpg_log_status(struct tpg_data *tpg)
2212 {
2213     pr_info("tpg source WxH: %ux%u (%s)\n",
2214         tpg->src_width, tpg->src_height,
2215         tpg_color_enc_str(tpg->color_enc));
2216     pr_info("tpg field: %u\n", tpg->field);
2217     pr_info("tpg crop: %ux%u@%dx%d\n", tpg->crop.width, tpg->crop.height,
2218             tpg->crop.left, tpg->crop.top);
2219     pr_info("tpg compose: %ux%u@%dx%d\n", tpg->compose.width, tpg->compose.height,
2220             tpg->compose.left, tpg->compose.top);
2221     pr_info("tpg colorspace: %d\n", tpg->colorspace);
2222     pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func);
2223     if (tpg->color_enc == TGP_COLOR_ENC_HSV)
2224         pr_info("tpg HSV encoding: %d/%d\n",
2225             tpg->hsv_enc, tpg->real_hsv_enc);
2226     else if (tpg->color_enc == TGP_COLOR_ENC_YCBCR)
2227         pr_info("tpg Y'CbCr encoding: %d/%d\n",
2228             tpg->ycbcr_enc, tpg->real_ycbcr_enc);
2229     pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization);
2230     pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range);
2231 }
2232 EXPORT_SYMBOL_GPL(tpg_log_status);
2233 
2234 /*
2235  * This struct contains common parameters used by both the drawing of the
2236  * test pattern and the drawing of the extras (borders, square, etc.)
2237  */
2238 struct tpg_draw_params {
2239     /* common data */
2240     bool is_tv;
2241     bool is_60hz;
2242     unsigned twopixsize;
2243     unsigned img_width;
2244     unsigned stride;
2245     unsigned hmax;
2246     unsigned frame_line;
2247     unsigned frame_line_next;
2248 
2249     /* test pattern */
2250     unsigned mv_hor_old;
2251     unsigned mv_hor_new;
2252     unsigned mv_vert_old;
2253     unsigned mv_vert_new;
2254 
2255     /* extras */
2256     unsigned wss_width;
2257     unsigned wss_random_offset;
2258     unsigned sav_eav_f;
2259     unsigned left_pillar_width;
2260     unsigned right_pillar_start;
2261 };
2262 
2263 static void tpg_fill_params_pattern(const struct tpg_data *tpg, unsigned p,
2264                     struct tpg_draw_params *params)
2265 {
2266     params->mv_hor_old =
2267         tpg_hscale_div(tpg, p, tpg->mv_hor_count % tpg->src_width);
2268     params->mv_hor_new =
2269         tpg_hscale_div(tpg, p, (tpg->mv_hor_count + tpg->mv_hor_step) %
2270                    tpg->src_width);
2271     params->mv_vert_old = tpg->mv_vert_count % tpg->src_height;
2272     params->mv_vert_new =
2273         (tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height;
2274 }
2275 
2276 static void tpg_fill_params_extras(const struct tpg_data *tpg,
2277                    unsigned p,
2278                    struct tpg_draw_params *params)
2279 {
2280     unsigned left_pillar_width = 0;
2281     unsigned right_pillar_start = params->img_width;
2282 
2283     params->wss_width = tpg->crop.left < tpg->src_width / 2 ?
2284         tpg->src_width / 2 - tpg->crop.left : 0;
2285     if (params->wss_width > tpg->crop.width)
2286         params->wss_width = tpg->crop.width;
2287     params->wss_width = tpg_hscale_div(tpg, p, params->wss_width);
2288     params->wss_random_offset =
2289         params->twopixsize * prandom_u32_max(tpg->src_width / 2);
2290 
2291     if (tpg->crop.left < tpg->border.left) {
2292         left_pillar_width = tpg->border.left - tpg->crop.left;
2293         if (left_pillar_width > tpg->crop.width)
2294             left_pillar_width = tpg->crop.width;
2295         left_pillar_width = tpg_hscale_div(tpg, p, left_pillar_width);
2296     }
2297     params->left_pillar_width = left_pillar_width;
2298 
2299     if (tpg->crop.left + tpg->crop.width >
2300         tpg->border.left + tpg->border.width) {
2301         right_pillar_start =
2302             tpg->border.left + tpg->border.width - tpg->crop.left;
2303         right_pillar_start =
2304             tpg_hscale_div(tpg, p, right_pillar_start);
2305         if (right_pillar_start > params->img_width)
2306             right_pillar_start = params->img_width;
2307     }
2308     params->right_pillar_start = right_pillar_start;
2309 
2310     params->sav_eav_f = tpg->field ==
2311             (params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
2312 }
2313 
2314 static void tpg_fill_plane_extras(const struct tpg_data *tpg,
2315                   const struct tpg_draw_params *params,
2316                   unsigned p, unsigned h, u8 *vbuf)
2317 {
2318     unsigned twopixsize = params->twopixsize;
2319     unsigned img_width = params->img_width;
2320     unsigned frame_line = params->frame_line;
2321     const struct v4l2_rect *sq = &tpg->square;
2322     const struct v4l2_rect *b = &tpg->border;
2323     const struct v4l2_rect *c = &tpg->crop;
2324 
2325     if (params->is_tv && !params->is_60hz &&
2326         frame_line == 0 && params->wss_width) {
2327         /*
2328          * Replace the first half of the top line of a 50 Hz frame
2329          * with random data to simulate a WSS signal.
2330          */
2331         u8 *wss = tpg->random_line[p] + params->wss_random_offset;
2332 
2333         memcpy(vbuf, wss, params->wss_width);
2334     }
2335 
2336     if (tpg->show_border && frame_line >= b->top &&
2337         frame_line < b->top + b->height) {
2338         unsigned bottom = b->top + b->height - 1;
2339         unsigned left = params->left_pillar_width;
2340         unsigned right = params->right_pillar_start;
2341 
2342         if (frame_line == b->top || frame_line == b->top + 1 ||
2343             frame_line == bottom || frame_line == bottom - 1) {
2344             memcpy(vbuf + left, tpg->contrast_line[p],
2345                     right - left);
2346         } else {
2347             if (b->left >= c->left &&
2348                 b->left < c->left + c->width)
2349                 memcpy(vbuf + left,
2350                     tpg->contrast_line[p], twopixsize);
2351             if (b->left + b->width > c->left &&
2352                 b->left + b->width <= c->left + c->width)
2353                 memcpy(vbuf + right - twopixsize,
2354                     tpg->contrast_line[p], twopixsize);
2355         }
2356     }
2357     if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top &&
2358         frame_line < b->top + b->height) {
2359         memcpy(vbuf, tpg->black_line[p], params->left_pillar_width);
2360         memcpy(vbuf + params->right_pillar_start, tpg->black_line[p],
2361                img_width - params->right_pillar_start);
2362     }
2363     if (tpg->show_square && frame_line >= sq->top &&
2364         frame_line < sq->top + sq->height &&
2365         sq->left < c->left + c->width &&
2366         sq->left + sq->width >= c->left) {
2367         unsigned left = sq->left;
2368         unsigned width = sq->width;
2369 
2370         if (c->left > left) {
2371             width -= c->left - left;
2372             left = c->left;
2373         }
2374         if (c->left + c->width < left + width)
2375             width -= left + width - c->left - c->width;
2376         left -= c->left;
2377         left = tpg_hscale_div(tpg, p, left);
2378         width = tpg_hscale_div(tpg, p, width);
2379         memcpy(vbuf + left, tpg->contrast_line[p], width);
2380     }
2381     if (tpg->insert_sav) {
2382         unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width / 3);
2383         u8 *p = vbuf + offset;
2384         unsigned vact = 0, hact = 0;
2385 
2386         p[0] = 0xff;
2387         p[1] = 0;
2388         p[2] = 0;
2389         p[3] = 0x80 | (params->sav_eav_f << 6) |
2390             (vact << 5) | (hact << 4) |
2391             ((hact ^ vact) << 3) |
2392             ((hact ^ params->sav_eav_f) << 2) |
2393             ((params->sav_eav_f ^ vact) << 1) |
2394             (hact ^ vact ^ params->sav_eav_f);
2395     }
2396     if (tpg->insert_eav) {
2397         unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width * 2 / 3);
2398         u8 *p = vbuf + offset;
2399         unsigned vact = 0, hact = 1;
2400 
2401         p[0] = 0xff;
2402         p[1] = 0;
2403         p[2] = 0;
2404         p[3] = 0x80 | (params->sav_eav_f << 6) |
2405             (vact << 5) | (hact << 4) |
2406             ((hact ^ vact) << 3) |
2407             ((hact ^ params->sav_eav_f) << 2) |
2408             ((params->sav_eav_f ^ vact) << 1) |
2409             (hact ^ vact ^ params->sav_eav_f);
2410     }
2411     if (tpg->insert_hdmi_video_guard_band) {
2412         unsigned int i;
2413 
2414         switch (tpg->fourcc) {
2415         case V4L2_PIX_FMT_BGR24:
2416         case V4L2_PIX_FMT_RGB24:
2417             for (i = 0; i < 3 * 4; i += 3) {
2418                 vbuf[i] = 0xab;
2419                 vbuf[i + 1] = 0x55;
2420                 vbuf[i + 2] = 0xab;
2421             }
2422             break;
2423         case V4L2_PIX_FMT_RGB32:
2424         case V4L2_PIX_FMT_ARGB32:
2425         case V4L2_PIX_FMT_XRGB32:
2426         case V4L2_PIX_FMT_BGRX32:
2427         case V4L2_PIX_FMT_BGRA32:
2428             for (i = 0; i < 4 * 4; i += 4) {
2429                 vbuf[i] = 0x00;
2430                 vbuf[i + 1] = 0xab;
2431                 vbuf[i + 2] = 0x55;
2432                 vbuf[i + 3] = 0xab;
2433             }
2434             break;
2435         case V4L2_PIX_FMT_BGR32:
2436         case V4L2_PIX_FMT_XBGR32:
2437         case V4L2_PIX_FMT_ABGR32:
2438         case V4L2_PIX_FMT_RGBX32:
2439         case V4L2_PIX_FMT_RGBA32:
2440             for (i = 0; i < 4 * 4; i += 4) {
2441                 vbuf[i] = 0xab;
2442                 vbuf[i + 1] = 0x55;
2443                 vbuf[i + 2] = 0xab;
2444                 vbuf[i + 3] = 0x00;
2445             }
2446             break;
2447         }
2448     }
2449 }
2450 
2451 static void tpg_fill_plane_pattern(const struct tpg_data *tpg,
2452                    const struct tpg_draw_params *params,
2453                    unsigned p, unsigned h, u8 *vbuf)
2454 {
2455     unsigned twopixsize = params->twopixsize;
2456     unsigned img_width = params->img_width;
2457     unsigned mv_hor_old = params->mv_hor_old;
2458     unsigned mv_hor_new = params->mv_hor_new;
2459     unsigned mv_vert_old = params->mv_vert_old;
2460     unsigned mv_vert_new = params->mv_vert_new;
2461     unsigned frame_line = params->frame_line;
2462     unsigned frame_line_next = params->frame_line_next;
2463     unsigned line_offset = tpg_hscale_div(tpg, p, tpg->crop.left);
2464     bool even;
2465     bool fill_blank = false;
2466     unsigned pat_line_old;
2467     unsigned pat_line_new;
2468     u8 *linestart_older;
2469     u8 *linestart_newer;
2470     u8 *linestart_top;
2471     u8 *linestart_bottom;
2472 
2473     even = !(frame_line & 1);
2474 
2475     if (h >= params->hmax) {
2476         if (params->hmax == tpg->compose.height)
2477             return;
2478         if (!tpg->perc_fill_blank)
2479             return;
2480         fill_blank = true;
2481     }
2482 
2483     if (tpg->vflip) {
2484         frame_line = tpg->src_height - frame_line - 1;
2485         frame_line_next = tpg->src_height - frame_line_next - 1;
2486     }
2487 
2488     if (fill_blank) {
2489         linestart_older = tpg->contrast_line[p];
2490         linestart_newer = tpg->contrast_line[p];
2491     } else if (tpg->qual != TPG_QUAL_NOISE &&
2492            (frame_line < tpg->border.top ||
2493             frame_line >= tpg->border.top + tpg->border.height)) {
2494         linestart_older = tpg->black_line[p];
2495         linestart_newer = tpg->black_line[p];
2496     } else if (tpg->pattern == TPG_PAT_NOISE || tpg->qual == TPG_QUAL_NOISE) {
2497         linestart_older = tpg->random_line[p] +
2498                   twopixsize * prandom_u32_max(tpg->src_width / 2);
2499         linestart_newer = tpg->random_line[p] +
2500                   twopixsize * prandom_u32_max(tpg->src_width / 2);
2501     } else {
2502         unsigned frame_line_old =
2503             (frame_line + mv_vert_old) % tpg->src_height;
2504         unsigned frame_line_new =
2505             (frame_line + mv_vert_new) % tpg->src_height;
2506         unsigned pat_line_next_old;
2507         unsigned pat_line_next_new;
2508 
2509         pat_line_old = tpg_get_pat_line(tpg, frame_line_old);
2510         pat_line_new = tpg_get_pat_line(tpg, frame_line_new);
2511         linestart_older = tpg->lines[pat_line_old][p] + mv_hor_old;
2512         linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new;
2513 
2514         if (tpg->vdownsampling[p] > 1 && frame_line != frame_line_next) {
2515             int avg_pat;
2516 
2517             /*
2518              * Now decide whether we need to use downsampled_lines[].
2519              * That's necessary if the two lines use different patterns.
2520              */
2521             pat_line_next_old = tpg_get_pat_line(tpg,
2522                     (frame_line_next + mv_vert_old) % tpg->src_height);
2523             pat_line_next_new = tpg_get_pat_line(tpg,
2524                     (frame_line_next + mv_vert_new) % tpg->src_height);
2525 
2526             switch (tpg->field) {
2527             case V4L2_FIELD_INTERLACED:
2528             case V4L2_FIELD_INTERLACED_BT:
2529             case V4L2_FIELD_INTERLACED_TB:
2530                 avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_new);
2531                 if (avg_pat < 0)
2532                     break;
2533                 linestart_older = tpg->downsampled_lines[avg_pat][p] + mv_hor_old;
2534                 linestart_newer = linestart_older;
2535                 break;
2536             case V4L2_FIELD_NONE:
2537             case V4L2_FIELD_TOP:
2538             case V4L2_FIELD_BOTTOM:
2539             case V4L2_FIELD_SEQ_BT:
2540             case V4L2_FIELD_SEQ_TB:
2541                 avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_next_old);
2542                 if (avg_pat >= 0)
2543                     linestart_older = tpg->downsampled_lines[avg_pat][p] +
2544                         mv_hor_old;
2545                 avg_pat = tpg_pattern_avg(tpg, pat_line_new, pat_line_next_new);
2546                 if (avg_pat >= 0)
2547                     linestart_newer = tpg->downsampled_lines[avg_pat][p] +
2548                         mv_hor_new;
2549                 break;
2550             }
2551         }
2552         linestart_older += line_offset;
2553         linestart_newer += line_offset;
2554     }
2555     if (tpg->field_alternate) {
2556         linestart_top = linestart_bottom = linestart_older;
2557     } else if (params->is_60hz) {
2558         linestart_top = linestart_newer;
2559         linestart_bottom = linestart_older;
2560     } else {
2561         linestart_top = linestart_older;
2562         linestart_bottom = linestart_newer;
2563     }
2564 
2565     switch (tpg->field) {
2566     case V4L2_FIELD_INTERLACED:
2567     case V4L2_FIELD_INTERLACED_TB:
2568     case V4L2_FIELD_SEQ_TB:
2569     case V4L2_FIELD_SEQ_BT:
2570         if (even)
2571             memcpy(vbuf, linestart_top, img_width);
2572         else
2573             memcpy(vbuf, linestart_bottom, img_width);
2574         break;
2575     case V4L2_FIELD_INTERLACED_BT:
2576         if (even)
2577             memcpy(vbuf, linestart_bottom, img_width);
2578         else
2579             memcpy(vbuf, linestart_top, img_width);
2580         break;
2581     case V4L2_FIELD_TOP:
2582         memcpy(vbuf, linestart_top, img_width);
2583         break;
2584     case V4L2_FIELD_BOTTOM:
2585         memcpy(vbuf, linestart_bottom, img_width);
2586         break;
2587     case V4L2_FIELD_NONE:
2588     default:
2589         memcpy(vbuf, linestart_older, img_width);
2590         break;
2591     }
2592 }
2593 
2594 void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
2595                unsigned p, u8 *vbuf)
2596 {
2597     struct tpg_draw_params params;
2598     unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
2599 
2600     /* Coarse scaling with Bresenham */
2601     unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height;
2602     unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height;
2603     unsigned src_y = 0;
2604     unsigned error = 0;
2605     unsigned h;
2606 
2607     tpg_recalc(tpg);
2608 
2609     params.is_tv = std;
2610     params.is_60hz = std & V4L2_STD_525_60;
2611     params.twopixsize = tpg->twopixelsize[p];
2612     params.img_width = tpg_hdiv(tpg, p, tpg->compose.width);
2613     params.stride = tpg->bytesperline[p];
2614     params.hmax = (tpg->compose.height * tpg->perc_fill) / 100;
2615 
2616     tpg_fill_params_pattern(tpg, p, &params);
2617     tpg_fill_params_extras(tpg, p, &params);
2618 
2619     vbuf += tpg_hdiv(tpg, p, tpg->compose.left);
2620 
2621     for (h = 0; h < tpg->compose.height; h++) {
2622         unsigned buf_line;
2623 
2624         params.frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
2625         params.frame_line_next = params.frame_line;
2626         buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
2627         src_y += int_part;
2628         error += fract_part;
2629         if (error >= tpg->compose.height) {
2630             error -= tpg->compose.height;
2631             src_y++;
2632         }
2633 
2634         /*
2635          * For line-interleaved formats determine the 'plane'
2636          * based on the buffer line.
2637          */
2638         if (tpg_g_interleaved(tpg))
2639             p = tpg_g_interleaved_plane(tpg, buf_line);
2640 
2641         if (tpg->vdownsampling[p] > 1) {
2642             /*
2643              * When doing vertical downsampling the field setting
2644              * matters: for SEQ_BT/TB we downsample each field
2645              * separately (i.e. lines 0+2 are combined, as are
2646              * lines 1+3), for the other field settings we combine
2647              * odd and even lines. Doing that for SEQ_BT/TB would
2648              * be really weird.
2649              */
2650             if (tpg->field == V4L2_FIELD_SEQ_BT ||
2651                 tpg->field == V4L2_FIELD_SEQ_TB) {
2652                 unsigned next_src_y = src_y;
2653 
2654                 if ((h & 3) >= 2)
2655                     continue;
2656                 next_src_y += int_part;
2657                 if (error + fract_part >= tpg->compose.height)
2658                     next_src_y++;
2659                 params.frame_line_next =
2660                     tpg_calc_frameline(tpg, next_src_y, tpg->field);
2661             } else {
2662                 if (h & 1)
2663                     continue;
2664                 params.frame_line_next =
2665                     tpg_calc_frameline(tpg, src_y, tpg->field);
2666             }
2667 
2668             buf_line /= tpg->vdownsampling[p];
2669         }
2670         tpg_fill_plane_pattern(tpg, &params, p, h,
2671                 vbuf + buf_line * params.stride);
2672         tpg_fill_plane_extras(tpg, &params, p, h,
2673                 vbuf + buf_line * params.stride);
2674     }
2675 }
2676 EXPORT_SYMBOL_GPL(tpg_fill_plane_buffer);
2677 
2678 void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
2679 {
2680     unsigned offset = 0;
2681     unsigned i;
2682 
2683     if (tpg->buffers > 1) {
2684         tpg_fill_plane_buffer(tpg, std, p, vbuf);
2685         return;
2686     }
2687 
2688     for (i = 0; i < tpg_g_planes(tpg); i++) {
2689         tpg_fill_plane_buffer(tpg, std, i, vbuf + offset);
2690         offset += tpg_calc_plane_size(tpg, i);
2691     }
2692 }
2693 EXPORT_SYMBOL_GPL(tpg_fillbuffer);
2694 
2695 MODULE_DESCRIPTION("V4L2 Test Pattern Generator");
2696 MODULE_AUTHOR("Hans Verkuil");
2697 MODULE_LICENSE("GPL");