Archived

This topic is now archived and is closed to further replies.

Viscous-Flow

TGA Problems

Recommended Posts

Hello, I have searched all over the forums on Gamedev.net (using the nifty search function ). I have yet to find a resolve to my problem. Well here goes. I got the uncompressed TGA to load ggrrreeeaaaatttt! It's the compressed that's making me mad. When I run the program with a compressed image I get a Degug Error that says DAMAGE: after Normal block (#18) at 0x006F5294. When I debug the application the error code the compiler finds is in DbgHeap.c
        
/* forced failure */
if (!(*_pfnAllocHook)(_HOOK_FREE, pUserData, 0, nBlockUse, 0L, NULL, 0))
{
    _RPT0(_CRT_WARN, "Client hook free failure.\n");

    return;
}
  
Here is my code for the compressed TGA. It's essentially based on NeHe's code and this websites code.
     
//  Gets the tga image data if it is compressed

int GLImage::tgaGetCompressedData()
{
	//  Allocate memory for the image data

	tgaImageData = (unsigned char*)malloc(tgaImageSize);

	//  Check to make sure the allocation of memory was a success

	if(tgaImageData == NULL)
		return 0;

	int	currentPixel	= 0;	//  Current pixel that is being read from data

	int currentByte		= 0;	//  Current byte we are writing into image data


	//  Storage space for one pixel

	unsigned char *	colorBuffer = (unsigned char *)malloc(tgaImageBytes);

	//  Begin the uncompression loop

	do
	{
		int chunkHeader = 0;	//  Variables to store the value of te ID chunk


		//  Attemp to read the chunk's header

		if(fread(&chunkHeader, sizeof(int), 1, file) == NULL)
		{
			if(tgaImageData != NULL)
				free(tgaImageData);
			if(colorBuffer != NULL)
				free(colorBuffer);
			return 0;
		}
		
		if(chunkHeader < 128)	//  If the chunk is a 'RAW' chunk

		{
			chunkHeader++;	//  Add on to the value to get the total number of RAW pixels

			
			//  Start RAW pixel reading loop

			for(short i = 0; i < chunkHeader; i++)
			{
				//  Try to read one pixel and if it fails return false

				if(fread(colorBuffer, 1, tgaImageBytes, file) != (size_t)tgaImageBytes)
				{
					if(tgaImageData != NULL)
						free(tgaImageData);

					if(colorBuffer != NULL)
						free (colorBuffer);
					return 0;
				}

				tgaImageData[currentByte]		= colorBuffer[2];	//  Write the 'R' byte

				tgaImageData[currentByte + 1]	= colorBuffer[1];	//  Write the 'G' byte

				tgaImageData[currentByte + 2]	= colorBuffer[0];	//  Write the 'B' byte


				//  If the image is 32bpp

				if(tgaImageBytes == 4)
					tgaImageData[currentByte + 3] = colorBuffer[3];	//  Write the 'A' byte


				currentByte += tgaImageBytes;	//  Increment the byte counter

				currentPixel++;					//  Increment the pixel counter


				//  If the program read to many pixels

				if(currentPixel > tgaImagePixels)
				{
					if(tgaImageData != NULL)
						free(tgaImageData);

					if(colorBuffer != NULL)
						free (colorBuffer);
					return 0;
				}
			}
		}
		//  If it's an RLE header

		else
		{
			chunkHeader -= 127;	//  Subtract 127 to get rid of the ID bit


			//  Read the next pixel and check if an error occurred

			if(fread(colorBuffer, 1, tgaImageBytes, file) != (size_t)tgaImageBytes)
			{
				if(tgaImageData != NULL)
					free(tgaImageData);

				if(colorBuffer != NULL)
					free (colorBuffer);
				return 0;
			}

			//  Start the RLE pixel reading loop

			for(short j = 0; j < chunkHeader; j++)
			{
				tgaImageData[currentByte]		= colorBuffer[2];	//  Write the 'R' byte

				tgaImageData[currentByte + 1]	= colorBuffer[1];	//  Write the 'G' byte

				tgaImageData[currentByte + 2]	= colorBuffer[0];	//  Write the 'B' byte


				//  If the image is 32bpp

				if(tgaImageBytes == 4)
					tgaImageData[currentByte + 3] = colorBuffer[3];	//  Write the 'A' byte

				
				currentByte += tgaImageBytes;	//  Increment the byte counter

				currentPixel++;					//  Increment the pixel counter


				//  If the program read to many pixels

				if(currentPixel > tgaImagePixels)
				{
					if(tgaImageData != NULL)
						free(tgaImageData);

					if(colorBuffer != NULL)
						free (colorBuffer);
					return 0;
				}
			}
		}

	} while(currentPixel < tgaImagePixels);

	//  Release the colorBuffer memory

	free(colorBuffer);

	return 1;
}
  
If it is of any use I generate the RLE compression using the GIMP image editing program. ThAnKs in AdVaNcE! Edited by - Viscous-Flow on October 22, 2001 12:23:19 AM

Share this post


Link to post
Share on other sites
No response in one and and half days . I guess you all are busy writing your own games, debugging code at work, or doing whatever you do (I understand) . Just a simple reply of there''s nothing I can see wrong with the code would suffice since if that happens I''ll just trash my RLE loading code and start from scratch .

Anyways the people on GameDev.net (and people in general) have always helped me out and I appreciate it, and I think people appreciate it when I help them. So, I would just like it if someone gave me a helping hand.

Thanks in advance !!!!

Share this post


Link to post
Share on other sites
I dont know if this will help ya but here is the code I use to uncompress tga''s:

  

BOOL bNewTGAFormat = FALSE;
if (strcmp(tgafoot.cSignature, "TRUEVISION-XFILE.") == 0)
bNewTGAFormat = TRUE;

fileHeader.byImageType = 2;

int Srcbytes=fileHeader.nImageWidth;
Srcbytes*=3;
Srcbytes=((Srcbytes+3)&~3);

int Offset=4-(fileHeader.nImageWidth%4);
if (Offset==4)
Offset=0;

int iWidthBytes=(fileHeader.nImageWidth+Offset)*3;

int size=( iWidthBytes*fileHeader.nImageHeight)
+sizeof(TGA_FILE_HEADER);

DWORD dwFileLength = size;
char* UncompressedTga=new char[size/*+sizeof(TGA_FILE_HEADER)*/];
ZeroMemory(UncompressedTga,size/*+sizeof(TGA_FILE_HEADER)*/
);
char* UncompressedTgaPtr=UncompressedTga;
char* charP = new char[size];
ZeroMemory(charP,size);
int width = fileHeader.nImageWidth;
int depth = fileHeader.nImageHeight;
int pitch = width*(fileHeader.byPixelDepth/8);
int pwidth = fileHeader.byPixelDepth/8;

memcpy(UncompressedTgaPtr,(LPSTR)&fileHeader,sizeof(fileHeader));
UncompressedTgaPtr+=sizeof(fileHeader);

for ( int y = 0; y < depth; y++ )
{
for ( int x = 0; x < width; )
{
int ctl;

unsigned char ret = 0;
file.Read((char*)&ret,1);
int reti = (int)ret;
ctl = reti&0xff;


if ( ctl >= 0x80 )
{ // next pixel repeated {ctl} times


ctl = ( ctl & 0x7f ) + 1;

unsigned char buff[ 8 ];

file.Read( (char*)buff, pwidth );

while ( ctl-- )
{
memcpy( charP + x * pwidth, buff, pwidth );
x++;
}
}

else
{ // next {ctl} pixels uncompressed


ctl = ctl + 1;

file.Read( (char*) charP + x * pwidth, ctl * pwidth );

x += ctl;
}
}

memcpy(UncompressedTgaPtr,charP,pitch);

UncompressedTgaPtr+=pitch;

charP += pitch;
}
charP-=((pitch*depth));
delete[]charP;

file.Close();

if (fileHeader.byColorMapType != 0)
{
TRACE(_T("Color map type is non zero in the TGA file header for this uncompressed true-color tga file, instead it is %d\n"), fileHeader.byColorMapType);
return NULL;
}

//Determine the end offset of the "Image Data"

DWORD dwEndImageData = 0;
if (bNewTGAFormat)
dwEndImageData = tgafoot.lExtensionAreaOffset - 1;
else
dwEndImageData = dwFileLength;

//Determine the start offset of the "Image Data" and the pointer to

//the color map

DWORD dwStartImageData = sizeof(TGA_FILE_HEADER) + fileHeader.byIdLength;

//Read in the image data

DWORD dwImageSize = (size-sizeof(TGA_FILE_HEADER));
////////////////////

if (tgafoot.lExtensionAreaOffset==0)
dwImageSize=dwFileLength;

BYTE* pImageData = new BYTE[dwImageSize];
ZeroMemory(pImageData,dwImageSize);

UncompressedTgaPtr=UncompressedTga;
UncompressedTgaPtr+=sizeof(TGA_FILE_HEADER);



I then go on to convert to a bitmap. Hope it helps.

Share this post


Link to post
Share on other sites