Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_04 / synfig-core / src / modules / mod_gif / trgt_gif.h
1 /*! ========================================================================
2 ** Synfig
3 ** Template Header File
4 ** $Id: trgt_gif.h,v 1.1.1.1 2005/01/04 01:23:10 darco Exp $
5 **
6 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
7 **
8 **      This package is free software; you can redistribute it and/or
9 **      modify it under the terms of the GNU General Public License as
10 **      published by the Free Software Foundation; either version 2 of
11 **      the License, or (at your option) any later version.
12 **
13 **      This package is distributed in the hope that it will be useful,
14 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
15 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 **      General Public License for more details.
17 **
18 ** === N O T E S ===========================================================
19 **
20 ** ========================================================================= */
21
22 /* === S T A R T =========================================================== */
23
24 #ifndef __SYNFIG_TRGT_GIF_H
25 #define __SYNFIG_TRGT_GIF_H
26
27 /* === H E A D E R S ======================================================= */
28
29 #include <synfig/target_scanline.h>
30 #include <synfig/string.h>
31 #include <synfig/smartfile.h>
32 #include <cstdio>
33 #include <synfig/surface.h>
34 #include <synfig/palette.h>
35
36 /* === M A C R O S ========================================================= */
37
38 /* === T Y P E D E F S ===================================================== */
39
40 /* === C L A S S E S & S T R U C T S ======================================= */
41
42 class gif : public synfig::Target_Scanline
43 {
44         SYNFIG_TARGET_MODULE_EXT
45 private:
46         // Class for abstracting the
47         // output of the codes
48         struct bitstream
49         {
50                 synfig::SmartFILE file;
51                 unsigned char pool;
52                 char curr_bit;
53                 bitstream():pool(0),curr_bit(0),curr_pos(0) {}
54                 bitstream(synfig::SmartFILE file):file(file),pool(0),curr_bit(0),curr_pos(0) {}
55                 unsigned char buffer[256];
56                 int curr_pos;
57                 
58                 // Pushes a single bit onto the bit
59                 void push_bit(bool bit)
60                 {
61                         if(bit)
62                                 pool|=(1<<(curr_bit));
63                         curr_bit++;
64                         if(curr_bit==8)
65                                 empty();
66                 }
67                 
68                 // Emptys out the current pool into
69                 // the buffer. Calls 'dump()' if the
70                 // buffer is full.
71                 void empty()
72                 {
73                         buffer[curr_pos++]=pool;
74                         curr_bit=0;
75                         pool=0;
76                         if(curr_pos==255)dump();
77                 }
78                 
79                 // If there is anything in the
80                 // buffer or in the pool, it 
81                 // dumps it to the filestream.
82                 // Buffer and pool are cleared.
83                 void dump()
84                 {
85                         if(curr_bit)
86                                 empty();
87                         if(curr_pos || curr_bit)
88                         {
89                                 fputc(curr_pos,file.get());
90                                 fwrite(buffer,curr_pos,1,file.get());
91                                 curr_pos=0;
92                         }
93                 }
94                 
95                 // Pushes a symbol of the given size
96                 // onto the bitstream.
97                 void push_value(int value, int size)
98                 {
99                         int i;
100                         for(i=0;i<size;i++)
101                                 push_bit((value>>(i))&1);
102                 }
103         };
104
105         // Class for dealing with the LZW codes
106         struct lzwcode
107         {
108                 int value; // the data element or character
109                 int code; // lzwcode
110                 struct lzwcode* kids; // children of this node
111                 struct lzwcode* next; // siblings of this node
112                 
113                 lzwcode():value(0),code(0),kids(0),next(0) { }
114                 
115                 lzwcode *FindCode(int value)
116                 {
117                         lzwcode *node=this;
118                         
119                         // check the children (kids) of the node for the value
120                         for (node = node->kids; node != 0; node = node->next)
121                                 if (node->value == value)
122                                         return(node);
123                         return(0);
124                 }
125         
126                 void AddNode(unsigned short code, unsigned short value)
127                 {
128                         lzwcode *n = new lzwcode;
129                 
130                         // add a new child to node; the child will have code and value
131                         n->value = value;
132                         n->code = code;
133                         n->kids = 0;
134                         n->next = this->kids;
135                         this->kids = n;
136                 }
137                 
138                 static lzwcode * NewTable(int values)
139                 {
140                         int i;
141                         lzwcode * table = new lzwcode;
142                 
143                         table->kids = 0;
144                         for (i = 0; i < values; i++)
145                                 table->AddNode( i, i);
146                 
147                         return(table);
148                 }
149                 
150                 // Destructor just deletes any
151                 // children and sibblings.
152                 ~lzwcode()
153                 {
154                         if(kids)
155                                 delete kids;
156                         if(next)
157                                 delete next;
158                 }
159         };
160
161 private:
162         bitstream bs;
163         synfig::String filename;
164         synfig::SmartFILE file;
165         int 
166                 i,                      // General-purpose index
167                 codesize,       // Current code size
168                 rootsize,       // Size of pixel bits (will be recalculted)
169                 nextcode;       // Next code to use
170         lzwcode *table,*next,*node;
171         
172         synfig::Surface curr_surface;
173         etl::surface<unsigned char> curr_frame;
174         etl::surface<unsigned char> prev_frame;
175
176         int imagecount;
177         int cur_scanline;
178
179
180         // GIF compression parameters
181         bool lossy;
182         bool multi_image;
183         bool dithering;
184         int color_bits;
185         int iframe_density;
186         int loop_count;
187         bool local_palette;
188         
189         synfig::Palette curr_palette;
190         
191         void output_curr_palette();
192         
193 public:
194         gif(const char *filename);
195
196         virtual bool set_rend_desc(synfig::RendDesc *desc);
197         virtual bool init();
198         virtual bool start_frame(synfig::ProgressCallback *cb);
199         virtual void end_frame();
200
201         virtual ~gif();
202         
203         virtual synfig::Color * start_scanline(int scanline);
204         virtual bool end_scanline(void);
205
206 };
207
208 /* === E N D =============================================================== */
209
210 #endif