/*
 * Reverse Antialiasing Shader
 * http://kdepepo.wordpress.com/2012/08/15/reverse-antialiasing-for-image-scaling/
 *
 * Adapted from the C source (see Copyright below) to shader
 * cg language by Hyllian/Jararaca - sergiogdb@gmail.com
 *
 * Adapted from the cg to glsl edgbla - edgbla@yandex.ru
 *
 * This shader works best using 2x scale.
 */

/* source: http://imagezero.maxiom.de/files/ppmdouble.c
 *
 * Copyright (c) 2012, Christoph Feck <christoph@maxiom.de>
 * All Rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

uniform sampler2D OGL2Texture;
uniform vec4 OGL2Param;
uniform vec4 OGL2Size;
uniform vec4 OGL2InvSize;

void main()
{
    vec2 fp = fract(gl_TexCoord[0].xy * OGL2Size.xy);
    vec3 n1, n2, n3, n4, s, aa, bb, cc, dd;
    vec3 t, m;

    vec3 B1 = texture2D(OGL2Texture, gl_TexCoord[1].yw).rgb;
    vec3 B  = texture2D(OGL2Texture, gl_TexCoord[2].yw).rgb;
    vec3 D  = texture2D(OGL2Texture, gl_TexCoord[3].xw).rgb;
    vec3 E  = texture2D(OGL2Texture, gl_TexCoord[3].yw).rgb;
    vec3 F  = texture2D(OGL2Texture, gl_TexCoord[3].zw).rgb;
    vec3 H  = texture2D(OGL2Texture, gl_TexCoord[4].yw).rgb;
    vec3 H5 = texture2D(OGL2Texture, gl_TexCoord[5].yw).rgb;
    vec3 D0 = texture2D(OGL2Texture, gl_TexCoord[6].xz).rgb;
    vec3 F4 = texture2D(OGL2Texture, gl_TexCoord[7].xz).rgb;

    n1 = B1;
    n2 = B;
    s = E;
    n3 = H;
    n4 = H5;
    aa = n2 - n1;
    bb = s - n2;
    cc = n3 - s;
    dd = n4 - n3;

    t = (vec3(7.0, 7.0, 7.0) * (bb + cc) - vec3(3.0, 3.0, 3.0) * (aa + dd)) / vec3(16.0, 16.0, 16.0);

    if(all(lessThan(s, vec3(0.5, 0.5, 0.5))))
        m = vec3(2.0, 2.0, 2.0) * s;
    else
        m = vec3(2.0, 2.0, 2.0) * (vec3(1.0, 1.0, 1.0) - s);

    m = min(m, vec3(2.0, 2.0, 2.0) * abs(bb));
    m = min(m, vec3(2.0, 2.0, 2.0) * abs(cc));

    t = clamp(t, -m, m);

    vec3 s1 = s + t / vec3(2.0, 2.0, 2.0);
    vec3 s0 = s1 - t;

    n1 = D0;
    n2 = D;
    s = s0;
    n3 = F;
    n4 = F4;
    aa = n2 - n1;
    bb = s - n2;
    cc = n3 - s;
    dd = n4 - n3;

    t = (vec3(7.0, 7.0, 7.0) * (bb + cc) - vec3(3.0, 3.0, 3.0) * (aa + dd)) / vec3(16.0, 16.0, 16.0);

    if(all(lessThan(s, vec3(0.5, 0.5, 0.5))))
        m = vec3(2.0, 2.0, 2.0) * s;
    else
        m = vec3(2.0, 2.0, 2.0) * (vec3(1.0, 1.0, 1.0) - s);

    m = min(m, vec3(2.0, 2.0, 2.0) * abs(bb));
    m = min(m, vec3(2.0, 2.0, 2.0) * abs(cc));

    t = clamp(t, -m, m);

    vec3 E1 = s + t / vec3(2.0, 2.0, 2.0);
    vec3 E0 = E1 - t;

    s = s1;
    bb = s - n2;
    cc = n3 - s;

    t = (vec3(7.0, 7.0, 7.0) * (bb + cc) - vec3(3.0, 3.0, 3.0) * (aa + dd)) / vec3(16.0, 16.0, 16.0);

    if(all(lessThan(s, vec3(0.5, 0.5, 0.5))))
        m = vec3(2.0, 2.0, 2.0) * s;
    else
        m = vec3(2.0, 2.0, 2.0) * (vec3(1.0, 1.0, 1.0) - s);

    m = min(m, vec3(2.0, 2.0, 2.0) * abs(bb));
    m = min(m, vec3(2.0, 2.0, 2.0) * abs(cc));

    t = clamp(t, -m, m);

    vec3 E3 = s + t / vec3(2.0, 2.0, 2.0);
    vec3 E2 = E3 - t;

    vec3 res = (fp.x < 0.5) ? (fp.y < 0.5 ? E0 : E2) : (fp.y < 0.5 ? E1: E3);

    gl_FragColor = vec4(res, 1.0);
}
