View Full Version : gamut conversions through Avisynth ?
Pages :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
15]
nand chan
2nd September 2011, 16:25
yesgrey was planning to specify the meaning of the color encoding fields for a while. He hasn't had the time to do that yet.
I'd welcome an addition to the 3dlut spec with the changes you're suggesting. Hopefully yesgrey can participate? The problem is that yesgrey is in the process of moving to another country, so this is a bad time for him to extend the spec. I don't know how much time (if any at all) he will have to participate in the next couple of days/weeks.
Yeah, I've contacted him via PM and it seems like he won't have time for a few months at least.
It seems we will have to make do with ourselves for now, it's just a spec after all - not the implementation in yCMS.
In effort to get this moving forwards, I shall propose some suggested changes:
In addition to modifying the current color encoding fields, we will have to add new tags for some things. Should the space in the current header not suffice, the solution will be to increase the offset of the parameters file, which is helpfully encoded in the format itself. As such, all new tags will simply be appended to the end of the last tag, lutUncompressedSize, to maintain backwards compatibility with v1.
Encoding the input and output value ranges
Three ways I have thought of dealing with this:
Encoding the value range as enumeration of possibilities, eg. 0 = (0-255), 1 = (16-235), possibly more in the future (xvYCC?)
Encoding the lower and upper bounds as separate numbers, eg. 0 and 255 - this has the possibility of added flexibility, but it would create a situation where we have to either complicate the rendering chain further or risk creating unsupported LUTs
Encoding the lower and upper bounds as floating point numbers, relative to the maximum for that bit-depth, eg. 0.0627 and 0.922 for 16-235 (as relative to 255). While this may seem like an ideal solution in practice, and required if we are to use 32-bit floating point LUTs, it will also complicate the rendering chain and possibly add inaccuracies.
I'm personally leaning towards either options 1 or 3, the latter because it offers the greatest flexibility, and the former because it's the easiest to work with, especially if you don't want to add the conversion logic and simply want to detect whether a LUT is 16-235 (and reject it otherwise, like madVR does).
Color Encoding field
Given that the current color encoding value of 0 represents BGR, in both value order and enumeration order, we can introduce the value of 1 for YCbCr and the value of 2 for RGB. If the value is 2, the values would simply be flipped around, meaning that the offset would now be (b<<(inputBitDepth[1]+inputBitDepth[0])+g<<(inputBitDepth[0])+r)*3, and so forth.
If this is too contrived or seems unnecessary, it could also be simply limited to 0 and 1.
Color space encoding
This tag will be a strictly optional, with 0 for every value meaning “disabled” or “unknown”. Some things we would have to take care of:
Encoding the red point, green point, blue point and white point of RGB data
Potentially encode the conversion constants for YCbCr output, but this alone will not remove color space ambiguity
A simple method would be to introduce the following fields:
float primaryRedX
float primaryRedY
float primaryGreenX
float primaryGreenY
float primaryBlueX
float primaryBlueY
float primaryWhiteX
float primaryWhiteY
Another possibility would be to encode the values using doubles.
File compression:
We will probably have to make a trade-off here between compression quality and decompression speed, as waiting a few seconds to decompress the LUT when starting playback might be more of a trade-off than it's worth, especially with increasing hard drive sizes.
In effort to measure the gain, I have performed some test compressions on the .3dlut which I use for daily viewing, sorted by size:
Original size: 100 MB
.bz2: 83.59 MB
.gz: 77.66 MB
.zip (normal): 75.84 MB
.rar (fastest): 66.42 MB
.rar (fast): 64.34 MB
.7z (LZMA): 34.61 MB
.rar (normal): 7.35 MB
Gamma
Another thing that might be useful to store is the input/output gamma transfer functions, but I don't know where this would truly be necessary.
XYZ output and PCS
Finally, in effort to get the power of 3dluts closer to something like ICC profiles, we could perhaps allow a PCS such as XYZ as an acceptable output color encoding, that way you could generate two RGB -> PCS LUTs and link them using implementation specific logic to form a single RGB -> RGB LUT.
On the matter of backwards compatibility (for tools and implementations):
To indicate the presence and/or alterations of these fields, the “fileVersion” shall be updated to 2. Should a program supporting version 2 encounter a version 1 LUT, the appropriate backup response shall be to ignore the ColorEncoding fields and draw information from the parameters file as currently. Similarly, if creating a v1 YCbCr LUT, the field shall be kept as “0” to avoid confusing older programs unnecessarily.
Thoughts?
If nobody has any suggestions or further input, then I'll create the first draft of the spec v2 myself and implement it for my toolset.
nand chan
6th September 2011, 00:53
If nobody has any suggestions or further input, then I'll create the first draft of the spec v2 myself and implement it for my toolset.
Said and done:
The updated .3dlut spec proposal: OBSOLETE - See the 3DL2 spec below
________________________________________________________________________________
3DLUT file format specification (version 2)
________________________________________________________________________________
enum {PAGE_SIZE = 16384};
struct H3DLUT
{
char signature[4]; // file signature; must be: '3DLT'
long fileVersion; // file format version number (currently 2)
char programName[32]; // name of the program that created the file
long long programVersion; // version number of the program that created the file
long inputBitDepth[3]; // input bit depth per component (Y,Cb,Cr or B,G,R)
long inputColorEncoding; // input color encoding standard (0 = BGR, 1 = YCbCr)
long outputBitDepth; // output bit depth for all components (valid values are 8, 16, 32 and 64)
long outputColorEncoding; // output color encoding standard (0 = BGR, 1 = YCbCr, 2 = XYZ)
long parametersFileOffset; // number of bytes between the beginning of the file and array parametersData
long parametersSize; // size in bytes of the array parametersData
long lutFileOffset; // number of bytes between the beginning of the file and array lutData
long lutCompressionMethod; // type of compression used if any (0 = none, ...)
long lutCompressedSize; // size in bytes of the array lutData inside the file, whether compressed or not
long lutUncompressedSize; // true size in bytes of the array lutData when in memory for usage (outside the file)
long inputValueRange; // value range for the input (0 = Full range (0-255), 1 = Limited (16-235))
long outputValueRange; // value range for the output
// Input color space - this section is strictly optional, a value of 0 for all means “disabled/unknown”
double inputPrimaryRedX; // Though the X and Y are capitalized here for the naming convention,
double inputPrimaryRedY; // they refer to the x and y coordinates on the CIE xy chromaticity diagram,
double inputPrimaryGreenX; // and *not* the XY values of the XYZ color space.
double inputPrimaryGreenY;
double inputPrimaryBlueX;
double inputPrimaryBlueY;
double inputPrimaryWhiteX;
double inputPrimaryWhiteY;
// This header is followed by the char array 'parametersData', of length 'parametersSize',
// and by the array 'lutDataxx', of length 'lutCompressedSize'.
};
char parametersData[1];
union LUTDATA
{
unsigned char lutData8[1];
unsigned short lutData16[1];
float lutData32[1];
double lutData64[1];
};
// The array 'parametersData' starts 'parametersFileOffset' bytes after the beginning of the file.
// The array 'lutDataxx' starts 'lutFileOffset' bytes after the beginning of the file.
// When creating a 3DLUT file, 'lutDataxx' should be positioned on a 16384 byte boundary.
//
// parametersData - char array with size parametersSize that contains an exact copy of the
// input file with the commands and settings used for creating the 3DLUT file
// lutDataxx - array with size lutSizeUncompressed that contains the 3D LUTs output values.
// The type used depends on the 'outputBitDepth' field:
// - unsigned char, if outputBitDepth = 8
// - unsigned short, if outputBitDepth = 16
// - float, if outputBitDepth = 32
// - double, if outputBitDepth = 64
// The value ranges are assumed to be as follows:
// Full range (integers): 0 to (2^depth) - 1, for example 0-255 and 0-65535
// Full range (floats): 0 to 1
// Limited range (integers): 16 to 235, left/right shifted to the correct bit depth, eg. 4096-60160)
// Limited range (floats): (16/255) to (235/255), approx. 0.06275 - 0.92157.
// For XYZ output:
// XYZ must be appropriately normalized so that the luminosity of white = the range limit.
// eg. for limited range 8-bit output, the luminosity of white would be 235. If the value range is full range,
// this would mean that the values are essentially capped to 255. As such, using limited range for XYZ is
// preferable for integer output. It is strongly recommended that one uses full range floats for XYZ however,
// where the luminosity of white would be normalized to 1.0
// The offset inside the array is calculated as:
// offset = (cr<<(inputBitDepth[1]+inputBitDepth[0])+cb<<(inputBitDepth[0])+y)*3 // YCbCr input
// offset = ( r<<(inputBitDepth[1]+inputBitDepth[0])+ g<<(inputBitDepth[0])+b)*3 // BGR input
// The output order inside the array is:
// Y = lutDataxx(offset); Cb = lutDataxx(offset+1); Cr = lutDataxx(offset+2) // YCbCr output
// B = lutDataxx(offset); G = lutDataxx(offset+1); R = lutDataxx(offset+2) // BGR output
// X = lutDataxx(offset); Y = lutDataxx(offset+1); Z = lutDataxx(offset+2) // XYZ output
// The 'lutUncompressedSize' of the array is calculated as:
// lutDim = 3*(2^inputBitDepth[0]*2^inputBitDepth[1]*2^inputBitDepth[2])
// lutUncompressedSize = lutDim*outputBitDepth/8
// This specification assumes:
// char = 1 byte; short = 2 byte; float = 4 byte; long = 4 byte; long long = 8 byte; double = 8 byte
Notable changes:
The inputBitDepth field has been redefined to be ordered as B,G,R instead of R,G,B
64 is now an acceptable outputBitDepth, and an appropriate array has been added to LUTDATA
The addition of fields inputValueRange and outputValueRange, and the definition of their ranges in the specification itself
Fields inputPrimaryRedX through inputPrimaryWhiteY define the input color space of a .3dlut
The inputColorEncoding and outputColorEncoding fields have been elaborated on
XYZ is now an acceptable output color encoding, and the implementation is defined
Due to the increased header size, the parametersFileOffset must not fall short of 168, a value of 176 is recommended
Reference implementation:
Preview release of the v0.9 of the TI3Parser toolset which includes full support for .3dlut v2 can be found here: http://www.mediafire.com/?aix71ea5y5kmqw8 (source code included)
This includes a utility to convert v2 .3dluts into v1 .3dluts (by running tag3dlut -1 -i <somefile>.3dlut) so we can use the new spec until madVR supports them.
Full changelog of the version 0.9 up to now:
Version 0.9:
! Created and added support for the .3dlut specification v2, changes include:
+ Added support for 64-bit floating point LUTs
+ Added support for color-space aware LUTs
+ Added support for RGB/YCbCr -> XYZ LUTs for profiling purposes, similar to how ICC device profiles work
+ Added support for file-encoded value ranges
* Utilities such as gen3dlut and changedepth which create new LUTs now use the v2, so you no longer need to fix tagging
using tag3dlut
? Note: Since programs such as madVR still only support v1 .3dluts, you need to “convert” it to a v1 for those programs
+ --one (-1) tag added to tag3dlut in order to degrade the version number to v1, this also overwrites the params in order
to correctly tag everything for madVR etc.
+ --color-space (-c) flag added to inspect3dlut
+ !Input_Primaries(rx, ry, gx, gy, bx, by, wx, wy) tag added to LutScript
+ !Input_Primaries(String) overload added to LutScript, acceptable values are currently: "BT709" and "None"
+ --ycbcr (-y) flag added to gen3dlut to generate a blank YCbCr LUT
* ColorTriple<T> is now aware of its encoding, in order to ensure transformations are properly chained
eg. the grayscale filter now simply sets Cr and Cb to 0 if the input is already YCbCr
~ Significantly increased performance here and there by operating on a single value in memory instead of copying it
over and over, however the old style of doing it is still available for cases where it's needed
yesgrey
6th September 2011, 01:03
The updated .3dlut spec:
You are forcing a spec without any of the original authors agreeing with it, so you are at your own risk.
Sorry, but I don't have time for this now. I don't see any reason for all this rush...
nand chan
6th September 2011, 01:49
You are forcing a spec without any of the original authors agreeing with it, so you are at your own risk.
Sorry, but I don't have time for this now.
As I've said, it's a first draft.
I don't see any reason for all this rush...
Because I'm having issues working with the existing .3dlut format. If you would prefer I not touch the original spec, then I shall simply create a new file format from scratch for my projects.
nand chan
6th September 2011, 03:55
If you would prefer I not touch the original spec, then I shall simply create a new file format from scratch for my projects.
Actually, this seems like a good idea regardless, so I can re-order the existing header without worrying about backwards compatibility.
.3dl2 specification:
________________________________________________________________________________
3DLUT2 file format specification
________________________________________________________________________________
enum {PAGE_SIZE = 16384};
struct H3DLUT2
{
byte signature[4]; // file signature; must be: “3DL2” as encoded using the ASCII standard (0x33444C32)
int fileVersion; // file format version number (currently 1)
byte programName[32]; // name of the program that created the file
long programVersion; // version number of the program that created the file
int inputBitDepth[3]; // input bit depth per component (Y,Cb,Cr or B,G,R)
int inputColorEncoding; // input color encoding standard (0 = BGR, 1 = YCbCr)
int inputValueRange; // value range for the input (0 = Full range (0-255), 1 = Limited (16-235))
int outputBitDepth; // output bit depth for all components (valid values are 8, 16, 32 and 64)
int outputColorEncoding; // output color encoding standard (0 = BGR, 1 = YCbCr, 2 = XYZ)
int outputValueRange; // value range for the output
int parametersFileOffset; // number of bytes between the beginning of the file and array 'parametersData'
int parametersSize; // size in bytes of the array 'parametersData'
int lutFileOffset; // number of bytes between the beginning of the file and array lutData
int lutCompressionMethod; // type of compression used if any (0 = none, 1 = LZO, ...)
int lutCompressedSize; // size in bytes of the array 'lutData' inside the file, whether compressed or not
PRIMARIES inputColorSpace; // Input color space - this section is strictly optional,
// a value of 0 for all means “disabled/unknown”
PRIMARIES outputColorSpace; // Output color space - the same rules apply as for input color space.
// In addition, if the output is XYZ, this section is to be set to 0 for all values
// This header is followed by the byte array 'parametersData', of length 'parametersSize',
// and by the array 'lutDataxx', of length 'lutCompressedSize'.
};
struct PRIMARIES
{
double primaryRedX; // Though the X and Y are capitalized here for the naming convention,
double primaryRedY; // they refer to the x and y coordinates on the CIE xy chromaticity diagram,
double primaryGreenX; // and *not* the XY values of the XYZ color space.
double primaryGreenY;
double primaryBlueX;
double primaryBlueY;
double primaryWhiteX;
double primaryWhiteY;
};
byte parametersData[1];
union LUTDATA
{
byte lutData8[1];
ushort lutData16[1];
float lutData32[1];
double lutData64[1];
};
// The array 'parametersData' starts 'parametersFileOffset' bytes after the beginning of the file.
// The array 'lutDataxx' starts 'lutFileOffset' bytes after the beginning of the file.
// When creating a 3DLUT2 file, 'lutDataxx' should be positioned on a 16384 byte boundary.
//
// parametersData - byte array with size 'parametersSize' that contains an exact copy of the
// input file with the commands and settings used for creating the 3DLUT2 file
//
// lutDataxx - array with size lutSizeUncompressed that contains the 3D LUTs output values.
// The type used depends on the outputBitDepth field:
// - unsigned byte, if outputBitDepth = 8
// - unsigned short, if outputBitDepth = 16
// - float, if outputBitDepth = 32
// - double, if outputBitDepth = 64
//
// The value ranges are assumed to be as follows:
// Full range (integers): 0 to (2∧depth)−1, for example 0–255 and 0–65535
// Full range (floats): 0 to 1
// Limited range (integers): 16–235, left/right shifted to the correct bit depth, eg. 4096–60160)
// Limited range (floats): (16÷255)≈0.06275 to (235÷255)≈0.92157.
//
// For XYZ output:
// XYZ must be appropriately normalized so that the luminosity of white = the range limit.
// eg. for limited range 8-bit output, the luminosity of white would be 235. If the value range is full range,
// this would mean that the values are essentially capped to 255. As such, using limited range for XYZ is
// preferable for integer output. It is strongly recommended that one uses full range floats for XYZ however,
// where the luminosity of white would be normalized to 1.0
//
// The offset inside the array is calculated as:
// offset = (Cr<<(inputBitDepth[1]+inputBitDepth[0])+Cb<<(inputBitDepth[0])+Y)×3 // YCbCr input
// offset = ( R<<(inputBitDepth[1]+inputBitDepth[0])+ G<<(inputBitDepth[0])+B)×3 // BGR input
//
// The output order inside the array is:
// Y = lutDataxx[offset]; Cb = lutDataxx[offset+1]; Cr = lutDataxx[offset+2] // YCbCr output
// B = lutDataxx[offset]; G = lutDataxx[offset+1]; R = lutDataxx[offset+2] // BGR output
// X = lutDataxx[offset]; Y = lutDataxx[offset+1]; Z = lutDataxx[offset+2] // XYZ output
//
// The lutUncompressedSize of the array is calculated as:
// lutDim = 3 × 2∧inputBitDepth[0] × 2∧inputBitDepth[1] × 2∧inputBitDepth[2] × outputBitDepth÷8
//
// This specification assumes:
// byte = 1 byte; short = 2 byte; int = 4 byte; long = 8 byte; // integers
// float = 4 byte; double = 8 byte; // floating point numbers
//
// << is used to denote an arithmetic left shift operator. Where strict/large inequality is wanted, ≪ is used.
I've updated the signature to 3DL2 and decreased the fileVersion back to 1. This also makes code supporting both very easy, you simply check to see if the signature is 3DLT or 3DL2 and is what I do in my code.
Other changes include the addition of an output color space field as well (I'll eventually create a fully color aware pipeline that can link together multiple 3dluts by mapping the gamuts between each step, so I've added this as a prerequisite) and the fixing of some stylistic issues (eg. incorrect ASCII symbols for mathematical operators being used where appropriate Unicode replacements exist)
madshi
6th September 2011, 19:27
Original size: 100 MB
.bz2: 83.59 MB
.gz: 77.66 MB
.zip (normal): 75.84 MB
.rar (fastest): 66.42 MB
.rar (fast): 64.34 MB
.7z (LZMA): 34.61 MB
.rar (normal): 7.35 MB
That's all too slow for real time use. I've already experimented with LZO and although it doesn't compress too well, at least it decompresses faster than reading from harddisk. I've already fully working LZO compression projects for 3dluts on my harddisk, but haven't had time yet to polish and publish it all.
nand chan
6th September 2011, 22:19
That's all too slow for real time use. I've already experimented with LZO and although it doesn't compress too well, at least it decompresses faster than reading from harddisk. I've already fully working LZO compression projects for 3dluts on my harddisk, but haven't had time yet to polish and publish it all.
I've added LZO compression to v0.10 of mine, using CompressionMethod = 1 to denote LZO.
Some metrics:
16-bit “blank” .3dl2 (input=output): Reduced from ~100 MB to ~50 MB
8-bit “blank” .3dl2: /increased/ from ~49 MB to ~50 MB. LutCompressedSize is larger than LutUncompressedSize.
16-bit gamut mapping .3dl2 created using LittleCMS + ICC profiles: Decreased from ~100 MB to ~70 MB.
Doesn't seem too bad, and decompressing is quite fast as mentioned. I'll leave it in for now.
Yellow_
6th September 2011, 22:21
A bit of a weird query but if I wanted a 3D LUT to convert from rec709/sRGB to 'another' with primaries as follows: Red CIE x = 0.73470 CIE y = 0.26530, Green CIE x = 0.00000, CIE y = 1.00000 and Blue CIE x 0.00010 & CIE y -0.07700.
Neutral Axis CIE x = 0.32168, y = 0.33767 Approx CIE D60 and Reference Midpoint Grey at CIE XYZ {0.1715, 0.1800, 0.1816}
What would I need to put in the 3dlut config file?
madshi
6th September 2011, 22:32
I've added LZO compression to v0.10 of mine, using CompressionMethod = 1 to denote LZO.
Some metrics:
16-bit “blank” .3dl2 (input=output): Reduced from ~100 MB to ~50 MB
8-bit “blank” .3dl2: /increased/ from ~49 MB to ~50 MB. LutCompressedSize is larger than LutUncompressedSize.
16-bit gamut mapping .3dl2 created using LittleCMS + ICC profiles: Decreased from ~100 MB to ~70 MB.
Doesn't seem too bad, and decompressing is quite fast as mentioned. I'll leave it in for now.
I've found that pre-processing the data before compression helps a lot with LZO compression. E.g. compression the difference instead of the absolute values.
nand chan
7th September 2011, 13:59
I've found that pre-processing the data before compression helps a lot with LZO compression. E.g. compression the difference instead of the absolute values.
So we make a LZOM (Lempel-Ziv-Oberhumer-Madshi) variation of it? :P
I'll experiment with what you suggested later. The only immediately jarring problem I see is that you need a signed integer to encode a negative offset, and if you use a signed integer then you can't encode a difference of something like 200. For example, if I want to make a 3dlut that inverts its output, I'll either need two signed integers or an unsigned integer to encode the difference offset.
A bit of a weird query but if I wanted a 3D LUT to convert from rec709/sRGB to 'another' with primaries as follows: Red CIE x = 0.73470 CIE y = 0.26530, Green CIE x = 0.00000, CIE y = 1.00000 and Blue CIE x 0.00010 & CIE y -0.07700.
Neutral Axis CIE x = 0.32168, y = 0.33767 Approx CIE D60 and Reference Midpoint Grey at CIE XYZ {0.1715, 0.1800, 0.1816}
What would I need to put in the 3dlut config file?
Just use yCMS? Something like
Input_Primaries 0.640312221900565 0.331429429181046 0.309178195500916 0.598966865076147 0.146091462964633 0.0570065026117047 0.3127266146811209 0.32902313032606195
Output_Primaries 0.73470 0.26530 0.00000 1.00000 0.00010 -0.07700 0.32168 0.33767
By the way, that is one *HUGE* color space you are talking about. 180% NTSC laser projector or what are you mapping to?
Yellow_
7th September 2011, 16:51
By the way, that is one *HUGE* color space you are talking about. 180% NTSC laser projector or what are you mapping to?
hehe, yep and pretty pointless from rec709/sRGB for 90% of uses. :-)
It's ACES IIF a overview here: Need to scroll down a bit to the ACES section.
http://www.fxguide.com/featured/the-art-of-digital-color/
And
http://www.oscars.org/science-technology/council/projects/iif.html
Thanks for the yCMS config.
nand chan
7th September 2011, 18:33
hehe, yep and pretty pointless from rec709/sRGB for 90% of uses. :-)
It's ACES IIF a overview here: Need to scroll down a bit to the ACES section.
http://www.fxguide.com/featured/the-art-of-digital-color/
And
http://www.oscars.org/science-technology/council/projects/iif.html
Thanks for the yCMS config.
Oh, thanks a lot for pointing me to this.
So it's basically like the PRMG except less shitty? It would be a good reference gamut for perceptual conversions in ICCv2 profiles (too bad the ICCv4 is already standardized to the PRMG).
(Then again, for perceptual conversions, it doesn't make a difference).
I like the idea of using the ACES as an *essentially* device independent gamut, we could use RGB as a PCS without needing to modify existing RGB gamut correction technologies (eg. yCMS).
That way you could make a 3dlut from BT.709 to ACES, and a 3dlut from ACES to any device, and link the two together using technologies such as merge3dlut.exe.
Yellow_
7th September 2011, 21:41
I'm pleased it's useful to you, most of what you've said is over my head, not really got into ICC stuff. :-)
On the subject of gamut's and conversions though, could I point you to this too in case it is of use, was meaning to ask here if anyone is looking at a plugin for Avisynth using it.
http://opencolorio.org/
http://code.google.com/p/opencolorio/
Although it's by Sony, it's open standard / opensource and being adopted pretty much everywhere, including VFX apps like the Foundary's Nuke Compositor and OSS tools like Blender.
OpenColorIO is also in the process of supporting ACES.
nand chan
7th September 2011, 21:57
I'm pleased it's useful to you, most of what you've said is over my head, not really got into ICC stuff. :-)
On the subject of gamut's and conversions though, could I point you to this too in case it is of use, was meaning to ask here if anyone is looking at a plugin for Avisynth using it.
http://opencolorio.org/
http://code.google.com/p/opencolorio/
Although it's by Sony, it's open standard / opensource and being adopted pretty much everywhere, including VFX apps like the Foundary's Nuke Compositor and OSS tools like Blender.
OpenColorIO is also in the process of supporting ACES.
Looks interesting. I wonder how much it differs from LittleCMS as far as gamut mapping goes. I may have to provide a LutScript function for this :P
nand chan
8th September 2011, 22:08
Updating my 3DL2 spec, it seems like we will have to support dynamic ranges after all. It's good that I split it off since now I can experiment and change the spec as the different needs and wants come in, and adapt my own implementation - until the changes are ready to be pushed back upstream.
For the sake of future flexibility, I am going to encode the black and white levels as 64 bit floating point values on the scale 0-1.
So, for example, a limited range 8-bit LUT (value ranges 16-235) would be (16/255) and (235/255) respectively, or approx. 0.0627451 - 0.921561.
Edit: Having done some testing, it is revealed to me that this method is not quite perfect, since that way you can't simply shift the bit depth without accounting for the value range, eg. (16/255) * 65535 is not, as correct, 4096, but in fact 4112. I'm still trying to come up with an elegant solution for this problem.
Edit 2: The solution dawned on me just as I type this. The value will not be represented as a fraction of the maximum value, but that of /one above it/ (eg. the range limit).
So, a 16-235 value range would be encoded as 16/256 and 235/256, or about 0.0625 and 0.91796875 respectively. This way, the scaling is preserved - 0.0625 * 65536 = 4096 and 0.91796875 * 65536 = 60160.
Some minor rewriting of my pullup/down engine will be required but very doable.
Floating point values will still be kept as their respective exact values, eg. a 32-bit .3dl2 with the output white level set to 0.2 will have a white point of exactly 0.8.
IanB
8th September 2011, 23:42
... For the sake of future flexibility, I am going to encode the black and white levels as 64 bit floating point values on the scale 0-1.
...
So, a 16-235 value range would be encoded as 16/256 and 235/256, or about 0.0625 and 0.91796875 respectively. This way, the scaling is preserved - 0.0625 * 65536 = 4096 and 0.91796875 * 65536 = 60160.
You may be better off using rational pairs (like FPS is done with numerator and denominator) to store this concept. This lets you store the exact values and do any required rounding at the time you implement them some time later. Once rounding is done it cannot be undone.
Edit 2: The solution dawned on me just as I type this. The value will not be represented as a fraction of the maximum value, but that of /one above it/ (eg. the range limit).This might be better expressed as the number of values in the range, i.e. [0..255] has 256 values, [16..235] has 220 values.
nand chan
9th September 2011, 01:08
You may be better off using rational pairs (like FPS is done with numerator and denominator) to store this concept. This lets you store the exact values and do any required rounding at the time you implement them some time later. Once rounding is done it cannot be undone.
This might be a good idea, the only issue I see here is an implementation issue: If you have some arbitrary value limit, how would you compute the best matching fraction (unless you allow floating point fractions as well)?
For example, say I have some 32-bit LUT with value limits of, I dunno, 0.19439583945 and 0.938593485 - you'd have to generate some sort of integer fraction pair for those and the process for that might as well introduce more rounding inaccuracies than the process of storing a floating point value.
Also, you have to realize that technically, floating points are themselves just a collection of fractions, eg. 1/4 + 1/8 + 1/16 = 0.4375.
And with 64-bit precision the difference between storing the value and computing the value at runtime will be negligible.
This might be better expressed as the number of values in the range, i.e. [0..255] has 256 values, [16..235] has 220 values.
I don't see how that would get us anywhere, elaborate?
IanB
10th September 2011, 01:23
This might be a good idea, the only issue I see here is an implementation issue: If you have some arbitrary value limit, how would you compute the best matching fraction (unless you allow floating point fractions as well)?
For example, say I have some 32-bit LUT with value limits of, I dunno, 0.19439583945 and 0.938593485 - you'd have to generate some sort of integer fraction pair for those and the process for that might as well introduce more rounding inaccuracies than the process of storing a floating point value.
Also, you have to realise that technically, floating points are themselves just a collection of fractions, eg. 1/4 + 1/8 + 1/16 = 0.4375.
And with 64-bit precision the difference between storing the value and computing the value at runtime will be negligible.
Yes, floating point numbers are built from fractions of the form 1/2^n so only fractional values that have a last decimal digit of 5 after the point can be exactly represented, and then only within the available precision of the mantissa. But yes it is still a very good representation of the value.
Using rational pair to store a value is a way of never actually doing the divisions in the calculation of the value, thus never having a rounding issue.
If you are always just plonking pre-calculated decimal values into the LUT header then you gain nothing and you might as well use a double.
However if the values are calculations resulting in a normalised (a+b/c) result then rational pairs have a lot to offer.
For your 2 example number with simple normalising and also approximated with continued fractions limited to your last digit :-
0.19439583945 = (3887916789/20000000000) ~ (231749/1192150) = 0.19439583944973
0.938593485 = (187718697/200000000) ~ (106811/113799) = 0.938593485004
Of course I don't know your original calculation, I am working with what appears as an already rounded double result. The true result maybe a much simpler rational pair.
Some rational pairs for PI are 22/7, 333/106, 355/113
This might be better expressed as the number of values in the range, i.e. [0..255] has 256 values, [16..235] has 220 values.
I don't see how that would get us anywhere, elaborate?For the original idea you were expressing, the justification to use 256 and 220 as the divisors in your specification were that they are the count of unique values in the range not the range limit, e.g. which would be 236 for the [16.235] subset.
nand chan
10th September 2011, 12:52
Yes, floating point numbers are built from fractions of the form 1/2^n so only fractional values that have a last decimal digit of 5 after the point can be exactly represented, and then only within the available precision of the mantissa. But yes it is still a very good representation of the value.
Using rational pair to store a value is a way of never actually doing the divisions in the calculation of the value, thus never having a rounding issue.
Negligible since the calculations of the value will be performed millions of times during both generation and usage either way - even if you /could/ store some theoretically perfect fraction it would offer no single usage case.
If you are always just plonking pre-calculated decimal values into the LUT header then you gain nothing and you might as well use a double.
The only situations in which you /wouldn't/ want to put a pre-calculated value into the header is for the Full range situation (0-1), but both 0 and 1 can be accurately represented as a double. Everything else will be implicitly tied to the generation, whether it's during gamut mapping using ICC profiles, or yCMS' 64 bit creation, or even simple I=O mapping (pulldown and pullup get performed regardless to transfer the values from an 8-bit range to a 16-bit range, for example - so precision is lost)
You have to remember also we are dealing with color here and the difference between, say, 0.123456789 and 0.123456788 approximates to a difference in XYZ of <0.0000001, even after gamma pullup and mapping.
However if the values are calculations resulting in a normalised (a+b/c) result then rational pairs have a lot to offer
Such exact calculations are not performed here and are in the realm of mathematical accuracy implementations, not color management.
Even if you could achieve such results after /one/ step of the operation (eg. pulldown/pullup which will indeed get calculated as an a + b*c or (a-b)/c triple, storing them that way would be detrimental to both storage space and calculation speed - the point of .3dluts is to pre-calculate everything already so the resulting program just has to run the values through.
For your 2 example number with simple normalising and also approximated with continued fractions limited to your last digit :-
0.19439583945 = (3887916789/20000000000) ~ (231749/1192150) = 0.19439583944973
0.938593485 = (187718697/200000000) ~ (106811/113799) = 0.938593485004
Of course I don't know your original calculation, I am working with what appears as an already rounded double result. The true result maybe a much simpler rational pair.
Some rational pairs for PI are 22/7, 333/106, 355/113
For the original idea you were expressing, the justification to use 256 and 220 as the divisors in your specification were that they are the count of unique values in the range not the range limit, e.g. which would be 236 for the [16.235] subset.
Yes, I understood that much, it's just that I'm wondering what dividing by the count of values would achieve - the point of dividing by 256 in the first place is so you can express the range limits - if you divide by some factor of that range in the first place then the point is destroyed - we would end up with a situation where every range limit turns out to be 1.0 (or every value from 0-1 plus some number (base/lim)).
Unless you are suggesting that we define the divisor as the amount of unique values within the integer range we are representing (and not the value range), in which case that's just expressing the same thing using different words (and would pose a problem to floating point values).
Also, I'm considering removing the whole variable-range proposal in the first place, since it complicates implementations - a true implementation will now have to perform an addition, a subtraction, a multiplication and a division for each components of each pixel of each frame - four things that would previously all not have been necessary.
The point of .3dluts was to be to pre-calculate values, so I'm wondering why re-calculation should be necessarily - .3dluts should be simple look up tables.
The original idea for the variable range limits was to fix a problem that never existed (and indeed, introducing variable ranges didn't fix the problem either - I had forgotten that the range gets normalized within the pipeline either way).
And lastly, the only situation in which flexible range limits would be of benefit is for adjustable white and black levels - and for those, a normalized, full range floating point .3dlut would be ideal, since you can just express, say, 1.15 easily.
Edit: I've also slightly rewritten my copy of the 3DL2 proposal to remove the distinction between R/G/B or Y/Cb/Cr - calculations are now simply performed as “A, B and C” and are unaware of their own encoding, the encoding type determines which channel means what. Encoding = 0 means “BGR”, so A = Blue, B = Green and C = Red.
nand chan
12th September 2011, 01:43
I've removed the silly variable ranges again, here is my current copy:
________________________________________________________________________________
3DL2 file format specification
________________________________________________________________________________
enum {PAGE_SIZE = 16384};
struct H3DLUT2
{
byte signature[4]; // file signature; must be: “3DL2” as encoded using the ASCII standard (0x33444C32)
int fileVersion; // file format version number (currently 2)
byte programName[32]; // name of the program that created the file
long programVersion; // version number of the program that created the file
int inputBitDepth[3]; // input bit depth per component (Y,Cb,Cr or B,G,R)
int inputColorEncoding; // input color encoding standard (0 = BGR, 1 = YCbCr)
int inputValueRange; // value range for the input (0 = Full range (0-255), 1 = Limited (16-235)) [up to v1]
int outputBitDepth; // output bit depth for all components (valid values are 8, 16, 32 and 64)
int outputColorEncoding; // output color encoding standard (0 = BGR, 1 = YCbCr, 2 = XYZ)
int outputValueRange; // value range for the output
int parametersFileOffset; // number of bytes between the beginning of the file and array 'parametersData'
int parametersSize; // size in bytes of the array 'parametersData'
int lutFileOffset; // number of bytes between the beginning of the file and array lutData
int lutCompressionMethod; // type of compression used if any (0 = none, 1 = LZO, ...)
int lutCompressedSize; // size in bytes of the array 'lutData' inside the file, whether compressed or not
PRIMARIES inputColorSpace; // Input color space - this section is strictly optional,
// a value of 0 for all means “disabled/unknown”
PRIMARIES outputColorSpace; // Output color space - the same rules apply as for input color space.
// In addition, if the output is XYZ, this section is to be set to 0 for all values
// This header is followed by the byte array 'parametersData', of length 'parametersSize',
// and by the array 'lutDataxx', of length 'lutCompressedSize'.
};
struct PRIMARIES
{
double primaryRedx; // The x and y refer here to the coordinates on the CIE xy chromaticity diagram,
double primaryRedy; // Y is assumed to be 1.0 for these primaries
double primaryGreenx;
double primaryGreeny;
double primaryBluex;
double primaryBluey;
double primaryWhitex;
double primaryWhitey;
};
byte parametersData[1];
union LUTDATA
{
byte lutData8[1];
ushort lutData16[1];
float lutData32[1];
double lutData64[1];
};
// The array 'parametersData' starts 'parametersFileOffset' bytes after the beginning of the file.
// The array 'lutDataxx' starts 'lutFileOffset' bytes after the beginning of the file.
// When creating a 3DLUT2 file, 'lutDataxx' should be positioned on a 16384 byte boundary.
//
// parametersData - byte array with size 'parametersSize' that contains an exact copy of the
// input file with the commands and settings used for creating the 3DLUT2 file
//
// lutDataxx - array with size lutSizeUncompressed that contains the 3D LUTs output values.
// The type used depends on the outputBitDepth field:
// - unsigned byte, if outputBitDepth = 8
// - unsigned short, if outputBitDepth = 16
// - float, if outputBitDepth = 32
// - double, if outputBitDepth = 64
//
// The value ranges are assumed to be as follows:
// Full range (integers): 0 to (2∧depth)−1, for example 0–255 and 0–65535
// Full range (floats): 0 to 1
// Limited range (integers): 16–235, left/right shifted to the correct bit depth, eg. 4096–60160)
// Limited range (floats): (16÷255)≈0.06275 to (235÷255)≈0.92157.
//
// For XYZ output:
// XYZ must be appropriately normalized so that the luminosity of white = the range limit.
// eg. for limited range 8-bit output, the luminosity of white would be 235. If the value range is full range,
// this would mean that the values are essentially capped to 255. As such, using limited range for XYZ is
// preferable for integer output. It is strongly recommended that one uses full range floats for XYZ however,
// where the luminosity of white would be normalized to 1.0
//
// The offset inside the array is calculated as:
// offset = (A + B << (inputBitDepth[0]) + C << (inputBitDepth[1]+inputBitDepth[0])) × 3
//
// The output order inside the array is:
// A = lutDataxx[offset]; B = lutDataxx[offset+1]; C = lutDataxx[offset+2]
//
// A, B and C refer to the respective channels of the used encoding (eg. B, G, R or Y', Cb, Cr)
//
// The lutUncompressedSize of the array is calculated as:
// lutDim = 3 × 2∧inputBitDepth[0] × 2∧inputBitDepth[1] × 2∧inputBitDepth[2] × outputBitDepth÷8
//
// This specification assumes:
// byte = 1 byte; short = 2 byte; int = 4 byte; long = 8 byte; // integers
// float = 4 byte; double = 8 byte; // floating point numbers
//
// << is used to denote an arithmetic left shift operator. Where strict/large inequality is wanted, ≪ is used.
leeperry
24th November 2011, 06:51
I might consider creating a bigger ramdisk and use 16bit YUY2 LUT's instead of 8bit, but why is t3dlut() so much more power hungry than rgb3dlut() again? :o
hi tritical, if you're still around: is there any way you could provide a way to apply 16bit LUT's w/ the same CPU load as rgb3dlut() please? t3dlut() is a CPU hog :/
leeperry
18th August 2013, 11:42
BTW, it's funny to see that in 2013 they still use a Sony CRT for TV shows production(and more than likely color correction): http://s.tf1.fr/mmdia/i/33/5/plateau-speciale-10-ans-ci-26-10592335hxsqq.jpg
It's one of those: http://www.highwayav.com/Portals/0/Products/Production_Monitors/BVM_PVM_Monitors/BVM-A14F5M/1169568028-191.jpg
fijam
13th January 2018, 12:42
Does anyone still have a copy of ddcc.zip? The original links are down and it wasn't archived by the Wayback machine.
StainlessS
13th January 2018, 13:47
ddcc_v17.zip, @ SendSpace below in my sig [~0.1MB].
Source (still there), https://forum.doom9.org/showthread.php?t=168012, posted by Wilbert (bottom of first post, 350MB+).
EDIT: I think there were also at least a couple of earlier versions in the archive zip posted by Wilbert.
EDIT: File linked by Wilbert:- Plugins4_20130531.zip, again here (~350MB):- http://www.avisynth.nl/users/warpenterprises/Plugins4_20130531.zip
Contents of Zip
avsfilmcutter_Source_0020b
ffmpegsource_119
flash3kyuu_deband
QTGMC
tc2mp4_20070124
_FSubstitute.zip
_FSubstitute_121122.zip
_FSubstitute_121202.zip
_FSubstitute_121223.zip
_GPU25_002_test3.rar
3dubois3.zip
AddGrainC-1.5.1.7z
AddGrainC-1.5.3.7z
AddGrainC-1.6.1.7z
AddGrainC-1.7.0.7z
addgrainc_1.4.zip
anisotools-v1.0a1.zip
anisotools-v1.0a2.zip
anisotools-v1.0a3.zip
anisotools-v1.0a4.zip
anisotools-v1.0a5.zip
assrender-0.18.7z
assrender-0.18-src.7z
assrender-0.24.1.7z
assrender-0.24.7z
assrender_0.1.7z
assrender_0.1-src.7z
autolevels0.3.zip
autolevels0.3b.zip
autolevels_0.6_20101226.zip
autolevels_0.6_20110109.zip
autolevels_20101104.zip
autoyuy2_101.zip
Average_v10.zip
Average_v11.zip
avfs_1.0.0.3.zip
avfs_20080602.zip
AVIInfo_v03.zip
AviSynth26.7z
avisynth26_20110913.7z
AviSynth26_old.7z
AVISynth UI 0.01.zip
avisynth_pascal_v5.rar
AviSynth_R3D_Source_V1.0.zip
AvisynthStudio 1.2 Beta (Source).7z
AvisynthStudio 1.2 Beta.7z
AvisynthTrackin.1.0.binary.zip
AvisynthTrackin.1.0.source.zip
AVS2ASF_NIC.zip
avs2avi-140.7z
avs2avi-140a.zip
avs2bdnxml-1.3.tar.bz2
avs2bdnxml-2.04.tar.bz2
avs2pipe260-0.0.2.zip
avs2pipe-0.0.2.zip
avs2pipemod-0.1.2.7z
avs2pipemod-0.3.0.7z
avs2pipemod-20110509.zip
avs2pipemod-20110703-2.zip
avs2pipemod-20110919.zip
avs2wav.2011-05-21.zip
avs2yuv-0.24bm2.zip
avs.coder
AVSCurveFlow-2007.03.06.zip
avsfilmcutter_Source_0020b.rar
AVSInpaint-2008.01.06.zip
AVSInpaint-2008.02.23.zip
AVSMeter100.zip
AVSMeter112.zip
AVSMeter115.zip
AVSMeter144.zip
AVSMeter145.zip
AVSMeter149.zip
avsproxy_gui.2008-02-29.zip
avsproxy_gui.2008-03-01.zip
avss.7z
avss-src.7z
avstp-1.0.0.zip
avstp-1.0.1.zip
avsViewer.zip
aWarpSharp.rar
aWarpSharp_20090619.rar
aWarpSharp_20090619_fix1.rar
BassAudio2423.7z
BeHappy_r13913.7z
BlendBob_1.2.zip
BlindDeRing.dll
BZColorspace_Source.rar
ccc_v0.4a_avs.zip
chikuzen-HighBitDepth_VFWSource-f6729f2.zip
chikuzen-VS_AvsReader-8c6c94a.zip
chroma_optimize v0.2.0 (alpha).zip
CMVSource.zip
ColorBalance_0.26.zip
Colorit.zip
colorkeyframe02.zip
ColorMatrix_ICL11.rar
ColorMatrixv23.zip
ColorMatrixv24.zip
ColorMatrixv25.zip
ColorMatrixv25ICL11.zip
ColorScreenMask.zip
ColorSource_original.rar
ColorYUV Graffer.zip
colourlike_25_dll_20050825.zip
ColourLike_25Aug05.dll
Comparison-187.zip
ddcc.zip
ddcc_v16.zip
ddcc_v17.zip
DDigit_25_dll_20101017.zip
DDigitTest_25&26_v1-04_dll_20130420.zip
Deathray_1_00_DLL.zip
Deathray_1_00_src.zip
decomb524src_pitch_fix.zip
defish.zip
demosaic.zip
demosaic_ignus2.zip
depan1100.zip
depan1101.zip
depanestimate192.zip
despot351.zip
dfttest_281107.zip
dfttestv13.zip
dfttestv14.zip
dfttestv15.zip
dfttestv18.zip
dgavcdec100a8.zip
dgavcdec100a13.zip
dgavcdec101.zip
DGDecode158_Mod.zip
DGIndex158b.zip
dgmpgdec154.zip
dgmpgdec154src.zip
dgmpgdec156.zip
dgmpgdec157.zip
dgmpgdec158.zip
dgmpgdec158src.zip
DirectShowSource_2587.zip
Displace v0.1.rar
Dither16to8Bit.zip
dither-1.4.zip
dither-1.5.zip
dither-1.8.zip
dither-1.9.5.zip
dither-1.12.1.zip
dlAviShader042.rar
Dsynth based on 2.55 release.v9.rar
dvinfo_20100602.zip
EEDI2MT___(v0.9.2_-_2007-02-23).7z
eedi3.zip
EffectsMany.zip
exinpaint01.zip
exinpaint02.zip
FanFilter_19102008.zip
FanFilter_22102008.zip
fauxD_v010.zip
fdecimate110.zip
ffmpeg_eac3_mlp_rev10905.7z
ffmpeg_eac3_mlp_rev10905.patch
FFmpegSource-1.13.rar
FFmpegSource-1.14.rar
FFmpegSource-1.19.rar
FFmpegSource-2.00b1.rar
FFmpegSource-2.00b3.rar
ffmpegsource-2.15.7z
FFmpegSource_+++.7z
FFMpegSource_audio_test_281007.rar
FFmpegSource_r10891.7z
FFmpegSource_rev10905.7z
ffms2-2[1].13.7z
ffms2-2[1].13_src.7z
ffms2-r339.7z
ffms-2.16-src.tar.bz2
ffms-2.17.7z
FilmCutterVer0020beta.zip
flash3kyuu_deband_1.0.1.7z
FluaG_v01.zip
FluaG_v02.zip
FluaG_v04.zip
FluaG_v05.zip
FluxSmooth-1.1b.zip
framenumber_version_0.2c.zip
framenumber_version_0.4b.zip
fssetup-2[1].7.exe
FSubstitute.txt
fusion2.zip
fusion.zip
GetProcessName_dll_20121229(Take-2).zip
GetSystemEnv_v020.zip
GetSystemEnv_v030.zip
GPUBilateralFilter.Binary.Win32.1.0.zip
GPUBilateralFilter.Binary.Win32.1.2.zip
GPUBilateralFilter.Source1.0.zip
GPUBilateralFilter.Source.1.2.zip
GrainOptimizer_v12.zip
GrainOptimizer_v101.zip
GraMaMa_v02.zip
greyc01.zip
GRunT101.zip
GRunT.zip
GScript_10.zip
GScript_11.zip
HighBitDepth_VFWSource-0.1.3.7z
HSVAdjust_v01.zip
imagesequence_20080227.zip
imck-2.0.0.zip
imck-2.0.0-src.zip
InterFrame-1.0.zip
iuf_v1.5.zip
javisynth_0_2.tar.gz
libass-static-mingw32.tar.bz2
LoadDll.zip
loadfont.cpp
makeavis1603.zip
Manamanator_Installer.zip
Manamanator_Source.zip
MaskHS_src.zip
masktools-v2.0a33.zip
masktools-v2.0a34.zip
masktools-v2.0a44.zip
masktools-v2.0a46.zip
masktools-v2.0a47.zip
masktools-v2.0a48.zip
mcbobbers.zip
MCBobUv5.7z
McM_2D_to_3D_v0.2.rar
MDec2_source.zip
MinMaxAudio_v02.zip
mpasource_20080220.zip
MpegAutoIndex.zip
MSU Frame Rate Conversion Filter.zip
MT_07_with_Avisynth258.rar
mt_masktools-26-for-2.6alpha4.7z
mvtools-v1.8.6.zip
mvtools-v1.9.2.zip
mvtools-v1.9.3.zip
mvtools-v1.9.5.zip
mvtools-v2.5.11.3.zip
mxfsource_v01.zip
netAvs2yuv-0.3.1.tar.bz2
NicAudio_204.7z
NicAudio_205.7z
NicAudio_206.7z
NicAudio_r202.7z
NLMeansCL_0.1.1.zip
NLMeansCL_0.3.1.zip
NLMeansCL_0.3.1_source.zip
NLMeansCL_0.3.2.zip
NLMeansCL_0.3.2_source.zip
nnedi2.zip
nnedi2_v10.zip
nnedi2_v13.zip
nnedi2_v15.zip
nnedi3_v09.zip
nnedi_20100820.tar.bz2
overlua-0.7-alpha.rar
Pantarheon3DAviSynthToolbox-1-1.zip
pixelinfo0_3.zip
PointSize_0.1.7z
pop.zip
PremiereAVSPlugin-v1.91.exe
PremiereAVSPlugin-v1.91-src.zip
PremiereAVSPlugin-v1.95.exe
PremiereAVSPlugin-v1.95-src.zip
QTGMC2.47r.zip
QTGMC-3.32.zip
QTGMC 32-bit Plugins.zip
QTSource_0_0_8_bin.zip
QTSource_20100915_Test01.zip
quad_20121101.zip
quad-no-sse.zip
R_pack_23.zip
R_pack_020708.zip
R_pack_191107.zip
RaWav10b.7z
RawSource_25_dll_20110521.zip
RawSource_25_dll_20110523.zip
RawSource_25_dll_20110529.zip
RawSource_26_dll_20110614.zip
rawsource_26_dll_20110925.zip
rawsource_26_dll_20120831.zip.zip
rawsourceSeq_25_dll_20060412.7z
RedAverage___(1.4.3_-_2011-12-02).7z
RemoveGrain_v09.zip
ResampleHQ-v1.zip
ResampleHQ-v2.zip
rotate11.zip
rotate131.zip
RT_Stats_25_dll_0.0b_20120724.zip
RT_Stats_25_dll_1.05_20121003.zip
RT_Stats_25_dll_1.06_20121205.zip
RT_Stats_25_dll_1.07Beta_20121211.zip
Sample.avs
Sample.d2v
Sample.m2v
Sample_Wilbert.zip
sashimi_073.zip
sashimi_073_src.zip
sashimi_074.zip
sashimi_074_src.zip
sashimi_075.zip
sashimi_075_src.zip
sashimi_085.zip
Sashimi_085_src.zip
showpixelvalues1.4c.zip
SimpleResize_MOD.zip
SincResize4.7z
SmoothAdjust-v1.00.zip
SmoothAdjust-v1.16.zip
SmoothAdjust-v1.40.zip
SmoothAdjust-v2.00alpha.zip
SmoothAdjust-v2.00beta3.zip
SmoothAdjust-v2.00beta4.zip
SmoothD008.zip
SmoothD008_src.zip
sora_mtmp_package_20120211.7z
SoundOut-1.0.3.zip
SoundOut-1.1.1.zip
specials-src_davidhorman.zip
SSIM0.25.1.0.rar
SUPtext.zip
tc2mp4_doom9dotorg_20070124.rar
tcanny.zip
tcv2tov1_01.zip
TDeintv11.zip
ThreadRequest102a.zip
TIVTCv103.zip
TurnsTile_v010.zip
TurnsTile_v020.zip
TurnsTile_v030.zip
TurnsTile_v031.zip
TWriteAvi.zip
twriteavi_squid_80_mod.zip
unblock11.zip
Unfurl.zip
variableblur_20110314.zip
VariableBlur_30082008.zip
variableblur_v06.zip
VerticalCleaner.rar
ViDBuG.Beta3.msi
ViDBuG.Beta3.Source.7z
vsavsreader-4dafb1b.7z
vsfilter_250508.rar
waveform0.1.zip
waveform0.2.zip
WMCmd_20071011.zip
x264Resize.7z
yadif13.zip
yadif17.zip
yadifmod_v1.zip
yatta.txt
yatta_7-130-beta6.rar
yv12torgb24hq.zip
File list, extracted from Windows Explorer using NirSoft SysExporter.
Perhaps posting full contents might assist in future forum search.
EDIT: The zip posted by Wilbert seems to be a copy of WarpEnterprises plugs, but WarpEnterprises does not seem to
include the ddcc zip, perhaps there are other differences, anyways here is WarpEnterprises on the Avisynth.nl:- http://www.avisynth.nl/users/warpenterprises/
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.