View difference between Paste ID: kM1mip5n and BzXJk5Z8
SHOW: | | - or go back to the newest paste.
1-
/* ResizeX v1.0.1 mod 5
1+
/* ResizeX v1.0.1 mod 6
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") {
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") {
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-
src_width  = Default(src_width, iw)
55+
desampling = Default(desampling, false)
56-
src_height = Default(src_height, ih)
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
66
sispmt  = Findstr(VersionString(), "AviSynth+") != 0 && Findstr(VersionString(), "r1576") == 0
67
68
Assert(target_width  > 0, "ResizeX: target width must be greater than 0")
69
Assert(target_height > 0, "ResizeX: target height must be greater than 0")
70
Assert(cplace == "MPEG1" || cplace == "MPEG2", "ResizeX: cplace must be MPEG1 or MPEG2")
71
lsb_native = sispmt ? !(Input.BitsPerComponent() > 8 && (lsb)) : true
72
sispmt ? Assert(lsb_native, "lsb hack is not Compatible with native high bit depth" ) : nop()
73
sispmt ? Assert(!(Input.isYUVA() && lsb), "lsb hack is not Compatible with YUVA" ) : nop()
74
75-
src_width  = src_width  == 0 ? iw
75+
76
src_width  = src_width  == 0 ? desampling ? undefined : iw
77
\          : src_width  <  0 ? iw-src_left+src_width
78-
src_height = src_height == 0 ? ih
78+
79
src_height = src_height == 0 ? desampling ? undefined : ih
80
\          : src_height <  0 ? ih-src_top+src_height
81
\                            : src_height
82
83
# Get the input clip's colorspace
84
csp = input.PixelType()
85
86
sislumaonly = sispmt ? input.isy() : input.isy8()
87
88
chroma = sislumaonly ? false : chroma
89
90
chr420  = sispmt ? input.is420() : input.isyv12()
91
chr422  = sispmt ? input.is422() : input.isYV16()
92
chr444  = sispmt ? input.is444() : input.isYV24()
93
94
Assert(csp != "RGB24" && csp != "RGB32" || !lsb, "ResizeX: lsb things must be false for RGB input")
95
96
# Check for subsampled chroma
97
hssc12 = chr420 || chr422 || csp == "YUY2"
98
hssc14 = csp == "YV411"
99
vssc12 = chr420
100
101
Assert(!hssc12 || target_width%2  == 0, "ResizeX: target width of "+csp+" must be a multiple of 2")
102
Assert(!hssc14 || target_width%4  == 0, "ResizeX: target width of "+csp+" must be a multiple of 4")
103
Assert(!vssc12 || target_height%2 == 0, "ResizeX: target height of "+csp+" must be a multiple of 2")
104
105
# Set chroma target and src values based on the subsampling ratios
106
target_width_c  = hssc12 ? target_width/2  : hssc14 ? target_width/4 : target_width
107
target_height_c = vssc12 ? target_height/2 : target_height
108
src_left_c      = hssc12 ? src_left/2.0    : hssc14 ? src_left/4.0   : src_left
109-
src_width_c     = hssc12 ? src_width/2.0   : hssc14 ? src_width/4.0  : src_width
109+
110-
src_height_c    = vssc12 ? src_height/2.0  : src_height
110+
src_width2		= defined(src_width) ? src_width : iw
111
src_height2		= defined(src_height) ? src_height : ih
112
src_width_c     = defined(src_width) ? hssc12 ? src_width/2.0   : hssc14 ? src_width/4.0  : src_width : src_width
113-
MPEG2shift = hssc12 ? 0.25*(1.0-Float(src_width_c)/Float(target_width_c))
113+
src_height_c    = defined(src_height) ? vssc12 ? src_height/2.0  : src_height : src_height
114-
\          : hssc14 ? 0.375*(1.0-Float(src_width_c)/Float(target_width_c))
114+
src_width_c2    = defined(src_width_c) ? src_width_c : hssc12 ? src_width2/2.0   : hssc14 ? src_width2/4.0  : src_width2
115
src_height_c2   = defined(src_height_c) ? src_height_c : vssc12 ? src_height2/2.0  : src_height2
116
117
# Add the MPEG2 chroma shift correction to the src_left_c value
118
MPEG2shift = hssc12 ? 0.25*(1.0-Float(src_width_c2)/Float(target_width_c))
119
\          : hssc14 ? 0.375*(1.0-Float(src_width_c2)/Float(target_width_c))
120
\                   : 0
121
src_left_c  = cplace == "MPEG2" && kernel.LeftStr(5) != "Point" ? src_left_c+MPEG2shift
122
\                                                               : src_left_c
123
124
# Remove "Resize" from the end of the kernel string if present
125
kernel = kernel.RightStr(6) == "Resize" ? kernel.LeftStr(kernel.StrLen()-6) : kernel
126
127
# Support the Dither_resize16 kernel name variants when resizing 8-bit
128
kernel = kernel == "Linear"   ? "Bilinear"
129
\      : kernel == "Cubic"    ? "Bicubic"
130
\      : kernel == "Gaussian" ? "Gauss"
131
\                             : kernel
132
133
# Dither_resize16 kernels without an internal equivalent can't be used without lsb things being true
134
Assert(lsb || kernel == "Spline16" || kernel == "Spline36" || kernel == "Spline64" ||
135
\      kernel != "Rect" && kernel != "Box" && kernel != "Blackmanminlobe" && kernel.LeftStr(6) != "Spline" && kernel != "Impulse",
136
\      "ResizeX: Rect, Box, Blackmanminlobe, Spline, and Impulse kernels"+chr(10)+
137
\      "are available only when resizing for lsb things)")
138
139
# Get the taps value from the kernel string if present (overrides the parameter)
140
taps = kernel.LeftStr(6)  == "Spline"          && kernel != "Spline16" && kernel != "Spline36" && kernel != "Spline64" &&
141
\                                                 kernel.StrLen() >  6 ? kernel.RightStr(kernel.StrLen()-6).Value().Int()
142
\    : kernel.LeftStr(7)  == "Lanczos"         && kernel.StrLen() >  7 ? kernel.RightStr(kernel.StrLen()-7).Value().Int()
143
\    : kernel.LeftStr(8)  == "Blackman"        && kernel.LeftStr(15) != "Blackmanminlobe" &&
144
\                                                 kernel.StrLen() >  8 ? kernel.RightStr(kernel.StrLen()-8).Value().Int()
145
\    : kernel.LeftStr(15) == "Blackmanminlobe" && kernel.StrLen() > 15 ? kernel.RightStr(kernel.StrLen()-15).Value().Int()
146
\    : kernel.LeftStr(4)  == "Sinc"            && kernel.StrLen() >  4 ? kernel.RightStr(kernel.StrLen()-4).Value().Int()
147
\                                                                      : taps
148
149
# Remove the taps value from the kernel string if present
150
kernel = kernel.LeftStr(6)  == "Spline"          && kernel != "Spline16" && kernel != "Spline36" && kernel != "Spline64" &&
151
\                                                   kernel.StrLen() >  6 ? kernel.LeftStr(6)
152
\      : kernel.LeftStr(7)  == "Lanczos"         && kernel.StrLen() >  7 ? kernel.LeftStr(7)
153
\      : kernel.LeftStr(8)  == "Blackman"        && kernel.LeftStr(15) != "Blackmanminlobe" &&
154
\                                                   kernel.StrLen() >  8 ? kernel.LeftStr(8)
155
\      : kernel.LeftStr(15) == "Blackmanminlobe" && kernel.StrLen() > 15 ? kernel.LeftStr(15)
156
\      : kernel.LeftStr(4)  == "Sinc"            && kernel.StrLen() >  4 ? kernel.LeftStr(4)
157
\                                                                        : kernel
158
159
# Set the a1 and a2 values for bicubic presets (overrides the parameters)
160
    kernel == "Catmull-Rom" || kernel == "CatRom" ? 
161
\   Eval("""
162
         a1     = 0.0
163
         a2     = 0.5
164
         kernel = "Bicubic"
165
         """)
166
\ : kernel == "Hermite" ?
167
\   Eval("""
168
         a1     = 0.0
169
         a2     = 0.0
170
         kernel = "Bicubic"
171
         """)
172
\ : kernel == "Mitchell-Netravali" || kernel == "Mitchell" ?
173
\   Eval("""
174
         a1     = 1.0/3.0
175
         a2     = 1.0/3.0
176
         kernel = "Bicubic"
177
         """)
178
\ : kernel == "Robidoux" ?
179
\   Eval("""
180
         a1     = 0.3782
181
         a2     = 0.3109
182
         kernel = "Bicubic"
183
         """)
184
\ : kernel == "SoftCubic" ?
185
\   Eval("""
186
         a1     = 0.75
187
         a2     = 0.25
188
         kernel = "Bicubic"
189
         """)
190
\ : kernel.LeftStr(9) == "SoftCubic" && kernel.StrLen() > 9 ?
191
\   Eval("""
192
         a1     = kernel.RightStr(kernel.StrLen()-9).Value()
193
         a1     = a1 >= 0 && a1 <= 100 ? a1/100.0
194
         \      : Assert(false, "ResizeX: SoftCubic value must be in the range 0 through 100")
195
         a2     = 1.0-a1
196
         kernel = "Bicubic"
197
         """)
198
\ : NOP()
199
200
# If chroma=false and resizing 8-bit YUV, convert to Y8 to avoid processing chroma
201
csp2   = !chroma && !lsb && !(input.isrgb()) ? "Y" : csp
202
input2 = csp2 == "Y" && !sislumaonly ? sispmt ? input.ConvertToY() : input.ConvertToY8() : input
203
204
# Convert YUY2 to YV16 because Dither_resize16 only supports planar formats
205
input2 = csp2 == "YUY2" ? input2.ConvertToYV16() : input2
206
207
# Dither_resize16 is used if lsb things is true,
208
# so the input needs to be converted to stack16 format if lsb_in=false and lsb is used
209
input2 = !lsb_in && lsb ? input2.Dither_convert_8_to_16() : input2
210
211
# Blank luma channel for luma=false
212
noY = input2.BlankClip(width=target_width, height=target_height, pixel_type=sispmt ? "Y"+string(Input.BitsPerComponent()) : "Y8", color_yuv=color_gray)
213
214
# Perform resizing
215
    lsb ?
216
\   Eval("""
217-
         r8 = 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)
217+
218
         \                                taps=taps, a1=a1, a2=a2, cplace=cplace, y=luma?3:1, u=chroma?3:1, v=chroma?3:1"""+dither_params+""")
219
         """)
220
\ : input.isRGB() || (sispmt ? (csp2 == "Y" || input.is444() && luma) : (csp2 == "Y" || csp2 == "YV24" && luma)) ?
221
\   Eval("""
222-
         r8Y = 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)
222+
         r8 = desampling ? input2.ResizeX_deResizemt(target_width,target_height,-src_left,-src_top,src_width,src_height,kernel,taps,a1,a2,mt_params) : \
223
		 				   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)
224-
         r8U = 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)
224+
225
         """)
226-
         r8V = 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)
226+
227
         r8Y = sispmt ? input2.ConvertToY() : input2.ConvertToY8()
228
         r8Y = desampling ? r8Y.ResizeX_deResizemt(target_width,target_height,-src_left,-src_top,src_width,src_height,kernel,taps,a1,a2,mt_params) : \
229
		 					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)
230
         r8U = sispmt ? input2.ExtractU() : input2.UToY8()
231
         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) : \
232
		 					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)
233
         r8V = sispmt ? input2.ExtractV() : input2.VToY8()
234
         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) : \
235
		 					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)
236
         resized = luma ? YToUV(r8U,r8V,r8Y)
237
         \              : YToUV(r8U,r8V,noY)
238
         """)
239
240
# The resized clip will be in stack16 format if lsb is used, so dither down to 8-bit if lsb_out=false
241
resized = lsb && !lsb_out ? resized.DitherPost(mode=6) : resized
242
243
# Make sure the output is the same colorspace as the input
244
resized = csp == "YV12"  ? resized.ConvertToYV12()  
245
\       : csp == "YV16"  ? resized.ConvertToYV16()
246
\       : csp == "YUY2"  ? resized.ConvertToYUY2()
247
\       : csp == "YV411" ? resized.ConvertToYV411()
248
\       : csp == "YV24"  ? resized.ConvertToYV24()
249
\       : chr420         ? resized.ConvertToYUV420()  
250
\       : chr422         ? resized.ConvertToYUV422()  
251
\       : chr444         ? resized.ConvertToYUV444()  
252
\                        : resized
253
254
resized = sispmt ? 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
255
256
return resized
257
}
258
259
# Wrapper function for AviSynth's internal resizers
260
function ResizeX_AvsResize(clip input, int target_width, int target_height, float "src_left", float "src_top",
261
\                          float "src_width", float "src_height", string "kernel", int "taps", float "a1", float "a2") {
262
263
kernel = Default(kernel, "Spline36")
264
265
Eval("""
266
     kernel == "Spline16" ||
267
\    kernel == "Spline36" ||
268
\    kernel == "Spline64" || 
269
\    kernel == "Bilinear" ||
270
\    kernel == "Point"     ? input."""+kernel+"""Resize(target_width,target_height,src_left,src_top,src_width,src_height)
271
\  : kernel == "Lanczos"  ||
272
\    kernel == "Blackman" ||
273
\    kernel == "Sinc"      ? input."""+kernel+"""Resize(target_width,target_height,src_left,src_top,src_width,src_height,taps)
274
\  : kernel == "Bicubic"   ? input."""+kernel+"""Resize(target_width,target_height,a1,a2,src_left,src_top,src_width,src_height)
275
\  : kernel == "Gauss"     ? input."""+kernel+"""Resize(target_width,target_height,src_left,src_top,src_width,src_height,a1)
276
\                          : Assert(false, "ResizeX_AvsResize: invalid kernel")
277
     """)
278
}
279
280
# Wrapper function for AviSynth's mt resizers
281
function ResizeX_AvsmtResize(clip input, int target_width, int target_height, float "src_left", float "src_top",
282
\                          float "src_width", float "src_height", string "kernel", int "taps", float "a1", float "a2", string "mt_params") {
283
284
kernel    = Default(kernel, "Spline36")
285
mt_params = Default(mt_params,      "")
286
287
try { Eval("""
288
     kernel == "Spline16" ||
289
\    kernel == "Spline36" ||
290
\    kernel == "Spline64" || 
291
\    kernel == "Bilinear" ||
292
\    kernel == "Point"     ? input."""+kernel+"""Resizemt(target_width,target_height,src_left,src_top,src_width,src_height"""+mt_params+""")
293
\  : kernel == "Lanczos"  ||
294
\    kernel == "Blackman" ||
295
\    kernel == "Sinc"      ? input."""+kernel+"""Resizemt(target_width,target_height,src_left,src_top,src_width,src_height,taps"""+mt_params+""")
296
\  : kernel == "Bicubic"   ? input."""+kernel+"""Resizemt(target_width,target_height,a1,a2,src_left,src_top,src_width,src_height"""+mt_params+""")
297
\  : kernel == "Gauss"     ? input."""+kernel+"""Resizemt(target_width,target_height,src_left,src_top,src_width,src_height,a1"""+mt_params+""")
298
\                          : Assert(false, "ResizeX_AvsmtResize: invalid kernel")
299
          """)
300
      } catch(error_msg) { input.ResizeX_AvsResize(target_width, target_height, src_left, src_top, src_width, src_height, kernel, taps, a1, a2) }
301
}
302
303
# Wrapper function for AviSynth's mt deresizers
304
function ResizeX_deResizemt(clip input, int target_width, int target_height, float "src_left", float "src_top",
305
\                          float "src_width", float "src_height", string "kernel", int "taps", float "a1", float "a2", string "mt_params") {
306
307
kernel    = Default(kernel, "Spline36")
308
mt_params = Default(mt_params,      "")
309
310
     kernel == "Spline16" ||
311
\    kernel == "Spline36" ||
312
\    kernel == "Spline64" || 
313
\    kernel == "Bilinear"  ? Eval("input.de"+kernel+"Resizemt(target_width,target_height,src_left,src_top,src_width,src_height"+mt_params+")")
314
\  : kernel == "Lanczos"  ||
315
\    kernel == "Blackman" ||
316
\    kernel == "Sinc"      ? Eval("input.de"+kernel+"Resizemt(target_width,target_height,src_left,src_top,src_width,src_height,taps"+mt_params+")")
317
\  : kernel == "Bicubic"   ? Eval("input.de"+kernel+"Resizemt(target_width,target_height,a1,a2,src_left,src_top,src_width,src_height"+mt_params+")")
318
\  : kernel == "Gauss"     ? Eval("input.de"+kernel+"Resizemt(target_width,target_height,src_left,src_top,src_width,src_height,a1"+mt_params+")")
319
\                          : Assert(false, "ResizeX_deResizemt: invalid kernel")
320
}