X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftags%2Fsynfig_0_61_07_rc1%2Fsrc%2Fmodules%2Fmod_gif%2Ftrgt_gif.h;fp=synfig-core%2Ftags%2Fsynfig_0_61_07_rc1%2Fsrc%2Fmodules%2Fmod_gif%2Ftrgt_gif.h;h=d2359e609914982ad886cb6263439e3cf1daced5;hb=7d32b486bfe48032fdb52fbb3b6f144a6ce7e63e;hp=0000000000000000000000000000000000000000;hpb=e46234d7b452318bb265f47ba85f2a5226f9657a;p=synfig.git diff --git a/synfig-core/tags/synfig_0_61_07_rc1/src/modules/mod_gif/trgt_gif.h b/synfig-core/tags/synfig_0_61_07_rc1/src/modules/mod_gif/trgt_gif.h new file mode 100644 index 0000000..d2359e6 --- /dev/null +++ b/synfig-core/tags/synfig_0_61_07_rc1/src/modules/mod_gif/trgt_gif.h @@ -0,0 +1,213 @@ +/* === S Y N F I G ========================================================= */ +/*! \file trgt_gif.h +** \brief Template Header +** +** $Id$ +** +** \legal +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** +** This package is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License as +** published by the Free Software Foundation; either version 2 of +** the License, or (at your option) any later version. +** +** This package is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** \endlegal +** +** === N O T E S =========================================================== +** +** ========================================================================= */ + +/* === S T A R T =========================================================== */ + +#ifndef __SYNFIG_TRGT_GIF_H +#define __SYNFIG_TRGT_GIF_H + +/* === H E A D E R S ======================================================= */ + +#include +#include +#include +#include +#include +#include + +/* === M A C R O S ========================================================= */ + +/* === T Y P E D E F S ===================================================== */ + +/* === C L A S S E S & S T R U C T S ======================================= */ + +class gif : public synfig::Target_Scanline +{ + SYNFIG_TARGET_MODULE_EXT +private: + // Class for abstracting the + // output of the codes + struct bitstream + { + synfig::SmartFILE file; + unsigned char pool; + char curr_bit; + bitstream():pool(0),curr_bit(0),curr_pos(0) {} + bitstream(synfig::SmartFILE file):file(file),pool(0),curr_bit(0),curr_pos(0) {} + unsigned char buffer[256]; + int curr_pos; + + // Pushes a single bit onto the bit + void push_bit(bool bit) + { + if(bit) + pool|=(1<<(curr_bit)); + curr_bit++; + if(curr_bit==8) + empty(); + } + + // Emptys out the current pool into + // the buffer. Calls 'dump()' if the + // buffer is full. + void empty() + { + buffer[curr_pos++]=pool; + curr_bit=0; + pool=0; + if(curr_pos==255)dump(); + } + + // If there is anything in the + // buffer or in the pool, it + // dumps it to the filestream. + // Buffer and pool are cleared. + void dump() + { + if(curr_bit) + empty(); + if(curr_pos || curr_bit) + { + fputc(curr_pos,file.get()); + fwrite(buffer,curr_pos,1,file.get()); + curr_pos=0; + } + } + + // Pushes a symbol of the given size + // onto the bitstream. + void push_value(int value, int size) + { + int i; + for(i=0;i>(i))&1); + } + }; + + // Class for dealing with the LZW codes + struct lzwcode + { + int value; // the data element or character + int code; // lzwcode + struct lzwcode* kids; // children of this node + struct lzwcode* next; // siblings of this node + + lzwcode():value(0),code(0),kids(0),next(0) { } + + lzwcode *FindCode(int value) + { + lzwcode *node=this; + + // check the children (kids) of the node for the value + for (node = node->kids; node != 0; node = node->next) + if (node->value == value) + return(node); + return(0); + } + + void AddNode(unsigned short code, unsigned short value) + { + lzwcode *n = new lzwcode; + + // add a new child to node; the child will have code and value + n->value = value; + n->code = code; + n->kids = 0; + n->next = this->kids; + this->kids = n; + } + + static lzwcode * NewTable(int values) + { + int i; + lzwcode * table = new lzwcode; + + table->kids = 0; + for (i = 0; i < values; i++) + table->AddNode( i, i); + + return(table); + } + + // Destructor just deletes any + // children and sibblings. + ~lzwcode() + { + if(kids) + delete kids; + if(next) + delete next; + } + }; + +private: + bitstream bs; + synfig::String filename; + synfig::SmartFILE file; + int + i, // General-purpose index + codesize, // Current code size + rootsize, // Size of pixel bits (will be recalculted) + nextcode; // Next code to use + lzwcode *table,*next,*node; + + synfig::Surface curr_surface; + etl::surface curr_frame; + etl::surface prev_frame; + + int imagecount; + int cur_scanline; + + + // GIF compression parameters + bool lossy; + bool multi_image; + bool dithering; + int color_bits; + int iframe_density; + int loop_count; + bool local_palette; + + synfig::Palette curr_palette; + + void output_curr_palette(); + +public: + gif(const char *filename); + + virtual bool set_rend_desc(synfig::RendDesc *desc); + virtual bool init(); + virtual bool start_frame(synfig::ProgressCallback *cb); + virtual void end_frame(); + + virtual ~gif(); + + virtual synfig::Color * start_scanline(int scanline); + virtual bool end_scanline(void); + +}; + +/* === E N D =============================================================== */ + +#endif