/**
 * TrueReality - output/display/sw_renderer.c
 * Copyright (C) 1998, 1999 Niki W. Waibel
 *
 * This program is free software; you can redistribute it and/
 * or modify it under the terms of the GNU General Public Li-
 * cence as published by the Free Software Foundation; either
 * version 2 of the Licence, or any later version.
 *
 * This program is distributed in the hope that it will be use-
 * ful, but WITHOUT ANY WARRANTY; without even the implied war-
 * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public Licence for more details.
 *
 * You should have received a copy of the GNU General Public
 * Licence along with this program; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 * USA.
 *
 * Information about me (the author):
 *   Niki W. Waibel, Reichenau 20, 6890 Lustenau, Austria - EUROPE
 *   niki.waibel@gmx.net
**/





/*
*
*  All ideas from: Guenther Sohler
*
*  The 15/24/32bit and all endian stuff were hacked out by myself (Niki W.
*  Waibel) using the 8/16bit stuff from Guenther Sohler as a bases.
*  HEY GUE, GREAT WORK!
*
*/





#include <stdio.h>

#include <type_sizes.h>
#include <x11_extern.h>

#include "sw_renderer.h"





void
render_image_16_to_06(HWORD *imsrc2, BYTE *imdst1, int width, int height, int WIDTH, int HEIGHT)
{
        int     i, j, k, l;
        HWORD   ui;
        BYTE    c;

        for(j=0, i=0; i<height; i++)
        {
                for(; (j+1)*height <= (i+1)*HEIGHT; j++)
                {
                        for (l=0, k=0; k<width; k++)
                        {
#ifdef ENDIAN_IS_LITTLE
                                ui = imsrc2[(i*width+k) ^ 0x01];
#endif
#ifdef ENDIAN_IS_BIG
                                ui = imsrc2[(i*width+k)];
#endif
                                c  = ((ui & 0x30) >> 4) | ((ui & 0x600) >> 7) | ((ui & 0xc000) >> 10);

                                for(; (l+1)*width <= (k+1)*WIDTH; l++)
                                {
                                        imdst1[j*WIDTH+l] = c;
                                }
                        }
                }
        }
}





void
render_image_16_to_15(HWORD *imsrc2, HWORD *imdst2, int width, int height, int WIDTH, int HEIGHT)
{
        int     i, j, k, l;
        HWORD   ui;

        for(j=0, i=0; i<height; i++)
        {
                for(; (j+1)*height <= (i+1)*HEIGHT; j++)
                {
                        for(l=0, k=0; k<width; k++)
                        {
#ifdef ENDIAN_IS_BIG
                                ui = imsrc2[i*width+k];
#endif
#ifdef ENDIAN_IS_LITTLE
                                ui = imsrc2[(i*width+k)^0x01];
#endif
                                for(; (l+1)*width <= (k+1)*WIDTH; l++)
                                {
                                        imdst2[j*WIDTH+l] = ui >> 1;
                                }
                        }
                }
        }
}





void
render_image_16_to_16(HWORD *imsrc2, HWORD *imdst2, int width, int height, int WIDTH, int HEIGHT)
{
        int     i, j, k, l;
        HWORD   ui;

        for(j=0, i=0; i<height; i++)
        {
                for(; (j+1)*height <= (i+1)*HEIGHT; j++)
                {
                        for(l=0, k=0; k<width; k++)
                        {
#ifdef ENDIAN_IS_BIG
                                ui = imsrc2[i*width+k];
#endif
#ifdef ENDIAN_IS_LITTLE
                                ui = imsrc2[(i*width+k)^0x01];
#endif
                                ui = ((ui >> 1) & 0x1f) | (ui & 0xffc0);

                                for(; (l+1)*width <= (k+1)*WIDTH; l++)
                                {
                                        imdst2[j*WIDTH+l] = ui;
                                }
                        }
                }
        }
}





void
render_image_16_to_24(HWORD *imsrc2, BYTE *imdst1, int width, int height, int WIDTH, int HEIGHT)
{
        int     i, j, k, l;
        HWORD   ui;

        for(j=0, i=0; i<height; i++)
        {
                for(; (j+1)*height <= (i+1)*HEIGHT; j++)
                {
                        for(l=0, k=0; k<width; k++)
                        {
#ifdef ENDIAN_IS_LITTLE
                                ui = imsrc2[(i*width+k)^0x01];
#endif
#ifdef ENDIAN_IS_BIG
                                ui = imsrc2[i*width+k];
#endif
                                for(; (l+1)*width <= (k+1)*WIDTH; l++)
                                {
                                        imdst1[3*(j*WIDTH+l)+0] = (ui << 2) & 0xf8;
                                        imdst1[3*(j*WIDTH+l)+1] = (ui >> 3) & 0xf8;
                                        imdst1[3*(j*WIDTH+l)+2] = (ui >> 8) & 0xf8;
                                }
                        }
                }
        }

}





void
render_image_16_to_32(HWORD *imsrc2, WORD *imdst4, int width, int height, int WIDTH, int HEIGHT)
{
        int     i, j, k, l;
        HWORD   ui;

        for(j=0, i=0; i<height; i++)
        {
                for(; (j+1)*height <= (i+1)*HEIGHT; j++)
                {
                        for(l=0, k=0; k<width; k++)
                        {
#ifdef ENDIAN_IS_BIG
                                ui = imsrc2[i*width+k];
#endif
#ifdef ENDIAN_IS_LITTLE
                                ui = imsrc2[(i*width+k)^0x01];
#endif
                                for(; (l+1)*width <= (k+1)*WIDTH; l++)
                                {
                                        imdst4[j*WIDTH+l] =
                                                ((ui << 18) & 0xf80000) |
                                                ((ui <<  5) & 0x00f800) |
                                                ((ui <<  2) & 0x0000f8);
                                }
                        }
                }
        }
}










void
render_image_32_to_06(WORD *imsrc4, BYTE *imdst1, int width, int height, int WIDTH, int HEIGHT)
{
        int     i, j, k, l;
        WORD    ul;
        BYTE    c;

        for(j=0, i=0; i<height; i++)
        {
                for(; (j+1)*height <= (i+1)*HEIGHT; j++)
                {
                        for(l=0, k=0; k<width; k++)
                        {
                                ul = imsrc4[i*width+k];
                                c = ((ul & 0xc0) >> 6) | ((ul & 0xc000) >> 12) | ((ul & 0xc00000) >> 18);
                                
                                for (; (l+1)*width <= (k+1)*WIDTH; l++)
                                {
                                        imdst1[j*WIDTH] = c;
                                }
                        }
                }
        }
}





void
render_image_32_to_15(WORD *imsrc4, HWORD *imdst2, int width, int height, int WIDTH, int HEIGHT)
{
        int     i, j, k, l;
        HWORD   ui;
        WORD    ul;

        for(j=0, i=0; i < height; i++)
        {
                for(; (j+1)*height <= (i+1)*HEIGHT; j++)
                {
                        for(l=0, k=0; k<width; k++)
                        {
                                ul = imsrc4[i*width+k];
                                ui = ((ul & 0xf8) >> 3) | ((ul & 0xf800) >> 6) | ((ul & 0xf80000) >> 9);

                                for(; (l+1)*width <= (k+1)*WIDTH; l++)
                                {
                                        imdst2[j*WIDTH+l] = ui;
                                }
                        }
                }
        }
}





void
render_image_32_to_16(WORD *imsrc4, HWORD *imdst2, int width, int height, int WIDTH, int HEIGHT)
{
        int     i, j, k, l;
        HWORD   ui;
        WORD    ul;

        for(j=0, i=0; i < height; i++)
        {
                for(; (j+1)*height <= (i+1)*HEIGHT; j++)
                {
                        for(l=0, k=0; k<width; k++)
                        {
                                ul = imsrc4[i*width+k];
                                ui = ((ul & 0xf8) >> 3) | ((ul & 0xfc00) >> 5) | ((ul & 0xf80000) >> 8);

                                for(; (l+1)*width <= (k+1)*WIDTH; l++)
                                {
                                        imdst2[j*WIDTH+l] = ui;
                                }
                        }
                }
        }
}





void
render_image_32_to_24(WORD *imsrc4, BYTE *imdst1, int width, int height, int WIDTH, int HEIGHT)
{
        int     i, j, k, l;

        for(j=0, i=0; i < height; i++)
        {
                for(; (j+1)*height <= (i+1)*HEIGHT; j++)
                {
                        for(l=0, k=0; k<width; k++)
                        {
                                for(; (l+1)*width <= (k+1)*WIDTH; l++)
                                {
                                        imdst1[3*(j*WIDTH+l)+0] = (imsrc4[i*width+k] & 0xf800)     >> 8;
                                        imdst1[3*(j*WIDTH+l)+1] = (imsrc4[i*width+k] & 0xf80000)   >> 16;
                                        imdst1[3*(j*WIDTH+l)+2] = (imsrc4[i*width+k] & 0xf8000000) >> 24;
                                }
                        }
                }
        }
}





void
render_image_32_to_32(WORD *imsrc4, WORD *imdst4, int width, int height, int WIDTH, int HEIGHT)
{
        int     i, j, k, l;

        for(j=0, i=0; i < height; i++)
        {
                for(; (j+1)*height <= (i+1)*HEIGHT; j++)
                {
                        for(l=0, k=0; k<width; k++)
                        {
                                for(; (l+1)*width <= (k+1)*WIDTH; l++)
                                {
                                        imdst4[j*WIDTH+l] = imsrc4[i*width+k] >> 8;
                                }
                        }
                }
        }
}

