'Glitch' Art Filters - again

(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

Is that the aftermath image after the applied filter? It seems that you’re close, but I can’t help as I don’t know about JPEG enough to find a solution for you. Other than that I like it better than the one you want to recreate.

No, it’s a real screwed up JPEG from the Snorpey site again. I’m not going for the exact effect but I want to capture this thing with the pattern of tiles. Why high-frequency vertical ones in particular?

I don’t know how to get this Fisher-Yates shuffle to work properly:

rm
8,1,1,1,"x"
f "begin(shuffle(vv)=
(nn=size(vv);for(ii=(nn-1),ii>0,ii-=1,jj=floor(u(0,ii+1-1e-8));swap(vv[ii],vv[jj]));vv));
ref(crop(0,0,8,1),src);
shuffle(src);
draw(src);"
d