I realise that I am actually running two IDCTs. I can generate a tile set for a DCT but I want to figure out a faster way.
rm
tw=8
th=8
{$tw^2},{$th^2},1,1
+f "!((x%("$tw"+1))||(y%("$th"+1)))?1" at. "dct",$tw,$th
n 0,255
display
Edit: I’ve figured out how to make the DCT tileset, and now the encoder is working for square tiles. For some reason it doesn’t work for non-square tiles.
dct_tileset:
{$1^2},{$2^2},1,1
f. :"begin(const tw=$1;const th=$2;const stw=sqrt(tw);const sth=sqrt(th);const itw=1/tw;const ith=1/th;const istw=sqrt(itw);const isth=sqrt(ith);const s2=sqrt(2));
px=x%tw;
py=y%th;
tx=(x-(px))*itw;
ty=(y-(py))*ith;
cx=cos((tx*0.5+((tx+0.5)*x*itw))*pi)*istw;
cy=cos((ty*0.5+((ty+0.5)*y*ith))*pi)*isth;
px!=0?(cx*=s2);
py!=0?(cy*=s2);
val=cx*cy;
val;
"
idct_tileset:
{$1^2},{$2^2},1,1
f. :"begin(const tw=$1;const th=$2;const stw=sqrt(tw);const sth=sqrt(th);const itw=1/tw;const ith=1/th;const istw=sqrt(itw);const isth=sqrt(ith);const s2=sqrt(2));
px=x%tw;
py=y%th;
tx=(x-(px))*itw;
ty=(y-(py))*ith;
cx=cos((x+0.5)*tx*pi*itw)*istw;
cy=cos((y+0.5)*ty*pi*ith)*isth;
tx!=0?(cx*=s2);
ty!=0?(cy*=s2);
val=cx*cy;
((tx+ty)%2)?(val*=-1);
val;
"
fx_jpeg :
to_rgb
tw=8
th=8
dct_tileset $tw,$th
idct_tileset $tw,$th
nm[-2,-1] dct,idct
repeat {$!-2} l[$>,dct,idct]
ww={w(#0)}
hh={h(#0)}
r[0] {w(#0)+(-w(#0)%$tw)},{h(#0)+(-h(#0)%$th)},1,100%,0,3
s[0] c
repeat 3
[$>]
f[$>] :"
begin_t(const tw="$tw";const th="$th";const twh=tw*th);
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 + th*l; res += src[off]*crop(#"$dct",k*tw,l*th,tw,th,1)));
draw(#-1,res,x,y,0,0,tw,th);
); i"
f. :"
begin_t(const tw="$tw";const th="$th";const twh=tw*th;res=vector(#twh));
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 + th*l; res += src[off]*crop(#"$idct",k*tw,l*th,tw,th,1)));
draw(#"$>",res,x,y,0,0,tw,th);
); i"
rm.
done
a[0-2] c
r[0] {$ww},{$hh},1,100%,0,3
endl done
rm[dct,idct]
display
When the second dimension is smaller than the first, it looks all wrong. When it’s larger, all the values in the resulting image turn to NaN.
Edit: a simple fix, I should’ve used tw
and not th
.
fx_jpeg :
to_rgb
tw=$1
th=$2
dct_tileset $tw,$th
idct_tileset $tw,$th
nm[-2,-1] dct,idct
repeat {$!-2} l[$>,dct,idct]
ww={w(#0)}
hh={h(#0)}
r[0] {w(#0)+(-w(#0)%$tw)},{h(#0)+(-h(#0)%$th)},1,100%,0,3
s[0] c
repeat 3
[$>]
f[$>] :"
begin_t(const tw="$tw";const th="$th";const twh=tw*th);
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(#"$dct",k*tw,l*th,tw,th,1)));
draw(#-1,res,x,y,0,0,tw,th);
); i"
f. :"
begin_t(const tw="$tw";const th="$th";const twh=tw*th;res=vector(#twh));
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(#"$idct",k*tw,l*th,tw,th,1)));
draw(#"$>",res,x,y,0,0,tw,th);
); i"
rm.
done
a[0-2] c
r[0] {$ww},{$hh},1,100%,0,3
endl done
rm[dct,idct]