#include "PictureReader.h"


PictureReader::PictureReader() : picPtr(NULL)
{
}

PictureReader::PictureReader(char* path) : Reader(path), picPtr(NULL)
{
}

PictureReader::~PictureReader()
{
}


bool PictureReader::setBitsPerPixel(char depth)
{
	char	*newptr;
	short	C16;
	long	*tmp;


	if(!processed)
		return false;

	if(depth == bitsPerPixel)
		return true;

	switch(bitsPerPixel)
	{
	case 16:
		if(depth == 24)								// Expand from 16 to 24 bits per pixel
		{
			newptr = new char [width*height*3];		// Gör en ny STÖRRE buffer

			for(long offset = 0; offset<width*height; offset++)
			{
				*(newptr+offset*3) = (*(short*)(picPtr+offset*2) & 0x001F) << 3;			// R
				*(newptr+offset*3+1) = (*(short*)(picPtr+offset*2) & 0x07F0) >> 3;		// G
				*(newptr+offset*3+2) = (*(short*)(picPtr+offset*2) & 0xF800) >> 8;		// B
			}
			bitsPerPixel = 24;
		}

		if(depth == 32)								// Expand from 16 to 24 bits per pixel
		{
			newptr = new char [width*height*4];		// Gör en ny STÖRRE buffer

			tmp=(long*)newptr;

			for(long offset = 0; offset<width*height; offset++)
			{
				*(newptr+offset*4) = (*((short*)(picPtr+offset*2)) & 0x001F) << 3;		// R
				*(newptr+offset*4+1) = (*((short*)(picPtr+offset*2)) & 0x07F0) >> 3;		// G
				*(newptr+offset*4+2) = (*((short*)(picPtr+offset*2)) & 0xF800) >> 8;		// B
				*(newptr+offset*4+3) = (char)0xFF;											// A
			}
			bitsPerPixel = 32;
		}
		break;

	case 24:
		if(depth == 16)								// Shrink from 24 to 16 bits per pixel
		{
			newptr = new char [width*height*2];		// Gör en ny MINDRE buffer

			tmp=(long*)newptr;

			for(long offset = 0; offset<width*height; offset++)
			{
				C16  = ((*(picPtr+offset*3)) & 0xF8) >> 3;		// R
				C16 |= ((*(picPtr+offset*3+1)) & 0xFC) << 3;		// G
				C16 |= ((*(picPtr+offset*3+2)) & 0xF8) << 8;		// B
				*(newptr+offset*2) = (char)C16;
				*(newptr+offset*2+1) = (char)(C16 >> 8);
			}

			bitsPerPixel = 16;
		}

		if(depth == 32)								// Expand from 24 to 32 bits per pixel
		{
			newptr = new char [width*height*4];		// Gör en ny STÖRRE buffer

			for(long offset = 0; offset<width*height; offset++)
				memcpy(newptr+offset*4,picPtr+offset*3,3);

			bitsPerPixel = 32;
		}
		break;

	case 32:
		if(depth == 16)								// Shrink from 24 to 16 bits per pixel
		{
			newptr = new char [width*height*2];		// Gör en ny MINDRE buffer

			for(long offset = 0; offset<width*height; offset++)
			{
				C16  = (*(picPtr+offset*4) & 0xF8) >> 3;		// R
				C16 |= (*(picPtr+offset*4+1) & 0xFC) << 3;		// G
				C16 |= (*(picPtr+offset*4+2) & 0xF8) << 8;		// B
				*(newptr+offset*2) = (char)C16;
				*(newptr+offset*2+1) = (char)(C16 >> 8);
			}

			bitsPerPixel = 16;
		}

		if(depth == 24)								// Expand from 24 to 32 bits per pixel
		{
			newptr = new char [width*height*3];		// Gör en ny STÖRRE buffer

			for(long offset = 0; offset<width*height; offset++)
				memcpy(newptr+offset*3,picPtr+offset*4,3);

			bitsPerPixel = 24;
		}
		break;

	default:
		return false;
	}


	if(picPtr)	delete [] picPtr;			// Ta bort den gamla buffern
	picPtr = newptr;						// och byt pekare till den nya

	return true;
}


void* PictureReader::getPic()
{
	if(!processed)
		return NULL;	

	return (void*)picPtr;	
}


bool PictureReader::process()
{
	if(!stricmp(fileExt,".TGA"))
		processTGA();

	return true;
}


void PictureReader::processTGA()
{
	char	*dest;
	long	BytesPP;
	long	BytesPL;

	if(!fileLoaded)
		return;

	SAFE_DELETE(picPtr);							// Ta bort den gamla buffern

	setPtrPos(12);

	width = getWord();
	height = getWord();
	bitsPerPixel = getByte();

	BytesPP = bitsPerPixel/8;
	BytesPL = BytesPP * width;

	picPtr = new char [width * height * BytesPP];

	setPtrPos(18);

	getChunk(picPtr, width*height*BytesPP);

	dest = new char [BytesPL];			// Bildens är upp och ner = VÄND!!!!

	for(long i=0;i<height/2;i++)
	{
		memcpy(dest,picPtr + i*BytesPL, BytesPL);
		memcpy(picPtr + i*BytesPL, picPtr + (height-1-i)*BytesPL, BytesPL);	
		memcpy(picPtr + (height-1-i)*BytesPL, dest, BytesPL);	
	}

	delete [] dest;

	processed = true;
}

