X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b59bf2db65896d128d72016c201dc1df9ff6c94e..a28d23bb2c4a5967a11dd4e392aff86275ae8c66:/src/common/imaggif.cpp diff --git a/src/common/imaggif.cpp b/src/common/imaggif.cpp index ddcce30a7f..cae432499b 100644 --- a/src/common/imaggif.cpp +++ b/src/common/imaggif.cpp @@ -33,38 +33,36 @@ FOLLOWING CODE IS BY G.R.G. : */ /************************************************************************ - READGIF.H - Leer un archivo GIF de 8 bits - ------------------------------------------------------------------------ - Tratamiento Digital de la Imagen + READGIF.H - Reads a GIF file ------------------------------------------------------------------------ Guillermo Rodriguez Garcia - Version: 2.0 + Version: 2.1 *************************************************************************/ + typedef struct { int w; /* width */ int h; /* height */ + int transparent; /* transparent color (-1 = none) */ unsigned char *p; /* bitmap */ unsigned char *pal; /* palette */ } IMAGEN; + /************************************************************************ - READGIF.C - Lee un archivo GIF de 256 colores - ------------------------------------------------------------------------ - Tratamiento Digital de la Imagen + READGIF.C - Reads a GIF file ------------------------------------------------------------------------ Guillermo Rodriguez Garcia - Version: 2.0 + Version: 2.1 *************************************************************************/ -#include #include #include @@ -86,43 +84,19 @@ class gifDecoder unsigned int restbyte; /* remaining bytes in this block */ unsigned int lastbyte; /* last byte read */ - unsigned char* file; /* input file in memory */ - unsigned int file_pos, file_size; /* position & size in it */ - - int fgetc(); - void fread(void *ptr, size_t size, size_t nmemb); - void fseekcur(int rel_pos); + wxInputStream *f; /* input file */ - public: - gifDecoder(unsigned char* mem, int sz) {file = mem; file_pos = 0; file_size = sz;} - int getcode(int bits); - int dgif(IMAGEN *img, int interl, int bits); - int readgif(IMAGEN *img); + public: + gifDecoder(wxInputStream *s) { f = s; } + int getcode(int bits); + int dgif(IMAGEN *img, int interl, int bits); + int readgif(IMAGEN *img); }; -int gifDecoder::fgetc() -{ - if (file_pos < file_size) return file[file_pos++]; - else return EOF; -} - -void gifDecoder::fread(void *ptr, size_t size, size_t nmemb) -{ - int todo = size * nmemb; - if (todo + file_pos > file_size) todo = file_size - file_pos; - memcpy(ptr, file + file_pos, todo); - file_pos += todo; -} - -void gifDecoder::fseekcur(int rel_pos) -{ - file_pos += rel_pos; -} /* getcode: * Reads the next code from the file, with size 'bits' - * v2.0 - changed to support 'bits' values < 8 */ int gifDecoder::getcode(int bits) { @@ -134,15 +108,15 @@ int gifDecoder::getcode(int bits) mask = (1 << bits) - 1; code = (lastbyte >> (8 - restbits)) & mask; - /* keep reading new bytes until needed */ + /* keep reading new bytes while needed */ while (bits > restbits) { /* if no bytes left in this block, read the next block */ if (restbyte == 0) - restbyte = fgetc(); + restbyte = (unsigned char)f->GetC(); /* read next byte and isolate the bits we need */ - lastbyte = fgetc(); + lastbyte = (unsigned char)f->GetC(); mask = (1 << (bits - restbits)) - 1; code = code + ((lastbyte & mask) << restbits); restbyte--; @@ -150,13 +124,15 @@ int gifDecoder::getcode(int bits) /* adjust total number of bits extracted from the buffer */ restbits = restbits + 8; } - + /* find number of bits reamining for next code */ restbits = (restbits - bits); return code; } + + /* dgif: * GIF decoding function. The initial code size (aka root size) * is 'bits'. Supports interlaced images (interl == 1). @@ -293,6 +269,8 @@ int gifDecoder::dgif(IMAGEN *img, int interl, int bits) return 0; } + + /* readgif: * Reads a GIF image from the file with filename 'nombre' in the * IMAGEN structure pointed by 'img'. Can read GIFs with any bit @@ -310,7 +288,7 @@ int gifDecoder::readgif(IMAGEN *img) /* read header and logical screen descriptor block (LSDB) */ - fread(buf, 1, 13); + f->Read(buf, 13); /* check GIF signature */ if (memcmp(buf, "GIF", 3) != 0) return E_FORMATO; @@ -319,22 +297,29 @@ int gifDecoder::readgif(IMAGEN *img) if ((buf[10] & 0x80) == 0x80) { ncolors = 2 << (buf[10] & 0x07); - fread(pal, 1, 3 * ncolors); + f->Read(pal, 3 * ncolors); } - /* skip extensions */ - while (fgetc() == 0x21) /* separator */ - { - fgetc(); /* function code */ + /* assume no transparent color */ + img->transparent = -1; - while ((i = fgetc()) != 0) /* byte count */ - fseekcur(i); + /* skip most extensions */ + while (((unsigned char)f->GetC()) == 0x21) /* separator */ + { + if (((unsigned char)f->GetC()) == 0xF9) /* graphic control ext. */ + { + f->Read(buf, 6); + if (buf[1] & 0x01) + img->transparent = buf[4]; + } + else + while ((i = (unsigned char)f->GetC()) != 0) /* byte count */ + f->SeekI(i, wxFromCurrent); } /* read image descriptor block (IDB) */ - fread(buf, 1, 9); + f->Read(buf, 9); img->w = buf[4] + 256 * buf[5]; - img->h = buf[6] + 256 * buf[7]; size = img->w * img->h; interl = ((buf[8] & 0x40)? 1 : 0); @@ -343,11 +328,11 @@ int gifDecoder::readgif(IMAGEN *img) if ((buf[8] & 0x80) == 0x80) { ncolors = 2 << (buf[8] & 0x07); - fread(pal, 1, 3 * ncolors); + f->Read(pal, 3 * ncolors); } /* get initial code size from first byte in raster data */ - bits = fgetc(); + bits = (unsigned char)f->GetC(); /* allocate memory for image and palette */ if ((img->p = (unsigned char*) malloc(size)) == NULL) return E_MEMORIA; @@ -355,7 +340,7 @@ int gifDecoder::readgif(IMAGEN *img) /* shift palette to fit VGA 6-bit format */ 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 */ dgif(img, interl, bits); @@ -364,6 +349,8 @@ int gifDecoder::readgif(IMAGEN *img) return E_OK; } + + /* FOLLOWING CODE IS BY V.S. : @@ -379,26 +366,19 @@ IMPLEMENT_DYNAMIC_CLASS(wxGIFHandler,wxImageHandler) bool wxGIFHandler::LoadFile( wxImage *image, wxInputStream& stream ) { unsigned char *ptr, *src, *pal; - int file_size; - unsigned char* file_con; IMAGEN igif; int i; gifDecoder *decod; image->Destroy(); - file_size = stream.StreamSize(); - file_con = (unsigned char*) malloc(file_size); - stream.Read(file_con, file_size); - decod = new gifDecoder(file_con, file_size); + decod = new gifDecoder(&stream); - if (decod -> readgif(&igif) != E_OK) { - wxLogDebug("Error reading GIF"); - free(file_con); + if (decod->readgif(&igif) != E_OK) { + wxLogDebug(_T("Error reading GIF")); delete decod; return FALSE; } - free(file_con); delete decod; image->Create(igif.w, igif.h); @@ -407,11 +387,21 @@ bool wxGIFHandler::LoadFile( wxImage *image, wxInputStream& stream ) free(igif.p); return FALSE; } - image->SetMask(FALSE); ptr = image->GetData(); src = igif.p; 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++) { *(ptr++) = pal[3 * (*src) + 0]; *(ptr++) = pal[3 * (*src) + 1]; @@ -425,30 +415,12 @@ bool wxGIFHandler::LoadFile( wxImage *image, wxInputStream& stream ) bool wxGIFHandler::SaveFile( wxImage *image, wxOutputStream& stream ) { - wxLogDebug("wxGIFHandler is read-only!!"); + wxLogDebug(_T("wxGIFHandler is read-only!!")); return FALSE; } -//////////////////// Module: - -/* We haven't yet decided to go for the wxModule approach or - * explicit handler-adding: assuming the latter for now -- JACS - -class wxGIFModule : public wxModule -{ - DECLARE_DYNAMIC_CLASS(wxGIFModule) - public: - virtual bool OnInit() - { - wxImage::AddHandler(new wxGIFHandler); - return TRUE; - } - virtual void OnExit() {} -}; -IMPLEMENT_DYNAMIC_CLASS(wxGIFModule, wxModule) -*/