Advertisement
Guest User

edi_rpow2

a guest
Mar 19th, 2017
419
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Avisynth 40.42 KB | None | 0 0
  1. /* edi_rpow2 v1.0 mod 2
  2.  
  3. An improved rpow2 function for nnedi3, nnedi3ocl, eedi3, and eedi2.
  4.  
  5.  
  6. ##### Requirements #####
  7.  
  8. Plugins:
  9.   Dither
  10.   eedi2
  11.   eedi3
  12.   FTurn
  13.   MaskTools2
  14.   nnedi3
  15.   nnedi3ocl
  16.  
  17. Scripts:
  18.   ResizeX
  19.  
  20. Dither is only required if lsb=true.
  21. FTurn is optional but recommended.
  22. MaskTools2 is only required if eedi3's mclip parameter is used.
  23.  
  24. Color formats:
  25.   Y8, YV12, YV16, YUY2, YV411, YV24, RGB24
  26.    
  27. Using eedi2 on RGB24 isn't recommended as it can cause discoloration.
  28.  
  29.  
  30. ##### Common Parameters ######
  31.  
  32. int rfactorX, int rfactorY (defaults: 2, rfactorX)
  33. --------------------------------------------------
  34. The horizontal and vertical image enlargement factors. Must be a power of 2.
  35. This includes 1, meaning no enlargement in that direction.
  36.  
  37.  
  38. string edi (default: "nnedi3")
  39. ------------------------------
  40. The edi method to use for image enlargement.
  41. Options are "nnedi3", "nnedi3ocl", "eedi3", and "eedi2".
  42.  
  43.  
  44. string cshift (default: "")
  45. ---------------------------
  46. The resize kernel to use for correcting the image center shift caused by
  47. image enlargement and for scaling to the final output resolution.
  48. It can be any kernel supported by ResizeX, although kernels exclusive to
  49. Dither_resize16 can only be used if lsb=true.
  50.  
  51.  
  52. int fwidth, int fheight (defaults: width*rfactorX, height*rfactorY)
  53. -------------------------------------------------------------------
  54. The final output width and height to scale to after image enlargement.
  55. These settings have no effect unless cshift is specified.
  56.  
  57.  
  58. int taps (default: undefined)
  59. -----------------------------
  60. The number of taps to use for the cshift kernel.
  61. Only applies to the Blackman, Blackmanminlobe, Lanczos, Sinc, and Spline kernels.
  62.  
  63.  
  64. float a1, float a2 (defaults: undefined)
  65. ----------------------------------------
  66. If cshift="Bicubic", these set the b and c values.
  67. If cshift="Gauss", a1 sets the p value.
  68.  
  69.  
  70. string cplace (default: "MPEG2")
  71. --------------------------------
  72. Specifies the input's chroma placement. Options are "MPEG1" and "MPEG2".
  73. Only applies to formats with subsampled chroma.
  74. Note that only YV12 should be able to have MPEG1 chroma placement.
  75.  
  76.  
  77. bool Y, bool U, bool V (defaults: true)
  78. ---------------------------------------
  79. Controls whether the specified plane is processed or not.
  80. These settings have no effect for RGB24 input.
  81.  
  82.  
  83. bool lsb (default: false)
  84. -------------------------
  85. When set to true, Dither_resize16 will be used to correct the image
  86. center shift if applicable and the output will be in stack16 format.
  87. If the input is RGB24, the output will be in the RGB48Y format used by Dither.
  88. It can be converted back to RGB24 with the following script:
  89.  
  90.      DitherPost()
  91.      MergeRGB(SelectEvery(3,0),SelectEvery(3,1),SelectEvery(3,2),"RGB24")
  92.  
  93.  
  94. bool bordfix (default: true)
  95. ----------------------------
  96. nnedi3, nnedi3ocl, and eedi2 cause lines at the edge of the frame to distort slightly.
  97. When set to true, the distortion is avoided by padding the frame with rows of
  98. duplicate pixels before image enlargement and then cropping the padding off afterward.
  99. Defaults to false when edi="eedi3" because it isn't needed when using eedi3.
  100.  
  101.  
  102. bool YV12cfix (default: true)
  103. -----------------------------
  104. Enlarging YV12 vertically causes a small chroma shift that's corrected by
  105. resizing the chroma channels even when not correcting the image center shift.
  106. When set to false, the chroma shift won't be corrected, providing
  107. output that hasn't been resized at all after image enlargement.
  108. Only applies when the input is YV12 and the center shift isn't corrected.
  109.  
  110.  
  111. ##### nnedi3 Parameters ######
  112.  
  113. int nsize, int nns, int qual, int etype, int pscrn, int threads, int opt, int fapprox
  114. -------------------------------------------------------------------------------------
  115. See nnedi3's documentation for explanations of these parameters.
  116. Like nnedi3_rpow2, defaults are nsize=0, nns=3, and the rest are the same as nnedi3.
  117.  
  118.  
  119. ##### nnedi3ocl Parameters ######
  120.  
  121. int nsize, int nns, int qual, int etype
  122. ---------------------------------------
  123. Same as nnedi3's parameters.
  124. As of the 2013.12.08-beta version, only nsize=0 is implemented. Other nsize values are ignored.
  125. Like nnedi3x_rpow2, defaults are nsize=0, nns=3, and the rest are the same as nnedi3.
  126.  
  127.  
  128. ##### eedi3 Parameters ######
  129.  
  130. float alpha, float beta, float gamma, int nrad, int mdis, bool hp, bool ucubic, bool cost3, int vcheck,
  131. float vthresh0, float vthresh1, float vthresh2, string sclip, string sclip_params, clip mclip, int threads, int opt
  132. -------------------------------------------------------------------------------------------------------------------
  133. See eedi3's documentation for explanations of these parameters.
  134.  
  135.  
  136. string sclip (default: "")
  137. --------------------------
  138. Unlike eedi3, the sclip parameter in edi_rpow2 takes a string rather than a clip.
  139. It specifies what resize kernel or edi method to use to generate the sclip.
  140. All of AviSynth's internal resize kernels, ResizeX's bicubic presets,
  141. "nnedi3", "nnedi3ocl", and "eedi2" are supported.
  142.  
  143.  
  144. string sclip_params (default: "")
  145. ---------------------------------
  146. Used to pass parameters to ResizeX, nnedi3, nnedi3ocl, or eedi2 when generating the sclip.
  147. If nnedi3 or nnedi3ocl is used, it defaults to "nsize=0, nns=3".
  148.  
  149.  
  150. clip mclip (default: undefined)
  151. -------------------------------
  152. The mclip should be the same resolution and colorspace as the input, with the exception of Y8 and RGB24.
  153. If the input is Y8 or RGB24, the mclip can be any YUV format, but only its luma channel will be used.
  154. The mclip is automatically scaled to the appropriate resolution for each iteration of image enlargement.
  155.  
  156.  
  157. Other parameters are the same as eedi3.
  158.  
  159.  
  160. ##### eedi2 Parameters ######
  161.  
  162. int mthresh, int lthresh, int vthresh, int estr, int dstr, int maxd, int map, int nt, int pp
  163. --------------------------------------------------------------------------------------------
  164. See eedi2's documentation for explanations of these parameters.
  165. Defaults are the same as eedi2.
  166. */
  167.  
  168. function edi_rpow2(clip input, int "rfactorX", int "rfactorY", string "edi", string "cshift", int "fwidth", int "fheight",
  169. \                  int "taps", float "a1", float "a2", string "cplace", bool "Y", bool "U", bool "V", bool "lsb", bool "bordfix", bool "YV12cfix",
  170. \                  int "nsize", int "nns", int "qual", int "etype", int "pscrn", int "threads", int "opt", int "fapprox",
  171. \                  float "alpha", float "beta", float "gamma", int "nrad", int "mdis", bool "hp", bool "ucubic", bool "cost3",
  172. \                  int "vcheck", float "vthresh0", float "vthresh1", float "vthresh2", string "sclip", string "sclip_params", clip "mclip",
  173. \                  int "mthresh", int "lthresh", int "vthresh", int "estr", int "dstr", int "maxd", int "map", int "nt", int "pp", bool "mt", string "mt_params") {
  174.  
  175. # Row 1-2: Common parameters
  176. # Row 3:   nnedi3 and nnedi3ocl parameters
  177. # Row 4-5: eedi3 parameters (also threads and opt)
  178. # Row 6:   eedi2 parameters
  179.  
  180. iw = input.Width()
  181. ih = input.Height()
  182.  
  183. rfactorX  = Default(rfactorX, 2)
  184. rfactorY  = Default(rfactorY, rfactorX)
  185. edi       = Default(edi, "nnedi3")
  186. cshift    = Default(cshift, "")
  187. fwidth    = Default(fwidth, iw*rfactorX)
  188. fheight   = Default(fheight, ih*rfactorY)
  189. cplace    = Default(cplace, "MPEG2")
  190. Y         = Default(Y, true)
  191. U         = Default(U, true)
  192. V         = Default(V, true)
  193. lsb       = Default(lsb, false)
  194. bordfix   = Default(bordfix, edi != "eedi3" ? true : false)
  195. YV12cfix  = Default(YV12cfix, true)
  196. nsize     = Default(nsize, 0)
  197. nns       = Default(nns, 3)
  198.  
  199. sispmt  = Findstr(VersionString(), "AviSynth+") != 0 && Findstr(VersionString(), "r1576") == 0
  200.  
  201. Assert(rfactorX > 0 && BitAnd(rfactorX,rfactorX-1) == 0, "edi_rpow2: rfactorX must be a power of 2")
  202. Assert(rfactorY > 0 && BitAnd(rfactorY,rfactorY-1) == 0, "edi_rpow2: rfactorY must be a power of 2")
  203. Assert(edi == "nnedi3" || edi == "nnedi3ocl" || edi == "eedi3" || edi == "eedi2", "edi_rpow2: invalid edi setting")
  204. Assert(cplace == "MPEG1" || cplace == "MPEG2", "edi_rpow2: cplace must be MPEG1 or MPEG2")
  205. Assert(!mclip.Defined() || mclip.Defined() && mclip.IsYUV(), "edi_rpow2: eedi3 mclip must be YUV")
  206. lsb_native = sispmt ? !(Input.BitsPerComponent() > 8 && (lsb)) : true
  207. sispmt ? Assert(lsb_native, "lsb hack is not Compatible with native high bit depth" ) : nop()
  208. sispmt ? Assert(!(Input.isYUVA() && lsb), "lsb hack is not Compatible with YUVA" ) : nop()
  209.  
  210. # Override the fwidth and fheight parameters if not correcting the center shift
  211. ffwidth  = cshift == "" ? iw*rfactorX : fwidth
  212. ffheight = cshift == "" ? ih*rfactorY : fheight
  213.  
  214. # Get the input clip's colorspace
  215. csp = input.PixelType()
  216.  
  217. chr420  = sispmt ? input.is420() : input.isyv12()
  218. chr422  = sispmt ? input.is422() : input.isYV16()
  219. chr444  = sispmt ? input.is444() : input.isYV24()
  220.  
  221. # Check for subsampled chroma
  222. hssc12 = chr420  || chr422 || csp == "YUY2"
  223. hssc14 = csp == "YV411"
  224. vssc12 = chr420
  225. alignc = hssc12 || hssc14
  226.  
  227. Assert(!hssc12 || ffwidth%2  == 0, "edi_rpow2: fwidth of "+csp+" must be a multiple of 2")
  228. Assert(!hssc14 || ffwidth%4  == 0, "edi_rpow2: fwidth of "+csp+" must be a multiple of 4")
  229. Assert(!vssc12 || ffheight%2 == 0, "edi_rpow2: fheight of "+csp+" must be a multiple of 2")
  230.  
  231. # Input and output chroma width and height determined by subsampling
  232. iw_c      = hssc12 ? iw/2 : hssc14 ? iw/4 : iw
  233. ih_c      = vssc12 ? ih/2 : ih
  234. fwidth_c  = hssc12 ? ffwidth/2 : hssc14 ? ffwidth/4 : ffwidth
  235. fheight_c = vssc12 ? ffheight/2 : ffheight
  236.  
  237. # Center shift correction values
  238. cshiftH   = rfactorX == 1    ?  0
  239. \         : hssc12 || hssc14 ? -0.5*(rfactorX-1)
  240. \                            : -0.5
  241. cshiftV   = rfactorY == 1    ?  0
  242. \                            : -0.5
  243. cshiftH_c = hssc12 ? cshiftH/2.0
  244. \         : hssc14 ? cshiftH/4.0
  245. \                  : cshiftH
  246. cshiftV_c = vssc12 && rfactorY > 1 ? cshiftV/2.0-0.25
  247. \                                  : cshiftV
  248.  
  249. # Add the MPEG1 or MPEG2 chroma shift correction to the cshiftH_c value
  250. no_MPEG2shift_kernel = cshift.LeftStr(5) == "Point" ||
  251. \                      cshift.LeftStr(4) == "Rect"  ||
  252. \                      cshift.LeftStr(3) == "Box"    ? true : false
  253. MPEG1shift = hssc12 ? -0.25*(rfactorX-1)
  254. \          : hssc14 ? -0.375*(rfactorX-1)
  255. \                   : 0
  256. MPEG2shift = hssc12 ? 0.25*(1.0-Float(iw_c*rfactorX)/Float(fwidth_c))
  257. \          : hssc14 ? 0.375*(1.0-Float(iw_c*rfactorX)/Float(fwidth_c))
  258. \                   : 0
  259. cshiftH_c = cplace == "MPEG1"     ? cshiftH_c+MPEG1shift
  260. \         : cplace == "MPEG2"    &&
  261. \           !no_MPEG2shift_kernel ? cshiftH_c+MPEG2shift
  262. \                                 : cshiftH_c
  263.  
  264. # Pad the frame with rows of duplicate pixels to support mod1 and mod2
  265. # resolutions with eedi3 and eedi2 since they have to work in YV12.
  266. # Also pad at least four rows if bordfix=true.
  267. iw_ismod8 = iw%8 == 0 ? true : false
  268. ih_ismod8 = ih%8 == 0 ? true : false
  269. iw_ismod4 = iw%4 == 0 ? true : false
  270. ih_ismod4 = ih%4 == 0 ? true : false
  271.  
  272. pad8 = edi == "eedi3" && hssc14 && !iw_ismod8 ||
  273. \      edi == "eedi3" && hssc14 && !ih_ismod8 ||
  274. \      edi == "eedi2" && hssc14 && !iw_ismod8 ||
  275. \      edi == "eedi2" && hssc14 && !ih_ismod8  ? true : false
  276. pad4 = edi == "eedi3" && !chr420 && !iw_ismod4 ||
  277. \      edi == "eedi3" && !chr420 && !ih_ismod4 ||
  278. \      edi == "eedi2" && !chr420 && !iw_ismod4 ||
  279. \      edi == "eedi2" && !chr420 && !ih_ismod4  ? true : false
  280. pad  = pad8 || pad4 ? true : false
  281.  
  282. padR = pad8 && !iw_ismod8 ? 8-iw%8
  283. \    : pad4 && !iw_ismod4 ? 4-iw%4
  284. \                         : 0
  285. padT = pad8 && !ih_ismod8 ? 8-ih%8
  286. \    : pad4 && !ih_ismod4 ? 4-ih%4
  287. \                         : 0
  288.  
  289. padR = padR >= 4                       ? padR
  290. \    : bordfix && rfactorX > 1         ? padR+4
  291. \                                      : padR
  292. padT = padT >= 4                       ? padT
  293. \    : bordfix && rfactorY > 1         ? padT+4
  294. \                                      : padT
  295. padL = bordfix && rfactorX > 1 && pad8 ? 8
  296. \    : bordfix && rfactorX > 1         ? 4
  297. \                                      : 0
  298. padB = bordfix && rfactorY > 1 && pad8 ? 8
  299. \    : bordfix && rfactorY > 1         ? 4
  300. \                                      : 0
  301.  
  302. padL_c = hssc12 ? padL/2 : hssc14 ? padL/4 : padL
  303. padT_c = vssc12 ? padT/2 : padT
  304. padR_c = hssc12 ? padR/2 : hssc14 ? padR/4 : padR
  305. padB_c = vssc12 ? padB/2 : padB
  306.  
  307. einput = pad || bordfix ? input.ResizeX(iw+padL+padR, ih+padT+padB, -padL, -padT, iw+padL+padR, ih+padT+padB,
  308. \                                       kernel="Point", luma=Y, chroma=U||V?true:false,mt=mt,mt_params=mt_params)
  309. \                       : input
  310. emclip = mclip.Defined() && pad     ||
  311. \        mclip.Defined() && bordfix  ? mclip.ResizeX(iw+padL+padR, ih+padT+padB, -padL, -padT, iw+padL+padR, ih+padT+padB,
  312. \                                                   kernel="Point", luma=Y, chroma=U||V?true:false,mt=mt,mt_params=mt_params)
  313. \                                    : mclip
  314.  
  315. # nnedi3 image enlargement
  316.     edi == "nnedi3" && (sispmt ? input.isy() : csp == "Y8") ?
  317. \   Eval("""
  318.         pow2  = einput.edi_rpow2_nnedi3(rfactorX,rfactorY,alignc,true,false,false,nsize,nns,qual,etype,pscrn,threads,opt,fapprox)
  319.         """)
  320. \ : edi == "nnedi3" && chr420  ||
  321. \   edi == "nnedi3" && chr422  ||
  322. \   edi == "nnedi3" && csp == "YUY2"  ||
  323. \   edi == "nnedi3" && csp == "YV411" ||
  324. \   edi == "nnedi3" && chr444   ?
  325. \   Eval("""
  326.         # For nnedi3 and nnedi3ocl, it's faster to split YV12 channels into separate Y8 clips even though they don't need to be
  327.         pow2Y = einput.ConvertToY8().edi_rpow2_nnedi3(rfactorX,rfactorY,alignc,true,false,false,nsize,nns,qual,etype,pscrn,threads,opt,fapprox)
  328.         pow2U = einput.UToY8().edi_rpow2_nnedi3(rfactorX,rfactorY,alignc,true,false,false,nsize,nns,qual,etype,pscrn,threads,opt,fapprox)
  329.         pow2V = einput.VToY8().edi_rpow2_nnedi3(rfactorX,rfactorY,alignc,true,false,false,nsize,nns,qual,etype,pscrn,threads,opt,fapprox)
  330.         """)
  331. \ : edi == "nnedi3" && input.isrgb() ?
  332. \   Eval("""
  333.         # If using FTurn, it's faster to split RGB24 channels into an interleaved Y8 clip because FTurn doesn't support RGB24
  334.         try {
  335.             sispmt || csp != "RGB24" ? dontdoft : nop()
  336.             tft  = BlankClip(pixel_type="Y8").FTurnRight()
  337.             pow2 = Interleave(einput.ShowRed("Y8"),einput.ShowGreen("Y8"),einput.ShowBlue("Y8"))
  338.             pow2 = pow2.edi_rpow2_nnedi3(rfactorX,rfactorY,alignc,true,false,false,nsize,nns,qual,etype,pscrn,threads,opt,fapprox)
  339.             splitRGB24 = true
  340.             }
  341.         catch(err_msg) {
  342.             pow2 = einput.edi_rpow2_nnedi3(rfactorX,rfactorY,alignc,true,true,true,nsize,nns,qual,etype,pscrn,threads,opt,fapprox)
  343.             splitRGB24 = false
  344.             }
  345.         """)
  346. \ : NOP()
  347.  
  348. # nnedi3ocl image enlargement
  349.     edi == "nnedi3ocl" && (sispmt ? input.isy() : csp == "Y8") ?
  350. \   Eval("""
  351.         pow2  = einput.edi_rpow2_nnedi3ocl(rfactorX,rfactorY,alignc,true,false,false,nsize,nns,qual,etype)
  352.         """)
  353. \ : edi == "nnedi3ocl" && chr420  ||
  354. \   edi == "nnedi3ocl" && chr422  ||
  355. \   edi == "nnedi3ocl" && csp == "YUY2"  ||
  356. \   edi == "nnedi3ocl" && csp == "YV411" ||
  357. \   edi == "nnedi3ocl" && chr444   ?
  358. \   Eval("""
  359.         pow2Y = sispmt ? einput.ConvertToY() : einput.ConvertToY8()
  360.         pow2Y = pow2Y.edi_rpow2_nnedi3ocl(rfactorX,rfactorY,alignc,true,false,false,nsize,nns,qual,etype)
  361.         pow2U = sispmt ? einput.ExtractU() : einput.UToY8()
  362.         pow2U = pow2U.edi_rpow2_nnedi3ocl(rfactorX,rfactorY,alignc,true,false,false,nsize,nns,qual,etype)
  363.         pow2V = sispmt ? einput.ExtractV() : einput.VToY8()
  364.         pow2V = pow2V.edi_rpow2_nnedi3ocl(rfactorX,rfactorY,alignc,true,false,false,nsize,nns,qual,etype)
  365.         """)
  366. \ : edi == "nnedi3ocl" && csp == "RGB24" ?
  367. \   Eval("""
  368.         pow2  = Interleave(einput.ShowRed(sispmt ? "Y" : "Y8"),einput.ShowGreen(sispmt ? "Y" : "Y8"),einput.ShowBlue(sispmt ? "Y" : "Y8"))
  369.         pow2  = pow2.edi_rpow2_nnedi3ocl(rfactorX,rfactorY,alignc,true,false,false,nsize,nns,qual,etype)
  370.         splitRGB24 = true
  371.         """)
  372. \ : NOP()
  373.  
  374. # Split the eedi3 mclip
  375.     !mclip.Defined() ?
  376. \   Eval("""
  377.         mclipY = Undefined()
  378.         mclipU = Undefined()
  379.         mclipV = Undefined()
  380.         """)
  381. \ : csp == "Y8" ?
  382. \   Eval("""
  383.         emclip  = emclip.ConvertToYV12()
  384.         """)
  385. \ : csp == "RGB24" ?
  386. \   Eval("""
  387.         emclip  = emclip.ConvertToYV12()
  388.         emclip  = emclip.SelectEvery(3,0,0,0,1,1,1,2,2,2)
  389.         """)
  390. \ : Eval("""
  391.         mclipY = emclip.ConvertToYV12()
  392.         mclipU = emclip.UToY8().ConvertToYV12()
  393.         mclipV = emclip.VToY8().ConvertToYV12()
  394.         """)
  395.  
  396. # eedi3 image enlargement
  397.     edi == "eedi3" && csp == "Y8" ?
  398. \   Eval("""
  399.         pow2  = einput.ConvertToYV12()
  400.         \            .edi_rpow2_eedi3(rfactorX,rfactorY,alignc,true,false,false,alpha,beta,gamma,nrad,mdis,hp,ucubic,cost3,
  401.         \                             vcheck,vthresh0,vthresh1,vthresh2,sclip,sclip_params,threads,emclip,opt)
  402.         \            .ConvertToY8()
  403.         """)
  404. \ : edi == "eedi3" && csp == "YV12" ?
  405. \   Eval("""
  406.         pow2  = einput.edi_rpow2_eedi3(rfactorX,rfactorY,alignc,Y,U,V,alpha,beta,gamma,nrad,mdis,hp,ucubic,cost3,
  407.         \                             vcheck,vthresh0,vthresh1,vthresh2,sclip,sclip_params,threads,mclipY,opt)
  408.         pow2Y = pow2.ConvertToY8()
  409.         pow2U = pow2.UToY8()
  410.         pow2V = pow2.VToY8()
  411.         """)
  412. \ : edi == "eedi3" && csp == "YV16"  ||
  413. \   edi == "eedi3" && csp == "YUY2"  ||
  414. \   edi == "eedi3" && csp == "YV411" ||
  415. \   edi == "eedi3" && csp == "YV24"   ?
  416. \   Eval("""
  417.         pow2Y = einput.ConvertToYV12()
  418.         \            .edi_rpow2_eedi3(rfactorX,rfactorY,alignc,true,false,false,alpha,beta,gamma,nrad,mdis,hp,ucubic,cost3,
  419.         \                             vcheck,vthresh0,vthresh1,vthresh2,sclip,sclip_params,threads,mclipY,opt)
  420.         \            .ConvertToY8()
  421.         pow2U = einput.UToY8().ConvertToYV12()
  422.         \            .edi_rpow2_eedi3(rfactorX,rfactorY,alignc,true,false,false,alpha,beta,gamma,nrad,mdis,hp,ucubic,cost3,
  423.         \                             vcheck,vthresh0,vthresh1,vthresh2,sclip,sclip_params,threads,mclipU,opt)
  424.         \            .ConvertToY8()
  425.         pow2V = einput.VToY8().ConvertToYV12()
  426.         \            .edi_rpow2_eedi3(rfactorX,rfactorY,alignc,true,false,false,alpha,beta,gamma,nrad,mdis,hp,ucubic,cost3,
  427.         \                             vcheck,vthresh0,vthresh1,vthresh2,sclip,sclip_params,threads,mclipV,opt)
  428.         \            .ConvertToY8()
  429.         """)
  430. \ : edi == "eedi3" && csp == "RGB24" ?
  431. \   Eval("""
  432.         # Always split RGB24 so that the sclip and mclip parameters work
  433.         pow2 = Interleave(einput.ShowRed("YV12"),einput.ShowGreen("YV12"),einput.ShowBlue("YV12"))
  434.         pow2 = pow2.edi_rpow2_eedi3(rfactorX,rfactorY,alignc,true,false,false,alpha,beta,gamma,nrad,mdis,hp,ucubic,cost3,
  435.         \                           vcheck,vthresh0,vthresh1,vthresh2,sclip,sclip_params,threads,emclip,opt).ConvertToY8()
  436.         splitRGB24 = true
  437.         """)
  438. \ : NOP()
  439.  
  440. # eedi2 image enlargement
  441.     edi == "eedi2" && csp == "Y8" ?
  442. \   Eval("""
  443.         pow2  = einput.ConvertToYV12()
  444.         \            .edi_rpow2_eedi2(rfactorX,rfactorY,alignc,mthresh,lthresh,vthresh,estr,dstr,maxd,map,nt,pp)
  445.         \            .ConvertToY8()
  446.         """)
  447. \ : edi == "eedi2" && csp == "YV12" ?
  448. \   Eval("""
  449.         pow2  = einput.edi_rpow2_eedi2(rfactorX,rfactorY,alignc,mthresh,lthresh,vthresh,estr,dstr,maxd,map,nt,pp)
  450.         pow2Y = pow2.ConvertToY8()
  451.         pow2U = pow2.UToY8()
  452.         pow2V = pow2.VToY8()
  453.         """)
  454. \ : edi == "eedi2" && csp == "YV16"  ||
  455. \   edi == "eedi2" && csp == "YUY2"  ||
  456. \   edi == "eedi2" && csp == "YV411" ||
  457. \   edi == "eedi2" && csp == "YV24"   ?
  458. \   Eval("""
  459.         pow2Y = einput.ConvertToYV12()
  460.         \            .edi_rpow2_eedi2(rfactorX,rfactorY,alignc,mthresh,lthresh,vthresh,estr,dstr,maxd,map,nt,pp)
  461.         \            .ConvertToY8()
  462.         pow2U = einput.UToY8().ConvertToYV12()
  463.         \            .edi_rpow2_eedi2(rfactorX,rfactorY,alignc,mthresh,lthresh,vthresh,estr,dstr,maxd,map,nt,pp)
  464.         \            .ConvertToY8()
  465.         pow2V = einput.VToY8().ConvertToYV12()
  466.         \            .edi_rpow2_eedi2(rfactorX,rfactorY,alignc,mthresh,lthresh,vthresh,estr,dstr,maxd,map,nt,pp)
  467.         \            .ConvertToY8()
  468.         """)
  469. \ : edi == "eedi2" && csp == "RGB24" ?
  470. \   Eval("""
  471.         pow2  = Interleave(einput.ShowRed("YV12"),einput.ShowGreen("YV12"),einput.ShowBlue("YV12"))
  472.         pow2  = pow2.edi_rpow2_eedi2(rfactorX,rfactorY,alignc,mthresh,lthresh,vthresh,estr,dstr,maxd,map,nt,pp).ConvertToY8()
  473.         splitRGB24 = true
  474.         """)
  475. \ : NOP()
  476.  
  477. # Crop off the padding
  478.     pad     && (sispmt ? input.isy() : csp == "Y8")    ||
  479. \   bordfix && (sispmt ? input.isy() : csp == "Y8")    ||
  480. \   pad     && input.isRGB() ||
  481. \   bordfix && input.isRGB()  ?
  482. \   Eval("""
  483.         pow2  = pow2.Crop(padL*rfactorX, padT*rfactorY, -padR*rfactorX, -padB*rfactorY)
  484.         """)
  485. \ : pad || bordfix ?
  486. \   Eval("""
  487.         pow2Y = pow2Y.Crop(padL*rfactorX, padT*rfactorY, -padR*rfactorX, -padB*rfactorY)
  488.         pow2U = pow2U.Crop(padL_c*rfactorX, padT_c*rfactorY, -padR_c*rfactorX, -padB_c*rfactorY)
  489.         pow2V = pow2V.Crop(padL_c*rfactorX, padT_c*rfactorY, -padR_c*rfactorX, -padB_c*rfactorY)
  490.         """)
  491. \ : NOP()
  492.  
  493. # Blank luma and chroma channels for Y/U/V=false
  494. noY  = einput.BlankClip(width=ffwidth, height=lsb?ffheight*2:ffheight, pixel_type=sispmt ? "Y"+string(Input.BitsPerComponent()) : "Y8", color_yuv=color_gray)
  495. noUV = einput.BlankClip(width=fwidth_c, height=lsb?fheight_c*2:fheight_c, pixel_type=sispmt ? "Y"+string(Input.BitsPerComponent()) : "Y8", color_yuv=color_gray)
  496.  
  497. # Center shift correction
  498.     cshift != "" && (sispmt ? input.isy() : csp == "Y8") ?
  499. \   Eval("""
  500.         shift  = Y ? pow2.ResizeX(ffwidth,ffheight,cshiftH,cshiftV,0,0,cshift,taps,a1,a2, chroma=false, lsb=lsb,mt=mt,mt_params=mt_params) : noY
  501.         """)
  502. \ : cshift != "" && chr420  ||
  503. \   cshift != "" && chr422  ||
  504. \   cshift != "" && csp == "YUY2"  ||
  505. \   cshift != "" && csp == "YV411" ||
  506. \   cshift != "" && chr444   ?
  507. \   Eval("""
  508.         shiftY = Y ? pow2Y.ResizeX(ffwidth,ffheight,cshiftH,cshiftV,0,0,cshift,taps,a1,a2, chroma=false, lsb=lsb,mt=mt,mt_params=mt_params) : noY
  509.         shiftU = U ? pow2U.ResizeX(fwidth_c,fheight_c,cshiftH_c,cshiftV_c,0,0,cshift,taps,a1,a2, chroma=false, lsb=lsb,mt=mt,mt_params=mt_params) : noUV
  510.         shiftV = V ? pow2V.ResizeX(fwidth_c,fheight_c,cshiftH_c,cshiftV_c,0,0,cshift,taps,a1,a2, chroma=false, lsb=lsb,mt=mt,mt_params=mt_params) : noUV
  511.         shift  = YToUV(shiftU,shiftV,shiftY)
  512.         shift  = csp == "YUY2" ? shift.ConvertToYUY2() : shift
  513.         """)
  514. \ : cshift != "" && input.isRGB() && !splitRGB24 ?
  515. \   Eval("""
  516.         shift  = lsb ? Interleave(pow2.ShowRed("Y8"),pow2.ShowGreen("Y8"),pow2.ShowBlue("Y8")) : pow2
  517.         shift  = shift.ResizeX(ffwidth,ffheight,cshiftH,cshiftV,0,0,cshift,taps,a1,a2, chroma=false, lsb=lsb,mt=mt,mt_params=mt_params)
  518.         """)
  519. \ : cshift != "" && input.isRGB() && splitRGB24 ?
  520. \   Eval("""
  521.         shift  = pow2.ResizeX(ffwidth,ffheight,cshiftH,cshiftV,0,0,cshift,taps,a1,a2, chroma=false, lsb=lsb,mt=mt,mt_params=mt_params)
  522.         shift  = !lsb ? MergeRGB(shift.SelectEvery(3,0),shift.SelectEvery(3,1),shift.SelectEvery(3,2),"RGB24") : shift
  523.         """)
  524. \ : NOP()
  525.  
  526. # No center shift correction
  527.     cshift == "" && (sispmt ? input.isy() : csp == "Y8") ?
  528. \   Eval("""
  529.         shift  = Y &&  lsb ? pow2.Dither_convert_8_to_16()
  530.         \      : Y && !lsb ? pow2
  531.         \                  : noY
  532.         """)
  533. \ : cshift == "" && chr420 && rfactorY == 1 ||
  534. \   cshift == "" && chr420 && !YV12cfix     ||
  535. \   cshift == "" && chr422                  ||
  536. \   cshift == "" && csp == "YUY2"                  ||
  537. \   cshift == "" && csp == "YV411"                 ||
  538. \   cshift == "" && chr444                   ?
  539. \   Eval("""
  540.         shiftY = Y &&  lsb ? pow2Y.Dither_convert_8_to_16()
  541.         \      : Y && !lsb ? pow2Y
  542.         \                  : noY
  543.         shiftU = U &&  lsb ? pow2U.Dither_convert_8_to_16()
  544.         \      : U && !lsb ? pow2U
  545.         \                  : noUV
  546.         shiftV = V &&  lsb ? pow2V.Dither_convert_8_to_16()
  547.         \      : V && !lsb ? pow2V
  548.         \                  : noUV
  549.         shift  = YToUV(shiftU,shiftV,shiftY)
  550.         shift  = csp == "YUY2" ? shift.ConvertToYUY2() : shift
  551.         """)
  552. \ : cshift == "" && chr420 ?
  553. \   Eval("""
  554.         # Even if the center shift isn't corrected,
  555.         # doubling the height of YV12 causes a vertical chroma shift that needs to be corrected
  556.         shiftY = Y &&  lsb ? pow2Y.Dither_convert_8_to_16()
  557.         \      : Y && !lsb ? pow2Y
  558.         \                  : noY
  559.         shiftU = U ? pow2U.ResizeX(fwidth_c,fheight_c,0,-0.25,0,0,"Spline36", chroma=false, lsb=lsb,mt=mt,mt_params=mt_params) : noUV
  560.         shiftV = V ? pow2V.ResizeX(fwidth_c,fheight_c,0,-0.25,0,0,"Spline36", chroma=false, lsb=lsb,mt=mt,mt_params=mt_params) : noUV
  561.         shift  = YToUV(shiftU,shiftV,shiftY)
  562.         """)
  563. \ : cshift == "" && input.isRGB() && !splitRGB24 ?
  564. \   Eval("""
  565.         shift  = lsb ? Interleave(pow2.ShowRed("Y8"),pow2.ShowGreen("Y8"),pow2.ShowBlue("Y8")).Dither_convert_8_to_16() : pow2
  566.         """)
  567. \ : cshift == "" && input.isRGB() && splitRGB24 ?
  568. \   Eval("""
  569.         shift  = lsb ? pow2.Dither_convert_8_to_16()
  570.         \            : MergeRGB(pow2.SelectEvery(3,0),pow2.SelectEvery(3,1),pow2.SelectEvery(3,2),"RGB24")
  571.         """)
  572. \ : NOP()
  573.  
  574. shift = sispmt ? input.hasalpha() && !(shift.hasalpha()) ? shift.AddAlphaPlane(input.ExtractA().edi_rpow2(rfactorX,rfactorY,edi,cshift,fwidth,fheight,
  575. \                                      taps,a1,a2,cplace,Y,U,V,lsb,bordfix,YV12cfix,
  576. \                                      nsize,nns,qual,etype,pscrn,threads,opt,fapprox,
  577. \                                      alpha,beta,gamma,nrad,mdis,hp,ucubic,cost3,
  578. \                                      vcheck,vthresh0,vthresh1,vthresh2,sclip,sclip_params,defined(mclip) ? mclip.ExtractA() : mclip,
  579. \                                      mthresh,lthresh,vthresh,estr,dstr,maxd,map,nt,pp,mt,mt_params)) : shift : shift
  580.  
  581. return shift
  582. }
  583.  
  584. # Recursive functions for repeated edi image doubling
  585. # When calling these functions, the f and t parameters should always be left at their default values.
  586. # They're used only to control behavior during recursion and changing them will cause a malfunction.
  587. function edi_rpow2_nnedi3(clip input, int "rfactorX", int "rfactorY", bool "alignc",
  588. \                         bool "Y", bool "U", bool "V", int "nsize", int "nns", int "qual",
  589. \                         int "etype", int "pscrn", int "threads", int "opt", int "fapprox",
  590. \                         bool "f", bool "t") {
  591.  
  592. rfactorX = Default(rfactorX, 2)
  593. rfactorY = Default(rfactorY, rfactorX)
  594. alignc   = Default(alignc, false)
  595. Y        = Default(Y, true)
  596. U        = Default(U, true)
  597. V        = Default(V, true)
  598. nsize    = Default(nsize, 0)
  599. nns      = Default(nns, 3)
  600. f        = Default(f, true)
  601. t        = Default(t, false)
  602.  
  603. Assert(rfactorX > 0 && BitAnd(rfactorX,rfactorX-1) == 0, "edi_rpow2_nnedi3: rfactorX must be a power of 2")
  604. Assert(rfactorY > 0 && BitAnd(rfactorY,rfactorY-1) == 0, "edi_rpow2_nnedi3: rfactorY must be a power of 2")
  605.  
  606. # YV16/YUY2/YV411 chroma gets mangled by turning, so don't allow processing it
  607. sispmt  = Findstr(VersionString(), "AviSynth+") != 0 && Findstr(VersionString(), "r1576") == 0
  608. chr422  = sispmt ? input.is422() : input.isYV16()
  609. Assert(!chr422 && !input.IsYUY2() && !input.IsYV411() || !U && !V,
  610. \      "edi_rpow2_nnedi3: YV16/YUY2/YV411 supported only when U and V are false")
  611.  
  612. # If alignc=true, always use field=1 for doubling the width
  613. # to maintain alignment of horizontally subsampled chroma.
  614. field2 = f ? 1 : 0
  615. field1 = alignc ? 1 : field2
  616. UVbool = U || V ? true : false
  617.  
  618. # Only turn right if doubling the width and the input isn't already turned
  619.     !t && rfactorX > 1 ?
  620. \   Eval("""
  621.         dbl = sispmt ? input.TurnRight() : input.TryFTurnRight(UVbool)
  622.         t   = true
  623.         """)
  624. \ : Eval("""dbl = input""")
  625.  
  626. dbl = rfactorX > 1 ? dbl.nnedi3(field1,true,Y,U,V,nsize,nns,qual,etype,pscrn,threads,opt,fapprox) : dbl
  627.  
  628. # Only turn left if the height is going to be doubled or after the last iteration of doubling the width.
  629. # This avoids unnecessary turning when only the width is doubled repeatedly.
  630.     t && rfactorY >  1 ||
  631. \   t && rfactorX == 2  ?
  632. \   Eval("""
  633.         dbl = sispmt ? dbl.TurnLeft() : dbl.TryFTurnLeft(UVbool)
  634.         t   = false
  635.         """)
  636. \ : Eval("""dbl = dbl""")
  637.  
  638. dbl = rfactorY > 1 ? dbl.nnedi3(field2,true,Y,U,V,nsize,nns,qual,etype,pscrn,threads,opt,fapprox) : dbl
  639.  
  640. return rfactorX > 1 ||
  641. \      rfactorY > 1  ? dbl.edi_rpow2_nnedi3(Max(1,rfactorX/2),Max(1,rfactorY/2),alignc,Y,U,V,
  642. \                                           nsize,nns,qual,etype,pscrn,threads,opt,fapprox,false,t)
  643. \                    : input
  644. }
  645.  
  646. function edi_rpow2_nnedi3ocl(clip input, int "rfactorX", int "rfactorY", bool "alignc",
  647. \                            bool "Y", bool "U", bool "V", int "nsize", int "nns", int "qual", int "etype",
  648. \                            bool "f", bool "t") {
  649.  
  650. rfactorX = Default(rfactorX, 2)
  651. rfactorY = Default(rfactorY, rfactorX)
  652. alignc   = Default(alignc, false)
  653. Y        = Default(Y, true)
  654. U        = Default(U, true)
  655. V        = Default(V, true)
  656. nsize    = Default(nsize, 0)
  657. nns      = Default(nns, 3)
  658. f        = Default(f, true)
  659. t        = Default(t, false)
  660.  
  661. Assert(rfactorX > 0 && BitAnd(rfactorX,rfactorX-1) == 0, "edi_rpow2_nnedi3ocl: rfactorX must be a power of 2")
  662. Assert(rfactorY > 0 && BitAnd(rfactorY,rfactorY-1) == 0, "edi_rpow2_nnedi3ocl: rfactorY must be a power of 2")
  663. sispmt  = Findstr(VersionString(), "AviSynth+") != 0 && Findstr(VersionString(), "r1576") == 0
  664. chr422  = sispmt ? input.is422() : input.isYV16()
  665. Assert(!chr422 && !input.IsYV411() || !U && !V,
  666. \      "edi_rpow2_nnedi3ocl: YV16/YV411 supported only when U and V are false")
  667.  
  668. field2 = f ? 1 : 0
  669. field1 = alignc ? 1 : field2
  670. dw     = rfactorX > 1 ? field1 : -1
  671. UVbool = U || V ? true : false
  672.  
  673. # Doubling the width and height together is faster than turning,
  674. # but doubling only the width causes artifacts because the clip still gets deinterlaced vertically,
  675. # so the input is turned and the height doubled in that case.
  676.  
  677. dbl1 = input.nnedi3ocl(field2,true,Y,U,V,nsize,nns,qual,etype,dw)
  678.  
  679.     !t && rfactorX > 1 && rfactorY < 2 ?
  680. \   Eval("""
  681.         dbl2 = sispmt ? input.TurnRight() : input.TryFTurnRight(UVbool)
  682.         t    = true
  683.         """)
  684. \ : Eval("""dbl2 = input""")
  685.  
  686. dbl2 = rfactorX > 1 ? dbl2.nnedi3ocl(field1,true,Y,U,V,nsize,nns,qual,etype,-1) : dbl2
  687.  
  688.     t && rfactorX == 2 ?
  689. \   Eval("""
  690.         dbl2 = sispmt ? dbl2.TurnLeft() : dbl2.TryFTurnLeft(UVbool)
  691.         t    = false
  692.         """)
  693. \ : Eval("""dbl2 = dbl2""")
  694.  
  695. dbl = rfactorX > 1 && rfactorY < 2 ? dbl2 : dbl1
  696.  
  697. return rfactorX > 1 ||
  698. \      rfactorY > 1  ? dbl.edi_rpow2_nnedi3ocl(Max(1,rfactorX/2),Max(1,rfactorY/2),alignc,Y,U,V,nsize,nns,qual,etype,false,t)
  699. \                    : input
  700. }
  701.  
  702. function edi_rpow2_eedi3(clip input, int "rfactorX", int "rfactorY", bool "alignc",
  703. \                        bool "Y", bool "U", bool "V", float "alpha", float "beta", float "gamma",
  704. \                        int "nrad", int "mdis", bool "hp", bool "ucubic", bool "cost3",
  705. \                        int "vcheck", float "vthresh0", float "vthresh1", float "vthresh2",
  706. \                        string "sclip", string "sclip_params", int "threads", clip "mclip", int "opt",
  707. \                        bool "f", bool "t", bool "mt", string "mt_params") {
  708.  
  709. rfactorX     = Default(rfactorX, 2)
  710. rfactorY     = Default(rfactorY, rfactorX)
  711. alignc       = Default(alignc, false)
  712. Y            = Default(Y, true)
  713. U            = Default(U, true)
  714. V            = Default(V, true)
  715. sclip        = Default(sclip, "")
  716. sclip_params = Default(sclip_params, sclip == "nnedi3" || sclip == "nnedi3ocl" ? "nsize=0, nns=3" : "")
  717. f            = Default(f, true)
  718. t            = Default(t, false)
  719.  
  720. Assert(rfactorX > 0 && BitAnd(rfactorX,rfactorX-1) == 0, "edi_rpow2_eedi3: rfactorX must be a power of 2")
  721. Assert(rfactorY > 0 && BitAnd(rfactorY,rfactorY-1) == 0, "edi_rpow2_eedi3: rfactorY must be a power of 2")
  722. sispmt  = Findstr(VersionString(), "AviSynth+") != 0 && Findstr(VersionString(), "r1576") == 0
  723. chr422  = sispmt ? input.is422() : input.isYV16()
  724. chr420  = sispmt ? input.is420() : input.isyv12()
  725. Assert(!chr422 && !input.IsYUY2() || !U && !V, "edi_rpow2_eedi3: 422 supported only when U and V are false")
  726.  
  727. # If the sclip_params string doesn't start with a comma, add one to avoid a syntax error
  728. sclip_params = sclip_params == "" || sclip_params.LeftStr(1) == "," ? sclip_params : ","+sclip_params
  729.  
  730. field2  = f ? 1 : 0
  731. field1  = alignc ? 1 : field2
  732. UVbool  = U || V ? true : false
  733. Yint    = Y ? 3 : 1
  734. Uint    = U ? 3 : 1
  735. Vint    = V ? 3 : 1
  736.  
  737. # Use a src_left or src_top shift dependent on the field when resizing
  738. # for the sclip or mclip to keep it in alignment with the eedi3 clip.
  739. # Additionally, the vertical shift for YV12 chroma is doubled,
  740. # so the chroma must be resized separately when doubling the height.
  741. rshift1 = field1 == 1 ? 0.25 : -0.25
  742. rshift2 = field2 == 1 ? 0.25 : -0.25
  743.  
  744.     !t && rfactorX > 1 ?
  745. \   Eval("""
  746.         dbl      = sispmt ? input.TurnRight() : input.TryFTurnRight(UVbool)
  747.         t        = true
  748.         """)
  749. \ : Eval("""
  750.         dbl      = input
  751.         """)
  752.  
  753. sclip2 = sclip == ""          ? Undefined()
  754. \      : sclip == "nnedi3"    ? Eval(""" rfactorX > 1    ? dbl.nnedi3(field1,true,Y=Y,U=U,V=V"""+sclip_params+""") : Undefined() """)
  755. \      : sclip == "nnedi3ocl" ? Eval(""" rfactorX > 1    ? dbl.nnedi3ocl(field1,true,Y=Y,U=U,V=V"""+sclip_params+""") : Undefined() """)
  756. \      : sclip == "eedi2"     ? Eval(""" rfactorX > 1    ? dbl.eedi2(field=field1"""+sclip_params+""") : Undefined() """)
  757. \                             : Eval(""" rfactorX > 1   &&
  758.                                     \   UVbool         &&
  759.                                     \   chr420          ? dbl.ResizeX(dbl.Width(),dbl.Height()*2,0,rshift1, kernel=sclip,
  760.                                     \                                 luma=Y,mt=mt,mt_params=mt_params, chroma=false"""+sclip_params+""")
  761.                                     \                        .MergeChroma(dbl.ResizeX(dbl.Width(),dbl.Height()*2,0,rshift1*2.0, kernel=sclip,
  762.                                     \                                                 luma=false,mt=mt,mt_params=mt_params, chroma=true"""+sclip_params+"""))
  763.                                     \ : rfactorX > 1    ? dbl.ResizeX(dbl.Width(),dbl.Height()*2,0,rshift1, kernel=sclip,
  764.                                     \                                 luma=Y,mt=mt,mt_params=mt_params, chroma=UVbool"""+sclip_params+""")
  765.                                     \                   : Undefined() """)
  766. mclip1 = mclip.Defined() && rfactorX > 1 ? sispmt ? mclip.TurnRight() : mclip.TryFTurnRight(UVbool) : mclip
  767. dbl    = rfactorX > 1 ? dbl.eedi3(field1,true,Y,U,V,alpha,beta,gamma,nrad,mdis,hp,ucubic,cost3,
  768. \                                 vcheck,vthresh0,vthresh1,vthresh2,sclip2,threads,mclip1,opt) : dbl
  769.  
  770. # No need to resize YV12 chroma separately here because it's the width being doubled
  771. mclip  = mclip.Defined() && rfactorX > 1 ? mclip.ResizeX(mclip.Width()*2,mclip.Height(),rshift1,0, luma=Y, chroma=UVbool,mt=mt,mt_params=mt_params)
  772. \                                               .mt_binarize(128, Y=Yint, U=Uint, V=Vint)
  773. \                                        : mclip
  774.  
  775.     t && rfactorY >  1 ||
  776. \   t && rfactorX == 2  ?
  777. \   Eval("""
  778.         dbl = sispmt ? dbl.TurnLeft() : dbl.TryFTurnLeft(UVbool)
  779.         t   = false
  780.         """)
  781. \ : Eval("""dbl = dbl""")
  782.  
  783. sclip2 = sclip == ""          ? Undefined()
  784. \      : sclip == "nnedi3"    ? Eval(""" rfactorY > 1    ? dbl.nnedi3(field2,true,Y=Y,U=U,V=V"""+sclip_params+""") : Undefined() """)
  785. \      : sclip == "nnedi3ocl" ? Eval(""" rfactorY > 1    ? dbl.nnedi3ocl(field2,true,Y=Y,U=U,V=V"""+sclip_params+""") : Undefined() """)
  786. \      : sclip == "eedi2"     ? Eval(""" rfactorY > 1    ? dbl.eedi2(field=field2"""+sclip_params+""") : Undefined() """)
  787. \                             : Eval(""" rfactorY > 1   &&
  788.                                     \   UVbool         &&
  789.                                     \   chr420          ? dbl.ResizeX(dbl.Width(),dbl.Height()*2,0,rshift2, kernel=sclip,
  790.                                     \                                 luma=Y,mt=mt,mt_params=mt_params, chroma=false"""+sclip_params+""")
  791.                                     \                        .MergeChroma(dbl.ResizeX(dbl.Width(),dbl.Height()*2,0,rshift2*2.0, kernel=sclip,
  792.                                     \                                                 luma=false,mt=mt,mt_params=mt_params, chroma=true"""+sclip_params+"""))
  793.                                     \ : rfactorY > 1    ? dbl.ResizeX(dbl.Width(),dbl.Height()*2,0,rshift2, kernel=sclip,
  794.                                     \                                 luma=Y,mt=mt,mt_params=mt_params, chroma=UVbool"""+sclip_params+""")
  795.                                     \                   : Undefined() """)
  796. dbl    = rfactorY > 1 ? dbl.eedi3(field2,true,Y,U,V,alpha,beta,gamma,nrad,mdis,hp,ucubic,cost3,
  797. \                                 vcheck,vthresh0,vthresh1,vthresh2,sclip2,threads,mclip,opt) : dbl
  798. mclip  = mclip.Defined() && rfactorY > 1 &&
  799. \        chr420          && UVbool        ? mclip.ResizeX(mclip.Width(),mclip.Height()*2,0,rshift2, luma=Y, chroma=false,mt=mt,mt_params=mt_params)
  800. \                                                .MergeChroma(mclip.ResizeX(mclip.Width(),mclip.Height()*2,0,rshift2*2.0, luma=false, chroma=true,mt=mt,mt_params=mt_params))
  801. \      : mclip.Defined() && rfactorY > 1  ? mclip.ResizeX(mclip.Width(),mclip.Height()*2,0,rshift2, luma=Y, chroma=UVbool,mt=mt,mt_params=mt_params)
  802. \                                                .mt_binarize(128, Y=Yint, U=Uint, V=Vint)
  803. \                                         : mclip
  804.  
  805. return rfactorX > 1 ||
  806. \      rfactorY > 1  ? dbl.edi_rpow2_eedi3(Max(1,rfactorX/2),Max(1,rfactorY/2),alignc,Y,U,V,alpha,beta,gamma,nrad,mdis,hp,ucubic,cost3,
  807. \                                          vcheck,vthresh0,vthresh1,vthresh2,sclip,sclip_params,threads,mclip,opt,false,t)
  808. \                    : input
  809. }
  810.  
  811. function edi_rpow2_eedi2(clip input, int "rfactorX", int "rfactorY", bool "alignc",
  812. \                        int "mthresh", int "lthresh", int "vthresh", int "estr",
  813. \                        int "dstr", int "maxd", int "map", int "nt", int "pp",
  814. \                        bool "f", bool "t") {
  815.  
  816. rfactorX = Default(rfactorX, 2)
  817. rfactorY = Default(rfactorY, rfactorX)
  818. alignc   = Default(alignc, false)
  819. f        = Default(f, true)
  820. t        = Default(t, false)
  821.  
  822. sispmt  = Findstr(VersionString(), "AviSynth+") != 0 && Findstr(VersionString(), "r1576") == 0
  823.  
  824. Assert(rfactorX > 0 && BitAnd(rfactorX,rfactorX-1) == 0, "edi_rpow2_eedi2: rfactorX must be a power of 2")
  825. Assert(rfactorY > 0 && BitAnd(rfactorY,rfactorY-1) == 0, "edi_rpow2_eedi2: rfactorY must be a power of 2")
  826. Assert(!input.IsYUY2(), "edi_rpow2_eedi2: YUY2 not supported")
  827.  
  828. field2 = f ? 1 : 0
  829. field1 = alignc ? 1 : field2
  830.  
  831.     !t && rfactorX > 1 ?
  832. \   Eval("""
  833.         dbl = sispmt ? input.TurnRight() : input.TryFTurnRight()
  834.         t   = true
  835.         """)
  836. \ : Eval("""dbl = input""")
  837.  
  838. dbl = rfactorX > 1 ? dbl.eedi2(mthresh,lthresh,vthresh,estr,dstr,maxd,field1,map,nt,pp) : dbl
  839.  
  840.     t && rfactorY >  1 ||
  841. \   t && rfactorX == 2  ?
  842. \   Eval("""
  843.         dbl = sispmt ? dbl.TurnLeft() : dbl.TryFTurnLeft()
  844.         t   = false
  845.         """)
  846. \ : Eval("""dbl = dbl""")
  847.  
  848. dbl = rfactorY > 1 ? dbl.eedi2(mthresh,lthresh,vthresh,estr,dstr,maxd,field2,map,nt,pp) : dbl
  849.  
  850. return rfactorX > 1 ||
  851. \      rfactorY > 1  ? dbl.edi_rpow2_eedi2(Max(1,rfactorX/2),Max(1,rfactorY/2),alignc,mthresh,lthresh,vthresh,estr,dstr,maxd,map,nt,pp,false,t)
  852. \                    : input
  853. }
  854.  
  855. # Functions to use FTurn if available or else fall back to the internal turn functions
  856. function TryFTurnLeft(clip c, bool "chroma") {
  857. try {
  858.     return c.FTurnLeft(chroma=chroma)
  859.     }
  860. catch(err_msg) {
  861.     return c.TurnLeft()
  862.     }
  863. }
  864.  
  865. function TryFTurnRight(clip c, bool "chroma") {
  866. try {
  867.     return c.FTurnRight(chroma=chroma)
  868.     }
  869. catch(err_msg) {
  870.     return c.TurnRight()
  871.     }
  872. }
  873.  
  874. function TryFTurn180(clip c, bool "chroma") {
  875. try {
  876.     return c.FTurn180(chroma=chroma)
  877.     }
  878. catch(err_msg) {
  879.     return c.Turn180()
  880.     }
  881. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement