]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/imaggif.cpp
don't log empty status messages in wxLogWindow
[wxWidgets.git] / src / common / imaggif.cpp
index 887e94e9242470a30fbf9161d08663e0c430898c..cae432499b8d68dcdf41d99ed3034f3fb4da57cc 100644 (file)
@@ -33,34 +33,33 @@ 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
   <guille@iies.es>
 
-  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
   <guille@iies.es>
 
-  Version: 2.0
+  Version: 2.1
 *************************************************************************/
 
 
@@ -87,23 +86,17 @@ class gifDecoder
 
         wxInputStream  *f;                  /* input file */
 
-    public:
-        gifDecoder(wxInputStream *s) {f = s;}
-        int getcode(int bits);
-        int dgif(IMAGEN *img, int interl, int bits);
-        int readgif(IMAGEN *img);
-       
-    private:
-        int mygetc() {return (unsigned char)f -> GetC();}
-          // This is NEEDED! GetC is char (signed) why we need unsigned value
-          // from here
+       public:
+               gifDecoder(wxInputStream *s) { f = s; }
+               int getcode(int bits);
+               int dgif(IMAGEN *img, int interl, int bits);
+               int readgif(IMAGEN *img);
 };
 
 
 
 /* getcode:
  *  Reads the next code from the file, with size 'bits'
- *  v2.0 - changed to support 'bits' values < 8
  */
 int gifDecoder::getcode(int bits)
 {
@@ -115,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 = mygetc();
+            restbyte = (unsigned char)f->GetC();
 
         /* read next byte and isolate the bits we need */
-        lastbyte = mygetc();
+        lastbyte = (unsigned char)f->GetC();
         mask     = (1 << (bits - restbits)) - 1;
         code     = code + ((lastbyte & mask) << restbits);
         restbyte--;
@@ -131,7 +124,7 @@ 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);
 
@@ -139,6 +132,7 @@ int gifDecoder::getcode(int bits)
 }
 
 
+
 /* dgif:
  *  GIF decoding function. The initial code size (aka root size)
  *  is 'bits'. Supports interlaced images (interl == 1).
@@ -275,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
@@ -290,8 +286,9 @@ int gifDecoder::readgif(IMAGEN *img)
     unsigned char   pal[768];
     unsigned char   buf[16];
 
+
     /* read header and logical screen descriptor block (LSDB) */
-    f -> Read(buf, 13);
+    f->Read(buf, 13);
 
     /* check GIF signature */
     if (memcmp(buf, "GIF", 3) != 0) return E_FORMATO;
@@ -300,22 +297,29 @@ int gifDecoder::readgif(IMAGEN *img)
     if ((buf[10] & 0x80) == 0x80)
     {
         ncolors = 2 << (buf[10] & 0x07);
-        f -> Read(pal, 3 * ncolors);
+        f->Read(pal, 3 * ncolors);
     }
 
-    /* skip extensions */
-    while (mygetc() == 0x21)            /* separator */
-    {
-        mygetc();                       /* function code */
+    /* assume no transparent color */
+    img->transparent = -1;
 
-        while ((i = mygetc()) != 0)      /* byte count */
-            f -> SeekI(i, wxFromCurrent);
+    /* 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) */
-    f -> Read(buf, 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);
@@ -324,11 +328,11 @@ int gifDecoder::readgif(IMAGEN *img)
     if ((buf[8] & 0x80) == 0x80)
     {
         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 */
-    bits = mygetc();
+    bits = (unsigned char)f->GetC();
 
     /* allocate memory for image and palette */
     if ((img->p   = (unsigned char*) malloc(size)) == NULL) return E_MEMORIA;
@@ -336,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);
@@ -345,6 +349,8 @@ int gifDecoder::readgif(IMAGEN *img)
     return E_OK;
 }
 
+
+
 /*
 
 FOLLOWING CODE IS BY V.S. :
@@ -368,8 +374,8 @@ bool wxGIFHandler::LoadFile( wxImage *image, wxInputStream& stream )
 
     decod = new gifDecoder(&stream);
 
-    if (decod -> readgif(&igif) != E_OK) {
-        wxLogDebug("Error reading GIF");
+    if (decod->readgif(&igif) != E_OK) {
+        wxLogDebug(_T("Error reading GIF"));
         delete decod;
         return FALSE;
     }
@@ -381,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];
@@ -399,8 +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;
 }
 
 
+
+
+
+