For all platforms except WXMAC, the wxGIFDecoder::dgif function was
allocating 3 arrays of 4096 ints in the stack (48K) which causes problems with Watcom. Now all platforms behave like WXMAC, i.e. the arrays are allocated (and freed) dynamically on the heap. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10546 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -63,11 +63,11 @@ void wxGIFDecoder::Destroy()
|
|||||||
|
|
||||||
while (pimg != NULL)
|
while (pimg != NULL)
|
||||||
{
|
{
|
||||||
paux = pimg->next;
|
paux = pimg->next;
|
||||||
free(pimg->p);
|
free(pimg->p);
|
||||||
free(pimg->pal);
|
free(pimg->pal);
|
||||||
delete pimg;
|
delete pimg;
|
||||||
pimg = paux;
|
pimg = paux;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pimage = NULL;
|
m_pimage = NULL;
|
||||||
@@ -97,7 +97,7 @@ bool wxGIFDecoder::ConvertToImage(wxImage *image) const
|
|||||||
image->Create(GetWidth(), GetHeight());
|
image->Create(GetWidth(), GetHeight());
|
||||||
|
|
||||||
if (!image->Ok())
|
if (!image->Ok())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pal = GetPalette();
|
pal = GetPalette();
|
||||||
src = GetData();
|
src = GetData();
|
||||||
@@ -107,46 +107,46 @@ bool wxGIFDecoder::ConvertToImage(wxImage *image) const
|
|||||||
/* set transparent colour mask */
|
/* set transparent colour mask */
|
||||||
if (transparent != -1)
|
if (transparent != -1)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
if ((pal[3 * i + 0] == 255) &&
|
if ((pal[3 * i + 0] == 255) &&
|
||||||
(pal[3 * i + 1] == 0) &&
|
(pal[3 * i + 1] == 0) &&
|
||||||
(pal[3 * i + 2] == 255))
|
(pal[3 * i + 2] == 255))
|
||||||
{
|
{
|
||||||
pal[3 * i + 2] = 254;
|
pal[3 * i + 2] = 254;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pal[3 * transparent + 0] = 255,
|
pal[3 * transparent + 0] = 255,
|
||||||
pal[3 * transparent + 1] = 0,
|
pal[3 * transparent + 1] = 0,
|
||||||
pal[3 * transparent + 2] = 255;
|
pal[3 * transparent + 2] = 255;
|
||||||
|
|
||||||
image->SetMaskColour(255, 0, 255);
|
image->SetMaskColour(255, 0, 255);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
image->SetMask(FALSE);
|
image->SetMask(FALSE);
|
||||||
|
|
||||||
if (pal)
|
if (pal)
|
||||||
{
|
{
|
||||||
unsigned char* r = new unsigned char[256];
|
unsigned char* r = new unsigned char[256];
|
||||||
unsigned char* g = new unsigned char[256];
|
unsigned char* g = new unsigned char[256];
|
||||||
unsigned char* b = new unsigned char[256];
|
unsigned char* b = new unsigned char[256];
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
r[i] = pal[3*i + 0];
|
r[i] = pal[3*i + 0];
|
||||||
g[i] = pal[3*i + 1];
|
g[i] = pal[3*i + 1];
|
||||||
b[i] = pal[3*i + 2];
|
b[i] = pal[3*i + 2];
|
||||||
}
|
}
|
||||||
image->SetPalette(wxPalette(256, r, g, b));
|
image->SetPalette(wxPalette(256, r, g, b));
|
||||||
delete[] r; delete[] g; delete[] b;
|
delete[] r; delete[] g; delete[] b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy image data */
|
/* copy image data */
|
||||||
for (i = 0; i < (GetWidth() * GetHeight()); i++, src++)
|
for (i = 0; i < (GetWidth() * GetHeight()); i++, src++)
|
||||||
{
|
{
|
||||||
*(dst++) = pal[3 * (*src) + 0];
|
*(dst++) = pal[3 * (*src) + 0];
|
||||||
*(dst++) = pal[3 * (*src) + 1];
|
*(dst++) = pal[3 * (*src) + 1];
|
||||||
*(dst++) = pal[3 * (*src) + 2];
|
*(dst++) = pal[3 * (*src) + 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -186,7 +186,7 @@ bool wxGIFDecoder::IsAnimation() const { return (m_nimages > 1); }
|
|||||||
bool wxGIFDecoder::GoFirstFrame()
|
bool wxGIFDecoder::GoFirstFrame()
|
||||||
{
|
{
|
||||||
if (!IsAnimation())
|
if (!IsAnimation())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
m_image = 1;
|
m_image = 1;
|
||||||
m_pimage = m_pfirst;
|
m_pimage = m_pfirst;
|
||||||
@@ -196,7 +196,7 @@ bool wxGIFDecoder::GoFirstFrame()
|
|||||||
bool wxGIFDecoder::GoLastFrame()
|
bool wxGIFDecoder::GoLastFrame()
|
||||||
{
|
{
|
||||||
if (!IsAnimation())
|
if (!IsAnimation())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
m_image = m_nimages;
|
m_image = m_nimages;
|
||||||
m_pimage = m_plast;
|
m_pimage = m_plast;
|
||||||
@@ -206,45 +206,45 @@ bool wxGIFDecoder::GoLastFrame()
|
|||||||
bool wxGIFDecoder::GoNextFrame(bool cyclic)
|
bool wxGIFDecoder::GoNextFrame(bool cyclic)
|
||||||
{
|
{
|
||||||
if (!IsAnimation())
|
if (!IsAnimation())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if ((m_image < m_nimages) || (cyclic))
|
if ((m_image < m_nimages) || (cyclic))
|
||||||
{
|
{
|
||||||
m_pimage = m_pimage->next;
|
m_pimage = m_pimage->next;
|
||||||
m_image++;
|
m_image++;
|
||||||
|
|
||||||
if (!m_pimage)
|
if (!m_pimage)
|
||||||
{
|
{
|
||||||
m_image = 1;
|
m_image = 1;
|
||||||
m_pimage = m_pfirst;
|
m_pimage = m_pfirst;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxGIFDecoder::GoPrevFrame(bool cyclic)
|
bool wxGIFDecoder::GoPrevFrame(bool cyclic)
|
||||||
{
|
{
|
||||||
if (!IsAnimation())
|
if (!IsAnimation())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if ((m_image > 1) || (cyclic))
|
if ((m_image > 1) || (cyclic))
|
||||||
{
|
{
|
||||||
m_pimage = m_pimage->prev;
|
m_pimage = m_pimage->prev;
|
||||||
m_image--;
|
m_image--;
|
||||||
|
|
||||||
if (!m_pimage)
|
if (!m_pimage)
|
||||||
{
|
{
|
||||||
m_image = m_nimages;
|
m_image = m_nimages;
|
||||||
m_pimage = m_plast;
|
m_pimage = m_plast;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxGIFDecoder::GoFrame(int which)
|
bool wxGIFDecoder::GoFrame(int which)
|
||||||
@@ -252,19 +252,19 @@ bool wxGIFDecoder::GoFrame(int which)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!IsAnimation())
|
if (!IsAnimation())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if ((which >= 1) && (which <= m_nimages))
|
if ((which >= 1) && (which <= m_nimages))
|
||||||
{
|
{
|
||||||
m_pimage = m_pfirst;
|
m_pimage = m_pfirst;
|
||||||
|
|
||||||
for (i = 1; i < which; i++)
|
for (i = 1; i < which; i++)
|
||||||
m_pimage = m_pimage->next;
|
m_pimage = m_pimage->next;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -288,35 +288,35 @@ int wxGIFDecoder::getcode(int bits, int ab_fin)
|
|||||||
/* keep reading new bytes while needed */
|
/* keep reading new bytes while needed */
|
||||||
while (bits > m_restbits)
|
while (bits > m_restbits)
|
||||||
{
|
{
|
||||||
/* if no bytes left in this block, read the next block */
|
/* if no bytes left in this block, read the next block */
|
||||||
if (m_restbyte == 0)
|
if (m_restbyte == 0)
|
||||||
{
|
{
|
||||||
m_restbyte = (unsigned char)m_f->GetC();
|
m_restbyte = (unsigned char)m_f->GetC();
|
||||||
|
|
||||||
/* Some encoders are a bit broken: instead of issuing
|
/* Some encoders are a bit broken: instead of issuing
|
||||||
* an end-of-image symbol (ab_fin) they come up with
|
* an end-of-image symbol (ab_fin) they come up with
|
||||||
* a zero-length subblock!! We catch this here so
|
* a zero-length subblock!! We catch this here so
|
||||||
* that the decoder sees an ab_fin code.
|
* that the decoder sees an ab_fin code.
|
||||||
*/
|
*/
|
||||||
if (m_restbyte == 0)
|
if (m_restbyte == 0)
|
||||||
{
|
{
|
||||||
code = ab_fin;
|
code = ab_fin;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prefetch data */
|
/* prefetch data */
|
||||||
m_f->Read((void *) m_buffer, m_restbyte);
|
m_f->Read((void *) m_buffer, m_restbyte);
|
||||||
m_bufp = m_buffer;
|
m_bufp = m_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read next byte and isolate the bits we need */
|
/* read next byte and isolate the bits we need */
|
||||||
m_lastbyte = (unsigned char) (*m_bufp++);
|
m_lastbyte = (unsigned char) (*m_bufp++);
|
||||||
mask = (1 << (bits - m_restbits)) - 1;
|
mask = (1 << (bits - m_restbits)) - 1;
|
||||||
code = code + ((m_lastbyte & mask) << m_restbits);
|
code = code + ((m_lastbyte & mask) << m_restbits);
|
||||||
m_restbyte--;
|
m_restbyte--;
|
||||||
|
|
||||||
/* adjust total number of bits extracted from the buffer */
|
/* adjust total number of bits extracted from the buffer */
|
||||||
m_restbits = m_restbits + 8;
|
m_restbits = m_restbits + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find number of bits remaining for next code */
|
/* find number of bits remaining for next code */
|
||||||
@@ -332,23 +332,17 @@ int wxGIFDecoder::getcode(int bits, int ab_fin)
|
|||||||
//
|
//
|
||||||
int wxGIFDecoder::dgif(GIFImage *img, int interl, int bits)
|
int wxGIFDecoder::dgif(GIFImage *img, int interl, int bits)
|
||||||
{
|
{
|
||||||
#ifdef __WXMAC__
|
int *ab_prefix = new int[4096]; /* alphabet (prefixes) */
|
||||||
int *ab_prefix = new int[4096]; /* alphabet (prefixes) */
|
int *ab_tail = new int[4096]; /* alphabet (tails) */
|
||||||
int *ab_tail = new int[4096]; /* alphabet (tails) */
|
int *stack = new int[4096]; /* decompression stack */
|
||||||
int *stack = new int[4096]; /* decompression stack */
|
int ab_clr; /* clear code */
|
||||||
#else
|
int ab_fin; /* end of info code */
|
||||||
int ab_prefix[4096]; /* alphabet (prefixes) */
|
int ab_bits; /* actual symbol width, in bits */
|
||||||
int ab_tail[4096]; /* alphabet (tails) */
|
int ab_free; /* first free position in alphabet */
|
||||||
int stack[4096]; /* decompression stack */
|
int ab_max; /* last possible character in alphabet */
|
||||||
#endif
|
int pass; /* pass number in interlaced images */
|
||||||
int ab_clr; /* clear code */
|
int pos; /* index into decompresion stack */
|
||||||
int ab_fin; /* end of info code */
|
unsigned int x, y; /* position in image buffer */
|
||||||
int ab_bits; /* actual symbol width, in bits */
|
|
||||||
int ab_free; /* first free position in alphabet */
|
|
||||||
int ab_max; /* last possible character in alphabet */
|
|
||||||
int pass; /* pass number in interlaced images */
|
|
||||||
int pos; /* index into decompresion stack */
|
|
||||||
unsigned int x, y; /* position in image buffer */
|
|
||||||
|
|
||||||
int code, readcode, lastcode, abcabca;
|
int code, readcode, lastcode, abcabca;
|
||||||
|
|
||||||
@@ -372,103 +366,102 @@ int wxGIFDecoder::dgif(GIFImage *img, int interl, int bits)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* get next code */
|
/* get next code */
|
||||||
readcode = code = getcode(ab_bits, ab_fin);
|
readcode = code = getcode(ab_bits, ab_fin);
|
||||||
|
|
||||||
/* end of image? */
|
/* end of image? */
|
||||||
if (code == ab_fin) break;
|
if (code == ab_fin) break;
|
||||||
|
|
||||||
/* reset alphabet? */
|
/* reset alphabet? */
|
||||||
if (code == ab_clr)
|
if (code == ab_clr)
|
||||||
{
|
{
|
||||||
/* reset main variables */
|
/* reset main variables */
|
||||||
ab_bits = bits + 1;
|
ab_bits = bits + 1;
|
||||||
ab_free = (1 << bits) + 2;
|
ab_free = (1 << bits) + 2;
|
||||||
ab_max = (1 << ab_bits) - 1;
|
ab_max = (1 << ab_bits) - 1;
|
||||||
lastcode = -1;
|
lastcode = -1;
|
||||||
abcabca = -1;
|
abcabca = -1;
|
||||||
|
|
||||||
/* skip to next code */
|
/* skip to next code */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unknown code: special case (like in ABCABCA) */
|
/* unknown code: special case (like in ABCABCA) */
|
||||||
if (code >= ab_free)
|
if (code >= ab_free)
|
||||||
{
|
{
|
||||||
code = lastcode; /* take last string */
|
code = lastcode; /* take last string */
|
||||||
stack[pos++] = abcabca; /* add first character */
|
stack[pos++] = abcabca; /* add first character */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build the string for this code in the stack */
|
/* build the string for this code in the stack */
|
||||||
while (code > ab_clr)
|
while (code > ab_clr)
|
||||||
{
|
{
|
||||||
stack[pos++] = ab_tail[code];
|
stack[pos++] = ab_tail[code];
|
||||||
code = ab_prefix[code];
|
code = ab_prefix[code];
|
||||||
}
|
}
|
||||||
stack[pos] = code; /* push last code into the stack */
|
stack[pos] = code; /* push last code into the stack */
|
||||||
abcabca = code; /* save for special case */
|
abcabca = code; /* save for special case */
|
||||||
|
|
||||||
/* make new entry in alphabet (only if NOT just cleared) */
|
/* make new entry in alphabet (only if NOT just cleared) */
|
||||||
if (lastcode != -1)
|
if (lastcode != -1)
|
||||||
{
|
{
|
||||||
ab_prefix[ab_free] = lastcode;
|
ab_prefix[ab_free] = lastcode;
|
||||||
ab_tail[ab_free] = code;
|
ab_tail[ab_free] = code;
|
||||||
ab_free++;
|
ab_free++;
|
||||||
|
|
||||||
if ((ab_free > ab_max) && (ab_bits < 12))
|
if ((ab_free > ab_max) && (ab_bits < 12))
|
||||||
{
|
{
|
||||||
ab_bits++;
|
ab_bits++;
|
||||||
ab_max = (1 << ab_bits) - 1;
|
ab_max = (1 << ab_bits) - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dump stack data to the buffer */
|
/* dump stack data to the buffer */
|
||||||
while (pos >= 0)
|
while (pos >= 0)
|
||||||
{
|
{
|
||||||
(img->p)[x + (y * (img->w))] = (char)stack[pos--];
|
(img->p)[x + (y * (img->w))] = (char)stack[pos--];
|
||||||
|
|
||||||
if (++x >= (img->w))
|
if (++x >= (img->w))
|
||||||
{
|
{
|
||||||
x = 0;
|
x = 0;
|
||||||
|
|
||||||
if (interl)
|
if (interl)
|
||||||
{
|
{
|
||||||
/* support for interlaced images */
|
/* support for interlaced images */
|
||||||
switch (pass)
|
switch (pass)
|
||||||
{
|
{
|
||||||
case 1: y += 8; break;
|
case 1: y += 8; break;
|
||||||
case 2: y += 8; break;
|
case 2: y += 8; break;
|
||||||
case 3: y += 4; break;
|
case 3: y += 4; break;
|
||||||
case 4: y += 2; break;
|
case 4: y += 2; break;
|
||||||
}
|
}
|
||||||
if (y >= (img->h))
|
if (y >= (img->h))
|
||||||
{
|
{
|
||||||
switch (++pass)
|
switch (++pass)
|
||||||
{
|
{
|
||||||
case 2: y = 4; break;
|
case 2: y = 4; break;
|
||||||
case 3: y = 2; break;
|
case 3: y = 2; break;
|
||||||
case 4: y = 1; break;
|
case 4: y = 1; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* non-interlaced */
|
/* non-interlaced */
|
||||||
y++;
|
y++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
lastcode = readcode;
|
lastcode = readcode;
|
||||||
}
|
}
|
||||||
while (code != ab_fin);
|
while (code != ab_fin);
|
||||||
|
|
||||||
#ifdef __WXMAC__
|
|
||||||
delete [] ab_prefix ;
|
delete [] ab_prefix ;
|
||||||
delete [] ab_tail ;
|
delete [] ab_tail ;
|
||||||
delete [] stack ;
|
delete [] stack ;
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,13 +502,13 @@ int wxGIFDecoder::ReadGIF()
|
|||||||
|
|
||||||
/* check GIF signature */
|
/* check GIF signature */
|
||||||
if (!CanRead())
|
if (!CanRead())
|
||||||
return wxGIF_INVFORMAT;
|
return wxGIF_INVFORMAT;
|
||||||
|
|
||||||
/* check for animated GIF support (ver. >= 89a) */
|
/* check for animated GIF support (ver. >= 89a) */
|
||||||
m_f->Read(buf, 6);
|
m_f->Read(buf, 6);
|
||||||
|
|
||||||
if (memcmp(buf + 3, "89a", 3) < 0)
|
if (memcmp(buf + 3, "89a", 3) < 0)
|
||||||
m_anim = FALSE;
|
m_anim = FALSE;
|
||||||
|
|
||||||
/* read logical screen descriptor block (LSDB) */
|
/* read logical screen descriptor block (LSDB) */
|
||||||
m_f->Read(buf, 7);
|
m_f->Read(buf, 7);
|
||||||
@@ -525,10 +518,10 @@ int wxGIFDecoder::ReadGIF()
|
|||||||
/* load global color map if available */
|
/* load global color map if available */
|
||||||
if ((buf[4] & 0x80) == 0x80)
|
if ((buf[4] & 0x80) == 0x80)
|
||||||
{
|
{
|
||||||
m_background = buf[5];
|
m_background = buf[5];
|
||||||
|
|
||||||
ncolors = 2 << (buf[4] & 0x07);
|
ncolors = 2 << (buf[4] & 0x07);
|
||||||
m_f->Read(pal, 3 * ncolors);
|
m_f->Read(pal, 3 * ncolors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* transparent colour, disposal method and delay default to unused */
|
/* transparent colour, disposal method and delay default to unused */
|
||||||
@@ -545,153 +538,153 @@ int wxGIFDecoder::ReadGIF()
|
|||||||
|
|
||||||
while(!done)
|
while(!done)
|
||||||
{
|
{
|
||||||
type = (unsigned char)m_f->GetC();
|
type = (unsigned char)m_f->GetC();
|
||||||
|
|
||||||
/* end of data? */
|
/* end of data? */
|
||||||
if (type == 0x3B)
|
if (type == 0x3B)
|
||||||
{
|
{
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* extension block? */
|
/* extension block? */
|
||||||
if (type == 0x21)
|
if (type == 0x21)
|
||||||
{
|
{
|
||||||
if (((unsigned char)m_f->GetC()) == 0xF9)
|
if (((unsigned char)m_f->GetC()) == 0xF9)
|
||||||
/* graphics control extension, parse it */
|
/* graphics control extension, parse it */
|
||||||
{
|
{
|
||||||
m_f->Read(buf, 6);
|
m_f->Read(buf, 6);
|
||||||
|
|
||||||
/* read delay and convert from 1/100 of a second to ms */
|
/* read delay and convert from 1/100 of a second to ms */
|
||||||
delay = 10 * (buf[2] + 256 * buf[3]);
|
delay = 10 * (buf[2] + 256 * buf[3]);
|
||||||
|
|
||||||
/* read transparent colour index, if used */
|
/* read transparent colour index, if used */
|
||||||
if (buf[1] & 0x01)
|
if (buf[1] & 0x01)
|
||||||
transparent = buf[4];
|
transparent = buf[4];
|
||||||
|
|
||||||
/* read disposal method */
|
/* read disposal method */
|
||||||
disposal = (buf[1] & 0x1C) - 1;
|
disposal = (buf[1] & 0x1C) - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* other extension, skip */
|
/* other extension, skip */
|
||||||
{
|
{
|
||||||
while ((i = (unsigned char)m_f->GetC()) != 0)
|
while ((i = (unsigned char)m_f->GetC()) != 0)
|
||||||
{
|
{
|
||||||
m_f->SeekI(i, wxFromCurrent);
|
m_f->SeekI(i, wxFromCurrent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* image descriptor block? */
|
/* image descriptor block? */
|
||||||
if (type == 0x2C)
|
if (type == 0x2C)
|
||||||
{
|
{
|
||||||
/* allocate memory for IMAGEN struct */
|
/* allocate memory for IMAGEN struct */
|
||||||
pimg = (*ppimg) = new GIFImage();
|
pimg = (*ppimg) = new GIFImage();
|
||||||
|
|
||||||
if (pimg == NULL)
|
if (pimg == NULL)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
return wxGIF_MEMERR;
|
return wxGIF_MEMERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill in the data */
|
/* fill in the data */
|
||||||
m_f->Read(buf, 9);
|
m_f->Read(buf, 9);
|
||||||
pimg->left = buf[4] + 256 * buf[5];
|
pimg->left = buf[4] + 256 * buf[5];
|
||||||
pimg->top = buf[4] + 256 * buf[5];
|
pimg->top = buf[4] + 256 * buf[5];
|
||||||
pimg->w = buf[4] + 256 * buf[5];
|
pimg->w = buf[4] + 256 * buf[5];
|
||||||
pimg->h = buf[6] + 256 * buf[7];
|
pimg->h = buf[6] + 256 * buf[7];
|
||||||
interl = ((buf[8] & 0x40)? 1 : 0);
|
interl = ((buf[8] & 0x40)? 1 : 0);
|
||||||
size = pimg->w * pimg->h;
|
size = pimg->w * pimg->h;
|
||||||
|
|
||||||
pimg->transparent = transparent;
|
pimg->transparent = transparent;
|
||||||
pimg->disposal = disposal;
|
pimg->disposal = disposal;
|
||||||
pimg->delay = delay;
|
pimg->delay = delay;
|
||||||
pimg->next = NULL;
|
pimg->next = NULL;
|
||||||
pimg->prev = pprev;
|
pimg->prev = pprev;
|
||||||
pprev = pimg;
|
pprev = pimg;
|
||||||
ppimg = &pimg->next;
|
ppimg = &pimg->next;
|
||||||
|
|
||||||
/* allocate memory for image and palette */
|
/* allocate memory for image and palette */
|
||||||
pimg->p = (unsigned char *) malloc((size_t)size);
|
pimg->p = (unsigned char *) malloc((size_t)size);
|
||||||
pimg->pal = (unsigned char *) malloc(768);
|
pimg->pal = (unsigned char *) malloc(768);
|
||||||
|
|
||||||
if ((!pimg->p) || (!pimg->pal))
|
if ((!pimg->p) || (!pimg->pal))
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
return wxGIF_MEMERR;
|
return wxGIF_MEMERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* load local color map if available, else use global map */
|
/* load local color map if available, else use global map */
|
||||||
if ((buf[8] & 0x80) == 0x80)
|
if ((buf[8] & 0x80) == 0x80)
|
||||||
{
|
{
|
||||||
ncolors = 2 << (buf[8] & 0x07);
|
ncolors = 2 << (buf[8] & 0x07);
|
||||||
m_f->Read(pimg->pal, 3 * ncolors);
|
m_f->Read(pimg->pal, 3 * ncolors);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
memcpy(pimg->pal, pal, 768);
|
memcpy(pimg->pal, pal, 768);
|
||||||
|
|
||||||
/* get initial code size from first byte in raster data */
|
/* get initial code size from first byte in raster data */
|
||||||
bits = (unsigned char)m_f->GetC();
|
bits = (unsigned char)m_f->GetC();
|
||||||
|
|
||||||
/* decode image */
|
/* decode image */
|
||||||
dgif(pimg, interl, bits);
|
dgif(pimg, interl, bits);
|
||||||
m_nimages++;
|
m_nimages++;
|
||||||
|
|
||||||
/* if this is not an animated GIF, exit after first image */
|
/* if this is not an animated GIF, exit after first image */
|
||||||
if (!m_anim)
|
if (!m_anim)
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup image pointers */
|
/* setup image pointers */
|
||||||
if (m_nimages != 0)
|
if (m_nimages != 0)
|
||||||
{
|
{
|
||||||
m_image = 1;
|
m_image = 1;
|
||||||
m_plast = pimg;
|
m_plast = pimg;
|
||||||
m_pimage = m_pfirst;
|
m_pimage = m_pfirst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try to read to the end of the stream */
|
/* try to read to the end of the stream */
|
||||||
while (type != 0x3B)
|
while (type != 0x3B)
|
||||||
{
|
{
|
||||||
type = (unsigned char)m_f->GetC();
|
type = (unsigned char)m_f->GetC();
|
||||||
|
|
||||||
if (type == 0x21)
|
if (type == 0x21)
|
||||||
{
|
{
|
||||||
/* extension type */
|
/* extension type */
|
||||||
(void) m_f->GetC();
|
(void) m_f->GetC();
|
||||||
|
|
||||||
/* skip all data */
|
/* skip all data */
|
||||||
while ((i = (unsigned char)m_f->GetC()) != 0)
|
while ((i = (unsigned char)m_f->GetC()) != 0)
|
||||||
{
|
{
|
||||||
m_f->SeekI(i, wxFromCurrent);
|
m_f->SeekI(i, wxFromCurrent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == 0x2C)
|
else if (type == 0x2C)
|
||||||
{
|
{
|
||||||
/* image descriptor block */
|
/* image descriptor block */
|
||||||
m_f->Read(buf, 9);
|
m_f->Read(buf, 9);
|
||||||
|
|
||||||
/* local color map */
|
/* local color map */
|
||||||
if ((buf[8] & 0x80) == 0x80)
|
if ((buf[8] & 0x80) == 0x80)
|
||||||
{
|
{
|
||||||
ncolors = 2 << (buf[8] & 0x07);
|
ncolors = 2 << (buf[8] & 0x07);
|
||||||
m_f->SeekI(3 * ncolors, wxFromCurrent);
|
m_f->SeekI(3 * ncolors, wxFromCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initial code size */
|
/* initial code size */
|
||||||
(void) m_f->GetC();
|
(void) m_f->GetC();
|
||||||
|
|
||||||
/* skip all data */
|
/* skip all data */
|
||||||
while ((i = (unsigned char)m_f->GetC()) != 0)
|
while ((i = (unsigned char)m_f->GetC()) != 0)
|
||||||
{
|
{
|
||||||
m_f->SeekI(i, wxFromCurrent);
|
m_f->SeekI(i, wxFromCurrent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((type != 0x3B) && (type != 00)) /* testing */
|
else if ((type != 0x3B) && (type != 00)) /* testing */
|
||||||
{
|
{
|
||||||
/* images are OK, but couldn't read to the end of the stream */
|
/* images are OK, but couldn't read to the end of the stream */
|
||||||
return wxGIF_TRUNCATED;
|
return wxGIF_TRUNCATED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxGIF_OK;
|
return wxGIF_OK;
|
||||||
|
Reference in New Issue
Block a user