353 lines
8.7 KiB
Lua
353 lines
8.7 KiB
Lua
shader_dct_apply, result = shader_new{name="dct_apply",
|
|
vert=[=[
|
|
#version 120
|
|
// vertex shader
|
|
|
|
void main()
|
|
{
|
|
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
|
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
|
}
|
|
|
|
]=], frag=[=[
|
|
#version 120
|
|
// fragment shader
|
|
|
|
uniform sampler2D tex0;
|
|
uniform vec2 smul;
|
|
uniform vec2 smul_inv;
|
|
uniform float is_init;
|
|
uniform float is_fini;
|
|
uniform float is_inverse;
|
|
|
|
const float[] sfac = float[]( 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.0 );
|
|
|
|
// todo: replace this with a proper floating-point version
|
|
// rather than a fixed point integer version divided by its 1.0 representation
|
|
/*
|
|
const float[] cosinetab = float[](
|
|
0.3515625, 0.3515625, 0.3515625, 0.3515625, 0.3515625, 0.3515625, 0.3515625, 0.3515625,
|
|
0.48828125, 0.4140625, 0.27734375, 0.09375, -0.09375, -0.27734375,-0.4140625, -0.48828125,
|
|
0.4609375, 0.1875, -0.1875, -0.4609375, -0.4609375, -0.1875, 0.1875, 0.4609375,
|
|
0.4140625, -0.09375, -0.48828125,-0.27734375, 0.27734375, 0.48828125, 0.09375, -0.4140625,
|
|
0.3515625, -0.3515625, -0.3515625, 0.3515625, 0.3515625, -0.3515625, -0.3515625, 0.3515625,
|
|
0.27734375,-0.48828125, 0.09375, 0.4140625, -0.4140625, -0.09375, 0.48828125,-0.27734375,
|
|
0.1875, -0.4609375, 0.4609375, -0.1875, -0.1875, 0.4609375, -0.4609375, 0.1875,
|
|
0.09375, -0.27734375, 0.4140625, -0.48828125, 0.48828125,-0.4140625, 0.27734375,-0.09375
|
|
);
|
|
*/
|
|
|
|
const int[] deint_tab_y = int[](0,4,2,5,1,6,3,7);
|
|
//const int[] deint_tab_y_inv = int[](0,4,2,6,1,3,5,7);
|
|
|
|
// standard
|
|
const float recode_thres = 0.5*4.0*8.0/255.0;
|
|
const float recode_div = 32.0;
|
|
const float recode_round = 0.3/255.0;
|
|
|
|
/*
|
|
// sweet bro and hella jeff-tier
|
|
const float recode_thres = 0.05;
|
|
const float recode_div = 50.0;
|
|
const float recode_round = 0.3/255.0;
|
|
*/
|
|
|
|
vec3 color_recode(vec3 c)
|
|
{
|
|
vec3 s = sign(c);
|
|
c = abs(c);
|
|
|
|
const float mfac = 1.0/recode_div;
|
|
const float afac = -recode_thres/recode_div + recode_thres + recode_round;
|
|
|
|
// slightly slower to use mix,step
|
|
//c = mix(c, c*mfac + afac, step(recode_thres, c));
|
|
if(c.r > recode_thres) c.r = c.r*mfac + afac;
|
|
if(c.g > recode_thres) c.g = c.g*mfac + afac;
|
|
if(c.b > recode_thres) c.b = c.b*mfac + afac;
|
|
|
|
c *= s;
|
|
c += 0.5;
|
|
return c;
|
|
}
|
|
|
|
vec3 color_decode(vec3 c)
|
|
{
|
|
c -= 0.5;
|
|
|
|
vec3 s = sign(c);
|
|
c = abs(c);
|
|
|
|
const float mfac = 1.0*recode_div;
|
|
const float afac = -recode_thres*recode_div + recode_thres;
|
|
|
|
// slightly slower to use mix,step
|
|
//c = mix(c, c*mfac + afac, step(recode_thres, c));
|
|
if(c.r > recode_thres) c.r = c.r*mfac + afac;
|
|
if(c.g > recode_thres) c.g = c.g*mfac + afac;
|
|
if(c.b > recode_thres) c.b = c.b*mfac + afac;
|
|
|
|
c *= s;
|
|
return c;
|
|
}
|
|
|
|
vec3 space_recode(vec3 c)
|
|
{
|
|
float l = (c.r+c.g*2.0+c.b+2.0/255.0)/4.0;
|
|
float cr = c.r-l;
|
|
float cb = c.b-l;
|
|
return vec3(l, cr, cb);
|
|
}
|
|
|
|
vec3 space_decode(vec3 c)
|
|
{
|
|
float l = c.r;
|
|
float cr = c.g;
|
|
float cb = c.b;
|
|
|
|
float r = cr+l;
|
|
float b = cb+l;
|
|
float g = (l*4.0-r-b+1.0/255.0)/2.0;
|
|
return vec3(r, g, b);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
// get texcoord in pixels
|
|
vec2 tc = gl_TexCoord[0].st * smul;
|
|
|
|
// useful for debugging: skip pass
|
|
if(false)
|
|
{
|
|
vec4 color = texture2D(tex0, tc * smul_inv);
|
|
color.a = 1.0;
|
|
gl_FragColor = color;
|
|
return;
|
|
}
|
|
|
|
// get sub texcoords
|
|
tc += 0.02;
|
|
vec2 tcq = floor(tc / 8.0)*8.0;
|
|
vec2 tcr = floor(tc - tcq + 0.02);
|
|
tcq += 0.4;
|
|
|
|
vec2 offs_x = vec2(1.0, 0.0);
|
|
vec2 tcf = vec2(0.0, tcr.x);
|
|
int iquant = int(tcr.y+0.1);
|
|
|
|
// fetch pixels
|
|
vec3 color0 = texture2D(tex0, (tcq + tcf + 0.0*offs_x) * smul_inv).rgb;
|
|
vec3 color1 = texture2D(tex0, (tcq + tcf + 1.0*offs_x) * smul_inv).rgb;
|
|
vec3 color2 = texture2D(tex0, (tcq + tcf + 2.0*offs_x) * smul_inv).rgb;
|
|
vec3 color3 = texture2D(tex0, (tcq + tcf + 3.0*offs_x) * smul_inv).rgb;
|
|
vec3 color4 = texture2D(tex0, (tcq + tcf + 4.0*offs_x) * smul_inv).rgb;
|
|
vec3 color5 = texture2D(tex0, (tcq + tcf + 5.0*offs_x) * smul_inv).rgb;
|
|
vec3 color6 = texture2D(tex0, (tcq + tcf + 6.0*offs_x) * smul_inv).rgb;
|
|
vec3 color7 = texture2D(tex0, (tcq + tcf + 7.0*offs_x) * smul_inv).rgb;
|
|
|
|
// work out matrix to apply
|
|
bool do_transp = !(is_inverse != 0.0);
|
|
int quantmul = (do_transp ? 8 : 1);
|
|
int stepmul = (do_transp ? 1 : 8);
|
|
|
|
// decode interim dct values
|
|
if(is_init == 0.0)
|
|
{
|
|
color0 = color_decode(color0);
|
|
color1 = color_decode(color1);
|
|
color2 = color_decode(color2);
|
|
color3 = color_decode(color3);
|
|
color4 = color_decode(color4);
|
|
color5 = color_decode(color5);
|
|
color6 = color_decode(color6);
|
|
color7 = color_decode(color7);
|
|
} else {
|
|
color0 = space_decode(color0);
|
|
color1 = space_decode(color1);
|
|
color2 = space_decode(color2);
|
|
color3 = space_decode(color3);
|
|
color4 = space_decode(color4);
|
|
color5 = space_decode(color5);
|
|
color6 = space_decode(color6);
|
|
color7 = space_decode(color7);
|
|
}
|
|
|
|
// apply dct/idct
|
|
vec3 color;
|
|
|
|
if(do_transp)
|
|
{
|
|
int iqint = deint_tab_y[iquant];
|
|
//int iqint = iquant;
|
|
|
|
/*
|
|
if(iqint < 4) {
|
|
if (iqint < 2) {
|
|
iqint = (iqint == 0 ? 0 : 4);
|
|
} else {
|
|
iqint = (iqint == 2 ? 2 : 5);
|
|
}
|
|
} else {
|
|
if (iqint < 6) {
|
|
iqint = (iqint == 4 ? 1 : 6);
|
|
} else {
|
|
iqint = (iqint == 6 ? 3 : 7);
|
|
}
|
|
}
|
|
*/
|
|
|
|
if(iqint >= 4)
|
|
{
|
|
vec3 g0 = (color0-color7);
|
|
vec3 g1 = (color1-color6);
|
|
vec3 g2 = (color2-color5);
|
|
vec3 g3 = (color3-color4);
|
|
const float t0 = 0.48828125;
|
|
const float t1 = 0.4140625;
|
|
const float t2 = 0.27734375;
|
|
const float t3 = 0.09375;
|
|
|
|
if(iqint < 6)
|
|
{
|
|
color = (iqint == 4
|
|
? t0*g0 + t1*g1 + t2*g2 + t3*g3
|
|
: t1*g0 - t3*g1 - t0*g2 - t2*g3
|
|
);
|
|
} else {
|
|
color = (iqint == 6
|
|
? t2*g0 - t0*g1 + t3*g2 + t1*g3
|
|
: t3*g0 - t2*g1 + t1*g2 - t0*g3
|
|
);
|
|
}
|
|
|
|
} else if(iqint >= 2) {
|
|
vec3 g0 = (color0-color3-color4+color7);
|
|
vec3 g1 = (color1-color2-color5+color6);
|
|
color = (iqint == 2
|
|
? 0.1875*g1 + 0.4609375*g0
|
|
: 0.1875*g0 - 0.4609375*g1
|
|
);
|
|
|
|
} else {
|
|
vec3 g0 = (color0+color3+color4+color7);
|
|
vec3 g1 = (color1+color2+color5+color6);
|
|
color = 0.3515625*(iqint == 0 ? g0+g1 : g0-g1);
|
|
}
|
|
|
|
/*
|
|
if(iqint-(iqint/2)*2 == 1)
|
|
{
|
|
vec3 g0 = (color0-color7);
|
|
vec3 g1 = (color1-color6);
|
|
vec3 g2 = (color2-color5);
|
|
vec3 g3 = (color3-color4);
|
|
const float t0 = 0.48828125;
|
|
const float t1 = 0.4140625;
|
|
const float t2 = 0.27734375;
|
|
const float t3 = 0.09375;
|
|
|
|
if(iqint < 4)
|
|
{
|
|
color = (iqint == 1
|
|
? t0*g0 + t1*g1 + t2*g2 + t3*g3
|
|
: t1*g0 - t3*g1 - t0*g2 - t2*g3
|
|
);
|
|
} else {
|
|
color = (iqint == 5
|
|
? t2*g0 - t0*g1 + t3*g2 + t1*g3
|
|
: t3*g0 - t2*g1 + t1*g2 - t0*g3
|
|
);
|
|
}
|
|
} else if(iqint == 2 || iqint == 6) {
|
|
vec3 g0 = (color0-color3-color4+color7);
|
|
vec3 g1 = (color1-color2-color5+color6);
|
|
color = (iqint == 2
|
|
? 0.1875*g1 + 0.4609375*g0
|
|
: 0.1875*g0 - 0.4609375*g1
|
|
);
|
|
|
|
} else {
|
|
vec3 g0 = (color0+color3+color4+color7);
|
|
vec3 g1 = (color1+color2+color5+color6);
|
|
color = 0.3515625*(iqint == 0 ? g0+g1 : g0-g1);
|
|
}
|
|
*/
|
|
|
|
/*
|
|
color0 = color0*cosinetab[8*iquant+0];
|
|
color1 = color1*cosinetab[8*iquant+1];
|
|
color2 = color2*cosinetab[8*iquant+2];
|
|
color3 = color3*cosinetab[8*iquant+3];
|
|
color4 = color4*cosinetab[8*iquant+4];
|
|
color5 = color5*cosinetab[8*iquant+5];
|
|
color6 = color6*cosinetab[8*iquant+6];
|
|
color7 = color7*cosinetab[8*iquant+7];
|
|
color = (color0 + color1 + color2 + color3 + color4 + color5 + color6 + color7);
|
|
*/
|
|
} else {
|
|
const float t0 = 0.48828125;
|
|
const float t1 = 0.4140625;
|
|
const float t2 = 0.27734375;
|
|
const float t3 = 0.09375;
|
|
|
|
/*
|
|
bool mflip1 = (iquant >= 4);
|
|
int msel1 = (mflip1 ? 7-iquant : iquant);
|
|
bool msel2 = (msel1 >= 2);
|
|
bool msel0 = (msel1 == 0 || msel1 == 3);
|
|
*/
|
|
bool mflip1 = (iquant >= 4);
|
|
int msel1 = (mflip1 ? 7-iquant : iquant);
|
|
bool msel2 = (msel1 >= 2);
|
|
bool msel0 = (msel1 == 0 || msel1 == 3);
|
|
|
|
vec3 m0 = 0.3515625*(msel0
|
|
? color0 + color4
|
|
: color0 - color4);
|
|
|
|
vec3 m2 = (msel0
|
|
? 0.4609375*color2 + 0.18750*color6
|
|
: 0.18750*color2 - 0.4609375*color6);
|
|
m2 = (msel2 ? -m2 : m2);
|
|
|
|
vec3 m1;
|
|
if(msel1 == 0)
|
|
{
|
|
m1 = t0*color1+t1*color3+t2*color5+t3*color7;
|
|
} else if(msel1 == 1) {
|
|
m1 = t1*color1-t3*color3-t0*color5-t2*color7;
|
|
} else if(msel1 == 2) {
|
|
m1 = t2*color1-t0*color3+t3*color5+t1*color7;
|
|
} else {
|
|
m1 = t3*color1-t2*color3+t1*color5-t0*color7;
|
|
}
|
|
m1 = (mflip1 ? -m1 : m1);
|
|
color = m0+m1+m2;
|
|
|
|
/*
|
|
color0 = color0*cosinetab[iquant+8*0];
|
|
color1 = color1*cosinetab[iquant+8*1];
|
|
color2 = color2*cosinetab[iquant+8*2];
|
|
color3 = color3*cosinetab[iquant+8*3];
|
|
color4 = color4*cosinetab[iquant+8*4];
|
|
color5 = color5*cosinetab[iquant+8*5];
|
|
color6 = color6*cosinetab[iquant+8*6];
|
|
color7 = color7*cosinetab[iquant+8*7];
|
|
color = (color0 + color1 + color2 + color3 + color4 + color5 + color6 + color7);
|
|
*/
|
|
}
|
|
|
|
// encode interim dct value
|
|
if(is_fini == 0.0)
|
|
color = color_recode(color);
|
|
else
|
|
color = space_recode(color);
|
|
|
|
gl_FragColor = vec4(color, 1.0);
|
|
}
|
|
|
|
]=]}
|
|
|
|
assert(shader_dct_apply, result)
|
|
|