fixed transparency
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2152 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -33,9 +33,7 @@ FOLLOWING CODE IS BY G.R.G. :
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
READGIF.H - Leer un archivo GIF de 8 bits
|
READGIF.H - Reads a GIF file
|
||||||
------------------------------------------------------------------------
|
|
||||||
Tratamiento Digital de la Imagen
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
Guillermo Rodriguez Garcia
|
Guillermo Rodriguez Garcia
|
||||||
<guille@iies.es>
|
<guille@iies.es>
|
||||||
@@ -43,6 +41,7 @@ FOLLOWING CODE IS BY G.R.G. :
|
|||||||
Version: 2.1
|
Version: 2.1
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int w; /* width */
|
int w; /* width */
|
||||||
@@ -53,10 +52,9 @@ typedef struct
|
|||||||
} IMAGEN;
|
} IMAGEN;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
READGIF.C - Lee un archivo GIF de 256 colores
|
READGIF.C - Reads a GIF file
|
||||||
------------------------------------------------------------------------
|
|
||||||
Tratamiento Digital de la Imagen
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
Guillermo Rodriguez Garcia
|
Guillermo Rodriguez Garcia
|
||||||
<guille@iies.es>
|
<guille@iies.es>
|
||||||
@@ -88,30 +86,17 @@ class gifDecoder
|
|||||||
|
|
||||||
wxInputStream *f; /* input file */
|
wxInputStream *f; /* input file */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
gifDecoder(wxInputStream *s) {f = s;}
|
gifDecoder(wxInputStream *s) { f = s; }
|
||||||
int getcode(int bits);
|
int getcode(int bits);
|
||||||
int dgif(IMAGEN *img, int interl, int bits);
|
int dgif(IMAGEN *img, int interl, int bits);
|
||||||
int readgif(IMAGEN *img);
|
int readgif(IMAGEN *img);
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned char mygetc();
|
|
||||||
// This is NEEDED! GetC is char (signed) why we need unsigned value
|
|
||||||
// from here
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
unsigned char gifDecoder::mygetc()
|
|
||||||
{
|
|
||||||
unsigned char c;
|
|
||||||
f -> Read(&c, 1);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* getcode:
|
/* getcode:
|
||||||
* Reads the next code from the file, with size 'bits'
|
* Reads the next code from the file, with size 'bits'
|
||||||
* v2.0 - changed to support 'bits' values < 8
|
|
||||||
*/
|
*/
|
||||||
int gifDecoder::getcode(int bits)
|
int gifDecoder::getcode(int bits)
|
||||||
{
|
{
|
||||||
@@ -123,15 +108,15 @@ int gifDecoder::getcode(int bits)
|
|||||||
mask = (1 << bits) - 1;
|
mask = (1 << bits) - 1;
|
||||||
code = (lastbyte >> (8 - restbits)) & mask;
|
code = (lastbyte >> (8 - restbits)) & mask;
|
||||||
|
|
||||||
/* keep reading new bytes until needed */
|
/* keep reading new bytes while needed */
|
||||||
while (bits > restbits)
|
while (bits > restbits)
|
||||||
{
|
{
|
||||||
/* if no bytes left in this block, read the next block */
|
/* if no bytes left in this block, read the next block */
|
||||||
if (restbyte == 0)
|
if (restbyte == 0)
|
||||||
restbyte = mygetc();
|
restbyte = (unsigned char)f->GetC();
|
||||||
|
|
||||||
/* read next byte and isolate the bits we need */
|
/* read next byte and isolate the bits we need */
|
||||||
lastbyte = mygetc();
|
lastbyte = (unsigned char)f->GetC();
|
||||||
mask = (1 << (bits - restbits)) - 1;
|
mask = (1 << (bits - restbits)) - 1;
|
||||||
code = code + ((lastbyte & mask) << restbits);
|
code = code + ((lastbyte & mask) << restbits);
|
||||||
restbyte--;
|
restbyte--;
|
||||||
@@ -139,7 +124,7 @@ int gifDecoder::getcode(int bits)
|
|||||||
/* adjust total number of bits extracted from the buffer */
|
/* adjust total number of bits extracted from the buffer */
|
||||||
restbits = restbits + 8;
|
restbits = restbits + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find number of bits reamining for next code */
|
/* find number of bits reamining for next code */
|
||||||
restbits = (restbits - bits);
|
restbits = (restbits - bits);
|
||||||
|
|
||||||
@@ -147,6 +132,7 @@ int gifDecoder::getcode(int bits)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* dgif:
|
/* dgif:
|
||||||
* GIF decoding function. The initial code size (aka root size)
|
* GIF decoding function. The initial code size (aka root size)
|
||||||
* is 'bits'. Supports interlaced images (interl == 1).
|
* is 'bits'. Supports interlaced images (interl == 1).
|
||||||
@@ -283,6 +269,8 @@ int gifDecoder::dgif(IMAGEN *img, int interl, int bits)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* readgif:
|
/* readgif:
|
||||||
* Reads a GIF image from the file with filename 'nombre' in the
|
* Reads a GIF image from the file with filename 'nombre' in the
|
||||||
* IMAGEN structure pointed by 'img'. Can read GIFs with any bit
|
* IMAGEN structure pointed by 'img'. Can read GIFs with any bit
|
||||||
@@ -298,8 +286,9 @@ int gifDecoder::readgif(IMAGEN *img)
|
|||||||
unsigned char pal[768];
|
unsigned char pal[768];
|
||||||
unsigned char buf[16];
|
unsigned char buf[16];
|
||||||
|
|
||||||
|
|
||||||
/* read header and logical screen descriptor block (LSDB) */
|
/* read header and logical screen descriptor block (LSDB) */
|
||||||
f -> Read(buf, 13);
|
f->Read(buf, 13);
|
||||||
|
|
||||||
/* check GIF signature */
|
/* check GIF signature */
|
||||||
if (memcmp(buf, "GIF", 3) != 0) return E_FORMATO;
|
if (memcmp(buf, "GIF", 3) != 0) return E_FORMATO;
|
||||||
@@ -308,35 +297,29 @@ int gifDecoder::readgif(IMAGEN *img)
|
|||||||
if ((buf[10] & 0x80) == 0x80)
|
if ((buf[10] & 0x80) == 0x80)
|
||||||
{
|
{
|
||||||
ncolors = 2 << (buf[10] & 0x07);
|
ncolors = 2 << (buf[10] & 0x07);
|
||||||
f -> Read(pal, 3 * ncolors);
|
f->Read(pal, 3 * ncolors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assume no transparent color */
|
/* assume no transparent color */
|
||||||
img->transparent = -1;
|
img->transparent = -1;
|
||||||
|
|
||||||
/* skip most extensions */
|
/* skip most extensions */
|
||||||
while (mygetc() == 0x21) /* separator */
|
while (((unsigned char)f->GetC()) == 0x21) /* separator */
|
||||||
{
|
{
|
||||||
wxLogDebug(_T("ugh"));
|
if (((unsigned char)f->GetC()) == 0xF9) /* graphic control ext. */
|
||||||
if (mygetc() == 0xF9) /* graphic control ext. */
|
|
||||||
{
|
{
|
||||||
wxLogDebug(_T("..."));
|
|
||||||
f->Read(buf, 6);
|
f->Read(buf, 6);
|
||||||
wxLogDebug(_T("buf[1] is %i (%i)"), buf[1], buf[1] & 0x01);
|
if (buf[1] & 0x01)
|
||||||
if (buf[1] & 0x01) {
|
|
||||||
wxLogDebug(_T("setting transparen %i"), buf[4]);
|
|
||||||
img->transparent = buf[4];
|
img->transparent = buf[4];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
while ((i = mygetc()) != 0) /* byte count */
|
while ((i = (unsigned char)f->GetC()) != 0) /* byte count */
|
||||||
f->SeekI(i, wxFromCurrent);
|
f->SeekI(i, wxFromCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read image descriptor block (IDB) */
|
/* read image descriptor block (IDB) */
|
||||||
f -> Read(buf, 9);
|
f->Read(buf, 9);
|
||||||
img->w = buf[4] + 256 * buf[5];
|
img->w = buf[4] + 256 * buf[5];
|
||||||
|
|
||||||
img->h = buf[6] + 256 * buf[7];
|
img->h = buf[6] + 256 * buf[7];
|
||||||
size = img->w * img->h;
|
size = img->w * img->h;
|
||||||
interl = ((buf[8] & 0x40)? 1 : 0);
|
interl = ((buf[8] & 0x40)? 1 : 0);
|
||||||
@@ -345,11 +328,11 @@ int gifDecoder::readgif(IMAGEN *img)
|
|||||||
if ((buf[8] & 0x80) == 0x80)
|
if ((buf[8] & 0x80) == 0x80)
|
||||||
{
|
{
|
||||||
ncolors = 2 << (buf[8] & 0x07);
|
ncolors = 2 << (buf[8] & 0x07);
|
||||||
f -> Read(pal, 3 * ncolors);
|
f->Read(pal, 3 * ncolors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get initial code size from first byte in raster data */
|
/* get initial code size from first byte in raster data */
|
||||||
bits = mygetc();
|
bits = (unsigned char)f->GetC();
|
||||||
|
|
||||||
/* allocate memory for image and palette */
|
/* allocate memory for image and palette */
|
||||||
if ((img->p = (unsigned char*) malloc(size)) == NULL) return E_MEMORIA;
|
if ((img->p = (unsigned char*) malloc(size)) == NULL) return E_MEMORIA;
|
||||||
@@ -357,7 +340,7 @@ int gifDecoder::readgif(IMAGEN *img)
|
|||||||
|
|
||||||
/* shift palette to fit VGA 6-bit format */
|
/* shift palette to fit VGA 6-bit format */
|
||||||
for (i = 0; i < 768; i++)
|
for (i = 0; i < 768; i++)
|
||||||
(img->pal)[i] = (unsigned char)pal[i] /* >> 2 not needed under wxWin */;
|
(img->pal)[i] = (unsigned char)pal[i]; /* >> 2 not in wxWin */
|
||||||
|
|
||||||
/* decode GIF */
|
/* decode GIF */
|
||||||
dgif(img, interl, bits);
|
dgif(img, interl, bits);
|
||||||
@@ -366,6 +349,8 @@ int gifDecoder::readgif(IMAGEN *img)
|
|||||||
return E_OK;
|
return E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
FOLLOWING CODE IS BY V.S. :
|
FOLLOWING CODE IS BY V.S. :
|
||||||
@@ -389,8 +374,8 @@ bool wxGIFHandler::LoadFile( wxImage *image, wxInputStream& stream )
|
|||||||
|
|
||||||
decod = new gifDecoder(&stream);
|
decod = new gifDecoder(&stream);
|
||||||
|
|
||||||
if (decod -> readgif(&igif) != E_OK) {
|
if (decod->readgif(&igif) != E_OK) {
|
||||||
wxLogDebug(_T("Error reading GIF"));
|
wxLogDebug("Error reading GIF");
|
||||||
delete decod;
|
delete decod;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -402,24 +387,27 @@ bool wxGIFHandler::LoadFile( wxImage *image, wxInputStream& stream )
|
|||||||
free(igif.p);
|
free(igif.p);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
image->SetMask(FALSE);
|
|
||||||
|
|
||||||
ptr = image->GetData();
|
ptr = image->GetData();
|
||||||
src = igif.p;
|
src = igif.p;
|
||||||
pal = igif.pal;
|
pal = igif.pal;
|
||||||
|
|
||||||
|
if (igif.transparent != -1) {
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
if ((pal[3 * i + 0] == 255) && (pal[3 * i + 1] == 0) && (pal[3 * i + 2] == 255)) pal[3 * i + 2] = 254;
|
||||||
|
pal[3 * (igif.transparent) + 0] = 255,
|
||||||
|
pal[3 * (igif.transparent) + 1] = 0,
|
||||||
|
pal[3 * (igif.transparent) + 2] = 255;
|
||||||
|
image->SetMaskColour(255, 0, 255);
|
||||||
|
}
|
||||||
|
else image->SetMask(FALSE);
|
||||||
|
|
||||||
for (i = 0; i < igif.w * igif.h; i++, src++) {
|
for (i = 0; i < igif.w * igif.h; i++, src++) {
|
||||||
*(ptr++) = pal[3 * (*src) + 0];
|
*(ptr++) = pal[3 * (*src) + 0];
|
||||||
*(ptr++) = pal[3 * (*src) + 1];
|
*(ptr++) = pal[3 * (*src) + 1];
|
||||||
*(ptr++) = pal[3 * (*src) + 2];
|
*(ptr++) = pal[3 * (*src) + 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (igif.transparent != -1) {
|
|
||||||
wxLogDebug(_T("oko"));
|
|
||||||
image->SetMaskColour(pal[3 * (igif.transparent) + 0], pal[3 * (igif.transparent) + 0], pal[3 * (igif.transparent) + 0]);
|
|
||||||
image->SetMask(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxLogDebug(_T("(unsigned int)%i"), (unsigned int)-1);
|
|
||||||
free(igif.pal);
|
free(igif.pal);
|
||||||
free(igif.p);
|
free(igif.p);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -427,7 +415,7 @@ bool wxGIFHandler::LoadFile( wxImage *image, wxInputStream& stream )
|
|||||||
|
|
||||||
bool wxGIFHandler::SaveFile( wxImage *image, wxOutputStream& stream )
|
bool wxGIFHandler::SaveFile( wxImage *image, wxOutputStream& stream )
|
||||||
{
|
{
|
||||||
wxLogDebug(_T("wxGIFHandler is read-only!!"));
|
wxLogDebug("wxGIFHandler is read-only!!");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,4 +424,3 @@ bool wxGIFHandler::SaveFile( wxImage *image, wxOutputStream& stream )
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user