From: pabs Date: Tue, 17 Apr 2007 08:46:29 +0000 (+0000) Subject: Add a non-working, partial implementation of MNG output X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=80899abc12a91a4fe6e6375bd2f41bc5c3b607e7;p=synfig.git Add a non-working, partial implementation of MNG output git-svn-id: http://svn.voria.com/code@470 1f10aa63-cdf2-0310-b900-c93c546f37ac --- diff --git a/synfig-core/trunk/config/configure.ac b/synfig-core/trunk/config/configure.ac index 226f5b9..bafe40d 100644 --- a/synfig-core/trunk/config/configure.ac +++ b/synfig-core/trunk/config/configure.ac @@ -337,6 +337,7 @@ dnl PKG_CHECK_MODULES(GLIB, glib-2.0,[GLIB="yes"],[GLIB="no"]) TARGET_TIF="yes" TARGET_PNG="yes" +TARGET_MNG="no" TARGET_JPEG="yes" if test "$TARGET_TIF" != "disabled" ; then @@ -370,6 +371,17 @@ AC_CHECK_LIB(png, png_write_row,[ ],[-lz -L${exec_prefix}/lib]) ],[-lz -L${exec_prefix}/lib]) +#AC_CHECK_LIB(mng, mng_initialize,[ +# MNG_LIBS="-lmng -lz" +# AC_DEFINE(HAVE_LIBMNG,[], [ Define if MNG library is available ] ) +# AC_SUBST(MNG_LIBS) +# AM_CONDITIONAL(HAVE_LIBMNG,true) +#],[ +# AC_MSG_RESULT([ *** MNG Output target disabled]) +# TARGET_MNG="no" +# AM_CONDITIONAL(HAVE_LIBMNG,false) +#],[-lz -L${exec_prefix}/lib]) + AC_CHECK_LIB(jpeg, main,[ JPEG_LIBS="-ljpeg" AC_DEFINE(HAVE_LIBJPEG,[], [ Define if JPEG library is available ] ) @@ -520,6 +532,8 @@ AC_SUBST(synfigincludedir) )] +# src/modules/mod_mng/Makefile + AC_OUTPUT( synfig-config @PACKAGE_TARNAME@.pc @@ -571,6 +585,7 @@ GProf Profiling ------------------> $profiling Debug Mode -----------------------> $debug ($debug_flags) Optimization ---------------------> $optimization PNG output target support --------> $TARGET_PNG +MNG output target support --------> $TARGET_MNG TIFF output target support -------> $TARGET_TIF JPEG output target support -------> $TARGET_JPEG ETL_CFLAGS -----------------------> $ETL_CFLAGS diff --git a/synfig-core/trunk/src/modules/mod_mng/Makefile.am b/synfig-core/trunk/src/modules/mod_mng/Makefile.am new file mode 100644 index 0000000..3a6b5e8 --- /dev/null +++ b/synfig-core/trunk/src/modules/mod_mng/Makefile.am @@ -0,0 +1,18 @@ +# $Id$ + +# FIXME: THIS DOES NOT ACTUALLY WORK YET + +MAINTAINERCLEANFILES=Makefile.in +INCLUDES = -I$(top_srcdir)/src + +moduledir=@MODULE_DIR@ + +if HAVE_LIBMNG +module_LTLIBRARIES = libmod_mng.la +libmod_mng_la_SOURCES = main.cpp trgt_mng.cpp trgt_mng.h +libmod_mng_la_LDFLAGS = -module @MNG_LIBS@ -no-undefined +libmod_mng_la_CXXFLAGS = @SYNFIG_CFLAGS@ +libmod_mng_la_LIBADD = -L../../synfig -lsynfig @SYNFIG_LIBS@ +else +endif +EXTRA_DIST= mod_mng.nsh unmod_mng.nsh diff --git a/synfig-core/trunk/src/modules/mod_mng/main.cpp b/synfig-core/trunk/src/modules/mod_mng/main.cpp new file mode 100644 index 0000000..f1ab11c --- /dev/null +++ b/synfig-core/trunk/src/modules/mod_mng/main.cpp @@ -0,0 +1,67 @@ +/* === S Y N F I G ========================================================= */ +/*! \file mod_mng/main.cpp +** \brief MNG plugin +** +** $Id$ +** +** \legal +** Copyright 2007 Paul Wise +** +** 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 =========================================================== +** +** FIXME: THIS DOES NOT ACTUALLY WORK YET +** +** ========================================================================= */ + +/* === H E A D E R S ======================================================= */ + +#define SYNFIG_MODULE + +#ifdef USING_PCH +# include "pch.h" +#else +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "trgt_mng.h" +/* FIXME: Implement MNG import +#include "mptr_mng.h" +*/ +#endif + +/* === E N T R Y P O I N T ================================================= */ + +MODULE_DESC_BEGIN(mod_mng) + MODULE_NAME("MNG Module (libmng)") +/* FIXME: Implement MNG import + MODULE_DESCRIPTION("Provides an MNG target and importer") +*/ + MODULE_DESCRIPTION("Provides an MNG target") + MODULE_AUTHOR("Paul Wise") + MODULE_VERSION("1.0") + MODULE_COPYRIGHT(SYNFIG_COPYRIGHT) +MODULE_DESC_END + +MODULE_INVENTORY_BEGIN(mod_mng) + BEGIN_TARGETS + TARGET(mng_trgt) + END_TARGETS +/* FIXME: implement MNG import + BEGIN_IMPORTERS + IMPORTER(mng_mptr) + END_IMPORTERS +*/ +MODULE_INVENTORY_END diff --git a/synfig-core/trunk/src/modules/mod_mng/mod_mng.nsh b/synfig-core/trunk/src/modules/mod_mng/mod_mng.nsh new file mode 100644 index 0000000..4986de7 --- /dev/null +++ b/synfig-core/trunk/src/modules/mod_mng/mod_mng.nsh @@ -0,0 +1,13 @@ +; FIXME: THIS DOES NOT ACTUALLY WORK YET + +Section "mod_mng" Sec_mod_mng + SetOutPath "$INSTDIR\lib\synfig\modules" + File /oname=mod_mng.dll "src\modules\mod_mng\.libs\libmod_mng-0.dll" + FileOpen $0 $INSTDIR\etc\synfig_modules.cfg a + FileSeek $0 0 END + FileWrite $0 "mod_mng" + FileWriteByte $0 "13" + FileWriteByte $0 "10" + FileClose $0 +SectionEnd + diff --git a/synfig-core/trunk/src/modules/mod_mng/trgt_mng.cpp b/synfig-core/trunk/src/modules/mod_mng/trgt_mng.cpp new file mode 100644 index 0000000..d925846 --- /dev/null +++ b/synfig-core/trunk/src/modules/mod_mng/trgt_mng.cpp @@ -0,0 +1,304 @@ +/* === S Y N F I G ========================================================= */ +/*! \file trgt_mng.cpp +** \brief MNG Target Module +** +** $Id$ +** +** \legal +** Copyright 2007 Paul Wise +** +** 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 =========================================================== +** +** FIXME: THIS DOES NOT ACTUALLY WORK YET +** +** You will need to read the PNG and MNG specs to understand this code +** +** ========================================================================= */ + +/* === 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_mng.h" +#include +#include +#include +#include +#include +#include + +#endif + +/* === M A C R O S ========================================================= */ + +using namespace synfig; +using namespace std; +using namespace etl; + +/* === G L O B A L S ======================================================= */ + +SYNFIG_TARGET_INIT(mng_trgt); +SYNFIG_TARGET_SET_NAME(mng_trgt,"mng"); +SYNFIG_TARGET_SET_EXT(mng_trgt,"mng"); +SYNFIG_TARGET_SET_VERSION(mng_trgt,"0.1"); +SYNFIG_TARGET_SET_CVS_ID(mng_trgt,"$Id$"); + +/* === M E T H O D S ======================================================= */ + +static mng_ptr MNG_DECL mng_alloc_proc(mng_size_t size){ + return (mng_ptr)calloc(1,size); +} + +static void MNG_DECL mng_free_proc(mng_ptr ptr, mng_size_t size) +{ + free(ptr); return; +} + +static mng_bool MNG_DECL mng_null_proc(mng_handle mng) +{ + synfig::error("mng_trgt: error: mng_null_proc"); + return MNG_TRUE; +} + +static mng_bool MNG_DECL mng_write_proc(mng_handle mng, mng_ptr buf, mng_uint32 size, mng_uint32* written) +{ + synfig::error("mng_trgt: error: mng_write_proc"); + FILE* file = (FILE*)mng_get_userdata (mng); + *written = fwrite(buf, 1, size, file); + return MNG_TRUE; +} + +static mng_bool MNG_DECL mng_error_proc( + mng_handle mng, mng_int32 error, mng_int8 severity, mng_chunkid chunkname, + mng_uint32 chunkseq, mng_int32 extra1, mng_int32 extra2, mng_pchar errortext){ + mng_trgt* me = (mng_trgt*)mng_get_userdata (mng); + fprintf(stderr,"mng_trgt: error: %s",errortext); + // me->ready=false; + return MNG_TRUE; +} + +mng_trgt::mng_trgt(const char *Filename): + filename(Filename) +{ + file=NULL; + buffer=NULL; + color_buffer=NULL; + zbuffer=NULL; + zbuffer_len=0; + ready=false; +} + +mng_trgt::~mng_trgt() +{ + synfig::error("mng_trgt: error: ~mng_trgt"); + if( mng != MNG_NULL){ + mng_putchunk_mend(mng); + if( mng_write(mng) != 0 ){ + mng_int8 severity; + mng_chunkid chunkname; + mng_uint32 chunkseq; + mng_int32 extra1; + mng_int32 extra2; + mng_pchar errortext; + mng_getlasterror(mng, &severity, &chunkname, &chunkseq, &extra1,&extra2, &errortext); + synfig::error("mng_trgt: error: couldn't write mng: %s",errortext); + } + mng_cleanup (&mng); + } + if( file != NULL ) fclose(file); file=NULL; + if( buffer != NULL ){ delete [] buffer; buffer = NULL; } + if( color_buffer != NULL ){ delete [] color_buffer; color_buffer = NULL; } + if( zbuffer != NULL ){ free(zbuffer); zbuffer = NULL; zbuffer_len = 0; } +} + +bool +mng_trgt::set_rend_desc(RendDesc *given_desc) +{ + desc=*given_desc; + imagecount=desc.get_frame_start(); + if(desc.get_frame_end()-desc.get_frame_start()>0) + multi_image=true; + else + multi_image=false; + return true; +} + + +bool +mng_trgt::init(){ + time_t t = time (NULL); + struct tm* gmt = gmtime(&t); + w=desc.get_w(); h=desc.get_h(); + //synfig::error("mng_trgt: init %d %d",w,h); + file = fopen(filename.c_str(), "wb"); + if( file == NULL ) goto cleanup_on_error; + mng = mng_initialize((mng_ptr)file, mng_alloc_proc, mng_free_proc, MNG_NULL); + if(mng == MNG_NULL) goto cleanup_on_error; + if( mng_setcb_errorproc(mng, mng_error_proc) != 0 ) goto cleanup_on_error; + if( mng_setcb_writedata(mng, mng_write_proc) != 0 ) goto cleanup_on_error; + if( mng_setcb_openstream(mng, mng_null_proc) != 0 ) goto cleanup_on_error; + if( mng_setcb_closestream(mng, mng_null_proc) != 0 ) goto cleanup_on_error; + if( mng_create(mng) != 0 ) goto cleanup_on_error; + if( mng_putchunk_mhdr(mng, w, h, multi_image?1000:0, 1, desc.get_frame_end()-desc.get_frame_start(), 0, 0) != 0 ) goto cleanup_on_error; + if( mng_putchunk_term(mng, MNG_TERMACTION_REPEAT, MNG_ITERACTION_LASTFRAME, 0, 0x7fffffff) != 0 ) goto cleanup_on_error; + if( mng_putchunk_text(mng, sizeof(MNG_TEXT_TITLE), MNG_TEXT_TITLE, get_canvas()->get_name().length(), const_cast(get_canvas()->get_name().c_str()) ) != 0 ) goto cleanup_on_error; + if( mng_putchunk_text(mng, sizeof(MNG_TEXT_DESCRIPTION), MNG_TEXT_DESCRIPTION, get_canvas()->get_description().length(), const_cast(get_canvas()->get_description().c_str()) ) != 0 ) goto cleanup_on_error; + if( mng_putchunk_text(mng, sizeof(MNG_TEXT_SOFTWARE), MNG_TEXT_SOFTWARE, sizeof("SYNFIG"), "SYNFIG" ) != 0 ) goto cleanup_on_error; + /* FIXME: not sure if this is correct */ + if( mng_putchunk_gama(mng, MNG_FALSE, (int)(1.0/gamma().get_gamma()*100000)) != 0 ) goto cleanup_on_error; + if( mng_putchunk_phyg(mng, MNG_FALSE,round_to_int(desc.get_x_res()),round_to_int(desc.get_y_res()),MNG_UNIT_METER) != 0 ) goto cleanup_on_error; + if( mng_putchunk_time(mng, gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday, gmt->tm_hour, gmt->tm_min, gmt->tm_sec) != 0 ) goto cleanup_on_error; + buffer=new unsigned char[4*w]; + if( buffer == NULL ) goto cleanup_on_error; + color_buffer=new Color[w]; + if( color_buffer == NULL ) goto cleanup_on_error; + return true; + +cleanup_on_error: + ready=false; + if( mng != MNG_NULL){ + mng_int8 severity; + mng_chunkid chunkname; + mng_uint32 chunkseq; + mng_int32 extra1; + mng_int32 extra2; + mng_pchar errortext; + mng_getlasterror (mng, &severity, &chunkname, &chunkseq, &extra1,&extra2, &errortext); + synfig::error("mng_trgt: libmng: %s",errortext); + mng_cleanup (&mng); + } + if( file && file!=stdout ) fclose(file); file=NULL; + if( buffer != NULL ){ delete [] buffer; buffer = NULL; } + if( color_buffer != NULL ){ delete [] color_buffer; color_buffer = NULL; } + return false; +} + +void +mng_trgt::end_frame() +{ + //synfig::error("mng_trgt: endf %d %d",w,h); + //synfig::error("mng_trgt: error: endframe"); + deflate(&zstream,Z_FINISH); + deflateEnd(&zstream); + if( mng != MNG_NULL ){ + mng_int8 severity; + mng_chunkid chunkname; + mng_uint32 chunkseq; + mng_int32 extra1; + mng_int32 extra2; + mng_pchar errortext; + mng_putchunk_idat(mng, zbuffer_len, zbuffer); + //mng_getlasterror (mng, &severity, &chunkname, &chunkseq, &extra1,&extra2, &errortext); + //synfig::error("mng_trgt: libmng: %s %d",errortext,zbuffer_len); + mng_putchunk_iend(mng); + //mng_getlasterror (mng, &severity, &chunkname, &chunkseq, &extra1,&extra2, &errortext); + //synfig::error("mng_trgt: libmng: %s %d",errortext); + } + imagecount++; + ready=false; +} + +bool +mng_trgt::start_frame(synfig::ProgressCallback *callback) +{ + //synfig::error("mng_trgt: startf %d %d",w,h); + //synfig::error("mng_trgt: error: startframe"); + /* + FIXME: figure out if we need this + mng_putchunk_fram(mng, + MNG_FALSE, + MNG_FRAMINGMODE_NOCHANGE, + 0, + NULL, + MNG_CHANGEDELAY_NO, + MNG_CHANGETIMOUT_NO, + MNG_CHANGECLIPPING_NO, + MNG_CHANGESYNCID_NO, + 0, + 0, + 0, + layer_offset_x, + layer_offset_x + layer_cols, + layer_offset_y, + layer_offset_y + layer_rows, + 0, + 0) + mng_getchunk_fram(mng_handle hHandle, + mng_handle hChunk, + mng_bool *bEmpty, + mng_uint8 *iMode, + mng_uint32 *iNamesize, + mng_pchar *zName, + mng_uint8 *iChangedelay, + mng_uint8 *iChangetimeout, + mng_uint8 *iChangeclipping, + mng_uint8 *iChangesyncid, + mng_uint32 *iDelay, + mng_uint32 *iTimeout, + mng_uint8 *iBoundarytype, + mng_int32 *iBoundaryl, + mng_int32 *iBoundaryr, + mng_int32 *iBoundaryt, + mng_int32 *iBoundaryb, + mng_uint32 *iCount, + mng_uint32p *pSyncids); + */ + if( mng == MNG_NULL ) return false; + if( mng_putchunk_defi(mng,0,MNG_DONOTSHOW_VISIBLE,MNG_ABSTRACT,MNG_FALSE,0,0,MNG_FALSE,0,0,0,0) != 0) return false; + if( mng_putchunk_ihdr(mng,w,h,MNG_BITDEPTH_8,MNG_COLORTYPE_RGBA,MNG_COMPRESSION_DEFLATE, 0/*MNG_FILTER_NO_DIFFERING*/,MNG_INTERLACE_NONE) != 0) return false; + zstream.zalloc = Z_NULL; + zstream.zfree = Z_NULL; + zstream.opaque = Z_NULL; + zstream.data_type = Z_BINARY; + if( deflateInit(&zstream, Z_DEFAULT_COMPRESSION) != Z_OK ) return false; + //zbuffer_len = deflateBound(&zstream,4*w*h); + if(zbuffer == NULL){ + zbuffer_len = 4*w*h; + zbuffer = (unsigned char*)realloc(zbuffer, zbuffer_len); + zstream.next_out = zbuffer; + zstream.avail_out = zbuffer_len; + } + ready=true; + return true; +} + +Color * +mng_trgt::start_scanline(int scanline) +{ + //synfig::error("mng_trgt: starts %d %d",w,h); + //synfig::error("mng_trgt: error: startscanline"); + return color_buffer; +} + +bool +mng_trgt::end_scanline() +{ + //synfig::error("mng_trgt: ends %d %d",w,h); + //synfig::error("mng_trgt: error: endscanline"); + if(!file || !ready) + return false; + convert_color_format(buffer, color_buffer, desc.get_w(), PF_RGB|PF_A, gamma()); + /* FIXME: Implement buffer management */ + zstream.next_in = buffer; + zstream.avail_in = 4*w; + deflate(&zstream,Z_NO_FLUSH); + return true; +} diff --git a/synfig-core/trunk/src/modules/mod_mng/trgt_mng.h b/synfig-core/trunk/src/modules/mod_mng/trgt_mng.h new file mode 100644 index 0000000..1d211c5 --- /dev/null +++ b/synfig-core/trunk/src/modules/mod_mng/trgt_mng.h @@ -0,0 +1,100 @@ +/*! ======================================================================== +** Synfig +** +** Copyright (c) 2007 Paul Wise +** +** 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. +** +** === N O T E S =========================================================== +** +** FIXME: THIS DOES NOT ACTUALLY WORK YET +** +** ========================================================================= */ + +/* === S T A R T =========================================================== */ + +#ifndef __SYNFIG_TRGT_MNG_H +#define __SYNFIG_TRGT_MNG_H + +/* === H E A D E R S ======================================================= */ + +#include +#include +#include + +#include +#include + +#if !defined(MNG_SUPPORT_FULL) +#define MNG_SUPPORT_FULL 1 +#endif + +#if !defined(MNG_SUPPORT_READ) +#define MNG_SUPPORT_READ 1 +#endif + +#if !defined(MNG_SUPPORT_WRITE) +#define MNG_SUPPORT_WRITE 1 +#endif + +#if !defined(MNG_SUPPORT_DISPLAY) +#define MNG_SUPPORT_DISPLAY 1 +#endif + +#if !defined(MNG_ACCESS_CHUNKS) +#define MNG_ACCESS_CHUNKS 1 +#endif + +#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 mng_trgt : public synfig::Target_Scanline +{ + SYNFIG_TARGET_MODULE_EXT + +private: + + FILE *file; + int w,h; + mng_handle mng; + + bool multi_image,ready; + int imagecount; + synfig::String filename; + unsigned char *buffer; + synfig::Color *color_buffer; + + z_stream zstream; + unsigned char* zbuffer; + unsigned int zbuffer_len; + +public: + + mng_trgt(const char *filename); + virtual ~mng_trgt(); + + virtual bool set_rend_desc(synfig::RendDesc *desc); + virtual bool init(); + virtual bool start_frame(synfig::ProgressCallback *cb); + virtual void end_frame(); + + virtual synfig::Color * start_scanline(int scanline); + virtual bool end_scanline(); +}; + +/* === E N D =============================================================== */ + +#endif diff --git a/synfig-core/trunk/src/modules/mod_mng/unmod_mng.nsh b/synfig-core/trunk/src/modules/mod_mng/unmod_mng.nsh new file mode 100644 index 0000000..ddff595 --- /dev/null +++ b/synfig-core/trunk/src/modules/mod_mng/unmod_mng.nsh @@ -0,0 +1,6 @@ +; FIXME: THIS DOES NOT ACTUALLY WORK YET +Section "un.mod_mng" + Delete "$INSTDIR\lib\synfig\modules\mod_mng.dll" + RMDir "$INSTDIR" +SectionEnd +