   TGA files hate me [not any more]
  Hi,I tried writing a TGA loader based on the NeHe tutorial again ...However there are weird errors.I can load the compressed TGA-file from the tutorial with the code.It is just mirrored ... doesn't matter.I can't load a different compressed TGA-file (unhandled win32 exception) ... but NeHe's tutorial code can load it.When I put logfile-entries into the do-while loop it doesn't crash ... It just loops forever ... after filling 6000-something pixels!????I don't see where it could get stuck ... and I don't know of any mayor differences between my code and NeHe's code.Does anybody notice any errors?The entries up to the do-loop look fine:Logfile - BeginBeginLogging Started!ImportingImporting compressed TGASuccessFile loaded into memorySuccessWidth: 256Height: 256SuccessBpp: 3SuccessUncompressed Imagesize: 192kbLogfile - End void Image::import_compressedTGA() {    start_reading();    Uint32 filesize = get_filesize();    Uint8 tgafile[filesize];    read_uint8(tgafile, filesize);    finish_reading();    LOG << "File loaded into memory<br />" << ENDL;    g_pLog->flush("Success");    m_width  = tgafile[13] * 256 + tgafile[12];    m_height = tgafile[15] * 256 + tgafile[14];    m_bitsPP = tgafile[16];    LOG << "Width: " << m_width << "<br />" << ENDL;    LOG << "Height: " << m_height << "<br />" << ENDL;    g_pLog->flush("Success");    m_bytesPP = m_bitsPP / 8;    LOG << "Bpp: " << m_bytesPP << "<br />" << ENDL;    g_pLog->flush("Success");    m_imagesize = m_width*m_height*m_bytesPP;    m_pPixels = new Uint8[m_imagesize];    LOG << "Uncompressed Imagesize: " << m_imagesize/1024 << "kb<br />" << ENDL;    g_pLog->flush("Success");    if (m_bytesPP != 3 and m_bytesPP != 4) {   LOG << "Unexpected number of bytes!<br />" << ENDL;   g_pLog->flush("Error", debug::FlushError);   /* ERROR */    } else {   /* General State */   Uint8  currentColor[m_bytesPP];   Uint32 pixelsFilled =  0;   Uint32 currentPos   = 18;   Uint8  chunkHeader;   do {  chunkHeader = tgafile[currentPos];  currentPos++;  if (chunkHeader < 128) { chunkHeader++; for (int i=0; i<chunkHeader; i++) {memcpy(currentColor,  &tgafile[currentPos],  m_bytesPP);currentPos += m_bytesPP;m_pPixels[pixelsFilled*m_bytesPP]   = currentColor[2];m_pPixels[pixelsFilled*m_bytesPP+1] = currentColor[1];m_pPixels[pixelsFilled*m_bytesPP+2] = currentColor[0];if (4 == m_bytesPP) {    m_pPixels[pixelsFilled*m_bytesPP+3] =   currentColor[3];}pixelsFilled++;if (pixelsFilled > m_width*m_height) {    /* ERROR */} }  } else { chunkHeader -= 127; memcpy(currentColor,   &tgafile[currentPos],   m_bytesPP); currentPos += m_bytesPP; for (int i=0; i<chunkHeader; i++) {m_pPixels[pixelsFilled*m_bytesPP]   = currentColor[2];m_pPixels[pixelsFilled*m_bytesPP+1] = currentColor[1];m_pPixels[pixelsFilled*m_bytesPP+2] = currentColor[0];if (4 == m_bytesPP) {    m_pPixels[pixelsFilled*m_bytesPP+3] =   currentColor[3];}pixelsFilled++;if (pixelsFilled > m_width*m_height) {    /* ERROR */} }  }   } while (pixelsFilled < m_width*m_height);   LOG << "Left the loop!<br />" << ENDL;   g_pLog->flush("Success");    }}[Edited by - Clueless on May 27, 2006 11:50:29 AM]
  Hi.If you can load NeHe's image, it sounds like the new picture you are trying to load is not saved in the correct format rather than your code being incorrect.I had a few problems with tga's when i first started using them too.  Remeber that your texture should be based in Base2 i.e. 64*64, 128*128 ect.  Also, check that what resolution you are saving the tga in. I know Photoshop can save in 16, 24 and 32 bit.  I use 24bit for non-alpha images, and 32 bit for those that do have an alpha layer.Hope that helps.   ;  Thanks for your reply!I'd agree if that texture couldn't be loaded by NeHe's code.It is a simple 256x256 RLE-compressed texture with 24 bits for the colors, though.The only difference between the file from the tutorial and the file that I can't load is width and height AFAIK.   ;  I can't spot any obvious problems.  How do you read from the file?  Do you read in binary mode?  If not that could be causing your problems.Also be aware that the ability to specify a stack array size using anything other than a constant is a C99 feature included in your compiler as an extension to C++ and is not standard C++ and therefore not portable.  You use it here:Uint32 filesize = get_filesize();Uint8 tgafile[filesize];Σnigma   ;  Thanks. I didn't know that ...Changing it to:Uint8* tgafile = NULL;tgafile = new Uint8[filesize];...delete[] tgafile;actually helped ... somewhat.Something is loaded now and the program doesn't crash.The texture is completely messed up, though.I'll try to figure out what happens ...Thanks again!   ;  Hi again,can't figure it out.There were some more dynamic arrays that I turned into pointers.I even temporarily tried replacing the new and delete[] stuff with malloc/free and I use memset to clear the allocated regions ... but nothing seems to work.Since the import_uncompressedTGA(...) function is now left properly the next suspect is this:Image* Image::import_tga(const char* filename) {    g_pLog = new debug::Logfile("logs/load.html");    set_filename(filename);    if (m_pPixels) {   delete[] m_pPixels;   m_pPixels = NULL;   glDeleteTextures(1, &m_texId);    }    const Uint8 uncpHeader[12] = {0,0, 2,0,0,0,0,0,0,0,0,0};    const Uint8 compHeader[12] = {0,0,10,0,0,0,0,0,0,0,0,0};    Uint8* header = new Uint8[12];    start_reading();    read_uint8(header, 12);    finish_reading();    if (0 == memcmp(header, uncpHeader, sizeof(Uint8)*12)) {   LOG << "Importing uncompressed TGA<br />" << ENDL;   g_pLog->flush("Importing");   import_uncompressedTGA();   GLenum format;   if (3 == m_bytesPP) {  format = GL_RGB;   } else if (4 == m_bytesPP) {  format = GL_RGBA;   }   glGenTextures(1, &m_texId);   glBindTexture(GL_TEXTURE_2D, m_texId);   glTexImage2D(GL_TEXTURE_2D, 0, m_bytesPP, m_width, m_height, 0, format, GL_UNSIGNED_BYTE, m_pPixels);   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);    } else if (0 == memcmp(header, compHeader, sizeof(Uint8)*12)) {   LOG << "Importing compressed TGA<br />" << ENDL;   g_pLog->flush("Importing");   import_compressedTGA();   LOG << "Imported compressed TGA<br />" << ENDL;   g_pLog->flush("Success");   GLenum format;   if (3 == m_bytesPP) {  format = GL_RGB;   } else if (4 == m_bytesPP) {  format = GL_RGBA;   }   glGenTextures(1, &m_texId);   glBindTexture(GL_TEXTURE_2D, m_texId);   glTexImage2D(GL_TEXTURE_2D, 0, m_bytesPP, m_width, m_height, 0, format, GL_UNSIGNED_BYTE, m_pPixels);   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);    } else {   /* Error */    }    delete[] header;    g_pLog->free();    return this;}Anything weird here?Or there (I doubt it, though):void Resource::set_filename(const char* filename){    m_filename = filename;}void Resource::start_writing() {    m_out.open( m_filename.c_str(), std::ios::binary | std::ios::out |   std::ios::trunc );}void Resource::finish_writing() {    m_out.close();}void Resource::start_reading() {    m_in.open( m_filename.c_str(), std::ios::binary | std::ios::in );}void Resource::finish_reading() {    m_in.close();}Uint32 Resource::get_filesize() {    Uint32 filesize = m_in.seekg(0, std::ios::end).tellg();    m_in.seekg(0);    return filesize;}void Resource::read_uint8(Uint8* trg, Uint16 amount) {    m_in.read((char*)trg, sizeof(Uint8)*amount);}Logfile looks ok again:BeginLogging Started!ImportingImporting compressed TGASuccessFile loaded into memorySuccessWidth: 256Height: 256SuccessBpp: 3SuccessImagesize: 192kbSuccessLeft the loop!Right amount of pixels filled!65536 SuccessImported compressed TGAHere's what the texture looks like now:[Edited by - Clueless on May 27, 2006 10:28:52 AM];  Using a Uint16 for the amount in your Resource::read_uint8 function could be a problem, although I would expect that to produce different symptons.If changing that doesn't fix the problem then could you upload a zip with sufficient source for me to test and a copy of the tga in question and I'll try to have a look at it.Σnigma   ;  After reading that I was pretty confident that would fix the problem.And rightly so!You just rock!! ThanksAs I mentioned the only real difference is width and height ...I saw another thread with a short that was too small (as a counter variable) ...still it didn't click.I had a zip file prepared already.Guess uploading that isn't neccessary now. :-)   ;  A bit after the fact and off topic to boot... But instead of using malloc/free so you can memset... Just use ZeroMemory() or FillMemory() with new/delete.   ;  Thanks for mentioning that.Those are from the Win API I guess?I do use them in the windows specific code.Btw. I can still use memset even if I use new and delete, right?The post kinda sounds as if thas is not possible ...   