Log in

View Full Version : Else if and script review of my crappy code


Pages : [1] 2

FranceBB
17th June 2020, 13:24
Hi there,
I was trying to make the conversion through my LUTs a bit more user friendly, so I fired up AVSPmod and gave it a shot, however I'm puzzled on a few things.

Question 1: matrices of linear transformation (LUTs) can be quite large, depending on their size. Should I hard-link them to a folder in my code and ask users to put the LUTs in a specific folder all the time, or should I include them in my avsi script somewhere? If the latter is chosen, how can I pass them to Cube()? You can see that I left the path blank where there's "myvalue".
I mean, I know how to pass a string, but if I include them in the file it would be an array, not a string...
Ideally I would like to include them all together in one big avsi file.

Question 2: If statement work like a charm in Avisynth, however if I don't put an else, it complains... Ideally, I'd like to do:

If (aaa == true)
{
do something
}
else if ( bbb == true)
{
do something else
}

however in the current implementation when I use "?" it expects a ":" which is "else", not "else if".
How can I get an else if?



function LinearTransformation(clip clp, string "Input" string "Output")

{
Assert( ( clp.isYV12() || clp.isYUY2() || clp.isYV16() || clp.isYV24() || clp.Is420() || clp.Is422() || clp.Is444() || clp.IsPlanarRGB() ||
clp.IsRGB() || clp.IsRGB24() || clp.IsRGB32() || clp.IsRGB48() || clp.IsRGB64()) ? true : false,
chr(10) + "Color Format not supported, only 4:2:0, 4:2:2, 4:4:4 and RGB planar are supported" + chr(10))

source = clp
clp.IsYV12() ? original="YV12"
clp.IsYUY2() ? original="YUY2"
clp.IsYV16() ? original="YV16"
clp.IsYV24() ? original="YV24"
clp.Is420() ? original="YUV420"
clp.Is422() ? original="YUV422"
clp.Is444() ? original="YUV444"
clp.IsRGB() ? original="RGB"
clp.IsRGB24() ? original="RGB24"
clp.IsRGB32() ? original="RGB32"
clp.IsRGB48() ? original="RGB48"
clp.IsRGB64() ? original="RGB64"

clp = clp.IsPlanarRGB() ? clp : clp.ConvertBits(bits=16).ConvertToPlanarRGB()

BT601_NTSC_to_BT709=myvalues
BT601_PAL_to_BT709=myvalues
BT709_to_BT601_NTSC=myvalues
BT709_to_BT601_PAL=myvalues
BT709_to_HLG=myvalues
BT709_to_PQ=myvalues
BT2100_HDR_PQ_to_BT2020_SDR=myvalues
CLog3_to_BT709=myvalues
CLog3_to_HDR_HLG=myvalues
CLog3_to_HDR_PQ=myvalues
DCIXYZ_to_YUVBT709=myvalues
HLG_to_BT709=myvalues
HLG_to_PQ=myvalues
LogC_to_BT709=myvalues
PQ_to_BT709_v1=myvalues
PQ_to_HLG=myvalues
Slog2_to_BT709=myvalues
Slog3_to_BT709=myvalues
Vlog_to_BT709=myvalues
YUVBT709_to_DCIXYZ=myvalues
Z-Log_to_BT709=myvalues

Input="Linear_BT601_NTSC" && Output="LinearBT709" ? Cube(clp, BT601_NTSC_to_BT709, fullrange=true) : Null(copy="none")
Input="Linear_BT601_PAL" && Output="BT601_PAL_to_BT709" ? Cube(clp, BT601_PAL_to_BT709, fullrange=true) : Null(copy="none")
Input="LinearBT709" && Output="Linear_BT601_NTSC" ? Cube(clp, BT709_to_BT601_NTSC, fullrange=true) : Null(copy="none")
Input="LinearBT709" && Output="Linear_BT601_PAL" ? Cube(clp, BT709_to_BT601_PAL, fullrange=true) : Null(copy="none")
Input="LinearBT709" && Output="BT2020_HLG" ? Cube(clp, BT709_to_HLG, fullrange=true) : Null(copy="none")
Input="LinearBT709" && Output="BT2100_PQ" ? Cube(clp, BT709_to_PQ, fullrange=true) : Null(copy="none")
Input="BT2100_PQ" && Output="Linear_BT2020" ? Cube(clp, BT2100_HDR_PQ_to_BT2020_SDR, fullrange=true) : Null(copy="none")
Input="CLog3" && Output="Linear_BT709" ? Cube(clp, CLog3_to_BT709, fullrange=true) : Null(copy="none")
Input="CLog3" && Output="BT2020_HLG" ? Cube(clp, CLog3_to_HDR_HLG, fullrange=true) : Null(copy="none")
Input="CLog3" && Output="BT2100_PQ" ? Cube(clp, CLog3_to_HDR_PQ, fullrange=true) : Null(copy="none")
Input="DCI_XYZ" && Output="Linear_BT709" ? Cube(clp, DCIXYZ_to_YUVBT709, fullrange=true) : Null(copy="none")
Input="BT2020_HLG" && Output="Linear_BT709" ? Cube(clp, HLG_to_BT709, fullrange=true) : Null(copy="none")
Input="BT2020_HLG" && Output="BT2100_PQ" ? Cube(clp, HLG_to_PQ, fullrange=true) : Null(copy="none")
Input="LogC" && Output="Linear_BT709" ? Cube(clp, LogC_to_BT709, fullrange=true) : Null(copy="none")
Input="BT2100_PQ" && Output="Linear_BT709" ? Cube(clp, PQ_to_BT709_v1, fullrange=true) : Null(copy="none")
Input="BT2100_PQ" && Output="BT2020_HLG" ? Cube(clp, PQ_to_HLG, fullrange=true) : Null(copy="none")
Input="SLog2" && Output="Linear_BT709" ? Cube(clp, Slog2_to_BT709, fullrange=true) : Null(copy="none")
Input="SLog3" && Output="Linear_BT709" ? Cube(clp, Slog3_to_BT709, fullrange=true) : Null(copy="none")
Input="VLog" && Output="Linear_BT709" ? Cube(clp, Vlog_to_BT709, fullrange=true) : Null(copy="none")
Input="Linear_BT709" && Output="DCI_XYZ" ? Cube(clp, YUVBT709_to_DCIXYZ, fullrange=true) : Null(copy="none")
Input="Linear_BT709" && Output="DCI_XYZ" ? Cube(clp, Z-Log_to_BT709, fullrange=true) : Null(copy="none")

original="YV12" ? last.ConvertBits(bits=8, dither=1).ConverttoYV12() : last
original="YUY2" ? last.ConvertBits(bits=8, dither=1).ConverttoYUY2() : last
original="YV16" ? last.ConvertBits(bits=8, dither=1).ConverttoYV16() : last
original="YV24" ? last.ConvertBits(bits=8, dither=1).ConverttoYV24() : last
original="YUV420" ? last.ConverttoYUV420() : last
original="YUV422" ? last.ConverttoYUV422() : last
original="YUV444" ? last.ConverttoYUV444() : last
original="RGB" ? last.ConverttoRGB() : last
original="RGB24" ? last.ConverttoRGB24() : last
original="RGB32" ? last.ConverttoRGB32() : last
original="RGB48" ? last.ConverttoRGB48() : last
original="RGB64" ? last.ConverttoRGB64() : last



}




Last time I tried to do something with the Avisynth Scripting it was with VideoTek() and the sober-at-that-time StainlessS came into help. Will he come in rescue this time as well or will it be someone else? Who knows...

By the way, sorry in advance to whoever will read my crappy code

ChaosKing
17th June 2020, 13:57
Isn't elseif() {} just more or less a short version of else { if() {} } ?

You can use nested inline if statements

blankclip()
a = false
b = false

text = a ? "a=true" : b ? "b=true" : "b=false"
subtitle(text)

StainlessS
17th June 2020, 16:10
I would expect the below line to fail due to missing line continuation '\' characters on extra lines

Assert( ( clp.isYV12() || clp.isYUY2() || clp.isYV16() || clp.isYV24() || clp.Is420() || clp.Is422() || clp.Is444() || clp.IsPlanarRGB() ||
\ clp.IsRGB() || clp.IsRGB24() || clp.IsRGB32() || clp.IsRGB48() || clp.IsRGB64()) ? true : false,
\ chr(10) + "Color Format not supported, only 4:2:0, 4:2:2, 4:4:4 and RGB planar are supported" + chr(10))


Below '== true' is superfluous when testing bool (which can be only true or false), compare to either true or false will actually fetch Global variable 'true' or 'false'
from Global variables table, and global variables are really quite slow to access.


If (aaa == true)
{
do something
}
else if ( bbb == true)
{
do something else
}


so instead of eg 'a == true', need (as ChaosKing did) just 'a', as in

text = a ? "a=true" : b ? "b=true" : "b=false"

When using as above, the test on 'a' will (I think) be done directly by parser, and is quick, same for '!a' which is equivalent to 'a==false'.

and the sober-at-that-time
I am deeply offended by that line, I'll have you know that I have never knowingly been sober without good reason.

Groucho2004
17th June 2020, 16:26
so instead of eg 'a == true', need (as ChaosKing did) just 'a', as in

text = a ? "a=true" : b ? "b=true" : "b=false"
I like these kind of conditionals, you can do cool stuff such as this:
bool isLeapYear(int year )
{
return year % 400 ? year % 100 ? year % 4 ? false : true : false : true;
}Well, this is C code but you get the idea.

StainlessS
17th June 2020, 17:07
so instead of eg 'a == true', need (as ChaosKing did) just 'a', as in

text = a ? "a=true" : b ? "b=true" : "b=false"



In actual fact it should perhaps be this

text = a ? "a=true" : b ? "b=true" : "a=false && b=false"


Well, this is C code but you get the idea.
Avs script

Function isLeapYear(int year) { return (year % 400)!=0 ? (year % 100)!=0 ? (year % 4)!=0 ? false : true : false : true }

for(i=0,3000,100) {
RT_DebugF("%4d] %s",i,i.isLeapYear)
}



00000436 0.19900697 RT_DebugF: 0] True
00000437 0.19911566 RT_DebugF: 100] False
00000438 0.19921313 RT_DebugF: 200] False
00000439 0.19930732 RT_DebugF: 300] False
00000440 0.19982870 RT_DebugF: 400] True
00000441 0.19983993 RT_DebugF: 500] False
00000442 0.19997905 RT_DebugF: 600] False
00000443 0.20008123 RT_DebugF: 700] False
00000444 0.20018087 RT_DebugF: 800] True
00000445 0.20028014 RT_DebugF: 900] False
00000446 0.20037977 RT_DebugF: 1000] False
00000447 0.20047905 RT_DebugF: 1100] False
00000448 0.20057796 RT_DebugF: 1200] True
00000449 0.20067760 RT_DebugF: 1300] False
00000450 0.20077759 RT_DebugF: 1400] False
00000451 0.20087615 RT_DebugF: 1500] False
00000452 0.20097686 RT_DebugF: 1600] True
00000453 0.20107687 RT_DebugF: 1700] False
00000454 0.20117651 RT_DebugF: 1800] False
00000455 0.20127578 RT_DebugF: 1900] False
00000456 0.20137469 RT_DebugF: 2000] True
00000457 0.20147397 RT_DebugF: 2100] False
00000458 0.20157360 RT_DebugF: 2200] False
00000459 0.20167288 RT_DebugF: 2300] False
00000460 0.20177324 RT_DebugF: 2400] True
00000461 0.20187323 RT_DebugF: 2500] False
00000462 0.20197323 RT_DebugF: 2600] False
00000463 0.20207323 RT_DebugF: 2700] False
00000464 0.20217106 RT_DebugF: 2800] True
00000465 0.20227033 RT_DebugF: 2900] False
00000466 0.20236960 RT_DebugF: 3000] False


I guess Grouchy also has Roman and Chinese Leap months, and also Leap seconds well sewn up too.

EDIT:
Or maybe easier figuroutable,

Function isLeapYear(int year) { return (year % 400)==0 ? true : (year % 100)==0 ? false : (year % 4)==0 }

EDIT: Oops, added in blue

ChaosKing
17th June 2020, 20:53
In actual fact it should perhaps be this

text = a ? "a=true" : b ? "b=true" : "a=false && b=false"



If you care about a=false, then yes. But a=false wasn't in FranceBB example, so... :D

Boulder
18th June 2020, 09:11
I like these kind of conditionals, you can do cool stuff such as this:
bool isLeapYear(int year )
{
return year % 400 ? year % 100 ? year % 4 ? false : true : false : true;
}Well, this is C code but you get the idea.

Hehe, the chain of what ifs gets quite confusing there. Are they parsed like parentheses so that the last "true" applies to the case of "year % 400" being false?

Groucho2004
18th June 2020, 12:28
Hehe, the chain of what ifs gets quite confusing there. Are they parsed like parentheses so that the last "true" applies to the case of "year % 400" being false?Nested conditional ternary operators:
https://stackoverflow.com/questions/20712745/c-nested-conditional-operator-loop
https://stackoverflow.com/questions/27942835/c-nested-conditional-operator-order-of-evaluation

feisty2
18th June 2020, 16:17
it's actually a binary tree structure, you go to the left child if the condition is satisfied, otherwise you go to the right child, the evaluation completes whenever you reach a leaf node.

root: x % 400 != 0, left child: node A, right child (leaf): true
node A: x % 100 !=0, left child: node B, right child (leaf): false
node B: x % 4 != 0, left child (leaf): false, right child (leaf): true

there're better ways to handle this kinda stuff than cryptic nested ?: operators

Gavino
18th June 2020, 16:23
there're better ways to handle this kinda stuff than cryptic nested ?: operators
Obviously. :rolleyes:
But the whole point of Groucho's amusing post was to make it look as cryptic as possible.

feisty2
18th June 2020, 16:57
make it look as cryptic as possible.

sure


auto btree_eval(auto x, auto cond, auto lchild, auto ...p) {
if (cond(x))
return lchild;
else
if constexpr (sizeof...(p) == 0)
return !lchild;
else
return btree_eval(x, p...);
}

for (auto x = 0; x <= 3000; x += 100)
std::cout << x << ": " << btree_eval(x,
[](auto x) { return x % 400 == 0; }, true,
[](auto x) { return x % 100 == 0; }, false,
[](auto x) { return x % 4 == 0; }, true
) << std::endl;


https://godbolt.org/z/WbHspP

Groucho2004
18th June 2020, 18:12
Obviously. :rolleyes:
But the whole point of Groucho's amusing post was to make it look as cryptic as possible.Hehe, yeah.

However, if you think that's cryptic, check these (https://en.wikipedia.org/wiki/International_Obfuscated_C_Code_Contest#Toledo_Nanochess) out.

StainlessS
18th June 2020, 18:55
More Crappy Code, not written by FranceBB [Other people can be equally adept in the crappy code department]


# C/CPP can treat int 0 as false, and anything other than 0 as true,
# so C/CPP can make decision based on value of int being zero or non-zero.
# AVS can only make decision on bool so to do same in AVS must convert int into bool,
# so where x is int, must use eg,
# C:= (x), <=====> AVS:= (x!=0) # True if x!=0, otherwise False (as x==0) : REMark (x==0) and (x!=0) both produce a bool.
# C:= (!x), <=====> AVS:= (x==0) # True if x==0, otherwise False (as x!=0)
/*
# Grouchy C/CPP version
bool isLeapYear_G(int year ) {
return year % 400 ? year % 100 ? year % 4 ? false : true : false : true;
}
*/

# AVS conversion of Grouchy C/CPP ternary conditional method. (Without Shortcut)
Function isLeapYear_G1(int year) { # <<<<<- Without Shortcut->>>>
Answer = (year % 400)!=0 ? (year % 100)!=0 ? (year % 4)!=0 ? false : true : false : true
return Answer
}

# AVS conversion #2 of Grouchy C/CPP, if/else method.
Function isLeapYear_G2(int year) {
if((year % 400)!=0) { # TEST_1
if((year % 100)!=0) { # TEST_2
if((year % 4)!=0) { # TEST_3
Answer = false # ANS_3B : TEST_1 SUCCEED, TEST_2 SUCCEED, return false based on TEST_3 SUCCEED
} else {
Answer = true # ANS_3A : TEST_1 SUCCEED, TEST_2 SUCCEED, return true based on TEST_3 FAIL
}
} else {
Answer = false # ANS_2 : TEST_1 SUCCEED, TEST_2 FAIL, 2nd least complex solution.
}
} else {
Answer = true # ANS_1 : If TEST_1 FAILS, then this is the least complex solution in the problem domain, ie we got the answer with least testing.
}
return Answer
}

# AVS conversion #3 of Grouchy C/CPP ternary conditional method, with logic shortcut
Function isLeapYear_G3(int year) { # <<-SHORTCUT=>>>
Answer = (year % 400)!=0 ? (year % 100)!=0 ? ((year % 4)==0) : false : true
return Answer
}

# AVS conversion #4 of Grouchy C/CPP, if/else method, with logic shortcut.
Function isLeapYear_G4(int year) {
if((year % 400)!=0) { # TEST_1
if((year % 100)!=0) { # TEST_2
Answer = ((year % 4)==0) # TEST_3 : ANS_3 : TEST_1 and TEST_2 SUCCEED, # SHORTCUT, Get true/false using ((year % 4)==0) instead of explict assignment of true or false.
} else {
Answer = false # ANS_2 : TEST_1 SUCCEED, TEST_2 FAIL, 2nd least complex solution.
}
} else {
Answer = true # ANS_1 : If TEST_1 FAIL, then this is the least complex solution in the problem domain, ie we got the answer with least testing.
}
return Answer
}

# AVS conversion using more easily figuroutable ternary conditional method.
Function isLeapYear_S1(int year) {
Answer = ((year % 400)==0) ? true : ((year % 100)==0) ? false : ((year % 4)==0) ? true : false
return Answer
}

# AVS conversion using more easily figuroutable, if/else method.
Function isLeapYear_S2(int year) {
if ((year % 400)==0) { # TEST_1
Answer = true # ANS_1 : If TEST_1 SUCCEEDS, then this is the least complex solution in the problem domain, ie we got the answer with least testing.
} else if((year % 100)==0) { # TEST_2
Answer = false # ANS_2 : TEST_1 FAILS, TEST_2 SUCCEEDS, 2nd least complex solution.
} else if ((year % 4)==0) { # TEST_3
Answer = true # ANS_3A : TEST_1 FAILS, TEST_2 FAILS, return true based on TEST_3 SUCCEED
} else {
Answer = false # ANS_3B : TEST_1 FAILS, TEST_2 FAILS, return false based on TEST_3 FAIL
}
return Answer
}

# AVS conversion using more easily figuroutable ternary conditional method, with logic shortcut
Function isLeapYear_S3(int year) { # <<-SHORTCUT=>>>
Answer = ((year % 400)==0) ? true : ((year % 100)==0) ? false : ((year % 4)==0) # Get final true/false using ((year % 4)==0) instead of explict assignment of true or false.
return Answer
}

# AVS conversion using more easily figuroutable if/else method, with logic shortcut
Function isLeapYear_S4(int year) {
if ((year % 400)==0) { # TEST_1
Answer = true # ANS_1 : If TEST_1 SUCCEEDS, then this is the least complex solution in the problem domain, ie we got the answer with least testing.
} else if((year % 100)==0) { # TEST_2
Answer = false # ANS_2 : TEST_1 FAILS, TEST_2 SUCCEEDS, 2nd least complex solution.
} else { # <<-SHORTCUT=>>>
Answer = ((year % 4)==0) # TEST_3 : ANS_3 : TEST_1 FAIL, TEST_2 FAIL, # SHORTCUT, Get true/false using ((year % 4)==0) instead of explict assignment of true or false.
}
return Answer
}

##################
##################
##################

ErrCnt=0
SSS=""
for(i=0,3000,1) {
G1=isLeapYear_G1(i)
G2=isLeapYear_G2(i)
G3=isLeapYear_G3(i)
G4=isLeapYear_G4(i)
S1=isLeapYear_S1(i)
S2=isLeapYear_S2(i)
S3=isLeapYear_S3(i)
S4=isLeapYear_S4(i)
AllSame = (G1==G2==G3==G4==S1==S2==S3==S4) # Cheeky jiggery pokery scripting, did not know if it would work, similar to eg Assert(0 <= digit <= 9,"Error 0 <= digit <= 9")
ErrCnt = (!AllSame) ? ErrCnt + 1 : ErrCnt # Check for errors on All Years
S=RT_String("%4d] %.1s%.1s%.1s%.1s%.1s%.1s%.1s%.1s :: All Same=%s",i,G1,G2,G3,G4,S1,S2,S3,S4,AllSame)
RT_DebugF("%s",S,Name="LEAP: ")
if((i % 100)==0) { # Only Show every 100 years
SSS=RT_string("%s%s\\n",SSS,S)
}
}
RT_DebugF("\nErrCnt=%d",ErrCnt,Name="LEAP: ")

BlankClip(width=480,height=640)
SSS=RT_string("%s\\nErrCnt=%d",SSS,ErrCnt)
Subtitle(SSS,font="CourierNew",lsp=0)
Return Last


https://i.postimg.cc/Y9X7m0MW/test-00.jpg (https://postimages.cc/)

feisty2
18th June 2020, 18:59
stainless, you skipped my version at #11, not cool :(

StainlessS
18th June 2020, 19:11
Sorry, I got no idea what that lot does :) [also I did not really see it]

feisty2
18th June 2020, 19:15
Sorry, I got no idea what that lot does :) [also I did not really see it]

it's just c++, click the link and see the code being compiled and executed at real time. you old folks must be very familiar with c++, right?

StainlessS
18th June 2020, 19:26
That looks a handy site if your wanting to clue up on Assembler, thanks, copied link.
[GeeksForGeeks.org has a similar online compiler test thingy (without asm)] :- https://www.geeksforgeeks.org/

you old folks must be very familiar with c++, right?
Not really, does it work on XP ?

EDIT: And not really relevant, but, did you know that a Venus day is longer than a Venus year ? [shock horror, maybe its a leap day].
["Not a lot of people know that" (In the melodic voice of Michael Caine)].

feisty2
18th June 2020, 19:49
That looks a handy site if your wanting to clue up on Assembler, thanks, copied link.
[GeeksForGeeks.org has a similar online compiler test thingy (without asm)] :- https://www.geeksforgeeks.org/


Not really, does it work on XP ?

sure, as long as you can find a compiler that supports c++20 and works on xp, there's no wording in the c++ standard that excludes xp support.

I translated the code at #11 to a more "nostalgic" kind of c++ that you grandpas might find easier to understand.

https://godbolt.org/z/acBwqF


#include <iostream>

typedef bool(*cond_type)(int);

bool btree_eval(int x, cond_type cond, bool lchild) {
if (cond(x))
return lchild;
else
return !lchild;
}

template<typename ...T>
bool btree_eval(int x, cond_type cond, bool lchild, T ...p) {
if (cond(x))
return lchild;
else
return btree_eval(x, p...);
}

bool cond1(int x) {
return x % 400 == 0;
}

bool cond2(int x) {
return x % 100 == 0;
}

bool cond3(int x) {
return x % 4 == 0;
}

int main() {
for (int x = 0; x <= 3000; x += 100) {
bool res = btree_eval(x, cond1, true, cond2, false, cond3, true);
std::cout << x << ": " << res << std::endl;
}
}


I think everything has been translated to c++98 syntax except for the variadic template (introduced in c++11) part, it is simply not possible to replicate the functionality of variadic templates in c++98.

you can now have another try! ;)

StainlessS
18th June 2020, 20:03
Not really, does it work on XP ?
I mean't Does C++ work on XP :) not that Gobble-de-gook stuff.

C++98, CPP11, C++20, who cares, Me likee proper C, without the jibberish :)

EDIT:
What I know about CPP was learnt on a 6 week course about Jan 1996 [1st week instructor was off sick so 5 weeks course],
I aint really read up any further than that.
[EDIT: And I never actually used CPP at all until I joined D9 in Dec 2009, indeed I gave up all coding except for a little bit VB6, just after doing above mentioned course]

feisty2
18th June 2020, 20:08
I mean't Does C++ work on XP :) not that Gobble-de-gook stuff.

C++98, CPP11, C++20, who cares, Me likee proper C, without the jibberish :)

oh, but c is so boring, it doesn't even have templates, no, forget about parameterized polymorphism, it doesn't even have ad hoc polymorphism, and no RAII, good luck with mem leaks :cool:

StainlessS
18th June 2020, 20:09
Yeh thats right, just the good stuff.

feisty2
18th June 2020, 21:06
Yeh thats right, just the good stuff.

well you asked for it, this is now 100% C
happy deciphering

https://godbolt.org/z/eLpo4n


#include <stdio.h>
#include <stdarg.h>

typedef bool(*cond_type)(int);

bool _btree_eval_(int n, int x, va_list args) {
cond_type cond = va_arg(args, cond_type);
bool lchild = va_arg(args, int);
if (cond(x))
return lchild;
else
if (n == 1)
return !lchild;
else
return _btree_eval_(n - 1, x, args);
}

bool btree_eval(int n, int x, ...) {
va_list args;
va_start(args, x);
bool res = _btree_eval_(n, x, args);
va_end(args);
return res;
}

bool cond1(int x) {
return x % 400 == 0;
}

bool cond2(int x) {
return x % 100 == 0;
}

bool cond3(int x) {
return x % 4 == 0;
}

int main() {
for (int x = 0; x <= 3000; x += 100) {
bool res = btree_eval(3, x, cond1, true, cond2, false, cond3, true);
printf("%d: %d\n", x, res);
}
}


edit: typo

StainlessS
18th June 2020, 22:23
I think that the best person to present the AVS variations in implementation of your impressive code would of course be your good self.
I am intrigued and even avid to know just how you will achieve this task.
I await with baited breath and on tenterhooks for your masterclass in C/CPP to AVS script conversion,
which will of course be so much better than the Grouchy effort.

Go Feisty go Feisty go !

feisty2
19th June 2020, 08:49
oh cmon stainless, don't ruin the fun
I haven't touched avs for like 4 or 5 years? my avs skills are now rusty, u are the true avs master here :)

Groucho2004
19th June 2020, 09:16
u are the true avs master here :)Agreed. :D

manolito
19th June 2020, 10:24
u are the true avs master here :)

Not wanting to insult anyone, but I think this crown belongs to Gavino... :cool:

StainlessS
19th June 2020, 10:40
Oh cmon feisty, Oh cmon Grouchy, now you're both blowing smoke up my jacksie, its me thats feelin' bloated https://www.cosgan.de/images/smilie/frech/s078.gif

https://www.cosgan.de/images/smilie/frech/s073.gif

EDIT: Cheers Mani, and agreed, you're the only sane one here, and I also think Gavino should do the binary tree thingy.

Gavino
19th June 2020, 17:38
I also think Gavino should do the binary tree thingy.
function btree_eval(int x, string c1, bool b1, string "c2", bool "b2", string "c3", bool "b3") {
c1.Apply(x) ? b1 : !Defined(c2) ? !b1 : btree_eval(x, c2, b2, c3, b3)
}

function cond1(int x) {
return x % 400 == 0
}

function cond2(int x) {
return x % 100 == 0
}

function cond3(int x) {
return x % 4 == 0
}

function isLeapYear(int x) {
return btree_eval(x, "cond1", true, "cond2", false, "cond3", true)
}

function yearString(int x) {
return string(x)+" : "+string(isLeapYear(x))
}

BlankClip(length=301, fps=2)
ScriptClip("""
Subtitle(yearString(current_frame*10), align=5)
""")
This uses only "classic" AVS.
It could probably be done neater in AVS+ using function variables, but I haven't caught up with that yet!

StainlessS
21st June 2020, 03:12
Lovely job Gavino, I'de forgotten totally that Apply() even existed.
Still, not as concise as

Function isLeapYear(int year) {Return ((year % 400)==0) ? true : ((year % 100)==0) ? false : ((year % 4)==0)}

I guess that feisty just likes typing or something. :)

FranceBB
22nd June 2020, 17:21
Ok, it's still me.
I'm trying to chainload if as suggested and indeed it works like a charm on a simple silly example I made.
I went on with the plugin I'm making and I came up with this draft, however it doesn't seem to work:


function LinearTransformation(clip clp, string Input, string Output)

{
mypath = "Z:\"
Assert( ( clp.isYV12() || clp.isYUY2() || clp.isYV16() || clp.isYV24() || clp.Is420() || clp.Is422() || clp.Is444() ||
\ clp.IsPlanarRGB() || clp.IsRGB() || clp.IsRGB24() || clp.IsRGB32() || clp.IsRGB48() || clp.IsRGB64())
\ ? true : false, chr(10) + "Color Format not supported, only 4:2:0, 4:2:2, 4:4:4 and RGB planar are supported" + chr(10))


source = clp
clp.IsYV12() ? original=="YV12"
\ : clp.IsYUY2() ? original=="YUY2"
\ : clp.IsYV16() ? original=="YV16"
\ : clp.IsYV24() ? original=="YV24"
\ : clp.Is420() ? original=="YUV420"
\ : clp.Is422() ? original=="YUV422"
\ : clp.Is444() ? original=="YUV444"
\ : clp.IsRGB() ? original=="RGB"
\ : clp.IsRGB24() ? original=="RGB24"
\ : clp.IsRGB32() ? original=="RGB32"
\ : clp.IsRGB48() ? original=="RGB48"
\ : clp.IsRGB64() ? original=="RGB64"
\ : original == "Null"

clp = clp.IsPlanarRGB() ? clp : clp.ConvertBits(bits=16).ConvertToPlanarRGB()

BT601_NTSC_to_BT709=mypath+BT601_NTSC_to_BT709.cube
BT601_PAL_to_BT709=mypath+BT601_PAL_to_BT709.cube
BT709_to_BT601_NTSC=mypath+BT709_to_BT601_NTSC.cube
BT709_to_BT601_PAL=mypath+BT709_to_BT601_PAL.cube
BT709_to_HLG=mypath+BT709_to_HLG.cube
BT709_to_PQ=mypath+BT709_to_PQ.cube
BT2100_HDR_PQ_to_BT2020_SDR=mypath+BT2100_HDR_PQ_to_BT2020_SDR.cube
CLog3_to_BT709=mypath+CLog3_to_BT709.cube
CLog3_to_HDR_HLG=mypath+CLog3_to_HDR_HLG.cube
CLog3_to_HDR_PQ=mypath+CLog3_to_HDR_PQ.cube
DCIXYZ_to_YUVBT709=mypath+DCIXYZ_to_YUVBT709.cube
HLG_to_BT709=mypath+HLG_to_BT709.cube
HLG_to_PQ=mypath+HLG_to_PQ.cube
LogC_to_BT709=mypath+LogC_to_BT709.cube
PQ_to_BT709_v1=mypath+PQ_to_BT709_v1.cube
PQ_to_HLG=mypath+PQ_to_HLG.cube
Slog2_to_BT709=mypath+Slog2_to_BT709.cube
Slog3_to_BT709=mypath+Slog3_to_BT709.cube
Vlog_to_BT709=mypath+Vlog_to_BT709.cube
YUVBT709_to_DCIXYZ=mypath+YUVBT709_to_DCIXYZ.cube
ZLog_to_BT709=mypath+ZLog_to_BT709.cube

Input=="Linear_BT601_NTSC" && Output=="LinearBT709" ? Cube(clp, BT601_NTSC_to_BT709, fullrange=true)
\ : Input=="Linear_BT601_PAL" && Output=="BT601_PAL_to_BT709" ? Cube(clp, BT601_PAL_to_BT709, fullrange=true)
\ : Input=="LinearBT709" && Output=="Linear_BT601_NTSC" ? Cube(clp, BT709_to_BT601_NTSC, fullrange=true)
\ : Input=="LinearBT709" && Output=="Linear_BT601_PAL" ? Cube(clp, BT709_to_BT601_PAL, fullrange=true)
\ : Input=="LinearBT709" && Output=="BT2020_HLG" ? Cube(clp, BT709_to_HLG, fullrange=true)
\ : Input=="LinearBT709" && Output=="BT2100_PQ" ? Cube(clp, BT709_to_PQ, fullrange=true)
\ : Input=="BT2100_PQ" && Output=="Linear_BT2020" ? Cube(clp, BT2100_HDR_PQ_to_BT2020_SDR, fullrange=true)
\ : Input=="CLog3" && Output=="Linear_BT709" ? Cube(clp, CLog3_to_BT709, fullrange=true)
\ : Input=="CLog3" && Output=="BT2020_HLG" ? Cube(clp, CLog3_to_HDR_HLG, fullrange=true)
\ : Input=="CLog3" && Output=="BT2100_PQ" ? Cube(clp, CLog3_to_HDR_PQ, fullrange=true)
\ : Input=="DCI_XYZ" && Output=="Linear_BT709" ? Cube(clp, DCIXYZ_to_YUVBT709, fullrange=true)
\ : Input=="BT2020_HLG" && Output=="Linear_BT709" ? Cube(clp, HLG_to_BT709, fullrange=true)
\ : Input=="BT2020_HLG" && Output=="BT2100_PQ" ? Cube(clp, HLG_to_PQ, fullrange=true)
\ : Input=="LogC" && Output=="Linear_BT709" ? Cube(clp, LogC_to_BT709, fullrange=true)
\ : Input=="BT2100_PQ" && Output=="Linear_BT709" ? Cube(clp, PQ_to_BT709_v1, fullrange=true)
\ : Input=="BT2100_PQ" && Output=="BT2020_HLG" ? Cube(clp, PQ_to_HLG, fullrange=true)
\ : Input=="SLog2" && Output=="Linear_BT709" ? Cube(clp, Slog2_to_BT709, fullrange=true)
\ : Input=="SLog3" && Output=="Linear_BT709" ? Cube(clp, Slog3_to_BT709, fullrange=true)
\ : Input=="VLog" && Output=="Linear_BT709" ? Cube(clp, Vlog_to_BT709, fullrange=true)
\ : Input=="Linear_BT709" && Output=="DCI_XYZ" ? Cube(clp, YUVBT709_to_DCIXYZ, fullrange=true)
\ : Input=="Linear_BT709" && Output=="DCI_XYZ" ? Cube(clp, ZLog_to_BT709, fullrange=true)
\ : Null()

original="YV12" ? last.ConvertBits(bits=8, dither=1).ConverttoYV12() : last
original="YUY2" ? last.ConvertBits(bits=8, dither=1).ConverttoYUY2() : last
original="YV16" ? last.ConvertBits(bits=8, dither=1).ConverttoYV16() : last
original="YV24" ? last.ConvertBits(bits=8, dither=1).ConverttoYV24() : last
original="YUV420" ? last.ConverttoYUV420() : last
original="YUV422" ? last.ConverttoYUV422() : last
original="YUV444" ? last.ConverttoYUV444() : last
original="RGB" ? last.ConverttoRGB() : last
original="RGB24" ? last.ConverttoRGB24() : last
original="RGB32" ? last.ConverttoRGB32() : last
original="RGB48" ? last.ConverttoRGB48() : last
original="RGB64" ? last.ConverttoRGB64() : last


}



When I call it


clp=ColorBars(848, 576, pixel_type="YUY2")

video=LinearTransformation(clp, Input="Linear_BT601_NTSC", Output="LinearBT709")

return video

it says "invalid argument to function LinearTransformation" without saying anything else, which makes it hard to debug...
Any idea?

EDIT: Is it because of the string addition I'm making? Can I do string addition just like that on Avisynth or do I have to store both into variables and then do string1+string2 ?

StainlessS
22nd June 2020, 20:39
function LinearTransformation(clip clp, string Input, string Output)
Args Input and Output are both non-optional [not enclosed in double quotes above].
As are non-optional, so cannot call with named args,
video=LinearTransformation(clp, "Linear_BT601_NTSC", "LinearBT709")
If named args required, then must signal that those args are optional, enclose in double quotes in prototype, ie
function LinearTransformation(clip clp, string "Input", string "Output")
and also, must provide defaults inside the function, eg

Input = Default(Input,"Linear_BT601_NTSC")
Output = Default(Output,""LinearBT709"")

Or whatever.

EDIT:
Below, remove in RED.

Assert( ( clp.isYV12() || clp.isYUY2() || clp.isYV16() || clp.isYV24() || clp.Is420() || clp.Is422() || clp.Is444() ||
\ clp.IsPlanarRGB() || clp.IsRGB() || clp.IsRGB24() || clp.IsRGB32() || clp.IsRGB48() || clp.IsRGB64())
\ ? true : false, chr(10) + "Color Format not supported, only 4:2:0, 4:2:2, 4:4:4 and RGB planar are supported" + chr(10))

StainlessS
23rd June 2020, 01:25
Function LinearTransformation(clip clp, string "Input", string "Output") {

Input = Default(Input ,"Linear_BT601_NTSC") # Assuming that you do want defaults
Output = Default(Output,"LinearBT709")

mypath = "Z:\"

# Removed IsRGB, that just means Any type of RGB at all, Interleaved, planar, any bit depth at all.
# We've used "RGBP" for Planar RGB
Original = clp.IsYV12 ? "YV12" : clp.IsYUY2 ? "YUY2" : clp.IsRGB24() ? "RGB24" : clp.IsRGB32() ? "RGB32"
\ : clp.IsYV16 ? "YV16" : clp.IsYV24 ? "YV24"
\ : clp.IsRGB48 ? "RGB48" : clp.IsRGB64 ? "RGB64" : clp.Is420 ? "YUV420" : clp.Is422 ? "YUV422" : clp.Is444() ? "YUV444"
\ : clp.IsPlanarRGB ? "RGBP"
\ : ""

Assert(original != "", "LinearTransformation: Color Format not supported," + Chr(10)+"only 4:2:0, 4:2:2, 4:4:4 and RGB are supported")

Bpc = clp.BitsPerComponent # original bits per component

clp = clp.ConvertToPlanarRGB().ConvertBits(bits=16) # If already PlanarRGB 16 bit then should do nearly nothing

CubeStr =
\ Input=="Linear_BT601_NTSC" && Output=="LinearBT709" ? "BT601_NTSC_to_BT709"
\ : Input=="Linear_BT601_PAL" && Output=="BT601_PAL_to_BT709" ? "BT601_PAL_to_BT709"
\ : Input=="LinearBT709" && Output=="Linear_BT601_NTSC" ? "BT709_to_BT601_NTSC"
\ : Input=="LinearBT709" && Output=="Linear_BT601_PAL" ? "BT709_to_BT601_PAL"
\ : Input=="LinearBT709" && Output=="BT2020_HLG" ? "BT709_to_HLG"
\ : Input=="LinearBT709" && Output=="BT2100_PQ" ? "BT709_to_PQ"
\ : Input=="BT2100_PQ" && Output=="Linear_BT2020" ? "BT2100_HDR_PQ_to_BT2020_SDR"
\ : Input=="CLog3" && Output=="Linear_BT709" ? "CLog3_to_BT709"
\ : Input=="CLog3" && Output=="BT2020_HLG" ? "CLog3_to_HDR_HLG"
\ : Input=="CLog3" && Output=="BT2100_PQ" ? "CLog3_to_HDR_PQ"
\ : Input=="DCI_XYZ" && Output=="Linear_BT709" ? "DCIXYZ_to_YUVBT709"
\ : Input=="BT2020_HLG" && Output=="Linear_BT709" ? "HLG_to_BT709"
\ : Input=="BT2020_HLG" && Output=="BT2100_PQ" ? "HLG_to_PQ"
\ : Input=="LogC" && Output=="Linear_BT709" ? "LogC_to_BT709"
\ : Input=="BT2100_PQ" && Output=="Linear_BT709" ? "PQ_to_BT709_v1"
\ : Input=="BT2100_PQ" && Output=="BT2020_HLG" ? "PQ_to_HLG"
\ : Input=="SLog2" && Output=="Linear_BT709" ? "Slog2_to_BT709"
\ : Input=="SLog3" && Output=="Linear_BT709" ? "Slog3_to_BT709"
\ : Input=="VLog" && Output=="Linear_BT709" ? "Vlog_to_BT709"
\ : Input=="Linear_BT709" && Output=="DCI_XYZ" ? "YUVBT709_to_DCIXYZ"
\ : Input=="Linear_BT709" && Output=="DCI_XYZ" ? "ZLog_to_BT709"
\ : ""

Assert(CubeStr != "","LinearTransformation: Unknown Cube, Input='"+Input+"' Output='"+Output+"'" )

Cube(clp, myPath + CubeStr + ".cube", fullrange=true)

out = Last.ConvertBits(bits=bpc, dither=1)

out = original == "YV12" ? out.ConverttoYV12
\ : original == "YUY2" ? out.ConverttoYUY2
\ : original == "RGB24" ? out.ConverttoRGB24
\ : original == "RGB32" ? out.ConverttoRGB32
\ : original == "YV16" ? out.ConverttoYV16
\ : original == "YV24" ? out.ConverttoYV24
\ : original == "RGB48" ? out.ConverttoRGB48
\ : original == "RGB64" ? out.ConverttoRGB64
\ : original == "YUV420" ? out.ConverttoYUV420
\ : original == "YUV422" ? out.ConverttoYUV422
\ : original == "YUV444" ? out.ConverttoYUV444
\ : out [* Must be RGBP *]
return out
}

I by no means have any idea bout your cube whotsits, but above might help a bit, I hope.
EDIT: Totally untested.
EDIT: No checks on Colorspace with Alpha channel.

FranceBB
23rd June 2020, 10:15
Thank you very much indeed for your useful insights and for the corrected code as well.
It definitely works.
As for the Cube thing, it basically allows LUT (matrices) to be used to apply a linear transformation: since a linear transformation maps each and every point of a space into another, such a transformation applies also to the points defining a color curve, in this case PQ, HLG, Slog, Clog, LogC, ZLog and so on.
I already released the matrices in the topic I keep updated in the General Section (FranceBB LUT Collection (https://forum.doom9.org/showthread.php?t=176091)), however I wanted to make something more user-friendly for users. :)

(I don't know whether you're into linear algebra or not, but if you're interested, please watch this series of videos made by Grant Sanderson, they're extremely well done and they'll give you an high-level overview of the mathematical field I love most: Link (https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab)
I think there's hardly anything more beautiful than a perfectly conceived linear transformation in this world.)

StainlessS
23rd June 2020, 22:24
I don't know whether you're into linear algebra or not
Hehehe, not really. [I got text books on the subject, but successfully resist the temptation of reading them].

I note that you have both "Linear_BT709" and "LinearBT709", is that intended ?

EDIT:
Made some changes, in BLUE

Function LinearTransformation(clip clp, string "Input", string "Output") {

Input = Default(Input ,"Linear_BT601_NTSC") # Assuming that you do want defaults
Output = Default(Output,"LinearBT709")

mypath = "Z:\"

# Removed IsRGB, that just means Any type of RGB at all, Interleaved, planar, any bit depth at all.
# We've used "RGBP" for Planar RGB
Original = clp.IsYV12 ? "YV12" : clp.IsYUY2 ? "YUY2" : clp.IsRGB24() ? "RGB24" : clp.IsRGB32() ? "RGB32"
\ : clp.IsYV16 ? "YV16" : clp.IsYV24 ? "YV24"
\ : clp.IsRGB48 ? "RGB48" : clp.IsRGB64 ? "RGB64" : clp.Is420 ? "YUV420" : clp.Is422 ? "YUV422" : clp.Is444() ? "YUV444"
\ : clp.IsPlanarRGB ? "RGBP"
\ : ""

Assert(original != "", "LinearTransformation: Color Format not supported," + Chr(10)+"only 4:2:0, 4:2:2, 4:4:4 and RGB are supported")

Bpc = clp.BitsPerComponent # original bits per component

clp = (Original=="YUY2") ? clp.ConvertToYV16 : clp # There is not 16 bit version of YUY2


# Convert to 16 bit first, reduce YUV -> RGB colorspace conversion losses
clp = clp.ConvertBits(bits=16).ConvertToPlanarRGB # If already PlanarRGB 16 bit then should do nearly nothing


CubeStr =
\ Input=="Linear_BT601_NTSC" && Output=="LinearBT709" ? "BT601_NTSC_to_BT709"
\ : Input=="Linear_BT601_PAL" && Output=="BT601_PAL_to_BT709" ? "BT601_PAL_to_BT709"
\ : Input=="LinearBT709" && Output=="Linear_BT601_NTSC" ? "BT709_to_BT601_NTSC"
\ : Input=="LinearBT709" && Output=="Linear_BT601_PAL" ? "BT709_to_BT601_PAL"
\ : Input=="LinearBT709" && Output=="BT2020_HLG" ? "BT709_to_HLG"
\ : Input=="LinearBT709" && Output=="BT2100_PQ" ? "BT709_to_PQ"
\ : Input=="BT2100_PQ" && Output=="Linear_BT2020" ? "BT2100_HDR_PQ_to_BT2020_SDR"
\ : Input=="CLog3" && Output=="Linear_BT709" ? "CLog3_to_BT709"
\ : Input=="CLog3" && Output=="BT2020_HLG" ? "CLog3_to_HDR_HLG"
\ : Input=="CLog3" && Output=="BT2100_PQ" ? "CLog3_to_HDR_PQ"
\ : Input=="DCI_XYZ" && Output=="Linear_BT709" ? "DCIXYZ_to_YUVBT709"
\ : Input=="BT2020_HLG" && Output=="Linear_BT709" ? "HLG_to_BT709"
\ : Input=="BT2020_HLG" && Output=="BT2100_PQ" ? "HLG_to_PQ"
\ : Input=="LogC" && Output=="Linear_BT709" ? "LogC_to_BT709"
\ : Input=="BT2100_PQ" && Output=="Linear_BT709" ? "PQ_to_BT709_v1"
\ : Input=="BT2100_PQ" && Output=="BT2020_HLG" ? "PQ_to_HLG"
\ : Input=="SLog2" && Output=="Linear_BT709" ? "Slog2_to_BT709"
\ : Input=="SLog3" && Output=="Linear_BT709" ? "Slog3_to_BT709"
\ : Input=="VLog" && Output=="Linear_BT709" ? "Vlog_to_BT709"
\ : Input=="Linear_BT709" && Output=="DCI_XYZ" ? "YUVBT709_to_DCIXYZ"
\ : Input=="Linear_BT709" && Output=="DCI_XYZ" ? "ZLog_to_BT709"
\ : ""

Assert(CubeStr != "","LinearTransformation: Unknown Cube, Input='"+Input+"' Output='"+Output+"'" )

Cube(clp, myPath + CubeStr + ".cube", fullrange=true)

out = Last.ConvertBits(bits=bpc, dither=1)

out = original == "YV12" ? out.ConverttoYV12
\ : original == "YUY2" ? out.ConverttoYUY2
\ : original == "RGB24" ? out.ConverttoRGB24
\ : original == "RGB32" ? out.ConverttoRGB32
\ : original == "YV16" ? out.ConverttoYV16
\ : original == "YV24" ? out.ConverttoYV24
\ : original == "RGB48" ? out.ConverttoRGB48
\ : original == "RGB64" ? out.ConverttoRGB64
\ : original == "YUV420" ? out.ConverttoYUV420
\ : original == "YUV422" ? out.ConverttoYUV422
\ : original == "YUV444" ? out.ConverttoYUV444
\ : out [* Must be RGBP *]
return out
}

FranceBB
24th June 2020, 09:48
Hehehe, not really. [I got text books on the subject, but successfully resist the temptation of reading them].

Oh... that's too bad... :(


I note that you have both "Linear_BT709" and "LinearBT709", is that intended ?


Absolutely not, I'm gonna put everything as "Linear_BT709".
Besides, I'm also gonna modify the default value as I want it to do nothing and just pass last if no input and no output are specified 'cause I don't really want it to do some kind of unknown conversion without the user knowing it.
In the future, I don't know whether I'm gonna make other matrices or if I'm gonna take the easy road and chain-load different linear transformation to do like PQ -> Linear BT709 -> Linear BT601, 'cause doing something like PQ -> Linear BT601 would require me to write a new matrix from scratch. I don't know, probably I'll make a new matrix from scratch...

By the way, thank you again.

StainlessS
24th June 2020, 10:39
Maybe make defaults both "", and if either one of them not set then throw error. (Or make them non optional but you get the less informative "Invalid arguments" style message from Avs when missing)
Assert(input!="" && output!="", "LinearTransformation: Need both Input and Output")
Best if user knows there is 'nuttin doin'. (Best he/she/it dont call at all if intended not to do anything).

feisty2
24th June 2020, 12:05
i just noticed that you still have to specify the type for the parameters of avs functions, this is bad, the parameter types should be automatically deduced from the arguments when the function is invoked.

StainlessS
24th June 2020, 13:21
No you dont, default is Val, ie any type,
val
A generic type name. It is applicable only inside a user defined script function's argument list, in order to be able to declare an argument variable to be of any type (int, float, bool, string, or clip). You must then explicitly test for its type (using the boolean functions) and take appropriate actions.

Although is somewhat unwise to use those unless explicit reason.
Feisty likes to break convention, and also compatiblity, take what he says with a large pinch of Sodium Chloride. :)

FBB,
coupla mods, NOTE the "???" marked. [I grouped similar inputs together]


Function LinearTransformation(clip clp, string "Input", string "Output") {
clp # Last = clp
Input = Default(Input ,"")
Output = Default(Output,"")
Assert(Input!="" && Output!="", "LinearTransformation: Need both Input and Output")

# Only Do something if Input Not same as Output
if(Input != Output) {
mypath = "Z:\"

Original = IsYUY2 ? "YUY2" : IsYV12||Is420 ? "YUV420" : IsYV16||Is422 ? "YUV422" : IsYV24||Is444 ? "YUV444"
\ : IsRGB24 ? "RGB24" : IsRGB32 ? "RGB32" : IsRGB48 ? "RGB48" : IsRGB64 ? "RGB64" :
\ : IsPlanarRGB ? "RGBP"
\ : ""

Assert(original != "", "LinearTransformation: Color Format not supported," + Chr(10)+"only 4:2:0, 4:2:2, 4:4:4, YUY2, and RGB are supported")
Bpc = BitsPerComponent # original bits per component

(Original=="YUY2") ? ConvertToYV16 : NOP # There is no 16 bit version of YUY2

# Convert to 16 bit first, reduce YUV -> RGB colorspace conversion losses
ConvertBits(bits=16).ConvertToPlanarRGB # If already PlanarRGB 16 bit then should do nearly nothing

CubeStr =
\ Input=="Linear_BT601_NTSC" && Output=="Linear_BT709" ? "BT601_NTSC_to_BT709"
\ : Input=="Linear_BT601_PAL" && Output=="BT601_PAL_to_BT709" ? "BT601_PAL_to_BT709"
\ : Input=="Linear_BT709" && Output=="Linear_BT601_NTSC" ? "BT709_to_BT601_NTSC"
\ : Input=="Linear_BT709" && Output=="Linear_BT601_PAL" ? "BT709_to_BT601_PAL"
\ : Input=="Linear_BT709" && Output=="BT2020_HLG" ? "BT709_to_HLG"
\ : Input=="Linear_BT709" && Output=="BT2100_PQ" ? "BT709_to_PQ"
\ : Input=="Linear_BT709" && Output=="DCI_XYZ" ? "YUVBT709_to_DCIXYZ" # ??? Same as below
\ : Input=="Linear_BT709" && Output=="DCI_XYZ" ? "ZLog_to_BT709" # ??? Presume wrong
\ : Input=="BT2100_PQ" && Output=="Linear_BT2020" ? "BT2100_HDR_PQ_to_BT2020_SDR"
\ : Input=="BT2100_PQ" && Output=="Linear_BT709" ? "PQ_to_BT709_v1"
\ : Input=="BT2100_PQ" && Output=="BT2020_HLG" ? "PQ_to_HLG"
\ : Input=="CLog3" && Output=="Linear_BT709" ? "CLog3_to_BT709"
\ : Input=="CLog3" && Output=="BT2020_HLG" ? "CLog3_to_HDR_HLG"
\ : Input=="CLog3" && Output=="BT2100_PQ" ? "CLog3_to_HDR_PQ"
\ : Input=="SLog2" && Output=="Linear_BT709" ? "Slog2_to_BT709"
\ : Input=="SLog3" && Output=="Linear_BT709" ? "Slog3_to_BT709"
\ : Input=="BT2020_HLG" && Output=="Linear_BT709" ? "HLG_to_BT709"
\ : Input=="BT2020_HLG" && Output=="BT2100_PQ" ? "HLG_to_PQ"
\ : Input=="DCI_XYZ" && Output=="Linear_BT709" ? "DCIXYZ_to_YUVBT709"
\ : Input=="LogC" && Output=="Linear_BT709" ? "LogC_to_BT709"
\ : Input=="VLog" && Output=="Linear_BT709" ? "Vlog_to_BT709"
\ : ""

Assert(CubeStr != "","LinearTransformation: Unknown Cube, Input='"+Input+"' Output='"+Output+"'" )

Cube(myPath + CubeStr + ".cube", fullrange=true)

ConvertBits(bits=bpc, dither=1) # To I/P Bpc bits Planar RGB

(original == "YUY2" ) ? ConvertToYUY2 : \
(original == "YUV420") ? ConvertToYUV420 : \ [* Includes YV12 *]
(original == "YUV422") ? ConvertToYUV422 : \ [* Includes YV16 *]
(original == "YUV444") ? ConvertToYUV444 : \ [* Includes YV24 *]
(original == "RGB24" ) ? ConvertToRGB24 : \
(original == "RGB32" ) ? ConvertToRGB32 : \
(original == "RGB48" ) ? ConvertToRGB48 : \
(original == "RGB64" ) ? ConvertToRGB64 : \
Last [* Must be RGBP *]
}
return Last
}

Still totally untested.

EDIT: I take it there are less conversion errors if convert from 16 bit RGB to output bits RGB with dither, before convert from RGB -> YUV,
rather than Convert RGB -> YUV at 16 bits, and then convert bits with dither to output bits.
Somebody say something if this is wrong.

EDIT: Not sure if below will produce an error, if so then just remove the [* ... *] comment

(original == "YUV420") ? ConvertToYUV420 : \ [* Includes YV12 *] # Appears after line continuation character '\'

FranceBB
24th June 2020, 16:05
FBB,
coupla mods, NOTE the "???" marked. [I grouped similar inputs together]


Yes, I corrected the error at that line as it should really be ZLog and not DCI.
As to the very last code, a normal if statement as your wrote doesn't work in Avisynth, however your last but one code was working absolutely fine.
This is that code with just a different error message and a fix in the repeated DCI boo boo:


Function LinearTransformation(clip clp, string "Input", string "Output") {

Input = Default(Input ,"")
Output = Default(Output,"")

mypath = "Z:\"

# Removed IsRGB, that just means Any type of RGB at all, Interleaved, planar, any bit depth at all.
# We've used "RGBP" for Planar RGB
Original = clp.IsYV12 ? "YV12" : clp.IsYUY2 ? "YUY2" : clp.IsRGB24() ? "RGB24" : clp.IsRGB32() ? "RGB32"
\ : clp.IsYV16 ? "YV16" : clp.IsYV24 ? "YV24"
\ : clp.IsRGB48 ? "RGB48" : clp.IsRGB64 ? "RGB64" : clp.Is420 ? "YUV420" : clp.Is422 ? "YUV422" : clp.Is444() ? "YUV444"
\ : clp.IsPlanarRGB ? "RGBP"
\ : ""

Assert(original != "", "LinearTransformation: Color Format not supported," + Chr(10)+"only 4:2:0, 4:2:2, 4:4:4 and RGB are supported")

Bpc = clp.BitsPerComponent # original bits per component

clp = (Original=="YUY2") ? clp.ConvertToYV16 : clp # There is not 16 bit version of YUY2


# Convert to 16 bit first, reduce YUV -> RGB colorspace conversion losses
clp = clp.ConvertBits(bits=16).ConvertToPlanarRGB # If already PlanarRGB 16 bit then should do nearly nothing


CubeStr =
\ Input=="Linear_BT601_NTSC" && Output=="Linear_BT709" ? "BT601_NTSC_to_BT709"
\ : Input=="Linear_BT601_PAL" && Output=="BT601_PAL_to_BT709" ? "BT601_PAL_to_BT709"
\ : Input=="Linear_BT709" && Output=="Linear_BT601_NTSC" ? "BT709_to_BT601_NTSC"
\ : Input=="Linear_BT709" && Output=="Linear_BT601_PAL" ? "BT709_to_BT601_PAL"
\ : Input=="Linear_BT709" && Output=="BT2020_HLG" ? "BT709_to_HLG"
\ : Input=="Linear_BT709" && Output=="BT2100_PQ" ? "BT709_to_PQ"
\ : Input=="Linear_BT709" && Output=="DCI_XYZ" ? "YUVBT709_to_DCIXYZ"
\ : Input=="Linear_BT709" && Output=="ZLog" ? "ZLog_to_BT709"
\ : Input=="BT2100_PQ" && Output=="Linear_BT2020" ? "BT2100_HDR_PQ_to_BT2020_SDR"
\ : Input=="BT2100_PQ" && Output=="Linear_BT709" ? "PQ_to_BT709_v1"
\ : Input=="BT2100_PQ" && Output=="BT2020_HLG" ? "PQ_to_HLG"
\ : Input=="CLog3" && Output=="Linear_BT709" ? "CLog3_to_BT709"
\ : Input=="CLog3" && Output=="BT2020_HLG" ? "CLog3_to_HDR_HLG"
\ : Input=="CLog3" && Output=="BT2100_PQ" ? "CLog3_to_HDR_PQ"
\ : Input=="SLog2" && Output=="Linear_BT709" ? "Slog2_to_BT709"
\ : Input=="SLog3" && Output=="Linear_BT709" ? "Slog3_to_BT709"
\ : Input=="BT2020_HLG" && Output=="Linear_BT709" ? "HLG_to_BT709"
\ : Input=="BT2020_HLG" && Output=="BT2100_PQ" ? "HLG_to_PQ"
\ : Input=="DCI_XYZ" && Output=="Linear_BT709" ? "DCIXYZ_to_YUVBT709"
\ : Input=="LogC" && Output=="Linear_BT709" ? "LogC_to_BT709"
\ : Input=="VLog" && Output=="Linear_BT709" ? "Vlog_to_BT709"
\ : ""

Assert(CubeStr != "","LinearTransformation: Transformation not supported, please choose a valid input and output Input='"+Input+"' Output='"+Output+"'" )

Cube(clp, myPath + CubeStr + ".cube", fullrange=true)

out = Last.ConvertBits(bits=bpc, dither=1)

out = original == "YV12" ? out.ConverttoYV12
\ : original == "YUY2" ? out.ConverttoYUY2
\ : original == "RGB24" ? out.ConverttoRGB24
\ : original == "RGB32" ? out.ConverttoRGB32
\ : original == "YV16" ? out.ConverttoYV16
\ : original == "YV24" ? out.ConverttoYV24
\ : original == "RGB48" ? out.ConverttoRGB48
\ : original == "RGB64" ? out.ConverttoRGB64
\ : original == "YUV420" ? out.ConverttoYUV420
\ : original == "YUV422" ? out.ConverttoYUV422
\ : original == "YUV444" ? out.ConverttoYUV444
\ : out [* Must be RGBP *]
return out
}


Once again, thanks.
I think I can now change the default path to something like: C:\Program Files (x86)\AviSynth+\LUTs and then write some documentation and finally publish it in the FranceBB LUT Collection topic so that people can use it. :)
(and of course I'm gonna include e big fat thank you in the documentation)
Or... shall I make a different thread in the Avisynth section? I think that would be redundant, I feel like the FranceBB LUT Collection one is more appropriate.
Anyway, thank you, once again.
Next time I'll visit London (when this whole pandemic is gonna be over), you're in for a treat as I'm gonna offer you a beer.
By the way, I visit London quite often (generally 3 times a year or more for work-related purposes and other things) so I wouldn't mind meeting you there every time I get there.
When this thing is over we should really have a Doom9 meeting.

feisty2
24th June 2020, 16:29
I don't "like" to break convention and compatibility, I only break them if I think they are poorly designed.

and I think explicitly assigning types to variables is absolutely stupid, the type of a variable should be automatically deduced when it binds to a value.

StainlessS
24th June 2020, 16:35
if statement as your wrote doesn't work in Avisynth

BitsPerComponent & ConvertBits dont work in 2.6 std, nor do other functions used, even under only your code,
I dont see how it could possibly have worked totally problem-free under 2.60std.
[EDIT: Actually ConvertBits was originally protected by condition]

So must work in Avs 2.60 std ? [and no v2.58]

You can use GImport together with GScript under v2.60 std for if/else etc.

Next time I'll visit London ...
I am totally anti-social, and dont do that,
you are not the first to have made such an offer, all similar offers have been declined,
so its got nothing whatever to do with your being of repulsive personality or anything https://www.cosgan.de/images/smilie/froehlich/s0452.gif
but thank you anyways.

EDIT: PlanarRGB is Avs+ only.
EDIT: What colorspaces do your Cube whotsits work for ?

StainlessS
24th June 2020, 16:44
I don't "like" to break convention and compatibility, I only break them if I think they are poorly designed.

and I think explicitly assigning types to variables is absolutely stupid, the type of a variable should be automatically deduced when it binds to a value.

So, to cope with things as you would have them, you would need a helluva lot more code to deal with different types, and in each and every script function.
This would make it both more awkward to write and bigger and negate the abiltiy of avisynth to do type checking on arguements for you.
No thanks, I prefer to keep things a little more sane.

EDIT: As already stated, any scriptor can use Val arg type if they want to implement your more awkward methodology.
[I have done so on rare occasion when has been necessary].

feisty2
24th June 2020, 16:50
no, I don't manually check the type of each parameter so there would be no "helluva more code", it is the caller's responsibility to ensure all arguments passed to the callee are of the correct types.

edit:
my coding philosophy: allowing all correct programs is more important than preventing possibly incorrect programs.

Gavino
24th June 2020, 17:18
I think explicitly assigning types to variables is absolutely stupid, the type of a variable should be automatically deduced when it binds to a value.
Indeed, that's how Avisynth works.
Variables don't have a type, only values do.
And variables are free to be bound to values of any type.

However, the expected types of function arguments can be (and usually are) specified in the function declaration. This (aka type-checking) is a very good thing which enables errors to be detected at the point of call rather than later in the execution of the function body, helping the caller who, as you say, has "responsibility to ensure all arguments passed to the callee are of the correct types".

Note that specifying the argument type in this way does not contradict what I said earlier - it just facilitates the type-checking on the call rather than the script writer having to code it manually.
Values of any type can still be assigned to the argument inside the function if you really want to.

StainlessS
24th June 2020, 18:27
Feisty:
my coding philosophy: allowing all correct programs is more important than preventing possibly incorrect programs.

Maybe so, and that would perhaps work if feisty code was always the client [ie you have full confidence in yourself], but in Avs scripting, it
is not so guaranteed that the coder is as expert as your good self, you have to assume that client is an idiot, because sometimes they are.

No offence intended dudes/dudesses :)

EDIT: There is often a line to be drawn as to how much of an idiot ones client might be. [every conceivable error is rarely trapped]

EDIT: To below:
'auto' type just obfuscates code readability
Absolutely.

Groucho2004
24th June 2020, 18:30
I suppose I'm really old school, this 'auto' variable type introduced in C++ 11 is not for me.
When I look at other people's code or something I wrote years ago I like to go to the variable declaration to see what type I'm dealing with.
'auto' type just obfuscates code readability. My 2 c's.

feisty2
24th June 2020, 18:48
I suppose I'm really old school, this 'auto' variable type introduced in C++ 11 is not for me.
When I look at other people's code or something I wrote years ago I like to go to the variable declaration to see what type I'm dealing with.
'auto' type just obfuscates code readability. My 2 c's.

that means your variables and functions were poorly named, a proper name should provide everything you need to know about the variable.

take a look at my code: https://github.com/IFeelBloated/vsFilterScript/blob/master/Examples/GaussBlur.hxx
there is zero type declaration, but is it really hard to understand? or is it that you're just not used to such coding style.

Groucho2004
24th June 2020, 18:53
that means your variables and functions were poorly named, a proper name should provide everything you need to know about the variable.Not necessarily. I always name my variables according to type with prefixes such as 'dw' for DWORD, 'i' for int and so on. Still, many coders don't do that so sometimes the actual type is hard to track down.

Groucho2004
24th June 2020, 18:57
or is it that you're just not used to such coding style.That must be it.

manolito
24th June 2020, 18:59
Looks like a Culture Clash or Generation Clash to me...

Like Groucho I am VERY Old School, and my main programming language in the good old DOS times was Turbo Pascal 6. I always liked its strict typing requirement, this was an essential aspect of learning to program. In straight C there was no strict typing requirement, you could get away with very sloppy programming, but sooner or later this would bite you on the ass.