soifunc 0.12.0__py3-none-any.whl → 0.14.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- soifunc/deband.py +31 -13
- soifunc/denoise.py +65 -13
- soifunc/interpolate.py +116 -5
- soifunc/resize.py +12 -7
- {soifunc-0.12.0.dist-info → soifunc-0.14.1.dist-info}/METADATA +5 -3
- soifunc-0.14.1.dist-info/RECORD +10 -0
- {soifunc-0.12.0.dist-info → soifunc-0.14.1.dist-info}/WHEEL +1 -1
- soifunc-0.12.0.dist-info/RECORD +0 -10
- {soifunc-0.12.0.dist-info → soifunc-0.14.1.dist-info/licenses}/LICENSE +0 -0
soifunc/deband.py
CHANGED
|
@@ -2,7 +2,13 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from vsdeband import f3k_deband
|
|
4
4
|
from vsmasktools import dre_edgemask
|
|
5
|
-
from vstools import
|
|
5
|
+
from vstools import (
|
|
6
|
+
UnsupportedVideoFormatError,
|
|
7
|
+
VariableFormatError,
|
|
8
|
+
check_variable,
|
|
9
|
+
core,
|
|
10
|
+
vs,
|
|
11
|
+
)
|
|
6
12
|
|
|
7
13
|
__all__ = [
|
|
8
14
|
"retinex_deband",
|
|
@@ -14,33 +20,45 @@ def retinex_deband(
|
|
|
14
20
|
threshold: int,
|
|
15
21
|
showmask: bool = False,
|
|
16
22
|
) -> vs.VideoNode:
|
|
23
|
+
"""Debanding using contrast-adaptive edge masking.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
clip: Input video (8-16bit YUV required).
|
|
27
|
+
threshold: Debanding strength (0-255). Default ~16-48 recommended.
|
|
28
|
+
showmask: If True, return edge mask instead of debanded clip.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Debanded video clip or edge mask.
|
|
32
|
+
|
|
33
|
+
Note:
|
|
34
|
+
Does not add grain. Use vsdeband.AddNoise for post-denoising.
|
|
17
35
|
"""
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
This function does not add grain on its own. Use another function like
|
|
25
|
-
`vsdeband.AddNoise` to do that.
|
|
26
|
-
"""
|
|
27
|
-
assert check_variable(clip, retinex_deband)
|
|
36
|
+
if threshold < 0 or threshold > 255:
|
|
37
|
+
raise ValueError(f"threshold must be between 0-255, got {threshold}")
|
|
38
|
+
|
|
39
|
+
if not check_variable(clip, retinex_deband):
|
|
40
|
+
raise VariableFormatError("clip must have constant format and fps")
|
|
28
41
|
|
|
29
42
|
if (
|
|
30
43
|
clip.format.color_family != vs.YUV
|
|
31
44
|
or clip.format.sample_type != vs.INTEGER
|
|
32
45
|
or clip.format.bits_per_sample > 16
|
|
33
46
|
):
|
|
34
|
-
raise
|
|
47
|
+
raise UnsupportedVideoFormatError(
|
|
35
48
|
retinex_deband,
|
|
36
49
|
clip.format,
|
|
37
50
|
"The format {format.name} is not supported! It must be an 8-16bit integer YUV bit format!",
|
|
38
51
|
)
|
|
39
52
|
|
|
40
|
-
mask = dre_edgemask.CLAHE(clip)
|
|
53
|
+
mask: vs.VideoNode = dre_edgemask.CLAHE(clip)
|
|
41
54
|
|
|
42
55
|
if showmask:
|
|
43
56
|
return mask
|
|
44
57
|
|
|
58
|
+
# The threshold value that `retinex_deband` takes is relative
|
|
59
|
+
# to 8-bit videos, but `f3kdb` changed their threshold
|
|
60
|
+
# values to be relative to 10-bit videos some time after this
|
|
61
|
+
# function was created. To keep this function compatible,
|
|
62
|
+
# we shift our threshold from 8-bit to 10-bit.
|
|
45
63
|
deband = f3k_deband(clip, thr=(threshold << 2))
|
|
46
64
|
return core.std.MaskedMerge(deband, clip, mask)
|
soifunc/denoise.py
CHANGED
|
@@ -3,17 +3,18 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import Callable, Optional
|
|
4
4
|
|
|
5
5
|
import vsdenoise
|
|
6
|
-
from vsdenoise import DFTTest, bm3d, mc_degrain
|
|
7
|
-
from vstools import core, vs
|
|
6
|
+
from vsdenoise import DFTTest, bm3d, mc_degrain, nl_means
|
|
7
|
+
from vstools import check_variable, core, join, split, vs
|
|
8
8
|
|
|
9
|
-
__all__ = ["MCDenoise", "magic_denoise", "hqbm3d", "mc_dfttest"]
|
|
9
|
+
__all__ = ["MCDenoise", "magic_denoise", "hqbm3d", "mc_dfttest", "Stab"]
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def hqbm3d(
|
|
13
13
|
clip: vs.VideoNode,
|
|
14
|
-
luma_str: float = 0.
|
|
14
|
+
luma_str: float = 0.5,
|
|
15
15
|
chroma_str: float = 0.4,
|
|
16
16
|
profile: bm3d.Profile = bm3d.Profile.FAST,
|
|
17
|
+
tr: int = 1,
|
|
17
18
|
) -> vs.VideoNode:
|
|
18
19
|
"""
|
|
19
20
|
High-quality presets for motion compensated denoising.
|
|
@@ -39,12 +40,24 @@ def hqbm3d(
|
|
|
39
40
|
),
|
|
40
41
|
planes=None,
|
|
41
42
|
)
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
[y, u, v] = split(clip)
|
|
44
|
+
[y_mv, u_mv, v_mv] = split(mv)
|
|
45
|
+
out_y = bm3d(y, sigma=luma_str, tr=tr, ref=y_mv, profile=profile)
|
|
46
|
+
if not hasattr(core, "nlm_cuda") and hasattr(core, "knlm"):
|
|
47
|
+
# the KNLMeansCL would force extra depth conversions
|
|
48
|
+
# and re-processing of the luma plane, so avoid it.
|
|
49
|
+
nlm_backend = nl_means.Backend.ISPC
|
|
50
|
+
else:
|
|
51
|
+
nlm_backend = nl_means.Backend.AUTO
|
|
52
|
+
out_u = nl_means(u, h=chroma_str, tr=tr, ref=u_mv, backend=nlm_backend)
|
|
53
|
+
out_v = nl_means(v, h=chroma_str, tr=tr, ref=v_mv, backend=nlm_backend)
|
|
54
|
+
return join(out_y, out_u, out_v, prop_src=clip)
|
|
44
55
|
|
|
45
56
|
|
|
46
57
|
def mc_dfttest(
|
|
47
|
-
clip: vs.VideoNode,
|
|
58
|
+
clip: vs.VideoNode,
|
|
59
|
+
thSAD: int = 75,
|
|
60
|
+
tr: int = 2,
|
|
48
61
|
) -> vs.VideoNode:
|
|
49
62
|
"""
|
|
50
63
|
A motion-compensated denoiser using DFTTEST.
|
|
@@ -52,19 +65,14 @@ def mc_dfttest(
|
|
|
52
65
|
Turn it up to 150 or more if you really need to nuke something.
|
|
53
66
|
It does a decent job at preserving details, but not nearly as good
|
|
54
67
|
as bm3d, so this is not recommended on clean, high-quality sources.
|
|
55
|
-
|
|
56
|
-
The `noisy` parameter did help preserve more detail on high-quality but grainy sources.
|
|
57
|
-
Currently it is deprecated, as the presets in `vsdenoise` changed,
|
|
58
|
-
but it may be un-deprecated in the future.
|
|
59
68
|
"""
|
|
60
|
-
# TODO: Do we need to tweak anything for the `noisy` param?
|
|
61
69
|
blksize = select_block_size(clip)
|
|
62
70
|
return mc_degrain(
|
|
63
71
|
clip,
|
|
64
72
|
prefilter=vsdenoise.Prefilter.DFTTEST,
|
|
65
73
|
preset=vsdenoise.MVToolsPreset.HQ_SAD,
|
|
66
74
|
thsad=thSAD,
|
|
67
|
-
tr=
|
|
75
|
+
tr=tr,
|
|
68
76
|
refine=3 if blksize > 16 else 2,
|
|
69
77
|
blksize=blksize,
|
|
70
78
|
)
|
|
@@ -210,3 +218,47 @@ def magic_denoise(clip: vs.VideoNode) -> vs.VideoNode:
|
|
|
210
218
|
tbsize=3,
|
|
211
219
|
ssystem=1,
|
|
212
220
|
)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
##############################################################################
|
|
224
|
+
# Original script by g-force converted into a stand alone script by McCauley #
|
|
225
|
+
# then copied from havsfunc when they deleted it #
|
|
226
|
+
# latest version from December 10, 2008 #
|
|
227
|
+
##############################################################################
|
|
228
|
+
def Stab(clp, dxmax=4, dymax=4, mirror=0):
|
|
229
|
+
if not isinstance(clp, vs.VideoNode):
|
|
230
|
+
raise vs.Error("Stab: this is not a clip")
|
|
231
|
+
|
|
232
|
+
clp = scdetect(clp, 25 / 255)
|
|
233
|
+
temp = clp.misc.AverageFrames([1] * 15, scenechange=True)
|
|
234
|
+
inter = core.std.Interleave(
|
|
235
|
+
[
|
|
236
|
+
core.rgvs.Repair(
|
|
237
|
+
temp, clp.misc.AverageFrames([1] * 3, scenechange=True), mode=[1]
|
|
238
|
+
),
|
|
239
|
+
clp,
|
|
240
|
+
]
|
|
241
|
+
)
|
|
242
|
+
mdata = inter.mv.DepanEstimate(trust=0, dxmax=dxmax, dymax=dymax)
|
|
243
|
+
last = inter.mv.DepanCompensate(data=mdata, offset=-1, mirror=mirror)
|
|
244
|
+
return last[::2]
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def scdetect(clip: vs.VideoNode, threshold: float = 0.1) -> vs.VideoNode:
|
|
248
|
+
def _copy_property(n: int, f: list[vs.VideoFrame]) -> vs.VideoFrame:
|
|
249
|
+
fout = f[0].copy()
|
|
250
|
+
fout.props["_SceneChangePrev"] = f[1].props["_SceneChangePrev"]
|
|
251
|
+
fout.props["_SceneChangeNext"] = f[1].props["_SceneChangeNext"]
|
|
252
|
+
return fout
|
|
253
|
+
|
|
254
|
+
assert check_variable(clip, scdetect)
|
|
255
|
+
|
|
256
|
+
sc = clip
|
|
257
|
+
if clip.format.color_family == vs.RGB:
|
|
258
|
+
sc = clip.resize.Point(format=vs.GRAY8, matrix_s="709")
|
|
259
|
+
|
|
260
|
+
sc = sc.misc.SCDetect(threshold)
|
|
261
|
+
if clip.format.color_family == vs.RGB:
|
|
262
|
+
sc = clip.std.ModifyFrame([clip, sc], _copy_property)
|
|
263
|
+
|
|
264
|
+
return sc
|
soifunc/interpolate.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import platform
|
|
4
3
|
from typing import TYPE_CHECKING
|
|
5
4
|
|
|
6
5
|
import vstools
|
|
@@ -10,7 +9,7 @@ from vstools import vs
|
|
|
10
9
|
if TYPE_CHECKING:
|
|
11
10
|
from vsmlrt import backendT
|
|
12
11
|
|
|
13
|
-
__all__ = ["rate_doubler", "decimation_fixer"]
|
|
12
|
+
__all__ = ["rate_doubler", "decimation_fixer", "replace_dupes"]
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
def rate_doubler(
|
|
@@ -26,6 +25,7 @@ def rate_doubler(
|
|
|
26
25
|
|
|
27
26
|
width = clip.width
|
|
28
27
|
height = clip.height
|
|
28
|
+
format = clip.format
|
|
29
29
|
matrix = vstools.Matrix.from_video(clip)
|
|
30
30
|
transfer = vstools.Transfer.from_video(clip)
|
|
31
31
|
primaries = vstools.Primaries.from_video(clip)
|
|
@@ -45,7 +45,7 @@ def rate_doubler(
|
|
|
45
45
|
)
|
|
46
46
|
# TODO: Handle other chroma samplings
|
|
47
47
|
clip = clip.resize.Bicubic(
|
|
48
|
-
format=
|
|
48
|
+
format=format,
|
|
49
49
|
width=width,
|
|
50
50
|
height=height,
|
|
51
51
|
matrix=matrix,
|
|
@@ -55,6 +55,117 @@ def rate_doubler(
|
|
|
55
55
|
return clip
|
|
56
56
|
|
|
57
57
|
|
|
58
|
+
def replace_dupes(
|
|
59
|
+
clip: vs.VideoNode,
|
|
60
|
+
max_length: int = 5,
|
|
61
|
+
backend: backendT | None = None,
|
|
62
|
+
threshold: float = 0.001,
|
|
63
|
+
) -> vs.VideoNode:
|
|
64
|
+
"""
|
|
65
|
+
Detects strings of duplicate frames in a video and replaces them
|
|
66
|
+
with interpolated frames from RIFE.
|
|
67
|
+
|
|
68
|
+
Max number of continuous duplicates to detect is determined by the `max_length` parameter.
|
|
69
|
+
`threshold` is the maximum average pixel difference (0-1 scale) to consider frames as duplicates.
|
|
70
|
+
Lower values are stricter (frames must be more similar to be considered duplicates).
|
|
71
|
+
"""
|
|
72
|
+
import vsmlrt
|
|
73
|
+
|
|
74
|
+
# Store original properties
|
|
75
|
+
width = clip.width
|
|
76
|
+
height = clip.height
|
|
77
|
+
format = clip.format
|
|
78
|
+
matrix = vstools.Matrix.from_video(clip)
|
|
79
|
+
transfer = vstools.Transfer.from_video(clip)
|
|
80
|
+
primaries = vstools.Primaries.from_video(clip)
|
|
81
|
+
|
|
82
|
+
# Compute frame differences using PlaneStats
|
|
83
|
+
# This compares each frame with the previous one
|
|
84
|
+
diff_clip = clip.std.PlaneStats(clip[0] + clip)
|
|
85
|
+
|
|
86
|
+
# Prepare clip for RIFE (convert to RGBS and resize to multiple of 64)
|
|
87
|
+
rife_clip = clip.resize.Bicubic(
|
|
88
|
+
format=vs.RGBS,
|
|
89
|
+
width=next_multiple_of(64, width),
|
|
90
|
+
height=next_multiple_of(64, height),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Create interpolated frames using RIFE (double the framerate)
|
|
94
|
+
interpolated = vsmlrt.RIFE(
|
|
95
|
+
rife_clip,
|
|
96
|
+
multi=2,
|
|
97
|
+
model=vsmlrt.RIFEModel.v4_25_heavy,
|
|
98
|
+
backend=(backend if backend else autoselect_backend()),
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Convert interpolated frames back to original format
|
|
102
|
+
interpolated = interpolated.resize.Bicubic(
|
|
103
|
+
format=format,
|
|
104
|
+
width=width,
|
|
105
|
+
height=height,
|
|
106
|
+
matrix=matrix,
|
|
107
|
+
transfer=transfer,
|
|
108
|
+
primaries=primaries,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# Track sequence state for lazy evaluation
|
|
112
|
+
state = {"prev_len": 0}
|
|
113
|
+
|
|
114
|
+
def select_frame(n):
|
|
115
|
+
"""
|
|
116
|
+
Select interpolated frame if current frame is a duplicate,
|
|
117
|
+
otherwise use original. Copies PlaneStatsDiff property to output
|
|
118
|
+
to help users calibrate the threshold parameter.
|
|
119
|
+
"""
|
|
120
|
+
if n == 0 or n == clip.num_frames - 1:
|
|
121
|
+
state["prev_len"] = 0
|
|
122
|
+
# Frame 0 and final frame are never duplicates
|
|
123
|
+
# (no previous frame for 0, no next frame for final)
|
|
124
|
+
output = clip[n : n + 1]
|
|
125
|
+
diff_val = (
|
|
126
|
+
0.0
|
|
127
|
+
if n == 0
|
|
128
|
+
else diff_clip.get_frame(n).props.get("PlaneStatsDiff", 1.0)
|
|
129
|
+
)
|
|
130
|
+
return output.std.SetFrameProp(prop="PlaneStatsDiff", floatval=diff_val)
|
|
131
|
+
|
|
132
|
+
# Get difference from PlaneStats (lazy evaluation)
|
|
133
|
+
f = diff_clip.get_frame(n)
|
|
134
|
+
diff = f.props.get("PlaneStatsDiff", 1.0)
|
|
135
|
+
|
|
136
|
+
# Determine if this is a duplicate
|
|
137
|
+
if diff < threshold:
|
|
138
|
+
new_len = state["prev_len"] + 1
|
|
139
|
+
if new_len <= max_length:
|
|
140
|
+
state["prev_len"] = new_len
|
|
141
|
+
is_dupe = True
|
|
142
|
+
else:
|
|
143
|
+
state["prev_len"] = 0
|
|
144
|
+
is_dupe = False
|
|
145
|
+
else:
|
|
146
|
+
state["prev_len"] = 0
|
|
147
|
+
is_dupe = False
|
|
148
|
+
|
|
149
|
+
if is_dupe:
|
|
150
|
+
# Use interpolated frame between previous and current
|
|
151
|
+
# If the original sequence is 0 1 2 where 0 and 1 are dupes,
|
|
152
|
+
# the interpolated sequence will have 0 1 2 3 4 5
|
|
153
|
+
# where 3 is the interpolated frame we want to fetch
|
|
154
|
+
# to replace frame 1..
|
|
155
|
+
|
|
156
|
+
output = interpolated[n * 2 + 1 : n * 2 + 2]
|
|
157
|
+
else:
|
|
158
|
+
output = clip[n : n + 1]
|
|
159
|
+
|
|
160
|
+
# Attach PlaneStatsDiff property to output frame for threshold calibration
|
|
161
|
+
return output.std.SetFrameProp(prop="PlaneStatsDiff", floatval=diff)
|
|
162
|
+
|
|
163
|
+
# Apply frame selection with lazy evaluation
|
|
164
|
+
result = clip.std.FrameEval(select_frame)
|
|
165
|
+
|
|
166
|
+
return result
|
|
167
|
+
|
|
168
|
+
|
|
58
169
|
def decimation_fixer(
|
|
59
170
|
clip: vs.VideoNode, cycle: int, offset: int = 0, backend: backendT | None = None
|
|
60
171
|
) -> vs.VideoNode:
|
|
@@ -78,6 +189,7 @@ def decimation_fixer(
|
|
|
78
189
|
width = clip.width
|
|
79
190
|
height = clip.height
|
|
80
191
|
fps = clip.fps
|
|
192
|
+
format = clip.format
|
|
81
193
|
input_cycle = cycle - 1
|
|
82
194
|
matrix = vstools.Matrix.from_video(clip)
|
|
83
195
|
transfer = vstools.Transfer.from_video(clip)
|
|
@@ -115,9 +227,8 @@ def decimation_fixer(
|
|
|
115
227
|
fpsnum=fps.numerator * cycle // input_cycle, fpsden=fps.denominator
|
|
116
228
|
)
|
|
117
229
|
|
|
118
|
-
# TODO: Handle other chroma samplings
|
|
119
230
|
out_clip = out_clip.resize.Bicubic(
|
|
120
|
-
format=
|
|
231
|
+
format=format,
|
|
121
232
|
width=width,
|
|
122
233
|
height=height,
|
|
123
234
|
matrix=matrix,
|
soifunc/resize.py
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from vsaa.deinterlacers import NNEDI3
|
|
4
|
-
from vskernels import
|
|
5
|
-
Hermite,
|
|
6
|
-
Spline36,
|
|
7
|
-
)
|
|
4
|
+
from vskernels import Hermite, LeftShift, Spline36, TopShift
|
|
8
5
|
from vsscale import ArtCNN
|
|
9
|
-
from vstools import
|
|
6
|
+
from vstools import (
|
|
7
|
+
VariableFormatError,
|
|
8
|
+
check_variable_format,
|
|
9
|
+
is_gpu_available,
|
|
10
|
+
join,
|
|
11
|
+
vs,
|
|
12
|
+
)
|
|
10
13
|
|
|
11
14
|
__all__ = [
|
|
12
15
|
"good_resize",
|
|
@@ -17,7 +20,7 @@ def good_resize(
|
|
|
17
20
|
clip: vs.VideoNode,
|
|
18
21
|
width: int,
|
|
19
22
|
height: int,
|
|
20
|
-
shift: tuple[
|
|
23
|
+
shift: tuple[TopShift | list[TopShift], LeftShift | list[LeftShift]] = (0, 0),
|
|
21
24
|
gpu: bool | None = None,
|
|
22
25
|
anime: bool = False,
|
|
23
26
|
) -> vs.VideoNode:
|
|
@@ -55,10 +58,12 @@ def good_resize(
|
|
|
55
58
|
else:
|
|
56
59
|
luma_scaler = Hermite(sigmoid=True)
|
|
57
60
|
|
|
58
|
-
|
|
61
|
+
if not check_variable_format(clip, "good_resize"):
|
|
62
|
+
raise VariableFormatError("Invalid clip format for good_resize")
|
|
59
63
|
|
|
60
64
|
luma = luma_scaler.scale(clip, width, height, shift)
|
|
61
65
|
|
|
66
|
+
# Grayscale doesn't need chroma processing
|
|
62
67
|
if clip.format.num_planes == 1:
|
|
63
68
|
return luma
|
|
64
69
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: soifunc
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.14.1
|
|
4
4
|
Summary: Soichiro's VapourSynth Functions Collection
|
|
5
5
|
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
6
7
|
Author: Josh Holmer
|
|
7
8
|
Author-email: jholmer.in@gmail.com
|
|
8
9
|
Requires-Python: >=3.12,<4.0
|
|
@@ -10,8 +11,9 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
10
11
|
Classifier: Programming Language :: Python :: 3
|
|
11
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
13
|
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
15
|
Requires-Dist: vapoursynth (>=68)
|
|
14
|
-
Requires-Dist: vsjetpack (>=0.
|
|
16
|
+
Requires-Dist: vsjetpack (>=1.0.0,<2.0.0)
|
|
15
17
|
Description-Content-Type: text/markdown
|
|
16
18
|
|
|
17
19
|
## soifunc
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
soifunc/__init__.py,sha256=H6BWoCLRW2ZD47wQtL72SIZvTpD6REH7cUqIYWvCn0k,174
|
|
2
|
+
soifunc/deband.py,sha256=8mT1FqKAteUAs1XJYi8WvmlcJtyQN2OxM5mfiujTKX4,1887
|
|
3
|
+
soifunc/denoise.py,sha256=pWmGbFU5IRU0AAPi56a57NNBq-zaNUd7IG-nfdCgTeA,8897
|
|
4
|
+
soifunc/interpolate.py,sha256=2Agg1N4GG9h6lkl7soy7G--ahVk3msbDfKGuRbj2Syo,7878
|
|
5
|
+
soifunc/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
soifunc/resize.py,sha256=sOJpkovIEgaKvABEJTLfvYfKj6zvGf9pFRQMoWb7XdY,1998
|
|
7
|
+
soifunc-0.14.1.dist-info/METADATA,sha256=xVcBWO_TJ36Fx2Mc60QwRH3XFeKMVYjhPM1NxWZZ1Gc,1287
|
|
8
|
+
soifunc-0.14.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
9
|
+
soifunc-0.14.1.dist-info/licenses/LICENSE,sha256=vgEDSMEV1J2nMiCgXE5_sjNtw2VT7_lP7rkAnrFKOWI,1068
|
|
10
|
+
soifunc-0.14.1.dist-info/RECORD,,
|
soifunc-0.12.0.dist-info/RECORD
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
soifunc/__init__.py,sha256=H6BWoCLRW2ZD47wQtL72SIZvTpD6REH7cUqIYWvCn0k,174
|
|
2
|
-
soifunc/deband.py,sha256=MbI5OOG8JpWqM5B5ux6OU784-39PtCMQWrh9mk4k2xY,1273
|
|
3
|
-
soifunc/denoise.py,sha256=ALTftqL9Q1cPLKtAU60mT3-RUkVHXBqgg2Pa9GwjGIY,6982
|
|
4
|
-
soifunc/interpolate.py,sha256=dgYczCdn716afJ3sZgQgcF6KfAkaU2J_obJD-Kp7wP4,4091
|
|
5
|
-
soifunc/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
soifunc/resize.py,sha256=pSoQtrsxfWr44Wg4M9GRyMJnOsgnjsWEr6ZyoJW7Qkk,1781
|
|
7
|
-
soifunc-0.12.0.dist-info/LICENSE,sha256=vgEDSMEV1J2nMiCgXE5_sjNtw2VT7_lP7rkAnrFKOWI,1068
|
|
8
|
-
soifunc-0.12.0.dist-info/METADATA,sha256=cIZ9ZFeGwNCWcyiyKTStP51OvnaG7pLWRX3fTcv0vzo,1214
|
|
9
|
-
soifunc-0.12.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
10
|
-
soifunc-0.12.0.dist-info/RECORD,,
|
|
File without changes
|