Advertisement
Guest User

edi_rpow2

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