X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftags%2Fsynfig_0_61_06%2Fsrc%2Fmodules%2Fmod_yuv420p%2Ftrgt_yuv.cpp;fp=synfig-core%2Ftags%2Fsynfig_0_61_06%2Fsrc%2Fmodules%2Fmod_yuv420p%2Ftrgt_yuv.cpp;h=8dcfb5ec9316be657aa9ccae4c0eb0edcf703e3c;hb=9f067badc4463e2ad6363dfe9b8c4fc28b0ec503;hp=0000000000000000000000000000000000000000;hpb=34168bb24164074ff22eb5bc47a612a738901e0a;p=synfig.git diff --git a/synfig-core/tags/synfig_0_61_06/src/modules/mod_yuv420p/trgt_yuv.cpp b/synfig-core/tags/synfig_0_61_06/src/modules/mod_yuv420p/trgt_yuv.cpp new file mode 100644 index 0000000..8dcfb5e --- /dev/null +++ b/synfig-core/tags/synfig_0_61_06/src/modules/mod_yuv420p/trgt_yuv.cpp @@ -0,0 +1,222 @@ +/* === S Y N F I G ========================================================= */ +/*! \file trgt_yuv.cpp +** \brief Template File +** +** $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 +*/ +/* ========================================================================= */ + +/* === H E A D E R S ======================================================= */ + +#define SYNFIG_TARGET + +#ifdef USING_PCH +# include "pch.h" +#else +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "trgt_yuv.h" +#include +#include +#include +#include +#endif + +using namespace synfig; +using namespace std; +using namespace etl; + +/* === M A C R O S ========================================================= */ + +#define Y_FLOOR (16) +#define Y_CEIL (235) +#define Y_RANGE (Y_CEIL-Y_FLOOR) + +#define UV_FLOOR (16) +#define UV_CEIL (240) +#define UV_RANGE (UV_CEIL-UV_FLOOR) + +/* === G L O B A L S ======================================================= */ + +SYNFIG_TARGET_INIT(yuv); +SYNFIG_TARGET_SET_NAME(yuv,"yuv420p"); +SYNFIG_TARGET_SET_EXT(yuv,"yuv"); +SYNFIG_TARGET_SET_VERSION(yuv,"0.1"); +SYNFIG_TARGET_SET_CVS_ID(yuv,"$Id$"); + +/* === M E T H O D S ======================================================= */ + +yuv::yuv(const char *FILENAME): + filename(FILENAME), + file( (filename=="-")?stdout:fopen(filename.c_str(),"wb") ), + dithering(true) +{ + // YUV420P doesn't have an alpha channel + set_remove_alpha(); +} + +yuv::~yuv() +{ +} + +bool +yuv::set_rend_desc(RendDesc *given_desc) +{ + given_desc->clear_flags(); + + // Make sure our width is divisible by two + given_desc->set_w(given_desc->get_w()*2/2); + given_desc->set_h(given_desc->get_h()*2/2); + + desc=*given_desc; + + // Set up our surface + surface.set_wh(desc.get_w(),desc.get_h()); + + return true; +} + +bool +yuv::start_frame(synfig::ProgressCallback *callback) +{ + return static_cast(file); +} + +Color * +yuv::start_scanline(int x) +{ + return surface[x]; +} + +bool +yuv::end_scanline() +{ + return static_cast(file); +} + +void +yuv::end_frame() +{ + const int w=desc.get_w(),h=desc.get_h(); + int x,y; + + assert(file); + + // Output Y' channel, adjusting + // the gamma as we go + for(y=0;yy+1) + { + surface[y+1][x-1]+=error * ((float)3/(float)16); + surface[y+1][x]+=error * ((float)5/(float)16); + if(surface.get_w()>x+1) + surface[y+1][x+1]+=error * ((float)1/(float)16); + } + if(surface.get_w()>x+1) + surface[y][x+1]+=error * ((float)7/(float)16); + } + + fputc(i,file.get()); + } + + + // Create new super-sampled surface + Surface sm_surface(w/2,h/2); + for(y=0;yy+1) + { + sm_surface[y+1][x-1]+=error * ((float)3/(float)16); + sm_surface[y+1][x]+=error * ((float)5/(float)16); + if(sm_surface.get_w()>x+1) + sm_surface[y+1][x+1]+=error * ((float)1/(float)16); + } + if(sm_surface.get_w()>x+1) + sm_surface[y][x+1]+=error * ((float)7/(float)16); + } + fputc(i,file.get()); + } + + // Output V channel + for(y=0;yy+1) + { + sm_surface[y+1][x-1]+=error * ((float)3/(float)16); + sm_surface[y+1][x]+=error * ((float)5/(float)16); + if(sm_surface.get_w()>x+1) + sm_surface[y+1][x+1]+=error * ((float)1/(float)16); + } + if(sm_surface.get_w()>x+1) + sm_surface[y][x+1]+=error * ((float)7/(float)16); + } + fputc(i,file.get()); + } + + // Flush out the frame + fflush(file.get()); +}