Advertisement

tga loading

Started by September 20, 2003 09:53 AM
11 comments, last by Mithoric 21 years, 5 months ago
Zy or Paul, could you send a copy of that ammended code to me?
michael@mudsplat.com ...

I''m downloading that update for photoshop as well, maybe that''s my problem?
you also have to remember to check the first byte of the file and skip that many bytes after reading the header (PSP8 will set that byte).. The older code which just does a block compare of the header will fail..

here is my TGA loader (I use a custom glTexture struct but you can remove it).. which loads both compressed/uncompressed 24/32 bit TGA files

you may have to modify it if you want to create mipmap textures..

hope it helps..

typedef enum {	txUnknown	= 0,	// images	txBmp		= 1,	txJpg		= 2,	txPng		= 3,	txTga		= 4,	txGif		= 5,	txIco		= 6,	txEmf		= 7,	txWmf		= 8,	// add new ones at the end} eglTexType;typedef	struct{	GLuint		TextureID;									// Texture ID Used To Select A Texture	eglTexType	TexType;									// Texture Format	GLuint		Width;										// Image Width	GLuint		Height;										// Image Height	GLuint		Type;										// Image Type (GL_RGB, GL_RGBA)	GLuint		Bpp;										// Image Color Depth In Bits Per Pixel} glTexture;// TGA Header               typedef struct {                        	unsigned char ImgIdent;                 	unsigned char ignored[ 1 ];                     	unsigned char ImgType;                  	unsigned char ignored2[ 9 ];                    	unsigned char WidthLo;                  	unsigned char WidthHi;                  	unsigned char HeightLo;                 	unsigned char HeightHi;                 	unsigned char Bpp;                      	unsigned char ignored3[ 1 ];            } _TGAHeader;



and the code...


// Load a TGA file//int LoadTGAFromDisk(char *pszFileName, glTexture *pglTexture){	FILE		*fTGA;													// File pointer to texture file	_TGAHeader	header;	GLubyte		*pImgData;	fTGA = fopen(pszFileName, "rb");									// Open file for reading	if(fTGA == NULL)													// If it didn't open....	{		return FALSE;													// Exit function	}	if(fread(&header, sizeof(_TGAHeader), 1, fTGA) == 0)				// Attempt to read 12 byte header from file	{		if(fTGA != NULL)												// Check to seeiffile is still open		{			fclose(fTGA);												// If it is, close it		}		return FALSE;													// Exit function	}	// Precalc some values from the header          	const unsigned int imageType		= header.ImgType;         	const unsigned int imageWidth		= header.WidthLo  + header.WidthHi  * 256;                	const unsigned int imageHeight		= header.HeightLo + header.HeightHi * 256;                	const unsigned int imageBytesPerPel	= header.Bpp / 8;            	const unsigned int imageSize		= imageWidth * imageHeight * imageBytesPerPel;            	// load up our texture information	pglTexture->Width  = imageWidth;	pglTexture->Height = imageHeight;	pglTexture->Bpp	   = header.Bpp;	if(pglTexture->Bpp == 24)											// If the BPP of the image is 24...	{		pglTexture->Type = GL_RGB;										// Set Image type to GL_RGB	}	else																// Else if its 32 BPP	{		pglTexture->Type = GL_RGBA;										// Set image type to GL_RGBA	}	// Validate header info         	if( ( imageType != 2 && imageType != 10 ) || 	    ( imageWidth == 0 ) || ( imageHeight == 0 ) || 		( imageBytesPerPel != 3 && imageBytesPerPel != 4 ) ) 	{		// invalid header, bomb out		fclose( fTGA );		return (FALSE);	}	// Allocate the memory for the image size	pImgData = (GLubyte *)malloc(imageSize);						if(pImgData == NULL)												// If no space was allocated	{		fclose(fTGA);													// Close the file		return FALSE;													// Return failed	}	// Skip image ident field               	if( header.ImgIdent > 0 )                       	{		fseek(fTGA, header.ImgIdent, SEEK_CUR);	}	// un-compresses image ?	if (imageType == 2)	{		if(fread(pImgData, 1, imageSize, fTGA) != imageSize)				// Attempt to read image data		{			if(pImgData != NULL)											// If imagedata has data in it			{				free(pImgData);												// Delete data from memory			}			fclose(fTGA);													// Close file			return FALSE;													// Return failed		}		// Byte Swapping Optimized By Steve Thomas		for(GLuint cswap = 0; cswap < imageSize; cswap += imageBytesPerPel)		{			pImgData[cswap] ^= pImgData[cswap+2] ^=			pImgData[cswap] ^= pImgData[cswap+2];		}	}	else	{		// compressed image		GLuint pixelcount	= imageHeight * imageWidth;						// Nuber of pixels in the image		GLuint currentpixel	= 0;											// Current pixel being read		GLuint currentbyte	= 0;											// Current byte 		GLubyte * colorbuffer = (GLubyte *)malloc(imageBytesPerPel);		// Storage for 1 pixel		do		{			GLubyte chunkheader = 0;										// Storage for "chunk" header				if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0)			// Read in the 1 byte header			{				if(fTGA != NULL)											// If file is open				{					fclose(fTGA);											// Close file				}				if(pImgData != NULL)										// If there is stored image data				{					free(pImgData);											// Delete image data				}				return FALSE;												// Return failed			}				if(chunkheader < 128)											// If the ehader is < 128, it means the that is the number of RAW color packets minus 1			{																// that follow the header				chunkheader++;												// add 1 to get number of following color values				for(short counter = 0; counter < chunkheader; counter++)	// Read RAW color values				{					if(fread(colorbuffer, 1, imageBytesPerPel, fTGA) != imageBytesPerPel) // Try to read 1 pixel					{						if(fTGA != NULL)									// See if file is open						{							fclose(fTGA);									// If so, close file						}							if(colorbuffer != NULL)								// See if colorbuffer has data in it						{							free(colorbuffer);								// If so, delete it						}							if(pImgData != NULL)								// See if there is stored Image data						{							free(pImgData);									// If so, delete it too						}							return FALSE;										// Return failed					}																			// write to memory					pImgData[currentbyte		] = colorbuffer[2];			// Flip R and B vcolor values around in the process 					pImgData[currentbyte + 1	] = colorbuffer[1];					pImgData[currentbyte + 2	] = colorbuffer[0];					if (imageBytesPerPel == 4)								// if its a 32 bpp image					{						pImgData[currentbyte + 3] = colorbuffer[3];			// copy the 4th byte					}						currentbyte += imageBytesPerPel;						// Increase thecurrent byte by the number of bytes per pixel					currentpixel++;											// Increase current pixel by 1						if(currentpixel > pixelcount)							// Make sure we havent read too many pixels					{						if(fTGA != NULL)									// If there is a file open						{							fclose(fTGA);									// Close file						}							if(colorbuffer != NULL)								// If there is data in colorbuffer						{							free(colorbuffer);								// Delete it						}						if(pImgData != NULL)								// If there is Image data						{							free(pImgData);									// delete it						}						return FALSE;										// Return failed					}				}			}			else															// chunkheader > 128 RLE data, next color reapeated chunkheader - 127 times			{				chunkheader -= 127;											// Subtract 127 to get rid of the ID bit				if(fread(colorbuffer, 1, imageBytesPerPel, fTGA) != imageBytesPerPel)	// Attempt to read following color values				{						if(fTGA != NULL)										// If thereis a file open					{						fclose(fTGA);										// Close it					}					if(colorbuffer != NULL)									// If there is data in the colorbuffer					{						free(colorbuffer);									// delete it					}					if(pImgData != NULL)									// If there is image data					{						free(pImgData);										// delete it					}					return FALSE;											// return failed				}				for(short counter = 0; counter < chunkheader; counter++)	// copy the color into the image data as many times as dictated 				{															// by the header					pImgData[currentbyte		] = colorbuffer[2];			// switch R and B bytes areound while copying					pImgData[currentbyte + 1	] = colorbuffer[1];					pImgData[currentbyte   + 2	] = colorbuffer[0];					if(imageBytesPerPel == 4)								// If TGA images is 32 bpp					{						pImgData[currentbyte + 3] = colorbuffer[3];			// Copy 4th byte					}					currentbyte += imageBytesPerPel;						// Increase current byte by the number of bytes per pixel					currentpixel++;											// Increase pixel count by 1					if(currentpixel > pixelcount)							// Make sure we havent written too many pixels					{						if(fTGA != NULL)									// If there is a file open						{							fclose(fTGA);									// Close file						}							if(colorbuffer != NULL)								// If there is data in colorbuffer						{							free(colorbuffer);								// Delete it						}						if(pImgData != NULL)								// If there is Image data						{							free(pImgData);									// delete it						}						return FALSE;										// Return failed					}				} // for(counter)			} // if(chunkheader)		}		while(currentpixel < pixelcount);									// Loop while there are still pixels left	} // if (imageType == 2)	fclose (fTGA);													// Close the TGA file	// Typical Texture Generation Using Data From The TGA loader	glGenTextures(1, &pglTexture->TextureID);						// Create The Texture 	glBindTexture(GL_TEXTURE_2D, pglTexture->TextureID);	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);	glTexImage2D(GL_TEXTURE_2D, 				 0, 				 pglTexture->Type, 				 pglTexture->Width, 				 pglTexture->Height, 				 0, 				 pglTexture->Type, 				 GL_UNSIGNED_BYTE, 				 pImgData);	// free the memory allocated	free(pImgData);	return TRUE;														// All went well, continue on}



Jumpman - Under Construction


[edited by - Jumpman on September 21, 2003 2:53:06 AM]
Advertisement
quote:
Original post by Mithoric
Zy or Paul, could you send a copy of that ammended code to me?
michael@mudsplat.com ...

I''m downloading that update for photoshop as well, maybe that''s my problem?


I''ve emailed you a copy of the code.

This topic is closed to new replies.

Advertisement