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!!");