'Glitch' Art Filters - again

I’ve figured it out. Now the only thing stopping me from sending in a pull request is the fact that I have to remove a bunch of brackets around the arguments of some if statements. There’s around 900 of these. Is there a way I can quickly get rid of them all?

You can work from the file provided in github gmic-community thanks to @David_Tschumperle blood, sweat, and tears required to do the code fixes.

Thanks. I managed to sort it all out.

Edit: thanks for merging it!

1 Like
(glitch>0)?((u>aec)?(pswitch=1):(glitcha*=0))

Why does this give me an error? glitcha is meant to be a vector. It’s meant to set all elements in glitcha to 0 if glitch>0 and u>aec.

*** Error in ./fx_jpeg_preview/fx_jpeg/*repeat/*local/*repeat/ *** Command 'fill': Operator '?:': Right-hand operand has invalid type 'vector64' (should be 'scalar'), in expression '...(glitch>0)?((u>aec)?(pswitch=1):(glitcha*=0))...'.

I don’t know why it’s treating glitcha as a scalar when it has always been a vector. It works just fine like this normally, for example: glitcha=vector(#twh,0)

In a construction like cond?expr_then:expr_else, the expressions expr_then and expr_else must have the same return type, because this kind of expression can be actually set in a variable (with a prescribed type).
If you don’t assign the result of your condition, then you can add a 0 at the end of each sub-expressions to ensure they all return a scalar value:

glitch>0?(u>aec?(pswitch=1; 0):(glitcha*=0; 0)

That’s odd. I was thinking that would set a pixel value, but it doesn’t if I specify something further for the pixel value after that. Maybe this trick should be in the documentation since I thought it was just about assigning variables and it didn’t have to return anything.

No, it set the pixel value only if this is the last value of a fill expression, which is not the case here (hopefully).

In a math expression, every item returns something. There is no type like ‘nothing’ :slight_smile:
For instance, expression 0; returns a scalar with value 0.
And in conditionals, all returned types must be the same.

1 Like

@Joan_Rake1 The way I satisfy the parallelism (of type) between the condition and the expressions is to make the condition involve a vector of the same dimensions as the result of the expression.

@afre That’s useful for the sake of keeping things organised. I should learn it as a programming pattern, although the only rigid rules I like are the ones which let me rely on certain features for certain results (like the difference between a number and a string)…

Anyway, I have finally got a fully-working JPEG encoder with glitching.

#@gui JPEG Encoder: fx_jpeg_preview
#@gui : sep = separator()
#@gui : 1. Quality=float(80,0,100)
#@gui : 2. Colour Space = choice(21,"RGB","sRGB","CMY","RYB","Ohta8","Ohta","YES8","YES","Kodak1-8","Kodak1","Lab8","Lab","Oklab","LUV","Jzazbz","YIQ8","YIQ","YUV8","YUV","YCbCr","YCbCrGLIC","YCbCrJPEG","YDbDr","YCoCg","LC1C2","XYZ8","XYZ","HSV8","HSV","HSL8","HSL","HSI8","HSI","LCH8","LCH","JzCzHz","HCY")
#@gui : 3. Channel 1 Block Width = int(8,2,32)
#@gui : 4. Channel 1 Block Height = int(8,2,32)
#@gui : 5. Channel 2 Block Width = int(16,2,32)
#@gui : 6. Channel 2 Block Height = int(16,2,32)
#@gui : 7. Channel 3 Block Width = int(16,2,32)
#@gui : 8. Channel 3 Block Height = int(16,2,32)
#@gui : Toggle Block Offsets = bool(0)
#@gui : 9. Channel 1 Block X Offset = int(0,-32,32)
#@gui : 10. Channel 1 Block Y Offset = int(0,-32,32)
#@gui : 11. Channel 2 Block X Offset = int(0,-32,32)
#@gui : 12. Channel 2 Block Y Offset = int(0,-32,32)
#@gui : 13. Channel 3 Block X Offset = int(0,-32,32)
#@gui : 14. Channel 3 Block Y Offset = int(0,-32,32)
#@gui : Toggle Glitch = bool(0)
#@gui : 15. Glitch Start = float(0.2,0,1)
#@gui : 16. Glitch Min Distance = float(0.2,0,1)
#@gui : 17. Glitch Max Distance = float(0.8,0,1)
#@gui : 18. Distortion Intensity = float(1,0,5)
#@gui : 19. Additive Intensity = float(1,0,5)
#@gui : 20. Persistent Error Chance = float(0.25,0,1)
#@gui : 21. Tile Shift Chance = float(0.25,0,1)
#@gui : 22. Tile Shift Direction = float(0.5,0,1)
#@gui : 23. Tile Width = int(16,2,32)
#@gui : 24. Tile Height = int(16,2,32)
#@gui : 25. Tile X Offset = int(0,-32,32)
#@gui : 26. Tile Y Offset = int(0,-32,32)

fx_jpeg :
to_rgb

inum=$!
q=$1
cs=$2
startg=$15
ming=$16
maxg=$17
di=$18
ai=$19
pec=$20
tsc=$21
tsd=$22
tstw=$23
tsth=$24
tsox={$25%$tstw}
tsoy={$26%$tsth}

csswap 0,$cs


($3,$5,$7;$4,$6,$8;0,0,0;$9,$11,$13;$10,$12,$14)
nm. params

eval. "begin(index=0;list=transpose(crop(0,0,3,2),3);foundlist=vector6(0));
for(n=0,n<3,++n,
pos=n*2;
cp=list[pos,2];
(find(foundlist,cp,0,2)==-1)?(
index=find(foundlist,[0,0],0,2);
foundlist[index]=cp[0];
foundlist[index+1]=cp[1]);
i(n,2)=find(foundlist,cp,0,2)*0.5
);"

tcount=0
repeat 3
tnum={i(#$params,$>,2)}
if $tnum==$tcount
tw={i(#$params,$>,0)}
th={i(#$params,$>,1)}
dct_tileset $tw,$th
idct_tileset $tw,$th
# nm[-2,-1] "dct"$tcount"","idct"$tcount""
tcount+=1
fi
done

repeat $inum l[$>,{(-2*$tcount)-1}--1]

cw={w(#0)}
ch={h(#0)}

$cw,$ch,1,1
f. ">begin(const ming="$ming";const maxg="$maxg";count="$startg"*wh);
count-=1;
count<0?(count=u(ming,maxg)*wh;1):0"
nm. gpunch

z[0] {-$tsox},{-$tsoy},{$cw+((-$cw)%$tstw)-1-$tsox},{$ch+((-$ch)%$tsth)-1-$tsoy},3
[0]
f[0] >"begin(const tstw="$tstw";const tsth="$tsth";const tstwh=tstw*tsth;const itstw=1/tstw;const itsth=1/tsth;const iw=1/w;const tsox="$tsox";const tsoy="$tsoy";tsc="$tsc";tsd="$tsd";ioff=0);
if (!(x%tstw) && !(y%tsth),
glitch=max(crop(#"$gpunch",x-tsox,y-tsoy,0,0,tstw,tsth,1,1));
(glitch)?((u<tsc)?(ioff+=(u<tsd)?(1):(-1)));
index=(x*itstw+y*itsth*w*itstw);
nindex=index+ioff;
ref(crop(#-1,(nindex%(w*itstw))*tstw,floor(nindex*tstw*iw)*tsth,0,0,tstw,tsth,1,3,0),src);
draw(src,x,y,0,0,tstw,tsth,1,3));
I
"
rm.
z[0] $tsox,$tsoy,{$cw-1+$tsox},{$ch-1+$tsoy},3

s[0] c

repeat 3

tw={i(#$params,$>,0)}
th={i(#$params,$>,1)}
tn={i(#$params,$>,2)}
ox={-i(#$params,$>,3)%$tw}
oy={-i(#$params,$>,4)%$th}
imax=0
imin=0
l[$>]
imax={iM}
imin={im}
if $imax!=$imin
- $imin * {1/($imax-$imin)}
else
+ {1-$imax}
fi
endl

z[$>] {-$ox},{-$oy},{$cw+((-$cw)%$tw)-1-$ox},{$ch+((-$ch)%$th)-1-$oy},3
[$>]

# dct
f[$>] :"
begin(const tw="$tw";const th="$th";const twh=tw*th;const tn="$tn";const tileset=(tn-"$tcount")*2-2);
if (!(x%tw) && !(y%th),
res=vector(#twh,0);
ref(crop(x,y,tw,th),src);
for (l = 0, l<th, ++l, for (k = 0, k<tw, ++k,
off = k + tw*l;
res += src[off]*crop(#tileset,k*tw,l*th,tw,th,1)));
draw(#-1,res,x,y,0,0,tw,th);
); i"

# glitch

if ($di||$ai)&&(1-$startg)&&((1-$ming)||(1-$maxg))
f. >"begin(const tw="$tw";const th="$th";const twh=tw*th;const itw=1/tw;const ith=1/th;const ox="$ox";const oy="$oy";const di="$di";const ai="$ai";const pec="$pec";const glitchd=sqrt(max(twh/wh,avg("$ming","$maxg")));glitchm=vector(#twh,1);glitcha=vector(#twh,0);pswitch=0;ioff=0);
if (!(x%tw) && !(y%th),
glitch=max(crop(#"$gpunch",x-ox,y-oy,0,0,tw,th,1,1,1));
(glitch)?(for(n=0,n<twh,++n,
glitchm[n]=glitchm[n]+(di*u(-1,1)*glitchd));
pswitch=1);
ref(crop(x,y,0,0,tw,th,1,1,0),src);
(pswitch==1)?(for(l=0,l<th,++l,for(k=0,k<tw,++k,
glitcha[l*tw+k]=itw*(64/((l+1)*(k+1)))*ai*u(-1,1))));
draw(src*glitchm+glitcha,x,y,0,0,tw,th);
pswitch=0;
(glitch)?((u<pec)?(pswitch=1;0):(
glitcha=vector(#twh,0);0)));
i
"
fi

# very lazy compression emulation
f. :"begin(const factor=sqrt("$tw"*"$th");const invfactor=1/factor; const qual=(1-("$q"*0.01))^4);factor*round(i*invfactor,qual)"

# idct
f. :"
begin(const tw="$tw";const th="$th";const twh=tw*th;const tn="$tn";const tileset=(tn-"$tcount")*2-1);
if (!(x%tw) && !(y%th),
res=vector(#twh,0);
ref(crop(x,y,tw,th),src);
for (l = 0, l<th, ++l, for (k = 0, k<tw, ++k,
off = k + tw*l;
res += src[off]*crop(#tileset,k*tw,l*th,tw,th,1)));
draw(#"$>",res,x,y,0,0,tw,th);
); i"
rm.
l[$>]
if $imax!=$imin
* {($imax-$imin)} + $imin
else
+ {$imax-1}
fi
endl

z[$>] $ox,$oy,{$cw-1+$ox},{$ch-1+$oy},3


done
a[0-2] c

endl done

rm[{(-2*$tcount)-2}--1]

csswap $cs,0

fx_jpeg_preview:

if $9
o0,o1,o2,o3,o4,o5=${10-15}
else
repeat 6
o$>=0
done
fi

if $16
g0,g1,g2,g3,g4,g5,g6,g7,g8,g9,g10,g11=${17-28}
else
repeat 6
g$>=1
done
g6=0
g7=0.5
g8=16
g9=16
g10=0
g11=0
fi

fx_jpeg ${1-8},$o0,$o1,$o2,$o3,$o4,$o5,$g0,$g1,$g2,$g3,$g4,$g5,$g6,$g7,$g8,$g9,$g10,$g11

u "{$1}"\
"{$2}"\
"{$3}"\
"{$4}"\
"{$5}"\
"{$6}"\
"{$7}"\
"{$8}"\
"{$9}"\
"{"$o0"}_"{$9?2:0}\
"{"$o1"}_"{$9?2:0}\
"{"$o2"}_"{$9?2:0}\
"{"$o3"}_"{$9?2:0}\
"{"$o4"}_"{$9?2:0}\
"{"$o5"}_"{$9?2:0}\
"{$16}"\
"{"$g0"}_"{$16?2:0}\
"{"$g1"}_"{$16?2:0}\
"{"$g2"}_"{$16?2:0}\
"{"$g3"}_"{$16?2:0}\
"{"$g4"}_"{$16?2:0}\
"{"$g5"}_"{$16?2:0}\
"{"$g6"}_"{$16?2:0}\
"{"$g7"}_"{$16?2:0}\
"{"$g8"}_"{$16?2:0}\
"{"$g9"}_"{$16?2:0}\
"{"$g10"}_"{$16?2:0}\
"{"$g11"}_"{$16?2:0}\

At least one issue remains: when I uncheck and re-check the toggle glitch option, the parameter values under that section reset. I would like them to be remembered, but I don’t know how I would do that.

There’s a way to do that. You can have copies of options and hide them based on parameters to be evaluated. That’s what I did for some of my filters.

Oh yeah. Let me try something…

I now have this:

#@gui JPEG Encoder: fx_jpeg_preview
#@gui : sep = separator()
#@gui : 1. Quality=float(80,0,100)
#@gui : 2. Colour Space = choice(21,"RGB","sRGB","CMY","RYB","Ohta8","Ohta","YES8","YES","Kodak1-8","Kodak1","Lab8","Lab","Oklab","LUV","Jzazbz","YIQ8","YIQ","YUV8","YUV","YCbCr","YCbCrGLIC","YCbCrJPEG","YDbDr","YCoCg","LC1C2","XYZ8","XYZ","HSV8","HSV","HSL8","HSL","HSI8","HSI","LCH8","LCH","JzCzHz","HCY")
#@gui : 3. Channel 1 Block Width = int(8,2,32)
#@gui : 4. Channel 1 Block Height = int(8,2,32)
#@gui : 5. Channel 2 Block Width = int(16,2,32)
#@gui : 6. Channel 2 Block Height = int(16,2,32)
#@gui : 7. Channel 3 Block Width = int(16,2,32)
#@gui : 8. Channel 3 Block Height = int(16,2,32)
#@gui : 9. Mirror = choice("None","X","Y","XY")
#@gui : 10. Rotate = choice("None,"90 clockwise","180","90 anticlockwise")
#@gui : sep = separator()
#@gui : Toggle Block Offsets = bool(0)
#@gui : 11. Channel 1 Block X Offset = int(0,-32,32)
#@gui : 12. Channel 1 Block Y Offset = int(0,-32,32)
#@gui : 13. Channel 2 Block X Offset = int(0,-32,32)
#@gui : 14. Channel 2 Block Y Offset = int(0,-32,32)
#@gui : 15. Channel 3 Block X Offset = int(0,-32,32)
#@gui : 16. Channel 3 Block Y Offset = int(0,-32,32)
#@gui : sep = separator()
#@gui : Toggle Glitch = bool(0)
#@gui : 17. Glitch Start = float(0.2,0,1)
#@gui : 18. Glitch Min Distance = float(0.2,0,1)
#@gui : 19. Glitch Max Distance = float(0.8,0,1)
#@gui : 20. Distortion Intensity = float(1,0,5)
#@gui : 21. Additive Intensity = float(1,0,5)
#@gui : 22. Persistent Error Chance = float(0.25,0,1)
#@gui : 23. Tile Shift Chance = float(0.25,0,1)
#@gui : 24. Tile Shift Direction = float(0.5,0,1)
#@gui : 25. Tile Width = int(16,2,32)
#@gui : 26. Tile Height = int(16,2,32)
#@gui : 27. Tile X Offset = int(0,-32,32)
#@gui : 28. Tile Y Offset = int(0,-32,32)


fx_jpeg :
to_rgb

inum=$!
q=$1
cs=$2
startg=$17
ming=$18
maxg=$19
di=$20
ai=$21
pec=$22
tsc=$23
tsd=$24
tstw=$25
tsth=$26
tsox={$27%$tstw}
tsoy={$28%$tsth}

if $9==1
mirror x
elif $9==2
mirror y
elif $9==3
mirror xy
fi
if $10
rotate {$10*90},0
fi

csswap 0,$cs

($3,$5,$7;$4,$6,$8;0,0,0;$11,$13,$15;$12,$14,$16)
nm. params

eval. "begin(index=0;list=transpose(crop(0,0,3,2),3);foundlist=vector6(0));
for(n=0,n<3,++n,
pos=n*2;
cp=list[pos,2];
(find(foundlist,cp,0,2)==-1)?(
index=find(foundlist,[0,0],0,2);
foundlist[index]=cp[0];
foundlist[index+1]=cp[1]);
i(n,2)=find(foundlist,cp,0,2)*0.5
);"

tcount=0
repeat 3
tnum={i(#$params,$>,2)}
if $tnum==$tcount
tw={i(#$params,$>,0)}
th={i(#$params,$>,1)}
dct_tileset $tw,$th
idct_tileset $tw,$th
# nm[-2,-1] "dct"$tcount"","idct"$tcount""
tcount+=1
fi
done

repeat $inum l[$>,{(-2*$tcount)-1}--1]

cw={w(#0)}
ch={h(#0)}

$cw,$ch,1,1
f. ">begin(const ming="$ming";const maxg="$maxg";count="$startg"*wh);
count-=1;
count<0?(count=u(ming,maxg)*wh;1):0"
nm. gpunch

# tile shift glitch
if $tsc
z[0] {-$tsox},{-$tsoy},{$cw+((-$cw)%$tstw)-1-$tsox},{$ch+((-$ch)%$tsth)-1-$tsoy},3
[0]
f[0] >"begin(const tstw="$tstw";const tsth="$tsth";const tstwh=tstw*tsth;const itstw=1/tstw;const itsth=1/tsth;const iw=1/w;const tsox="$tsox";const tsoy="$tsoy";tsc="$tsc";tsd="$tsd";ioff=0);
if (!(x%tstw) && !(y%tsth),
glitch=max(crop(#"$gpunch",x-tsox,y-tsoy,0,0,tstw,tsth,1,1));
(glitch)?((u<tsc)?(ioff+=(u<tsd)?(1):(-1)));
index=(x*itstw+y*itsth*w*itstw);
nindex=index+ioff;
ref(crop(#-1,(nindex%(w*itstw))*tstw,floor(nindex*tstw*iw)*tsth,0,0,tstw,tsth,1,3,0),src);
draw(src,x,y,0,0,tstw,tsth,1,3));
I
"
rm.
z[0] $tsox,$tsoy,{$cw-1+$tsox},{$ch-1+$tsoy},3
fi

s[0] c

repeat 3

tw={i(#$params,$>,0)}
th={i(#$params,$>,1)}
tn={i(#$params,$>,2)}
ox={-i(#$params,$>,3)%$tw}
oy={-i(#$params,$>,4)%$th}
imax=0
imin=0
l[$>]
imax={iM}
imin={im}
if $imax!=$imin
- $imin * {1/($imax-$imin)}
else
+ {1-$imax}
fi
endl

z[$>] {-$ox},{-$oy},{$cw+((-$cw)%$tw)-1-$ox},{$ch+((-$ch)%$th)-1-$oy},3
[$>]

# dct
f[$>] :"
begin(const tw="$tw";const th="$th";const twh=tw*th;const tn="$tn";const tileset=(tn-"$tcount")*2-2);
if (!(x%tw) && !(y%th),
res=vector(#twh,0);
ref(crop(x,y,tw,th),src);
for (l = 0, l<th, ++l, for (k = 0, k<tw, ++k,
off = k + tw*l;
res += src[off]*crop(#tileset,k*tw,l*th,tw,th,1)));
draw(#-1,res,x,y,0,0,tw,th);
); i"

# distortion glitch

if ($di||$ai)&&(1-$startg)&&((1-$ming)||(1-$maxg))
f. >"begin(const tw="$tw";const th="$th";const twh=tw*th;const itw=1/tw;const ith=1/th;const ox="$ox";const oy="$oy";const di="$di";const ai="$ai";const pec="$pec";const glitchd=sqrt(max(twh/wh,avg("$ming","$maxg")));glitchm=vector(#twh,1);glitcha=vector(#twh,0);pswitch=0;ioff=0);
if (!(x%tw) && !(y%th),
glitch=max(crop(#"$gpunch",x-ox,y-oy,0,0,tw,th,1,1,1));
(glitch)?(for(n=0,n<twh,++n,
glitchm[n]=glitchm[n]+(di*u(-1,1)*glitchd));
pswitch=1);
ref(crop(x,y,0,0,tw,th,1,1,0),src);
(pswitch==1)?(for(l=0,l<th,++l,for(k=0,k<tw,++k,
glitcha[l*tw+k]=itw*(64/((l+1)*(k+1)))*ai*u(-1,1))));
draw(src*glitchm+glitcha,x,y,0,0,tw,th);
pswitch=0;
(glitch)?((u<pec)?(pswitch=1;0):(
glitcha=vector(#twh,0);0)));
i
"
fi

# very lazy compression emulation
f. :"begin(const factor=sqrt("$tw"*"$th");const invfactor=1/factor; const qual=(1-("$q"*0.01))^4);factor*round(i*invfactor,qual)"

# idct
f. :"
begin(const tw="$tw";const th="$th";const twh=tw*th;const tn="$tn";const tileset=(tn-"$tcount")*2-1);
if (!(x%tw) && !(y%th),
res=vector(#twh,0);
ref(crop(x,y,tw,th),src);
for (l = 0, l<th, ++l, for (k = 0, k<tw, ++k,
off = k + tw*l;
res += src[off]*crop(#tileset,k*tw,l*th,tw,th,1)));
draw(#"$>",res,x,y,0,0,tw,th);
); i"
rm.
l[$>]
if $imax!=$imin
* {($imax-$imin)} + $imin
else
+ {$imax-1}
fi
endl

z[$>] $ox,$oy,{$cw-1+$ox},{$ch-1+$oy},3


done
a[0-2] c

endl done

rm[{(-2*$tcount)-2}--1]

csswap $cs,0

if $10
rotate {-$10*90},0
fi
if $9==1
mirror x
elif $9==2
mirror y
elif $9==3
mirror xy
fi

fx_jpeg_preview:

if $11
o0,o1,o2,o3,o4,o5=${12-17}
else
repeat 6
o$>=0
done
fi

if $18
g0,g1,g2,g3,g4,g5,g6,g7,g8,g9,g10,g11=${19-30}
else
repeat 6
g$>=1
done
g6=0
g7=0.5
g8=16
g9=16
g10=0
g11=0
fi

fx_jpeg ${1-10},$o0,$o1,$o2,$o3,$o4,$o5,$g0,$g1,$g2,$g3,$g4,$g5,$g6,$g7,$g8,$g9,$g10,$g11

u "{$1}"\
"{$2}"\
"{$3}"\
"{$4}"\
"{$5}"\
"{$6}"\
"{$7}"\
"{$8}"\
"{$9}"\
"{$10}"\
"{$11}"\
"{"$12"}_"{$11?2:0}\
"{"$13"}_"{$11?2:0}\
"{"$14"}_"{$11?2:0}\
"{"$15"}_"{$11?2:0}\
"{"$16"}_"{$11?2:0}\
"{"$17"}_"{$11?2:0}\
"{$18}"\
"{"$19"}_"{$18?2:0}\
"{"$20"}_"{$18?2:0}\
"{"$21"}_"{$18?2:0}\
"{"$22"}_"{$18?2:0}\
"{"$23"}_"{$18?2:0}\
"{"$24"}_"{$18?2:0}\
"{"$25"}_"{$18?2:0}\
"{"$26"}_"{$18?2:0}\
"{"$27"}_"{$18?2:0}\
"{"$28"}_"{$18?2:0}\
"{"$27"}_"{$18?2:0}\
"{"$28"}_"{$18?2:0}\
"{"$29"}_"{$18?2:0}\
"{"$30"}_"{$18?2:0}\

Now the parameters won’t hide. How do I fix this? What am I missing?

Remove the last slash.

I’ve tried that, and it doesn’t work. Meanwhile, I’ve sneaked in a few more features.

#@gui JPEG Encoder: fx_jpeg_preview
#@gui : sep = separator()
#@gui : 1. Quality=float(80,0,100)
#@gui : 2. Colour Space = choice(21,"RGB","sRGB","CMY","RYB","Ohta8","Ohta","YES8","YES","Kodak1-8","Kodak1","Lab8","Lab","Oklab","LUV","Jzazbz","YIQ8","YIQ","YUV8","YUV","YCbCr","YCbCrGLIC","YCbCrJPEG","YDbDr","YCoCg","LC1C2","XYZ8","XYZ","HSV8","HSV","HSL8","HSL","HSI8","HSI","LCH8","LCH","JzCzHz","HCY")
#@gui : 3. Channel 1 Block Width = int(8,2,32)
#@gui : 4. Channel 1 Block Height = int(8,2,32)
#@gui : 5. Channel 2 Block Width = int(16,2,32)
#@gui : 6. Channel 2 Block Height = int(16,2,32)
#@gui : 7. Channel 3 Block Width = int(16,2,32)
#@gui : 8. Channel 3 Block Height = int(16,2,32)
#@gui : 9. Mirror = choice("None","X","Y","XY")
#@gui : 10. Rotate = choice("None,"90 clockwise","180","90 anticlockwise")
#@gui : sep = separator()
#@gui : Toggle Block Offsets = bool(0)
#@gui : 11. Channel 1 Block X Offset = int(0,-32,32)
#@gui : 12. Channel 1 Block Y Offset = int(0,-32,32)
#@gui : 13. Channel 2 Block X Offset = int(0,-32,32)
#@gui : 14. Channel 2 Block Y Offset = int(0,-32,32)
#@gui : 15. Channel 3 Block X Offset = int(0,-32,32)
#@gui : 16. Channel 3 Block Y Offset = int(0,-32,32)
#@gui : sep = separator()
#@gui : Toggle Glitch = bool(0)
#@gui : 17. Glitch Start = float(0.2,0,1)
#@gui : 18. Glitch Min Distance = float(0.2,0,1)
#@gui : 19. Glitch Max Distance = float(0.8,0,1)
#@gui : 20. Distortion Strength = float(1,0,5)
#@gui : 21. Additive Strength = float(1,0,5)
#@gui : 22. Persistent Error Strength = float(0.25,0,1)
#@gui : 23. Persistent Error Chance = float(0.25,0,1)
#@gui : 24. Tile Shift Direction = float(0.5,0,1)
#@gui : 25. Tile Shift Chance = float(0.25,0,1)
#@gui : 26. Tile Width = int(16,2,32)
#@gui : 27. Tile Height = int(16,2,32)
#@gui : 28. Tile X Offset = int(0,-32,32)
#@gui : 29. Tile Y Offset = int(0,-32,32)


fx_jpeg :
to_rgb

inum=$!
q=$1
cs=$2
startg=$17
ming=$18
maxg=$19
di=$20
ai=$21
pei=$22
pec=$23
tsd=$24
tsc=$25
tstw=$26
tsth=$27
tsox={$28%$tstw}
tsoy={$29%$tsth}

if $9==1
mirror x
elif $9==2
mirror y
elif $9==3
mirror xy
fi
if $10
rotate {$10*90},0
fi

csswap 0,$cs

($3,$5,$7;$4,$6,$8;0,0,0;$11,$13,$15;$12,$14,$16)
nm. params

eval. "begin(index=0;list=transpose(crop(0,0,3,2),3);foundlist=vector6(0));
for(n=0,n<3,++n,
pos=n*2;
cp=list[pos,2];
(find(foundlist,cp,0,2)==-1)?(
index=find(foundlist,[0,0],0,2);
foundlist[index]=cp[0];
foundlist[index+1]=cp[1]);
i(n,2)=find(foundlist,cp,0,2)*0.5
);"

tcount=0
repeat 3
tnum={i(#$params,$>,2)}
if $tnum==$tcount
tw={i(#$params,$>,0)}
th={i(#$params,$>,1)}
dct_tileset $tw,$th
idct_tileset $tw,$th
# nm[-2,-1] "dct"$tcount"","idct"$tcount""
tcount+=1
fi
done

repeat $inum l[$>,{(-2*$tcount)-1}--1]

cw={w(#0)}
ch={h(#0)}

$cw,$ch,1,1
f. ">begin(const ming="$ming";const maxg="$maxg";count="$startg"*wh);
count-=1;
count<0?(count=u(ming,maxg)*wh;1):0"
nm. gpunch

# tile shift glitch
if $tsc
z[0] {-$tsox},{-$tsoy},{$cw+((-$cw)%$tstw)-1-$tsox},{$ch+((-$ch)%$tsth)-1-$tsoy},3
[0]
f[0] >"begin(const tstw="$tstw";const tsth="$tsth";const tstwh=tstw*tsth;const itstw=1/tstw;const itsth=1/tsth;const iw=1/w;const tsox="$tsox";const tsoy="$tsoy";tsc="$tsc";tsd="$tsd";ioff=0);
if (!(x%tstw) && !(y%tsth),
glitch=max(crop(#"$gpunch",x-tsox,y-tsoy,0,0,tstw,tsth,1,1));
(glitch)?((u<tsc)?(ioff+=(u<tsd)?(1):(-1)));
index=(x*itstw+y*itsth*w*itstw);
nindex=index+ioff;
ref(crop(#-1,(nindex%(w*itstw))*tstw,floor(nindex*tstw*iw)*tsth,0,0,tstw,tsth,1,3,0),src);
draw(src,x,y,0,0,tstw,tsth,1,3));
I
"
rm.
z[0] $tsox,$tsoy,{$cw-1+$tsox},{$ch-1+$tsoy},3
fi

s[0] c

repeat 3

tw={i(#$params,$>,0)}
th={i(#$params,$>,1)}
tn={i(#$params,$>,2)}
ox={-i(#$params,$>,3)%$tw}
oy={-i(#$params,$>,4)%$th}
imax=0
imin=0
l[$>]
imax={iM}
imin={im}
if $imax!=$imin
- $imin * {1/($imax-$imin)}
else
+ {1-$imax}
fi
endl

z[$>] {-$ox},{-$oy},{$cw+((-$cw)%$tw)-1-$ox},{$ch+((-$ch)%$th)-1-$oy},3
[$>]

# dct
f[$>] :"
begin(const tw="$tw";const th="$th";const twh=tw*th;const tn="$tn";const tileset=(tn-"$tcount")*2-2);
if (!(x%tw) && !(y%th),
res=vector(#twh,0);
ref(crop(x,y,tw,th),src);
for (l = 0, l<th, ++l, for (k = 0, k<tw, ++k,
off = k + tw*l;
res += src[off]*crop(#tileset,k*tw,l*th,tw,th,1)));
draw(#-1,res,x,y,0,0,tw,th);
); i"

# distortion glitch

if ($di||$ai||$pei)&&(1-$startg)&&((1-$ming)||(1-$maxg))
f. >"begin(const tw="$tw";const th="$th";const twh=tw*th;const itw=1/tw;const ith=1/th;const ox="$ox";const oy="$oy";const di="$di";const ai="$ai";const pei="$pei";const pec="$pec";const glitchd=sqrt(max(twh/wh,avg("$ming","$maxg")));glitchm=vector(#twh,1);glitcha=vector(#twh,0);pswitch=0;ioff=0);
if (!(x%tw) && !(y%th),
glitch=max(crop(#"$gpunch",x-ox,y-oy,0,0,tw,th,1,1,1));
(glitch)?(for(n=0,n<twh,++n,
glitchm[n]=glitchm[n]+(di*u(-1,1)*glitchd));
pswitch=1;amult=ai):(amult=pei);
ref(crop(x,y,0,0,tw,th,1,1,0),src);
(pswitch==1)?(for(l=0,l<th,++l,for(k=0,k<tw,++k,
glitcha[l*tw+k]=itw*(64/((l+1)*(k+1)))*amult*u(-1,1))));
draw(src*glitchm+glitcha,x,y,0,0,tw,th);
pswitch=0;
(glitch)?((u<pec)?(pswitch=1;0):(
glitcha=vector(#twh,0);0)));
i
"
fi

# very lazy compression emulation
f. :"begin(const factor=sqrt("$tw"*"$th");const invfactor=1/factor; const qual=(1-("$q"*0.01))^4);factor*round(i*invfactor,qual)"

# idct
f. :"
begin(const tw="$tw";const th="$th";const twh=tw*th;const tn="$tn";const tileset=(tn-"$tcount")*2-1);
if (!(x%tw) && !(y%th),
res=vector(#twh,0);
ref(crop(x,y,tw,th),src);
for (l = 0, l<th, ++l, for (k = 0, k<tw, ++k,
off = k + tw*l;
res += src[off]*crop(#tileset,k*tw,l*th,tw,th,1)));
draw(#"$>",res,x,y,0,0,tw,th);
); i"
rm.
l[$>]
if $imax!=$imin
* {($imax-$imin)} + $imin
else
+ {$imax-1}
fi
endl

z[$>] $ox,$oy,{$cw-1+$ox},{$ch-1+$oy},3


done
a[0-2] c

endl done

rm[{(-2*$tcount)-2}--1]

csswap $cs,0

if $10
rotate {-$10*90},0
fi
if $9==1
mirror x
elif $9==2
mirror y
elif $9==3
mirror xy
fi

fx_jpeg_preview:

if $11
o0,o1,o2,o3,o4,o5=${12-17}
else
repeat 6
o$>=0
done
fi

if $18
g0,g1,g2,g3,g4,g5,g6,g7,g8,g9,g10,g11,g12=${19-31}
else
repeat 13
g$>=0
done
fi

fx_jpeg ${1-10},$o0,$o1,$o2,$o3,$o4,$o5,$g0,$g1,$g2,$g3,$g4,$g5,$g6,$g7,$g8,$g9,$g10,$g11,$g12

u "{$1}"\
"{$2}"\
"{$3}"\
"{$4}"\
"{$5}"\
"{$6}"\
"{$7}"\
"{$8}"\
"{$9}"\
"{$10}"\
"{$11}"\
"{"$12"}_"{$11?2:0}\
"{"$13"}_"{$11?2:0}\
"{"$14"}_"{$11?2:0}\
"{"$15"}_"{$11?2:0}\
"{"$16"}_"{$11?2:0}\
"{"$17"}_"{$11?2:0}\
"{$18}"\
"{"$19"}_"{$18?2:0}\
"{"$20"}_"{$18?2:0}\
"{"$21"}_"{$18?2:0}\
"{"$22"}_"{$18?2:0}\
"{"$23"}_"{$18?2:0}\
"{"$24"}_"{$18?2:0}\
"{"$25"}_"{$18?2:0}\
"{"$26"}_"{$18?2:0}\
"{"$27"}_"{$18?2:0}\
"{"$28"}_"{$18?2:0}\
"{"$27"}_"{$18?2:0}\
"{"$28"}_"{$18?2:0}\
"{"$29"}_"{$18?2:0}\
"{"$30"}_"{$18?2:0}\
"{"$31"}_"{$18?2:0}

Never mind. You just have to be very careful.

@Joan_Rake1

Try this:

u "{$1}"\
"{$2}"\
"{$3}"\
"{$4}"\
"{$5}"\
"{$6}"\
"{$7}"\
"{$8}"\
"{$9}"\
"{$10}"\
"{$11}"\
"{"$12"}_"{$11?2:0}\
"{"$13"}_"{$11?2:0}\
"{"$14"}_"{$11?2:0}\
"{"$15"}_"{$11?2:0}\
"{"$16"}_"{$11?2:0}\
"{"$17"}_"{$11?2:0}\
"{$18}"\
"{"$19"}_"{$18?2:0}\
"{"$20"}_"{$18?2:0}\
"{"$21"}_"{$18?2:0}\
"{"$22"}_"{$18?2:0}\
"{"$23"}_"{$18?2:0}\
"{"$24"}_"{$18?2:0}\
"{"$25"}_"{$18?2:0}\
"{"$26"}_"{$18?2:0}\
"{"$27"}_"{$18?2:0}\
"{"$28"}_"{$18?2:0}\
"{"$29"}_"{$18?2:0}\
"{"$30"}_"{$18?2:0}\
"{"$31"}_"{$18?2:0}
1 Like

It was a duplication error after all! Thanks for sorting it out.

How did you make that triangular modulo again? Edit: never mind, I found something better for this case involving sines.

For modulo, I had made modf command. You can utilize layer or value as an argument. Also, I had made trigonometric mapping filter as well. I have yet to add tone mapping to these filters though they do a lot already.

The command’s colour distortion is way better now but still not fully finished:

#@gui JPEG Encoder: fx_jpeg_preview
#@gui : sep = separator()
#@gui : 1. Quality=float(80,0,100)
#@gui : 2. Colour Space = choice(21,"RGB","sRGB","CMY","RYB","Ohta8","Ohta","YES8","YES","Kodak1-8","Kodak1","Lab8","Lab","Oklab","LUV","Jzazbz","YIQ8","YIQ","YUV8","YUV","YCbCr","YCbCrGLIC","YCbCrJPEG","YPbPr","YDbDr","YCoCg","LC1C2","LMS","XYZ8","XYZ","HSV8","HSV","HSL8","HSL","HSI8","HSI","HWB8","HWB","LCH8","LCH","Oklch","LCHuv","JzCzHz","HCY")
#@gui : 3. Channel 1 Block Width = int(8,2,32)
#@gui : 4. Channel 1 Block Height = int(8,2,32)
#@gui : 5. Channel 2 Block Width = int(16,2,32)
#@gui : 6. Channel 2 Block Height = int(16,2,32)
#@gui : 7. Channel 3 Block Width = int(16,2,32)
#@gui : 8. Channel 3 Block Height = int(16,2,32)
#@gui : 9. Mirror = choice("None","X","Y","XY")
#@gui : 10. Rotate = choice("None,"90 clockwise","180","90 anticlockwise")
#@gui : sep = separator()
#@gui : Toggle Block Offsets = bool(0)
#@gui : 11. Channel 1 Block X Offset = int(0,-32,32)
#@gui : 12. Channel 1 Block Y Offset = int(0,-32,32)
#@gui : 13. Channel 2 Block X Offset = int(0,-32,32)
#@gui : 14. Channel 2 Block Y Offset = int(0,-32,32)
#@gui : 15. Channel 3 Block X Offset = int(0,-32,32)
#@gui : 16. Channel 3 Block Y Offset = int(0,-32,32)
#@gui : sep = separator()
#@gui : Toggle Glitch = bool(0)
#@gui : 17. Glitch Start = float(0.2,0,1)
#@gui : 18. Glitch Min Distance = float(0.2,0,1)
#@gui : 19. Glitch Max Distance = float(0.8,0,1)
#@gui : 20. Glitch Frequency Skew = float(-0.5,-1,1)
#@gui : 21. Distortion Strength = float(1,0,2)
#@gui : 22. Distortion Variation = float(1,0,2)
#@gui : 23. Distortion Speed = float(1,0,2)
#@gui : 24. Additive Strength = float(1,0,2)
#@gui : 25. Persistent Error Strength = float(0.25,0,2)
#@gui : 26. Persistent Error Chance = float(0.25,0,1)
#@gui : 27. Tile Shift Direction = float(0.5,0,1)
#@gui : 28. Tile Shift Chance = float(0.25,0,1)
#@gui : 29. Tile Width = int(16,2,32)
#@gui : 30. Tile Height = int(16,2,32)
#@gui : 31. Tile X Offset = int(0,-32,32)
#@gui : 32. Tile Y Offset = int(0,-32,32)

fx_jpeg :
to_rgb

inum=$!
q=$1
cs=$2
startg=$17
ming=$18
maxg=$19
gfs=$20
di=$21
dv=$22
ds=$23
ai=$24
pei=$25
pec=$26
tsd=$27
tsc=$28
tstw=$29
tsth=$30
tsox={$31%$tstw}
tsoy={$32%$tsth}

gfskew={-log(2)/(log(0.5-$gfs*0.5))}

if $9==1
mirror x
elif $9==2
mirror y
elif $9==3
mirror xy
fi
if $10
rotate {$10*90},0
fi

csswap 0,$cs

($3,$5,$7;$4,$6,$8;0,0,0;$11,$13,$15;$12,$14,$16)
nm. params

eval. "begin(index=0;list=transpose(crop(0,0,3,2),3);foundlist=vector6(0));
for(n=0,n<3,++n,
pos=n*2;
cp=list[pos,2];
(find(foundlist,cp,0,2)==-1)?(
index=find(foundlist,[0,0],0,2);
foundlist[index]=cp[0];
foundlist[index+1]=cp[1]);
i(n,2)=find(foundlist,cp,0,2)*0.5
);"

tcount=0
repeat 3
tnum={i(#$params,$>,2)}
if $tnum==$tcount
tw={i(#$params,$>,0)}
th={i(#$params,$>,1)}
dct_tileset $tw,$th
idct_tileset $tw,$th
# nm[-2,-1] "dct"$tcount"","idct"$tcount""
tcount+=1
fi
done

repeat $inum l[$>,{(-2*$tcount)-1}--1]

cw={w(#0)}
ch={h(#0)}

$cw,$ch,1,1

# glitch punch card image
f. ">begin(const ming="$ming";const maxg="$maxg";count="$startg"*wh;const gfs="$gfs"; const gfskew="$gfskew";const igfskew=1/gfskew);
count-=1;
count<0?(count=(1-((1-u(ming,maxg)^gfskew)^igfskew))*wh;1):0"
nm. gpunch

# tile shift glitch
if $tsc
z[0] {-$tsox},{-$tsoy},{$cw+((-$cw)%$tstw)-1-$tsox},{$ch+((-$ch)%$tsth)-1-$tsoy},3
[0]
f[0] >"begin(const tstw="$tstw";const tsth="$tsth";const tstwh=tstw*tsth;const itstw=1/tstw;const itsth=1/tsth;const iw=1/w;const tsox="$tsox";const tsoy="$tsoy";tsc="$tsc";tsd="$tsd";ioff=0);
if (!(x%tstw) && !(y%tsth),
glitch=max(crop(#"$gpunch",x-tsox,y-tsoy,0,0,tstw,tsth,1,1));
(glitch)?((u<tsc)?(ioff+=(u<tsd)?(1):(-1)));
index=(x*itstw+y*itsth*w*itstw);
nindex=index+ioff;
ref(crop(#-1,(nindex%(w*itstw))*tstw,floor(nindex*tstw*iw)*tsth,0,0,tstw,tsth,1,3,0),src);
draw(src,x,y,0,0,tstw,tsth,1,3));
I
"
rm.
z[0] $tsox,$tsoy,{$cw-1+$tsox},{$ch-1+$tsoy},3
fi

s[0] c

repeat 3

tw={i(#$params,$>,0)}
th={i(#$params,$>,1)}
tn={i(#$params,$>,2)}
ox={-i(#$params,$>,3)%$tw}
oy={-i(#$params,$>,4)%$th}
imax=0
imin=0
l[$>]
imax={iM}
imin={im}
if $imax!=$imin
- $imin * {1/($imax-$imin)}
else
+ {1-$imax}
fi
endl

z[$>] {-$ox},{-$oy},{$cw+((-$cw)%$tw)-1-$ox},{$ch+((-$ch)%$th)-1-$oy},3
[$>]

# dct
f[$>] :"
begin(const tw="$tw";const th="$th";const twh=tw*th;const tn="$tn";const tileset=(tn-"$tcount")*2-2);
if (!(x%tw) && !(y%th),
res=vector(#twh,0);
ref(crop(x,y,tw,th),src);
for (l = 0, l<th, ++l, for (k = 0, k<tw, ++k,
off = k + tw*l;
res += src[off]*crop(#tileset,k*tw,l*th,tw,th,1)));
draw(#-1,res,x,y,0,0,tw,th);
); i"

# distortion glitch

if ($di||$ai||$pei)&&(1-$startg)&&((1-$ming)||(1-$maxg))
f. >"begin(const tw="$tw";const th="$th";const twh=tw*th;const itw=1/tw;const ith=1/th;const ox="$ox";const oy="$oy";const di="$di";const dv="$dv";const ds="$ds";const ai="$ai";const pei="$pei";const pec="$pec"; const gfskew="$gfskew";const igfskew=1/gfskew;const glitchf=sqrt(max(twh/wh,(1-((1-avg("$ming","$maxg")^gfskew)^igfskew))));glitchdm=vector(#twh,1);first=1;glitchdc=0;glitchdv=0;glitcha=vector(#twh,0);pswitch=0;ioff=0);
if (!(x%tw) && !(y%th),
glitch=max(crop(#"$gpunch",x-ox,y-oy,0,0,tw,th,1,1,1));
(glitch)?(first?(glitchdc=u(-1,1)*glitchf;first=0);
glitchdv=(glitchdv+(u(-1,1)*glitchf*(ds^2)));
# for(n=1,n<twh,++n,
# glitchdm[n]=glitchdm[n]);
pswitch=1;amult=ai^2):(amult=pei^2);
ref(crop(x,y,0,0,tw,th,1,1,0),src);
src[0]+=sin((glitchdc+glitchdv*(dv^2))*pi)*10*(di^2);
(pswitch==1)?(for(l=0,l<th,++l,for(k=0,k<tw,++k,
glitcha[l*tw+k]=itw*(64/((l+1)*(k+1)))*(amult)*u(-1,1))));
draw(src+glitcha,x,y,0,0,tw,th);
pswitch=0;
(glitch)?((u<pec)?(pswitch=1;0):(
glitcha=vector(#twh,0);0)));
i
"
fi

# very lazy compression emulation
f. :"begin(const factor=sqrt("$tw"*"$th");const invfactor=1/factor; const qual=(1-("$q"*0.01))^4);factor*round(i*invfactor,qual)"

# idct
f. :"
begin(const tw="$tw";const th="$th";const twh=tw*th;const tn="$tn";const tileset=(tn-"$tcount")*2-1);
if (!(x%tw) && !(y%th),
res=vector(#twh,0);
ref(crop(x,y,tw,th),src);
for (l = 0, l<th, ++l, for (k = 0, k<tw, ++k,
off = k + tw*l;
res += src[off]*crop(#tileset,k*tw,l*th,tw,th,1)));
draw(#"$>",res,x,y,0,0,tw,th);
); i"
rm.
l[$>]
c 0,1
if $imax!=$imin
* {($imax-$imin)} + $imin
else
+ {$imax-1}
fi
endl

z[$>] $ox,$oy,{$cw-1+$ox},{$ch-1+$oy},3


done
a[0-2] c

endl done

rm[{(-2*$tcount)-2}--1]

csswap $cs,0

if $10
rotate {-$10*90},0
fi
if $9==1
mirror x
elif $9==2
mirror y
elif $9==3
mirror xy
fi

fx_jpeg_preview:

if $11
o0,o1,o2,o3,o4,o5=${12-17}
else
repeat 6
o$>=0
done
fi

if $18
g0,g1,g2,g3,g4,g5,g6,g7,g8,g9,g10,g11,g12,g13,g14,g15=${19-34}
else
repeat 16
g$>=0
done
fi

fx_jpeg ${1-10},$o0,$o1,$o2,$o3,$o4,$o5,$g0,$g1,$g2,$g3,$g4,$g5,$g6,$g7,$g8,$g9,$g10,$g11,$g12,$g13,$g14,$g15

u "{$1}"\
"{$2}"\
"{$3}"\
"{$4}"\
"{$5}"\
"{$6}"\
"{$7}"\
"{$8}"\
"{$9}"\
"{$10}"\
"{$11}"\
"{"$12"}_"{$11?2:0}\
"{"$13"}_"{$11?2:0}\
"{"$14"}_"{$11?2:0}\
"{"$15"}_"{$11?2:0}\
"{"$16"}_"{$11?2:0}\
"{"$17"}_"{$11?2:0}\
"{$18}"\
"{"$19"}_"{$18?2:0}\
"{"$20"}_"{$18?2:0}\
"{"$21"}_"{$18?2:0}\
"{"$22"}_"{$18?2:0}\
"{"$23"}_"{$18?2:0}\
"{"$24"}_"{$18?2:0}\
"{"$25"}_"{$18?2:0}\
"{"$26"}_"{$18?2:0}\
"{"$27"}_"{$18?2:0}\
"{"$28"}_"{$18?2:0}\
"{"$29"}_"{$18?2:0}\
"{"$30"}_"{$18?2:0}\
"{"$31"}_"{$18?2:0}\
"{"$32"}_"{$18?2:0}\
"{"$33"}_"{$18?2:0}\
"{"$34"}_"{$18?2:0}

In particular, there’s a kind of distortion that sometimes happens which I want to recreate. Here’s an example from the Snorpey site:

image

This image is very interesting to me because it tells me that simply rounding everything afterwards isn’t gonna work…

image