X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fmodules%2Fmod_gif%2Ftrgt_gif.cpp;fp=synfig-core%2Ftrunk%2Fsrc%2Fmodules%2Fmod_gif%2Ftrgt_gif.cpp;h=0000000000000000000000000000000000000000;hb=a095981e18cc37a8ecc7cd237cc22b9c10329264;hp=20689955c714b954fddbe2ed01d3e5ca0d9d8bbb;hpb=9459638ad6797b8139f1e9f0715c96076dbf0890;p=synfig.git diff --git a/synfig-core/trunk/src/modules/mod_gif/trgt_gif.cpp b/synfig-core/trunk/src/modules/mod_gif/trgt_gif.cpp deleted file mode 100644 index 2068995..0000000 --- a/synfig-core/trunk/src/modules/mod_gif/trgt_gif.cpp +++ /dev/null @@ -1,456 +0,0 @@ -/* === S Y N F I G ========================================================= */ -/*! \file trgt_gif.cpp -** \brief BMP Target Module -** -** $Id$ -** -** \legal -** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley -** Copyright (c) 2007 Chris Moore -** -** 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 =========================================================== -** -** ========================================================================= */ - -/* === H E A D E R S ======================================================= */ - -#define SYNFIG_TARGET - -#ifdef USING_PCH -# include "pch.h" -#else -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "trgt_gif.h" -#include -#endif - -/* === M A C R O S ========================================================= */ - -using namespace synfig; -using namespace std; -using namespace etl; - -#define MAX_FRAME_RATE (20.0) - -/* === G L O B A L S ======================================================= */ - -SYNFIG_TARGET_INIT(gif); -SYNFIG_TARGET_SET_NAME(gif,"gif"); -SYNFIG_TARGET_SET_EXT(gif,"gif"); -SYNFIG_TARGET_SET_VERSION(gif,"0.1"); -SYNFIG_TARGET_SET_CVS_ID(gif,"$Id$"); - -/* === M E T H O D S ======================================================= */ - -gif::gif(const char *filename_): - filename(filename_), - file( (filename=="-")?stdout:fopen(filename_,POPEN_BINARY_WRITE_TYPE) ), - imagecount(0), - - lossy(true), - multi_image(false), - dithering(true), - color_bits(8), - iframe_density(30), - loop_count(0x7fff), - local_palette(true) -{ -} - -gif::~gif() -{ - if(file) - fputc(';',file.get()); // Image terminator -} - -bool -gif::set_rend_desc(RendDesc *given_desc) -{ - if(given_desc->get_frame_rate()>MAX_FRAME_RATE) - given_desc->set_frame_rate(MAX_FRAME_RATE); - - desc=*given_desc; - - if(desc.get_frame_end()-desc.get_frame_start()>0) - { - multi_image=true; - //set_remove_alpha(); - imagecount=desc.get_frame_end()-desc.get_frame_start(); - } - else - multi_image=false; - return true; -} - -bool -gif::init() -{ - int w=desc.get_w(),h=desc.get_h(); - - if(!file) - { - synfig::error(strprintf(_("Unable to open \"%s\" for write access!"),filename.c_str())); - return false; - } - - rootsize=color_bits; // Size of pixel bits - - curr_frame.set_wh(w,h); - prev_frame.set_wh(w,h); - curr_surface.set_wh(w,h); - curr_frame.clear(); - prev_frame.clear(); - curr_surface.clear(); - - if(get_quality()>5) - lossy=true; - else - lossy=false; - - // Output the header - fprintf(file.get(),"GIF89a"); - fputc(w&0x000000ff,file.get()); - fputc((w&0x0000ff00)>>8,file.get()); - fputc(h&0x000000ff,file.get()); - fputc((h&0x0000ff00)>>8,file.get()); - if(!local_palette) - fputc(0xF0+(rootsize-1),file.get()); // flags - else - fputc((0xF0+(rootsize-1))&~(1<<7),file.get()); // flags - - fputc(0,file.get()); // background color - fputc(0,file.get()); // Pixel Aspect Ratio - - if(!local_palette) - { - curr_palette=Palette::grayscale(256/(1<<(8-rootsize))-1); - output_curr_palette(); - } - - if(loop_count && multi_image) - { - fputc(33,file.get()); // 33 (hex 0x21) GIF Extension code - fputc(255,file.get()); // 255 (hex 0xFF) Application Extension Label - fputc(11,file.get()); // 11 (hex (0x0B) Length of Application Block - fprintf(file.get(),"NETSCAPE2.0"); - fputc(3,file.get()); // 3 (hex 0x03) Length of Data Sub-Block - fputc(1,file.get()); // 1 (hex 0x01) - fputc(loop_count&0x000000ff,file.get()); - fputc((loop_count&0x0000ff00)>>8,file.get()); - fputc(0,file.get()); // 0 (hex 0x00) a Data Sub-block Terminator. - } - - return true; -} - -void -gif::output_curr_palette() -{ - // Output the color table - for(i=0;i<256/(1<<(8-rootsize));i++) - { - if(i<(signed)curr_palette.size()) - { - Color color(curr_palette[i].color.clamped()); - //fputc(i*(1<<(8-rootsize)),file.get()); - //fputc(i*(1<<(8-rootsize)),file.get()); - //fputc(i*(1<<(8-rootsize)),file.get()); - fputc(gamma().r_F32_to_U8(color.get_r()),file.get()); - fputc(gamma().g_F32_to_U8(color.get_g()),file.get()); - fputc(gamma().b_F32_to_U8(color.get_b()),file.get()); - } - else - { - fputc(255,file.get()); - fputc(0,file.get()); - fputc(255,file.get()); - } - } -} - -bool -gif::start_frame(synfig::ProgressCallback *callback) -{ -// int -// w=desc.get_w(), -// h=desc.get_h(); - - if(!file) - { - if(callback)callback->error(string("BUG:")+_("Description not set!")); - return false; - } - - if(callback)callback->task(filename+strprintf(" %d",imagecount)); - - - - return true; -} - -void -gif::end_frame() -{ - int w=desc.get_w(),h=desc.get_h(),i; - unsigned int value; - int - delaytime=round_to_int(100.0/desc.get_frame_rate()); - - bool build_off_previous(multi_image); - - Palette prev_palette(curr_palette); - - // Fill in the background color - if(!get_remove_alpha()) - { - Surface::alpha_pen pen(curr_surface.begin(),1.0,Color::BLEND_BEHIND); - pen.set_value(get_canvas()->rend_desc().get_bg_color()); - for(int y=0;y0.1) - pen.put_value(); - else - pen[0][0]=Color::alpha(); - } - pen.dec_x(x); - } - } - - if(local_palette) - { - curr_palette=Palette(curr_surface,256/(1<<(8-rootsize))-build_off_previous-1); - synfig::info("curr_palette.size()=%d",curr_palette.size()); - } - - int transparent_index(curr_palette.find_closest(Color(1,0,1,0))-curr_palette.begin()); - bool has_transparency(curr_palette[transparent_index].color.get_a()<=0.00001); - - if(has_transparency) - build_off_previous=false; - - if(build_off_previous) - { - transparent_index=0; - has_transparency=true; - } - -#define DISPOSE_UNDEFINED (0) -#define DISPOSE_NONE (1<<2) -#define DISPOSE_RESTORE_BGCOLOR (2<<2) -#define DISPOSE_RESTORE_PREVIOUS (3<<2) - int gec_flags(0); - if(build_off_previous) - gec_flags|=DISPOSE_NONE; - else - gec_flags|=DISPOSE_RESTORE_PREVIOUS; - if(has_transparency) - gec_flags|=1; - - // output the Graphic Control Extension - fputc(0x21,file.get()); // Extension introducer - fputc(0xF9,file.get()); // Graphic Control Label - fputc(4,file.get()); // Block Size - fputc(gec_flags,file.get()); // Flags (Packed Fields) - fputc(delaytime&0x000000ff,file.get()); // Delay Time (MSB) - fputc((delaytime&0x0000ff00)>>8,file.get()); // Delay Time (LSB) - fputc(transparent_index,file.get()); // Transparent Color Index - fputc(0,file.get()); // Block Terminator - - // output the image header - fputc(',',file.get()); - fputc(0,file.get()); // image left - fputc(0,file.get()); // image left - fputc(0,file.get()); // image top - fputc(0,file.get()); // image top - fputc(w&0x000000ff,file.get()); - fputc((w&0x0000ff00)>>8,file.get()); - fputc(h&0x000000ff,file.get()); - fputc((h&0x0000ff00)>>8,file.get()); - if(local_palette) - fputc(0x80|(rootsize-1),file.get()); // flags - else - fputc(0x00+ rootsize-1,file.get()); // flags - - - if(local_palette) - { - Palette out(curr_palette); - - if(build_off_previous) - curr_palette.insert(curr_palette.begin(),Color(1,0,1,0)); - output_curr_palette(); - curr_palette=out; - } - - bs=bitstream(file); - - // Prepare ourselves for LZW compression - codesize=rootsize+1; - nextcode=(1<color); - //error*=0.25; - if(curr_surface.get_h()>cur_scanline+1) - { - curr_surface[cur_scanline+1][i-1] += error * ((float)3/(float)16); - curr_surface[cur_scanline+1][i] += error * ((float)5/(float)16); - if(curr_surface.get_w()>i+1) - curr_surface[cur_scanline+1][i+1] += error * ((float)1/(float)16); - } - if(curr_surface.get_w()>i+1) - curr_surface[cur_scanline][i+1] += error * ((float)7/(float)16); - } - - curr_frame[cur_scanline][i]=iter-curr_palette.begin(); - - value=curr_frame[cur_scanline][i]; - if(build_off_previous) - value++; - if(value>(unsigned)(1<color-prev_palette[prev_frame[cur_scanline][i]-1].color ).get_y() ) > (1.0/16.0) || -// abs((int)value-(int)prev_frame[cur_scanline][i])>2|| -// (value<=2 && value!=prev_frame[cur_scanline][i]) || - (imagecount%iframe_density)==0 || imagecount==desc.get_frame_end()-1 ) // lossy version - prev_frame[cur_scanline][i]=value; - else - { - prev_frame[cur_scanline][i]=value; - value=0; - } - } - else - { - // lossless version - if(value!=prev_frame[cur_scanline][i]) - prev_frame[cur_scanline][i]=value; - else - value=0; - } - } - else - prev_frame[cur_scanline][i]=value; - - next=node->FindCode(value); - if(next) - node=next; - else - { - node->AddNode(nextcode, value); - bs.push_value(node->code, codesize); - node = table->FindCode(value); - - // Check to see if we need to increase the codesize - if (nextcode == ( 1 << codesize)) - codesize += 1; - - nextcode += 1; - - // check to see if we have filled up the table - if (nextcode == 4096) - { - // output the clear code: make sure to use the current - // codesize - bs.push_value((unsigned) 1 << rootsize, codesize); - - delete table; - table = lzwcode::NewTable((1<FindCode(value); - } - } - } - } - - - - - - // Push the last code onto the bitstream - bs.push_value(node->code,codesize); - - // Push a end-of-stream code onto the bitstream - bs.push_value((1<