Remove ancient trunk folder from svn repository
[synfig.git] / synfig-core / src / synfig / listimporter.cpp
diff --git a/synfig-core/src/synfig/listimporter.cpp b/synfig-core/src/synfig/listimporter.cpp
new file mode 100644 (file)
index 0000000..02680f0
--- /dev/null
@@ -0,0 +1,208 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file listimporter.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007, 2008 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
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "listimporter.h"
+#include "general.h"
+#include <fstream>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+
+/* === M A C R O S ========================================================= */
+
+#define LIST_IMPORTER_CACHE_SIZE       20
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ListImporter::ListImporter(const String &filename)
+{
+       fps=15;
+
+       ifstream stream(filename.c_str());
+
+       if(!stream)
+       {
+               synfig::error("Unable to open "+filename);
+               return;
+       }
+       String line;
+       String prefix=etl::dirname(filename)+ETL_DIRECTORY_SEPARATOR;
+       getline(stream,line);           // read first line and check whether it is a Papagayo lip sync file
+
+       if (line == "MohoSwitch1")      // it is a Papagayo lipsync file
+       {
+               String phoneme, prevphoneme, prevext, ext(".jpg"); // default image format
+               int frame, prevframe = -1; // it means that the previous phoneme is not known
+
+               while(!stream.eof())
+               {
+                       getline(stream,line);
+
+                       if(line.find(String("FPS ")) == 0)
+                       {
+                               float f = atof(String(line.begin()+4,line.end()).c_str());
+                               if (f) fps = f;
+                               continue;
+                       }
+
+                       if (line == "bmp"  ||
+                               line == "gif"  ||
+                               line == "jpg"  ||
+                               line == "png"  ||
+                               line == "ppm"  ||
+                               line == "tiff" )
+                       {
+                               ext = String(".") + line;
+                               continue;
+                       }
+
+                       size_t pos = line.find(String(" ")); // find space position. The format is "frame phoneme-name".
+                       if(pos != String::npos)
+                       {
+                               frame = atoi(String(line.begin(),line.begin()+pos).c_str());
+                               phoneme = String(line.begin()+pos+1, line.end());
+
+                               if (prevframe != -1)
+                                       while (prevframe < frame)
+                                       {
+                                               filename_list.push_back(prefix + prevphoneme + prevext);
+                                               synfig::info("frame %d, phoneme = %s, path = '%s'", prevframe, prevphoneme.c_str(), (prefix + prevphoneme + prevext).c_str());
+                                               prevframe++;
+                                       }
+
+                               prevext = ext;
+                               prevframe = frame;
+                               prevphoneme = phoneme;
+                       }
+               }
+
+               filename_list.push_back(prefix + prevphoneme + prevext);        // do it one more time for the last phoneme
+               synfig::info("finally, frame %d, phoneme = %s, path = '%s'", prevframe, prevphoneme.c_str(), (prefix + prevphoneme + prevext).c_str());
+
+               return;
+       }
+
+       stream.seekg(ios_base::beg);
+       while(!stream.eof())
+       {
+               getline(stream,line);
+               if(line.empty())
+                       continue;
+               // If we have a framerate, then use it
+               if(line.find(String("FPS "))==0)
+               {
+                       fps=atof(String(line.begin()+4,line.end()).c_str());
+                       //synfig::warning("FPS=%f",fps);
+                       if(!fps)
+                               fps=15;
+                       continue;
+               }
+               filename_list.push_back(prefix+line);
+       }
+}
+
+Importer*
+ListImporter::create(const char *filename)
+{
+       return new ListImporter(filename);
+}
+
+ListImporter::~ListImporter()
+{
+}
+
+bool
+ListImporter::get_frame(Surface &surface,Time time, ProgressCallback *cb)
+{
+       int frame=round_to_int(time*fps);
+
+       if(!filename_list.size())
+       {
+               if(cb)cb->error(_("No images in list"));
+               else synfig::error(_("No images in list"));
+               return false;
+       }
+
+       if(frame<0)frame=0;
+       if(frame>=(signed)filename_list.size())frame=filename_list.size()-1;
+
+       // See if that frame is cached
+       std::list<std::pair<String,Surface> >::iterator iter;
+       for(iter=frame_cache.begin();iter!=frame_cache.end();++iter)
+       {
+               if(iter->first==filename_list[frame])
+               {
+                       surface.mirror(iter->second);
+                       return static_cast<bool>(surface);
+               }
+       }
+
+       Importer::Handle importer(Importer::open(filename_list[frame]));
+
+       if(!importer)
+       {
+               if(cb)cb->error(_("Unable to open ")+filename_list[frame]);
+               else synfig::error(_("Unable to open ")+filename_list[frame]);
+               return false;
+       }
+
+       if(!importer->get_frame(surface,0,cb))
+       {
+               if(cb)cb->error(_("Unable to get frame from ")+filename_list[frame]);
+               else synfig::error(_("Unable to get frame from ")+filename_list[frame]);
+               return false;
+       }
+
+       if(frame_cache.size()>=LIST_IMPORTER_CACHE_SIZE)
+               frame_cache.pop_front();
+
+       frame_cache.push_back(std::pair<String,Surface>(filename_list[frame],surface));
+
+       surface.mirror(frame_cache.back().second);
+
+       return static_cast<bool>(surface);
+}
+
+bool
+ListImporter::is_animated()
+{
+       return true;
+}