ReduceFlicker

From Avisynth wiki
(Difference between revisions)
Jump to: navigation, search
m (Requirements: add AvsRecursion.dll)
(v0.1.1 update)
 
(8 intermediate revisions by one user not shown)
Line 1: Line 1:
{{FilterCat4|External_filters|Plugins|Restoration_filters|Luma_Equalization}}
+
{{FilterCat6|External_filters|Plugins|Plugins_x64|Restoration_filters|Luma_Equalization|Deep_color_tools}}
 
{{Filter3
 
{{Filter3
| {{Author/kassandro}}
+
|1={{Author/Chikuzen}}, {{Author/Asd-g}}
| v0.5
+
|2=v0.1.1
| [http://xhmikosr.1f0.de/_old/avisynth/plugins/ReduceFlicker_0.5.zip ReduceFlicker_0.5.zip]
+
|3=[https://github.com/Asd-g/ReduceFlicker/releases ReduceFlicker-0.1.1.7z]
| Luma Equalization   
+
|4=Luma Equalization   
| [http://www.gnu.org/licenses/gpl-2.0.txt GPLv2]
+
|5=[http://www.gnu.org/licenses/gpl-2.0.txt GPLv2]
|6=[http://videoprocessing.fr.yuku.com/topic/24/ReduceFlicker-05 VideoProcessing Thread]}}
+
|6=}}
  
 
== Description ==
 
== Description ==
The plugin contains three purely temporal filters: ReduceFlicker, ReduceFluctuation, and LockClense. As purely temporal filters both filters can be used for all kind of material, but they are particularly useful for interlaced footage or progressive videos from digicams like my Canon Powershot S1 IS. They should be applied before deinterlacing. If done so, the motion detection of the deinterlacer is fooled less by flicker, whence more detail is preserved.  
+
AviSynth 2.6 / AviSynth+ plugin to reduce temporal oscillations. This is a rewite of [[ReduceFlicker_v0.5|ReduceFlicker v0.5]] which written by Rainer Wittmann.
 +
This plugin has only <code>ReduceFlicker()</code>. <code>ReduceFluctuation()</code> and <code>LockClense()</code> are not implemented.
 +
 
 +
ReduceFlicker performs controlled averaging of a frame with its two adjacent temporal neighbors. Controlled means that averaging only takes place in the presence of oscillations. Without such a restraint the filter would create massive ghosts.
 +
 
 +
ReduceFlicker is purely a temporal filter that can be used for all kinds of material, but it is are particularly useful for interlaced footage or progressive videos from digicams like my Canon Powershot S1 IS. It should be applied before deinterlacing. If done so, the motion detection of the deinterlacer is fooled less by flicker, whence more detail is preserved.
 +
 
 +
The type of flicker, which can be removed or at least reduced with ReduceFlicker, is more prevalent in camcorder material and the chroma of analog clips, especially clips captured from VHS tapes. In other words ReduceFlicker is suited for removing or reducing certain kinds of electronic noise, but it has virtually no effect on dust and film grain.  
 
<br>
 
<br>
 
<br>
 
<br>
 +
 
== Requirements ==
 
== Requirements ==
* AviSynth 2.5.8 or later
+
* [x86]: [[AviSynth+]] or [http://sourceforge.net/projects/avisynth2/ AviSynth 2.6]
* Supported color formats: [[RGB32]], [[RGB24]], [[YUY2]], [[YV12]]
+
* [x64]: [[AviSynth+]]
 +
* Supported color formats: [[Y8]], [[YV12]], [[YV16]], [[YV24]], [[YV411]]
 +
**AviSynth+: all [[planar]] Y and YUV(A) formats (8/10/12/14/16/32-bit) are supported.
 
<br>
 
<br>
* [[SSE2]] or [[SSE3]] capable CPU
+
* [https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads Microsoft Visual C++ 2019 Redistributable Package (x86 / x64)]
* [http://www.microsoft.com/en-us/download/details.aspx?id=8328 Microsoft Visual C++ 2010 Redistributable Package (x86)]
+
:<span style="color:red">***</span> <tt>vcredist_x86.exe</tt> is required for <tt>ReduceFlicker-x86</tt>
* [http://wayback.archive.org/web/20150708165546/http://www.avsrecursion.de.tf/ AvsRecursion.dll]
+
:<span style="color:red">***</span> <tt>vcredist_x64.exe</tt> is required for <tt>ReduceFlicker-x64</tt>
 
<br>
 
<br>
 +
 
== [[Script variables|Syntax and Parameters]] ==
 
== [[Script variables|Syntax and Parameters]] ==
 
+
:{{Template:FuncDef|ReduceFlicker (clip, int "strength", bool "aggressive", bool "grey", int "opt", bool "raccess", bool "luma")}}
===Reduce Flicker===
+
ReduceFlicker performs controlled averaging of a frame with its two adjacent temporal neighbours. Controlled means that averaging only takes place in the presence of oscillations. Without such a restraint the filter would creat massive ghosts. To explain the algorithm in more detail, let c be the luma value of a pixel, p1, p2,p3 its temporal predecessors and n1,n2,n3 its temporal successors. Thus the values are observed in the sequence p3,p2,p1,c,n1,n2,n3. Then ReduceFlicker(strength=1) calculates d = |c - p2|,  a = max(c, min(p1, n1) - d), b = min(c, max(p1, n1) + d) and clips the average (p1 + n1 +2*c)/4 at a,b, i.e. c is replaced by max(b, min((p1 + n1 +2*c)/4, a)). Note that we always have a > = c > = b and that always either a = c or b= c. When  |n1 -n2| or d= |c - p2| is large then we even have a = b = c. To illustrate the above formulas, let us look at some examples. The input sequence 10, 20, 10, 20, 10, 20 is converted into 10,20,15,15,15,20. The first two and the last value remain unchanged, while in the middle the oscillations are averaged away. This was the ideal case. If we have the less regular 11,21, 9, 20, 12, 19 then ReduceFlicker yields 11,21,15,15,16,19. On the other hand 11,13,9, 20,12,19 yields 11,13,9,19,16,19. The third and the fourth member are changed very much, because there is not enough oscillation. If strength > 1 only the value of d is changed it may become smaller. More precisely we have d = min(|c - p2|,  |c - n2|) if strength = 2 and d = min(|c - p2|,  (|c - p3|,  |c - n2|,  |c - n3|) ). From the above definition of a and b it follows that the clipping band gets smaller as the value of d increases. Thus as d gets larger, averaging is reduced more and more. The clipping band spanned by a and b also gets smaller if |min(p1, n1) - max(p1, n1)| = |p1 - n1| gets larger, whence ReduceFlicker only generates significant averaging if d and |p1 - n1| are small. In other words the value of a pixel has to alternate three times within a sequence of four frames to get averaged, if strength = 1,2 and within a sequence of five frames if strength = 3. This is the key idea, which evolved from a long thinking process about flicker. So far we have described ReduceFlicker if aggressive=false. If aggressive=true, then the important correction term d in the definition of a and b, which is very important to prohibit artifacts, is replaced by two smaller terms. If strength=1 and aggressive=true, then we define d1 = max(0, p2 - c), d2 = max(0, c - p2), a = max(c, min(p1, n1) - d1), b = min(c, max(p1, n1) + d2). Note that d = d1 + d2 and that either d1=0 or d2=0. Similarly, if strength=2 and aggressive= true, then we define d1 = max(0, min(p2 - c, n2 - c)), d2 = max(0, min(c - p2, c - n2)), and if strength=3 and aggressive= true, then we define d1 = max(0, min(p2 - c, n2 - c, p3 - c, n3 - c)), d2 = max(0, min(c - p2, c - n2, c - p3, c - n3)). We do not recommend to combine strength=3 with aggressive=true.
+
 
+
The type of flicker, which can be removed or at least reduced with ReduceFlicker, is more prevalent in camcorder material and the chroma of analog clips, especially clips captured from VHS tapes. In other words ReduceFlicker is suited for removing or reducing certain kinds of electronic noise, but it has virtually no effect on dust and film grain.
+
 
+
Unlike most other purely temporal filters like the "cheap" ReduceFluctuation filter below, ReduceFlicker doesn't impose any limitation on the amount of change. Theoretically this bears a substantial artifact risk. The worst case scenario for ReduceFlicker is a lamp which is turned on and off 25 times per second within a PAL video. Obviously this is not very natural and quite rare. It is more natural if a regular pattern, like a fence, is moving at a constant speed within a video. If the spatial properties of this pattern fits well to its speed, then this pattern gets blurred by ReduceFlicker. However, the likelihood of such a "fit" is extremely low if strength = 1,2. It is far higher, but still tolerable,  if strength =3. It can be nicely compared with the physical phenomenon of resonance. We all learn at school, that if a large group of soldiers marches in step over a bridge, the bridge may crash. While theoretically possible, I never heart about such an event, because the step frequency and the resonance frequency of the bridge, which depends on its size, have to be very close.
+
<br>
+
<br>
+
:{{Template:FuncDef|ReduceFlicker (clip, int "strength", bool "aggressive", bool "grey", bool "planar")}}
+
 
<br>
 
<br>
 
::{{Par2| |clip| }}
 
::{{Par2| |clip| }}
:::Input clip.
+
:::Input clip; must be planar YUV.
 
<br>
 
<br>
 
::{{Par2|strength|int|2}}
 
::{{Par2|strength|int|2}}
:::With the "strength" variable (default=2) one can specify the strength of ReduceFlicker. Higher values mean more aggressive operation. Currently three values 1,2,3 are allowed for "strength".
+
:::Specify the strength of ReduceFlicker. Higher values mean more aggressive operation.
:::*ReduceFlicker(strength=1) makes use of 4 frames, the current frame, the subsequent frame and the two predecessors. Consequently, the first two frames and the last frame are left unchanged, because not all three neighbours are available for these frames.  
+
:::*1 : makes use of 4(current + 2*previous + 1*next) frames.
:::*ReduceFlicker(strength=2) uses 5 frames, the current frame, the two successors and the two predecessors.  
+
:::*2 : makes use of 5(current + 2*previous + 2*next) frames. (default)
:::*ReduceFlicker(strength=3) uses 7 frames, the current frame, the three successors and the three predecessors. Increasing "strength" makes ReduceFlicker more aggressive and slower.  
+
:::*3 : makes use of 7(current + 3*previous + 3*next) frames.
 
<br>
 
<br>
 
::{{Par2|aggressive|bool|false}}
 
::{{Par2|aggressive|bool|false}}
:::Beginning with version 0.5 the boolean variable "aggressive" (default value = false) has been introduced. If aggressive=true, then a significantly more aggressive variant of the algorithm is selected (the speed is the same as with aggressive=false).  
+
:::If set to true, then a significantly more aggressive variant of the algorithm is selected.  
 
<br>
 
<br>
 
::{{Par2|grey|bool|false}}
 
::{{Par2|grey|bool|false}}
:::If grey=true (false is the default value), then only the luma plane is processed. The other planes contain random garbage. Thus the internal filter [[GreyScale]]() has to be applied later. The variable "grey" is only used for planar color spaces.
+
:::Whether chroma planes will be processed or not. If set to true, chroma planes will be garbage.
 
<br>
 
<br>
::{{Par2|planar|bool|false}}
+
::{{Par2|opt|int|}}
:::If you use planar YUY2, RGB24, RGB32, then you have to set "planar=true" (false is the default value).  
+
:::Controls which cpu optimizations are used.
 +
:::Currently, this filter has three(C++, SSE2 and AVX2) routines.
 +
:::*0 : Use C++ routine.
 +
:::*1 : Use SSE2 routine.
 +
:::*Others (default) : Use AVX2 routine if possible.
 +
::::*If your machine does not have AVX2, fallback to 1.
 
<br>
 
<br>
===ReduceFluctuations===
+
::{{Par2|raccess|bool|true}}
ReduceFluctuations is just a limited version of the very simple filter Clense (cf. RemoveGrain). In fact, it is a combination of Clense and the filter LimitChange from the SSETools plugin. It is slightly slower than Clense but significantly faster than the combination of Clense and LimitChange. Because Clense can be very destructive, limitation is absolutely necessary and the values for limit, limitU, limitV, limitA should never be > 10. Even the default value 5 may be too big.  
+
:::When the previous and next frames are accessed.
 +
:::*True (default) - the next frames are accessed first.
 +
:::*False - the previous frame are accessed first.
 
<br>
 
<br>
 +
::{{Par2|luma|bool|true}}
 +
:::Whether luma plane will be processed or not. If set this to false, luma plane will be garbage.
 +
:::Default value is true.
 
<br>
 
<br>
:{{Template:FuncDef|ReduceFluctuations(clip, clip "previous", clip "next",  int "limit", int "limitU", int "limitV", int "limitA", int "recursive", bool "planar")}}
+
==Examples==
<br>
+
ReduceFlicker with default settings:
::{{Par2| |clip| }}
+
:::Input clip.
+
<br>
+
::{{Par2|previous|clip| }}
+
::{{Par2|next|clip| }}
+
:::Optional clips, works the same as Clense.
+
<br>
+
::{{Par2|limit|int|5}}
+
::{{Par2|limitU|int|limit}}
+
::{{Par2|limitV|int|limitU}}
+
::{{Par2|limitA|int|255}}
+
:::With the variable "limit" (default = 5) one can specifiy the maximum amount of change of the luma. Similarily, one can specify with "limitU", "limitV" the maximum amount of change of the U and the V values. "limitU" inherits the value of "limit" as the default value and "limitV" inherits the value of "limitU" as the default value.
+
:::*If limitV > 255, then the V channels is replaced by random values.
+
:::*If limitV > 255 and limitU > 255, then the entire chroma is replaced by random values. This is useful for b&w video. Of course, Greyscale() has to be applied later.
+
:::*For an RGB color space "limit"is for blue channel, "limitU" is for the green channel and "limitV" is for the red channel, but it may also be the other way round. "limitA" is the limit for the fourth channel of the RGB32 color space (it is only used, if planar = false).
+
:::*For interleaved RGB24 (i.e. planar = false)clips the values of  "limitU" and "limitV" are ignored and the value of "limit" is taken instead. This was necessary because an efficient SSE implementation is not possible with interleaved pixels of size 3.
+
<br>
+
::{{Par2|recursive|int|-1}}
+
:::ReduceFluctuations makes use of three frames, the current, the subsequent and the previous frame. Consequently, the first and the last frame are left unchanged, because only one of the neighbours is available for these frames.
+
:::If recursive>=0 (-1 is the default), then instead of the previous frame, the previously processed frame from a recursion clip is taken, if the frames are requested sequentially, as it usually happens during an encoding process and if a recursion clip is assigned later with AssignRecursionClip to the recursion slot specified with the variable "recursive". AssignRecursionClip is contained in AvsTimer For instance,
+
::::<code>input=ReduceFluctuations(recursive = 7)<br>AssignRecursionClip(input,7)<br>return input</code>
+
:::reserves the recursion slot 7 (values between 0 and 9 are allowed here) and assigns the output of ReduceFluctuation as the recursion clip for ReduceFluctuations. This was the default behaviour of ReduceFluctuations version 0.3. The following example is more sophisticated:
+
::::<code>input=ReduceFluctuations(recursive = 7).RemoveGrain(mode = 17)<br>AssignRecursionClip(input7)<br>return input</code>
+
:::Now the output of ReduceFluctuations(recursive = 7).RemoveGrain(mode = 17) is used as recursion clip. For more information about recursion see section The delay filter and AssignRecursionClip of the AvsTimer documentation.
+
<br>
+
::{{Par2|planar|bool|false}}
+
:::If you use planar YUY2, RGB24, RGB32, then you have to set "planar=true" (false is the default value).
+
<br>
+
===LockClense===
+
LockClense is essentially the implementation of an idea of Ralph Boecker. To explain how LockClense works, let c be luma of a pixel in the current frame, p be the luma of the same pixel in the previous frame and n be the luma of the same pixel in the subsequent frame. If |c - p| <= limit, then LockClense replaces c by p. Otherwise, if |c - n| <= 2*limit, then LockClense replaces c by (c + n)/2 (actually we take a more sophisticated  unbiased average). Finally, if neither |c - p| <= limit nor |c - n| <= 2*limit, then LockClense does the same as ReduceFluctuations (with the same limit). The U channel and the V channel are handled the same way, but with limitU and limitV instead of limit. If "clense= false" (true is the default value of this variable), then ReduceFluctuations is not applied. Thus in this case c remains unchanged if neither |c - p| <= limit nor |c - n| <= 2*limit. If clense= false, then LockClense has much more discontinuities, which have a negative impact on compression.  Thus we do not recommend this mode, which is similar to the DNR1 mode of the DNR2 filter. The values for limit, limitU, limitV should be <= 5 to avoid artifacts (2 is the default value).
+
  
 
+
ReduceFlicker(strength=2, aggressive=false, grey=false)
:{{Template:FuncDef|LockClense (clip, int "limit", int "limitU", int "limitV", int "limitA", bool "clense", int "recursive", bool "planar")}}
+
<br>
+
::{{Par2| |clip| }}
+
:::Input clip.
+
<br>
+
::{{Par2|limit|int|2}}
+
::{{Par2|limitU|int|limit}}
+
::{{Par2|limitV|int|limitU}}
+
::{{Par2|limitA|int|255}}
+
::{{Par2|recursive|int|-1}}
+
:::See corresponding parameters in ReduceFluctuations.
+
<br>
+
::{{Par2|clense|bool|true}}
+
:::
+
<br>
+
::{{Par2|planar|bool|false}}
+
:::If you use planar YUY2, RGB24, RGB32, then you have to set "planar=true" (false is the default value).
+
 
<br>
 
<br>
== Archived Downloads ==
+
== Changelog ==
{| class="wikitable" border="1"; width="100%"
+
Version     Date            Changes<br>
|-
+
v0.1.1      2020/09/22      - Separated SSE2 and AVX2 code.
!!width="100px"| Version
+
                              - Registered as [[MT_NICE_FILTER]].
!!width="300px"| Download
+
                              - Added support for all planar formats.<br>
!!width="300px"| Mirror
+
v0.1.0      2020/05/24      - Changes by asd-g
!!width="500px"| Comments
+
                              - Added version.
|-
+
                              - Added support for 10..32-bit.
!v0.5
+
                              - Fixed frame access when strength=2, raccess=false.
|[http://xhmikosr.1f0.de/_old/avisynth/plugins/ReduceFlicker_0.5.zip ReduceFlicker_0.5.zip]
+
                              - Added "luma" parameter.
|[http://web.archive.org/web/20150405235918/http://xhmikosr.1f0.de/_old/avisynth/plugins/ReduceFlicker_0.5.zip ReduceFlicker_0.5.zip]
+
                              - Allowed AVX2 routine for AviSynth 2.6.<br>
|Includes statically and dynamically linked [[SSE2]] and [[SSE3]] binaries compiled with MSVC2010. Dynamically linked binaries requires the [http://www.microsoft.com/en-us/download/details.aspx?id=8328 Microsoft Visual C++ 2010 Redistributable Package (x86)] to be installed. In addition, [http://wayback.archive.org/web/20150708165546/http://www.avsrecursion.de.tf/ AvsRecursion.dll] is required on your [https://www.google.com/search?q=windows+path PATH] or in the same folder with the ReduceFlicker DLL.
+
v0.0.1      2020/05/13      - Changes by asd-g
|-
+
                              - Added support for AviSynth+ v8 interface.
!v0.5
+
                              - Removed /arch:AVX2 requirement to use the AVX2 routine.<br>
|<strike>[http://home.arcor.de/kassandro/ReduceFlicker/ReduceFlicker.zip ReduceFlicker.zip]</strike>
+
v0.0.0      2016/05/05      - Initial release
|<strike>[http://web.archive.org/web/20070106122020/http://home.arcor.de/kassandro/ReduceFlicker/ReduceFlicker.zip ReduceFlicker.zip]</strike>
+
|Includes 3 binaries: one statically linked (<tt>RemoveDirtS.dll</tt>) and two dynamically linked (<tt>RemoveDirt.dll, RemoveDirtSSE2.dll</tt>). SSE2 version is recommended but unfortunately it requires the <tt>Msvcr71.dll</tt> runtime component from the very ancient Microsoft Visual C++ .NET 2003. For this reason this package is considered deprecated!
+
|-
+
!Source code
+
|[http://home.arcor.de/kassandro/ReduceFlicker/ReduceFlicker-src.zip ReduceFlicker-src.zip]
+
|[http://web.archive.org/web/20071017115341/http://home.arcor.de/kassandro/ReduceFlicker/ReduceFlicker-src.zip ReduceFlicker-src.zip]
+
|}
+
 
<br>
 
<br>
 
== External Links ==
 
== External Links ==
*[http://home.arcor.de/kassandro/ReduceFlicker/ReduceFlicker.htm ReduceFlicker.htm] | [http://web.archive.org/web/20140723074402/http://home.arcor.de/kassandro/RemoveDirt/RemoveDirt.htm Mirror] - official documentation.  
+
*[https://github.com/chikuzen/ReduceFlicker/tree/master/avisynth GitHub] - Source code repository.
 +
*[https://github.com/Asd-g/ReduceFlicker/tree/v8_interface/avisynth GitHub] - Source code repository (updated).
 
<br>
 
<br>
 
<br>
 
<br>
 
-----------------------------------------------
 
-----------------------------------------------
 
'''Back to [[External_filters#Luma_Equalization|External Filters]] &larr;'''
 
'''Back to [[External_filters#Luma_Equalization|External Filters]] &larr;'''

Latest revision as of 18:47, 26 September 2020

Abstract
Author Chikuzen, Asd-g
Version v0.1.1
Download ReduceFlicker-0.1.1.7z
Category Luma Equalization
License GPLv2
Discussion

Contents

 [hide

[edit] Description

AviSynth 2.6 / AviSynth+ plugin to reduce temporal oscillations. This is a rewite of ReduceFlicker v0.5 which written by Rainer Wittmann. This plugin has only ReduceFlicker(). ReduceFluctuation() and LockClense() are not implemented.

ReduceFlicker performs controlled averaging of a frame with its two adjacent temporal neighbors. Controlled means that averaging only takes place in the presence of oscillations. Without such a restraint the filter would create massive ghosts.

ReduceFlicker is purely a temporal filter that can be used for all kinds of material, but it is are particularly useful for interlaced footage or progressive videos from digicams like my Canon Powershot S1 IS. It should be applied before deinterlacing. If done so, the motion detection of the deinterlacer is fooled less by flicker, whence more detail is preserved.

The type of flicker, which can be removed or at least reduced with ReduceFlicker, is more prevalent in camcorder material and the chroma of analog clips, especially clips captured from VHS tapes. In other words ReduceFlicker is suited for removing or reducing certain kinds of electronic noise, but it has virtually no effect on dust and film grain.

[edit] Requirements


*** vcredist_x86.exe is required for ReduceFlicker-x86
*** vcredist_x64.exe is required for ReduceFlicker-x64


[edit] Syntax and Parameters

ReduceFlicker (clip, int "strength", bool "aggressive", bool "grey", int "opt", bool "raccess", bool "luma")


clip   =
Input clip; must be planar YUV.


int  strength = 2
Specify the strength of ReduceFlicker. Higher values mean more aggressive operation.
  • 1 : makes use of 4(current + 2*previous + 1*next) frames.
  • 2 : makes use of 5(current + 2*previous + 2*next) frames. (default)
  • 3 : makes use of 7(current + 3*previous + 3*next) frames.


bool  aggressive = false
If set to true, then a significantly more aggressive variant of the algorithm is selected.


bool  grey = false
Whether chroma planes will be processed or not. If set to true, chroma planes will be garbage.


int  opt =
Controls which cpu optimizations are used.
Currently, this filter has three(C++, SSE2 and AVX2) routines.
  • 0 : Use C++ routine.
  • 1 : Use SSE2 routine.
  • Others (default) : Use AVX2 routine if possible.
  • If your machine does not have AVX2, fallback to 1.


bool  raccess = true
When the previous and next frames are accessed.
  • True (default) - the next frames are accessed first.
  • False - the previous frame are accessed first.


bool  luma = true
Whether luma plane will be processed or not. If set this to false, luma plane will be garbage.
Default value is true.


[edit] Examples

ReduceFlicker with default settings:

ReduceFlicker(strength=2, aggressive=false, grey=false)


[edit] Changelog

Version      Date            Changes
v0.1.1 2020/09/22 - Separated SSE2 and AVX2 code. - Registered as MT_NICE_FILTER. - Added support for all planar formats.
v0.1.0 2020/05/24 - Changes by asd-g - Added version. - Added support for 10..32-bit. - Fixed frame access when strength=2, raccess=false. - Added "luma" parameter. - Allowed AVX2 routine for AviSynth 2.6.
v0.0.1 2020/05/13 - Changes by asd-g - Added support for AviSynth+ v8 interface. - Removed /arch:AVX2 requirement to use the AVX2 routine.
v0.0.0 2016/05/05 - Initial release


[edit] External Links

  • GitHub - Source code repository.
  • GitHub - Source code repository (updated).




Back to External Filters

Personal tools