-
Notifications
You must be signed in to change notification settings - Fork 2
/
bborders.avsi
422 lines (361 loc) · 21.9 KB
/
bborders.avsi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
/*
by PL
Функция изменяет значения крайних пикселей клипа так, чтобы они были "более похожи" на соседние,
что, возможно, позволит избежать "сильного" использования Crop() для удаления "неприятных краёв",
не очень сильно отличающихся от "основного" изображения. См. примеры скринов.
*/
/******* bbmod is a balanceborders mod that uses division instead subtraction for the filtering. *******/
### Usage ###
###
# BalanceBorders(clip c, val "cTop", val "cBottom", val "cLeft", val "cRight", val "thresh", val "blur", bool "y", bool "u", bool "v", string "cloc", int "float_range")
###
# bbmod(clip c, val "cTop", val "cBottom", val "cLeft", val "cRight", val "thresh", val "blur", bool "y", bool "u", bool "v", string "cloc", int "float_range")
###
## Parameters ##
#---------------
# c: Input clip.
# Only progessive video is supported.
#---------------
# cTop, cBottom, cLeft, cRight (default 0): The number of lines to be filtered along each edge.
# If single value for cTop/cBottom/cLeft/cRight is used, it will be right shifted by subsampling factor for chroma planes.
# If two values for cTop/cBottom/cLeft/cRight are given then the second value will be used for the third plane.
#---------------
# thresh (default 128.0): Threshold of the filtering.
# Higher values: more filtering.
# Lower values: less filtering.
# Recommended values: 0..16.0 or 128.0.
# If single number is used: it's applied for all three planes.
# If array is used: the first number is applied to luma plane, the second number - u plane, the third number - v plane.
# If array of two numbers is used: the first number - luma plane, the second number - u and v planes.
#---------------
# blur (default 999): Blur strength.
# Higher values: weak blurring.
# Lower values: strong blurring.
# Recommended values: 1..20 or 999.
# If single number is used: it's applied for all three planes.
# If array is used: the first number is applied to luma plane, the second number - u plane, the third number - v plane.
# If array of two numbers is used: the first number - luma plane, the second number - u and v planes.
#---------------
# y, u, v (default true): Whether to filter the corresponding plane.
# If the clip is RGB, y=u=v=true.
#---------------
# cloc (default "left"): Chroma location of the video.
# Possible values: "left", "center", "top_left".
#---------------
# float_range (default 0): What's the assumed range for 32-bit input.
# 0: [0.0, 1.0]
# 1: [16.0/235.0, 235.0/255.0]
#СОВЕТЫ:
#-------------------------------------------------------------------------------------------------------------------------------
# 1)При значениях по умолчанию thresh=128 blur=999 вы получите ряды пикселей,
# изменённые только подбором цвета для каждого ряда целиком, без локального подбора,
# т.е. цвета соседних пикселей могут сильно отличатся в некоторых местах,
# но при этом не произойдёт изменения характера рисунка.
# А при thresh=128 и blur=1 вы получите практически одинаковые ряды пикселей,
# т.е. цвета между ними будут совпадать полностью, но оригинальный рисунок потеряется.
#
# 2)Остерегайтесь использования большого количества пикселей для изменения в сочетании с большим уровнем "thresh", и маленьким "blur"
# это может привести к появлению нежелательных артефактов "на чистом месте".
# Старайтесь для каждого вызова функции установить как можно меньшее количество пикселей для изменения и
# как можно меньшее значение порога "thresh" (при использовании blur 0..16).
#-------------------------------------------------------------------------------------------------------------------------------
#ПРИМЕРЫ:
#-------------------------------------------------------------------------------------------------------------------------------
# Минимально необходимый вариант из двух вызовов (количество изменяемых пикселей, естественно, указано для примера):
# BalanceBorders(7,6,4,4)
# BalanceBorders(7,6,4,4, thresh=4,blur=10)
#
# Вариант нескольких вызовов поряд:
# BalanceBorders(7,6,4,4) //"общий" подбор цветов
# BalanceBorders(5,5,4,4, thresh=2, blur=10) //совсем чуть-чуть изменяет большую область (с "запасом")
# BalanceBorders(3,3,2,2, thresh=8, blur=4) //несильно изменяет "основную проблемную область"
# BalanceBorders(1,1,0,0, thresh=128, blur=1) //заменяет верхнюю и нижнюю строку пикселей (для удаления "чёрных полос")
#-------------------------------------------------------------------------------------------------------------------------------
### Example with arrays (AviSynth 3.7.1 required) ###
/*
BalanceBorders/bbmod([60,20], cleft=[40,20], y=true, u=true, v= false)
# same as BalanceBorders/bbmod(60, cleft=40, blur=999, y=true, u=false, v=false).BalanceBorders/bbmod(40, cleft=40, y=false, u=true, v=false)
*/
###
/*
BalanceBorders/bbmod([60], cleft=[40])
# same as BalanceBorders/bbmod(60, cleft=40) or BalanceBorders/bbmod(60, cleft=[40]) or BalanceBorders/bbmod([60], cleft=40)
*/
###
/*
BalanceBorders/bbmod([60,30], cleft=[40,20], thresh=[12,12], blur=[100,100], y=false, u=true, v= true)
# same as BalanceBorders/bbmod(60, cleft=40, thresh=12, blur=100, y=false) or BalanceBorders/bbmod([1,30,30], cleft=[1,20,20], thresh=[1,12,12], blur=[1,100,100], y=false, u=true, v= true)
/*
###
/*
BalanceBorders/bbmod([60,20,40], cleft=[40,20,10], thresh=[12,4,5], blur=[100,999,20])
# same as BalanceBorders/bbmod(60, cleft=40, thresh=12, blur=100, u=false, v=false).BalanceBorders/bbmod(40, cleft=40, thresh=4, y=false, v=false).BalanceBorders/bbmod(80, cleft=20, thresh=5, blur=20, y=false, u=false)
*/
###
### Requirements - AviSynth+ >= 3.7.1, avsresize
### Version: 1.0.0
### Changelog ###
#---------------
# 1.0.0
# Added support for planar RGB clips.
# Added parameter float_range.
#---------------
# Fixed processing when the input has one plane.
#---------------
# Changed the behavior of cTop/cBottom/cLeft/cRight values when specified for chroma planes - previously the values were right bit shifted by the subsampling factor (for example, YUV 4:2:0 and cTop=[2,4] means 2px for chroma planes will be filtered - 4 >> 1 (chroma subsampling)); now the values are passed as specified.
# Changed the required AviSynth+ version.
#---------------
# Added note that only progressive video is supported.
# Improved some error messages.
#---------------
# Fixed nuked _ChromaLocation frame property if available in the source.
#---------------
# Fixed processing when the clip has only one plane.
#---------------
# Added parameter "cloc".
#---------------
# Code clean up; fixed cBottom assert for chroma; arrays - if a single value is specified, it will be used for all planes, if two values are given then the second value will be used for the third plane as well.
#---------------
# Fixed error when cTop/cBottom/cLeft/cRight=1.
#---------------
# Merged all calculations in one expression that leads to ~15-20% less memory usage, ~10% speedup with 16-bit clips. (BalanceBorders)
# Merged all calculations in one expression that leads to ~20-35% less memory usage, ~20% speedup with 16-bit clips, ~10% speedup with 10-bit clips; fixed output with clips in float bit depth. (bbmod)
#---------------
# Added array support for parameters.
#---------------
# Removed an unnecessary resize call. (bbmod)
#---------------
# Replaced ResampleMT with z_ resizers.
#---------------
# Added usage info; intermediate function name changed; replaced lutxyz -> 8-bit ~15% speedup, 10-bit ~75% speedup, 16-bit ~50% speedup; removed full_range parameter. (BalanceBorders)
# Added usage info, intermediate function name changed; replaced lutxyz for 8/10-bit -> 8-bit 2x less memory usage, 10-bit ~25% speedup; 16-bit ~10% speedup; removed full_range parameter. (bbmod)
#---------------
# Added Y/YUV422/YUV444 processing.
#---------------
# Additional options bool y (true), bool u (true), bool v (true) for processing different planes; renamed to balanceborders_.avsi.
#---------------
# Fixed default thresh value; allowed 32-bit input; added bool full_range parameter (default=false) - it works only for high bit depth; it determines how the scaling to the input bit depth->8-bit->input bit depth is done ( http://avisynth.nl/index.php/MaskTools2#Expression_syntax_supporting_bit_depth_independent_expressions ).
#---------------
# Changed the thresh type int -> float, thresh is always in the range [0,128] (before it was in the range [0,bit depth half range]).
#---------------
# All options are optional (balanceborders/bbmod(2), balanceborders/bbmod(cleft=1) and so on). Added restriction - clip width / height should be > cLeft*4, cRgith*4 / cTop*4, cBottom*4.
#---------------
# Processing only part of the frame.
Function BalanceBorders(clip c, val "cTop", val "cBottom", val "cLeft", val "cRight", val "thresh", val "blur", bool "y", bool "u", bool "v", string "cloc", int "float_range")
{
bb_process(c, 0, cTop, cBottom, cLeft, cRight, thresh, blur, y, u, v, cloc, float_range)
return propCopy(c)
}
Function bbmod(clip c, val "cTop", val "cBottom", val "cLeft", val "cRight", val "thresh", val "blur", bool "y", bool "u", bool "v", string "cloc", int "float_range")
{
bb_process(c, 1, cTop, cBottom, cLeft, cRight, thresh, blur, y, u, v, cloc, float_range)
return propCopy(c)
}
Function bb_process(clip c, int func_name, val "cTop", val "cBottom", val "cLeft", val "cRight", val "thresh", val "blur", bool "y", bool "u", bool "v", string "cloc", int "float_range")
{
Assert(IsPlanar(c), "The clip must be in planar format.")
Assert(!(propGetType(c, "_FieldBased") > 0 && propGetInt(c, "_FieldBased") > 0), "Only progressive video is supported.")
clip_rgb = IsRGB(c)
y = clip_rgb ? true : Default(y, true)
u = clip_rgb ? true : Default(u, true)
v = clip_rgb ? true : Default(v, true)
clip_444 = Is444(c) || clip_rgb
clip_420 = Is420(c)
chrh = clip_420 ? [0, 1, 1] : [0, 0, 0]
chrw = clip_444 ? [0, 0, 0] : [0, 1, 1]
ctop_a = Defined(cTop) ?
\ IsArray(cTop) ?
\ ArraySize(cTop) == 1 ? [cTop[0], BitRShiftL(cTop[0], chrh[1]), BitRShiftL(cTop[0], chrh[1])] :
\ ArraySize(cTop) == 2 ? [cTop[0], cTop[1], cTop[1]] :
\ ArraySize(cTop) == 3 ? [cTop[0], cTop[1], cTop[2]] :
\ Assert(ArraySize(cTop) == 3, "The cTop values must be no more than three.") :
\ [cTop, BitRShiftL(cTop, chrh[1]), BitRShiftL(cTop, chrh[1])] :
\ [0, 0, 0]
cbottom_a = Defined(cBottom) ?
\ IsArray(cBottom) ?
\ ArraySize(cBottom) == 1 ? [cBottom[0], BitRShiftL(cBottom[0], chrh[1]), BitRShiftL(cBottom[0], chrh[1])] :
\ ArraySize(cBottom) == 2 ? [cBottom[0], cBottom[1], cBottom[1]] :
\ ArraySize(cBottom) == 3 ? [cBottom[0], cBottom[1], cBottom[2]] :
\ Assert(ArraySize(cBottom) == 3, "The cBottom values must be no more than three.") :
\ [cBottom, BitRShiftL(cBottom, chrh[1]), BitRShiftL(cBottom, chrh[1])] :
\ [0, 0, 0]
cleft_a = Defined(cLeft) ?
\ IsArray(cLeft) ?
\ ArraySize(cLeft) == 1 ? [cLeft[0], BitRShiftL(cLeft[0], chrw[1]), BitRShiftL(cLeft[0], chrw[1])] :
\ ArraySize(cLeft) == 2 ? [cLeft[0], cLeft[1], cLeft[1]] :
\ ArraySize(cLeft) == 3 ? [cLeft[0], cLeft[1], cLeft[2]] :
\ Assert(ArraySize(cLeft) == 3, "The cLeft values must be no more than three.") :
\ [cLeft, BitRShiftL(cLeft, chrw[1]), BitRShiftL(cLeft, chrw[1])] :
\ [0, 0, 0]
cright_a = Defined(cRight) ?
\ IsArray(cRight) ?
\ ArraySize(cRight) == 1 ? [cRight[0], BitRShiftL(cRight[0], chrw[1]), BitRShiftL(cRight[0], chrw[1])] :
\ ArraySize(cRight) == 2 ? [cRight[0], cRight[1], cRight[1]] :
\ ArraySize(cRight) == 3 ? [cRight[0], cRight[1], cRight[2]] :
\ Assert(ArraySize(cRight) == 3, "The cRight values must be no more than three.") :
\ [cRight, BitRShiftL(cRight, chrw[1]), BitRShiftL(cRight, chrw[1])] :
\ [0, 0, 0]
thresh_a = Defined(thresh) ?
\ IsArray(thresh) ?
\ ArraySize(thresh) == 1 ? [thresh[0], thresh[0], thresh[0]] :
\ ArraySize(thresh) == 2 ? [thresh[0], thresh[1], thresh[1]] :
\ ArraySize(thresh) == 3 ? [thresh[0], thresh[1], thresh[2]] :
\ Assert(ArraySize(thresh) == 3, "The thresh values must be no more than three.") :
\ [thresh, thresh, thresh] :
\ [128.0, 128.0, 128.0]
blur_a = Defined(blur) ?
\ IsArray(blur) ?
\ ArraySize(blur) == 1 ? [blur[0], blur[0], blur[0]] :
\ ArraySize(blur) == 2 ? [blur[0], blur[1], blur[1]] :
\ ArraySize(blur) == 3 ? [blur[0], blur[1], blur[2]] :
\ Assert(ArraySize(blur) == 3, "The blur values must be no more than three.") :
\ [blur, blur, blur] :
\ [999, 999, 999]
cloc = Default(cloc, "left")
Assert(cloc == "left" || cloc == "top_left" || cloc == "center", "cloc must be one of the values 'left', 'top_left', 'center'.")
float_range = Default(float_range, 0)
Assert(float_range == 0 || float_range == 1, "float_range must be either 0 or 1.")
source_planes = [y, u, v]
num_planes = min(NumComponents(c), 3) - 1
plane_a = !clip_rgb ?
\ (num_planes == 0) ? [ExtractY(c)] :
\ [ExtractY(c), ExtractU(c), ExtractV(c)] :
\ [ExtractR(c), ExtractG(c), ExtractB(c)]
plane_error = clip_rgb ? ["(R plane).", "(G plane).", "(B plane)."] : ["(Y plane).", "(U plane).", "(V plane)."]
ctop_crop = [BitLShift(ctop_a[0], 1), BitLShift(ctop_a[1], 1), BitLShift(ctop_a[2], 1)]
cleft_crop = [BitLShift(cleft_a[0], 1), BitLShift(cleft_a[1], 1), BitLShift(cleft_a[2], 1)]
cbottom_crop = [BitLShift(cbottom_a[0], 1), BitLShift(cbottom_a[1], 1), BitLShift(cbottom_a[2], 1)]
cright_crop = [BitLShift(cright_a[0], 1), BitLShift(cright_a[1], 1), BitLShift(cright_a[2], 1)]
yuv_planes = []
f_name = (func_name == 0) ? "BalanceTopBorder" : "btb"
for (i = 0, num_planes)
{
plane_a[i]
if (source_planes[i])
{
Assert(blur_a[i] > 0 && blur_a[i] <= 999, "Blur parameter must be between 0..999 " + plane_error[i])
Assert(thresh_a[i] > 0.0 && thresh_a[i] <= 128.0, "Thresh parameter must be between 0.0..128.0 " + plane_error[i])
Assert(cleft_a[i] * 4 < Width() && cright_a[i] * 4 < Width(), "cLeft / cRight must be lower than " + String(Width() / 4) + " " + plane_error[i])
Assert(ctop_a[i] * 4 < Height() && cbottom_a[i] * 4 < Height(), "cTop / cBottom must be lower than " + String(Height() / 4) + " " + plane_error[i])
(ctop_a[i] > 0) ? (StackVertical(Crop(0, 0, 0, ctop_crop[i]).Eval(f_name + "(ctop_a[i], thresh_a[i], blur_a[i], i, clip_rgb, clip_444, clip_420, cloc, float_range)"), Crop(0, ctop_crop[i], 0, 0)).TurnRight()) : TurnRight()
(cleft_a[i] > 0) ? (StackVertical(Crop(0, 0, 0, cleft_crop[i]).Eval(f_name + "(cleft_a[i], thresh_a[i], blur_a[i], i, clip_rgb, clip_444, clip_420, cloc, float_range)"), Crop(0, cleft_crop[i], 0, 0)).TurnRight()) : TurnRight()
(cbottom_a[i] > 0) ? (StackVertical(Crop(0, 0, 0, cbottom_crop[i]).Eval(f_name + "(cbottom_a[i] , thresh_a[i], blur_a[i], i, clip_rgb, clip_444, clip_420, cloc, float_range)"), Crop(0, cbottom_crop[i], 0, 0)).TurnRight()) : TurnRight()
(cright_a[i] > 0) ? StackVertical(Crop(0, 0, 0, cright_crop[i]).Eval(f_name + "(cright_a[i], thresh_a[i], blur_a[i], i, clip_rgb, clip_444, clip_420, cloc, float_range)"), Crop(0, cright_crop[i], 0, 0)).TurnRight() : TurnRight()
if (NumComponents(c) == 1)
{
return last
}
else
{
yuv_planes = ArrayAdd(yuv_planes, last)
}
}
else
{
yuv_planes = ArrayAdd(yuv_planes, last)
}
}
return CombinePlanes(yuv_planes[0], yuv_planes[1], yuv_planes[2], planes=clip_rgb ? "RGB" : "YUV", sample_clip=c)
}
Function BalanceTopBorder(clip c, int cTop, float thresh, int blur, int plane, bool clip_rgb, bool clip_444, bool clip_420, string cloc, int float_range)
{
cWidth = c.width
cHeight = c.height
cTop = min(cTop,cHeight-1)
blurWidth = max(4,floor(cWidth/blur))
c2 = c.z_PointResize(cWidth * 2, cHeight * 2)
c2.\
Crop(0, cTop * 2, cWidth * 2, 2)
z_PointResize(cWidth * 2, cTop * 2)
z_BilinearResize(blurWidth * 2, cTop * 2)
Blur(1.5,0.1)
z_BilinearResize(cWidth * 2, cTop * 2)
referenceBlur = last
original = c2.Crop(0, 0, cWidth * 2, cTop * 2)
original
z_BilinearResize(blurWidth * 2, cTop * 2)
Blur(1.5,0.1)
z_BilinearResize(cWidth * 2, cTop * 2)
originalBlur = last
if (clip_rgb)
{
Expr(original, originalBlur, referenceBlur, ""+ String(thresh) +" scaleb B^ z y - A@ B > x B + A "+ String(-thresh) +" scaleb < x B - A x + ? ?", clamp_float=true)
StackVertical(last, c2.Crop(0, cTop * 2, cWidth * 2, (cHeight - cTop) * 2))
z_PointResize(cWidth, cHeight)
}
else if (plane == 0)
{
scale = (ComponentSize(c) == 4 && float_range == 0) ? "0 1 clip" : "16 scaleb 235 scaleb clip"
Expr(original, originalBlur, referenceBlur, ""+ String(thresh) +" scaleb B^ z y - A@ B > x B + A "+ String(-thresh) +" scaleb < x B - A x + ? ? "+ scale +"")
StackVertical(last, c2.Crop(0, cTop * 2, cWidth * 2, (cHeight - cTop) * 2))
z_PointResize(cWidth, cHeight)
}
else
{
if (ComponentSize(c) == 4)
{
scale = (float_range == 0) ? "-0.5 0.5 clip" : "-0.43921568627 0.43921568627 clip"
Expr(original, originalBlur, referenceBlur, ""+ String(thresh) +" 128 - scaleb 0.5 + B^ z y - A@ B > x B + A "+ String(-thresh) +" 128 - scaleb 0.5 + < x B - A x + ? ? "+ scale +"")
}
else { Expr(original, originalBlur, referenceBlur, ""+ String(thresh) +" scaleb B^ z y - A@ B > x B + A "+ String(-thresh) +" scaleb < x B - A x + ? ? 16 scaleb 240 scaleb clip") }
StackVertical(last, c2.Crop(0, cTop * 2, cWidth * 2, (cHeight - cTop) * 2))
chroma_shift_(clip_444, clip_420, cloc)
}
}
Function btb(clip c, int cTop, float thresh, int blur, int plane, bool clip_rgb, bool clip_444, bool clip_420, string cloc, int float_range)
{
cWidth = c.width
cHeight = c.height
cTop = min(cTop,cHeight-1)
blurWidth = max(8,floor(cWidth/blur))
c2 = c.z_PointResize(cWidth * 2, cHeight * 2)
c2.\
Crop(0, cTop * 2, cWidth * 2, 2)
z_PointResize(cWidth * 2, cTop * 2)
referenceBlur = z_bicubicresize(blurWidth * 2, cTop * 2, b=1, c=0).z_bicubicresize(cWidth * 2, cTop * 2, b=1, c=0)
original = c2.Crop(0, 0, cWidth * 2, cTop * 2)
original
z_bicubicresize(blurWidth * 2, cTop * 2, b=1, c=0)
originalBlur = z_bicubicresize(blurWidth * 2, cTop * 2, b=1, c=0).z_bicubicresize(cWidth * 2, cTop * 2, b=1, c=0)
if (clip_rgb)
{
Expr(original, originalBlur, referenceBlur, ""+ String(thresh) +" scaleb B^ z y / 8 min 0.4 max x * A@ x - B > x B + A x - "+ String(-thresh) +" scaleb < x B - A ? ?", clamp_float=true)
StackVertical(last, c2.Crop(0, cTop * 2, cWidth * 2, (cHeight - cTop) * 2))
z_PointResize(cWidth, cHeight)
}
else if (plane == 0)
{
if (ComponentSize(c) == 4 && float_range == 0)
{
Expr(original, originalBlur, referenceBlur, ""+ String(thresh) +" scaleb B^ z y / 8 min 0.4 max x * A@ x - B > x B + A x - "+ String(-thresh) +" scaleb < x B - A ? ?", clamp_float=true)
}
else
{
Expr(original, originalBlur, referenceBlur, ""+ String(thresh) +" scaleb B^ z 16 scaleb - y 16 scaleb - / 8 min 0.4 max x 16 scaleb - * 16 scaleb + A@ x - B > x B + A x - "+ String(-thresh) +" scaleb < x B - A ? ? 16 scaleb 235 scaleb clip")
}
StackVertical(last, c2.Crop(0, cTop * 2, cWidth * 2, (cHeight - cTop) * 2))
z_PointResize(cWidth, cHeight)
}
else
{
if (ComponentSize(c) == 4)
{
scale = (float_range == 0) ? "-0.5 0.5 clip" : "-0.43921568627 0.43921568627 clip"
Expr(original, originalBlur, referenceBlur, ""+ String(thresh) +" 128 - scaleb 0.5 + B^ z y - z 0.5 + y 0.5 + / 8 min 0.4 max x * + A@ x - B > x B + A x - "+ String(-thresh) +" 128 - scaleb 0.5 + < x B - A ? ? "+ scale +"")
}
else { Expr(original, originalBlur, referenceBlur, ""+ String(thresh) +" scaleb B^ z y - z y / 8 min 0.4 max x 128 scaleb - * 128 scaleb + + A@ x - B > x B + A x - "+ String(-thresh) +" scaleb < x B - A ? ? 16 scaleb 240 scaleb clip") }
StackVertical(last, c2.Crop(0, cTop * 2, cWidth * 2, (cHeight - cTop) * 2))
chroma_shift_(clip_444, clip_420, cloc)
}
}
Function chroma_shift_(clip c, bool clip_444, bool clip_420, string cloc)
{
c
if (!clip_444)
{
if ((clip_420 && cloc == "left") || (!clip_420 && cloc != "center")) { z_PointResize(Width() / 2, Height() / 2, -0.25) }
else if (clip_420 && cloc == "top_left") { z_PointResize(Width() / 2, Height() / 2, -0.25, -0.25) }
else { z_PointResize(Width() / 2, Height() / 2) }
}
else { z_PointResize(Width() / 2, Height() / 2) }
}