Dither tools

From Avisynth wiki
(Difference between revisions)
Jump to: navigation, search
m (Dither_convert_rgb_to_yuv: formatting)
m (add internal link anchor: 'chroma placement')
Line 847: Line 847:
 
The chroma placement is ignored when ''center'' is set to <tt>false</tt> or ''kernel'' to <tt>"point"</tt>.  
 
The chroma placement is ignored when ''center'' is set to <tt>false</tt> or ''kernel'' to <tt>"point"</tt>.  
  
You’ll find below an overview of common chroma placement and subsampling combinations (click to enlarge)
+
<div id="chroma_placement">You’ll find below an overview of common chroma placement and subsampling combinations (click to enlarge)
 
::[[File:Colorspace-subsampling.png|171px]]
 
::[[File:Colorspace-subsampling.png|171px]]
 
+
</div>
 
;kernelh, kernelv
 
;kernelh, kernelv
 
: ''kernel'' parameter specialisation for a given direction (horizontal or vertical). An empty string means that the ''kernel'' value is used.
 
: ''kernel'' parameter specialisation for a given direction (horizontal or vertical). An empty string means that the ''kernel'' value is used.

Revision as of 22:01, 16 September 2015

Dither — high bitdepth tools for AviSynth

This package offers a set of tools to manipulate high-bitdepth (16 bits per plane) video clips. The most prominent features are color banding artifact removal, dithering to 8 bits, colorspace conversions and resizing.

Additionally, some existing filters (dfttest, MDegrain from MVTools, etc) have been modified to handle 16-bit clips.

Abstract
Author cretindesalpes
Version 1.23.0
Download http://ldesoras.free.fr/prod.html
Category Deep color tools
Requirements Planar colorspace,
  • Masktools 2 alpha 48 or later,
  • RemoveGrain 1.0b beta or later,
  • AddGrainC 1.5.1 or later
License WTFPL
Discussion doom9.org

Contents

Formats

As Avisynth doesn't support natively high bit depth, a specific format named stack16 is introduced. The picture is made of two parts: one containing the highest 8 bits (MSB) for each pixel, stacked on top of another containing the lowest 8 bits (LSB). When previewing the video stored in stack16 format, the top part looks quite like the original picture and the bottom one generally looks like psychedelic garbage.

Some functions may also use an MSB/LSB decomposition as interleaved pictures, but this format should be considered deprecated and is only supported for backward compatibility.

Finally, there are a few other formats made specifically for encoding, allowing Avisynth to send more than 8 bits per plane by faking raw data characteristics on the codec side.

When working with 16-bit clips, it’s important to know exactly which format a function takes as input and output. Specifically, you cannot process directly 16-bit clips with the usual 8-bit Avisynth filters, because they will interpret the LSB and MSB parts as regular data and mess everything. However there are various workarounds to mix 8- and 16-bit processing with minimal quality loss, please refer to the example section.

Outputting high-bitdepth clips to encode in 10 bits or more has become possible and is now quite common and supported by various encoding tools. However there is no practical mean to load a high-bitdepth media into Avisynth at this time. Regardless, SAPikachu hacked FFmpegSource2 to load 10-bit clips using a special parameter enable10bithack=true, resulting in stack16 output. See the latest ffms2 release here. Patch source code here.

Debanding and dithering

The main reason this package has been made is to address the color banding problem. Color banding generally occurs on low gradients or almost flat colors covering large areas, which is often the case in cartoons and animes. Because of the limited video bitdepth, the gradient color values show staircases in its curve, making apparent the discontinuity between two adjacent color steps.

This artifacts can appear at various stages:

  • It can be already present in the source,
  • created during a filtering pass
  • or added by the final codec because of bitrate starvation or inappropriate encoding settings.

Debanding functions helps to remove the banding from a source. Using high-bitdepth processing prevents the banding to appear during filtering. Finally, appropriate dithering helps to avoid banding during the conversion to 8 bits and the encoding stage.

Generally, film grain and video noise act as natural dithering. Filtering them out also removes this dithering and thus creates color banding. That’s why some denoising filters have been modified, in order to work as reversed dithering, outputting smooth 16-bit gradients from a noisy 8-bit source.

Color space conversions

Using 16-bit data helps working with curves without creating steps or holes in the histogram, which often are a sign of color banding. Color space conversion has the same kind of issues, and benefits from accurate 16-bit calculations too.

It makes possible to handle the picture information in linear light (without gamma correction), increasing the accuracy of some operations when processing pictures exhibiting high contrast.

Content

The functions are spread across dither.dll and dither.avsi. There are other files:

  • mt_xxpand_multi.avsi, containing utility functions not specifically related to dithering (they rather are Masktools extensions).
  • avstp.dll, to make dither.dll support native multi-threading. If this avstp is missing, the functions will still work but will be limited to single-threading only.

You may already have obtained them by other means. Put all these files in your AviSynth plugins directory. The package also contains mod16-modified denoising plug-ins to directly generate 16-bit data in a much more efficient way.

Functions implemented in dither.dll should be compatible with all the MT modes (including mode 1) and accept any planar colorspace. On this topic, scripted functions are limited by their external dependencies. YV12 colorspace and MT mode 2 should always work fine, anyway.

Considerations

If you’re going multi-threaded using the MT command, make sure you have set splitvertical=true for two reasons:

  • The functions may have to change the clip height
  • Stacked LSB and MSB of a given pixel must not be separated.

Examples of use

Use of modified denoisers

There are specifically modified denoising plug-ins allowing 16-bit output (I called them mod16), currently dfttest, MDegrain1, MDegrain2 and MDegrain3. They are included in the Dither package and can safely replace the regular versions, when up-to-date. Use the named parameter lsb=true to enable 16 bit output. Then, MSB is stacked on top of the LSB.

dfttest (lsb=true)      # The output contains stacked MSB-LSB on the same frame.
DitherPost ()

Transdithering using a non-modified temporal denoiser

An effective but very slow way to remove low noise while avoiding the introduction of color banding artifacts and keeping an excellent compressibility. Actually, better quality could be achieved with motion compensation but this is not the scope of this example. It shows how to use Dither2Pre to create a 16-bit clip with a 8-bit denoiser. Here, the default TTempSmooth parameters have been multiplied by 4 to adapt to the internal scale of pixel values.

o = last
Dither2Pre (
\   "TTempSmooth (lthresh=16, cthresh=20, lmdiff=8, cmdiff=12, scthresh=48)",
\   overlap=0, tvopt=true)
ref = last
mask = DitherPost (mode=-1).mt_edge (mode="min/max", thY1=0, thY2=255, thC1=0, thC2=255)
mask = mask.mt_binarize (1, u=3, v=3).mt_expand (u=3, v=3).mt_expand (u=3, v=3)
mask = mask.RemoveGrain (20).RemoveGrain (20)
Dither_bilateral16 (radius=16, thr=1.5, wmin=1, flat=0.75)
Dither_bilateral16 (radius=8, thr=2.5, wmin=1, flat=0.33, ref=ref)
Dither_limit_dif16 (ref, thr=0.3)
DitherPost ()
mt_merge (last, o, mask, u=3, v=3)

Combining 8- and 16-bit processing

Generic method

There is often a need to mix 8- and 16-bit processing because only a few filters are available in 16 bits. Below is a little template to achieve this. This is not a perfect solution but work quite well. It’s possible to lower a bit the Dither_limit_dif16 thr parameter. You can repeat the steps as many times you need to alternate 8 and 16 bits.

dfttest (lsb=true) # or whatever generating stack16 data

# Insert 16-bit filters here

s16 = last
DitherPost (mode=-1)

# Insert 8-bit filters here

Dither_convert_8_to_16 ()
s16.Dither_limit_dif16 (last, thr=1.0, elast=2.0)

# Insert 16-bits filters again...

# Finally
DitherPost () # or Dither_out ()

Filtering in 16 bits with basic sharpening

The example below shows how to use a 8-bit sharpener with a 16-bit clip. This method guarantees that the dithering pattern will not be sharpened. This is an alternative method to the proposed above. The rationale is: going back to 8-bit without dithering (mode = -1), doing stuff, compute the difference between processed and unprocessed clips, dither the 16-bit clip and add the previously computed difference to the result. This method can be applied to some other kinds of processing.

dfttest (lsb=true)
f = DitherPost (mode=-1)
s = f.Sharpen ()
d = mt_makediff (s, f)
DitherPost ()
mt_adddiff (last, d, u=2, v=2)

Debanding a clip

Without filtering:

GradFun3 ()

Advanced multi-pass filtering for a source containing both noise and banding. This script requires the modified version of the MVTools2.

# Your favourite 8-bit denoiser here, doing the main job
denoised = dfttest (sigma=16)

# Restores a bit of noise
mt_lutxy (last, denoised, expr="x y < y 1 - x y > y 1 + y ? ?", y=3, u=3, v=3)

super   = last.MSuper ()
super_a = denoised.MSuper ()

# You could also reuse the vectors found in a previous processing stage
vf1 = super_a.MAnalyse (isb=false, delta=1, overlap=4, blksize=16)
vb1 = super_a.MAnalyse (isb=true,  delta=1, overlap=4, blksize=16)

# Turns remaining noise into 16-bit gradients
cf1 = MCompensate (super, vf1, thSAD=200)
cb1 = MCompensate (super, vb1, thSAD=200)
Interleave (cf1, last, cb1)
dfttest (sigma=1.0, tbsize=3, lsb=true)
SelectEvery (3, 1)

# Additional smoothing pass and back to 8 bits
GradFun3 (thr=0.25, lsb_in=true)

When a clip contains sharpening overshoots, the color banding may be resilient to GradFun3, even with high thresholds (> 1.5). The following script helps to remove it without loosing too much details. You may have to adapt some values. Display mask_details.GreyScale() to check the mask. It shouldn’t show the color band boundaries (or just marginally).

lvl_overshoot = 3.5
lvl_details   = 2

o = last
w = Width ()
h = Height ()

edges= mt_edge (mode="prewitt", thY1=0, thY2=255)
details = mt_edge (mode="min/max", thY1=0, thY2=255)

mask_lines= edges.mt_lut ("x 6 - 50 *")
mask_lines= mask_lines.mt_expand().mt_expand().mt_expand().mt_expand ()
mask_overshoot = edges.mt_lut ("x "+String(lvl_overshoot)+" - 2 ^ 40 *")
mask_overshoot = mask_overshoot.mt_inpand().RemoveGrain (12, -1)
mask_overshoot = mt_logic (mask_overshoot, mask_lines, mode="max")
mask_details= details.mt_binarize (lvl_details)>
mask_details= mask_details.RemoveGrain (21 ,-1).mt_expand ()
mask_final= mt_logic (mask_overshoot, mask_details, mode="min")
mask_final= mask_final.RemoveGrain (20, -1).RemoveGrain (20, -1)

o
BicubicResize (w/16 * 4, h/16 * 4, 1, 0).BicubicResize (w, h, 1, 0)
GradFun3 (radius=4, thr=0.6, mask=0, mode=6) # Huge blur
mt_merge (last, o, mask_overshoot, luma=true) # W/o overshoot
GradFun3 (thr=0.6, mask=0)                    # W/o banding
mt_merge (last, o, mask_final, luma=true)     # Details protected

Working with curves

The following examples are designed for TV-range data (luma in 16–235).

Denoises very slightly, debands and protects the darkest shades by increasing the dynamic range for low luma values:

a = 0.5 # The smaller, the greater the protection
sa = String (a)
sd = String (Pow (219*256, 1 - 1.0/a))
dfttest (sigma=0.25, lsb=true)
Dither_lut16 ("x 4096 - 0 max "+sd+" / "+sa+" ^", y=3, u=2, v=2) # Direct
SmoothGrad ()
Dither_lut16 ("x 1 "+sa+" / ^ "+sd+" * 4096 +", y=3, u=2, v=2)   # Inverse
DitherPost ()

Blending 8-bit pictures in linear light:

# Blending amount for the first clip
bl   = 0.75
bls1 = String (    bl)
bls2 = String (1 - bl)

# 8-bit clips converted to linear 16-bit full range (gamma undone)
ug = " 16 - 0 max 1.41624 / 2.2 ^ "

# Redo the gamma, result in 16 bits YUV
rg = " 0.454545 ^ 362.5585 * 4096 +"

# Blend
Dither_lutxy8 (src1, src2,
\       expr ="x     " + bls1 + " * y     " + bls2 + " * + 256 *",
\       yexpr="x" + ug + bls1 + " * y" + ug + bls2 + " * +" + rg,
\       y=3, u=3, v=3)

# Back to 8 bits
DitherPost ()

Resizing in 16 bits

Simple resize

Dither_convert_8_to_16 ()
Dither_resize16 (1280, 720)
DitherPost ()

Sharpening the luma using the convolver of the resizer:

Dither_convert_8_to_16 ()
Dither_resize16 (Width (), Height () / 2, kernel="impulse -1 6 -1",
\                fh=-1, fv=-1, cnorm=true, center=false, y=3, u=2, v=2)
DitherPost ()

Restoring the original size of a picture using kernel inversion:

# Input in 8 bits
w = Width ()  # Original size
h = Height () #
BilinearResize (w * 3 / 2, h * 3 / 2) # Upscale

Dither_convert_8_to_16 ()
Dither_resize16 (w, h, kernel="bilinear", invks=true)
DitherPost ()

Colorspace conversions

Color conversions of 8-bit clips:

BlankClip () # Assumes RGB
Dither_convert_rgb_to_yuv ()
Dither_convert_yuv_to_rgb ()

Upscaling in 16 bits a SD video to HD with correct color matrix conversion (slow way), output dithered to 8 bits ready for encoding:

MPEG2Source ("video_sd.d2v")
Dither_convert_8_to_16 ()
Dither_resize16 (1280, 720)
Dither_convert_yuv_to_rgb (matrix="601", output="rgb48y", lsb_in=true)
r = SelectEvery (3, 0)
g = SelectEvery (3, 1)
b = SelectEvery (3, 2)
Dither_convert_rgb_to_yuv (r, g, b, matrix="709", lsb=false, mode=0)

Another possibility, with the resizing function operating in RGB land:

MPEG2Source ("video_sd.d2v")
Dither_convert_yuv_to_rgb (matrix="601", output="rgb48y")
Dither_resize16 (1280, 720, y=3, u=1, v=1)
r = SelectEvery (3, 0)
g = SelectEvery (3, 1)
b = SelectEvery (3, 2)
Dither_convert_rgb_to_yuv (r, g, b, matrix="709", lsb=false, mode=0)

Displaying a preview of a YUV stream with automatic matrix detection, conversion to sRGB with correct transfer curve, non-ringing scaling to 1080 lines in RGB linear colorspace and anamorphic correction:

MPEG2Source ("anything.d2v")
Dither_srgb_display (h=1080, dar=1.778)   # or 1.333 for 4:3 AR

Special output to high bitdepth

Simple denoising, quick debanding and direct 16-bit output for x264-10bit. Make sure reading the important remarks in the Dither_out function description:

dfttest (lsb=true)
SmoothGrad ()
Dither_out ()

Same as above, but outputting 10-bit data aligned on 16-bit words (still needs --input-depth 16 in x264. Use reducerange=true for real 10-bit input):

dfttest (lsb=true)
SmoothGrad ()
Dither_quantize (10, mode=6)
Dither_out ()

Simple debanding with RGB48 output (needs specific encoding step):

Dither_convert_8_to_16 ()
SmoothGrad ()
Dither_convert_yuv_to_rgb (lsb_in=true, output="rgb48y")
r = SelectEvery (3, 0)
g = SelectEvery (3, 1)
b = SelectEvery (3, 2)
Dither_convey_rgb48_on_yv12 (r, g, b)

Common parameters

Exactly like MaskTools 2, Dither has functions sharing common parameters.

int y (3), int u (3), int v (3)
These three values describe the actual processing mode that is to be used on each plane / channel. Here is how the modes are coded:
-255...0 or -65535...0 All the pixels of the plane will be set to -x. The range depends whether the output clip is a stack16 or a regular 8-bit clip.
1 The plane will not be processed. That means the content of the plane after the filter is pure garbage.
2 The plane of the first input clip will be copied.
3 The plane will be processed with the processing the filter is designed to do.
4 When applicable, the plane of the second input clip will be copied.
5 When applicable, the plane of the third input clip will be copied.

Unlike Masktools 2, all the planes are processed by default.

Filters description

DitherPost

DitherPost (
        clip  m,
        clip  clsb (undefined),
        int   mode (0),
        float ampo (1),
        float ampn (0),
        int   pat (1),
        bool  dyn (false),
        bool  prot (false),
        clip  mask (undefined),
        float thr (-1),
        bool  stacked (true),
        bool  interlaced (false),
        int   y (3),
        int   u (3),
        int   v (3),
        bool  staticnoise (false)
)

Adds the dither, turning a 16-bit clip generated by Dither1Pre, Dither2Pre or a mod16 denoiser into a regular 8-bit clip.

Pure ordered dithering seems to be retained better than noise or error diffusion during video compression. Therefore this is the recommended method to avoid color banding, unless you encode at very high bitrates. If you don't care about video compression, error diffusion gives the most accurate results. To avoid discontinuities between purely flat areas and dithered areas, you can add a bit of noise.

Important note: the colorbanding removal is not done by the dithering stage, but by the filtering stage. The latter rebuilds the fine gradients in the 16-bit land. The dithering helps converting the picture data to something watchable, in 8 bits, while preserving a perceptually high colordepth, thus preventing the colorbanding to appear.

m
If clsb is defined, contains the main picture data (MSB). If clsb is not defined, it contains both MSB and LSB clips as interleaved frames (same format as the first pass output), or as stacked frames, depending on the stacked value.
clsb
Contains the residual information (LSB) if defined.
mode
Dithering method:
-1 no dither, round to the closest value
0 8-bit ordered dither + noise.
1 1-bit dither
2 2-bit dither, light
3 2-bit dither, medium
4 2-bit dither, strong
5 2-bit dither, stronger
6 Serpentine Floyd-Steinberg error diffusion + noise. Well-balanced algorithm.
7 Stucki error diffusion + noise. Looks “sharp” and preserve light edges and details well.
8 Atkinson error diffusion + noise. Generates distinct patterns but keeps clean the flat areas.
ampo
The ordered dither peak-to-peak amplitude, on an 8 bit scale. = 0. On error diffusion algorithms, it increases the collected error amount, helping to extend the range of the dithering while preserving its natural pattern (especially Atkinson’s). This gives a better looking result than just adding noise.
ampn
The noise peak-to-peak amplitude, on an 8 bit scale. = 0. Currently, the maximum value is 4.
pat
is the dither pattern type for 2-bit dither:
0 Regular
1 Alternate V
2 Alternate H
dyn
Indicates if the ordered dither pattern is dynamic. If so, the pattern is rotated each frame.
prot
Enables the protection against MSB-LSB inconsistencies, which can occur when the main picture (MSB only) is processed.
mask
If defined, dithering is applied where the pixel values are lower than 128. Must be defined for all the planes. You can build the mask with DitherBuildMask.
thr
Threshold below which no dither occurs, in pixel value units on an 8 bit scale. It helps to keep calm flat areas where the LSB content is just low-level residual noise. Works only for dithering mode 0. Ranges from 0 to 0.5. -1 = disabled.
stacked
When clsb is undefined, true indicates that the clip is composed of the MSB part stacked on top of the LSB part. false indicates that MSB and LSB are interleaved.
interlaced
Indicates that the clip is interlaced and that the dither should be applied on each field separately.
staticnoise
If set to true, the noise generated with ampn is static.

Category: dll.

DitherBuildMask

DitherBuildMask (
        clip cnew,
        clip cold (undefined),
        int  edgelvl (8),
        int  radius (2)
)

This function builds a mask to use in DitherPost. It helps avoiding artifacts during the dithering when the picture was processed between the DitherXPre and DitherPost operations. It also helps to preserve detailed areas from dithering. Call this function right before DitherPost and pass the result in the mask parameter.

cnew
The MSB part of the processed clip.
cold
The original MSB part of the clip. If this argument is specified, cold must be of the same size as cnew. Pixel which are different are set in the mask and are expanded like the edges.
edgelvl
Threshold for the edge detection (0–255). The lower, the more edges it detects.
radius
Minimum distance in pixels separating the dithered zones from the detected edges and potential artifacts (1–8).

Category: script.

SmoothGrad

SmoothGrad (
        clip  m,
        clip  clsb (undefined),
        int   radius (16),
        float thr (0.25),
        bool  stacked (true),
        clip  ref (undefined),
        float elast (3),
        int   y (3),
        int   u (3),
        int   v (3)
)

SmoothGrad smoothes the low gradients or flat areas of a 16-bit clip. It proceeds by applying a huge blur filter and comparing the result with the input data for each pixel. If the difference is below the specified threshold, the filtered version is taken into account, otherwise the input pixel remains unchanged.

m
If clsb is defined, contains the main picture data (MSB). If clsb is not defined, it contains both clips. In this case, its format depends on the stacked parameter.
clsb
Contains the residual information (LSB) if defined.
radius
Radius in pixels of the smoothing filter. > 0.
thr
Threshold between reference data and filtered data, on an 8-bit scale. > 0.
stacked
When clsb is undefined, true indicates that the clip is composed of the MSB part stacked on top of the LSB part. False indicates that MSB and LSB are interleaved.
ref
Reference clip for the filter output comparison. Specify here the input clip when you cascade several SmoothGrad calls. It is always a stacked or interleaved LSB/MSB combination, depending on the stacked parameter. When undefined, the input clip is taken as reference.
elast
To avoid artifacts, the threshold has some kind of elasticity. Value differences falling over this threshold are gradually attenuated, up to thr * elast. > 1.

Category: dll.

GradFun3

GradFun3 (
        clip  src,
        float thr (0.35),
        int   radius (12),
        float elast (3),
        int   mask (2),
        int   mode (undefined),
        float ampo (undefined),
        float ampn (undefined),
        int   pat (undefined),
        bool  dyn (undefined),
        float dthr (undefined),
        int   smode (0),
        float wmin (1.0),
        float thr_det (2),
        float thr_edg,
        int   debug (0),
        float subspl (0),
        bool  lsb (false),
        bool  lsb_in (false),
        bool  staticnoise (undefined),
        float thrc (thr),
        int   radiusc (radius),
        float elastc (elast)
        int   y (3),
        int   u (3),
        int   v (3)
)

This function is equivalent to GradFun2db and helps removing the existing color-banding from a source, dithered or not. The default dithering pattern is ordered and should be more resilient to lossy codec quantification than the other patterns. But to keep all the advantages of the gradient smoothing and dithering, you should make GradFun3 the very last filter of your encoding chain, or use masking methods to safeguard the dither patterns.

src
The input clip.
thr, thrc
Filter threshold. Below this value, the changes made by the banding filter on pixel values are not attenuated. The higher, the more effective the filter will be, but details will be smoothed and artifacts will appear near the edges between two flat areas. thrc is the parameter for the chroma planes. Keep it below 1.0. Range: 0.1–10.0.
radius, radiusc
Filter radius, in pixels. Basically, this is the extent of artificial gradient introduced on the band edges. radiusc is the parameter for the chroma planes. The default value is tuned for SD video and 720p, but you might probably want to increase it to 16 for 1080p video. Range: 1–68 for smode=0, 1–128 for smode=1 and 1–48 for smode=2.
elast, elastc
Elasticity of the filter attenuation. It’s a multiplier on the threshold. A pixel difference above thr * elast won’t have any effect. elastc is the parameter for the chroma planes. Good values are in the range 1.25–4.
mask
Depth in pixels of the detail/edge masking. Set it to 0 to disable it.
thr_det
Local contrast threshold for detail detection and masking. The lower, the better the details will be protected, but the lower the smoothing efficiency. Must be > 0, and above the height of a color-banding step. When kept unspecified, it more or less follows the main debanding threshold thr.
thr_edg
Unused. Kept for backward compatibility purpose.
smode
Indicates which filter to use for gradient smoothing.
0 Box filter. Very fast, whatever the radius. Drawback: can introduce slight but large halos, especially with high thresholds.
1 dfttest. Much slower, but less prone to artefacts and halos than the box filter. This is the prefered mode for high quality results with acceptable processing time.
2 Bilateral filter. Very slow, and slower for bigger radius, but much less prone to artefacts than the box filter. Almost haloless, even for high thresholds.
3 Undocumented mode.
wmin
For smode 2 (bilateral filter), this parameter prevents the filter to totally flatten the small areas of nearly uniform color. It ranges between 0.0 (normal bilateral filtering) and 1.0 (protection fully activated).
debug
0 Normal output, without debugging information.
1 Shows the detail/edge mask.
subspl
Subsampling rate for the bilateral filter. Set it to 0 to adjust it automatically to the radius. Disable it with 1. Normal subsampling values should be greater or equal to 4. The maximum value depends on the radius.
lsb
When set to true, leaves the 16-bit data instead of dithering them to 8 bits.
lsb_in
When set to true, works on 16-bit input.

other parameters

The other parameters are directly transmitted to DitherPost. dthr is translated to thr.

Here is a table showing the equivalent parameters in GradFun3 and GradFun2DBmod:

GradFun3
Conversion
GradFun2DBmod
thr
= 0.3 * thr
mask
= radius
thr_det
= range

Category: script.

Dither_box_filter16

Dither_box_filter16 (
        clip src,
        int  radius (16),
        int  y (3),
        int  u (3),
        int  v (3)
)

Performs a box filtering on the input clip. Box filtering consists in averaging all the pixels in a square area whose center is the output pixel. This filter is very fast to compute and its speed doesn’t depend on its radius. You can approximate a large gaussian filtering by cascading a few box filters.

Both input and output are vertically stacked 16-bit clips.

src
Input clip to be filtered.
radius
Size of the averaged square. Its width is radius*2-1. Range: 2–91.

Category: dll.

Dither_bilateral16

Dither_bilateral16 (
        clip  src,
        clip  ref (undefined),
        int   radius (16),
        float thr (2.5),
        float flat (0.4),
        float wmin (0.0),
        float subspl (0),
        int   y (3),
        int   u (3),
        int   v (3)
)

Performs a bilateral filtering on the input clip. A bilateral filter is like a gaussian filter, but values of the filtering window are weighted with a gaussian curve, depending of their proximity with the center pixel. The closer the values, the more weight has the value in the final sum. Bilateral filters are very efficient to remove noise on flat areas and smooth gradients without being disturbed by surrounding areas of different colors or high contrast lines. The result of a bilateral filtering is indeed cartoonish and waxy, therefore it does a very good job at gradient smoothing, without producing halos like the box filter. However, this is a very slow filter.

Actually, this implementation is an approximation of a bilateral filter, like many other image processing tools do. The spatial weighting is not a gaussian curve but a box, and the value weighting is a trapezoid. Cascading several function calls leads to a better approximation of the gaussian shape.

If you plan to use this filter for debanding, do not use it alone. It has no protection against oversmoothing. You should first apply Dither_limit_dif16 on its result, exactly like with Dither_box_filter16, then use a mask to protect the finest details. The GradFun3 code is a good example to refer to.

This function works only on 16-bit stacked clips.

If you MT() the function, make sure to have an horizontal overlap greater or equal to twice the radius. Anyway, this is certainly not the most efficient way to get the processing multithreaded. Prefer using SetMTMode 1 or 2.

src
Clip to be filtered.
ref
When computing the value weighting, pixels of this clip are taken for reference. When cascading several calls to the function, set the original clip as reference to avoid the result to drift to something superflat.
radius
Size of the averaged square. Its width is radius*2-1. Range: 2–64.
thr
Pixels whose difference of value with the center pixel is over thr will be discarded. The parameter ranges on an 8 bit scale. Must be stricly positive.
flat
Determines the shape of the trapezoid weighting of the value differences. Close to 0, the shape is triangular. Close to 1, the shape is a rectangle, like a box filter with a hard threshold. Range: 0.0–1.0
wmin
The partial or missing pixels are completed with the center pixel to match the wmin fraction of the filter window at full weight. At 0.0, it acts like a classic bilateral filter. Raising the total weight helps preventing the filter to completely flatten the small areas of close colors. Range: 0.0–1.0. Values over 1 are tolerated, they are equivalent to keep wmin to 1 while reducing the overall strength of the filter.
subspl
Subsampling rate. When this parameter is activated, only a few pixels randomly chosen from the search window are taken into account. This leads to significative speed improvment, with only a minor quality loss. A value equal to twice the radius looks like a good compromise. Normal subsampling values should be greater or equal to 4. Below, subsampling is disabled. Set subspl to 0 to let the filter adjust the subsampling rate automatically, depending on the radius. The random pattern is the same for all the frames and planes.

Category: dll.

Dither_limit_dif16

Dither_limit_dif16 (
        clip  flt,
        clip  src,
        clip  ref (undefined),
        float thr (0.25),
        float elast (3.0),
        int   y (3),
        int   u (3),
        int   v (3)
)

This function compare a filtered clip with its original version, and keeps the filtered pixels only if the difference between the filtered pixel and the reference pixel is below the given threshold. This is a building block of SmoothGrad and GradFun3.

This function works only on 16-bit stacked clips.

flt
Filtered clip.
src
Original clip.
ref
Reference clip for the filter output comparison. Specify here the first original clip when you cascade several limited filters. When undefined, the src clip is taken as reference.
thr
Threshold between reference data and filtered data, on an 8-bit scale. > 0.
elast
To avoid artifacts, the threshold has some kind of elasticity. Value differences falling over this thershold are gradually attenuated, up to thr * elast. > 1.

Category: dll.

Dither_resize16

Dither_resize16 (
        clip   src,
        int    width,
        int    height,
        float  src_left (0),
        float  src_top (0),
        float  src_width (0),
        float  src_height (0),
        string kernel ("spline36"),
        float  fh (1.0),
        float  fv (1.0),
        int    taps (4),
        float  a1 (undefined),
        float  a2 (undefined),
        float  a3 (undefined),
        int    kovrspl (1),
        bool   cnorm (true),
        bool   center (true),
        string cplace ("MPEG2"),
        int    y (3),
        int    u (3),
        int    v (3),
        string kernelh (""),
        string kernelv (""),
        float  totalh (0),
        float  totalv (0),
        bool   invks (false),
        bool   invksh (invks),
        bool   invksv (invks),
        int    invkstaps (5)
)
Dither_resize16nr (
        …
        (same arguments as Dither_resize16)
        …
        bool   noring (true)
)

Resizes a 16-bit clip.

The function can resize interlaced content, but only if presented as separated, interleaved fields. It uses the Avisynth parity information to detect fields and maintain the correct chroma and luma positions. If this behaviour is not desired, add an AssumeFrameBased() before the resizing call.

The function can also be used to compute horizontal and vertical convolutions. If you do so, don’t forget to set:

  • fh or fv to -1 to make sure the clip is processed even if its size doesn’t change,
  • cnorm to false to avoid automatic kernel normalisation if your impulse is already normalised, or specify totalv or totalh if the normalisation factor is not the sum of the impulse
  • and center to false to keep the desired spacing between the sampling points.

This function works only on 16-bit stacked clips.

The Dither_resize16nr function is a wrapper over Dither_resize16, adding a ringing-cancellation algorithm.

src
Clip to be resized. Mandatory.
width, height
New picture width and height in pixels, > 0. Mandatory.
src_left, src_top
Coordinate of the top-left corner of the picture sub-area used as source for the resizing. They can be fractional. If negative, the picture is extended by replicating the left pixel column.
src_width, src_height
Size in pixels of the sub-area to resize. They can be fractional. If 0, the area has the same size as the source clip. If negative, they define coordinates relative to the bottom-right corner, in a Crop-like manner.
kernel
Kernel used by the resizer. Possible values are:
"point" Nearest neighbour interpolation. Same as PointResize().
"rect" or "box" Box filter.
"linear" or"bilinear" Bilinear interpolation. Same as BilinearResize().
"cubic" or"bicubic" Bicubic interpolation. Same as BicubicResize(). The b and c variables are mapped on a1 and a2 and are both set to 1/3 by default.
"lanczos" Sinc function windowed by the central lobe of a sinc. Use taps to specify its impulse length. Same as LanczosResize().
"blackman" Blackman-Harris windowed sinc. Use taps to control its length. Same as BlackmanResize().
"blackmanminlobe" Another kind of Blackman windowed sinc, with a bit less ringing. Use taps for you know what.
"spline16" Cubic spline based kernel, 4 sample points. Same as Spline16Resize().
"spline36" Spline, 6 sample points. Same as Spline36Resize().
"spline64" Spline, 8 sample points. Same as Spline64Resize().
"spline" Generic splines, number of sample points is twice the taps parameter, so you can use taps = 6 to get a Spline144Resize() equivalent.
"gauss" or"gaussian" Gaussian kernel. The p parameter is mapped on a1 and controls the curve width. The higher p, the sharper. It is set to 30 by default. This resizer is the same as GaussResize(), but taps offers a control on the filter impulse length. For low p values (soft and blurry), it’s better to increase the number of taps to avoid truncating the gaussian curve too early and creating artifacts.
"sinc" Truncated sinc function. Use taps to control its length. Same as SincResize().
"impulse" Offers the possibility to create your own kernel (useful for convolutions). Add your coefficents in the string after “impulse”, separated with spaces (ex: "impulse 1 2 1"). The number of coefficients must be odd. The curve is linearly interpolated between the provided points. You can oversample the impulse by setting kovrspl to a value > 1.
fh, fv
Horizontal and vertical frequency factors, also known as inverse kernel support. They are multipliers on the theoretical kernel cutoff frequency in both directions. Values below 1.0 spatially expand the kernel and blur the picture. Values over 1.0 shrink the kernel and let higher frequencies pass. The result will look sharper but more aliased. The multiplicator is applied after the kernel scaling in case of downsizing. Negative values force the processing, even if the horizontal size doesn’t change. The filter will use the absolute parameter value.
taps
Some kernels have a variable number of sample points, given by this parameter. Actually this counts half the number of lobes (or equivalent) ; in case of downscaling, the actual number of sample points may be greater than the specified value. Range: 1–128
a1, a2, a3
Specific parameters, depending on the selected kernel.
kovrspl
Specifies here how many times the kernel is oversampled when you provide a custom impluse response. ≥ 1.
cnorm
If set to true, the impulse sum is normalised to 1 for each pixel. This is the normal behaviour when resizing, to make sure the energy is constant for all pixels. If you use the resizer as a convolution engine, it is advised to disable the normalisation.
center
Like the Avisynth resizers, this resizer preserves the position of the picture center. Disable this parameter if you may want to resize by preserving the top-left corner position. Similarly, if you are convolving without resizing, setting it to false ensures you that the same kernel will be applied to all pixels.
cplace
Placement of the chroma samples. Can be one of these strings:
"MPEG1" 4:2:0 subsampling used in MPEG-1. Chroma samples are located on the center of each group of 4 pixels.
"MPEG2" Subsampling used in MPEG-2 4:2:x and most other formats. Chroma samples are located on the left pixel column of the group.
"DV" For 4:2:0 modes, it’s like MPEG-2 but U and V channels are “co-sited” vertically: V on the top row, and U on the bottom row. For 4:1:1, chroma is located on the leftmost column.

The chroma placement is ignored when center is set to false or kernel to "point".

You’ll find below an overview of common chroma placement and subsampling combinations (click to enlarge)
Colorspace-subsampling.png
kernelh, kernelv
kernel parameter specialisation for a given direction (horizontal or vertical). An empty string means that the kernel value is used.
totalh, totalv
When cnorm is activated, these parameters specify the normalisation value for the corresponding kernel. 0 means that the normalisation value is the sum of the coefficients. The Masktools’mt_convolution function has a single parameter for this use: total = totalh × totalv. Because the convolution is computed with floating point data, there is no saturation of intermediate results, therefore the balance between totalh and totalv is not important, only their product will be taken into account.
invks, invksh, invksv
Activates the kernel inversion mode for the specified direction (use invks for both). Inverting the kernel allows to “undo” a previous upsizing by compensating the loss in high frequencies, giving a sharper and more accurate output than classic kernels, closer to the original. This is particularly useful for clips upscaled with a bilinear kernel. All the kernel-related parameters specify the kernel to undo. The target resolution must be as close as possible to the initial resolution. The kernel inversion is mainly intended to downsize an upscaled picture. Using it for upsizing will not restore details but will give a sligthly sharper look, at the cost of a bit of aliasing and ringing. This mode is somewhat equivalent to the debilinear plug-in but works with a different principle.
invkstaps
In kernel inversion mode (invks=true), this parameter sets the number of taps for the inverted kernel. Use it as a tradeof between softness and ringing. Range: 1–128
noring
A ringing cancellation algorithm is additionally used when set to true.

Category: dll.

Dither_convert_yuv_to_rgb

Dither_convert_yuv_to_rgb (
        clip   src,
        string matrix (undefined),
        bool   interlaced (false),
        bool   tv_range (true),
        string cplace ("MPEG2"),
        string chromak ("bicubic"),
        float  fh (undefined),
        float  fv (undefined),
        int    taps (undefined),
        float  a1 (undefined),
        float  a2 (undefined),
        float  a3 (undefined),
        bool   lsb_in (false),
        int    mode (undefined or 6),
        float  ampn (undefined or 0.5),
        string output ("rgb32"),
        int    ampo (undefined),
        bool   staticnoise (undefined),
        bool   noring (false)
)

Converts a YUV clip to RGB using high bitdepth calculations. By default, 8 bit RGB output is dithered using error diffusion + noise to get the maximum visual quality.

src
An 8 or 16-bit YUV clip to be converted to RGB. If the clip is 16-bit stacked, set the lsb_in parameter to true.
matrix
The matrix used to convert the Y’CbCr pixels to computer RGB. Possible values are:
"601" ITU-R BT.601 / ITU-R BT.470-2 / SMPTE 170M. For Standard Definition content.
"709" ITU-R BT.709. For High Definition content.
"2020" ITU-R BT.2020, non constant luminance mode. For UHDTV content.
"240" SMPTE 240M
"FCC" FCC (where does that come from?)
"YCgCo" YCgCo

When the parameter is not defined, ITU-R BT.601 and ITU-R BT.709 are automatically selected depending on the clip definition (considered as HD if ≥ 600 lines).

interlaced
Indicates that the input clip is interlaced.
tv_range
true if input clip has TV range pixel values, false if it uses the full range (PC scale).
cplace
Placement of the chroma samples. Can be one of these strings:
"MPEG1" 4:2:0 subsampling used in MPEG-1. Chroma samples are located on the center of each group of 4 pixels.
"MPEG2" Subsampling used in MPEG-2 4:2:x and most other formats. Chroma samples are located on the left pixel column of the group.
"DV" For 4:2:0 modes, it’s like MPEG-2 but U and V channels are "co-sited" vertically: V on the top row, and U on the bottom row. For 4:1:1, chroma is located on the leftmost column.
chromak
Kernel used to shift and resize the chroma plane to full resolution before conversion.
fh, fv, taps, a1, a2, a3
Chroma resampling parameters. See Dither_resize16() for more information.
lsb_in
Indicates that the input clip is stack16.
mode, ampo, ampn, staticnoise
Dithering parameters, for 8 bit output. See DitherPost(). When and ampn are not defined, they are set to the specified default value.
output
Output format. Possible values are:
"rgb32" Regular RGB32 colorspace.
"rgb24" Regular RGB24 colorspace.
"rgb48yv12" 48-bit RGB conveyed on YV12. Use it for rawvideo export only. Not suitable for display or further processing (it will look like garbage).
"rgb48y" 48-bit RGB. The components R, G and B are conveyed on three YV12 or Y8 (if supported) stack16 clips interleaved on a frame basis.
noring
A ringing cancellation algorithm is used to upscale the chroma when this parameter set to true.

Category: script.

Dither_convert_rgb_to_yuv

Dither_convert_rgb_to_yuv (
        clip   src,
        clip   g (undefined),
        clip   b (undefined),
        string matrix (undefined),
        bool   interlaced (false),
        bool   tv_range (true),
        string cplace ("MPEG2"),
        string chromak ("bicubic"),
        float  fh (undefined),
        float  fv (undefined),
        int    taps (undefined),
        float  a1 (undefined),
        float  a2 (undefined),
        float  a3 (undefined),
        bool   lsb (undefined),
        int    mode (undefined),
        float  ampn (undefined),
        string output ("yv12"),
        int    ampo (undefined),
        bool   staticnoise (undefined),
        bool   noring (false)
)

Converts an RGB clip to YUV using high bitdepth calculations.

src
An 8 or 16-bit RGB clip to be converted to RGB. if only src is defined, the clip is considered as 8-bit RGB. If g and b are defined too, the three are assumed as 16-bit stacked clips containing the red, green and blue channels. They might be the deinterleaved result of Dither_convert_yuv_to_rgb() with "rgb48y" as output string.
matrix
The matrix used to convert the R’G’B’ pixels to Y’CbCr. Possible values are:
"601" ITU-R BT.601 / ITU-R BT.470-2 / SMPTE 170M. For Standard Definition content.
"709" ITU-R BT.709. For High Definition content.
"2020" ITU-R BT.2020, non constant luminance mode. For UHDTV content.
"240" SMPTE 240M
"FCC" FCC (where does that come from?)
"YCgCo" YCgCo

When the parameter is not defined, ITU-R BT.601 and ITU-R BT.709 are automatically selected depending on the clip definition (considered as HD if ≥ 600 lines).

interlaced
Indicates that the input clip is interlaced.
tv_range
true if input clip has TV range pixel values, false if it uses the full range (PC scale).
cplace
Placement of the chroma samples. Can be one of these strings:
"MPEG1" 4:2:0 subsampling used in MPEG-1. Chroma samples are located on the center of each group of 4 pixels.
"MPEG2" Subsampling used in MPEG-2 4:2:x and most other formats. Chroma samples are located on the left pixel column of the group.
"DV" For 4:2:0 modes, it’s like MPEG-2 but U and V channels are "co-sited" vertically: V on the top row, and U on the bottom row. For 4:1:1, chroma is located on the leftmost column.
chromak
Kernel used to shift and resize the chroma plane to full resolution before conversion.
fh, fv, taps, a1, a2, a3
Chroma resampling parameters. See Dither_resize16 for more information.
lsb
Indicates if the output clip is stack16 (true) or 8 bits. If not defined, it depends on the input bitdepth.
mode, ampo, ampn, staticnoise
Dithering parameters, for 8 bit output. See DitherPost.
output
Output format, 8 or 16-bit stacked. Possible values are:
"YV12"
"YV16"
"YV24"
"YV411"
"Y8"
noring
A ringing cancellation algorithm is used to downscale the chroma when this parameter set to true.

Category: script.

Dither_srgb_display

Dither_srgb_display (
        clip   src,
        int    debug (0),
        bool   lsb_in (false),
        string matrix (undefined),
        bool   tv_range (undefined),
        string chromak (undefined),
        int    w (undefined),
        int    h (undefined),
        string kernel ("spline36" or "spline64"),
        int    taps (undefined),
        bool   noring (true),
        bool   precrop (depends),
        bool   autopar (true),
        float  par (undefined),
        int    parnum (undefined),
        int    parden (undefined),
        float  dar (undefined),
        int    darnum (undefined),
        int    darden (undefined),
        float  src_left (0),
        float  src_top (0),
        float  src_width (0),
        float  src_height (0),
        float  gamma (2.2)
        bool   center (true),
        bool   lsb (false),
        string cplace (undefined),
        int    bkgcolor (undefined)
)

Converts a Y'CbCr or Y clip to sRGB for display on a computer. The purpose of this function is to be as simple as possible. Some clip characteristics are automatically detected but may be overriden if necessary.

The function first performs a conversion to gamma corrected R'G'B', then reverts the original transfer curve to get linear RGB values, scales the clip to its final resolution possibly using a non-ringing resize, and finally applies the sRGB transfer curve.

The function is well suited for screen captures. Similarly, this is recommended for enlarging SD pictures for previewing instead of the built-in pointresize-style zoom in video applications.

src
The clip to display.
debug
Overlays debug information if set to 1.
lsb_in, matrix, tv_range, chromak
These parameters are passed to the Dither_convert_yuv_to_rgb function called internally.
w, h
Display size of the clip. It’s possible to specify only one dimension. In this case, DAR and PAR information are used to compute the other dimension. If both dimensions are specified and if the PAR is available, pillarboxing or letterboxing may be used to satisfy the requirements.
kernel, taps, src_left, src_top, src_width, src_height, cplace
These parameters are passed to the Dither_resize16 function called internally.
noring
In case of resizing, indicates that a non-ringing algorithm must be used. Default kernel is set to "spline64" for non-ringing algorithms and "spline36" for normal resizing.
precrop
When this flag is set, if 1. the clip is detected as SD (Standard Definition) and 2. PAR or display height only is specified, the source is automatically cropped to the active zone (704 pixels)
autopar
Allows the function to automatically select a PAR, referring to standardized picture sizes and other information like the DAR.
par
Decimal value for PAR (Pixel Aspect Ratio, a.k.a. Sample Aspect Ratio). Depending on the other parameters, the clip may be resized for square pixel display.
parnum, parden
Numerator and denominator for PAR specification in form of a fraction. You cannot set both the PAR as a fraction and as decimal.
dar
Decimal value for DAR (Display Aspect Ratio). Depending on other parameters, this allows the function to display the clip in square pixels in case of anamorphic storage. 1.778 and 1.333 are fine for 16:9 and 4:3 DAR.
darnum, darden
Numerator and denominator for DAR specification in form of a fraction. You cannot set both the DAR as a fraction and as decimal.
gamma
Sets the gamma for target display. A gamma of 2.2 (default) is recommended for common practical viewing conditions in an office (200–300 lx ambiant light), 2.3 for viewing conditions specified by the sRGB standard (64 lx ambiant light), and 2.4 for studio conditions with a reference display.
center
Indicates that clipping, pillarboxing or letterboxing should be centered. Otherwise, the top-left corner of the picture is preserved.
lsb
When true, the output is in the stack16 RGB32 format.
bkgcolor
Color value for the added borders, black is the default. It works like the color parameter in AddBorders(). It depends on the colorspace and possibly the value range (TV or full).

Category: script.

Dither_quantize

Dither_quantize (
        clip  src,
        int   bitdepth,
        bool  reducerange (false),
        int   mode,
        float ampo,
        float ampn, 
        int   pat,
        bool  dyn,
        bool  prot,
        clip  mask,
        float thr,
        bool  interlaced,
        int   y,
        int   u,
        int   v,
        bool  staticnoise
)

Dither a clip to a given bitdepth. It’s possible to keep the resulting clip at the initial bitdepth of 16 or to reduce it to the specified depth.

To encode a clip in 10 bits using x264, set bitdepth=10 and reducerange=true, followed by Dither_out and set --input-depth 10 in the x264 parameters.

NB: Dither_quantize is known to be slightly buggy when the dither amplitude is greater than unity (ampo + ampn > 1). In this case, there is a risk of getting some artefacts in the result. When reducing to 10 bits, it affects a small range of pixel values below any multiple of 16 (on a 8-bit scale). Keeping ampo + ampn <= 1 shouldn’t create any noticeable artefact.

src
Clip to dither. Must be in stack16 format.
bitdepth
Desired bit depth, in range 8–14.
reducerange
Indicates if the output value range must be reduced. Even if reduced, the output clip is still in the regular stack16 format.
mode, ampo, ampn…
The other parameters are the same as in DitherPost.

Category: script.

Dither_out

Dither_out (
        clip src,
        bool bigendian (false)
)
Dither_convey_yuv4xxp16_on_yvxx (
        clip src,
        bool bigendian (false)
)

This function allows Avisynth to output 16-bit YUV pixel components. This is achieved by sending fake YV12 data, containing actually yuv420p16 data. Frame serving should be done via a rawvideo pipe, so the encoding application relies on information provided by the user, not Avisynth directly.

Dither_convey_yuv4xxp16_on_yvxx is the same as Dither_out and remains for compatibility purpose.

This function works only on 16-bit stacked clips.

src
Stack-16 YUV data to encode.
bigendian
Indicates that the output stream is big endian (MSB-LSB order, yuv4xxp16be instead of yuv4xxp16le).

Category: plugin.

Notes

This can be done this way with avs2yuv and 10-bit x264:

avs2yuv -raw "script.avs" -o - | x264-10bit --demuxer raw --input-depth 16
                        --input-res 1280x720 --fps 24 --output "out.mp4" -

This is actually a single line which has been split for convenient display. Note the minus sign at the end of the line. Of course, you’ll have to change and specify FPS, video resolution and interlacing information. Don’t do any further pixel processing after having called this function. Be sure to use the raw video trick for encoding, otherwise you’ll only get garbage.

To encode 4:4:4 10-bit video, you’ll need to add both --input-csp i444 and --output-csp i444 to the x264-10bit command line.

It’s also possible to dither to the exact target bitdepth. Before calling the function, you can add this little code snippet, here for a bitdepth of 10:

a = Dither_get_lsb ()
b = Dither_get_msb ()
c1 = a.mt_lut ("x 6 >>",        y=3, u=3, v=3)
c2 = a.mt_lut ("x 2 << 255 &u", y=3, u=3, v=3)
DitherPost (c1, c2)     # Add the mode you want and other parameters here
mt_lut ("x 6 <<", y=3, u=3, v=3)
StackVertical (b, last)
Dither_out ()

Dither_convey_rgb48_on_yv12

Dither_convey_rgb48_on_yv12 (
        clip r,
        clip g,
        clip b,
        bool bigendian (false)
)

This function provides the same kind of functionnality as Dither_out, but spits RGB48 pixels instead of YUV.

This function works only on 16-bit stacked clips.

r, g, b
Three YUV stack16 clips containing the red, green and blue channels in their luma plane.
bigendian
Indicates that MSB must be stored before the LSB (rgb48be instead of rgb48le).

Notes

Here is a command line to pipe the result to ImageMagick:

avs2yuv -raw "script.avs" -o - | convert -depth 16 -size 1280x720 rgb:- "out-%06d.png" 

The same with FFmpeg, although current releases don’t support completely the RGB48 reading and round the data to 8 bits:

avs2yuv -raw "script.avs" -o - | ffmpeg -f rawvideo -vcodec rawvideo -pix_fmt rgb48le
                             -s 1280x720 -aspect 1:1 -y -i - -f image2 "out-%06d.png"

This is actually a single line which has been split for convenient display.

Category: script.

Dither_removegrain16

Dither_removegrain16 (
        clip src,
        int  mode (2),
        int  modeU (mode),
        int  modeV (modeU)
)

This is the 16-bit equivalent of the RemoveGrain plug-in. It applies various kinds of smoothing to the input clip by combining each pixel with its 8 neighbours. As in the original RemoveGrain, the borders rows and columns (1-pixel thick) are not processed.

mode
The smoothing mode. It can apply to all the planes or to the Y plane only, depending on the values of modeU and modeV. All the RemoveGrain modes have not been ported yet. The available ones are listed below.
-1
The plane is not touched at all and may contain garbage on output.
0
The plane is copied without being processed.
1
Clips the pixel with the minimum and maximum of the 8 neighbour pixels.
2
Clips the pixel with the second minimum and maximum of the 8 neighbour pixels.
3
Clips the pixel with the third minimum and maximum of the 8 neighbour pixels.
4
Clips the pixel with the fourth minimum and maximum of the 8 neighbour pixels, which is equivalent to a median filter.
11
[1 2 1] horizontal and vertical kernel blur. Similar to Blur(1).
12
Same as mode 11.
19
Replaces the pixel with the average of its 8 neighbours.
20
Averages the 9 pixels ([1 1 1] horizontal and vertical blur). Similar to Blur(1.58).
modeU, modeV
Same as mode but for U and V planes. If not defined, they use the same value as mode.

Category: plug-in.

Dither_repair16

Dither_repair16 (
        clip src1,
        clip src2,
        int  mode (2),
        int  modeU (mode),
        int  modeV (modeU)
)

This is the 16-bit equivalent of the Repair plug-in. It can repair the artifacts generated by a processing by applying a RemoveGrain-like treatment on the input clip to fix the ouput clip.

src1
The clip to repair.
src2
The reference clip. Must have the same format as src1.
mode
The repairing mode. It can apply to all the planes or to the Y plane only, depending on the values of modeU and modeV. All the Repair modes have not been ported yet. The available ones are listed below. These modes are similar to the RemoveGrain modes but include the center pixel of the reference clip for min/max calculation.
-1
The plane is not touched at all and may contain garbage on output.
0
The plane is copied without being processed.
1–4
Clips the source pixel with the Nth minimum and maximum found on the 3×3-pixel square from the reference clip.
11–14
Same as modes 1–4 but uses min(Nth_min, c) and max(Nth_max, c) for the clipping, where c is the value of the center pixel of the reference clip.
modeU, modeV
Same as mode but for U and V planes. If not defined, they use the same value as mode.

Category: plug-in.

Dither_median16

Dither_median16 (
        clip src,
        int  rx (1),
        int  ry (1),
        int  rt (0),
        int  ql (undefined),
        int  qh (undefined),
        int  y,
        int  u,
        int  v
)

This filter performs quantile clipping, and more specifically can work as a median filter. The temporal component is currently not implemented and the filter is quite slow (not optimised at all).

rx, ry
Horizontal and vertical radius of the workarea. The middle pixel value is clipped by the lower and higher quantiles found in the defined group of pixels. With rx = 2 and ry = 3, the input area is 5×7 pixels.
rt
Temporal radius. Not used currently. Keep it to 0.
ql, qh
Low and high clipping quantiles. The filter chooses two pixels defined by their rank in the group of neighbours. Let’s call vl and vh the values corresponding to the ql-th and qh-th ranks. Pixel values outside the vl to vh range are clipped. ql and qh must be positive or null and less than (rx×2 + 1) × (ry×2 + 1) × (rt×2 + 1). Also, ql = qh. If these parameters are set to a negative value or undefined, they are internally set to the middle of the range, performing a median filtering.

Category: plug-in.

DitherTestPatterns

DitherTestPatterns (
        int size (192),
        int mag (1),
        int amp (1),
        int len (24),
        int luma (128)
)

Shows all the dithering patterns in the same picture.

size
Width in pixels of a single test pattern.
mag
Magnification factor, > 0. Global picture size is unchanged. Recommended value: 3.
amp
Amplification factor, > 0. Useful to actually see the patterns without hurting your eyes. Recommended value: 32.
len
Number of frames to generate, > 0.
luma
Average luma value used for the tests (0–255).

Category: script.

Dither1Pre, Dither2Pre

Dither1Pre (
        clip   m,
        string flt ("dfttest (sigma=64)"),
        bool   stacked (true),
        float  overlap (0.5),
        bool   tvopt (false)
)
Dither2Pre (
        clip   m,
        string flt ("dfttest (sigma=256)"),
        bool   stacked (true),
        float  overlap (0.5),
        bool   tvopt (false)
)

Filters a 8-bit clip and outputs the result with 1 or 2 extra bits of accuracy. This function allows using 8-bit denoisers which have not been modified to support stack16 format.

The MSB part is stacked onto the LSB part. They can be separated later into two clips using the utility functions. You can also choose to interleave the MSB and the LSB data instead of stacking them on the same frame.

This function works by splitting the picture histogram in slices of equal width, stretching the slices to the full range, filtering them and recombining them all into a higher bitdepth clip. The stretch scale is x2 for Dither1Pre and x4 for Dither2Pre. In order to ensure the continuity, the slices are overlapped. 3 slices are used for 1 extra bit, and 7 slices for 2 extra bits (50 % overlap). Compared to the normal CPU load of the provided filter, computation times are multiplied respectively by 3 and 5. It is possible to change the overlap amount to save CPU.

Because of this histogram split, keep any motion compensation code out of the function. Just provide a raw filter here. As another consequence of the split, only filters processing the luma and chroma planes independently will work correctly. Fortunately, most of them do. Filters internally converting pixels to RGB or doing similar things will likely fail.

Note that these functions are dirty hacks. First, they are not efficient, because they have to run multiple times the specified noise filter. Also, the slicing may introduce artifacts, depending on the behavious of the specified filter. It is strongly recommended to use a modified denoiser to generate the 16-bit data instead of DitherNPre. Use these functions only when there is no other way to achieve the desired filtering.

If you are using MT, additionnaly to the splitvertical=true requirement, you must be aware that stacked=false in this case may lead to temporal artifacts for some unknown reason (thanks to Dogway on the Doom9 forum for investigating all these issues). Correct example:

MT ("""Dither1Pre (flt="tnlmeans()")""", 2, 2, true)
m
The original, noisy clip.
flt
An optional string containing the filter command. You can insert double quotes (") in the parameters with Chr(34) sequences. Beware: filter parameters must be set according to their new input range. In Dither1Pre, all amplitude-relative parameters must be doubled, and powers quadrupled. In Dither2Pre, all amplitudes are quadrupled and powers multiplied by 16. Spatial and temporal values can be left unchanged.
stacked
Indicates that the MSB and LSB data must be vertically stacked instead of being interleaved.
overlap
The slice overlap rate. The greater, the lower the risk of artifacts. The required number of slices is deduced from the overlap rate parameter. Overlap ranges from 0 (no additional slice) to 0.5 (50 % overlap, number of slices almost doubled). When tvopt is false, the minimum number of additional slices is restricted to one instead of zero.
tvopt
Can increase the actual overlap for a fixed number of slices in presence of TV-scale values (luma in the 16–235 range, and chroma in 16–240) by reducing the slice covering to the visible range. This means super blacks and super whites are clipped. The option is useful with small overlap rates.

Category: script.

Utility functions

Dither_get_msb, Dither_get_lsb

Dither_get_msb (clip src)
Dither_get_lsb (clip src)

Extracts the MSB or the LSB from the stacked 16-bit frame src.

Category: script.

Dither_gen_null_lsb

Dither_gen_null_lsb (clip src)

Generates a LSB clip set to 0 for the non-stacked src clip, which can be a MSB or a standard 8-bit clip.

Category: script.

Dither_convert_8_to_16

Dither_convert_8_to_16 (clip src)

Converts the 8-bit src clip into a 16-bit stacked clip. For the inverse operation, just call DitherPost (mode=-1).

Category: script.

Dither_crop16

Dither_crop16 (
        clip src,
        int  left,
        int  top,
        int  width,
        int  height,
        bool align
)

Crops a 16-bit stacked clip. Coordinates are related to the real picture (half-height). Parameters are the same as the Avisynth Crop function.

Category: script.

Dither_addborders16

Dither_addborders16 (
        clip src,
        int  left,
        int  top,
        int  right,
        int  bottom,
        int  color_yuv (undefined)
        int  color (undefined)
)

Add borders to a 16-bit stacked clip. Coordinates are related to the real picture (half-height).

left, top, right, bottom
Border sizes, same as the Avisynth AddBorders function.
color_yuv, color
Filling color. Default is black, in TV-range. Actually you can use both value whatever the colorspace (color_yuv is left only for backward compatibility).

Category: script.

Dither_lut8, Dither_lutxy8, Dither_lutxyz8

Dither_lut8 (
        clip   src,
        string expr ("x"),
        string yexpr (undefined),
        string uexpr (undefined),
        string vexpr (undefined),
        int    y (3),
        int    u (1),
        int v (1)
)
Dither_lutxy8 (
        clip   src1,
        clip   src2,
        string expr ("x"),
        string yexpr (undefined),
        string uexpr (undefined),
        string vexpr (undefined),
        int    y (3),
        int    u (1),
        int    v (1)
)
Dither_lutxyz8 (
        clip   src,
        clip   src2,
        clip   src3,
        string expr ("x"),
        string yexpr (undefined),
        string uexpr (undefined),
        string vexpr (undefined),
        int    y (3),
        int    u (1),
        int    v (1)
)

These functions are the equivalent of the Masktools mt_lut, mt_lutxy and mt_lutxyz functions. Here, they generate 16-bit data from 8-bit clips. The output of the final function is rounded to the nearest integer and clipped into the [0; 65535] range. The result is stored into a 16-bit stacked clip.

If y, u or v are defined to 2, 4 or 5 (copy plane from the Nth clip), the plane is converted to 16-bit with a null LSB.

Please refer to the Masktools documentation for more information about these functions.

Category: script.

Dither_lut16

Dither_lut16 (
        clip   src,
        string expr ("x"),
        string yexpr (undefined),
        string uexpr (undefined),
        string vexpr (undefined),
        int    y (3),
        int    u (1),
        int    v (1)
)

This works like the Masktools mt_lut, excepted that both input and output are 16-bit values.

Category: script.

Dither_add16, Dither_sub16

Dither_add16 (
        clip src1,
        clip src2,
        bool wrap (false),
        int  y (3),
        int  u (3),
        int  v (3),
        bool dif (false)
)
Dither_sub16 (
        clip src1,
        clip src2,
        bool wrap (false),
        int  y (3),
        int  u (3),
        int  v (3),
        bool dif (false)
)

Adds or subtract two 16-bit clips, pixel per pixel, plane per plane.

Dither_sub16(dif=true) is the 16-bit equivalent to mt_makediff().Dither_add16(dif=true) is the 16-bit equivalent to mt_adddiff().

wrap
Indicates if the value should wrap in case of overflow instead of being clipped in 0–65535.
dif
Indicates that src2 is considered as a "difference" clip, 32768 (128 * 256) being the neutral value. The actual operation is src1 + src2 - 32768 (add) or src1 - src2 + 32768 (sub).

Category: dll.

Dither_max_dif16

Dither_max_dif16 (
        clip src1,
        clip src2,
        clip ref,
        int  y (3),
        int  u (3),
        int  v (3)
)

Compares pixel per pixel src1 and src2 to ref and takes the pixel with the greatest amplitude difference.

Category: dll.

Dither_merge16, Dither_merge16_8

Dither_merge16 (
        clip src1,
        clip src2,
        clip mask,
        int  y (3),
        int  u (2 or 3),
        int  v (2 or 3),
        bool luma (false)
)
Dither_merge16_8 (
        clip src1,
        clip src2,
        clip mask,
        int  y (3),
        int  u (2 or 3),
        int  v (2 or 3),
        bool luma (false)
)

These functions work like the Masktools’ mt_merge. The output is a blend between src1 and src2, depending on each mask pixel values. The bigger the mask value, the more the second clip will be taken into account.

All clips are 16-bit stacked. With Dither_merge16_8, mask is a regular 8-bit clip.

The default value for u and v are 2 (copy plane from src1) excepted when luma = true. In this case, chroma is always processed.

Category: Dither_merge16: dll, Dither_merge16_8: script.

Dither_y_gamma_to_linear, Dither_y_linear_to_gamma

Dither_y_gamma_to_linear (
        clip   src,
        bool   tv_range_in (true),
        bool   tv_range_out (true),
        string curve ("srgb"),
        int    y (3),
        int    u (3),
        int    v (3),
        float  gcor (1.0)
)
Dither_y_linear_to_gamma (
        clip   src,
        bool   tv_range_in (true),
        bool   tv_range_out (true),
        string curve ("srgb"),
        int    y (3),
        int    u (3),
        int    v (3),
        float  gcor (1.0)
)


Dither_y_gamma_to_linear converts the luma channel to linear light, and Dither_y_linear_to_gamma converts back a clip to gamma-corrected luma. Chroma channels remain untouched.

This function works only on 16-bit stacked clips.

Note: usually gamma compression applies to RGB channels, not Y’CbCr. Therefore this function should be used with RGB48Y clips, obtained from Dither_convert_yuv_to_rgb for example.

clip
The clip to be converted.
tv_range_in
Specifies if the luma range is 16-bit TV (16*256 to 235*256 inclusive) or full range (false)
tv_range_out
Same, but for output.
curve
Type of gamma mapping. Possible values:
"709" ITU-R BT.709 transfer curve for digital video
"601" ITU-R BT.601 transfer curve, same as "709"
"170" SMPTE 170M, same as "709"
"240" SMPTE 240M (1987)
"srgb" sRGB curve
"2020" ITU-R BT.2020 transfer curve, for 12-bit content. For sources of lower bitdepth, use the "709" curve:
Transfer.png
gcor
Gamma correction, applied on the linear part.

Category: script.

Dither_add_grain16

Dither_add_grain16 (
        clip  src,
        float var (1),
        float uvar (0),
        float soft (1),
        int   maxts (5),
        bool  replace (false),
        bool  lsb_in (true),
        int   seed (undefined)
)

Generates and adds 16-bit grain to a clip, with optional temporal stabilization. The output is always a stack16 clip.

var
Standard deviation of the luma noise. = 0.
uvar
Standard deviation of the chroma noise. = 0.
soft
Noise temporal stability. This is actually the regeneration period of the noise, in frames. Set to 100 or above, the grain becomes static.
maxts
Maximum radius for the temporal softening of the noise, in frames. Larger radii smooth very slow grain with a higher quality, but they are more resource-demanding.
replace
Set to true, the noise is generated on a mid-grey clip instead of being added to the src clip. The new clip has the same properties as the source clip.
lsb_in
Indicates that the input clip is stack16.
seed
If defined and not negative, forces a seed for the random number generator used in grain generation. This ensures that the produced grain remains the same each time the script is executed.

Category: script.

Troubleshooting

The resulting picture appears to be cut at half height.

You surely applied DitherPost twice, or use it on a regular 8-bit clip. Please check your script. Apply DitherPost only on 16-bit clips generated by the modified plug-ins with lsb=true or by the other dedicated functions outputing 16-bit stacked data.

GradFun3 and some other functions always output a green screen.

You surely have an old Masktools 2 version installed somewhere and autoloaded by Avisynth. Search on your disks the filenames mt_masktools.dll, mt_masktools-25.dll and mt_masktools-26.dll. Remove the culprits and install the latest Masktools 2 version from there.

Still not working? Remove all the mt_masktools dll you can found. If you did it well, running your script must make Avisynth complain about missing masktools function. If this is not the case, search again, there is a masktool file hidden somewhere in your filesystem.

Error message — Script error: dfttest does not have a named argument "lsb"

Remove your dfttest.dll and install the modified one, contained in this package.

Error message — RemoveGrain: invalid mode ##

Your RemoveGrain version is too old. Remove RemoveGrain*.dll, Repair*.dll and SSE?Tools.dll and install the version 1.0b "beta" from there, but do not copy the SSE3 files. This is not the latest version, but the most compatible with all the existing scripts around there.

Changelog

v1.23.0, 2013.08.04

  • Partial implementation of the BT.2020 color conversions. Only the non-constant luminance matrix is implemented.
  • Optimized Dither_merge16 for SSE2.
  • Fixed the radiusc type in GradFun3 (int), so it now should work correctly in Avisynth 2.6 alpha 4.
  • Fixed a bug in Dither_merge16 affecting the chroma of YV12 clips with luma=true. Thanks to tp7 for reporting these issues.

v1.22.1, 2013.01.09

  • Fixed green frame output in Dither_resize16nr for some combination of the y, u and v parameters.
  • Fixed Dither_quantize for 14-bit output. It is not perfect but much better than before.
  • Made the bitdepth parameter in Dither_quantize a named argument.
  • Fixed var and uvar scaling in Dither_add_grain16 to match better AddGrainC.

v1.22.0, 2012.12.31

  • Added temporal processing to Dither_median16.
  • Added Dither_resize16nr, a simple ringing-cancellation wrapper around Dither_resize16.
  • Added a noring parameter to conversion functions between YUV and RGB.
  • Added lsb, center and bkgcolor to Dither_srgb_display.
  • Replaced Dither_convey_yuv4xxp16_on_yvxx with Dither_out, which also works correctly with YV16 input. The old function is still there for compatibility, mapped on the new one.
  • Dither_addborders16 now works with RGB clips.
  • Badly designed and buggy resizing functionalities in Dither_srgb_display were rewritten.

v1.21.0, 2012.09.07

  • Added the seed parameter to Dither_add_grain16.
  • Reworked Dither_srgb_display for mor accurate aspect ratios and transfer characteristics, added gamma parameter.
  • Gamma transfer functions have now an optional gamma correction parameter.
  • Added Dither_median16, but slow and without temporal component at the moment.

v1.20.0, 2012.08.12

  • Added Dither_removegrain16 (modes 1–4, 11, 12, 19 and 20 only) and Dither_repair16 (modes 1–4 and 11–14 only).
  • Added threshold, radius and elasticity settings for chroma to GradFun3, as well as the usual plane filters. Better compatibility with the 4:1:1 colorspace.
  • Added Dither_sub16 and optimised Dither_add16 for SSE2.
  • Fixed a regression for 4:2:0 DV-PAL chroma placement in Dither_resize16.
  • Colorspace conversions using point-sampling for chroma are now more consistent regarding chroma placement.

v1.19.0, 2012.07.18

  • Added kernel inversion to Dither_resize16.
  • Added cropping parameters to Dither_srgb_display.
  • Fixed a bug preventing to use the 4:1:1 colorspace in some scripted functions.
  • Bug fixed in MVTools (v2.6.0.5).

v1.18.1, 2012.06.15

  • Forgot to include AVSTP 1.0.1 in the previous release.
  • The mode parameter in Dither_quantize was forgotten too…
  • Detailed a few things in the documentation.

v1.18.0, 2012.06.14

  • Added Dither_quantize to dither to bitdepths higher than 8.
  • Added Dither_srgb_display for Y’CbCr preview and accurate screen captures.
  • More meaningful error messages about wrong clip formats.
  • SmoothGrad and Dither_box_filter16 now work correctly on picture of width > 2048
  • Fixed a bug in multithreaded Dither_resize16.
  • Bug fixed in MVTools (v2.6.0.4).

v1.17.0, 2012.05.13

  • Added the YCgCo matrix in RGB conversions.
  • More dithering settings exposed in RGB conversions.
  • Fixed BT.709 coefficients.
  • Bug fixed in MVTools (v2.6.0.3).

v1.16.0, 2012.05.01

  • Added generic spline kernel to Dither_resize16.
  • Added the SMPTE 240M gamma curve and aliases for BT.601 and SMPTE 170M.
  • Fixed a bug related to chroma subsampling and multi-threading in Dither_merge16.
  • Bug fixed in MVTools (v2.6.0.2).

v1.15.0, 2012.03.23

  • Added the luma parameter to Dither_merge16 and defaulted u and v to 2 (copy) excepted when luma = true (process). This behaviour is now identical to mt_merge.
  • Added plane filtering in Dither_merge16_8. The function now internaly uses Dither_merge16 and is much faster (×20 on a 4-core CPU).
  • Added support for negative plane filter values in Dither_lut16. Thanks to 06_taro for the suggestion.
  • Set quiet = true as default in dfttest 1.9.2.
  • Fixed a bug in Dither_resize16 making it crash for some combinations of source and destination sizes.

v1.14.1, 2012.03.12

  • Bugs fixed in MVTools (v2.6.0.1).

v1.14.0, 2012.03.11

  • Multi-threading: most dither.dll functions are now multi-threaded, excepted Dither_box_filter16 and SmoothGrad (later, maybe). Some MVTools v2.6.0.0 functions support multi-threading too.
  • Fixed a bug in dfttest v1.9.1
  • Added staticnoise parameter to GradFun3.
  • Documentation revisited.

v1.13.2, 2011.12.13

  • Updated MVTools to v2.5.14.1 (bugfix)

v1.13.1, 2011.11.28

  • Updated dfttest to v1.9 and MVTools to v2.5.14.0
  • Fixed height checks in DitherPost with interlaced content.

v1.13.0, 2011.11.09

  • Added kernelh, kernelv, totalh and totalv to Dither_resize16. Please note that the custom convolution coefficients are now read in the correct order.
  • Fixed an error with the plane selectors in the Dither_lut*8 functions.
  • Updated MVTools to v2.5.13.1.

v1.12.1, 2011.10.27

  • Fixed a bug with Dither_resize16, occuring with positive values for src_left or src_top.
  • Fixed other issues in Dither_resize16, related to huge differences between vertical and horizontal resizing ratios. It’s not perfect yet, but still much better than before.
  • Dither_convert_yuv_to_rgb now supports RGB24 output colorspace.
  • Simplified Dither_crop16 for pure horizontal cropping.

v1.12.0, 2011.09.10

  • MVTools update again.

v1.11.1, 2011.09.10

  • Fixed a bug in the MVTools.

v1.11.0, 2011.09.10

  • Updated MVTools to v2.5.12.0. See the MVTools documentation for details.

v1.10.0, 2011.08.24

  • Added Dither_addborders16.
  • Added the BT 709 curve to Dither_y_gamma_to_linear and Dither_y_linear_to_gamma, as well as the plane selectors.
  • Added the possibility to have static noise in DitherPost.
  • Added Dither_add_grain16.
  • Added a dif parameter to Dither_add16.
  • Added the lsb and lsb_in parameters to GradFun3 to deal with 16-bit data. The function also accepts smaller radii than before.

v1.9.5, 2011.07.21

  • Bug fixed in Dither_resize16(), displaying green bars when SSE2 optimisations are disabled.
  • Better check of stack16 clip dimensions.

v1.9.4, 2011.07.17

  • Bug fix again in Dither_resize16().

v1.9.3, 2011.07.13

  • Fixed crashes in Dither_bilateral16() occuring with subsampling using more than 32 reference pixels. This affected GradFun3(smode=2) with radii greater than 13.
  • Fixed a mod4 check in Dither_convert_yuv_to_rgb().

v1.9.2, 2011.07.09

  • Fixed crashes and bugs in Dither_resize16().

v1.9.1, 2011.07.06

  • Improved memory usage and CPU load for the functions based on the 16-bit resizer.
  • Simplified a bit the GradFun3() detail masking.
  • Fixed a few glitches.

v1.9, 2011.06.11

  • The threshold of the detail mask in GradFun3() now automatically adjusts to the debanding threshold. This helps removing serious color banding, when band boundaries are masked because they are detected as details. Also, the radius for smode 0 has been internally reduced to make the value reflect more accurately the actual range in pixels.
  • Added an interlaced mode for DitherPost().
  • Added Dither_resize16(), a 16-bit resizer which can also work as a chained horizontal and vertical convolution engine.
  • Added y, u and v parameters to almost all the dither.dll functions. Their behaviour is the same as in masktools2.
  • Added Dither_y_gamma_to_linear() and Dither_y_linear_to_gamma(), for gamma ?? linear conversions in 16 bits.
  • Added Dither_convey_yuv4xxp16_on_yvxx() and Dither_convey_rgb48_on_yv12(), functions to export clips with 16 bits per component when Avisynth’s output is read as rawvideo via a pipe.
  • Added Dither_convert_yuv_to_rgb() and Dither_convert_rgb_to_yuv() to convert 8 or 16 bits YUV to RGB and back with dithering. It’s also possible to output RGB48 conveyed on YV12 via a rawvideo pipe.
  • Added Dither_max_dif16() to get from two clips the pixels having the maximum difference with a third reference clip.
  • Fixed an error message about wrong colorspace.
  • Bugfix: removed artifacts on flat pure white areas (luma == 255) when using error diffusion dithering (modes 6–8).
  • Non-YV12 planar Y(UV) colorspaces should now work correctly on Avisynth 2.6.0.

v1.8.1, 2011.05.28

  • Optimised Dither_bilateral16 with SSE and by introducing a subsampling parameter. Also, fixed a bug related to the use of a ref clip.
  • Added a troubleshooting section to the documentation.

v1.8, 2011.05.15

  • Dfttest has been modified to make it accept 16-bit input clips (v1.8 mod16b). It’s now possible to apply a curve on the input and the inverse curve to the output to protect dark shades for example, without resolution loss or risk of color banding.
  • Made available the two internal components of the SmoothGrad function: Dither_box_filter16 and Dither_limit_dif16.
  • Added Dither_bilateral16, a bilateral filter giving cleaner results than the box filter for gradient smoothing.
  • Improved GradFun3:
    • Better detail/edge masking with adjustable thresholds and optional mask display for debugging purpose.
    • Added two smoothing modes using the modified dfttest and the new bilateral filter. The latter is slow as hell and should be considered as experimental.
  • Added a Dither_crop16 function to properly crop stacked 16-bit clips.
  • Added a luma parameter to Dither_merge16_8 and fixed a slight chroma bug.

v1.7.1, 2011.05.11

  • Dither.avsi doesn’t use Max anymore, so it can now run on Avisynth 2.5.7 or earlier.
  • Bugfix in the modified MVTools2: the thSADC argument was ignored in MDegrain1/2/3.

v1.7, 2011.04.27

  • Slightly improved Dither1Pre and Dither2Pre functions, added the overlap and tvopt parameters.
  • People complained about GradFun3 being too strong and washing fine shades away, so I changed the default parameter values for a better match with the gradfun2db default settings. thr is set to 0.35 and radius to 12.

v1.6, 2011.04.10

  • Masktools 2 a48 is now the minimum requirement because some Dither functions use the new bitwise operators. I don’t know how to automatically detect the Masktools version, so be sure to update your Masktools before installing this Dither version.
  • The modified MVTools2 has been synchronised with the latest official release (2.5.11.2 beta)
  • Renamed the rem parameters into clsb in DitherPost and SmoothGrad functions
  • Changed the default for the stacked (now true) and prot (now false) parameters.
  • Added various utility functions, mainly Dither_lut8, Dither_lut16, Dither_add16 and Dither_merge16.

v1.5, 2010.11.07

  • Added error diffusion algorithms (Floyd-Steinberg, Stucki and Atkinson).
  • Fixed the internal noise generator, now with a better randomness.

v1.4, 2010.09.24

  • Added SmoothGrad as pre-processor to smooth the gradients before dithering.
  • Added GradFun3, a tool derived from SmoothGrad for color-banding removal.
  • Added the stacked parameter to DitherPost, for an easier use with the other functions.
  • Changed the documentation.
  • Fixed wrong output FPS in DitherPost when the input is submitted as an interleaved MSB-LSB clip.

v1.3, 2010.07.16

  • DitherPost is now a plug-in instead of a script function. Doesn’t require NoiseGenerator anymore.
  • Synchronised modified plug-ins: mvtools 2.5.10.1 and dfttest 1.8

v1.2, 2010.06.20

  • Synchronised the modified mvtools2 with the latest official release.

v1.1, 2010.05.06

  • Merged the DitherPost functions into a single one.
  • Fixed the static pattern for chroma in 1-bit dithering.
  • Strengthened the protection method and made it optional
  • Added new dithering patterns and a test function.
  • Added a masking function

v1.0, 2009.12.25

  • Initial release
Personal tools