v4l2-tpg-core.c 69 KB

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