'Glitch' Art Filters - again

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

You taught me how to do that with bit-plane shuffler, right? What’s different here if that’s the case.

I’ve found something workable. I also need to make the thing detect edges to emulate an error in the Huffman tables…

Edit: maybe shuffling isn’t the right idea. Huffman table errors can be extremely abrasive and I want to emulate them very well and in a more configurable way. I’ve found a site where I can easily edit JPEGs and see what happens - there, I made the two images by changing some Huffman table values:

Edit: here is the current state of this mess. I will add a new part just for the Huffman table error emulation.

#@gui JPEG Encoder: fx_jpeg_preview
#@gui : sep = separator()
#@gui : 1. Quality=float(80,0,100)
#@gui : 2. Bias=float(0,-5,5)
#@gui : 3. 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 : 4. Channel 1 Block Width = int(8,2,32)
#@gui : 5. Channel 1 Block Height = int(8,2,32)
#@gui : 6. Channel 2 Block Width = int(16,2,32)
#@gui : 7. Channel 2 Block Height = int(16,2,32)
#@gui : 8. Channel 3 Block Width = int(16,2,32)
#@gui : 9. Channel 3 Block Height = int(16,2,32)
#@gui : 10. Mirror = choice("None","X","Y","XY")
#@gui : 11. Rotate = choice("None,"90 clockwise","180","90 anticlockwise")
#@gui : sep = separator()
#@gui : Toggle Block Offsets = bool(0)
#@gui : 12. Channel 1 Block X Offset = int(0,-32,32)
#@gui : 13. Channel 1 Block Y Offset = int(0,-32,32)
#@gui : 14. Channel 2 Block X Offset = int(0,-32,32)
#@gui : 15. Channel 2 Block Y Offset = int(0,-32,32)
#@gui : 16. Channel 3 Block X Offset = int(0,-32,32)
#@gui : 17. Channel 3 Block Y Offset = int(0,-32,32)
#@gui : sep = separator()
#@gui : Toggle Distortion Glitch = bool(0)
#@gui : 18. Glitch Start = float(0.2,0,1)
#@gui : 19. Glitch Min Distance = float(0.2,0,1)
#@gui : 20. Glitch Max Distance = float(0.8,0,1)
#@gui : 21. Glitch Frequency Skew = float(-0.5,-1,1)
#@gui : 22. Glitch Min Length = int(1,1,10)
#@gui : 23. Glitch Max Length = int(5,1,10)
#@gui : 24. Discolouring Strength = float(1,0,2)
#@gui : 25. Discolouring Variation = float(1,0,2)
#@gui : 26. Discolouring Speed = float(1,0,2)
#@gui : 27. Additive Strength = float(1,0,2)
#@gui : 28. Persistent Error Strength = float(0.25,0,2)
#@gui : 29. Persistent Error Chance = float(0.25,0,1)
#@gui : 30. Tile Shift Direction = float(0.5,0,1)
#@gui : 31. Tile Shift Chance = float(0.25,0,1)
#@gui : 32. Tile Width = int(16,2,32)
#@gui : 33. Tile Height = int(16,2,32)
#@gui : 34. Tile X Offset = int(0,-32,32)
#@gui : 35. Tile Y Offset = int(0,-32,32)

fx_jpeg :
to_rgb

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

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

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

csswap 0,$cs

($4,$6,$8;$5,$7,$9;0,0,0;$12,$14,$16;$13,$15,$17)
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

# distortion 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. dpunch

# 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(#"$dpunch",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 itwh=itw*ith;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 glmin="$glmin";const glmax="$glmax";const glitchf=sqrt(max(twh/wh,(1-((1-avg("$ming","$maxg")^gfskew)^igfskew)))/avg(glmin,glmax));glitchdm=vector(#twh,1);first=1;gcount=0;glitchdc=0;glitchdv=0;glitcha=vector(#twh,0);aswitch=0;pswitch=0;ioff=0;shuf=vector(#twh,0);for(nn=0,nn<twh,nn++,shuf[nn]=nn);sswitch=0);
if (!(x%tw) && !(y%th),
ref(crop(x,y,0,0,tw,th,1,1,0),src);
res=(vector(#twh,0));
glitch=max(crop(#"$dpunch",x-ox,y-oy,0,0,tw,th,1,1,1));
(glitch)?(first?((glitchdc=u(-1,1)*glitchf);first=0;
#(u<0.25)?(sswitch=1; for(ii=(twh-1),ii>0,ii--,jj=floor(u(0,ii+1-1e-8));swap(shuf[ii],shuf[jj]))):(sswitch=0)
);
glitchcount=int(u(glmin,glmax+1-1e-8)));
(glitchcount)?(glitchcount-=1;aswitch=1;pswitch=((u<pec)?1:0);
glitchdv=(glitchdv+(u(-1,1)*glitchf*(ds^2)));
amult=ai^2;
):(amult=20^2);
(aswitch&&(!pswitch))?(for(n=1,n<twh,++n,
l=n-int(n*itw)*tw;k=int(n*itw);
glitcha[n]=(1/((l+1)*(k+1)))*(amult)*u(-1,1)));
#(sswitch)?(for(nn=0,nn<twh,nn++,res[nn]=src[shuf[nn]]);0):(res=src;0);
res=src+glitcha;
res[0]=lerp(res[0],sin(asin(res[0]*itwh*pi*0.5)+(glitchdc*10+glitchdv*(dv^2))*0.01*pi)*twh*2/pi,di^2);
draw(res,x,y,0,0,tw,th);
(pswitch==0)?(aswitch=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;const pow="$bias"; const invpow=1/pow);sign(i)*(factor*round((abs(i)^(invpow))*invfactor,qual))^pow"

# 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 $11
rotate {-$11*90},0
fi
if $10==1
mirror x
elif $10==2
mirror y
elif $10==3
mirror xy
fi

fx_jpeg_preview:

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

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

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

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

1 Like

@Joan_Rake1 How’s the JPEG Encoder coming out?