Skip to content

levels

Functions:

fix_levels

fix_levels(
    clip: VideoNode,
    gamma: float = 1.0,
    min_in: int | float | Sequence[int | float] | None = None,
    min_out: int | float | Sequence[int | float] | None = None,
    max_in: int | float | Sequence[int | float] | None = None,
    max_out: int | float | Sequence[int | float] | None = None,
    input_depth: int | None = 8,
    planes: PlanesT = 0,
) -> VideoNode
Source code in vsadjust/levels.py
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
def fix_levels(
    clip: vs.VideoNode,
    gamma: float = 1.0,
    min_in: int | float | Sequence[int | float] | None = None,
    min_out: int | float | Sequence[int | float] | None = None,
    max_in: int | float | Sequence[int | float] | None = None,
    max_out: int | float | Sequence[int | float] | None = None,
    input_depth: int | None = 8,
    planes: PlanesT = 0,
) -> vs.VideoNode:
    func = FunctionUtil(clip, fix_levels, planes, vs.YUV, 32)

    if not any(x is not None for x in (min_in, min_out, max_in, max_out)):
        return fix_range_levels(clip, gamma, ColorRange.LIMITED, planes)

    color_range = ColorRange.from_video(clip, False, fix_range_levels)

    def_min = get_lowest_values(clip, color_range)
    def_max = get_peak_values(clip, color_range)

    min_in, min_out, max_in, max_out = [
        (None if x is None else normalize_seq(x)) for x in (min_in, min_out, max_in, max_out)
    ]

    min_in = min_in or min_out or def_min
    max_in = max_in or max_out or def_max

    min_out = min_out or min_in
    max_out = max_out or max_in

    min_in, min_out, max_in, max_out = [
        [
            (y if y <= 1.0 else scale_value(y, input_depth or clip, 32, scale_offsets=True, chroma=i != 0))
            for i, y in enumerate(x)
        ]
        for x in (min_in, min_out, max_in, max_out)
    ]

    fix_lvls = func.work_clip

    if func.luma:
        fix_lvls = fix_lvls.std.Levels(min_in[0], max_in[0], gamma, min_out[0], max_out[0], 0)

    if func.chroma:
        cmin_in, cmin_out, cmax_in, cmax_out = [x[1:] for x in (min_in, min_out, max_in, max_out)]

        if all(len(set(x)) == 1 for x in (cmin_in, cmin_out, cmax_in, cmax_out)):
            print(fix_lvls, cmin_in[0], cmax_in[0], gamma, cmin_out[0], cmax_out[0], func.chroma_pplanes)
            fix_lvls = fix_lvls.std.Levels(cmin_in[0], cmax_in[0], gamma, cmin_out[0], cmax_out[0], func.chroma_pplanes)
        else:
            for i in func.chroma_pplanes:
                fix_lvls = fix_lvls.std.Levels(
                    cmin_in[i - 1], cmax_in[i - 1], gamma, cmin_out[i - 1], cmax_out[i - 1], i
                )

    return func.return_clip(fix_lvls)

fix_range_levels

fix_range_levels(
    clip: VideoNode,
    gamma: float = 1.0,
    range_in: ColorRangeT = LIMITED,
    planes: PlanesT = 0,
) -> VideoNode
Source code in vsadjust/levels.py
76
77
78
79
80
81
82
83
84
85
86
87
def fix_range_levels(
    clip: vs.VideoNode, gamma: float = 1.0, range_in: ColorRangeT = ColorRange.LIMITED, planes: PlanesT = 0
) -> vs.VideoNode:
    color_range = ColorRange.from_param(range_in, fix_range_levels)

    if not color_range:
        color_range = ColorRange.from_video(clip, False, fix_range_levels)

    min_in = min_out = get_lowest_values(clip, color_range)
    max_in = max_out = get_peak_values(clip, color_range)

    return fix_levels(clip, gamma, min_in, min_out, max_in, max_out, None, planes)