Tests for a proposed faster "-fx".
This page shows black-box tests performed on a new version of "-fx", comparing results to an old version of "-fx".
The tests were performed on my Windows 10 laptop. The CPU (Intel Core i7-4700MQ @2.40GHz) has 4 cores, and can run 8 threads. The IM version was v7.1.0-20, Q32, with HDRI and OpenMP. Two builds were created, for the old and new "-fx", and installed in the directories "%FXOLD%" and "%FXNEW%".
These tests are not exhaustive. I welcome any additions.
This is a companion page to New FX.
The script testPerf.bat runs a magick command for the old fx, and repeats it for the new fx. The command runs a "-fx" operation for each of the input strings in testPerf.txt. There are about 35 input strings.
Input size, pixels | Old "-fx" | New "-fx2" |
---|---|---|
10x10 | 2 second | 2 seconds |
100x10 | 4 seconds | 2 seconds |
100x100 | 14 seconds | 2 seconds |
1000x100 | 99 seconds | 4 seconds |
1000x1000 | ???? seconds | 9 seconds |
To test compatiblity, we run the same "-fx" operation using the old and new fx code, and find the RMSE distortion between the two results. The distortion is on a nominal scale of zero to one. If it is very close to zero, we consider the test has passed.
For accuracy, the results were compared to hand-calculations.
On my computer, the tests are run with the new fx installed at %FXNEW%:
set FXNEW=%IM7DEVFX2% set FXNEW=%IM7DEV2% set FXNEW
FXNEW=C:\cygwin64\home\Alan\imdevins711_10\bin\
As of 31-March-2023, I patch the file fx.c that is in directory %IM7DEV%.
set FXNEW=%IM7DEV% set FXNEW
FXNEW=C:\cygwin64\home\Alan\imdevins7114\bin\
call %IM7SRCFX%\snibgo\goodFxSyntax.bat
Tests with a single input image:
-fx input string | distortion |
---|---|
'0.000023M' | 0 |
'10 - 2 + 3' | 0 |
'10 * 2 + 3' | 0 |
'4 ^ 3 ^ 2' | 0 |
'0.3 ^ 1.5 ^ 2' | 0 |
'xx=1? xx:4' | 0 |
'-epsilon' | 0 |
'3-1 ? 4+5 : 6 ? 7 :2*3' | 0 |
'yy = 3-1 ? 4+5 : 6 ? 7 :2*3' | 0 |
'aa=56; yy = 3-3 ? 4+5 : 6 ? 2+aa+3 :2*3' | 0 |
'23+(+1)' | 0 |
'23+(-1)' | 0 |
'xx=23;-xx' | 0 |
'xx=23;-(xx+1)' | 0 |
'xx=23;-xx+1' | 0 |
'xx=23;xx-=2;xx' | 0 |
'xx=23; yy=34; xx+yy' | 0 |
'xx = yy = 2+3' | 0 |
'if (1,2,3)' | 0 |
'if (1,2,)' | 0 |
'if (1,,3)' | 0 |
'u<0.01 ? 1: u>0.99 ? 0: u' | 0 |
'if (u<0.01, 1, if (u>0.99, 0, u))' | 0 |
'mean' | 0 |
'mean.r' | 0 |
'u.mean' | 0 |
'u.mean.r' | 0 |
'#abd' | 0 |
'hsl(10%,20%,30%)' | 0 |
'u.saturation' | 0 |
'10 < i < 12' | 0 |
'(0.10 < i) && (i < 0.12)' | 0 |
'gray47' | 0 |
'r - gray47' | 0 |
'1/2' | 0 |
'(1.0/(1.0+exp(10.0*(0.5-u)))-0.006693)*1.0092503' | 0 |
'Xi=i-w/2; Yj=j-h/2; 1.2*(0.5-hypot(Xi,Yj)/70.0)+0.5' | 0 |
'for (prime=2, prime < 30, composite=0; for (nn=2, nn < (prime/2+1), if ((prime % nn) == 0, composite++, ); nn++); if (composite <= 0, debug(prime), ); prime++)' | 0 |
'channel ()' | 0 |
'channel (0.1, 0.2)' | 0 |
'i==10&&j==10?3:2; u' | 0 |
'(u>0.5 ? 0.123 : 0.456)' | 0 |
'if (u>0.5, 0.123, 0.456)' | 0 |
'1.01 - (u>0.5?0.123:0.456)' | 0 |
'1.01 - if (u>0.5, 0.123, 0.456)' | 0 |
'1.01 - (u>0.5?0.123:0.456) - 0.01' | 0 |
'1.01 - if (u>0.5, 0.123, 0.456) - 0.01' | 0 |
Tests with two input images:
-fx input string | distortion |
---|---|
'u' | 0 |
'v' | 0 |
's' | 0 |
'u[1]' | 0 |
'u.g' | 0 |
'v.g' | 0 |
's.g' | 0 |
'u[1].g' | 0 |
'mean' | 0 |
'u.mean' | 0 |
'v.mean' | 0 |
's.mean' | 0 |
'u[1].mean' | 0 |
'mean.g' | 0 |
'v.mean.g' | 0 |
'u[1]mean.g' | 0 |
'u.p{2,3}' | 0 |
'u.p[2,3]' | 0 |
'u.p{2,3}.g' | 0 |
'u.p[2,3].g' | 0 |
'v.p{2,3}' | 0 |
'v.p[2,3]' | 0 |
'v.p{2,3}.g' | 0 |
'v.p[2,3].g' | 0 |
'u[1].p{2,3}' | 0 |
'u[1].p[2,3]' | 0 |
'u[1].p{2,3}.g' | 0 |
'u[1].p[2,3].g' | 0 |
's.p{2,3}' | 0 |
's.p[2,3]' | 0 |
's.p{2,3}.g' | 0 |
's.p[2,3].g' | 0 |
'u.saturation' | 0 |
'v.saturation' | 0 |
's.saturation' | 0 |
'u[1].saturation' | 0 |
'u.p[1,2].saturation' | 0 |
'v.p[1,2].saturation' | 0 |
's.p[1,2].saturation' | 0 |
'u[1].p[1,2].saturation' | 0 |
'u-v+0.5' | 0 |
Tests that fail (they show significant differences):
-fx input string | distortion |
---|---|
'2300m' | 0 |
'23 ;' | 0 |
'23+(++1)' | 0 |
'23+(--1)' | 0 |
'xx=23;--xx' | 0 |
'xx=23;--xx+1' | 0 |
'xx=3; yy=xx++; yy' | 0 |
'iso=32; rone=rand(); rtwo=rand(); myn=sqrt(-2*ln(rone))*cos(2*Pi*rtwo); myntwo=sqrt(-2*ln(rtwo))* cos(2*Pi*rone); pnoise=sqrt(p)*myn*sqrt(iso)* channel(4.28,3.86,6.68,0)/255; max(0,p+pnoise)' | 0.131195 |
"2300m" has an SI prefix meaning "multiplied by 10-3", and the negative power doesn't work in the old "-fx".
"23 ;" shows different processing of the blank statement after the semi-colon. The old "-fx" returns 0 from blank statements. In the new "-fx", blank statements have no effect, so the return is whatever the previous statement returned.
Expressions with "rand()" give different results each time.
The old "-fx" has a problem with multiple unary prefixes:
%FXOLD%magick xc: -fx "23+(--2.5)" txt: %FXNEW%magick xc: -fx "23+(--2.5)" txt:
# ImageMagick pixel enumeration: 1,1,0,4294967295,srgb 0,0: (109521666023,109521666023,109521666023) #FFFFFFFFFFFFFFFFFFFFFFFF srgb(2550%,2550%,2550%) # ImageMagick pixel enumeration: 1,1,0,4294967295,srgb 0,0: (109521666023,109521666023,109521666023) #FFFFFFFFFFFFFFFFFFFFFFFF srgb(2550%,2550%,2550%)
I regard the new result to be correct.
For "xx=3; yy=xx++; yy", the old "-fx" returns zero. This is because it doesn't return a value from "xx++", but doesn't report a syntax problem and instead returns zero, which is used to set yy.
The script fmtTst.bat tests "-format %[string]" for the strings shown, for the old and new "-fx". There are two images, so two values are shown for each of the old and the new. It shows "same" when the outputs are identical, or "DIFFERENT" when they are different.
call %IM7SRCFX%\snibgo\fmtTst.bat
"-format %[fx:string]" using pixel operands without channel qualifiers are different because, as explained at New FX, the old "%[fx:u]" etc give an intensity, and the new versions give the red channel.
format string | old result | new result | same/different | ||
---|---|---|---|---|---|
"fx:u-1.23e-4" | 0.666544 | 0.666544 | 0.666544 | 0.666544 | same |
"fx:u-1.23e-4*2" | 0.666421 | 0.666421 | 0.666421 | 0.666421 | same |
"fx:u-gray47" | 0.196078 | 0.196078 | 0.196078 | 0.196078 | same |
"fx:u-gray47*2" | -0.27451 | -0.27451 | -0.27451 | -0.27451 | same |
"fx:u" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:v" | 0.4 | 0.4 | 0.4 | 0.4 | same |
"fx:s" | 0.666667 | 0.4 | 0.666667 | 0.4 | same |
"fx:u[0]" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:u[1-1]" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:u[1]" | 0.4 | 0.4 | 0.4 | 0.4 | same |
"fx:u.p[0,0]" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:v.p[0,0]" | 0.4 | 0.4 | 0.4 | 0.4 | same |
"fx:s.p[0,0]" | 0.666667 | 0.4 | 0.666667 | 0.4 | same |
"fx:u[0].p[0,0]" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:u[1-1].p[0,0]" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:u[1].p[0,0]" | 0.4 | 0.4 | 0.4 | 0.4 | same |
In cases where we don't have pixel operands without channel qualifiers, "-format %[fx:string]" give identical results.
format string | old result | new result | same/different | ||
---|---|---|---|---|---|
"fx:1.23e-4" | 0.000123 | 0.000123 | 0.000123 | 0.000123 | same |
"fx:1.23e-4*2" | 0.000246 | 0.000246 | 0.000246 | 0.000246 | same |
"fx:gray47" | 0.470588 | 0.470588 | 0.470588 | 0.470588 | same |
"fx:gray47*2" | 0.941176 | 0.941176 | 0.941176 | 0.941176 | same |
"fx:u-1.23e-4" | 0.666544 | 0.666544 | 0.666544 | 0.666544 | same |
"fx:u-1.23e-4*2" | 0.666421 | 0.666421 | 0.666421 | 0.666421 | same |
"fx:u-gray47" | 0.196078 | 0.196078 | 0.196078 | 0.196078 | same |
"fx:u-gray47*2" | -0.27451 | -0.27451 | -0.27451 | -0.27451 | same |
"fx:u" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:v" | 0.4 | 0.4 | 0.4 | 0.4 | same |
"fx:s" | 0.666667 | 0.4 | 0.666667 | 0.4 | same |
"fx:u[0]" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:u[1-1]" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:u[1]" | 0.4 | 0.4 | 0.4 | 0.4 | same |
"fx:u.p[0,0]" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:v.p[0,0]" | 0.4 | 0.4 | 0.4 | 0.4 | same |
"fx:s.p[0,0]" | 0.666667 | 0.4 | 0.666667 | 0.4 | same |
"fx:u[0].p[0,0]" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:u[1-1].p[0,0]" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:u[1].p[0,0]" | 0.4 | 0.4 | 0.4 | 0.4 | same |
"fx:u.g" | 0.733333 | 0.733333 | 0.733333 | 0.733333 | same |
"fx:v.g" | 0.333333 | 0.333333 | 0.333333 | 0.333333 | same |
"fx:s.g" | 0.733333 | 0.333333 | 0.733333 | 0.333333 | same |
"fx:u[0].g" | 0.733333 | 0.733333 | 0.733333 | 0.733333 | same |
"fx:u[1-1].g" | 0.733333 | 0.733333 | 0.733333 | 0.733333 | same |
"fx:u[1].g" | 0.333333 | 0.333333 | 0.333333 | 0.333333 | same |
"fx:u.p[0,0].g" | 0.733333 | 0.733333 | 0.733333 | 0.733333 | same |
"fx:v.p[0,0].g" | 0.333333 | 0.333333 | 0.333333 | 0.333333 | same |
"fx:s.p[0,0].g" | 0.733333 | 0.333333 | 0.733333 | 0.333333 | same |
"fx:u[0].p[0,0].g" | 0.733333 | 0.733333 | 0.733333 | 0.733333 | same |
"fx:u[1-1].p[0,0].g" | 0.733333 | 0.733333 | 0.733333 | 0.733333 | same |
"fx:u[1].p[0,0].g" | 0.333333 | 0.333333 | 0.333333 | 0.333333 | same |
"fx:u.saturation" | 0.428571 | 0.428571 | 0.428571 | 0.428571 | same |
"fx:v.saturation" | 0.2 | 0.2 | 0.2 | 0.2 | same |
"fx:s.saturation" | 0.428571 | 0.2 | 0.428571 | 0.2 | same |
"fx:u[0].saturation" | 0.428571 | 0.428571 | 0.428571 | 0.428571 | same |
"fx:u[1-1].saturation" | 0.428571 | 0.428571 | 0.428571 | 0.428571 | same |
"fx:u[1].saturation" | 0.2 | 0.2 | 0.2 | 0.2 | same |
"fx:u.p[0,0].saturation" | 0.428571 | 0.428571 | 0.428571 | 0.428571 | same |
"fx:v.p[0,0].saturation" | 0.2 | 0.2 | 0.2 | 0.2 | same |
"fx:s.p[0,0].saturation" | 0.428571 | 0.2 | 0.428571 | 0.2 | same |
"fx:u[0].p[0,0].saturation" | 0.428571 | 0.428571 | 0.428571 | 0.428571 | same |
"fx:u[1-1].p[0,0].saturation" | 0.428571 | 0.428571 | 0.428571 | 0.428571 | same |
"fx:u[1].p[0,0].saturation" | 0.2 | 0.2 | 0.2 | 0.2 | same |
"fx:u.median" | 0.755556 | 0.755556 | 0.755556 | 0.755556 | same |
"fx:v.median" | 0.333333 | 0.333333 | 0.333333 | 0.333333 | same |
"fx:s.median" | 0.755556 | 0.333333 | 0.755556 | 0.333333 | same |
"fx:u[0].median" | 0.755556 | 0.755556 | 0.755556 | 0.755556 | same |
"fx:u[1-1].median" | 0.755556 | 0.755556 | 0.755556 | 0.755556 | same |
"fx:u[1].median" | 0.333333 | 0.333333 | 0.333333 | 0.333333 | same |
"fx:u.median.r" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:v.median.r" | 0.4 | 0.4 | 0.4 | 0.4 | same |
"fx:s.median.r" | 0.666667 | 0.4 | 0.666667 | 0.4 | same |
"fx:u[0].median.r" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:u[1-1].median.r" | 0.666667 | 0.666667 | 0.666667 | 0.666667 | same |
"fx:u[1].median.r" | 0.4 | 0.4 | 0.4 | 0.4 | same |
"fx:u.median.g" | 0.733333 | 0.733333 | 0.733333 | 0.733333 | same |
"fx:v.median.g" | 0.333333 | 0.333333 | 0.333333 | 0.333333 | same |
"fx:s.median.g" | 0.733333 | 0.333333 | 0.733333 | 0.333333 | same |
"fx:u[0].median.g" | 0.733333 | 0.733333 | 0.733333 | 0.733333 | same |
"fx:u[1-1].median.g" | 0.733333 | 0.733333 | 0.733333 | 0.733333 | same |
"fx:u[1].median.g" | 0.333333 | 0.333333 | 0.333333 | 0.333333 | same |
"fx:u.median.b" | 0.866667 | 0.866667 | 0.866667 | 0.866667 | same |
"fx:v.median.b" | 0.266667 | 0.266667 | 0.266667 | 0.266667 | same |
"fx:s.median.b" | 0.866667 | 0.266667 | 0.866667 | 0.266667 | same |
"fx:u[0].median.b" | 0.866667 | 0.866667 | 0.866667 | 0.866667 | same |
"fx:u[1-1].median.b" | 0.866667 | 0.866667 | 0.866667 | 0.866667 | same |
"fx:u[1].median.b" | 0.266667 | 0.266667 | 0.266667 | 0.266667 | same |
"-format %[hex:string]" are entirely the same.
format string | old result | new result | same/different | ||
---|---|---|---|---|---|
"hex:1.23e-4" | 00080F9900080F9900080F99 | 00080F9900080F9900080F99 | 00080F9900080F9900080F99 | 00080F9900080F9900080F99 | same |
"hex:1.23e-4*2" | 00101F3200101F3200101F32 | 00101F3200101F3200101F32 | 00101F3200101F3200101F32 | 00101F3200101F3200101F32 | same |
"hex:gray47" | 787878787878787878787878 | 787878787878787878787878 | 787878787878787878787878 | 787878787878787878787878 | same |
"hex:gray47*2" | F0F0F0F0F0F0F0F0F0F0F0F0 | F0F0F0F0F0F0F0F0F0F0F0F0 | F0F0F0F0F0F0F0F0F0F0F0F0 | F0F0F0F0F0F0F0F0F0F0F0F0 | same |
"hex:u-1.23e-4" | AAA29B11BBB3AC22DDD5CE44 | AAA29B11BBB3AC22DDD5CE44 | AAA29B11BBB3AC22DDD5CE44 | AAA29B11BBB3AC22DDD5CE44 | same |
"hex:u-1.23e-4*2" | AA9A8B78BBAB9C89DDCDBEAB | AA9A8B78BBAB9C89DDCDBEAB | AA9A8B78BBAB9C89DDCDBEAB | AA9A8B78BBAB9C89DDCDBEAB | same |
"hex:u-gray47" | 323232324343434365656565 | 323232324343434365656565 | 323232324343434365656565 | 323232324343434365656565 | same |
"hex:u-gray47*2" | 000000000000000000000000 | 000000000000000000000000 | 000000000000000000000000 | 000000000000000000000000 | same |
"hex:u" | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | same |
"hex:v" | 666666665555555544444444 | 666666665555555544444444 | 666666665555555544444444 | 666666665555555544444444 | same |
"hex:s" | AAAAAAAABBBBBBBBDDDDDDDD | 666666665555555544444444 | AAAAAAAABBBBBBBBDDDDDDDD | 666666665555555544444444 | same |
"hex:u[0]" | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | same |
"hex:u[1-1]" | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | same |
"hex:u[1]" | 666666665555555544444444 | 666666665555555544444444 | 666666665555555544444444 | 666666665555555544444444 | same |
"hex:u.p[0,0]" | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | same |
"hex:v.p[0,0]" | 666666665555555544444444 | 666666665555555544444444 | 666666665555555544444444 | 666666665555555544444444 | same |
"hex:s.p[0,0]" | AAAAAAAABBBBBBBBDDDDDDDD | 666666665555555544444444 | AAAAAAAABBBBBBBBDDDDDDDD | 666666665555555544444444 | same |
"hex:u[0].p[0,0]" | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | same |
"hex:u[1-1].p[0,0]" | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | AAAAAAAABBBBBBBBDDDDDDDD | same |
"hex:u[1].p[0,0]" | 666666665555555544444444 | 666666665555555544444444 | 666666665555555544444444 | 666666665555555544444444 | same |
"hex:u.g" | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | same |
"hex:v.g" | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | same |
"hex:s.g" | BBBBBBBBBBBBBBBBBBBBBBBB | 555555555555555555555555 | BBBBBBBBBBBBBBBBBBBBBBBB | 555555555555555555555555 | same |
"hex:u[0].g" | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | same |
"hex:u[1-1].g" | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | same |
"hex:u[1].g" | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | same |
"hex:u.p[0,0].g" | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | same |
"hex:v.p[0,0].g" | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | same |
"hex:s.p[0,0].g" | BBBBBBBBBBBBBBBBBBBBBBBB | 555555555555555555555555 | BBBBBBBBBBBBBBBBBBBBBBBB | 555555555555555555555555 | same |
"hex:u[0].p[0,0].g" | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | same |
"hex:u[1-1].p[0,0].g" | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | same |
"hex:u[1].p[0,0].g" | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | same |
"hex:u.saturation" | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | same |
"hex:v.saturation" | 333333333333333333333333 | 333333333333333333333333 | 333333333333333333333333 | 333333333333333333333333 | same |
"hex:s.saturation" | 6DB6DB6D6DB6DB6D6DB6DB6D | 333333333333333333333333 | 6DB6DB6D6DB6DB6D6DB6DB6D | 333333333333333333333333 | same |
"hex:u[0].saturation" | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | same |
"hex:u[1-1].saturation" | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | same |
"hex:u[1].saturation" | 333333333333333333333333 | 333333333333333333333333 | 333333333333333333333333 | 333333333333333333333333 | same |
"hex:u.p[0,0].saturation" | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | same |
"hex:v.p[0,0].saturation" | 333333333333333333333333 | 333333333333333333333333 | 333333333333333333333333 | 333333333333333333333333 | same |
"hex:s.p[0,0].saturation" | 6DB6DB6D6DB6DB6D6DB6DB6D | 333333333333333333333333 | 6DB6DB6D6DB6DB6D6DB6DB6D | 333333333333333333333333 | same |
"hex:u[0].p[0,0].saturation" | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | same |
"hex:u[1-1].p[0,0].saturation" | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | 6DB6DB6D6DB6DB6D6DB6DB6D | same |
"hex:u[1].p[0,0].saturation" | 333333333333333333333333 | 333333333333333333333333 | 333333333333333333333333 | 333333333333333333333333 | same |
"hex:u.median" | C16C16C1C16C16C1C16C16C1 | C16C16C1C16C16C1C16C16C1 | C16C16C1C16C16C1C16C16C1 | C16C16C1C16C16C1C16C16C1 | same |
"hex:v.median" | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | same |
"hex:s.median" | C16C16C1C16C16C1C16C16C1 | 555555555555555555555555 | C16C16C1C16C16C1C16C16C1 | 555555555555555555555555 | same |
"hex:u[0].median" | C16C16C1C16C16C1C16C16C1 | C16C16C1C16C16C1C16C16C1 | C16C16C1C16C16C1C16C16C1 | C16C16C1C16C16C1C16C16C1 | same |
"hex:u[1-1].median" | C16C16C1C16C16C1C16C16C1 | C16C16C1C16C16C1C16C16C1 | C16C16C1C16C16C1C16C16C1 | C16C16C1C16C16C1C16C16C1 | same |
"hex:u[1].median" | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | same |
"hex:u.median.r" | AAAAAAAAAAAAAAAAAAAAAAAA | AAAAAAAAAAAAAAAAAAAAAAAA | AAAAAAAAAAAAAAAAAAAAAAAA | AAAAAAAAAAAAAAAAAAAAAAAA | same |
"hex:v.median.r" | 666666666666666666666666 | 666666666666666666666666 | 666666666666666666666666 | 666666666666666666666666 | same |
"hex:s.median.r" | AAAAAAAAAAAAAAAAAAAAAAAA | 666666666666666666666666 | AAAAAAAAAAAAAAAAAAAAAAAA | 666666666666666666666666 | same |
"hex:u[0].median.r" | AAAAAAAAAAAAAAAAAAAAAAAA | AAAAAAAAAAAAAAAAAAAAAAAA | AAAAAAAAAAAAAAAAAAAAAAAA | AAAAAAAAAAAAAAAAAAAAAAAA | same |
"hex:u[1-1].median.r" | AAAAAAAAAAAAAAAAAAAAAAAA | AAAAAAAAAAAAAAAAAAAAAAAA | AAAAAAAAAAAAAAAAAAAAAAAA | AAAAAAAAAAAAAAAAAAAAAAAA | same |
"hex:u[1].median.r" | 666666666666666666666666 | 666666666666666666666666 | 666666666666666666666666 | 666666666666666666666666 | same |
"hex:u.median.g" | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | same |
"hex:v.median.g" | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | same |
"hex:s.median.g" | BBBBBBBBBBBBBBBBBBBBBBBB | 555555555555555555555555 | BBBBBBBBBBBBBBBBBBBBBBBB | 555555555555555555555555 | same |
"hex:u[0].median.g" | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | same |
"hex:u[1-1].median.g" | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | BBBBBBBBBBBBBBBBBBBBBBBB | same |
"hex:u[1].median.g" | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | 555555555555555555555555 | same |
"hex:u.median.b" | DDDDDDDDDDDDDDDDDDDDDDDD | DDDDDDDDDDDDDDDDDDDDDDDD | DDDDDDDDDDDDDDDDDDDDDDDD | DDDDDDDDDDDDDDDDDDDDDDDD | same |
"hex:v.median.b" | 444444444444444444444444 | 444444444444444444444444 | 444444444444444444444444 | 444444444444444444444444 | same |
"hex:s.median.b" | DDDDDDDDDDDDDDDDDDDDDDDD | 444444444444444444444444 | DDDDDDDDDDDDDDDDDDDDDDDD | 444444444444444444444444 | same |
"hex:u[0].median.b" | DDDDDDDDDDDDDDDDDDDDDDDD | DDDDDDDDDDDDDDDDDDDDDDDD | DDDDDDDDDDDDDDDDDDDDDDDD | DDDDDDDDDDDDDDDDDDDDDDDD | same |
"hex:u[1-1].median.b" | DDDDDDDDDDDDDDDDDDDDDDDD | DDDDDDDDDDDDDDDDDDDDDDDD | DDDDDDDDDDDDDDDDDDDDDDDD | DDDDDDDDDDDDDDDDDDDDDDDD | same |
"hex:u[1].median.b" | 444444444444444444444444 | 444444444444444444444444 | 444444444444444444444444 | 444444444444444444444444 | same |
"-format %[pixel:string]" are entirely the same.
format string | old result | new result | same/different | ||
---|---|---|---|---|---|
"pixel:1.23e-4" | srgb(0.0123%,0.0123%,0.0123%) | srgb(0.0123%,0.0123%,0.0123%) | srgb(0.0123%,0.0123%,0.0123%) | srgb(0.0123%,0.0123%,0.0123%) | same |
"pixel:1.23e-4*2" | srgb(0.0246%,0.0246%,0.0246%) | srgb(0.0246%,0.0246%,0.0246%) | srgb(0.0246%,0.0246%,0.0246%) | srgb(0.0246%,0.0246%,0.0246%) | same |
"pixel:gray47" | srgb(120,120,120) | srgb(120,120,120) | srgb(120,120,120) | srgb(120,120,120) | same |
"pixel:gray47*2" | srgb(240,240,240) | srgb(240,240,240) | srgb(240,240,240) | srgb(240,240,240) | same |
"pixel:u-1.23e-4" | srgb(66.6544%,73.321%,86.6544%) | srgb(66.6544%,73.321%,86.6544%) | srgb(66.6544%,73.321%,86.6544%) | srgb(66.6544%,73.321%,86.6544%) | same |
"pixel:u-1.23e-4*2" | srgb(66.6421%,73.3087%,86.6421%) | srgb(66.6421%,73.3087%,86.6421%) | srgb(66.6421%,73.3087%,86.6421%) | srgb(66.6421%,73.3087%,86.6421%) | same |
"pixel:u-gray47" | srgb(50,67,101) | srgb(50,67,101) | srgb(50,67,101) | srgb(50,67,101) | same |
"pixel:u-gray47*2" | srgb(-27.451%,-20.7843%,-7.45098%) | srgb(-27.451%,-20.7843%,-7.45098%) | srgb(-27.451%,-20.7843%,-7.45098%) | srgb(-27.451%,-20.7843%,-7.45098%) | same |
"pixel:u" | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | same |
"pixel:v" | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | same |
"pixel:s" | srgb(170,187,221) | srgb(102,85,68) | srgb(170,187,221) | srgb(102,85,68) | same |
"pixel:u[0]" | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | same |
"pixel:u[1-1]" | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | same |
"pixel:u[1]" | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | same |
"pixel:u.p[0,0]" | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | same |
"pixel:v.p[0,0]" | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | same |
"pixel:s.p[0,0]" | srgb(170,187,221) | srgb(102,85,68) | srgb(170,187,221) | srgb(102,85,68) | same |
"pixel:u[0].p[0,0]" | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | same |
"pixel:u[1-1].p[0,0]" | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | srgb(170,187,221) | same |
"pixel:u[1].p[0,0]" | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | same |
"pixel:u.g" | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | same |
"pixel:v.g" | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | same |
"pixel:s.g" | srgb(187,187,187) | srgb(85,85,85) | srgb(187,187,187) | srgb(85,85,85) | same |
"pixel:u[0].g" | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | same |
"pixel:u[1-1].g" | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | same |
"pixel:u[1].g" | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | same |
"pixel:u.p[0,0].g" | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | same |
"pixel:v.p[0,0].g" | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | same |
"pixel:s.p[0,0].g" | srgb(187,187,187) | srgb(85,85,85) | srgb(187,187,187) | srgb(85,85,85) | same |
"pixel:u[0].p[0,0].g" | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | same |
"pixel:u[1-1].p[0,0].g" | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | same |
"pixel:u[1].p[0,0].g" | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | same |
"pixel:u.saturation" | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | same |
"pixel:v.saturation" | srgb(51,51,51) | srgb(51,51,51) | srgb(51,51,51) | srgb(51,51,51) | same |
"pixel:s.saturation" | srgb(42.8571%,42.8571%,42.8571%) | srgb(51,51,51) | srgb(42.8571%,42.8571%,42.8571%) | srgb(51,51,51) | same |
"pixel:u[0].saturation" | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | same |
"pixel:u[1-1].saturation" | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | same |
"pixel:u[1].saturation" | srgb(51,51,51) | srgb(51,51,51) | srgb(51,51,51) | srgb(51,51,51) | same |
"pixel:u.p[0,0].saturation" | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | same |
"pixel:v.p[0,0].saturation" | srgb(51,51,51) | srgb(51,51,51) | srgb(51,51,51) | srgb(51,51,51) | same |
"pixel:s.p[0,0].saturation" | srgb(42.8571%,42.8571%,42.8571%) | srgb(51,51,51) | srgb(42.8571%,42.8571%,42.8571%) | srgb(51,51,51) | same |
"pixel:u[0].p[0,0].saturation" | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | same |
"pixel:u[1-1].p[0,0].saturation" | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | srgb(42.8571%,42.8571%,42.8571%) | same |
"pixel:u[1].p[0,0].saturation" | srgb(51,51,51) | srgb(51,51,51) | srgb(51,51,51) | srgb(51,51,51) | same |
"pixel:u.median" | srgb(75.5556%,75.5556%,75.5556%) | srgb(75.5556%,75.5556%,75.5556%) | srgb(75.5556%,75.5556%,75.5556%) | srgb(75.5556%,75.5556%,75.5556%) | same |
"pixel:v.median" | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | same |
"pixel:s.median" | srgb(75.5556%,75.5556%,75.5556%) | srgb(85,85,85) | srgb(75.5556%,75.5556%,75.5556%) | srgb(85,85,85) | same |
"pixel:u[0].median" | srgb(75.5556%,75.5556%,75.5556%) | srgb(75.5556%,75.5556%,75.5556%) | srgb(75.5556%,75.5556%,75.5556%) | srgb(75.5556%,75.5556%,75.5556%) | same |
"pixel:u[1-1].median" | srgb(75.5556%,75.5556%,75.5556%) | srgb(75.5556%,75.5556%,75.5556%) | srgb(75.5556%,75.5556%,75.5556%) | srgb(75.5556%,75.5556%,75.5556%) | same |
"pixel:u[1].median" | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | same |
"pixel:u.median.r" | srgb(170,170,170) | srgb(170,170,170) | srgb(170,170,170) | srgb(170,170,170) | same |
"pixel:v.median.r" | srgb(102,102,102) | srgb(102,102,102) | srgb(102,102,102) | srgb(102,102,102) | same |
"pixel:s.median.r" | srgb(170,170,170) | srgb(102,102,102) | srgb(170,170,170) | srgb(102,102,102) | same |
"pixel:u[0].median.r" | srgb(170,170,170) | srgb(170,170,170) | srgb(170,170,170) | srgb(170,170,170) | same |
"pixel:u[1-1].median.r" | srgb(170,170,170) | srgb(170,170,170) | srgb(170,170,170) | srgb(170,170,170) | same |
"pixel:u[1].median.r" | srgb(102,102,102) | srgb(102,102,102) | srgb(102,102,102) | srgb(102,102,102) | same |
"pixel:u.median.g" | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | same |
"pixel:v.median.g" | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | same |
"pixel:s.median.g" | srgb(187,187,187) | srgb(85,85,85) | srgb(187,187,187) | srgb(85,85,85) | same |
"pixel:u[0].median.g" | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | same |
"pixel:u[1-1].median.g" | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | srgb(187,187,187) | same |
"pixel:u[1].median.g" | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | srgb(85,85,85) | same |
"pixel:u.median.b" | srgb(221,221,221) | srgb(221,221,221) | srgb(221,221,221) | srgb(221,221,221) | same |
"pixel:v.median.b" | srgb(68,68,68) | srgb(68,68,68) | srgb(68,68,68) | srgb(68,68,68) | same |
"pixel:s.median.b" | srgb(221,221,221) | srgb(68,68,68) | srgb(221,221,221) | srgb(68,68,68) | same |
"pixel:u[0].median.b" | srgb(221,221,221) | srgb(221,221,221) | srgb(221,221,221) | srgb(221,221,221) | same |
"pixel:u[1-1].median.b" | srgb(221,221,221) | srgb(221,221,221) | srgb(221,221,221) | srgb(221,221,221) | same |
"pixel:u[1].median.b" | srgb(68,68,68) | srgb(68,68,68) | srgb(68,68,68) | srgb(68,68,68) | same |
The script goodpc.bat tests examples of "%[...]" that were kindly supplied by GeeMack. (Many thanks, GeeMack!) For these tests, occurrences of "rand()" were changed to "0.23". This exposed two bugs in the new fx, now fixed, so all examples create identical outputs for the old and new fx code.
call %WebDisk%\web\im\geemack\goodpc.bat
format string | old result | new result | same/different | ||
---|---|---|---|---|---|
"%[fx:var=ceil(0.23*120+60);alt(var)*var]" | 88 | 88 | 88 | 88 | same |
"%[fx:t==0?0.23*32:t==1?0.23*32+16:0.23*32+32]" | 7.36 | 23.36 | 7.36 | 23.36 | same |
"%[pixel:p{0.23*w,0.23*h}]" | srgb(170,187,221) | srgb(102,85,68) | srgb(170,187,221) | srgb(102,85,68) | same |
"%[pixel:p{s.w/2,s.h/2}]" | srgb(170,187,221) | srgb(102,85,68) | srgb(170,187,221) | srgb(102,85,68) | same |
"%[pixel:u[-1].p{0.23*w,0.23*h}]" | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | same |
"%[pixel:u[-1].p{t*2,0}]" | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | same |
"%[pixel:u[-1].p{u[-1].w-2-(t*2),0}]" | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | srgb(102,85,68) | same |
"%[fx:(mean<0.5)*50]" | 0 | 50 | 0 | 50 | same |
"%[fx:(page.width>page.height)*30]" | 0 | 0 | 0 | 0 | same |
"%[fx:(t?80:60)-(mean*100)]" | -15.5556 | 46.6667 | -15.5556 | 46.6667 | same |
"%[fx:(w>h)*90]" | 0 | 0 | 0 | 0 | same |
"%[fx:180/page.y]" | 1.8e+14 | 1.8e+14 | 1.8e+14 | 1.8e+14 | same |
"%[fx:50-(mean*100)]" | -25.5556 | 16.6667 | -25.5556 | 16.6667 | same |
"%[fx:alt(int(0.23*100))*(0.23*30+15)]" | -21.9 | -21.9 | -21.9 | -21.9 | same |
"%[fx:alt(0.23*1000)*((0.23*h*0.025)+(h*0.025))]" | 0.03075 | 0.03075 | 0.03075 | 0.03075 | same |
"%[fx:alt(round(0.23))*(0.23*120+120)]" | 147.6 | 147.6 | 147.6 | 147.6 | same |
"%[fx:alt(t%2)*(round(0.23*5+4)*64)]" | 320 | -320 | 320 | -320 | same |
"%[fx:alt(t)*(0.23*30+15)]" | 21.9 | -21.9 | 21.9 | -21.9 | same |
"%[fx:alt(t)*w/2]" | 0.5 | -0.5 | 0.5 | -0.5 | same |
"%[fx:ceil(h*tan(pi/%SLICES%))]" | 1 | 1 | 1 | 1 | same |
"%[fx:ceil(h*tan(pi/page.x)*1.5)]" | -0 | -0 | -0 | -0 | same |
"%[fx:ceil(0.23*2)+1]" | 2 | 2 | 2 | 2 | same |
"%[fx:ceil(0.23*3)]" | 1 | 1 | 1 | 1 | same |
"%[fx:floor(n/2)-1]" | 0 | 0 | 0 | 0 | same |
"%[fx:floor(0.23*12)+8]" | 10 | 10 | 10 | 10 | same |
"%[fx:h-((t*h*0.05)+(h*0.1))]" | 0.9 | 0.85 | 0.9 | 0.85 | same |
"%[fx:hypot(w,h)-h]" | 0.414214 | 0.414214 | 0.414214 | 0.414214 | same |
"%[fx:int(0.23*2+2)]" | 2 | 2 | 2 | 2 | same |
"%[fx:max(page.width,page.height)*1.1]" | 1.1 | 1.1 | 1.1 | 1.1 | same |
"%[fx:max(u[-1].w,u[-1].h)*1.1]" | 1.1 | 1.1 | 1.1 | 1.1 | same |
"%[fx:n%2?0:n]" | 2 | 2 | 2 | 2 | same |
"%[fx:page.y+page.height]" | 1 | 1 | 1 | 1 | same |
"%[fx:0.23*(h*0.5)+(h*0.5)]" | 0.615 | 0.615 | 0.615 | 0.615 | same |
"%[fx:round(0.23)*180/page.x]" | 0 | 0 | 0 | 0 | same |
"%[fx:t*((u[-1].h-u[0].h)/n)+u[0].h]" | 1 | 1 | 1 | 1 | same |
"%[fx:t==0?0.23*32:t==1?0.23*32+16:0.23*32+32]" | 7.36 | 23.36 | 7.36 | 23.36 | same |
"%[fx:var=ceil(0.23*120+60);alt(var)*var]" | 88 | 88 | 88 | 88 | same |
Here are some invalid input strings, with each resulting error message. This error checking is done at translation, and has no impact on run-time performance.
call %IM7SRCFX%\snibgo\badFxSyntax fxnt_err.lis
-fx input string | Error message |
---|---|
23 /*+- | Expected operand at '*+-' @ error/fx.c/TranslateExpression/2653. |
23>> | Expected operand after operator at '' @ error/fx.c/TranslateExpression/2637. |
23 / | Expected operand after operator at '' @ error/fx.c/TranslateExpression/2637. |
10--2 | Attempted update to non-UserSymbol '' at '2' @ error/fx.c/TranslateExpression/2595. |
3-1 ? 4+5 ? 6 : 7 :2*3 | Already have '?' in sub-expression at '6 : 7 :2*3' @ error/fx.c/ProcessTernaryOpr/2376. |
? | Expected operand at '?' @ error/fx.c/GetOperand/2354. |
: | Expected operand at ':' @ error/fx.c/GetOperand/2354. |
3-1 ? : 4+5 | Expected operand at ': 4+5' @ error/fx.c/TranslateExpression/2653. |
aa=1 ? 34:45:56 | Need '?' in sub-expression at '56' @ error/fx.c/ProcessTernaryOpr/2396. |
aa=1 ? 34:45?56 | '?' with no corresponding ':' '' at '' @ error/fx.c/ResolveTernaryAddresses/2516. |
abs = 2+3 | Expected char '(' at '= 2+3' @ error/fx.c/ExpectChar/1279. |
r = 2+3 | Attempted assignment to non-UserSymbol 'r' at '2+3' @ error/fx.c/TranslateExpression/2588. |
epsilon = 2+3 | Attempted assignment to non-UserSymbol 'epsilon' at '2+3' @ error/fx.c/TranslateExpression/2588. |
s[0,1,2,3,4,5,6,7,8,9] | Not a real operator at '[0,1,2,3,4,5,6,7,8,9...' @ error/fx.c/GetOperator/2435. |
max(5,11,3,6) | For function 'max', arguments don't end with ')' at '3,6)' @ error/fx.c/GetFunction/1906. |
abs | Expected char '(' at '' @ error/fx.c/ExpectChar/1279. |
page.bad | Attribute 'page' needs qualifier at '' @ error/fx.c/GetImgAttrToken/1458. |
resolution.width | Attribute 'resolution' needs qualifier at '' @ error/fx.c/GetImgAttrToken/1458. |
u.bad | For function 'u', bad qualifier 'bad' at 'bad' @ error/fx.c/GetFunction/1969. |
page | Attribute 'page' needs qualifier at '' @ error/fx.c/GetImgAttrToken/1458. |
() | Empty expression in parentheses at '' @ error/fx.c/GetOperand/2089. |
(xx=123 | '(' but no ')' at '' @ error/fx.c/GetOperand/2096. |
abs () | For function 'abs' expected 1 arguments, found too few (0) at '' @ error/fx.c/GetFunction/1893. |
(3+ | Empty expression in parentheses at '' @ error/fx.c/GetOperand/2089. |
abs(12,) | For function 'abs', arguments don't end with ')' at ')' @ error/fx.c/GetFunction/1906. |
abs(12,34,56) | For function 'abs', arguments don't end with ')' at '34,56)' @ error/fx.c/GetFunction/1906. |
max(5,11,3,6) | For function 'max', arguments don't end with ')' at '3,6)' @ error/fx.c/GetFunction/1906. |
for (,,) | For function 'for' expected 3 arguments, found too few (0) at '' @ error/fx.c/GetFunction/1893. |
for (1,2) | For function 'for' expected 3 arguments, found too few (2) at '' @ error/fx.c/GetFunction/1893. |
mean.bad | Bad channel qualifier at 'bad' @ error/fx.c/GetOperand/2269. |
v | Symbol 'v' but fewer than two images at 'v' @ error/fx.c/GetOperand/2235. |
3 4 | Expected operator at '4' @ error/fx.c/GetOperator/2443. |
3 + * | Expected operand at '*' @ error/fx.c/TranslateExpression/2653. |
3 * | Expected operand after operator at '' @ error/fx.c/TranslateExpression/2637. |
3 ] | Not a real operator at ']' @ error/fx.c/GetOperator/2435. |
3 + 4 ) | Not a real operator at ')' @ error/fx.c/GetOperator/2435. |
3 ? 4 ? 5 : 6 | Already have '?' in sub-expression at '5 : 6' @ error/fx.c/ProcessTernaryOpr/2376. |
3 ? 4 : 5 : 6 | Need '?' in sub-expression at '6' @ error/fx.c/ProcessTernaryOpr/2396. |
3 : 4 | Need '?' in sub-expression at '4' @ error/fx.c/ProcessTernaryOpr/2396. |
xx = 3 + yy | NewUserSymbol 'yy' after non-assignment operator at '' @ error/fx.c/TranslateExpression/2661. |
xx | NewUserSymbol 'xx' needs assignment operator at '' @ error/fx.c/TranslateExpression/2677. |
xx++ | Expected assignment after new UserSymbol 'xx' at '' @ error/fx.c/TranslateExpression/2581. |
#badhex | Bad hex number at '#badhex' @ error/fx.c/GetOperand/2147. |
#a | Bad hex number at '#a' @ error/fx.c/GetOperand/2147. |
#z | Bad hex number at '#z' @ error/fx.c/GetOperand/2147. |
#abcde | Bad hex number at '#abcde' @ error/fx.c/GetOperand/2147. |
xx+=2 | Expected assignment after new UserSymbol 'xx' at '2' @ error/fx.c/TranslateExpression/2581. |
2=3 | Attempted assignment to non-UserSymbol '' at '3' @ error/fx.c/TranslateExpression/2588. |
r=2 | Attempted assignment to non-UserSymbol 'r' at '2' @ error/fx.c/TranslateExpression/2588. |
abs=2 | Expected char '(' at '=2' @ error/fx.c/ExpectChar/1279. |
2+=3 | Attempted update to non-UserSymbol '' at '3' @ error/fx.c/TranslateExpression/2595. |
r+=2 | Attempted update to non-UserSymbol 'r' at '2' @ error/fx.c/TranslateExpression/2595. |
abs+=2 | Expected char '(' at '+=2' @ error/fx.c/ExpectChar/1279. |
xx=2; xx++ *3 | '++' and '--' must be the final operators in an expression at '*3' @ error/fx.c/TranslateExpression/2645. |
2+xx+3 | NewUserSymbol 'xx' after non-assignment operator at '+3' @ error/fx.c/TranslateExpression/2661. |
u[-1].p[3,4].mean | For function 'p', bad qualifier 'mean' at 'mean' @ error/fx.c/GetFunction/1969. |
12*(34-5)) | Not a real operator at ')' @ error/fx.c/GetOperator/2435. |
-xx | After unary, NewUserSymbol at '' @ error/fx.c/GetOperand/2126. |
--xx | After unary, bad operand at '' @ error/fx.c/GetOperand/2118. |
u.p[0,0].median | For function 'p', bad qualifier 'median' at 'median' @ error/fx.c/GetFunction/1969. |
v.p[0,0].median | Symbol 'v' but fewer than two images at 'v.p[0,0].median' @ error/fx.c/GetOperand/2235. |
s.p[0,0].median | For function 'p', bad qualifier 'median' at 'median' @ error/fx.c/GetFunction/1969. |
u[0].p[0,0].median | For function 'p', bad qualifier 'median' at 'median' @ error/fx.c/GetFunction/1969. |
u[1-1].p[0,0].median | For function 'p', bad qualifier 'median' at 'median' @ error/fx.c/GetFunction/1969. |
u[1].p[0,0].median | For function 'p', bad qualifier 'median' at 'median' @ error/fx.c/GetFunction/1969. |
HCL(113 | constant color missing ')' at 'HCL(113' @ error/fx.c/GetConstantColour/1607. |
%[hex:KA=gZK=AK=AK&gZK=e] | Unknown property '%[hex:KA=gZK=AK=AK^&gZK=e]' at '%[hex:KA=gZK=AK=AK^&...' @ error/fx.c/GetProperty/1536. |
KA=gZK=AK=AK&gZK=e | Expected operand at '&gZK=e' @ error/fx.c/TranslateExpression/2653. |
do(o,,,2) | For function 'do' required argument is missing at ',2)' @ error/fx.c/GetFunction/1802. |
channel (1,2,3,4,5,6) | For function 'channel', arguments don't end with ')' at '6)' @ error/fx.c/GetFunction/1906. |
skewness.intensity | Bad channel qualifier at 'intensity' @ error/fx.c/GetOperand/2269. |
mean.intensity | Bad channel qualifier at 'intensity' @ error/fx.c/GetOperand/2269. |
w.intensity | Expected operator at '.intensity' @ error/fx.c/GetOperator/2443. |
quality.r | Expected operator at '.r' @ error/fx.c/GetOperator/2443. |
u.mean.intensity | Can't have statistical image attribute 'mean' with virtual channel qualifier 'intensity' at '' @ error/fx.c/GetFunction/2006. |
u.w.intensity | Can't have image attribute 'w' with channel qualifier 'intensity' at '' @ error/fx.c/GetFunction/1998. |
u.quality.r | Can't have image attribute 'quality' with channel qualifier 'r' at '' @ error/fx.c/GetFunction/1998. |
A message that includes "ValStack underflow" suggests the translator has a bug. The count of "underflow" messages in the above is: 0 .
A small selection of Fred's ImageMagick scripts were executed in sequence for the old "-fx" and the new "-fx2". For convenience on my computer, they were first modified to use the "magick" command. The elapsed times were measured, and the outputs from the old and new "-fx" were compared with "-metric RMSE".
The scripts were: adaptivegamma, defisheye, disperse, pano2rect, sharpedge, statsfilt, tunnelize, warplog and xpand.
The "disperse" script uses randomness, creating a different result each time, so the RMSE difference from that script was ignored.
The table shows the worst RMSE of the scripts (excluding "disperse"), on a nominal scale of 0.0 to 1.0. An RMSE of less than 1e-02 will generally not be noticable.
Input file | Size (pixels) | Old "-fx" | New "-fx2" | Worst RMSE |
---|---|---|---|---|
toes.png | 267x233 | 3096 seconds | 124 seconds | 1.13239e-05 |
The new fx code was developed to increase performance of large images, by decreasing the processing required at each pixel, at the expense of increasing the processing required at each image, which includes more extensive syntax checking and translation to a run-time RPN language.
A consequence is that the total processing required for small images has increased. We want to ensure the reduced performance is not excessive.
We consider two cases: without image statistics, then with image statistics.
%FXOLD%magick xc:white -duplicate 999 +noise random -brightness-contrast %%[fx:50-(0.34*100)] null: %FXNEW%magick xc:white -duplicate 999 +noise random -brightness-contrast %%[fx:50-(0.34*100)] null:
0 00:00:07 0 00:00:06
The times are shown in the format "D HH:MM:SS".
%FXOLD%magick xc:white -duplicate 999 +noise random -fx (50-(0.34*100))/100 null: %FXNEW%magick xc:white -duplicate 999 +noise random -fx (50-(0.34*100))/100 null:
0 00:00:01 0 00:00:00
Conclusion: when no image statistics are involved, there is very little difference in performance between the old and new code.
%FXOLD%magick xc:white -duplicate 999 +noise random -brightness-contrast %%[fx:50-(mean*100)] null: %FXNEW%magick xc:white -duplicate 999 +noise random -brightness-contrast %%[fx:50-(mean*100)] null:
0 00:00:09 0 00:00:10
In the above "%[fx:...]" example, the mean of each image is required. The old and the new calculate the mean of each image (and all the other statistics of each image).
%FXOLD%magick xc:white -duplicate 999 +noise random -fx (50-(mean*100))/100 null: %FXNEW%magick xc:white -duplicate 999 +noise random -fx (50-(mean*100))/100 null:
0 00:00:03 0 00:00:03
In the above "-fx" example, the mean of only the first image is required. The old fx calculates the mean of just that image. The new fx calculates the mean of every image in the list, so it takes longer.
Conclusion: the new fx code does decrease performance when we have many small images, but this is not excessive.
As is often the case, rearranging the command can increase performance. For example, repeating the above example but using an embedded "%[fx:mean]":
%FXNEW%magick xc:white -duplicate 999 +noise random -fx "(50-(%%[fx:mean]*100))/100" null:
0 00:00:01
For convenience, .bat scripts are also available in a single zip file. See Zipped BAT files.
The scripts use some utility programs such as StopWatchcGrep and chStrs. I do not supply the source or binaries of these.
set IMG=%~1 if "%IMG%"=="" set IMG=-size 1000x1000 xc:#abd set SCRFILE=tp.scr echo off ( for /F "tokens=*" %%L in (%~dp0testPerf.txt) do ( echo ^( -clone 0 -fx "%%L" +delete ^) ) echo NULL: ) >%SCRFILE% echo on type %SCRFILE% call StopWatch %FXOLD%magick %IMG% -script %SCRFILE% call StopWatch %FXNEW%magick %IMG% -script %SCRFILE% call StopWatch
set xc2=xc:#abd xc:#432 %FXOLD%magick %xc2% -append +repage gfs.png set VPIX=-virtual-pixel Black set PREC=-precision 6 set OUTSPEC=-define quantum:format=floating-point -depth 32 echo off ( for /F "tokens=*" %%L in (%~dp0goodfxsyntax.txt) do ( ( %FXNEW%magick %PREC% gfs.png %VPIX% -fx "%%L" %OUTSPEC% gfs_new.miff 2^>^&1 ) |tail -5 %FXOLD%magick %PREC% gfs.png %VPIX% -fx "%%L" %OUTSPEC% gfs_old.miff set cleaned=%%L set "cleaned=!cleaned:<=<!" set "cleaned=!cleaned:>=>!" set "cleaned=!cleaned:&=++amp++!" set "cleaned=!cleaned:%%=__!" set "cleaned=!cleaned:++amp++=&!" %IMG7%magick %PREC% gfs_old.miff gfs_new.miff -metric RMSE -format "=start= '!cleaned!' distortion=%%[distortion] =end=\n" -compare info: ) ) >fxn_gfs.lis echo on cgrep /ifxn_gfs.lis /ofxn_gfs1a.lis /sdistortion= /f\s\r\n chStrs /ifxn_gfs1a.lis /ofxn_gfs1a.lis /f"\(" /t^< chStrs /ifxn_gfs1a.lis /ofxn_gfs1a.lis /f"\)" /t^> chStrs /ifxn_gfs1a.lis /ofxn_gfs1a.lis /f"__" /t%% chStrs /ifxn_gfs1a.lis /ofxn_gfs1b.lis /f"=start=" /t\(tr\)\(td\) chStrs /ifxn_gfs1b.lis /ofxn_gfs1b.lis /f"distortion=" /t\(/td\)\(td\) chStrs /ifxn_gfs1b.lis /ofxn_gfs1b.lis /f"=end=" /t\(/td\)\(/tr\) cPrefix /ifxn_gfs1b.lis /X /t"\(tr\)\(th\)-fx input string\(/th\)\(th\)distortion\(/th\)\(/tr\)" cPrefix /ifxn_gfs1b.lis /X /t"\(table\)" /b"\(/table\)" echo off ( for /F "tokens=*" %%L in (%~dp0goodfxsyntax2.txt) do ( ( %FXNEW%magick %PREC% -size 4x4 %xc2% %VPIX% -fx "%%L" %OUTSPEC% gfs2_new.miff 2^>^&1 ) |tail -5 %FXOLD%magick %PREC% -size 4x4 %xc2% %VPIX% -fx "%%L" %OUTSPEC% gfs2_old.miff set cleaned=%%L set cleaned=!cleaned:%%=__! %IMG7%magick %PREC% gfs2_old.miff gfs2_new.miff -metric RMSE -format "=start= '!cleaned!' distortion=%%[distortion] =end=\n" -compare info: ) ) >fxn_gfs2.lis echo on cgrep /ifxn_gfs2.lis /ofxn_gfs2a.lis /sdistortion= /f\s\r\n chStrs /ifxn_gfs2a.lis /ofxn_gfs2b.lis /f"=start=" /t\(tr\)\(td\) chStrs /ifxn_gfs2b.lis /ofxn_gfs2b.lis /f"distortion=" /t\(/td\)\(td\) chStrs /ifxn_gfs2b.lis /ofxn_gfs2b.lis /f"=end=" /t\(/td\)\(/tr\) cPrefix /ifxn_gfs2b.lis /X /t"\(tr\)\(th\)-fx input string\(/th\)\(th\)distortion\(/th\)\(/tr\)" cPrefix /ifxn_gfs2b.lis /X /t"\(table\)" /b"\(/table\)" echo off ( for /F "tokens=*" %%L in (%~dp0goodBadFxSyntax.txt) do ( ( %FXNEW%magick %PREC% -size 4x4 %xc2% %VPIX% -fx "%%L" %OUTSPEC% gfs3_new.miff 2^>^&1 ) |tail -5 %FXOLD%magick %PREC% -size 4x4 %xc2% %VPIX% -fx "%%L" %OUTSPEC% gfs3_old.miff set cleaned=%%L set cleaned=!cleaned:%%=__! %IMG7%magick %PREC% gfs3_old.miff gfs3_new.miff -metric RMSE -format "=start= '!cleaned!' distortion=%%[distortion] =end=\n" -compare info: ) ) >fxn_gfs3.lis echo on cgrep /ifxn_gfs3.lis /ofxn_gfs3a.lis /sdistortion= /f\s\r\n chStrs /ifxn_gfs3a.lis /ofxn_gfs3b.lis /f"=start=" /t\(tr\)\(td\) chStrs /ifxn_gfs3b.lis /ofxn_gfs3b.lis /f"distortion=" /t\(/td\)\(td\) chStrs /ifxn_gfs3b.lis /ofxn_gfs3b.lis /f"=end=" /t\(/td\)\(/tr\) cPrefix /ifxn_gfs3b.lis /X /t"\(tr\)\(th\)-fx input string\(/th\)\(th\)distortion\(/th\)\(/tr\)" cPrefix /ifxn_gfs3b.lis /X /t"\(table\)" /b"\(/table\)"
set IMGS=xc:#abd xc:#654 set SLICES=5 set PREC=-precision 6 chStrs /i%~dp0goodpc.txt /ogoodpc_norand.txt /frand() /t0.23 %FXNEW%magick %IMGS% -define fx:debug=true -format "%%[fx:%~1]\n" info: echo off ( for /F "tokens=*" %%L in (goodpc_norand.txt) do ( for /F "usebackq tokens=*" %%B in (`%FXOLD%magick %PREC% %IMGS% -format "<td>%%L</td>" info:`) do set SOLD=%%B for /F "usebackq tokens=*" %%B in (`%FXNEW%magick %PREC% %IMGS% -format "<td>%%L</td>" info:`) do set SNEW=%%B set goodBad=same if !SOLD! NEQ !SNEW! set goodBad=DIFFERENT set NoLtGt=%%L set "NoLtGt=!NoLtGt:<=<!" set "NoLtGt=!NoLtGt:>=>!" echo =start= "!NoLtGt!" =mid= !SOLD! !SNEW! =mid2= !goodBad! =end= ) ) >fxn_ft.lis cGrep /ifxn_ft.lis /ofxn_ftb.lis /srand() /x chStrs /ifxn_ftb.lis /ofxn_ftb.lis /f"=start=" /t"\(tr\)\(td\)" chStrs /ifxn_ftb.lis /ofxn_ftb.lis /f"=mid=" /t"\(/td\)" chStrs /ifxn_ftb.lis /ofxn_ftb.lis /f"=mid2=" /t"\(td\)" chStrs /ifxn_ftb.lis /ofxn_ftb.lis /f"=end=" /t"\(/td\)\(/tr\)" cPrefix /ifxn_ftb.lis /X /t"\(tr\)\(th\)format string\(/th\)\(th cspan\)old result\(/th\)\(th cspan\)new result\(/th\)\(th\)same/different\(/th\)\(/tr\)" cPrefix /ifxn_ftb.lis /X /t"\(table\)" /b"\(/table\)" chStrs /ifxn_ftb.lis /ofxn_ft_gm.lis /fcspan /tcolspan=\q2\q echo on
set LIS_FILE=%1 if "%LIS_FILE%"=="" set LIS_FILE=fxn_err.lis echo off ( echo ^<table^> echo ^<tr^>^<th^>-fx input string^</th^>^<th^>Error message^</th^>^</tr^> for /F "tokens=*" %%A in (%~dp0badfxsyntax.txt) do ( for /F "usebackq tokens=*" %%B in (`%FXNEW%magick xc:#8bd -fx "%%A" NULL: 2^>^&1`) do set msg=%%B set cleaned=!msg! set "cleaned=!cleaned:<=<!" set "cleaned=!cleaned:>=>!" set "cleaned=!cleaned:&=++amp++!" set "cleaned=!cleaned:%%=__!" set "cleaned=!cleaned:++amp++=&!" set msg = !cleaned! set msg2=!msg:magick: =! if !msg2! NEQ !msg! ( set msg3=!msg2:fatal/fx2.inc/=! echo ^<tr^>^<td^>%%A^</td^>^<td^>!msg3!^</td^>^</tr^> ) ) echo ^</table^> ) >%LIS_FILE% echo on echo created %LIS_FILE%
set IMGS=xc:#abd xc:#654 set PREC=-precision 6 %FXNEW%magick %IMGS% -define fx:debug=true -format "%%[fx:%~1]\n" info: %FXOLD%magick %IMGS% -format "%%[fx:%~1]\n" info: for %%A in (fx) do ( echo %%A echo off ( for /F "tokens=*" %%L in (%~dp0fmtTstDiff.txt) do ( for /F "usebackq tokens=*" %%B in (`%FXOLD%magick %PREC% %IMGS% -format "<td>%%[%%A:%%L]</td>" info:`) do set SOLD=%%B for /F "usebackq tokens=*" %%B in (`%FXNEW%magick %PREC% %IMGS% -format "<td>%%[%%A:%%L]</td>" info:`) do set SNEW=%%B set goodBad=same if !SOLD! NEQ !SNEW! set goodBad=DIFFERENT echo =start= "%%A:%%L" =mid= !SOLD! !SNEW! =mid2= !goodBad! =end= ) ) >fxn_ft.lis echo on chStrs /ifxn_ft.lis /ofxn_ftb.lis /f"=start=" /t"\(tr\)\(td\)" chStrs /ifxn_ftb.lis /ofxn_ftb.lis /f"=mid=" /t"\(/td\)" chStrs /ifxn_ftb.lis /ofxn_ftb.lis /f"=mid2=" /t"\(td\)" chStrs /ifxn_ftb.lis /ofxn_ftb.lis /f"=end=" /t"\(/td\)\(/tr\)" cPrefix /ifxn_ftb.lis /X /t"\(tr\)\(th\)format string\(/th\)\(th cspan\)old result\(/th\)\(th cspan\)new result\(/th\)\(th\)same/different\(/th\)\(/tr\)" cPrefix /ifxn_ftb.lis /X /t"\(table\)" /b"\(/table\)" chStrs /ifxn_ftb.lis /ofxn_ft_diff_%%A.lis /fcspan /tcolspan=\q2\q ) for %%A in (fx pixel hex) do ( echo %%A echo off ( for /F "tokens=*" %%L in (%~dp0fmtTst.txt) do ( for /F "usebackq tokens=*" %%B in (`%FXOLD%magick %PREC% %IMGS% -format "<td>%%[%%A:%%L]</td>" info:`) do set SOLD=%%B for /F "usebackq tokens=*" %%B in (`%FXNEW%magick %PREC% %IMGS% -format "<td>%%[%%A:%%L]</td>" info:`) do set SNEW=%%B set goodBad=same if !SOLD! NEQ !SNEW! set goodBad=DIFFERENT echo =start= "%%A:%%L" =mid= !SOLD! !SNEW! =mid2= !goodBad! =end= ) ) >fxn_ft.lis echo on chStrs /ifxn_ft.lis /ofxn_ftb.lis /f"=start=" /t"\(tr\)\(td\)" chStrs /ifxn_ftb.lis /ofxn_ftb.lis /f"=mid=" /t"\(/td\)" chStrs /ifxn_ftb.lis /ofxn_ftb.lis /f"=mid2=" /t"\(td\)" chStrs /ifxn_ftb.lis /ofxn_ftb.lis /f"=end=" /t"\(/td\)\(/tr\)" cPrefix /ifxn_ftb.lis /X /t"\(tr\)\(th\)format string\(/th\)\(th cspan\)old result\(/th\)\(th cspan\)new result\(/th\)\(th\)same/different\(/th\)\(/tr\)" cPrefix /ifxn_ftb.lis /X /t"\(table\)" /b"\(/table\)" chStrs /ifxn_ftb.lis /ofxn_ft_%%A.lis /fcspan /tcolspan=\q2\q )
All images on this page were created by the commands shown, using:
%FXOLD%magick identify -version
Version: ImageMagick 7.1.1-5 (Beta) Q32-HDRI x86_64 852a723f1:20230319 https://imagemagick.org Copyright: (C) 1999 ImageMagick Studio LLC License: https://imagemagick.org/script/license.php Features: Cipher DPC HDRI Modules OpenMP(4.5) Delegates (built-in): bzlib cairo fftw fontconfig freetype heic jbig jng jpeg lcms ltdl lzma pangocairo png raqm raw rsvg tiff webp wmf x xml zip zlib Compiler: gcc (11.3)
%FXNEW%magick identify -version
Version: ImageMagick 7.1.1-5 (Beta) Q32-HDRI x86_64 852a723f1:20230319 https://imagemagick.org Copyright: (C) 1999 ImageMagick Studio LLC License: https://imagemagick.org/script/license.php Features: Cipher DPC HDRI Modules OpenMP(4.5) Delegates (built-in): bzlib cairo fftw fontconfig freetype heic jbig jng jpeg lcms ltdl lzma pangocairo png raqm raw rsvg tiff webp wmf x xml zip zlib Compiler: gcc (11.3)
To improve internet download speeds, some images may have been automatically converted (by ImageMagick, of course) from PNG or TIFF or MIFF to JPG.
Source file for this web page is fxntest.h1. To re-create this web page, execute "procH1 fxntest".
This page, including the images, is my copyright. Anyone is permitted to use or adapt any of the code, scripts or images for any purpose, including commercial use.
Anyone is permitted to re-publish this page, but only for non-commercial use.
Anyone is permitted to link to this page, including for commercial use.
Page version v1.0 8-January-2022.
Page created 04-Jul-2023 19:39:48.
Copyright © 2023 Alan Gibson.