View difference between Paste ID: AahjdmVC and Cg0EpAX6
SHOW: | | - or go back to the newest paste.
1
#################################################################################################
2-
###### nnedi3_resize16 v3.3      ######      by mawen1250      ######      2015.09.02      ######
2+
###### nnedi3_resize16 v3.3      ######      by mawen1250      ######      2015.09.05      ######
3
#################################################################################################
4
###### from v2.8 on, nnedi3_resize16 only supports AviSynth v2.6+                          ######
5
###### Requirements: masktools v2.0a48, dither v1.25.1, nnedi3 v0.9.4.19,                  ######
6
######               SmoothAdjust v3.00, Contra-Sharpen mod 3.4 (only for sharp>0),        ######
7
######               FTurn v1.4 (not necessarily required but will improve speed)          ######
8
#################################################################################################
9
###### accept Y8, YV12, YV16, YV24 input, use nnedi3 and Dither_resize16(nr) for scaling   ######
10
###### output format can be 8bit/16bit Y8/YV12/YV16/YV24 or RGB32/RGB24/RGB48YV12/RGB48Y   ######
11
#################################################################################################
12
###### "lsb_in"/"lsb" defines if input/output clip is stacked-16bit, default is False      ######
13
###### "output" defines colorspace of output clip, for RGB output "lsb" is ignored         ######
14
#################################################################################################
15
###### when horizontal/vertical scale ratio >  "ratiothr", we assume it's upscaling        ######
16
###### when horizontal/vertical scale ratio <= "ratiothr", we assume it's downscaling      ######
17
###### by default ratiothr=1.125                                                           ######
18
###### nnedi3 is only applied when upscaling                                               ######
19
###### Dither_resize16 is used after nnedi3 upscaling to fix shift and scale to target res ######
20
###### we call the nnedi3+Dither_resize16 scaling method "edge area resize"                ######
21
###### for downscaling, Dither_resize16 is applied instead, we call it "flat area resize"  ######
22
###### when mixed=True, nnedi3 (edge area) is combined with Dither_resize16 (flat area)    ######
23
#################################################################################################
24
25
26
Function nnedi3_resize16(clip input, int "target_width", int "target_height", float "src_left", float "src_top",
27
\                        float "src_width", float "src_height",
28
\                        string "kernel_d", string "kernel_u", float "f_d", float "f_u", int "taps",
29
\                        float "a1", float "a2", float "a3", bool "invks_d", bool "invks_u", int "invkstaps", bool "noring",
30
\                        int "nsize", int "nns", int "qual", int "etype", int "pscrn", int "threads",
31
\                        float "ratiothr", bool "mixed", float "thr", float "elast", float "sharp",
32
\                        string "output", bool "tv_range", string "cplace", string "matrix", string "curve", float "gcor",
33
\                        int "Y", int "U", int "V", bool "lsb_in", bool "lsb", int "dither")
34
{
35
    ###############################################################################################################################
36
    ###############################################################################################################################
37
    # Parameters for merging edge&flat upscaled clip
38
	
39
    mixed    = Default(mixed,    True   )   # nnedi3_resize16 uses nnedi3+Dither_resize16 for edge upscaling, this parameter defines whether to combine nnedi3+Dither_resize16(edge area) and Dither_resize16(flat area) in upscaling, which achieves higher precision upscaling result(mainly for flat area).
40
    thr      = Default(thr,      1.0    )   # the same with "thr"   in Dither_limit_dif16, valid value range is (0, 10.0].
41
    elast    = Default(elast,    1.5    )   # the same with "elast" in Dither_limit_dif16, valid value range is [1, 10.0].
42
                                            # PDiff: pixel value diff between flat   clip and edge clip (edge clip as reference)
43
                                            # ODiff: pixel value diff between merged clip and edge clip (edge clip as reference)
44
                                            # PDiff, thr and elast is used to calculate ODiff:
45
                                            # ODiff = PDiff when [PDiff <= thr]
46
                                            # ODiff gradually smooths from thr to 0 when [thr <= PDiff <= thr * elast]
47
                                            # for elast>2.0, ODiff reaches maximum when [PDiff == thr * elast / 2]
48
                                            # ODiff = 0     when [PDiff >= thr * elast]
49
                                            #
50
                                            # Larger "thr"   will result in more pixels being taken from flat area upscaled clip (Dither_resize16)
51
                                            # Larger "thr"   will result in less pixels being taken from edge area upscaled clip (nnedi3+Dither_resize16)
52
                                            # Larger "elast" will result in more pixels being blended from edge&flat area upscaled clip, for smoother merging
53
    
54
    ###############################################################################################################################
55
	###############################################################################################################################
56
    # Parameters for nnedi3
57
	
58
    nsize    = Default(nsize,    0      )
59
    nns      = Default(nns,      3      )
60
    qual     = Default(qual,     2      )
61
    etype    = Default(etype,    0      )
62
    pscrn    = Default(pscrn,    2      )
63
    threads  = Default(threads,  0      )
64
    
65
    ###############################################################################################################################
66
	###############################################################################################################################
67
    # Parameters for Dither_resize16
68
	
69
    kernel_d = Default(kernel_d, "Spline36" )   # "kernelh","kernelv" of Dither_resize16 used in downscaling
70
    kernel_u = Default(kernel_u, "Spline64" )   # "kernelh","kernelv" of Dither_resize16 used in upscaling
71
	f_d      = Default(f_d,      1.0        )   # "fh","fv" of Dither_resize16 used in downscaling
72
	f_u      = Default(f_u,      1.0        )   # "fh","fv" of Dither_resize16 used in upscaling
73
	taps     = Default(taps,     4          )   # "taps"    of Dither_resize16
74
	# a1, a2, a3                                # "a1","a2","a3"      of Dither_resize16
75
	invks_d  = Default(invks_d,  False      )   # "invksh","invksv"   of Dither_resize16 used in downscaling
76
	invks_u  = Default(invks_u,  False      )   # "invksh","invksv"   of Dither_resize16 used in upscaling
77
	invkstaps= Default(invkstaps,5          )   # "invkstaps"         of Dither_resize16
78
	
79
    noring   = Default(noring,   False      )   # True use non-ringing algorithm of Dither_resize16 in flat area scaling
80
                                                # It actually doesn't make much sense for nnedi3_resize16(which uses nnedi3 for upscaling),
81
                                                # while it may produce blurring and aliasing when downscaling.
82
                                                # You'd better not set it to True unless you know what you are doing.
83
    resste   = "Dither_resize16"
84
    resstf   = noring ? "Dither_resize16nr" : "Dither_resize16"
85
    
86
    ###############################################################################################################################
87
	###############################################################################################################################
88
    # Post-Process
89
	
90
    sharp    = Default(sharp,    0      )   # Strength of Contra-Sharpen mod, for sharper edge. 0 means no sharpening, common value is about 100.
91
                                            # *Only* when {horrizontal or vertical}{scale ratio}>{ratiothr} will sharpening take effect (when nnedi3 is used for upscaling).
92
    
93
    ###############################################################################################################################
94
	###############################################################################################################################
95
    # Parameters for input/output
96
	
97
    Y        = Default(Y,        3      )
98
    U        = Default(U,        3      )
99
    V        = Default(V,        3      )
100
    lsb_in   = Default(lsb_in,   False  )   # input  clip is 16-bit stacked or not
101
    lsb      = Default(lsb,      False  )   # output clip is 16-bit stacked or not
102
    tv_range = Default(tv_range, True   )   # input  clip is TV-range or PC-range
103
    dither   = tv_range ? Default(dither, 6) : Default(dither, 50)    # dither mode for 16-bit to 8-bit conversion
104
    
105
    sCSP     = input.nnedi3_resize16_GetCSP()
106
    Assert(sCSP=="Y8" || sCSP=="YV12" || sCSP=="YV16" || sCSP=="YV24", """nnedi3_resize16: only accept Y8, YV12, YV16, YV24 input""")
107
    
108
    output   = Default(output,   sCSP   )
109
    # Output format. Possible values are:
110
    # "Y8"       : Regular Y8    colorspace. Parameter "lsb" works on this output mode.
111
    # "YV12"     : Regular YV12  colorspace. Parameter "lsb" works on this output mode.
112
    # "YV16"     : Regular YV16  colorspace. Parameter "lsb" works on this output mode.
113
    # "YV24"     : Regular YV24  colorspace. Parameter "lsb" works on this output mode.
114
    # "RGB32"    : Regular RGB32 colorspace.
115
    # "RGB24"    : Regular RGB24 colorspace.
116
    # "RGB48YV12": 48-bit RGB conveyed on YV12. Use it for rawvideo export only. Not suitable for display or further processing (it will look like garbage).
117
    # "RGB48Y"   : 48-bit RGB. The components R, G and B are conveyed on three YV12 or Y8 (if supported) stack16 clips interleaved on a frame basis.
118
    
119
	###############################################################################################################################
120
	
121
    IsY8     = sCSP == "Y8" || output == "Y8"
122
    sCSP     = IsY8 ? "YV24" : sCSP
123
    
124
    IsRGB    = LeftStr(output, 3) == "RGB"
125
    oCSP     = IsRGB || IsY8 ? "YV24" : output
126
    
127
    Y        = min(Y, 4)
128
    U        = IsY8 ? 1 : min(U, 4)
129
    V        = IsY8 ? 1 : min(V, 4)
130
    Yt       = Y == 3 || Y == 4
131
    Ut       = U == 3 || U == 4
132
    Vt       = V == 3 || V == 4
133
    Y31      = Yt ? 3 : 1
134
    U31      = Ut ? 3 : 1
135
    V31      = Vt ? 3 : 1
136
    Y32      = Yt ? 3 : Y
137
    U32      = Ut ? 3 : U
138
    V32      = Vt ? 3 : V
139
    Y21      = Yt ? 2 : Y
140
    U21      = Ut ? 2 : U
141
    V21      = Vt ? 2 : V
142
    Y321     = Y > 1 ? 3 : Y
143
    U321     = U > 1 ? 3 : U
144
    V321     = V > 1 ? 3 : V
145
    
146
    sw       = input.Width ()
147
    sh       = input.Height()
148
    sh       = lsb_in ? sh/2 : sh
149
    swc      = sCSP=="YV24" ? sw   : sw/2
150
    shc      = sCSP=="YV12" ? sh/2 : sh
151
    HD       = (sw > 1024 || sh > 576) ? True : False
152
    
153
	###############################################################################################################################
154
	
155
    cplace   = Default(cplace,   "MPEG2")
156
    # Placement of the chroma subsamples. Can be one of these strings:
157
    # "MPEG1": 4:2:0 subsampling used in MPEG-1. Chroma samples are located on the center of each group of 4 pixels.
158
    # "MPEG2": Subsampling used in MPEG-2 4:2:x. Chroma samples are located on the left pixel column of the group.
159
    
160
    matrix   = Default(matrix,   HD ? "709" : "601")
161
    # The matrix used to convert the YUV pixels to computer RGB. Possible values are:
162
    # "601"  : ITU-R BT.601 / ITU-R BT.470-2 / SMPTE 170M. For Standard Definition content.
163
    # "709"  : ITU-R BT.709. For High Definition content.
164
    # "240"  : SMPTE 240M
165
    # "FCC"  : FCC
166
    # "YCgCo": YCgCo
167
    # When the parameter is not defined, ITU-R BT.601 and ITU-R BT.709 are automatically selected depending on the clip definition.
168
    
169
    curve    = Default(curve,    "linear"   )
170
    # type of gamma mapping(transfer characteristic) for gamma-aware resize(only take effects for Dither_resize16 processing parts)
171
    # possible values:
172
    # "709"    - ITU-R BT.709 transfer curve for digital video
173
    # "601"    - ITU-R BT.601 transfer curve, same as "709"
174
    # "170"    - SMPTE 170M, same as "709"
175
    # "240"    - SMPTE 240M (1987)
176
    # "srgb"   - sRGB curve
177
    # "2020"   - ITU-R BT.2020 transfer curve, for 12-bit content. For sources of lower bitdepth, use the "709" curve.
178
    # "linear" - linear curve without gamma-aware processing
179
    curve    = Yt ? curve : "linear"
180
    gcor     = Default(gcor,     1.0    )   # Gamma correction, applied on the linear part.
181
    
182
    ###############################################################################################################################
183
	###############################################################################################################################
184
    # Parameters for scaling
185
	
186
    ow       = Default(target_width,  sw)
187
    oh       = Default(target_height, sh)
188
    owc      = oCSP=="YV24" ? ow   : ow/2
189
    ohc      = oCSP=="YV12" ? oh/2 : oh
190
    Assert(!(output=="YV16" && ow!=owc*2), """nnedi3_resize16: width  of YV16 output clip must be MOD2!""")
191
    Assert(!(output=="YV12" && ow!=owc*2), """nnedi3_resize16: width  of YV12 output clip must be MOD2!""")
192
    Assert(!(output=="YV12" && oh!=ohc*2), """nnedi3_resize16: height of YV12 output clip must be MOD2!""")
193
    
194
    src_left    = Default(src_left,   0 )
195
    src_top     = Default(src_top,    0 )
196
    src_width   = Default(src_width,  sw)
197
    src_height  = Default(src_height, sh)
198
    
199
    ###############################################################################################################################
200
	###############################################################################################################################
201
    # Pre-Cropping/Padding Calculation
202
	
203
    prel        = int(src_left/2) * 2
204
    pret        = int(src_top /2) * 2
205
    prer        = int((src_width > 0 ? -sw+src_left+src_width : src_width )/2) * 2
206
    preb        = int((src_height> 0 ? -sh+src_top+src_height : src_height)/2) * 2
207
    prew        = sw - prel + prer
208
    preh        = sh - pret + preb
209
    
210
    sCSP=="YV24" ? \
211
    Eval("""
212
        swmod2      = sw  /2*2 == sw
213
        pwmod2      = prew/2*2 == prew
214
        wpre        = prew < sw
215
        prel        = wpre ?          prel            :          0
216
        prer        = wpre ? pwmod2 ? prer : prer + 1 : swmod2 ? 0 : 1
217
        prew        = sw - prel + prer
218
        wpre        = prew < sw || !swmod2
219
    """) : \
220
    Eval("""
221
        swmod4      = sw  /4*4 == sw
222
        pwmod4      = prew/4*4 == prew
223
        wpre        = prew < sw
224
        prel        = wpre ?          prel            :          0
225
        prer        = wpre ? pwmod4 ? prer : prer + 2 : swmod4 ? 0 : 2
226
        prew        = sw - prel + prer
227
        wpre        = prew < sw || !swmod4
228
    """)
229
    
230
    sCSP=="YV12" ? \
231
    Eval("""
232
        shmod4      = sh  /4*4 == sh
233
        phmod4      = preh/4*4 == preh
234
        hpre        = preh < sh
235
        pret        = hpre ?          pret            :          0
236
        preb        = hpre ? phmod4 ? preb : preb + 2 : shmod4 ? 0 : 2
237
        preh        = sh - pret + preb
238
        hpre        = preh < sh || !shmod4
239
    """) : \
240
    Eval("""
241
        shmod2      = sh  /2*2 == sh
242
        phmod2      = preh/2*2 == preh
243
        hpre        = preh < sh
244
        pret        = hpre ?          pret            :          0
245
        preb        = hpre ? phmod2 ? preb : preb + 1 : shmod2 ? 0 : 1
246
        preh        = sh - pret + preb
247
        hpre        = preh < sh || !shmod2
248
    """)
249
    
250
    src_width   = src_width <=0 ? +sw-src_left+src_width : src_width
251
    src_height  = src_height<=0 ? +sh-src_top+src_height : src_height
252
    src_left    = wpre ? src_left-prel : src_left
253
    src_top     = hpre ? src_top -pret : src_top
254
    
255
    src_leftc   = sCSP=="YV24" ? src_left      : src_left  /2.
256
    src_topc    = sCSP=="YV12" ? src_top   /2. : src_top
257
    src_widthc  = sCSP=="YV24" ? src_width     : src_width /2.
258
    src_heightc = sCSP=="YV12" ? src_height/2. : src_height
259
    
260
    ###############################################################################################################################
261
	###############################################################################################################################
262
    # Scaling Ratio Calculation
263
	
264
    ratiothr = Default(ratiothr,   1.125)    # When scale ratio is larger than ratiothr, use nnedi3+Dither_resize16 upscale method instead of pure Dither_resize16.
265
	# when horizontal/vertical scale ratio >  "ratiothr", we assume it's upscaling
266
    # when horizontal/vertical scale ratio <= "ratiothr", we assume it's downscaling
267
    
268
	###############################################################################################################################
269
	
270
    yhratio  = float(ow ) / float(src_width  )
271
    yvratio  = float(oh ) / float(src_height )
272
    chratio  = float(owc) / float(src_widthc )
273
    cvratio  = float(ohc) / float(src_heightc)
274
    
275
    enable   = yhratio!=1 || yvratio!=1 || chratio!=1 || cvratio!=1 ||
276
    \          src_width  !=int(src_width  ) || src_height !=int(src_height ) || src_widthc !=int(src_widthc ) || src_heightc!=int(src_heightc) ||
277
    \          src_left   !=int(src_left   ) || src_top    !=int(src_top    ) || src_leftc  !=int(src_leftc  ) || src_topc   !=int(src_topc   )
278
    
279
    yhct     = yhratio>ratiothr ? Ceil( log(yhratio/ratiothr) / log(2) ) : 0
280
    yhrf     = int(Pow(2, yhct))
281
    yrhratio = yhratio/yhrf
282
    yvct     = yvratio>ratiothr ? Ceil( log(yvratio/ratiothr) / log(2) ) : 0
283
    yvrf     = int(Pow(2, yvct))
284
    yrvratio = yvratio/yvrf
285
    
286
    chct     = chratio>ratiothr ? Ceil( log(chratio/ratiothr) / log(2) ) : 0
287
    chrf     = int(Pow(2, chct))
288
    crhratio = chratio/chrf
289
    cvct     = cvratio>ratiothr ? Ceil( log(cvratio/ratiothr) / log(2) ) : 0
290
    cvrf     = int(Pow(2, cvct))
291
    crvratio = cvratio/cvrf
292
    
293
    nonenny  = yhct<=0 && yvct<=0
294
    nonennc  = chct<=0 && cvct<=0
295
    nonenn   = nonenny || nonennc
296
    
297
    Ynnt     = Yt&&!nonenny
298
    Unnt     = Ut&&!nonennc
299
    Vnnt     = Vt&&!nonennc
300
    Ynn31    = Ynnt ? 3 : 1
301
    Unn31    = Unnt ? 3 : 1
302
    Vnn31    = Vnnt ? 3 : 1
303
    Ynn      = Yt&&nonenny ? 2 : Y
304
    Unn      = Ut&&nonennc ? 2 : U
305
    Vnn      = Vt&&nonennc ? 2 : V
306
    
307
    nnt      = Ynnt || Unnt || Vnnt
308
    mixed    = !nnt || !enable ? False : mixed
309
    
310
    ###############################################################################################################################
311
    ###############################################################################################################################
312
	# Shift Calculation
313
	
314
    yhshift  = yhrf>=2 ? 0.5 : 0       #              luma   horizontal shift introduced by nnedi3_resize16_rpow2 (edge area resize)
315
    yvshift  = yvrf>=2 ? 0.5 : 0       #              luma     vertical shift introduced by nnedi3_resize16_rpow2 (edge area resize)
316
    yhfix    = -yhshift                # value to fix luma   horizontal shift introduced by nnedi3_resize16_rpow2 (edge area resize)
317
    yvfix    = -yvshift                # value to fix luma     vertical shift introduced by nnedi3_resize16_rpow2 (edge area resize)
318
    
319
    chshift  = oCSP=="YV24" ? sCSP=="YV24" ?                   chrf>=2 ? 0.50         :  0
320
    \                                      : cplace=="MPEG1" ? chrf>=2 ? 0.50         :  0
321
    \                                                        : chrf>=2 ? 0.50-chrf/4. : -0.25
322
    \                       : sCSP=="YV24" ? cplace=="MPEG1" ? chrf>=2 ? 0.50         :  0
323
    \                                                        : chrf>=2 ? 0.75         :  0.25
324
    \                                      : cplace=="MPEG1" ? chrf>=2 ? 0.50         :  0
325
    \                                                        : chrf>=2 ? 0.75-chrf/4. :  0
326
	#                                                         (chrf/2-0.5)/2-(chrf/2-1)
327
	#                                                 chroma horizontal shift introduced by nnedi3_resize16_rpow2 (edge area resize)
328
    cvshift  = cvrf>=2 ? 0.5 : 0       #              chroma   vertical shift introduced by nnedi3_resize16_rpow2 (edge area resize)
329
    chfix    = -chshift                # value to fix chroma horizontal shift introduced by nnedi3_resize16_rpow2 (edge area resize)
330
    cvfix    = -cvshift                # value to fix chroma   vertical shift introduced by nnedi3_resize16_rpow2 (edge area resize)
331
    
332
    cphfixe  = oCSP=="YV24" ?                   0
333
    \                       : cplace=="MPEG1" ? 0
334
    \                                         : 0.25-0.25/crhratio
335
	# value to fix chroma horizontal shift introduced by Dither_resize16 after nnedi3_resize16_rpow2 processing   (edge area resize)
336
    
337
    cphfix   = oCSP=="YV24" ? sCSP=="YV24" ?                   0
338
    \                                      : cplace=="MPEG1" ? 0
339
    \                                                        : 0.25
340
    \                       : sCSP=="YV24" ? cplace=="MPEG1" ? 0
341
    \                                                        : -0.5
342
    \                                      : cplace=="MPEG1" ? 0
343
    \                                                        : 0.25-0.25/chratio
344
	# value to fix chroma horizontal shift introduced by Dither_resize16 (flat area resize)
345
	# this fixing only take effects when Y/U/V is processed separately(as Y8) in flat area scaling (colorspace transferring)
346
	# Dither_resize16 accepts "cplace" and correctly processes chroma placement for YUV input
347
    
348
    ###############################################################################################################################
349
	###############################################################################################################################
350
    # Pre-Process
351
	
352
    input    = wpre || hpre ? lsb_in ? input.Dither_resize16(wpre?prew:sw, hpre?preh:sh, wpre?prel:0, hpre?pret:0,
353
    \                                                        wpre?prew:sw, hpre?preh:sh, kernel="point")
354
    \                                : input.PointResize(wpre?prew:sw, hpre?preh:sh, wpre?prel:0, hpre?pret:0, wpre?prew:sw, hpre?preh:sh)
355
    \                       : input
356
    input8   = lsb_in ? input.nnedi3_resize16_Down8(tv_range, Yt, Ut, Vt, mixed ? -1 : dither) : input
357
    input16  = lsb_in ? input : input.nnedi3_resize16_U16(tv_range, True, True, True)
358
    
359
    ###############################################################################################################################
360
	###############################################################################################################################
361
    # nnedi3 upscale for edge area
362
	
363
    !(enable && nnt) ? NOP() : \
364
    yhct==chct && yvct==cvct && sCSP=="YV12" ? \
365
    Eval("""
366
        edgenn  = input8.nnedi3_resize16_rpow2(yvct, yhct, 1, 1, Yt, Ut, Vt, nsize, nns, qual, etype, pscrn, threads)
367
    	edgennY = sharp>0 ? edgenn.CSmod(chroma=False, ss_w=1.00, ss_h=1.00, preblur=-4, Smethod=1, kernel=6, strength=sharp, Soothe=-1)
368
        \                         .nnedi3_resize16_U16(tv_range, Yt, Ut, Vt)
369
    	\                 : edgenn.nnedi3_resize16_U16(tv_range, Yt, Ut, Vt)
370
    	edgennU = edgennY.UToY8()
371
    	edgennV = edgennY.VToY8()
372
    	edgennY = edgennY.ConvertToY8()
373
    """) : \
374
    Eval("""
375
        edgennY = !Ynnt ? NOP()
376
    	\               : sharp>0 ? input8.ConvertToY8  ().nnedi3_resize16_rpow2(yvct, yhct, 1, 1, Yt, False, False,
377
        \                                                                        nsize, nns, qual, etype, pscrn, threads).ConvertToYV12()
378
        \                                 .CSmod(chroma=False, ss_w=1.00, ss_h=1.00, preblur=-4, Smethod=1, kernel=6, strength=sharp, Soothe=-1)
379
    	\                                 .ConvertToY8  ().nnedi3_resize16_U16(tv_range, Yt, False, False)
380
        \                         : input8.ConvertToY8  ().nnedi3_resize16_rpow2(yvct, yhct, 1, 1, Yt, False, False,
381
        \                                                                        nsize, nns, qual, etype, pscrn, threads)
382
    	\                                                 .nnedi3_resize16_U16(tv_range, Yt, False, False)
383
    	edgennU = !Unnt ? NOP()
384
    	\               : input8.UToY8      ().nnedi3_resize16_rpow2(cvct, chct, 1, 1, Ut, False, False,
385
        \                                                            nsize, nns, qual, etype, pscrn, threads)
386-
    	\                       .ConvertToY8().nnedi3_resize16_U16(tv_range, Ut, False, False)
386+
    	\                                     .nnedi3_resize16_U16(tv_range, Ut, False, False)
387
    	edgennV = !Vnnt ? NOP()
388
    	\               : input8.VToY8      ().nnedi3_resize16_rpow2(cvct, chct, 1, 1, Vt, False, False,
389
        \                                                            nsize, nns, qual, etype, pscrn, threads)
390-
    	\                       .ConvertToY8().nnedi3_resize16_U16(tv_range, Vt, False, False)
390+
    	\                                     .nnedi3_resize16_U16(tv_range, Vt, False, False)
391
    """)
392
    
393
    ###############################################################################################################################
394
	###############################################################################################################################
395
    # edge area resize & fix center shift
396
	
397
	yrh      = yrhratio>ratiothr
398
	yrv      = yrvratio>ratiothr
399
	crh      = crhratio>ratiothr
400
	crv      = crvratio>ratiothr
401
	
402
    !(enable && nnt) ? NOP() : \
403
    Eval("""
404
        edgennY = !Ynnt ? NOP()
405
        \               : curve=="linear" ? edgennY
406
        \                                 : edgennY.Dither_y_gamma_to_linear(tv_range, tv_range, curve, u=1, v=1, gcor=gcor)
407
        edgeY   = !Ynnt ? input16.BlankClip(width=ow , height=oh *2, pixel_type="Y8", color_yuv=$008080)
408
    	\               : edgennY.""" + resste + """(ow , oh , src_left *yhrf+yhfix        , src_top *yvrf+yvfix,
409
        \                                            src_width *yhrf, src_height *yvrf, y=Y31, u=1  , v=1  ,
410
        \                                            kernelh=yrh?kernel_u:kernel_d, kernelv=yrv?kernel_u:kernel_d,
411
		\                                            fh=yrh?f_u:f_d, fv=yrv?f_u:f_d,
412
		\                                            invksh=yrh?invks_u:invks_d, invksv=yrv?invks_u:invks_d,
413
		\                                            taps=taps, a1=a1, a2=a2, a3=a3, invkstaps=invkstaps
414
		\                                           )
415
        edgeY   = !Ynnt ? edgeY
416
        \               : curve=="linear" ? edgeY
417
        \                                 : edgeY  .Dither_y_linear_to_gamma(tv_range, tv_range, curve, u=1, v=1, gcor=gcor)
418
        
419
    	edgeU   = !Unnt ? input16.BlankClip(width=owc, height=ohc*2, pixel_type="Y8", color_yuv=$008080)
420
    	\               : edgennU.""" + resste + """(owc, ohc, src_leftc*chrf+chfix+cphfixe, src_topc*cvrf+cvfix,
421
        \                                            src_widthc*chrf, src_heightc*cvrf, y=U31, u=1  , v=1  ,
422
        \                                            kernelh=crh?kernel_u:kernel_d, kernelv=crv?kernel_u:kernel_d,
423
		\                                            fh=crh?f_u:f_d, fv=crv?f_u:f_d,
424
		\                                            invksh=crh?invks_u:invks_d, invksv=crv?invks_u:invks_d,
425
		\                                            taps=taps, a1=a1, a2=a2, a3=a3, invkstaps=invkstaps
426
		\                                           )
427
		
428
    	edgeV   = !Vnnt ? input16.BlankClip(width=owc, height=ohc*2, pixel_type="Y8", color_yuv=$008080)
429
    	\               : edgennV.""" + resste + """(owc, ohc, src_leftc*chrf+chfix+cphfixe, src_topc*cvrf+cvfix,
430
        \                                            src_widthc*chrf, src_heightc*cvrf, y=V31, u=1  , v=1  ,
431
        \                                            kernelh=crh?kernel_u:kernel_d, kernelv=crv?kernel_u:kernel_d,
432
		\                                            fh=crh?f_u:f_d, fv=crv?f_u:f_d,
433
		\                                            invksh=crh?invks_u:invks_d, invksv=crv?invks_u:invks_d,
434
		\                                            taps=taps, a1=a1, a2=a2, a3=a3, invkstaps=invkstaps
435
		\                                           )
436
		
437
    	edge16  = IsY8 ? edgeY : YToUV(edgeU, edgeV, edgeY)
438
    """)
439
    
440
    ###############################################################################################################################
441
	###############################################################################################################################
442
    # flat area resize
443
444
	yh       = yhratio>ratiothr
445
	yv       = yvratio>ratiothr
446
	ch       = chratio>ratiothr
447
	cv       = cvratio>ratiothr
448
	
449
    !(enable && (mixed || !(Ynnt && Unnt && Vnnt))) ? NOP() : \
450
    yhratio==chratio && yvratio==cvratio && (!mixed || (Ynnt && Unnt && Vnnt)) ? \
451
    Eval("""
452
        flat16  = curve=="linear" ? input16
453
        \                         : input16.Dither_y_gamma_to_linear(tv_range, tv_range, curve, u=U21, v=V21, gcor=gcor)
454
        flat16  =                   flat16.      """ + resstf + """
455
		\                                           (ow , oh , src_left                    , src_top            ,
456
        \                                            src_width      , src_height      , y=Y32, u=U32, v=V32, cplace=cplace,
457
        \                                            kernelh=yh?kernel_u:kernel_d, kernelv=yv?kernel_u:kernel_d,
458
		\                                            fh=yh?f_u:f_d, fv=yv?f_u:f_d,
459
		\                                            invksh=yh?invks_u:invks_d, invksv=yv?invks_u:invks_d,
460
		\                                            taps=taps, a1=a1, a2=a2, a3=a3, invkstaps=invkstaps
461
		\                                           )
462
        flat16  = curve=="linear" ? flat16
463
        \                         : flat16 .Dither_y_linear_to_gamma(tv_range, tv_range, curve, u=U21, v=V21, gcor=gcor)
464
    """) : \
465
    Eval("""
466
        flatY   = curve=="linear"        ? input16.ConvertToY8() :
467
        \         (mixed || !Ynnt) && Yt ? input16.ConvertToY8().Dither_y_gamma_to_linear(tv_range, tv_range, curve, u=1  , v=1  , gcor=gcor)
468
        \                                : input16.ConvertToY8()
469
        flatY   = (mixed || !Ynnt) && Yt ? flatY          .""" + resstf + """
470
		\                                           (ow , oh , src_left                    , src_top            ,
471
        \                                            src_width      , src_height      , y=Y32, u=1  , v=1  ,
472
        \                                            kernelh=yh?kernel_u:kernel_d, kernelv=yv?kernel_u:kernel_d,
473
		\                                            fh=yh?f_u:f_d, fv=yv?f_u:f_d,
474
		\                                            invksh=yh?invks_u:invks_d, invksv=yv?invks_u:invks_d,
475
		\                                            taps=taps, a1=a1, a2=a2, a3=a3, invkstaps=invkstaps
476
		\                                           )
477
        \                                : input16.BlankClip(width=ow , height=oh *2, pixel_type="Y8", color_yuv=$008080)
478
        flatY   = curve=="linear"        ? flatY                 :
479
        \         (mixed || !Ynnt) && Yt ? flatY                .Dither_y_linear_to_gamma(tv_range, tv_range, curve, u=1  , v=1  , gcor=gcor)
480
        \                                : flatY
481
        
482
        flatU   = (mixed || !Unnt) && Ut ? input16.UToY8().""" + resstf + """
483
		\                                           (owc, ohc, src_leftc           +cphfix , src_topc           ,
484
        \                                            src_widthc     , src_heightc     , y=U32, u=1  , v=1  ,
485
        \                                            kernelh=ch?kernel_u:kernel_d, kernelv=cv?kernel_u:kernel_d,
486
		\                                            fh=ch?f_u:f_d, fv=cv?f_u:f_d,
487
		\                                            invksh=ch?invks_u:invks_d, invksv=cv?invks_u:invks_d,
488
		\                                            taps=taps, a1=a1, a2=a2, a3=a3, invkstaps=invkstaps
489
		\                                           )
490
        \                                : input16.BlankClip(width=owc, height=ohc*2, pixel_type="Y8", color_yuv=$008080)
491
		
492
        flatV   = (mixed || !Vnnt) && Vt ? input16.VToY8().""" + resstf + """
493
		\                                           (owc, ohc, src_leftc           +cphfix , src_topc           ,
494
        \                                            src_widthc     , src_heightc     , y=V32, u=1  , v=1  ,
495
        \                                            kernelh=ch?kernel_u:kernel_d, kernelv=cv?kernel_u:kernel_d,
496
		\                                            fh=ch?f_u:f_d, fv=cv?f_u:f_d,
497
		\                                            invksh=ch?invks_u:invks_d, invksv=cv?invks_u:invks_d,
498
		\                                            taps=taps, a1=a1, a2=a2, a3=a3, invkstaps=invkstaps
499
		\                                           )
500
        \                                : input16.BlankClip(width=owc, height=ohc*2, pixel_type="Y8", color_yuv=$008080)
501
		
502
    	flat16  = IsY8 ? flatY : YToUV(flatU, flatV, flatY)
503
    """)
504
    
505
    ###############################################################################################################################
506
	###############################################################################################################################
507
    # Threshold Merging & Output
508
	
509
    enable ? \
510
    Eval("""
511
        merge16  = !nnt ? flat16
512
        \               : mixed ? Dither_limit_dif16(flat16, edge16, thr=thr, elast=elast, y=Ynn, u=Unn, v=Vnn)
513
        \                       : Ynnt==Unnt && Unnt==Vnnt || IsY8 ? edge16
514
        \                                                          : mt_lutxy(edge16, flat16, Y=Yt?Ynnt?2:4:1, U=Ut?Unnt?2:4:1, V=Vt?Vnnt?2:4:1)
515
        merge16  = IsY8 ? output=="Y8" ? merge16.ConvertToY8() : Eval("merge16.ConvertTo"+oCSP).Dither_lut16(Y=2, U=-32768, V=-32768) : merge16
516
        
517
        final    = IsRGB ? merge16.Dither_convert_yuv_to_rgb(matrix=matrix, tv_range=tv_range, lsb_in=True, mode=dither, output=output)
518
        \                : lsb ? merge16
519
        \                      : merge16.nnedi3_resize16_Down8(tv_range, True, !IsY8, !IsY8, dither)
520
    """) : \
521
    Eval("""
522
        shift16  = input16.Dither_resize16(ow, oh, src_left, src_top, src_width, src_height, kernel="point", y=Y, u=U, v=V)
523
        shift16  = IsY8 ? output=="Y8" ? merge16.ConvertToY8() : Eval("shift16.ConvertTo"+oCSP).Dither_lut16(Y=2, U=-32768, V=-32768) : shift16
524
        
525
        final    = IsRGB ? shift16.Dither_convert_yuv_to_rgb(matrix=matrix, tv_range=tv_range, lsb_in=True, mode=dither, output=output)
526
        \                : lsb ? shift16
527
        \                      : shift16.nnedi3_resize16_Down8(tv_range, True, !IsY8, !IsY8, dither)
528
    """)
529
    
530
    
531
    return final
532
}
533
534
535
Function nnedi3_resize16_rpow2(clip input, int "vct", int "hct", int "vfield", int "hfield", bool "Y", bool "U", bool "V",
536
\                              int "nsize", int "nns", int "qual", int "etype", int "pscrn", int "threads", bool "honly")
537
{
538
    vct      = Default(vct,      1      )
539
    hct      = Default(hct,      1      )
540
    vfield   = Default(vfield,   1      )
541
    hfield   = Default(hfield,   1      )
542
    Y        = Default(Y,        True   )
543
    U        = Default(U,        False  )
544
    V        = Default(V,        False  )
545
    honly    = Default(honly,    False  )
546
    
547
    
548
    input
549
    
550
    hct >= 1 ? \
551
    Eval("""
552
        (honly) ? last
553
        \       : Eval(" try { fturnright(chroma=U||V, mt=threads!=1) } catch(error_msg) { TurnRight() } ")
554
        nnedi3(hfield, True, Y, U, V, nsize, nns, qual, etype, pscrn, threads)
555
        
556
    	hct    = hct - 1
557
        honly  = hct >= 1
558
        hfield = 0
559
        
560
    	(honly) ? last
561
        \       : Eval(" try { fturnleft (chroma=U||V, mt=threads!=1) } catch(error_msg) { TurnLeft () } ")
562
    """) : NOP()
563
    
564
    vct >= 1 && !honly ? \
565
    Eval("""
566
        nnedi3(vfield, True, Y, U, V, nsize, nns, qual, etype, pscrn, threads)
567
        
568
    	vct    = vct - 1
569
        vfield = 0
570
    """) : NOP()
571
    
572
    
573
    return Y||U||V ? vct <= 0 && hct <= 0 ? last
574
    \                                     : last.nnedi3_resize16_rpow2(vct, hct, vfield, hfield, Y, U, V, nsize, nns, qual, etype, pscrn, threads, honly)
575
    \              : input
576
}
577
578
579
Function nnedi3_resize16_GetCSP(clip c)
580
{
581
    return c.IsPlanar ? c.IsYV12 ? "YV12" :
582
    \                   c.IsYV16 ? "YV16" :
583
    \                   c.IsYV24 ? "YV24" : c.GetCSP_Y8_YV411 :
584
    \      c.IsYUY2   ? "YUY2"   :
585
    \      c.IsRGB32  ? "RGB32"  :
586
    \      c.IsRGB24  ? "RGB24"  : "Unknown"
587
    
588
    
589
    Function GetCSP_Y8_YV411(clip c) {
590
        try {
591
            c.UtoY
592
            csp = "YV411"
593
        } catch ( error_msg ) {
594
        csp = "Y8"
595
        }
596
        return csp
597
    }
598
}
599
600
/*
601
Function nnedi3_resize16_RemoveGrain(clip input, int "mode", int "modeU", int "modeV")
602
{
603
    mode     = Default(mode,     1      )
604
    modeU    = Default(modeU,    mode   )
605
    modeV    = Default(modeV,    modeU  )
606
    
607
    
608
    iCSP     = input.nnedi3_resize16_GetCSP()
609
    isYV12   = iCSP == "YV12"
610
    isY8     = iCSP == "Y8"
611
    
612
    sw       = input.Width ()
613
    sh       = input.Height()
614
    wmod4    = sw/4*4 == sw
615
    hmod4    = sh/4*4 == sh
616
    mod4     = wmod4 && hmod4
617
    padw     = wmod4 ? sw : (sw/4+1)*4
618
    padh     = hmod4 ? sh : (sh/4+1)*4
619
    
620
    
621
    input_m4 = mod4 ? input : input.PointResize(padw, padh, 0, 0, padw, padh)
622
    
623
    return isYV12 ? input.RemoveGrain(mode, modeU, modeV)
624
    \             : isY8 ? input_m4                       .RemoveGrain(mode , -1, -1)
625
    \                              .Crop(0, 0, sw, sh)
626
    \                    : YToUV(input_m4.UToY8()         .RemoveGrain(modeU, -1, -1),
627
    \                            input_m4.VToY8()         .RemoveGrain(modeV, -1, -1),
628
    \                            input_m4.ConvertToY8()   .RemoveGrain(mode , -1, -1))
629
    \                     .Crop(0, 0, sw, sh)
630
}
631
*/
632
633
Function nnedi3_resize16_U16(clip input, bool "tv_range", bool "Y", bool "U", bool "V", int "dither", int "interp", bool "HQ")
634
{ 
635
    tv_range = Default(tv_range, True   ) # define if input clip is of tv range(limited range)
636
    interp   = Default(interp,   0      ) # use interp or not for SmoothCurve/SmoothCurve16
637
    HQ       = Default(HQ,       False  ) # enable high quality interpolation (slower)
638
    dither   = Default(dither,   -1     ) # -1 for no dither, 0 for ordered-dither, 1-100 for noise strength
639
    Y        = Default(Y,        True   )
640
    U        = Default(U,        True   )
641
    V        = Default(V,        True   )
642
    
643
    
644
    Assert(dither>=-1 && dither<=100 , """nnedi3_resize16_U16: "dither" ranges from -1 to 100!""")
645
    
646
    oCceil   = (255-128) / (255.5-128) * (65535.5-32768) + 32768
647
    
648
    Yexpr    = "0-0  ;                  255-65535             ;65535-65535          "
649
    Cexpr    = "0-0.5;0.5-0.5;128-32768;255-"+String(oCceil)+";65535-"+String(oCceil)
650
    DfExpr   = "0-0;65535-65535"
651
    Yexpr    = Y ? Yexpr : DfExpr
652
    Uexpr    = U ? Cexpr : DfExpr
653
    Vexpr    = V ? Cexpr : DfExpr
654
      
655
    up       =  tv_range ? input.Dither_convert_8_to_16()
656
    \                    : Y||U||V ? StackVertical(input.Dither_gen_null_lsb(), input)
657
	\                               .SmoothCurve16(Ycurve=Yexpr, Ucurve=Uexpr, Vcurve=Vexpr, mode=0, interp=interp, HQ=HQ,
658
    \                                              dither=dither, limiter=False, TVrange=0)
659
    \                              : StackVertical(input.Dither_gen_null_lsb(), input)
660
    
661
    
662
    return up
663
}
664
665
666
Function nnedi3_resize16_Down8(clip input, bool "tv_range", bool "Y", bool "U", bool "V", int "dither", int "interp", bool "HQ")
667
{
668
    tv_range = Default(tv_range, True   ) # define if input clip is of tv range(limited range)
669
    interp   = Default(interp,   0      ) # use interp or not for SmoothCurve/SmoothCurve16
670
    HQ       = Default(HQ,       False  ) # enable high quality interpolation (slower)
671
    dither   = tv_range ? Default(dither, 6) : Default(dither, 50) # dither mode
672
    Y        = Default(Y,        True   )
673
    U        = Default(U,        True   )
674
    V        = Default(V,        True   )
675
    
676
    
677
    Assert(dither>=-1 && dither<=100 , """nnedi3_resize16_Down8: "dither" ranges from -1 to 100!""")
678
    
679
    iCceil   = (255-128) / (255.5-128) * (65535.5-32768) + 32768
680
    
681
    Yexpr    = "0-0;                                           65535-255"
682
    Cexpr    = "0-0.5;0.5-0.5;32768-128;"+String(iCceil)+"-255;65535-255"
683
    DfExpr   = "0-0;65535-65535"
684
    Yexpr    = Y ? Yexpr : DfExpr
685
    Uexpr    = U ? Cexpr : DfExpr
686
    Vexpr    = V ? Cexpr : DfExpr
687
    
688
    sDown    = tv_range ? NOP()
689
    \                   : input.SmoothCurve16(Ycurve=Yexpr, Ucurve=Uexpr, Vcurve=Vexpr, mode=0, interp=interp, HQ=HQ,
690
    \                                         dither=dither, limiter=False, TVrange=0)
691
    
692
    down     = tv_range ? input.DitherPost(mode=dither, y=Y?3:1, u=U?3:1, v=V?3:1)
693
    \                   : Y||U||V ? sDown.Dither_get_lsb()
694
    \                             : input.Dither_get_msb()
695
    
696
    
697
    return down
698
}