- type = (unsigned char)m_f->GetC();
-
- /* end of data? */
- if (type == 0x3B)
- {
- done = TRUE;
- }
- else
- /* extension block? */
- if (type == 0x21)
- {
- if (((unsigned char)m_f->GetC()) == 0xF9)
- /* graphics control extension, parse it */
- {
- m_f->Read(buf, 6);
-
- /* read delay and convert from 1/100 of a second to ms */
- delay = 10 * (buf[2] + 256 * buf[3]);
-
- /* read transparent colour index, if used */
- if (buf[1] & 0x01)
- transparent = buf[4];
-
- /* read disposal method */
- disposal = (buf[1] & 0x1C) - 1;
- }
- else
- /* other extension, skip */
- {
- while ((i = (unsigned char)m_f->GetC()) != 0)
- {
- m_f->SeekI(i, wxFromCurrent);
- }
- }
- }
- else
- /* image descriptor block? */
- if (type == 0x2C)
- {
- /* allocate memory for IMAGEN struct */
- pimg = (*ppimg) = new GIFImage();
-
- if (pimg == NULL)
- {
- Destroy();
- return wxGIF_MEMERR;
- }
-
- /* fill in the data */
- m_f->Read(buf, 9);
- pimg->left = buf[4] + 256 * buf[5];
- pimg->top = buf[4] + 256 * buf[5];
- pimg->w = buf[4] + 256 * buf[5];
- pimg->h = buf[6] + 256 * buf[7];
- interl = ((buf[8] & 0x40)? 1 : 0);
- size = pimg->w * pimg->h;
-
- pimg->transparent = transparent;
- pimg->disposal = disposal;
- pimg->delay = delay;
- pimg->next = NULL;
- pimg->prev = pprev;
- pprev = pimg;
- ppimg = &pimg->next;
-
- /* allocate memory for image and palette */
- pimg->p = (unsigned char *) malloc((size_t)size);
- pimg->pal = (unsigned char *) malloc(768);
-
- if ((!pimg->p) || (!pimg->pal))
- {
- Destroy();
- return wxGIF_MEMERR;
- }
-
- /* load local color map if available, else use global map */
- if ((buf[8] & 0x80) == 0x80)
- {
- ncolors = 2 << (buf[8] & 0x07);
- m_f->Read(pimg->pal, 3 * ncolors);
- }
- else
- memcpy(pimg->pal, pal, 768);
-
- /* get initial code size from first byte in raster data */
- bits = (unsigned char)m_f->GetC();
-
- /* decode image */
- dgif(pimg, interl, bits);
- m_nimages++;
-
- /* if this is not an animated GIF, exit after first image */
- if (!m_anim)
- done = TRUE;
- }
+ type = (unsigned char)m_f->GetC();
+
+ /*
+ If the end of file has been reached (or an error) and a ";"
+ (0x3B) hasn't been encountered yet, exit the loop. (Without this
+ check the while loop would loop endlessly.) Later on, in the next while
+ loop, the file will be treated as being truncated (But still
+ be decoded as far as possible). returning wxGIF_TRUNCATED is not
+ possible here since some init code is done after this loop.
+ */
+ if (m_f->Eof())// || !m_f->IsOk())
+ {
+ /*
+ type is set to some bogus value, so there's no
+ need to continue evaluating it.
+ */
+ break; // Alternative : "return wxGIF_INVFORMAT;"
+ }
+
+ /* end of data? */
+ if (type == 0x3B)
+ {
+ done = TRUE;
+ }
+ else
+ /* extension block? */
+ if (type == 0x21)
+ {
+ if (((unsigned char)m_f->GetC()) == 0xF9)
+ /* graphics control extension, parse it */
+ {
+ static const size_t gceSize = 6;
+ m_f->Read(buf, gceSize);
+ if (m_f->LastRead() != gceSize)
+ {
+ Destroy();
+ return wxGIF_INVFORMAT;
+ }
+
+ /* read delay and convert from 1/100 of a second to ms */
+ delay = 10 * (buf[2] + 256 * buf[3]);
+
+ /* read transparent colour index, if used */
+ if (buf[1] & 0x01)
+ transparent = buf[4];
+
+ /* read disposal method */
+ disposal = (buf[1] & 0x1C) - 1;
+ }
+ else
+ /* other extension, skip */
+ {
+ while ((i = (unsigned char)m_f->GetC()) != 0)
+ {
+ m_f->SeekI(i, wxFromCurrent);
+ if (m_f->Eof())
+ {
+ done = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ else
+ /* image descriptor block? */
+ if (type == 0x2C)
+ {
+ /* allocate memory for IMAGEN struct */
+ pimg = (*ppimg) = new GIFImage();
+
+ if (pimg == NULL)
+ {
+ Destroy();
+ return wxGIF_MEMERR;
+ }
+
+ /* fill in the data */
+ static const size_t idbSize = (2 + 2 + 2 + 2 + 1);
+ m_f->Read(buf, idbSize);
+ if (m_f->LastRead() != idbSize)
+ {
+ Destroy();
+ return wxGIF_INVFORMAT;
+ }
+
+ pimg->left = buf[0] + 256 * buf[1];
+ pimg->top = buf[2] + 256 * buf[3];
+/*
+ pimg->left = buf[4] + 256 * buf[5];
+ pimg->top = buf[4] + 256 * buf[5];
+*/
+ pimg->w = buf[4] + 256 * buf[5];
+ pimg->h = buf[6] + 256 * buf[7];
+
+ if (pimg->w == 0 || pimg->h == 0)
+ {
+ Destroy();
+ return wxGIF_INVFORMAT;
+ }
+
+ interl = ((buf[8] & 0x40)? 1 : 0);
+ size = pimg->w * pimg->h;
+
+ pimg->transparent = transparent;
+ pimg->disposal = disposal;
+ pimg->delay = delay;
+ pimg->next = NULL;
+ pimg->prev = pprev;
+ pprev = pimg;
+ ppimg = &pimg->next;
+
+ /* allocate memory for image and palette */
+ pimg->p = (unsigned char *) malloc((size_t)size);
+ pimg->pal = (unsigned char *) malloc(768);
+
+ if ((!pimg->p) || (!pimg->pal))
+ {
+ Destroy();
+ return wxGIF_MEMERR;
+ }
+
+ /* load local color map if available, else use global map */
+ if ((buf[8] & 0x80) == 0x80)
+ {
+ ncolors = 2 << (buf[8] & 0x07);
+ size_t numBytes = 3 * ncolors;
+ m_f->Read(pimg->pal, numBytes);
+ if (m_f->LastRead() != numBytes)
+ {
+ Destroy();
+ return wxGIF_INVFORMAT;
+ }
+ }
+ else
+ {
+ memcpy(pimg->pal, pal, 768);
+ }
+
+ /* get initial code size from first byte in raster data */
+ bits = (unsigned char)m_f->GetC();
+
+ /* decode image */
+ int result = dgif(pimg, interl, bits);
+ if (result != wxGIF_OK)
+ {
+ Destroy();
+ return result;
+ }
+ m_nimages++;
+
+ /* if this is not an animated GIF, exit after first image */
+ if (!m_anim)
+ done = TRUE;
+ }