- Main Page
- Related Pages
- Namespaces
- Classes
- Files

# trgt_gif.h

Go to the documentation of this file.

    00001 /* === S Y N F I G ========================================================= */
    00025 /* === S T A R T =========================================================== */
    00026
    00027 #ifndef __SYNFIG_TRGT_GIF_H
    00028 #define __SYNFIG_TRGT_GIF_H
    00029
    00030 /* === H E A D E R S ======================================================= */
    00031
    00032 #include <synfig/target_scanline.h>
    00033 #include <synfig/string.h>
    00034 #include <synfig/smartfile.h>
    00035 #include <cstdio>
    00036 #include <synfig/surface.h>
    00037 #include <synfig/palette.h>
    00038
    00039 /* === M A C R O S ========================================================= */
    00040
    00041 /* === T Y P E D E F S ===================================================== */
    00042
    00043 /* === C L A S S E S & S T R U C T S ======================================= */
    00044
    00045 class gif : public synfig::Target_Scanline
    00046 {
    00047     SYNFIG_TARGET_MODULE_EXT
    00048 private:
    00049     // Class for abstracting the
    00050     // output of the codes
    00051     struct bitstream
    00052     {
    00053         synfig::SmartFILE file;
    00054         unsigned char pool;
    00055         char curr_bit;
    00056         bitstream():pool(0),curr_bit(0),curr_pos(0) {}
    00057         bitstream(synfig::SmartFILE file):file(file),pool(0),curr_bit(0),curr_pos(0) {}
    00058         unsigned char buffer[256];
    00059         int curr_pos;
    00060
    00061         // Pushes a single bit onto the bit
    00062         void push_bit(bool bit)
    00063         {
    00064             if(bit)
    00065                 pool|=(1<<(curr_bit));
    00066             curr_bit++;
    00067             if(curr_bit==8)
    00068                 empty();
    00069         }
    00070
    00071         // Empties out the current pool into
    00072         // the buffer. Calls 'dump()' if the
    00073         // buffer is full.
    00074         void empty()
    00075         {
    00076             buffer[curr_pos++]=pool;
    00077             curr_bit=0;
    00078             pool=0;
    00079             if(curr_pos==255)dump();
    00080         }
    00081
    00082         // If there is anything in the
    00083         // buffer or in the pool, it
    00084         // dumps it to the filestream.
    00085         // Buffer and pool are cleared.
    00086         void dump()
    00087         {
    00088             if(curr_bit)
    00089                 empty();
    00090             if(curr_pos || curr_bit)
    00091             {
    00092                 fputc(curr_pos,file.get());
    00093                 fwrite(buffer,curr_pos,1,file.get());
    00094                 curr_pos=0;
    00095             }
    00096         }
    00097
    00098         // Pushes a symbol of the given size
    00099         // onto the bitstream.
    00100         void push_value(int value, int size)
    00101         {
    00102             int i;
    00103             for(i=0;i<size;i++)
    00104                 push_bit((value>>(i))&1);
    00105         }
    00106     };
    00107
    00108     // Class for dealing with the LZW codes
    00109     struct lzwcode
    00110     {
    00111         int value; // the data element or character
    00112         int code; // lzwcode
    00113         struct lzwcode* kids; // children of this node
    00114         struct lzwcode* next; // siblings of this node
    00115
    00116         lzwcode():value(0),code(0),kids(0),next(0) { }
    00117
    00118         lzwcode *FindCode(int value)
    00119         {
    00120             lzwcode *node=this;
    00121
    00122             // check the children (kids) of the node for the value
    00123             for (node = node->kids; node != 0; node = node->next)
    00124                 if (node->value == value)
    00125                     return(node);
    00126             return(0);
    00127         }
    00128
    00129         void AddNode(unsigned short code, unsigned short value)
    00130         {
    00131             lzwcode *n = new lzwcode;
    00132
    00133             // add a new child to node; the child will have code and value
    00134             n->value = value;
    00135             n->code = code;
    00136             n->kids = 0;
    00137             n->next = this->kids;
    00138             this->kids = n;
    00139         }
    00140
    00141         static lzwcode * NewTable(int values)
    00142         {
    00143             int i;
    00144             lzwcode * table = new lzwcode;
    00145
    00146             table->kids = 0;
    00147             for (i = 0; i < values; i++)
    00148                 table->AddNode( i, i);
    00149
    00150             return(table);
    00151         }
    00152
    00153         // Destructor just deletes any
    00154         // children and siblings.
    00155         ~lzwcode()
    00156         {
    00157             if(kids)
    00158                 delete kids;
    00159             if(next)
    00160                 delete next;
    00161         }
    00162     };
    00163
    00164 private:
    00165     bitstream bs;
    00166     synfig::String filename;
    00167     synfig::SmartFILE file;
    00168     int
    00169         i,          // General-purpose index
    00170         codesize,   // Current code size
    00171         rootsize,   // Size of pixel bits (will be recalculated)
    00172         nextcode;   // Next code to use
    00173     lzwcode *table,*next,*node;
    00174
    00175     synfig::Surface curr_surface;
    00176     etl::surface<unsigned char> curr_frame;
    00177     etl::surface<unsigned char> prev_frame;
    00178
    00179     int imagecount;
    00180     int cur_scanline;
    00181
    00182
    00183     // GIF compression parameters
    00184     bool lossy;
    00185     bool multi_image;
    00186     bool dithering;
    00187     int color_bits;
    00188     int iframe_density;
    00189     int loop_count;
    00190     bool local_palette;
    00191
    00192     synfig::Palette curr_palette;
    00193
    00194     void output_curr_palette();
    00195
    00196 public:
    00197     gif(const char *filename);
    00198
    00199     virtual bool set_rend_desc(synfig::RendDesc *desc);
    00200     virtual bool init();
    00201     virtual bool start_frame(synfig::ProgressCallback *cb);
    00202     virtual void end_frame();
    00203
    00204     virtual ~gif();
    00205
    00206     virtual synfig::Color * start_scanline(int scanline);
    00207     virtual bool end_scanline(void);
    00208
    00209 };
    00210
    00211 /* === E N D =============================================================== */
    00212
    00213 #endif