Guest User

edi_rpow2

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