/*-----------------------------------------------------------------
LOG
    GEM - Graphics Environment for Multimedia

    GemPixUtil.h
       - contains image functions for pix objects
       - part of GEM

    Copyright (c) 1997-1998 Mark Danks.
    For information on usage and redistribution, and for a DISCLAIMER OF ALL
    WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.

-----------------------------------------------------------------*/

#ifndef INCLUDE_GEMPIXUTIL_H_
#define INCLUDE_GEMPIXUTIL_H_

// I hate Microsoft...I shouldn't have to do this!
#ifdef _WINDOWS
#include <windows.h>
#endif

#include <GL/gl.h>

/*-----------------------------------------------------------------
-------------------------------------------------------------------
CLASS
    imageStruct
    
    The basic image structure

-----------------------------------------------------------------*/
struct imageStruct
{
    //////////
    // columns
    GLint           xsize;

    //////////
    // rows
    GLint   	    ysize;

    //////////
    // color (LUMINANCE = 1, RGBA = 4)
    GLint   	    csize;

    //////////
    // the format - either GL_RGBA or GL_LUMINANCE
    GLenum          format;

    //////////
     // data type - always UNSIGNED_BYTE
    GLenum          type;

    //////////
    // the actual image data
    unsigned char   *data;
};

/*-----------------------------------------------------------------
-------------------------------------------------------------------
CLASS
    pixBlock
    
    The pix block structure

-----------------------------------------------------------------*/
struct pixBlock
{
    //////////
    // the block's image
    imageStruct     image;

    //////////
    // is this a newimage since last time?
    //	ie, has it been refreshed
    int     	    newimage;
};

//////////
// These should be used to reference the various color channels
const int chRed		= 0;
const int chGreen	= 1;
const int chBlue	= 2;
const int chAlpha	= 3;

const int chGray	= 0;


//////////
// Clamp a value high
inline unsigned char CLAMP_HIGH(int x)
	{ return((unsigned char )((x > 255) ? 255 : x)); }

//////////
// Clamp a value low
inline unsigned char CLAMP_LOW(int x)
	{ return((unsigned char )((x < 0) ? 0 : x)); }

//////////
// Clamp an int to the range of an unsigned char
inline unsigned char CLAMP(int x)
    { return((unsigned char)((x > 255) ? 255 : ( (x < 0) ? 0 : x))); }

//////////
// Clamp a float to the range of an unsigned char
inline unsigned char CLAMP(float x)
    { return((unsigned char)((x > 255.f) ? 255.f : ( (x < 0.f) ? 0.f : x))); }

//////////
// Clamp a float to 0. <= x <= 1.0
inline float FLOAT_CLAMP(float x)
    { return((x > 1.f) ? 1.f : ( (x < 0.f) ? 0.f : x)); }


//////////
// Exactly multiply two unsigned chars
// This avoids a float value (important on Intel...)
// From Alvy Ray Smith paper
inline unsigned char INT_MULT(unsigned int a, unsigned int b)
	{ int t = (unsigned int)a * (unsigned int)b + 0x80; return(((t >> 8) + t) >> 8); }

//////////
// Exactly LERPs two values
// This avoids a float value (important on Intel...)
// From Alvy Ray Smith paper
inline unsigned char INT_LERP(unsigned int p, unsigned int q, unsigned int a)
	{ return(p + INT_MULT(a, q - p)); }

//////////
// Floating point LERP
inline float FLOAT_LERP(float p, float q, float a)
	{ return( a * (q - p) + p); }

//////////
// gets a pixel
inline unsigned char GetPixel(imageStruct *IMG, int Y, int X, int C)
    { return(IMG->data[Y * IMG->xsize * IMG->csize + X * IMG->csize + C]); }

//////////
// sets a pixel
inline void SetPixel(imageStruct *IMG, int Y, int X, int C, unsigned char VAL)
    { IMG->data[Y * IMG->xsize * IMG->csize + X * IMG->csize + C] = VAL; }

//////////
// copies all of the data over and mallocs memory
extern void copy2Image(imageStruct *to, imageStruct *from);

//////////
// assumes that it only has to refresh the data
extern void refreshImage(imageStruct *to, imageStruct *from);

#endif
