TGA loading error, psp9?

Started by
7 comments, last by cozzie 18 years, 7 months ago
Hi all. After a few months I decided to start working on my 3d engine again. No I've noticed something strange I load a tga texturefile in my engine, result = fine. When I open that specific TGA-file in Paint Shop Pro 9 and save it again as compressed or uncompressed TGA file in 24 or 32bit (all options tried), my TGA-loader in my engine gives an error and doesn't load the texture. It seems that Paint Shop Pro 9 does something to my TGA file, but I cant find out why. I've uploaded the working TGA file and the non-working TGA file: http://www.sierracosworth.nl/coding/good.tga and http://www.sierracosworth.nl/coding/bad.tga My sourcecode was always able to read both compressed and uncompressed and both 24 or 32bit TGA files. All help is wellcome.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement
Loads fine with my routine :)

Both images are flagged the same, 24bit, not upside down, no palette, not compressed.

A difference is in the header, the TGA saved from PSP9 (crap anyway since 8) has got a ID field length of 1 as opposed to the original image, which doesn't have that field (length 0).

After reading the 18 byte header simply advance the file pointer by the length of the id field.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Do you mind if I post the source of my TGA/Tex-loader?

That way maybe you can see what I can do to make my loader ignore the "stupid" PSP9 header

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Be my guest ;)
Actually just the code for the header is needed, no need for the image loading part itself, as that seems to work.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Are you by any chance using the NeHe TGA loader? If so, don't! It's horrific, and isn't standards compiant from what I remember.
If at first you don't succeed, redefine success.
Here it is:
(probably to much, but ok :))

bool GLtexture::LoadTGA(char *filename, int which){	GLubyte		TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};	GLubyte		TGAcompare[12];								GLubyte		header[6];								GLuint		bytesPerPixel;							GLuint		imageSize;								GLuint		temp;									GLuint		type;	FILE *file = fopen(filename, "rb");		if(file == NULL ||								   fread(TGAcompare, 1, sizeof(TGAcompare),file) != sizeof(TGAcompare)	||			   memcmp(TGAheader, TGAcompare, sizeof(TGAheader)) !=0					||				   fread(header, 1, sizeof(header), file) != sizeof(header))			{				if(file == NULL) return false;						else		{			fclose(file);							return false;						}	}	width  = header[1] * 256 + header[0];	height = header[3] * 256 + header[2];     	if(texture  <=0	|| texture <=0	|| (header[4]!=24 && header[4]!=32))	{		fclose(file);		return false;	}	bpp = header[4];	if(bpp == 24)	{		type=GL_RGB;	}	if(bpp == 32)	{		type=GL_RGBA;	}	bytesPerPixel = bpp/8;	imageSize = width*height*bytesPerPixel;				imageData = (GLubyte *)malloc(imageSize);	if(imageData==NULL ||							   fread(imageData, 1, imageSize, file) != imageSize)	{				if(imageData != NULL) free(imageData);				fclose(file);		return false;	} 	for(GLuint i=0;i<int(imageSize);i+=bytesPerPixel)	{												temp=imageData;								imageData = imageData;			<br>		imageData = temp;	<br>	}	<br>	fclose (file);										<br><br>	glGenTextures(<span class="cpp-number">1</span>, &amp;texture[which]);	<br>	glBindTexture(GL_TEXTURE_2D, texture[which]);		<br><br>	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);<br>	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);<br>	gluBuild2DMipmaps(GL_TEXTURE_2D, <span class="cpp-number">4</span>, width, height, type,<br>	  				  GL_UNSIGNED_BYTE, imageData);<br><br>	<span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>;									<br>}<br><br><br><br></pre></div><!–ENDSCRIPT–> 

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Looks strikingly like the NeHe loader. Don't use it. Seriously, just grab the format and do it yourself, not only will you gain a decent TGA loader, but it'll also teach you a lot. The problem with the NeHe loader is primarily how it loads the header, it just disregards most of the information. Yours isn't exactly the same looking at it, however, it will only load one type of TGA, and won't support the newer TGA format - If memory serves.
If at first you don't succeed, redefine success.
Your "loader" doesn't really check much of the header, and if there's a different format or bit set it bails out (with the memcmp test).

In this case the PSP9 modified TGA header has the value of 1 in the first byte of the TGAHeader struct. The method of using memcmp to test for the header bits is just completely wrong from a loader design view.

For a quick hack solution change the memcmp line to:

memcmp(&TGAheader[1], &TGAcompare[1], sizeof(TGAheader) - 1 ) !=0

BUT I SERIOUSLY ADVISE AGAINST THAT SOLUTION. It's fugly(TM).


Seriously, get rid of the memcmp and look up the file format at Wotsit. It's pretty easy actually.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Tried the solution and it does work sometimes.
But since I'm trying to build a nice reliable engine, I'll read myself into the TGA fileformat and make a new load function.

Thanks for the help

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement