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: