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