Archived

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

TGA Problems

This topic is 5895 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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