3 * Purpose: GIF Image Class Loader and Writer
\r
5 /* ==========================================================
\r
6 * CxImageGIF (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
\r
7 * For conditions of distribution and use, see copyright notice in ximage.h
\r
9 * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
\r
11 * original CImageGIF and CImageIterator implementation are:
\r
12 * Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
\r
14 * 6/15/97 Randy Spann: Added GIF87a writing support
\r
15 * R.Spann@ConnRiver.net
\r
17 * DECODE.C - An LZW decoder for GIF
\r
18 * Copyright (C) 1987, by Steven A. Bennett
\r
19 * Copyright (C) 1994, C++ version by Alejandro Aguilar Sierra
\r
21 * In accordance with the above, I want to credit Steve Wilhite who wrote
\r
22 * the code which this is heavily inspired by...
\r
24 * GIF and 'Graphics Interchange Format' are trademarks (tm) of
\r
25 * Compuserve, Incorporated, an H&R Block Company.
\r
27 * Release Notes: This file contains a decoder routine for GIF images
\r
28 * which is similar, structurally, to the original routine by Steve Wilhite.
\r
29 * It is, however, somewhat noticably faster in most cases.
\r
31 * ==========================================================
\r
34 #if !defined(__ximaGIF_h)
\r
39 #if CXIMAGE_SUPPORT_GIF
\r
41 typedef short int code_int;
\r
43 /* Various error codes used by decoder */
\r
44 #define OUT_OF_MEMORY -10
\r
45 #define BAD_CODE_SIZE -20
\r
46 #define READ_ERROR -1
\r
47 #define WRITE_ERROR -2
\r
48 #define OPEN_ERROR -3
\r
49 #define CREATE_ERROR -4
\r
50 #define MAX_CODES 4095
\r
51 #define GIFBUFTAM 16383
\r
52 #define TRANSPARENCY_CODE 0xF9
\r
54 //LZW GIF Image compression
\r
55 #define MAXBITSCODES 12
\r
56 #define HSIZE 5003 /* 80% occupancy */
\r
57 #define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)
\r
58 #define HashTabOf(i) htab[i]
\r
59 #define CodeTabOf(i) codetab[i]
\r
62 class CImageIterator;
\r
63 class DLL_EXP CxImageGIF: public CxImage
\r
67 typedef struct tag_gifgce{
\r
68 BYTE flags; /*res:3|dispmeth:3|userinputflag:1|transpcolflag:1*/
\r
70 BYTE transpcolindex;
\r
73 typedef struct tag_dscgif{ /* Logic Screen Descriptor */
\r
74 char header[6]; /* Firma and version */
\r
82 typedef struct tag_image{ /* Image Descriptor */
\r
90 typedef struct tag_TabCol{ /* Tabla de colores */
\r
91 short colres; /* color resolution */
\r
92 short sogct; /* size of global color table */
\r
93 rgb_color paleta[256]; /* paleta */
\r
96 typedef struct tag_RLE{
\r
100 int rl_table_pixel;
\r
109 int out_clear_init;
\r
115 unsigned char oblock[256];
\r
121 CxImageGIF(): CxImage(CXIMAGE_FORMAT_GIF) {m_loops=0; info.dispmeth=0; m_comment[0]='\0';}
\r
123 // bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_GIF);}
\r
124 // bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_GIF);}
\r
126 bool Decode(CxFile * fp);
\r
127 bool Decode(FILE *fp) { CxIOFile file(fp); return Decode(&file); }
\r
129 #if CXIMAGE_SUPPORT_ENCODE
\r
130 bool Encode(CxFile * fp);
\r
131 bool Encode(CxFile * fp, CxImage ** pImages, int pagecount, bool bLocalColorMap = false, bool bLocalDispMeth = false);
\r
132 bool Encode(FILE *fp) { CxIOFile file(fp); return Encode(&file); }
\r
133 bool Encode(FILE *fp, CxImage ** pImages, int pagecount, bool bLocalColorMap = false)
\r
134 { CxIOFile file(fp); return Encode(&file, pImages, pagecount, bLocalColorMap); }
\r
135 #endif // CXIMAGE_SUPPORT_ENCODE
\r
137 void SetLoops(int loops);
\r
139 void SetComment(const char* sz_comment_in);
\r
140 void GetComment(char* sz_comment_out);
\r
143 bool DecodeExtension(CxFile *fp);
\r
144 void EncodeHeader(CxFile *fp);
\r
145 void EncodeLoopExtension(CxFile *fp);
\r
146 void EncodeExtension(CxFile *fp);
\r
147 void EncodeBody(CxFile *fp, bool bLocalColorMap = false);
\r
148 void EncodeComment(CxFile *fp);
\r
149 bool EncodeRGB(CxFile *fp);
\r
150 void GifMix(CxImage & imgsrc2, struct_image & imgdesc);
\r
152 struct_gifgce gifgce;
\r
156 unsigned long cur_accum;
\r
158 int interlaced, iypos, istep, iheight, ipass;
\r
161 BYTE buf[GIFBUFTAM + 1];
\r
163 int GifNextPixel ();
\r
164 void Putword (int w, CxFile* fp );
\r
165 void compressNONE (int init_bits, CxFile* outfile);
\r
166 void compressLZW (int init_bits, CxFile* outfile);
\r
167 void output (code_int code );
\r
168 void cl_hash (long hsize);
\r
169 void char_out (int c);
\r
170 void flush_char ();
\r
171 short init_exp(short size);
\r
172 short get_next_code(CxFile*);
\r
173 short decoder(CxFile*, CImageIterator* iter, short linewidth, int &bad_code_count);
\r
174 int get_byte(CxFile*);
\r
175 int out_line(CImageIterator* iter, unsigned char *pixels, int linelen);
\r
176 int get_num_frames(CxFile *f,struct_TabCol* TabColSrc,struct_dscgif* dscgif);
\r
177 long seek_next_image(CxFile* fp, long position);
\r
179 short curr_size; /* The current code size */
\r
180 short clear; /* Value for a clear code */
\r
181 short ending; /* Value for a ending code */
\r
182 short newcodes; /* First available code */
\r
183 short top_slot; /* Highest code for current size */
\r
184 short slot; /* Last read code */
\r
186 /* The following static variables are used
\r
187 * for seperating out codes */
\r
188 short navail_bytes; /* # bytes left in block */
\r
189 short nbits_left; /* # bits left in current BYTE */
\r
190 BYTE b1; /* Current BYTE */
\r
191 BYTE byte_buff[257]; /* Current block */
\r
192 BYTE *pbytes; /* Pointer to next BYTE in block */
\r
193 /* The reason we have these seperated like this instead of using
\r
194 * a structure like the original Wilhite code did, is because this
\r
195 * stuff generally produces significantly faster code when compiled...
\r
196 * This code is full of similar speedups... (For a good book on writing
\r
197 * C for speed or for space optomisation, see Efficient C by Tom Plum,
\r
198 * published by Plum-Hall Associates...)
\r
200 BYTE stack[MAX_CODES + 1]; /* Stack for storing pixels */
\r
201 BYTE suffix[MAX_CODES + 1]; /* Suffix table */
\r
202 WORD prefix[MAX_CODES + 1]; /* Prefix linked list */
\r
204 //LZW GIF Image compression routines
\r
206 unsigned short codetab [HSIZE];
\r
207 int n_bits; /* number of bits/code */
\r
208 code_int maxcode; /* maximum code, given n_bits */
\r
209 code_int free_ent; /* first unused entry */
\r
219 char m_comment[256];
\r
222 //RLE compression routines
\r
223 void compressRLE( int init_bits, CxFile* outfile);
\r
224 void rle_clear(struct_RLE* rle);
\r
225 void rle_flush(struct_RLE* rle);
\r
226 void rle_flush_withtable(int count, struct_RLE* rle);
\r
227 void rle_flush_clearorrep(int count, struct_RLE* rle);
\r
228 void rle_flush_fromclear(int count,struct_RLE* rle);
\r
229 void rle_output_plain(int c,struct_RLE* rle);
\r
230 void rle_reset_out_clear(struct_RLE* rle);
\r
231 unsigned int rle_compute_triangle_count(unsigned int count, unsigned int nrepcodes);
\r
232 unsigned int rle_isqrt(unsigned int x);
\r
233 void rle_write_block(struct_RLE* rle);
\r
234 void rle_block_out(unsigned char c, struct_RLE* rle);
\r
235 void rle_block_flush(struct_RLE* rle);
\r
236 void rle_output(int val, struct_RLE* rle);
\r
237 void rle_output_flush(struct_RLE* rle);
\r