Archived

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

OleKaiwalker

TGA Loading pt. 2

Recommended Posts

Hey, My TGA Loading class is nearly finished, but I have some problems, when trying to load a RLE Compressed image... The problems is when I try to determin the width and height of the image in RLE (it works alright, when the image is uncompressed). This is my not optimized code, so have patience in me Can you help me? Here is my code -> class CTextureTGA { public: bool LoadTGA(char* strFileName, GLuint textureArray[], GLint textureID); private: GLubyte *iData; GLint iType; GLint iDepth; GLint iChannels; GLint iWidth; GLint iHeight; bool LoadUncompressedTGA(FILE *fileTGA); bool LoadCompressedTGA(FILE *fileTGA); }; bool CTextureTGA::LoadTGA(char* strFileName, GLuint textureArray[], GLint textureID){ GLbyte TGAHeader[3] = {0}; FILE *fileTGA; if (!(fileTGA = fopen(strFileName, "rb"))) return false; if (!(fread(TGAHeader, sizeof(TGAHeader), 1, fileTGA))) return false; if (TGAHeader[2] == 2){ if (!LoadUncompressedTGA(fileTGA)) return false; } else if (TGAHeader[2] == 10){ if (!LoadCompressedTGA(fileTGA)) return false; } else return false; glGenTextures(1, &textureArray[textureID]); glBindTexture(GL_TEXTURE_2D, textureArray[textureID]); gluBuild2DMipmaps( GL_TEXTURE_2D, iChannels, iWidth, iHeight, iType, GL_UNSIGNED_BYTE, iData); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); iType = iDepth = iChannels = iWidth = iHeight = NULL; if (iData) free(iData); return true; } bool CTextureTGA::LoadUncompressedTGA(FILE *fileTGA){ GLbyte TGAHeader[6] = {0}; fseek(fileTGA, 12, SEEK_SET); if(!(fread(TGAHeader, sizeof(TGAHeader), 1, fileTGA))) return false; iWidth = TGAHeader[1] * 256 + TGAHeader[0]; iHeight = TGAHeader[3] * 256 + TGAHeader[2]; iDepth = TGAHeader[4]; if (iWidth <= 0 || iHeight <= 0 || iDepth <= 0) return false; if (iDepth == 24) iType = GL_RGB; else iType = GL_RGBA; iChannels = (iDepth / 8); GLint iSize = iChannels * iWidth * iHeight; iData = (GLubyte *)malloc(iSize); if (iData == NULL) return false; if (!(fread(iData, 1, iSize, fileTGA))) return false; for (GLint sColor = 0; sColor < (GLint)iSize; sColor += iChannels){ iData[sColor] ^= iData[sColor+2] ^= iData[sColor] ^= iData[sColor+2]; } fclose(fileTGA); return true; } bool CTextureTGA::LoadCompressedTGA(FILE *fileTGA){ GLbyte TGAHeader[6] = {0}; fseek(fileTGA, 12, SEEK_SET); if(!(fread(TGAHeader, sizeof(TGAHeader), 1, fileTGA))) return false; // The problem is here!!! iWidth = TGAHeader[1] * 256 + TGAHeader[0]; iHeight = TGAHeader[3] * 256 + TGAHeader[2]; iDepth = TGAHeader[4]; // Just some added control if (TGAHeader[1] <= 0){ MessageBox(NULL,"JEK","INFO",MB_OK); return false; } if (iDepth == 24) iType = GL_RGB; else iType = GL_RGBA; iChannels = (iDepth / 8); GLint iSize = iChannels * iWidth * iHeight; GLint iStride = iChannels * iWidth; iData = (GLubyte *)malloc(iSize); if (iData == NULL) return false; GLint pixelCount = 0; GLuint cColors = 0; GLubyte rleID = 0; GLubyte *colorBuffer= (GLubyte *)malloc(sizeof(iChannels)); while ((iWidth * iHeight) > pixelCount){ fread(&rleID, sizeof(GLubyte), 1, fileTGA); if (rleID < 128){ rleID++; while (rleID){ fread(colorBuffer, sizeof(GLubyte *) * iChannels, 1, fileTGA); iData[cColors + 0] = colorBuffer[2]; iData[cColors + 1] = colorBuffer[1]; iData[cColors + 2] = colorBuffer[0]; if (iChannels == 4) iData[cColors + 3] = colorBuffer[3]; pixelCount++; rleID--; cColors += iChannels; } } else { rleID -= 127; fread(colorBuffer, sizeof(GLubyte) * iChannels, 1, fileTGA); while (rleID){ iData[cColors + 0] = colorBuffer[2]; iData[cColors + 1] = colorBuffer[1]; iData[cColors + 2] = colorBuffer[2]; if (iChannels == 4) iData[cColors + 3] = colorBuffer[3]; pixelCount++; rleID--; cColors += iChannels; } } } if (colorBuffer) free(colorBuffer); fclose(fileTGA); return true; }

Share this post


Link to post
Share on other sites
It has been a while since I last wrote a TGA loader so if there is anything TGA specific I probably missed it. That being said, why is TGAheader of type GLbyte? shouldn''t it be unsigned?
Are you using the same image for testing? One using RLE and one not using it? Have you checked with a hex editor that the values are ''correct'' (like the image editor using a format other than what you support)?
How do you know what the problem is? An RLE image that is incorrectly loaded usually has channels swapped, totally corrupted image, or is just one big memory big crunch waiting to happen (usually a combination).
Try logging anything meaningful, check what are *your* values for width, height, and compare to the final value of pixelcount, for example.

Share this post


Link to post
Share on other sites
I have managed to solve the problem...

I think you''r right - I put the TGA-Header in a unsigned byte (GLubyte), and instead for finding the width and height in the two diffrent functions, I just calculate them in the LoadTGA function!

Share this post


Link to post
Share on other sites