/****************************************************************************
 * loadbmap.c                                                               *
 *   Purpose: contains utility functions to load files based on colour      *
 *            depth.  We use both IMG and TGA files, depending on the       *
 *            colour depth.                                                 *
 *                                                                          *
 * Copyright (c) 1999 ATI Technologies Inc.  All rights reserved.           *
 ****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <i86.h>
#include "regdef.h"
#include "defines.h"
#include "main.h"
#include "viewtga.h"

/******************************************************************************
 * Load_Image (BYTE trajectory, DWORD bpp, WORD x, WORD y)                    *
 *  Function: loads an image into display memory                              *
 *    Inputs: BYTE trajectory - rectangular (0) or linear (1)                 *
 *            DWORD bpp - bpp of the image                                    *
 *            WORD x - X location in display memory where file will be loaded *
 *            WORD y - Y location in display memory where file will be loaded *
 *   Outputs: _img_info - structure containing information about the loaded   *
 *                        file.  See MAIN.H for the definition.               *
 ******************************************************************************/
_img_info Load_Image (BYTE trajectory, DWORD bpp, WORD x, WORD y)
{
    BYTE filename[255];
    BYTE buffer[255];
    BYTE test;
    img_handle *ImgPtr;
    int retval, size, bytepp;
    TARGA_HEADER tgaheader;
    _img_info IMG_INFO;
    FILE *fp;
    DWORD offset;

    // determine which image we will be loading, depending on pixel depth
    switch (bpp)
    {
        case DST_8BPP_RGB332:
        case DST_8BPP:  strcpy (filename, "..\\..\\image\\test8.tga");
                        break;
        case DST_15BPP: strcpy (filename, "..\\..\\image\\test15.img");
                        break;
        case DST_16BPP: strcpy (filename, "..\\..\\image\\test16.img");
                        break;
        case DST_24BPP: strcpy (filename, "..\\..\\image\\test24.tga");
                        break;
#if 0   // replaced with trepnk32.tga to show transparent blits.
        case DST_32BPP: strcpy (filename, "..\\..\\image\\test32.img");
#endif
        case DST_32BPP: strcpy (filename, "..\\..\\image\\trepnk32.tga");
                        break;
        case DST_16BPP_VYUY422: strcpy (filename, "..\\..\\image\\testvyuy.img");
                                break;
        case DST_16BPP_YVYU422: strcpy (filename, "..\\..\\image\\testyvyu.img");
                                break;
    }

    if ((bpp == DST_8BPP) || (bpp == DST_8BPP_RGB332) || (bpp == DST_24BPP)
        || (bpp == DST_32BPP))
    {
        test = get_targa_header (filename, &tgaheader);
        if (test != SUCCESS)
        {
            R128_ShutDown ();
            printf ("\nUnable to read image header.");
            printf ("\nProgram terminated.");
            exit (1);
        }

        IMG_INFO.width = tgaheader.width;
        IMG_INFO.height = tgaheader.height;

        if (R128_AdapterInfo.bpp == 8)
        {
            test = set_targa_palette (filename);
        }

        // Load the image into frame buffer memory, as per x and y
        test = load_targa (filename, x, y);

        if (test != SUCCESS)
        {
            R128_ShutDown ();
            printf ("\nUnable to load image.");
            printf ("\nProgram terminated.");
            exit (1);
        }
    }
    else
    {
        ImgPtr = get_img_header (filename);
        if (ImgPtr == NULL)
        {
            R128_ShutDown ();
            printf ("\nUnable to read image header.");
            printf ("\nProgram terminated.");
            exit (1);
        }

        IMG_INFO.width = ImgPtr->image->width;
        IMG_INFO.height = ImgPtr->image->height;

        // Load the image into frame buffer memory, as per x, y
        if (trajectory == 0)
        {
            retval = load_img (ImgPtr, x, y);
        }
        else
        {
            // Load the image into memory linearly.
            // open image file
            fp = fopen (filename, "rb");

            bytepp = R128_GetBPPFromValue (bpp);
            bytepp = (bytepp +1)/8;
            size = IMG_INFO.width * IMG_INFO.height * bytepp;
            // read header from file.
            fread (buffer, sizeof (img_header), 1, fp);
            // read the rest of the data to the offscreen memory location.
            offset = R128_AdapterInfo.xres * y * R128_AdapterInfo.bytepp + (x * R128_AdapterInfo.bytepp);
            fread ((char *)(offset + R128_AdapterInfo.virtual_MEM_BASE), size, 1, fp);
            fclose (fp);
        }

        if (retval == NULL)
        {
            R128_ShutDown ();
            printf ("\nUnable to load image.");
            printf ("\nProgram terminated.");
            exit (1);
        }

        free (ImgPtr);
    } // if/else

    IMG_INFO.bpp = bpp;
    IMG_INFO.bytepp = R128_GetBPPFromValue (bpp);
    IMG_INFO.bytepp = (IMG_INFO.bytepp + 1)/8;

    return (IMG_INFO);

} // Load_Image ()

/****************************************************************************
 * R128_LoadImageIntoSystemMemory (_img_info IMG_DATA)                      *
 *  Function: loads a test image into system memory.                        *
 *    Inputs: _img_info IMG_DATA - structure with information about the     *
 *            file that will be loaded into system memory.                  *
 *   Outputs: NONE.                                                         *
 ****************************************************************************/
void R128_LoadImageIntoSystemMemory (_img_info IMG_DATA)
{
    BYTE buffer[255];
    FILE *fp;
    DWORD bpp;

    bpp = R128_GetBPPValue (IMG_DATA.bpp);

    if ((bpp == DST_8BPP) || (bpp == DST_8BPP_RGB332) || (bpp == DST_24BPP))
    // For Targa Files
    {
        // Read in header.
        fp = fopen (IMG_DATA.name, "rb");

        // Read in header info.
        fread (buffer, sizeof (TARGA_HEADER), 1, fp);

        // Skip over colour table if 8 bpp image type.
        if (bpp != DST_24BPP)
        {
            fseek (fp, (DWORD) (768), SEEK_CUR);
        } // if

        // Read in data to "location".
        fread (IMG_DATA.location, 1, IMG_DATA.size, fp);
    }
    else
    // For IMG files
    {
        // Load the image into memory linearly.
        // open image file
        fp = fopen (IMG_DATA.name, "rb");

        // read header from file.
        fread (buffer, sizeof (img_header), 1, fp);

        // read the rest of the data to the offscreen memory location.
        fread (IMG_DATA.location, IMG_DATA.size, 1, fp);
    } // if/else

    fclose (fp);
    return;

} // R128_LoadImageIntoSystemMemory ()...

/****************************************************************************
 * R128_GetImageFileHeaderInfo (DWORD bpp)                                  *
 *  Function: retrieves image info.                                         *
 *    Inputs: DWORD bpp - bpp of image                                      *
 *   Outputs: _img_data - structure with image information or               *
 *            NULL if the image could not be loaded.                        *
 ****************************************************************************/
_img_info R128_GetImageFileHeaderInfo (DWORD bpp)
{
    char filename [256];
    _img_info IMG_DATA;
    img_handle *ImgPtr;
    TARGA_HEADER header;
    FILE *fp;

    // determine which image we will be loading, depending on pixel depth
    switch (bpp)
    {
        case DST_8BPP_RGB332:
        case DST_8BPP:  strcpy (filename, "..\\..\\image\\test8.tga");
                        break;
        case DST_15BPP: strcpy (filename, "..\\..\\image\\test15.img");
                        break;
        case DST_16BPP: strcpy (filename, "..\\..\\image\\test16.img");
                        break;
        case DST_24BPP: strcpy (filename, "..\\..\\image\\test24.tga");
                        break;
        case DST_32BPP: strcpy (filename, "..\\..\\image\\test32.img");
                        break;
        case DST_16BPP_VYUY422: strcpy (filename, "..\\..\\image\\testvyuy.img");
                                break;
        case DST_16BPP_YVYU422: strcpy (filename, "..\\..\\image\\testyvyu.img");
                                break;
    }

    if ((bpp == DST_8BPP) || (bpp == DST_8BPP_RGB332) || (bpp == DST_24BPP))
    {
        fp = fopen (filename, "rb");
        if (fp == NULL)
        {
            IMG_DATA.width = NULL;
            return (IMG_DATA);
        } // if

        // Read in the header info, copy appropriate values to IMG_DATA.
        fread (&header, sizeof (TARGA_HEADER), 1, fp);
        IMG_DATA.width = header.width;
        IMG_DATA.height = header.height;
        IMG_DATA.bytepp = (header.pixel_depth+1)/ 8;
    }
    else
    {
        ImgPtr = get_img_header (filename);
        if (ImgPtr == NULL)
        {
            // Could not get image header, return NULL
            IMG_DATA.width = NULL;
            return (IMG_DATA);
        }

        IMG_DATA.width = ImgPtr->image->width;
        IMG_DATA.height = ImgPtr->image->height;
        IMG_DATA.bytepp = ImgPtr->image->bytes_per_pixel;

        free (ImgPtr);
    }

    IMG_DATA.bpp = R128_GetBPPFromValue (bpp);
    strcpy (IMG_DATA.name, filename);
    //IMG_DATA.name = filename;
    IMG_DATA.size = IMG_DATA.width * IMG_DATA.height * IMG_DATA.bytepp;

    fclose (fp);
    return (IMG_DATA);

} // R128_GetImageFileHeaderInfo ()...

