/* === S Y N F I G ========================================================= */ /*! \file mptr_imagemagick.cpp ** \brief ppm 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 ======================================================= */ #ifdef USING_PCH # include "pch.h" #else #ifdef HAVE_CONFIG_H # include #endif #include #include "mptr_imagemagick.h" #include #include #if HAVE_SYS_WAIT_H #include #endif #if HAVE_IO_H #include #endif #if HAVE_PROCESS_H #include #endif #if HAVE_FCNTL_H #include #endif #include #include #include #include #include #endif /* === M A C R O S ========================================================= */ using namespace synfig; using namespace std; using namespace etl; #if defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID) #define UNIX_PIPE_TO_PROCESSES #else #define WIN32_PIPE_TO_PROCESSES #endif /* === G L O B A L S ======================================================= */ SYNFIG_IMPORTER_INIT(imagemagick_mptr); SYNFIG_IMPORTER_SET_NAME(imagemagick_mptr,"imagemagick"); SYNFIG_IMPORTER_SET_EXT(imagemagick_mptr,"miff"); SYNFIG_IMPORTER_SET_VERSION(imagemagick_mptr,"0.1"); SYNFIG_IMPORTER_SET_CVS_ID(imagemagick_mptr,"$Id$"); /* === M E T H O D S ======================================================= */ imagemagick_mptr::imagemagick_mptr(const char *f) { filename=f; file=NULL; } imagemagick_mptr::~imagemagick_mptr() { if(file) pclose(file); } bool imagemagick_mptr::get_frame(synfig::Surface &surface, const synfig::RendDesc &renddesc, Time /*time*/, synfig::ProgressCallback *cb) { //#define HAS_LIBPNG 1 #if 1 if(filename.empty()) { if(cb)cb->error(_("No file to load")); else synfig::error(_("No file to load")); return false; } string temp_file="/tmp/deleteme.png"; #if defined(WIN32_PIPE_TO_PROCESSES) if(file) pclose(file); string command; if(filename.find("psd")!=String::npos) command=strprintf("convert \"%s\" -flatten \"png32:%s\"\n",filename.c_str(),temp_file.c_str()); else command=strprintf("convert \"%s\" \"png32:%s\"\n",filename.c_str(),temp_file.c_str()); if(system(command.c_str())!=0) return false; #elif defined(UNIX_PIPE_TO_PROCESSES) string output="png32:"+temp_file; pid_t pid = fork(); if (pid == -1) { return false; } if (pid == 0){ // Child process if(filename.find("psd")!=String::npos) execlp("convert", "convert", filename.c_str(), "-flatten", output.c_str(), (const char *)NULL); else execlp("convert", "convert", filename.c_str(), output.c_str(), (const char *)NULL); // We should never reach here unless the exec failed return false; } int status; waitpid(pid, &status, 0); if( (WIFEXITED(status) && WEXITSTATUS(status) != 0) || !WIFEXITED(status) ) return false; #else #error There are no known APIs for creating child processes #endif Importer::Handle importer(Importer::open(temp_file)); if(!importer) { if(cb)cb->error(_("Unable to open ")+temp_file); else synfig::error(_("Unable to open ")+temp_file); return false; } if(!importer->get_frame(surface,renddesc,0,cb)) { if(cb)cb->error(_("Unable to get frame from ")+temp_file); else synfig::error(_("Unable to get frame from ")+temp_file); return false; } if(!surface) { if(cb)cb->error(_("Bad surface from ")+temp_file); else synfig::error(_("Bad surface from ")+temp_file); return false; } if(1) { // remove odd premultiplication for(int i=0;ierror(_("No file to load")); else synfig::error(_("No file to load")); return false; } command=strprintf("convert \"%s\" -flatten ppm:-\n",filename.c_str()); file=popen(command.c_str(),POPEN_BINARY_READ_TYPE); if(!file) { if(cb)cb->error(_("Unable to open pipe to imagemagick")); else synfig::error(_("Unable to open pipe to imagemagick")); return false; } int w,h; float divisor; char cookie[2]; while((cookie[0]=fgetc(file))!='P' && !feof(file)); if(feof(file)) { if(cb)cb->error(_("Reached end of stream without finding PPM header")); else synfig::error(_("Reached end of stream without finding PPM header")); return false; } cookie[1]=fgetc(file); if(cookie[0]!='P' || cookie[1]!='6') { if(cb)cb->error(string(_("stream not in PPM format"))+" \""+cookie[0]+cookie[1]+'"'); else synfig::error(string(_("stream not in PPM format"))+" \""+cookie[0]+cookie[1]+'"'); return false; } fgetc(file); fscanf(file,"%d %d\n",&w,&h); fscanf(file,"%f",&divisor); fgetc(file); if(feof(file)) { if(cb)cb->error(_("Premature end of file (after header)")); else synfig::error(_("Premature end of file (after header)")); return false; } int x; int y; frame.set_wh(w,h); for(y=0;yerror(_("Premature end of file")); else synfig::error(_("Premature end of file")); return false; } float b=gamma().r_U8_to_F32((unsigned char)fgetc(file)); float g=gamma().g_U8_to_F32((unsigned char)fgetc(file)); float r=gamma().b_U8_to_F32((unsigned char)fgetc(file)); /* float b=(float)(unsigned char)fgetc(file)/divisor; float g=(float)(unsigned char)fgetc(file)/divisor; float r=(float)(unsigned char)fgetc(file)/divisor; */ frame[y][x]=Color( b, g, r, 1.0 ); } surface=frame; return true; #endif }