Skip to content

exprop

Classes:

ExprList

Bases: StrList

Methods:

__call__

__call__(
    *clips: VideoNodeIterableT[VideoNodeT],
    planes: PlanesT = None,
    format: HoldsVideoFormatT | VideoFormatT | None = None,
    opt: bool | None = None,
    boundary: bool = True,
    func: FuncExceptT | None = None,
    split_planes: bool = False,
    **kwargs: Any
) -> VideoNodeT
Source code
114
115
116
117
118
119
120
121
122
123
124
def __call__(
    self, *clips: VideoNodeIterableT[VideoNodeT], planes: PlanesT = None,
    format: HoldsVideoFormatT | VideoFormatT | None = None, opt: bool | None = None,
    boundary: bool = True, func: FuncExceptT | None = None,
    split_planes: bool = False, **kwargs: Any
) -> VideoNodeT:
    from .funcs import norm_expr

    return norm_expr(
        flatten_vnodes(*clips), self, planes, format, opt, boundary, func, split_planes, **kwargs
    )

ExprOp

Bases: ExprOpBase, CustomEnum

Methods:

Attributes:

ABS class-attribute instance-attribute

ABS = ('abs', 1)

ABS_PIX class-attribute instance-attribute

ABS_PIX = ('{x:d} {y:d} {char:s}[]', 3)

ADD class-attribute instance-attribute

ADD = ('+', 2)

AND class-attribute instance-attribute

AND = ('and', 2)

CLAMP class-attribute instance-attribute

CLAMP = ('clamp', 3)

COS class-attribute instance-attribute

COS = ('cos', 1)

DIV class-attribute instance-attribute

DIV = ('/', 2)

DUP class-attribute instance-attribute

DUP = ('dup', 1)

DUPN class-attribute instance-attribute

DUPN = ('dupN', 1)

EQ class-attribute instance-attribute

EQ = ('=', 2)

EXP class-attribute instance-attribute

EXP = ('exp', 1)

FLOOR class-attribute instance-attribute

FLOOR = ('floor', 1)

GT class-attribute instance-attribute

GT = ('>', 2)

GTE class-attribute instance-attribute

GTE = ('>=', 2)

LOG class-attribute instance-attribute

LOG = ('log', 1)

LT class-attribute instance-attribute

LT = ('<', 2)

LTE class-attribute instance-attribute

LTE = ('<=', 2)

MAX class-attribute instance-attribute

MAX = ('max', 2)

MIN class-attribute instance-attribute

MIN = ('min', 2)

MOD class-attribute instance-attribute

MOD = ('%', 2)

MUL class-attribute instance-attribute

MUL = ('*', 2)

NOT class-attribute instance-attribute

NOT = ('not', 1)

OR class-attribute instance-attribute

OR = ('or', 2)

POW class-attribute instance-attribute

POW = ('pow', 2)

REL_PIX class-attribute instance-attribute

REL_PIX = ('{char:s}[{x:d},{y:d}]', 3)

ROUND class-attribute instance-attribute

ROUND = ('round', 1)

SIN class-attribute instance-attribute

SIN = ('sin', 1)

SQRT class-attribute instance-attribute

SQRT = ('sqrt', 1)

SUB class-attribute instance-attribute

SUB = ('-', 2)

SWAP class-attribute instance-attribute

SWAP = ('swap', 2)

SWAPN class-attribute instance-attribute

SWAPN = ('swapN', 2)

TERN class-attribute instance-attribute

TERN = ('?', 3)

TRUNC class-attribute instance-attribute

TRUNC = ('trunc', 1)

XOR class-attribute instance-attribute

XOR = ('xor', 2)

n_op instance-attribute

n_op: int

value instance-attribute

value: str

__call__

__call__(
    *clips: VideoNodeIterableT[VideoNodeT],
    suffix: StrArrOpt = None,
    prefix: StrArrOpt = None,
    expr_suffix: StrArrOpt = None,
    expr_prefix: StrArrOpt = None,
    planes: PlanesT = None,
    **expr_kwargs: Any
) -> VideoNodeT
__call__(*pos_args: Any, **kwargs: Any) -> ExprOpBase
__call__(*pos_args: Any, **kwargs: Any) -> VideoNode | ExprOpBase
Source code
224
225
226
227
228
229
230
231
232
233
234
235
236
237
def __call__(self, *pos_args: Any, **kwargs: Any) -> vs.VideoNode | ExprOpBase:
    args = list(flatten(pos_args))

    if isinstance(args[0], vs.VideoNode):
        return self.combine(*args, **kwargs)

    while True:
        try:
            return ExprOpBase(self.format(*args, **kwargs), 3)
        except KeyError as key:
            try:
                kwargs.update({str(key)[1:-1]: args.pop(0)})
            except IndexError:
                raise key

clamp classmethod

clamp(
    min: float | ExprToken = RangeMin,
    max: float | ExprToken = RangeMax,
    c: str = "",
) -> ExprList
Source code
251
252
253
254
255
256
257
258
259
@classmethod
def clamp(
    cls, min: float | ExprToken = ExprToken.RangeMin, max: float | ExprToken = ExprToken.RangeMax, c: str = ''
) -> ExprList:

    if complexpr_available:
        return ExprList([c, min, max, ExprOp.CLAMP])

    return ExprList([c, min, ExprOp.MAX, max, ExprOp.MIN])

combine

combine(
    *clips: VideoNode | Iterable[VideoNode | Iterable[VideoNode]],
    suffix: StrArrOpt = None,
    prefix: StrArrOpt = None,
    expr_suffix: StrArrOpt = None,
    expr_prefix: StrArrOpt = None,
    planes: PlanesT = None,
    **expr_kwargs: Any
) -> ConstantFormatVideoNode
Source code
158
159
160
161
162
163
164
165
def combine(
    self, *clips: vs.VideoNode | Iterable[vs.VideoNode | Iterable[vs.VideoNode]],
    suffix: StrArrOpt = None, prefix: StrArrOpt = None, expr_suffix: StrArrOpt = None,
    expr_prefix: StrArrOpt = None, planes: PlanesT = None, **expr_kwargs: Any
) -> ConstantFormatVideoNode:
    from .funcs import combine

    return combine(clips, self, suffix, prefix, expr_suffix, expr_prefix, planes, **expr_kwargs)

convolution classmethod

convolution(
    var: str | ExprVarsT,
    matrix: Iterable[SupportsFloat] | Iterable[Iterable[SupportsFloat]],
    bias: float | None = None,
    divisor: float | bool = True,
    saturate: bool = True,
    mode: ConvMode = HV,
    premultiply: float | int | None = None,
    multiply: float | int | None = None,
    clamp: bool = False,
) -> TupleExprList
Source code
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
@classmethod
def convolution(
    cls, var: str | ExprVarsT, matrix: Iterable[SupportsFloat] | Iterable[Iterable[SupportsFloat]],
    bias: float | None = None, divisor: float | bool = True, saturate: bool = True,
    mode: ConvMode = ConvMode.HV, premultiply: float | int | None = None,
    multiply: float | int | None = None, clamp: bool = False
) -> TupleExprList:
    convolution = list[float](flatten(matrix))

    if not (conv_len := len(convolution)) % 2:
        raise CustomValueError('Convolution length must be odd!', cls.convolution, matrix)
    elif conv_len < 3:
        raise CustomValueError('You must pass at least 3 convolution items!', cls.convolution, matrix)
    elif mode == ConvMode.SQUARE and conv_len != isqrt(conv_len) ** 2:
        raise CustomValueError(
            'With square mode, convolution must represent a '
            'horizontal*vertical square (radius*radius n items)!', cls.convolution
        )

    radius = conv_len // 2 if mode != ConvMode.SQUARE else isqrt(conv_len) // 2

    rel_pixels = cls.matrix(var, radius, mode)

    output = TupleExprList([
        ExprList([
            rel_pix if weight == 1 else [rel_pix, weight, ExprOp.MUL]
            for rel_pix, weight in zip(rel_px, convolution)
            if weight != 0
        ]) for rel_px in rel_pixels
    ])

    for out in output:
        out.extend(ExprOp.ADD * out.mlength)

        if premultiply is not None:
            out.append(premultiply, ExprOp.MUL)

        if divisor is not False:
            if divisor is True:
                divisor = sum(map(float, convolution))

            if divisor not in {0, 1}:
                out.append(divisor, ExprOp.DIV)

        if bias is not None:
            out.append(bias, ExprOp.ADD)

        if not saturate:
            out.append(ExprOp.ABS)

        if multiply is not None:
            out.append(multiply, ExprOp.MUL)

        if clamp:
            out.append(ExprOp.clamp(ExprToken.RangeMin, ExprToken.RangeMax))

    return output

mae classmethod

mae(planesa: ExprVarRangeT, planesb: ExprVarRangeT | None = None) -> ExprList
Source code
388
389
390
391
392
393
394
395
396
397
398
@classmethod
def mae(cls, planesa: ExprVarRangeT, planesb: ExprVarRangeT | None = None) -> ExprList:
    planesa, planesb = cls._parse_planes(planesa, planesb, cls.rmse)
    expr = ExprList()

    for a, b in zip(planesa, planesb):
        expr.append([a, b, cls.SUB, cls.ABS])

    expr.append(cls.MAX * expr.mlength)

    return expr

matrix classmethod

matrix(
    var: str | ExprVarsT,
    radius: int,
    mode: ConvMode,
    exclude: Iterable[tuple[int, int]] | None = None,
) -> TupleExprList
Source code
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
@classmethod
def matrix(
    cls, var: str | ExprVarsT, radius: int, mode: ConvMode, exclude: Iterable[tuple[int, int]] | None = None
) -> TupleExprList:
    exclude = list(exclude) if exclude else list()

    match mode:
        case ConvMode.SQUARE:
            coordinates = [
                (x, y)
                for y in range(-radius, radius + 1)
                for x in range(-radius, radius + 1)
            ]
        case ConvMode.VERTICAL:
            coordinates = [(0, xy) for xy in range(-radius, radius + 1)]
        case ConvMode.HORIZONTAL:
            coordinates = [(xy, 0) for xy in range(-radius, radius + 1)]
        case ConvMode.HV:
            return TupleExprList([
                cls.matrix(var, radius, ConvMode.VERTICAL, exclude)[0],
                cls.matrix(var, radius, ConvMode.HORIZONTAL, exclude)[0],
           ])
        case ConvMode.TEMPORAL:
            if len(var) != radius * 2 + 1:
                raise CustomValueError(
                    "`var` must have a number of elements proportional to the radius",
                    cls.matrix, var
                )

            return TupleExprList([ExprList(v for v in var)])
        case _:
            raise NotImplementedError

    return TupleExprList([ExprList([
        var if x == y == 0 else
        ExprOp.REL_PIX(var, x, y)
        for (x, y) in coordinates
        if (x, y) not in exclude
    ])])

rmse classmethod

rmse(planesa: ExprVarRangeT, planesb: ExprVarRangeT | None = None) -> ExprList
Source code
375
376
377
378
379
380
381
382
383
384
385
386
@classmethod
def rmse(cls, planesa: ExprVarRangeT, planesb: ExprVarRangeT | None = None) -> ExprList:
    planesa, planesb = cls._parse_planes(planesa, planesb, cls.rmse)

    expr = ExprList()

    for a, b in zip(planesa, planesb):
        expr.append([a, b, cls.SUB, cls.DUP, cls.MUL, cls.SQRT])

    expr.append(cls.MAX * expr.mlength)

    return expr

ExprOpBase

Bases: str

Methods:

Attributes:

n_op instance-attribute

n_op: int

value instance-attribute

value: str

combine

combine(
    *clips: VideoNode | Iterable[VideoNode | Iterable[VideoNode]],
    suffix: StrArrOpt = None,
    prefix: StrArrOpt = None,
    expr_suffix: StrArrOpt = None,
    expr_prefix: StrArrOpt = None,
    planes: PlanesT = None,
    **expr_kwargs: Any
) -> ConstantFormatVideoNode
Source code
158
159
160
161
162
163
164
165
def combine(
    self, *clips: vs.VideoNode | Iterable[vs.VideoNode | Iterable[vs.VideoNode]],
    suffix: StrArrOpt = None, prefix: StrArrOpt = None, expr_suffix: StrArrOpt = None,
    expr_prefix: StrArrOpt = None, planes: PlanesT = None, **expr_kwargs: Any
) -> ConstantFormatVideoNode:
    from .funcs import combine

    return combine(clips, self, suffix, prefix, expr_suffix, expr_prefix, planes, **expr_kwargs)

ExprToken

Bases: ExprTokenBase, CustomEnum

Methods:

Attributes:

ChromaMax class-attribute instance-attribute

ChromaMax = 'cmax'

ChromaMin class-attribute instance-attribute

ChromaMin = 'cmin'

ChromaRangeInMax class-attribute instance-attribute

ChromaRangeInMax = 'crange_in_max'

ChromaRangeInMin class-attribute instance-attribute

ChromaRangeInMin = 'crange_in_min'

ChromaRangeMax class-attribute instance-attribute

ChromaRangeMax = 'crange_max'

ChromaRangeMin class-attribute instance-attribute

ChromaRangeMin = 'crange_min'

LumaMax class-attribute instance-attribute

LumaMax = 'ymax'

LumaMin class-attribute instance-attribute

LumaMin = 'ymin'

LumaRangeInMax class-attribute instance-attribute

LumaRangeInMax = 'yrange_in_max'

LumaRangeInMin class-attribute instance-attribute

LumaRangeInMin = 'yrange_in_min'

LumaRangeMax class-attribute instance-attribute

LumaRangeMax = 'yrange_max'

LumaRangeMin class-attribute instance-attribute

LumaRangeMin = 'yrange_min'

Neutral class-attribute instance-attribute

Neutral = 'neutral'

RangeHalf class-attribute instance-attribute

RangeHalf = 'range_half'

RangeInMax class-attribute instance-attribute

RangeInMax = 'range_in_max'

RangeInMin class-attribute instance-attribute

RangeInMin = 'range_in_min'

RangeMax class-attribute instance-attribute

RangeMax = 'range_max'

RangeMin class-attribute instance-attribute

RangeMin = 'range_min'

RangeSize class-attribute instance-attribute

RangeSize = 'range_size'

is_chroma property

is_chroma: bool

value instance-attribute

value: str

get_value

get_value(
    clip: VideoNode,
    chroma: bool | None = None,
    range_in: ColorRange | None = None,
) -> float
Source code
 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
def get_value(self, clip: vs.VideoNode, chroma: bool | None = None, range_in: ColorRange | None = None) -> float:
    if self is ExprToken.LumaMin:
        return get_lowest_value(clip, False, ColorRange.LIMITED)

    if self is ExprToken.ChromaMin:
        return get_lowest_value(clip, True, ColorRange.LIMITED)

    if self is ExprToken.LumaMax:
        return get_peak_value(clip, False, ColorRange.LIMITED)

    if self is ExprToken.ChromaMax:
        return get_peak_value(clip, True, ColorRange.LIMITED)

    if self is ExprToken.Neutral:
        return get_neutral_value(clip)

    if self is ExprToken.RangeHalf:
        return ((val := get_peak_value(clip, range_in=ColorRange.FULL)) + (1 - (val <= 1.0))) / 2

    if self is ExprToken.RangeSize:
        return (val := get_peak_value(clip, range_in=ColorRange.FULL)) + (1 - (val <= 1.0))

    if self is ExprToken.RangeMin:
        return get_lowest_value(clip, chroma if chroma is not None else False, ColorRange.FULL)

    if self is ExprToken.LumaRangeMin:
        return get_lowest_value(clip, False)

    if self is ExprToken.ChromaRangeMin:
        return get_lowest_value(clip, True)

    if self is ExprToken.RangeMax:
        return get_peak_value(clip, chroma if chroma is not None else False, ColorRange.FULL)

    if self is ExprToken.LumaRangeMax:
        return get_peak_value(clip, False)

    if self is ExprToken.ChromaRangeMax:
        return get_peak_value(clip, True)

    if self is ExprToken.RangeInMin:
        return get_lowest_value(clip, chroma if chroma is not None else False, range_in)

    if self is ExprToken.LumaRangeInMin:
        return get_lowest_value(clip, False, range_in)

    if self is ExprToken.ChromaRangeInMin:
        return get_lowest_value(clip, True, range_in)

    if self is ExprToken.RangeInMax:
        return get_peak_value(clip, chroma if chroma is not None else False, range_in)

    if self is ExprToken.LumaRangeInMax:
        return get_peak_value(clip, False, range_in)

    if self is ExprToken.ChromaRangeInMax:
        return get_peak_value(clip, True, range_in)

    raise CustomValueError("You are using an unsupported ExprToken!", self.get_value, self)

ExprTokenBase

Bases: str

Attributes:

value instance-attribute

value: str

TupleExprList

Bases: tuple[ExprList, ...]

Methods:

__call__

__call__(
    *clips: VideoNodeIterableT[VideoNodeT],
    planes: PlanesT = None,
    format: HoldsVideoFormatT | VideoFormatT | None = None,
    opt: bool | None = None,
    boundary: bool = True,
    func: FuncExceptT | None = None,
    split_planes: bool = False,
    **kwargs: Any
) -> VideoNodeT
Source code
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
def __call__(
    self, *clips: VideoNodeIterableT[VideoNodeT], planes: PlanesT = None,
    format: HoldsVideoFormatT | VideoFormatT | None = None, opt: bool | None = None,
    boundary: bool = True, func: FuncExceptT | None = None,
    split_planes: bool = False, **kwargs: Any
) -> VideoNodeT:
    clip: Sequence[VideoNodeT] | VideoNodeT = flatten_vnodes(*clips)

    for exprlist in self:
        clip = exprlist(
            clip, planes=planes, format=format, opt=opt, boundary=boundary,
            func=func, split_planes=split_planes, **kwargs
        )

    return clip[0] if isinstance(clip, Sequence) else clip