   Our GIF decoder cannot decode *this* file!(weird bug!)
  This GIF decoder is done with the help of Kippesoep, see this page:http://www.gamedev.net/community/forums/topic.asp?topic_id=367911&whichpage=1�But I wanna know why both my and Kippesoep's GIF decoder can't decode one GIF file correctly.The source code:#include <iostream>#include <fstream>#include <windows.h>using namespace std;typedef unsigned long DWORD;typedef unsigned short WORD;typedef unsigned char BYTE;BITMAPFILEHEADER myBFH;BITMAPINFOHEADER myBIH;struct ScreenDescriptor{    WORD ScreenWidth;    WORD ScreenHeight;    BYTE bitField;    BYTE backgroundColor;    BYTE pixelAspectRatio;}mySD;struct ImageDescriptor{    WORD ImageLeft;    WORD ImageTop;    WORD ImageWidth;    WORD ImageHeight;    BYTE bitField;}myID;struct DictionaryTreeEntry{    BYTE red;    BYTE green;    BYTE blue;    WORD parent;}myDT[4096];    fstream infile, outfile;    WORD codesize = 0, // code size that read from .gif file    blokbytecount = 0, // block bytes count that read from .gif file    cucodesize = 0;    WORD code = 0, old = 0, tempcode = 0, mask = 0;    int bitremain = 0, bytesread = 0;    BYTE pixel = 0;    WORD stk[4096], // stack    sp = 0, // stack pointer    firstchar = 0;    int clearcode = 0;    int endcode = 0;    int startcode = 0;    int nextcode = 0;void ClearTable(){    nextcode = startcode;    cucodesize = codesize + 1;}BYTE readbuffer [256];int readptr = 0;BYTE ReadByte (){    //Load next block    if (readptr == blokbytecount)    {   infile.read ((char *)&blokbytecount, 1);   infile.read ((char *)&readbuffer [0], blokbytecount);   readptr = 0;    }    //Get byte from buffer    return readbuffer [readptr++];}void GetCode(){    bitremain -= cucodesize;    mask = (0xFFFF >> (16 - cucodesize));    if(bitremain < 0)    {   int oneortwo = bitremain < -8 ? 2 : 1;   code = tempcode;   tempcode = ReadByte ();   if (oneortwo == 2) tempcode |= ReadByte () << 8;   code |= (tempcode << (bitremain + cucodesize));   code &= mask;   tempcode >>= -bitremain;   bitremain += oneortwo*8;    }else{   code = tempcode & mask;   tempcode >>= cucodesize;    }}void PutCode(){    WORD t = code;    while (t>clearcode)    {   stk[sp++] = t;   t = myDT[t].parent;    }    stk [sp++] = firstchar = t;    while(sp > 0){   sp--;   outfile.write ((char *) &myDT[stk[sp]].blue, 1 ); // BGR   outfile.write ((char *) &myDT[stk[sp]].green, 1 );   outfile.write ((char *) &myDT[stk[sp]].red, 1 );    }}int main(){    infile.open ("image.gif", ios::in | ios::binary);    outfile.open ("image.bmp", ios::out | ios::binary);    if(!( (infile.get() == 'G') && (infile.get() == 'I') && (infile.get() == 'F') )){   std::cout << "not gif format!\n";   infile.close ();   outfile.close ();   return -1;    }    infile.seekg (3, ios::cur); // ignore version number    infile.read ((char *) &mySD, 7 );    std::cout << "ScreenDescriptor: " << '\n'    << "    ScreenWidth: " << mySD.ScreenWidth << '\n'    << "    ScreenHeight: " << mySD.ScreenHeight << '\n'    << "    bitField: " << mySD.bitField * 1 << '\n' // * 1 for output int not char    << "    M bit of bitField: " << ((mySD.bitField & 0x80) >> 7) << '\n' //0x80 = 10000000B    << "    cr field of bitField: " << ((mySD.bitField & 0x70) >> 4) << '\n'    << "    undefine bit of bitField: " << ((mySD.bitField & 8) >> 3) << '\n'    << "    pixel field of bitField: " << (mySD.bitField & 7) << '\n'    << "    backgroundColor: " << mySD.backgroundColor * 1 << '\n'    << "    pixelAspectRatio: " << mySD.pixelAspectRatio * 1 << '\n';    pixel = mySD.bitField & 0x7; // 7 = 00000111B = pixel field of the bitField    int limit = 1 << (pixel+1); // pow(2, pixel + 1);    clearcode = 1 << (pixel+1);    endcode = clearcode + 1;    startcode = clearcode + 2;    nextcode = startcode;    if(!(mySD.bitField & 0xFF)){   std::cout << "Sorry, this test program cannot decode a .gif file without a global color map.\n";   infile.close ();   outfile.close ();   return -2;    }    for(int i = 0; i < limit; i++ ){   infile.read ((char *) &myDT, 3);   myDT.parent = 0;    }    while(infile.get() != ',')   ;    infile.read ((char *) &myID, 9 );    std::cout << "ImageDescriptor: " << '\n'    << "    ImageLeft: " << myID.ImageLeft << '\n'    << "    ImageTop: " << myID.ImageTop << '\n'    << "    ImageWidth: " << myID.ImageWidth << '\n'    << "    ImageHeight: " << myID.ImageHeight << '\n'    << "    M bit of bitField: " << ((myID.bitField & 0x80) >> 7) << '\n' //0x80 = 10000000B    << "    I bit of bitField: " << ((myID.bitField & 0x40) >> 6) << '\n' //0x40 = 01000000B    << "    undefine field of bitField: " << ((myID.bitField & 0x38) >> 3) << '\n'    << "    pixel field of bitField: " << (myID.bitField & 7) << '\n';    myBFH.bfType = 0x4D42;    myBFH.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(mySD.ScreenWidth*mySD.ScreenHeight*3);    myBFH.bfReserved1 = 0;    myBFH.bfReserved2 = 0;    myBFH.bfOffBits = 0x36;    myBIH.biSize = 0x28;    myBIH.biWidth = mySD.ScreenWidth;    myBIH.biHeight = mySD.ScreenHeight;    myBIH.biPlanes = 1;    myBIH.biBitCount = 24;    myBIH.biCompression = 0;    myBIH.biSizeImage = mySD.ScreenWidth*mySD.ScreenHeight*3;    myBIH.biXPelsPerMeter = 0;    myBIH.biYPelsPerMeter = 0;    myBIH.biClrUsed = 1 << (pixel+1); //pow(2, pixel + 1)    myBIH.biClrImportant = 1 << (pixel+1); //pow(2, pixel + 1)    outfile.write ((char *) &myBFH, sizeof(myBFH));    outfile.write ((char *) &myBIH, sizeof(myBIH));    infile.read ((char *) &codesize, 1 );    cucodesize = codesize + 1;    while(true){   old = code;   if((nextcode >= (1 << cucodesize)/*pow(2, cucodesize)*/) && (cucodesize < 12)){  cucodesize++;   }   GetCode();   if(code == endcode){  break;   }else if(code == clearcode){  ClearTable();  GetCode();  PutCode();   }else if(code < nextcode){  PutCode();  myDT[nextcode] = myDT[firstchar];  myDT[nextcode].parent = old;  nextcode++;   }else if(code == nextcode){  myDT[nextcode] = myDT[firstchar];  myDT[nextcode].parent = old;  nextcode++;  PutCode();   }    }    if(infile.get() == 0){   if(infile.get() == ';'){  std::cout << "done.\n";   }else{  std::cout << "Sorry, this test program cannot decode a multiple images .gif file.\n";   }    }else{   std::cout << "Sorry, I don't know why there is no zero.\n";    }    infile.close ();    outfile.close ();    return 0;}If you are interesting in the GIF file, please tell me, I will send it to you by email.I really don't want my decoder with this weird bug.Thanks!   
  The GIF file is downloadable now:http://g3a24.mail.126.com/coremail/fcg/ldmsapp/image.gif?lettsid=aABcwqCZPKJAkydD&mid=1tbiKAQiVkJzM66y9QAAsz%250A40%250A8388762%250A1&funcid=readpart&part=3&filename=image.gif&download=1Thanks!   ;  You can't link to an e-mail attachment like that, and mail server with any sense (that one included) will block it for everyone except the person whos mail it is.What do you mean your program "can't decode it"? Does your code crash? Does it just give a garbled image?   ;  Sorry about that...The decoder run well without crash, and tested on a good number of GIF file without any problem. It just can't transform one GIF file into a BMP file correctly(Windows's decoder can't display the transformed BMP, but it can display the GIF file).Dear Evil Steve, are you interesting in it? Shall I email it to you?If you are interesting in it, please tell me to email it to you.Thanks!   ;  Well I dont know much about the specifics of the GIF image format, but a quick scan through yor code and I notice that you ignore the version number in the signature of the GIF your loading.  Doesnt that matter?Looking at google there seems to be two major types of GIFs that you get: GIF87a and GIF89aI havnt a clue what the difference is, but it sounds like its worth checking into.   ;Quote:Original post by was2_0If you are interesting in it, please tell me to email it to you.Why don't you just upload it to http://imageshack.us/ ?;  Your BMP writer looks like it does not have any support for padding rows of the image to be aligned to 4 bytes.  If your original GIF is an odd size (say, 129x200), Windows -- or any application for that matter -- will refuse to load it.I'd say your problem is not in the GIF decoding, but in the BMP creation process.   ;  The GIF file is simplyest GIF87a format without interleaving, animation, multiple images and any extension(my GIF decoder just do that).Thank you! Anonymous Poster! The GIF file is downloadable now:http://img222.imageshack.us/img222/6323/image1lm1.gifDear bpoint! Thank you! It must be ONE problem! I never know BMP need padding rows of the image until now, and the GIF is really 17x20.Shall I add these code to PutCode function?:static c = 0;if(c == 17){outfile.put(0);c = 0;}c++;Then it will be:void PutCode(){    WORD t = code;    while (t>clearcode)    {   stk[sp++] = t;   t = myDT[t].parent;    }    stk [sp++] = firstchar = t;    while(sp > 0){   sp--;   outfile.write ((char *) &myDT[stk[sp]].blue, 1 ); // BGR   outfile.write ((char *) &myDT[stk[sp]].green, 1 );   outfile.write ((char *) &myDT[stk[sp]].red, 1 );static c = 0;if(c == 17){outfile.put(0);c = 0;}c++;    }}Yeah! It become displayable but still not display correctly...;  The GIF file is simplyest GIF87a format without interleaving, animation, multiple images and any extension(my GIF decoder just do that).Thank you! Anonymous Poster! The GIF file is downloadable now:http://img222.imageshack.us/img222/6323/image1lm1.gifDear bpoint! Thank you! It must be ONE problem! I never know BMP need padding rows of the image until now, and the GIF is really 17x20.Shall I add these code to PutCode function?:static c = 0;if(c == 17){outfile.put(0);c = 0;}c++;Then it will be:void PutCode(){    WORD t = code;    while (t>clearcode)    {   stk[sp++] = t;   t = myDT[t].parent;    }    stk [sp++] = firstchar = t;    while(sp > 0){   sp--;   outfile.write ((char *) &myDT[stk[sp]].blue, 1 ); // BGR   outfile.write ((char *) &myDT[stk[sp]].green, 1 );   outfile.write ((char *) &myDT[stk[sp]].red, 1 );static c = 0;if(c == 17){outfile.put(0);c = 0;}c++;    }}Yeah! It become displayable but still not display correctly...;  Why not just use DevIL?   