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