// SuperResolution720p - Beta3
// Emmanuel - 31/03/2010
// Filtre de super resolution adapte aux diffuseurs 720p
// Ce filtre est concu comme un filtre de post-traitement d'un 
// filtre de sharpen tel que le filtre "unsharp mask" de ffdshow

#define FinesseRendu 0 // 0: tres fin, 1: fin, 2: moyen, 3: grossier 

#define SeuilBruit 0.15   // pour eviter la remontee du bruit de fond et
               // l'accentuation de petits details dans les textures
               // Entre 0.1 et 0.2

#define diff 0.49      // influe sur le rendu "3D-Like"
               // Apres unsharp mask a 19 dans ffdshow:
               // 0.49 => 3D-Like + present
               // 0.50 => 3D-Like present
               // 0.51 => 3D-Like - present 

sampler s0 : register(s0);
float4 p1 : register(c1);

#define dx (p1[0])
#define dy (p1[1])

float4 main( float2 tex : TEXCOORD0 ) : COLOR
{
   // pixels original, floute, corrige
   float4 ori = tex2D(s0, tex);
   float4 flou;
   float4 cori;
   float seuil = 0.82 + FinesseRendu/100;

   // recuperation de la matrice de 9 points
   // [ 1, 2 , 3 ]
   // [ 4,ori, 5 ]
   // [ 6, 7 , 8 ]

   float4 c1 = tex2D(s0, tex + float2(-dx,-dy));
   float4 c2 = tex2D(s0, tex + float2(0,-dy));
   float4 c3 = tex2D(s0, tex + float2(dx,-dy));
   float4 c4 = tex2D(s0, tex + float2(-dx,0));
   float4 c5 = tex2D(s0, tex + float2(dx,0));
   float4 c6 = tex2D(s0, tex + float2(-dx,dy));
   float4 c7 = tex2D(s0, tex + float2(0,dy));
   float4 c8 = tex2D(s0, tex + float2(dx,dy));

   // detection des contours
   // par filtre de sobel
   float delta1,delta2,value;

   // Gradient horizontal
   //   [ -1, 0 ,1 ]
   //   [ -2, 0, 2 ]
   //   [ -1, 0 ,1 ]
   delta1 = (c3 + 2*c5 + c8)-(c1 + 2*c4 + c6);

   // Gradient vertical
   //   [ -1,- 2,-1 ]
   //   [  0,  0, 0 ]
   //   [  1,  2, 1 ]
   delta2 = (c6 + 2*c7 + c8)-(c1 + 2*c2 + c3);

   // calcul
   value =  sqrt(mul(delta1,delta1) + mul(delta2,delta2)) ;

   // Gamma adaptatif a proximite d'une transition
   cori = ori;
   if ((value >= seuil-diff*1.15)&&(value <= seuil)) cori = pow(ori,1./(1-value/10));

   // Masque flou pour renforcer les textures

   // calcul image floue (filtre gaussien)
   // pour normaliser les valeurs, il faut diviser par la somme des coef
   // 1/(1+2+1+2+4+2+1+2+1) = 1/ 16 = .0625

   flou = (c1+c3+c6+c8 + 2*(c2+c4+c5+c7)+ 4*cori)*0.0625;

   // Accentuation des textures si on est loin d'un bord 
   if ((value > SeuilBruit) && (value < seuil-diff)) cori = 2*cori - flou;

   return cori;
}

