/*
   The GLSoft_smart_filter_very-high-res GLSL shader

   shader levels: 1 - normal
                  2 - bloom
                  3 - natural
                  4 - natural + bloom
*/

float bloom   = 0.50;
float natural = 1.15;

uniform sampler2D OGL2Texture;
uniform vec4 OGL2Param;

const mat3 RGBtoYIQ = mat3(0.299, 0.596, 0.212, 
                           0.587,-0.275,-0.523, 
                           0.114,-0.321, 0.311);

const mat3 YIQtoRGB = mat3(1.000, 1.000, 1.000,
                           0.955,-0.271,-1.108,
                           0.619,-0.646, 1.705);
						   

void main()
{
	vec3 c11 = texture2D(OGL2Texture, gl_TexCoord[0].xy).xyz;
	vec3 s00 = texture2D(OGL2Texture, gl_TexCoord[1].xy).xyz; 
	vec3 s20 = texture2D(OGL2Texture, gl_TexCoord[2].xy).xyz; 
	vec3 s22 = texture2D(OGL2Texture, gl_TexCoord[3].xy).xyz; 
	vec3 s02 = texture2D(OGL2Texture, gl_TexCoord[4].xy).xyz; 
	vec3 c00 = texture2D(OGL2Texture, gl_TexCoord[5].xy).xyz; 
	vec3 c22 = texture2D(OGL2Texture, gl_TexCoord[6].xy).xyz; 
	vec3 c20 = texture2D(OGL2Texture, gl_TexCoord[5].zw).xyz;
	vec3 c02 = texture2D(OGL2Texture, gl_TexCoord[6].zw).xyz;
	vec3 c10 = texture2D(OGL2Texture, gl_TexCoord[1].zw).xyz; 
	vec3 c21 = texture2D(OGL2Texture, gl_TexCoord[2].zw).xyz; 
	vec3 c12 = texture2D(OGL2Texture, gl_TexCoord[3].zw).xyz; 
	vec3 c01 = texture2D(OGL2Texture, gl_TexCoord[4].zw).xyz;     
	vec3 dt = vec3(1.0,1.0,1.0);

	float d1=dot(abs(c00-c22),dt)+0.001;
	float d2=dot(abs(c20-c02),dt)+0.001;
	float hl=dot(abs(c01-c21),dt)+0.001;
	float vl=dot(abs(c10-c12),dt)+0.001;
	float m1=dot(abs(s00-s22),dt)+0.001;
	float m2=dot(abs(s02-s20),dt)+0.001;

	vec3 mn1 = min(min(c00,c01),c02);
	vec3 mn2 = min(min(c10,c11),c12);
	vec3 mn3 = min(min(c20,c21),c22);
	vec3 mx1 = max(max(c00,c01),c02);
	vec3 mx2 = max(max(c10,c11),c12);
	vec3 mx3 = max(max(c20,c21),c22);

	mn1 = min(min(mn1,mn2),mn3);
	mx1 = max(max(mx1,mx2),mx3);	

	vec3 t1=(hl*(c10+c12)+vl*(c01+c21)+(hl+vl)*c11)/(3.0*(hl+vl));
	vec3 t2=(d1*(c20+c02)+d2*(c00+c22)+(d1+d2)*c11)/(3.0*(d1+d2));
	
	c11 =.25*(t1+t2+(m2*(s00+s22)+m1*(s02+s20))/(m1+m2));
	
	vec3 dif = mx1-mn1;	
	float filterparam = clamp(3.0*max(dif.x,max(dif.y,dif.z)),1.0,1.6);

	vec3 dif1 = abs(c11-mn1) + 0.001*dt;
	vec3 dif2 = abs(c11-mx1) + 0.001*dt;

	dif1=vec3(pow(dif1.x,filterparam),pow(dif1.y,filterparam),pow(dif1.z,filterparam));
	dif2=vec3(pow(dif2.x,filterparam),pow(dif2.y,filterparam),pow(dif2.z,filterparam));

	c11.r = (dif1.x*mx1.x + dif2.x*mn1.x)/(dif1.x + dif2.x);
	c11.g = (dif1.y*mx1.y + dif2.y*mn1.y)/(dif1.y + dif2.y);
	c11.b = (dif1.z*mx1.z + dif2.z*mn1.z)/(dif1.z + dif2.z);

	if  (OGL2Param.z < 2.0) natural = 1.0;
	c11=RGBtoYIQ*c11;
	c11=vec3(pow(c11.x,natural),c11.yz*natural);
	c11=YIQtoRGB*c11;
	float k1 = length(c11); bloom = mod(OGL2Param.z,2)*bloom;
	gl_FragColor.xyz = (1.0-bloom)*c11 + bloom*mix(k1,normalize(vec2(k1*k1,0.82)).x*1.74,0.577*k1)*normalize(c11);
}




