/*
 * SDL_zoom_template - surface scaling
 * 
 * Copyright (c) 2009 Citrix Systems, Inc.
 *
 * Derived from: SDL_rotozoom,  LGPL (c) A. Schiffler from the SDL_gfx library.
 * Modifications by Stefano Stabellini.
 *
 * This work is licensed under the terms of the GNU GPL version 2.
 * See the COPYING file in the top-level directory.
 *
 */

#if BPP == 16
#define SDL_TYPE Uint16
#elif BPP == 32
#define SDL_TYPE Uint32
#else
#error unsupport depth
#endif

/*  
 *  Simple helper functions to make the code looks nicer
 *
 *  Assume spf = source SDL_PixelFormat
 *         dpf = dest SDL_PixelFormat
 *
 */
#define getRed(color)   (((color) & spf->Rmask) >> spf->Rshift)
#define getGreen(color) (((color) & spf->Gmask) >> spf->Gshift)
#define getBlue(color)  (((color) & spf->Bmask) >> spf->Bshift)
#define getAlpha(color) (((color) & spf->Amask) >> spf->Ashift)

#define setRed(r, pcolor) do { \
    *pcolor = ((*pcolor) & (~(dpf->Rmask))) + \
              (((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \
} while (0);

#define setGreen(g, pcolor) do { \
    *pcolor = ((*pcolor) & (~(dpf->Gmask))) + \
              (((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \
} while (0);

#define setBlue(b, pcolor) do { \
    *pcolor = ((*pcolor) & (~(dpf->Bmask))) + \
              (((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \
} while (0);

#define setAlpha(a, pcolor) do { \
    *pcolor = ((*pcolor) & (~(dpf->Amask))) + \
              (((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \
} while (0);

static int glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smooth,
                                   SDL_Rect *dst_rect)
{
    int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, sstep_jump;
    SDL_TYPE *c00, *c01, *c10, *c11, *sp, *csp, *dp;
    int d_gap;
    SDL_PixelFormat *spf = src->format;
    SDL_PixelFormat *dpf = dst->format;

    if (smooth) { 
        /* For interpolation: assume source dimension is one pixel.
         * Smaller here to avoid overflow on right and bottom edge.
         */
        sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w);
        sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h);
    } else {
        sx = (int) (65536.0 * (float) src->w / (float) dst->w);
        sy = (int) (65536.0 * (float) src->h / (float) dst->h);
    }

    if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
        return (-1);
    }
    if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
        free(sax);
        return (-1);
    }

    sp = csp = (SDL_TYPE *) src->pixels;
    dp = (SDL_TYPE *) (dst->pixels + dst_rect->y * dst->pitch +
                       dst_rect->x * dst->format->BytesPerPixel);

    csx = 0;
    csax = sax;
    for (x = 0; x <= dst->w; x++) {
        *csax = csx;
        csax++;
        csx &= 0xffff;
        csx += sx;
    }
    csy = 0;
    csay = say;
    for (y = 0; y <= dst->h; y++) {
        *csay = csy;
        csay++;
        csy &= 0xffff;
        csy += sy;
    }

    d_gap = dst->pitch - dst_rect->w * dst->format->BytesPerPixel;

    if (smooth) {
        csay = say;
        for (y = 0; y < dst_rect->y; y++) {
            csay++;
            sstep = (*csay >> 16) * src->pitch;
            csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
        }

        /* Calculate sstep_jump */
        csax = sax; 
        sstep_jump = 0;
        for (x = 0; x < dst_rect->x; x++) {
            csax++; 
            sstep = (*csax >> 16);
            sstep_jump += sstep;
        }

        for (y = 0; y < dst_rect->h ; y++) {
            /* Setup colour source pointers */
            c00 = csp + sstep_jump;
            c01 = c00 + 1;
            c10 = (SDL_TYPE *) ((Uint8 *) csp + src->pitch) + sstep_jump;
            c11 = c10 + 1;
            csax = sax + dst_rect->x; 

            for (x = 0; x < dst_rect->w; x++) {

                /* Interpolate colours */
                ex = (*csax & 0xffff);
                ey = (*csay & 0xffff);
                t1 = ((((getRed(*c01) - getRed(*c00)) * ex) >> 16) +
                     getRed(*c00)) & (dpf->Rmask >> dpf->Rshift);
                t2 = ((((getRed(*c11) - getRed(*c10)) * ex) >> 16) +
                     getRed(*c10)) & (dpf->Rmask >> dpf->Rshift);
                setRed((((t2 - t1) * ey) >> 16) + t1, dp);
                t1 = ((((getGreen(*c01) - getGreen(*c00)) * ex) >> 16) +
                     getGreen(*c00)) & (dpf->Gmask >> dpf->Gshift);
                t2 = ((((getGreen(*c11) - getGreen(*c10)) * ex) >> 16) +
                     getGreen(*c10)) & (dpf->Gmask >> dpf->Gshift);
                setGreen((((t2 - t1) * ey) >> 16) + t1, dp);
                t1 = ((((getBlue(*c01) - getBlue(*c00)) * ex) >> 16) +
                     getBlue(*c00)) & (dpf->Bmask >> dpf->Bshift);
                t2 = ((((getBlue(*c11) - getBlue(*c10)) * ex) >> 16) +
                     getBlue(*c10)) & (dpf->Bmask >> dpf->Bshift);
                setBlue((((t2 - t1) * ey) >> 16) + t1, dp);
                t1 = ((((getAlpha(*c01) - getAlpha(*c00)) * ex) >> 16) +
                     getAlpha(*c00)) & (dpf->Amask >> dpf->Ashift);
                t2 = ((((getAlpha(*c11) - getAlpha(*c10)) * ex) >> 16) +
                     getAlpha(*c10)) & (dpf->Amask >> dpf->Ashift);
                setAlpha((((t2 - t1) * ey) >> 16) + t1, dp); 

                /* Advance source pointers */
                csax++; 
                sstep = (*csax >> 16);
                c00 += sstep;
                c01 += sstep;
                c10 += sstep;
                c11 += sstep;
                /* Advance destination pointer */
                dp++;
            }
            /* Advance source pointer */
            csay++;
            csp = (SDL_TYPE *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
            /* Advance destination pointers */
            dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
        }


    } else {
        csay = say;

        for (y = 0; y < dst_rect->y; y++) {
            csay++;
            sstep = (*csay >> 16) * src->pitch;
            csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
        }

        /* Calculate sstep_jump */
        csax = sax; 
        sstep_jump = 0;
        for (x = 0; x < dst_rect->x; x++) {
            csax++; 
            sstep = (*csax >> 16);
            sstep_jump += sstep;
        }

        for (y = 0 ; y < dst_rect->h ; y++) {
            sp = csp + sstep_jump;
            csax = sax + dst_rect->x;

            for (x = 0; x < dst_rect->w; x++) {

                /* Draw */
                *dp = *sp;

                /* Advance source pointers */
                csax++;
                sstep = (*csax >> 16);
                sp += sstep;

                /* Advance destination pointer */
                dp++;
            }
            /* Advance source pointers */
            csay++;
            sstep = (*csay >> 16) * src->pitch;
            csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);

            /* Advance destination pointer */
            dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
        }
    }

    free(sax);
    free(say);
    return (0);
}

#undef SDL_TYPE

