Advertisement
Guest User

ResizeX

a guest
Jul 17th, 2019
401
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* ResizeX v1.0.1 mod 9
  2.  
  3. ResizeX is a wrapper function for AviSynth's internal resizers and Dither_resize16
  4. that corrects for the chroma shift caused by the internal resizers when they're
  5. used on horizontally subsampled chroma with MPEG2 placement.
  6. If either the lsb_in or lsb parameters are set to true, Dither_resize16 is used.
  7. If both are false, AviSynth's internal resizers are used.
  8.  
  9. All AviSynth 2.6 colorspaces are supported. However, to use Dither_resize16 on RGB, the input
  10. must first be split into a Y8 clip containing the individual red, green, and blue channels.
  11. This can be done with the following script:
  12.  
  13.  
  14.      Interleave(ShowRed("Y8"),ShowGreen("Y8"),ShowBlue("Y8"))
  15.      ResizeX(target_width,target_height, lsb=true)
  16.      DitherPost()
  17.      MergeRGB(SelectEvery(3,0),SelectEvery(3,1),SelectEvery(3,2))
  18.  
  19.  
  20. Internal and Dither_resize16 kernels: "Bicubic", "Bilinear", "Blackman", "Gauss", "Lanczos",
  21.                                       "Point", "Sinc", "Spline16", "Spline36", "Spline64"
  22.  
  23. Dither_resize16 only kernels:         "Blackmanminlobe", "Impulse", "Rect" or "Box", "Spline"
  24.  
  25. Bicubic kernel presets:               "Catmull-Rom" or "CatRom", "Hermite",
  26.                                       "Mitchell-Netravali" or "Mitchell", "Robidoux", "SoftCubic"
  27.  
  28. The number of taps for the Blackman, Blackmanminlobe, Lanczos, Sinc, and Spline kernels
  29. can be set with the taps parameter or with a number after the kernel name.
  30. Using the latter method overrides the taps parameter.
  31.  
  32. The b and c values for the Bicubic kernel can be set with the a1 and a2 parameters, respectively.
  33. If a Bicubic preset is used, it will override a1 and a2.
  34. The p value for the Gauss kernel can be set with a1.
  35.  
  36. The softness of the SoftCubic preset can be set with a number after it ranging from 0 through 100.
  37. The default is 75.
  38. */
  39.  
  40. function ResizeX(clip input, int target_width, int target_height, float "src_left", float "src_top",
  41. \                float "src_width", float "src_height", string "kernel", int "taps", float "a1", float "a2",
  42. \                string "cplace", bool "luma", bool "chroma", bool "lsb_in", bool "lsb", bool "mt", string "mt_params", string "dither_params", bool "lsb_out", bool "desampling", int "dither_mode") {
  43.  
  44. lsb_in     = Default(lsb_in, false)
  45. lsb_out = Default(lsb_out, false)
  46. lsb        = Default(lsb, false)
  47.  
  48. lsb        = (lsb_out && !lsb) || (lsb_in && !lsb) ? true : lsb
  49.  
  50. iw = input.Width()
  51. ih = lsb_in ? input.Height()/2 : input.Height()
  52.  
  53. src_left   = Default(src_left, 0)
  54. src_top    = Default(src_top, 0)
  55. desampling = Default(desampling, false)
  56. src_width  = Default(src_width, desampling ? 0 : iw)
  57. src_height = Default(src_height, desampling ? 0 : ih)
  58. kernel     = Default(kernel, "Spline36")
  59. cplace     = Default(cplace, "MPEG2")
  60. luma       = Default(luma, true)
  61. chroma     = Default(chroma, true)
  62. mt         = Default(mt, true)
  63. mt_params  = Default(mt_params,      "")
  64. dither_params = Default(dither_params ,      "")
  65. dither_mode   = Default(dither_mode, 6)
  66.  
  67. sisphbd = AvsPlusVersionNumber > 2294
  68.  
  69. Assert(target_width  > 0, "ResizeX: target width must be greater than 0")
  70. Assert(target_height > 0, "ResizeX: target height must be greater than 0")
  71. Assert(cplace == "MPEG1" || cplace == "MPEG2", "ResizeX: cplace must be MPEG1 or MPEG2")
  72. lsb_native = sisphbd ? !(Input.BitsPerComponent() > 8 && (lsb)) : true
  73. sisphbd ? Assert(lsb_native, "lsb hack is not Compatible with native high bit depth" ) : nop()
  74. sisphbd ? Assert(!(Input.isYUVA() && lsb), "lsb hack is not Compatible with YUVA" ) : nop()
  75.  
  76. # Set correct src_width and src_height values if the input values are zero or negative
  77. src_width  = src_width  == 0 ? desampling ? undefined : iw
  78. \          : src_width  <  0 ? iw-src_left+src_width
  79. \                            : src_width
  80. src_height = src_height == 0 ? desampling ? undefined : ih
  81. \          : src_height <  0 ? ih-src_top+src_height
  82. \                            : src_height
  83.  
  84. # Get the input clip's colorspace
  85. csp = input.PixelType()
  86.  
  87. sislumaonly = sisphbd ? input.isy() : input.isy8()
  88.  
  89. chroma = sislumaonly ? false : chroma
  90.  
  91. chr420  = sisphbd ? input.is420() : input.isyv12()
  92. chr422  = sisphbd ? input.is422() : input.isYV16()
  93. chr444  = sisphbd ? input.is444() : input.isYV24()
  94.  
  95. Assert(csp != "RGB24" && csp != "RGB32" || !lsb, "ResizeX: lsb things must be false for RGB input")
  96.  
  97. # Check for subsampled chroma
  98. hssc12 = chr420 || chr422 || csp == "YUY2"
  99. hssc14 = csp == "YV411"
  100. vssc12 = chr420
  101.  
  102. Assert(!hssc12 || target_width%2  == 0, "ResizeX: target width of "+csp+" must be a multiple of 2")
  103. Assert(!hssc14 || target_width%4  == 0, "ResizeX: target width of "+csp+" must be a multiple of 4")
  104. Assert(!vssc12 || target_height%2 == 0, "ResizeX: target height of "+csp+" must be a multiple of 2")
  105.  
  106. # Set chroma target and src values based on the subsampling ratios
  107. target_width_c  = hssc12 ? target_width/2  : hssc14 ? target_width/4 : target_width
  108. target_height_c = vssc12 ? target_height/2 : target_height
  109. src_left_c      = hssc12 ? src_left/2.0    : hssc14 ? src_left/4.0   : src_left
  110. src_top_c       = vssc12 ? src_top/2.0     : src_top
  111. src_width2      = defined(src_width) ? src_width : iw
  112. src_height2     = defined(src_height) ? src_height : ih
  113. src_width_c     = defined(src_width) ? hssc12 ? src_width/2.0   : hssc14 ? src_width/4.0  : src_width : src_width
  114. src_height_c    = defined(src_height) ? vssc12 ? src_height/2.0  : src_height : src_height
  115. src_width_c2    = defined(src_width_c) ? src_width_c : hssc12 ? src_width2/2.0   : hssc14 ? src_width2/4.0  : src_width2
  116. src_height_c2   = defined(src_height_c) ? src_height_c : vssc12 ? src_height2/2.0  : src_height2
  117.  
  118. # Add the MPEG2 chroma shift correction to the src_left_c value
  119. MPEG2shift = hssc12 ? 0.25*(desampling ? 1.0-Float(target_width_c)/Float(src_width_c2): 1.0-Float(src_width_c2)/Float(target_width_c))
  120. \          : hssc14 ? 0.375*(desampling ? 1.0-Float(target_width_c)/Float(src_width_c2) : 1.0-Float(src_width_c2)/Float(target_width_c))
  121. \                   : 0
  122. src_left_c  = cplace == "MPEG2" && kernel.LeftStr(5) != "Point" ? src_left_c+MPEG2shift
  123. \                                                               : src_left_c
  124.  
  125. # Remove "Resize" from the end of the kernel string if present
  126. kernel = kernel.RightStr(6) == "Resize" ? kernel.LeftStr(kernel.StrLen()-6) : kernel
  127.  
  128. # Support the Dither_resize16 kernel name variants when resizing 8-bit
  129. kernel = kernel == "Linear"   ? "Bilinear"
  130. \      : kernel == "Cubic"    ? "Bicubic"
  131. \      : kernel == "Gaussian" ? "Gauss"
  132. \                             : kernel
  133.  
  134. # Dither_resize16 kernels without an internal equivalent can't be used without lsb things being true
  135. Assert(lsb || kernel == "Spline16" || kernel == "Spline36" || kernel == "Spline64" ||
  136. \      kernel != "Rect" && kernel != "Box" && kernel != "Blackmanminlobe" && kernel.LeftStr(6) != "Spline" && kernel != "Impulse",
  137. \      "ResizeX: Rect, Box, Blackmanminlobe, Spline, and Impulse kernels"+chr(10)+
  138. \      "are available only when resizing for lsb things)")
  139.  
  140. # Get the taps value from the kernel string if present (overrides the parameter)
  141. taps = kernel.LeftStr(6)  == "Spline"          && kernel != "Spline16" && kernel != "Spline36" && kernel != "Spline64" &&
  142. \                                                 kernel.StrLen() >  6 ? kernel.RightStr(kernel.StrLen()-6).Value().Int()
  143. \    : kernel.LeftStr(7)  == "Lanczos"         && kernel.StrLen() >  7 ? kernel.RightStr(kernel.StrLen()-7).Value().Int()
  144. \    : kernel.LeftStr(8)  == "Blackman"        && kernel.LeftStr(15) != "Blackmanminlobe" &&
  145. \                                                 kernel.StrLen() >  8 ? kernel.RightStr(kernel.StrLen()-8).Value().Int()
  146. \    : kernel.LeftStr(15) == "Blackmanminlobe" && kernel.StrLen() > 15 ? kernel.RightStr(kernel.StrLen()-15).Value().Int()
  147. \    : kernel.LeftStr(4)  == "Sinc"            && kernel.StrLen() >  4 ? kernel.RightStr(kernel.StrLen()-4).Value().Int()
  148. \                                                                      : taps
  149.  
  150. # Remove the taps value from the kernel string if present
  151. kernel = kernel.LeftStr(6)  == "Spline"          && kernel != "Spline16" && kernel != "Spline36" && kernel != "Spline64" &&
  152. \                                                   kernel.StrLen() >  6 ? kernel.LeftStr(6)
  153. \      : kernel.LeftStr(7)  == "Lanczos"         && kernel.StrLen() >  7 ? kernel.LeftStr(7)
  154. \      : kernel.LeftStr(8)  == "Blackman"        && kernel.LeftStr(15) != "Blackmanminlobe" &&
  155. \                                                   kernel.StrLen() >  8 ? kernel.LeftStr(8)
  156. \      : kernel.LeftStr(15) == "Blackmanminlobe" && kernel.StrLen() > 15 ? kernel.LeftStr(15)
  157. \      : kernel.LeftStr(4)  == "Sinc"            && kernel.StrLen() >  4 ? kernel.LeftStr(4)
  158. \                                                                        : kernel
  159.  
  160. # Set the a1 and a2 values for bicubic presets (overrides the parameters)
  161.     kernel == "Catmull-Rom" || kernel == "CatRom" ?
  162. \   Eval("""
  163.         a1     = 0.0
  164.         a2     = 0.5
  165.         kernel = "Bicubic"
  166.         """)
  167. \ : kernel == "Hermite" ?
  168. \   Eval("""
  169.         a1     = 0.0
  170.         a2     = 0.0
  171.         kernel = "Bicubic"
  172.         """)
  173. \ : kernel == "Mitchell-Netravali" || kernel == "Mitchell" ?
  174. \   Eval("""
  175.         a1     = 1.0/3.0
  176.         a2     = 1.0/3.0
  177.         kernel = "Bicubic"
  178.         """)
  179. \ : kernel == "Robidoux" ?
  180. \   Eval("""
  181.         a1     = 0.3782
  182.         a2     = 0.3109
  183.         kernel = "Bicubic"
  184.         """)
  185. \ : kernel == "SoftCubic" ?
  186. \   Eval("""
  187.         a1     = 0.75
  188.         a2     = 0.25
  189.         kernel = "Bicubic"
  190.         """)
  191. \ : kernel.LeftStr(9) == "SoftCubic" && kernel.StrLen() > 9 ?
  192. \   Eval("""
  193.         a1     = kernel.RightStr(kernel.StrLen()-9).Value()
  194.         a1     = a1 >= 0 && a1 <= 100 ? a1/100.0
  195.         \      : Assert(false, "ResizeX: SoftCubic value must be in the range 0 through 100")
  196.         a2     = 1.0-a1
  197.         kernel = "Bicubic"
  198.         """)
  199. \ : NOP()
  200.  
  201. # If chroma=false and resizing 8-bit YUV, convert to Y8 to avoid processing chroma
  202. csp2   = !chroma && !lsb && !(input.isrgb()) ? "Y" : csp
  203. input2 = csp2 == "Y" && !sislumaonly ? sisphbd ? input.ConvertToY() : input.ConvertToY8() : input
  204.  
  205. # Convert YUY2 to YV16 because Dither_resize16 only supports planar formats
  206. input2 = csp2 == "YUY2" ? input2.ConvertToYV16() : input2
  207.  
  208. # Dither_resize16 is used if lsb things is true,
  209. # so the input needs to be converted to stack16 format if lsb_in=false and lsb is used
  210. input2 = !lsb_in && lsb ? input2.Dither_convert_8_to_16() : input2
  211.  
  212. # Blank luma channel for luma=false
  213. noY = input2.BlankClip(width=target_width, height=target_height, pixel_type=sisphbd ? "Y"+string(Input.BitsPerComponent()) : "Y8", color_yuv=color_gray)
  214.  
  215. # Perform resizing
  216.     lsb ?
  217. \   Eval("""
  218.         resized = input2.Dither_resize16(target_width,target_height,src_left,src_top,src_width,src_height,kernel,
  219.         \                                taps=taps, a1=a1, a2=a2, cplace=cplace, y=luma?3:1, u=chroma?3:1, v=chroma?3:1"""+dither_params+""")
  220.         """)
  221. \ : input.isRGB() || (sisphbd ? (csp2 == "Y" || input.is444() && luma) : (csp2 == "Y" || csp2 == "YV24" && luma)) ?
  222. \   Eval("""
  223.         r8 = desampling ? input2.ResizeX_deResizemt(target_width,target_height,src_left,src_top,src_width,src_height,kernel,taps,a1,a2,mt_params) : \
  224.                            mt ? input2.ResizeX_AvsmtResize(target_width,target_height,src_left,src_top,src_width,src_height,kernel,taps,a1,a2,mt_params) : input2.ResizeX_AvsResize(target_width,target_height,src_left,src_top,src_width,src_height,kernel,taps,a1,a2)
  225.         resized = luma || input.isRGB() ? r8 : noY
  226.         """)
  227. \ : Eval("""
  228.         r8Y = sisphbd ? input2.ConvertToY() : input2.ConvertToY8()
  229.         r8Y = desampling ? r8Y.ResizeX_deResizemt(target_width,target_height,src_left,src_top,src_width,src_height,kernel,taps,a1,a2,mt_params) : \
  230.                             mt ? r8Y.ResizeX_AvsmtResize(target_width,target_height,src_left,src_top,src_width,src_height,kernel,taps,a1,a2,mt_params) : r8Y.ResizeX_AvsResize(target_width,target_height,src_left,src_top,src_width,src_height,kernel,taps,a1,a2)
  231.         r8U = sisphbd ? input2.ExtractU() : input2.UToY8()
  232.         r8U = desampling ? r8U.ResizeX_deResizemt(target_width_c,target_height_c,src_left_c,src_top_c,src_width_c,src_height_c,kernel,taps,a1,a2,mt_params) : \
  233.                             mt ? r8U.ResizeX_AvsmtResize(target_width_c,target_height_c,src_left_c,src_top_c,src_width_c,src_height_c,kernel,taps,a1,a2,mt_params) : r8U.ResizeX_AvsResize(target_width_c,target_height_c,src_left_c,src_top_c,src_width_c,src_height_c,kernel,taps,a1,a2)
  234.         r8V = sisphbd ? input2.ExtractV() : input2.VToY8()
  235.         r8V = desampling ? r8V.ResizeX_deResizemt(target_width_c,target_height_c,src_left_c,src_top_c,src_width_c,src_height_c,kernel,taps,a1,a2,mt_params) : \
  236.                             mt ? r8V.ResizeX_AvsmtResize(target_width_c,target_height_c,src_left_c,src_top_c,src_width_c,src_height_c,kernel,taps,a1,a2,mt_params) : r8V.ResizeX_AvsResize(target_width_c,target_height_c,src_left_c,src_top_c,src_width_c,src_height_c,kernel,taps,a1,a2)
  237.         resized = luma ? YToUV(r8U,r8V,r8Y)
  238.         \              : YToUV(r8U,r8V,noY)
  239.         """)
  240.  
  241. # The resized clip will be in stack16 format if lsb is used, so dither down to 8-bit if lsb_out=false
  242. resized = lsb && !lsb_out ? resized.DitherPost(mode=dither_mode) : resized
  243.  
  244. # Make sure the output is the same colorspace as the input
  245. resized = csp == "YV12"  ? resized.ConvertToYV12()  
  246. \       : csp == "YV16"  ? resized.ConvertToYV16()
  247. \       : csp == "YUY2"  ? resized.ConvertToYUY2()
  248. \       : csp == "YV411" ? resized.ConvertToYV411()
  249. \       : csp == "YV24"  ? resized.ConvertToYV24()
  250. \       : chr420         ? resized.ConvertToYUV420()  
  251. \       : chr422         ? resized.ConvertToYUV422()  
  252. \       : chr444         ? resized.ConvertToYUV444()  
  253. \                        : resized
  254.  
  255. resized = sisphbd ? input.IsYUVA() && !(resized.IsYUVA()) ? resized.AddAlphaPlane(mt ? input.ExtractA().ResizeX_AvsmtResize(target_width,target_height,src_left,src_top,src_width,src_height,kernel,taps,a1,a2,mt_params) : input.ExtractA().ResizeX_AvsResize(target_width,target_height,src_left,src_top,src_width,src_height,kernel,taps,a1,a2)) : resized : resized
  256.  
  257. return resized
  258. }
  259.  
  260. # Wrapper function for AviSynth's internal resizers
  261. function ResizeX_AvsResize(clip input, int target_width, int target_height, float "src_left", float "src_top",
  262. \                          float "src_width", float "src_height", string "kernel", int "taps", float "a1", float "a2") {
  263.  
  264. kernel = Default(kernel, "Spline36")
  265.  
  266. Eval("""
  267.     kernel == "Spline16" ||
  268. \    kernel == "Spline36" ||
  269. \    kernel == "Spline64" ||
  270. \    kernel == "Bilinear" ||
  271. \    kernel == "Point"     ? input."""+kernel+"""Resize(target_width,target_height,src_left,src_top,src_width,src_height)
  272. \  : kernel == "Lanczos"  ||
  273. \    kernel == "Blackman" ||
  274. \    kernel == "Sinc"      ? input."""+kernel+"""Resize(target_width,target_height,src_left,src_top,src_width,src_height,taps)
  275. \  : kernel == "Bicubic"   ? input."""+kernel+"""Resize(target_width,target_height,a1,a2,src_left,src_top,src_width,src_height)
  276. \  : kernel == "Gauss"     ? input."""+kernel+"""Resize(target_width,target_height,src_left,src_top,src_width,src_height,a1)
  277. \                          : Assert(false, "ResizeX_AvsResize: invalid kernel")
  278.     """)
  279. }
  280.  
  281. # Wrapper function for AviSynth's mt resizers
  282. function ResizeX_AvsmtResize(clip input, int target_width, int target_height, float "src_left", float "src_top",
  283. \                          float "src_width", float "src_height", string "kernel", int "taps", float "a1", float "a2", string "mt_params") {
  284.  
  285. kernel    = Default(kernel, "Spline36")
  286. mt_params = Default(mt_params,      "")
  287.  
  288. try { Eval("""
  289.     kernel == "Spline16" ||
  290. \    kernel == "Spline36" ||
  291. \    kernel == "Spline64" ||
  292. \    kernel == "Bilinear" ||
  293. \    kernel == "Point"     ? input."""+kernel+"""Resizemt(target_width,target_height,src_left,src_top,src_width,src_height"""+mt_params+""")
  294. \  : kernel == "Lanczos"  ||
  295. \    kernel == "Blackman" ||
  296. \    kernel == "Sinc"      ? input."""+kernel+"""Resizemt(target_width,target_height,src_left,src_top,src_width,src_height,taps"""+mt_params+""")
  297. \  : kernel == "Bicubic"   ? input."""+kernel+"""Resizemt(target_width,target_height,a1,a2,src_left,src_top,src_width,src_height"""+mt_params+""")
  298. \  : kernel == "Gauss"     ? input."""+kernel+"""Resizemt(target_width,target_height,src_left,src_top,src_width,src_height,a1"""+mt_params+""")
  299. \                          : Assert(false, "ResizeX_AvsmtResize: invalid kernel")
  300.          """)
  301.       } catch(error_msg) { input.ResizeX_AvsResize(target_width, target_height, src_left, src_top, src_width, src_height, kernel, taps, a1, a2) }
  302. }
  303.  
  304. # Wrapper function for AviSynth's mt deresizers
  305. function ResizeX_deResizemt(clip input, int target_width, int target_height, float "src_left", float "src_top",
  306. \                          float "src_width", float "src_height", string "kernel", int "taps", float "a1", float "a2", string "mt_params") {
  307.  
  308. kernel    = Default(kernel, "Spline36")
  309. mt_params = Default(mt_params,      "")
  310.  
  311.      kernel == "Spline16" ||
  312. \    kernel == "Spline36" ||
  313. \    kernel == "Spline64" ||
  314. \    kernel == "Bilinear"  ? Eval("input.de"+kernel+"Resizemt(target_width,target_height,src_left,src_top,src_width,src_height"+mt_params+")")
  315. \  : kernel == "Lanczos"  ||
  316. \    kernel == "Blackman" ||
  317. \    kernel == "Sinc"      ? Eval("input.de"+kernel+"Resizemt(target_width,target_height,src_left,src_top,src_width,src_height,taps"+mt_params+")")
  318. \  : kernel == "Bicubic"   ? Eval("input.de"+kernel+"Resizemt(target_width,target_height,a1,a2,src_left,src_top,src_width,src_height"+mt_params+")")
  319. \  : kernel == "Gauss"     ? Eval("input.de"+kernel+"Resizemt(target_width,target_height,src_left,src_top,src_width,src_height,a1"+mt_params+")")
  320. \                          : Assert(false, "ResizeX_deResizemt: invalid kernel")
  321. }
  322.  
  323. ################
  324.  
  325. # base on dithertools avsi functions by cretindesalpes
  326.  
  327. Function y_gamma_to_linear (clip src,
  328. \   bool "tv_range_in", bool "tv_range_out", string "curve", int "u", int "v",
  329. \   float "gcor", bool "sigmoid", float "thr", float "cont")
  330. {
  331.     src
  332.     linear_and_gamma (false,
  333. \       tv_range_in, tv_range_out, curve, u, v,
  334. \       gcor, sigmoid, thr, cont
  335. \   )
  336. }
  337.  
  338. Function y_linear_to_gamma (clip src,
  339. \   bool "tv_range_in", bool "tv_range_out", string "curve", int "u", int "v",
  340. \   float "gcor", bool "sigmoid", float "thr", float "cont")
  341. {
  342.     src
  343.     linear_and_gamma (true,
  344. \       tv_range_in, tv_range_out, curve, u, v,
  345. \       gcor, sigmoid, thr, cont
  346. \   )
  347. }
  348.  
  349. Function linear_and_gamma (clip src, bool l2g_flag,
  350. \   bool "tv_range_in", bool "tv_range_out", string "curve", int "u", int "v",
  351. \   float "gcor", bool "sigmoid", float "thr", float "cont")
  352. {
  353.     tv_range_in  = Default (tv_range_in,  true)
  354.     tv_range_out = Default (tv_range_out, true)
  355.     curve        = Default (curve,      "srgb")
  356.     u            = Default (u,               2)
  357.     v            = Default (v,               2)
  358.     gcor         = Default (gcor,          1.0)
  359.     sigmoid      = Default (sigmoid,     false)
  360.  
  361.     c_num =
  362. \     (curve == "srgb" ) ? 0
  363. \   : (curve == "709"  ) ? 1
  364. \   : (curve == "601"  ) ? 1
  365. \   : (curve == "170"  ) ? 1
  366. \   : (curve == "240"  ) ? 2
  367. \   : (curve == "2020" ) ? 3
  368. \   : (curve == "1886" ) ? 4
  369. \   : (curve == "1886a") ? 5
  370. \   : Assert (false, "linear_and_gamma: wrong curve value.")
  371.  
  372.     #                                  BT-709/601
  373.     #                         sRGB     SMPTE 170M  SMPTE 240M    BT-2020    BT-1886    BT-1886a
  374.     k0    = Select (c_num, " 0.04045", " 0.081  ", " 0.0912 ", " 0.08145", "0      ", "0.35   ")
  375.     phi   = Select (c_num, "12.92   ", " 4.5    ", " 4.0    ", " 4.5    ", "4.5    ", "0.65709357") # 0.35 ^ (3.0-2.6)
  376.     gam2  = Select (c_num, " 1      ", " 1      ", " 1      ", " 1      ", "1      ", "3.0    ")
  377.     alpha = Select (c_num, " 0.055  ", " 0.099  ", " 0.1115 ", " 0.0993 ", "0      ", "0      ")
  378.     gamma = Select (c_num, " 2.4    ", " 2.22222", " 2.22222", " 2.22222", "2.4    ", "2.6    ")
  379.  
  380.     expr = (tv_range_in) ? "x 4096 - 56064 /" : "x 65536 /"
  381.  
  382.     # E = (E' <= k0)   ?   (E' ^ gam2) / phi   :   ((E' + alpha) / (1 + alpha)) ^ gamma
  383.     g2l = expr
  384.     g2l =   g2l + " " + k0 +" <= "
  385. \         + g2l + " " + gam2 + " ^ " + phi +" / "
  386. \         + g2l + " " + alpha + " + 1 " + alpha + " + / " + gamma + " ^   ?"
  387.     g2l = (gcor != 1.0) ? g2l + " 0 >=   " + g2l + " " + String (gcor) + " ^   " + g2l + "   ?" : g2l
  388.     g2l = (sigmoid) ? build_sigmoid_expr (g2l , true , thr, cont) : g2l
  389.  
  390.     l2g = (sigmoid) ? build_sigmoid_expr (expr, false, thr, cont) : expr
  391.     l2g = (gcor != 1.0) ? l2g + " 0 >=   " + l2g + " " + String (gcor) + " ^   " + l2g + "   ?" : l2g
  392.     # E' = (E <= k0 / phi)   ?   (E * phi) ^ (1 / gam2)   :   (E ^ (1 / gamma)) * (alpha + 1) - alpha
  393.     l2g =   l2g + " " + k0 + " " + phi + " / <= "
  394. \         + l2g + " " + phi + " * 1 " + gam2 + " / ^ "
  395. \         + l2g + " 1 " + gamma + " / ^ " + alpha + " 1 + * " + alpha + " -   ?"
  396.  
  397.     expr = (l2g_flag) ? l2g : g2l
  398.     expr = expr + ((tv_range_out) ? " 56064 * 4096 +" : " 65536 *")
  399.     src.mt_lut (expr="i16 " + expr, scale_inputs=!tv_range_out || !tv_range_in ? "allf" : "all", y=3, u=u, v=v)
  400. }
  401.  
  402. # Sigmoidal functions:
  403. # x0 = 1 / (1 + exp (cont *  thr     ))
  404. # x1 = 1 / (1 + exp (cont * (thr - 1)))
  405. # y  = (1 / (1 + exp (cont * (thr - x))) - x0) / (x1 - x0)
  406. # x  = thr - log (1 / (y * (x1 - x0) + x0) - 1) / cont
  407. Function build_sigmoid_expr (string in, bool inv, float "thr", float "cont")
  408. {
  409.     thr   = Default (thr,  0.5)
  410.     cont  = Default (cont, 6.5)
  411.     Assert ((cont > 0), "build_sigmoid_expr: cont must be strictly positive.")
  412.     Assert ((thr >= 0 && thr <= 1), "build_sigmoid_expr: thr must be in the 0-1 range.")
  413.     x0v = 1 / (1 + exp (cont *  thr     ))
  414.     x1v = 1 / (1 + exp (cont * (thr - 1)))
  415.  
  416.     x0   = String (      x0v)
  417.     x1m0 = String (x1v - x0v)
  418.     cont = String (cont)
  419.     thr  = String (thr)
  420.  
  421.     expr = (inv)
  422. \   ? thr + " 1 " + in + " " + x1m0 + " * " + x0 + " + 0.000001 max / 1 - 0.000001 max log " + cont + " / -"
  423. \   : "1 1 " + cont + " " + thr + " " + in + " - * exp + / " + x0 + " - " + x1m0 + " /"
  424.  
  425.     return (expr)
  426. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement