]>
git.saurik.com Git - wxWidgets.git/blob - src/common/imaggif.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxGIFHandler 
   4 // Author:      Guillermo Rodriguez Garcia 
   5 //              wxWindows adaptation by Vaclav Slavik 
   6 // Licence:     wxWindows licence 
   7 ///////////////////////////////////////////////////////////////////////////// 
  10 #pragma implementation "imaggif.h" 
  13 // For compilers that support precompilation, includes "wx.h". 
  14 #include <wx/wxprec.h> 
  23 #include <wx/wfstream.h> 
  24 #include <wx/module.h> 
  26 #include <wx/imaggif.h> 
  30 FOLLOWING CODE IS BY G.R.G. : 
  31 (except wxInputStream stuff) 
  35 /************************************************************************ 
  36   READGIF.H - Leer un archivo GIF de 8 bits 
  37  ------------------------------------------------------------------------ 
  38   Tratamiento Digital de la Imagen 
  39  ------------------------------------------------------------------------ 
  40   Guillermo Rodriguez Garcia 
  44 *************************************************************************/ 
  50     unsigned char *p
;       /* bitmap */ 
  51     unsigned char *pal
;     /* palette */ 
  55 /************************************************************************ 
  56   READGIF.C - Lee un archivo GIF de 256 colores 
  57  ------------------------------------------------------------------------ 
  58   Tratamiento Digital de la Imagen 
  59  ------------------------------------------------------------------------ 
  60   Guillermo Rodriguez Garcia 
  64 *************************************************************************/ 
  72 #define E_OK        0               /* everything was OK */ 
  73 #define E_ARCHIVO   -1              /* error opening file */ 
  74 #define E_FORMATO   -2              /* error in gif header */ 
  75 #define E_MEMORIA   -3              /* error allocating memory */ 
  78 /* This class binding is by VS, so all bugs in it are mine ;-) */ 
  84         int            restbits
;            /* remaining valid bits */ 
  85         unsigned int   restbyte
;            /* remaining bytes in this block */ 
  86         unsigned int   lastbyte
;            /* last byte read */ 
  88         wxInputStream  
*f
;                  /* input file */ 
  91         gifDecoder(wxInputStream 
*s
) {f 
= s
;} 
  92         int getcode(int bits
); 
  93         int dgif(IMAGEN 
*img
, int interl
, int bits
); 
  94         int readgif(IMAGEN 
*img
); 
  97         int mygetc() {return (unsigned char)f 
-> GetC();} 
  98            // This is NEEDED! GetC is char (signed) why we need unsigned value 
 105  *  Reads the next code from the file, with size 'bits' 
 106  *  v2.0 - changed to support 'bits' values < 8 
 108 int gifDecoder::getcode(int bits
) 
 110     unsigned int    mask
;           /* bit mask */ 
 111     unsigned int    code
;           /* code (result) */ 
 114     /* get remaining bits from last byte read */ 
 115     mask 
= (1 << bits
) - 1; 
 116     code 
= (lastbyte 
>> (8 - restbits
)) & mask
; 
 118     /* keep reading new bytes until needed */ 
 119     while (bits 
> restbits
) 
 121         /* if no bytes left in this block, read the next block */ 
 125         /* read next byte and isolate the bits we need */ 
 127         mask     
= (1 << (bits 
- restbits
)) - 1; 
 128         code     
= code 
+ ((lastbyte 
& mask
) << restbits
); 
 131         /* adjust total number of bits extracted from the buffer */ 
 132         restbits 
= restbits 
+ 8; 
 135     /* find number of bits reamining for next code */ 
 136     restbits 
= (restbits 
- bits
); 
 143  *  GIF decoding function. The initial code size (aka root size) 
 144  *  is 'bits'. Supports interlaced images (interl == 1). 
 146 int gifDecoder::dgif(IMAGEN 
*img
, int interl
, int bits
) 
 148     int ab_prefix
[4096];        /* alphabet (prefixes) */ 
 149     int ab_tail
[4096];          /* alphabet (tails) */ 
 150     int stack
[4096];            /* decompression stack */ 
 152     int ab_clr
;                 /* clear code */ 
 153     int ab_fin
;                 /* end of info code */ 
 154     int ab_bits
;                /* actual symbol width, in bits */ 
 155     int ab_free
;                /* first free position in alphabet */ 
 156     int ab_max
;                 /* last possible character in alphabet */ 
 157     int pass
;                   /* pass number in interlaced images */ 
 158     int pos
;                    /* index into decompresion stack */ 
 159     int x
, y
;                   /* position in image buffer */ 
 161     int code
, readcode
, lastcode
, abcabca
; 
 163     /* these won't change */ 
 164     ab_clr  
= (1 << bits
); 
 165     ab_fin  
= (1 << bits
) + 1; 
 167     /* these will change through the decompression proccess */ 
 169     ab_free  
= (1 << bits
) + 2; 
 170     ab_max   
= (1 << ab_bits
) - 1; 
 176     /* reset static globals */ 
 184         readcode 
= code 
= getcode(ab_bits
); 
 187         if (code 
== ab_fin
) break; 
 189         /* reset alphabet? */ 
 192             /* reset main variables */ 
 194             ab_free  
= (1 << bits
) + 2; 
 195             ab_max   
= (1 << ab_bits
) - 1; 
 199             /* skip to next code */ 
 203         /* unknown code: special case (like in ABCABCA) */ 
 206             code 
= lastcode
;            /* take last string */ 
 207             stack
[pos
++] = abcabca
;     /* add first character */ 
 210         /* build the string for this code in the stack */ 
 211         while (code 
> ab_clr
) 
 213             stack
[pos
++] = ab_tail
[code
]; 
 214             code         
= ab_prefix
[code
]; 
 216         stack
[pos
] = code
;              /* push last code into the stack */ 
 217         abcabca    
= code
;              /* save for special case */ 
 219         /* make new entry in alphabet (only if NOT just cleared) */ 
 222             ab_prefix
[ab_free
] = lastcode
; 
 223             ab_tail
[ab_free
]   = code
; 
 226             if ((ab_free 
> ab_max
) && (ab_bits 
< 12)) 
 229                 ab_max 
= (1 << ab_bits
) - 1; 
 233         /* dump stack data to the buffer */ 
 236             (img
->p
)[x 
+ (y 
* (img
->w
))] = (char)stack
[pos
--]; 
 244                     /* support for interlaced images */ 
 247                         case 1: y 
+= 8; break; 
 248                         case 2: y 
+= 8; break; 
 249                         case 3: y 
+= 4; break; 
 250                         case 4: y 
+= 2; break; 
 256                             case 2: y 
= 4; break; 
 257                             case 3: y 
= 2; break; 
 258                             case 4: y 
= 1; break; 
 273     while (code 
!= ab_fin
); 
 279  *  Reads a GIF image from the file with filename 'nombre' in the 
 280  *  IMAGEN structure pointed by 'img'. Can read GIFs with any bit 
 281  *  size (color depth), but the output image is always expanded 
 282  *  to 8 bits per pixel. Also, the image palette always contains 
 283  *  256 colors, although some of them may be unused. Returns E_OK 
 284  *  (== 0) on success, or an error code if something fails. Error 
 285  *  codes are E_ARCHIVO, E_FORMATO, E_MEMORIA (see above). 
 287 int gifDecoder::readgif(IMAGEN 
*img
) 
 289     int             size
, ncolors
, bits
, interl
, i
; 
 290     unsigned char   pal
[768]; 
 291     unsigned char   buf
[16]; 
 293     /* read header and logical screen descriptor block (LSDB) */ 
 296     /* check GIF signature */ 
 297     if (memcmp(buf
, "GIF", 3) != 0) return E_FORMATO
; 
 299     /* load global color map if available */ 
 300     if ((buf
[10] & 0x80) == 0x80) 
 302         ncolors 
= 2 << (buf
[10] & 0x07); 
 303         f 
-> Read(pal
, 3 * ncolors
); 
 306     /* skip extensions */ 
 307     while (mygetc() == 0x21)            /* separator */ 
 309         mygetc();                       /* function code */ 
 311         while ((i 
= mygetc()) != 0)      /* byte count */ 
 312             f 
-> SeekI(i
, wxFromCurrent
); 
 315     /* read image descriptor block (IDB) */ 
 317     img
->w 
= buf
[4] + 256 * buf
[5]; 
 319     img
->h 
= buf
[6] + 256 * buf
[7]; 
 320     size   
= img
->w 
* img
->h
; 
 321     interl 
= ((buf
[8] & 0x40)? 1 : 0); 
 323     /* load local color map if available */ 
 324     if ((buf
[8] & 0x80) == 0x80) 
 326         ncolors 
= 2 << (buf
[8] & 0x07); 
 327         f 
-> Read(pal
, 3 * ncolors
); 
 330     /* get initial code size from first byte in raster data */ 
 333     /* allocate memory for image and palette */ 
 334     if ((img
->p   
= (unsigned char*) malloc(size
)) == NULL
) return E_MEMORIA
; 
 335     if ((img
->pal 
= (unsigned char*) malloc(768))  == NULL
) return E_MEMORIA
; 
 337     /* shift palette to fit VGA 6-bit format */ 
 338     for (i 
= 0; i 
< 768; i
++) 
 339         (img
->pal
)[i
] = (unsigned char)pal
[i
] /* >> 2 not needed under wxWin */; 
 342     dgif(img
, interl
, bits
); 
 344     /* finish successfully :-) */ 
 350 FOLLOWING CODE IS BY V.S. : 
 354 //----------------------------------------------------------------------------- 
 356 //----------------------------------------------------------------------------- 
 358 IMPLEMENT_DYNAMIC_CLASS(wxGIFHandler
,wxImageHandler
) 
 360 bool wxGIFHandler::LoadFile( wxImage 
*image
, wxInputStream
& stream 
) 
 362     unsigned char *ptr
, *src
, *pal
; 
 369     decod 
= new gifDecoder(&stream
); 
 371     if (decod 
-> readgif(&igif
) != E_OK
) { 
 372         wxLogDebug("Error reading GIF"); 
 378     image
->Create(igif
.w
, igif
.h
); 
 384     image
->SetMask(FALSE
); 
 386     ptr 
= image
->GetData(); 
 389     for (i 
= 0; i 
< igif
.w 
* igif
.h
; i
++, src
++) { 
 390         *(ptr
++) = pal
[3 * (*src
) + 0]; 
 391         *(ptr
++) = pal
[3 * (*src
) + 1]; 
 392         *(ptr
++) = pal
[3 * (*src
) + 2]; 
 400 bool wxGIFHandler::SaveFile( wxImage 
*image
, wxOutputStream
& stream 
) 
 402     wxLogDebug("wxGIFHandler is read-only!!");