Initial Stable Commit
[synfig.git] / synfig-core / trunk / src / sinfg / listimporter.cpp
1 /* === S I N F G =========================================================== */
2 /*!     \file listimporter.cpp
3 **      \brief Template File
4 **
5 **      $Id: listimporter.cpp,v 1.1.1.1 2005/01/04 01:23:14 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === H E A D E R S ======================================================= */
23
24 #ifdef USING_PCH
25 #       include "pch.h"
26 #else
27 #ifdef HAVE_CONFIG_H
28 #       include <config.h>
29 #endif
30
31 #include "listimporter.h"
32 #include "general.h"
33 #include <fstream>
34
35 #endif
36
37 /* === U S I N G =========================================================== */
38
39 using namespace std;
40 using namespace etl;
41 using namespace sinfg;
42
43 /* === M A C R O S ========================================================= */
44
45 #define LIST_IMPORTER_CACHE_SIZE        20
46
47 /* === G L O B A L S ======================================================= */
48
49 /* === P R O C E D U R E S ================================================= */
50
51 /* === M E T H O D S ======================================================= */
52
53 ListImporter::ListImporter(const String &filename)
54 {
55         fps=15;
56
57         ifstream stream(filename.c_str());
58
59         if(!stream)
60         {
61                 sinfg::error("Unable to open "+filename);
62                 return;
63         }
64         String line;
65         String prefix=etl::dirname(filename)+ETL_DIRECTORY_SEPERATOR;
66         while(!stream.eof())
67         {
68                 getline(stream,line);
69                 if(line.empty())
70                         continue;
71                 // If we have a framerate, then use it
72                 if(line.find(String("FPS "))==0)
73                 {
74                         fps=atof(String(line.begin()+4,line.end()).c_str());
75                         //sinfg::warning("FPS=%f",fps);
76                         if(!fps)
77                                 fps=15;
78                         continue;
79                 }
80                 filename_list.push_back(prefix+line);
81         }
82 }
83
84 Importer*
85 ListImporter::create(const char *filename)
86 {
87         return new ListImporter(filename);
88 }
89
90 ListImporter::~ListImporter()
91 {
92 }
93
94 bool
95 ListImporter::get_frame(Surface &surface,Time time, ProgressCallback *cb)
96 {
97 //                      DEBUGPOINT();
98         int frame=static_cast<int>(time*fps);
99 //                      DEBUGPOINT();
100         
101         if(!filename_list.size())
102         {
103                 if(cb)cb->error(_("No images in list"));
104                 else sinfg::error(_("No images in list"));
105                 return false;
106         }
107         
108 //                      DEBUGPOINT();
109         if(frame<0)frame=0;
110         if(frame>=(signed)filename_list.size())frame=filename_list.size()-1;
111         
112 //                      DEBUGPOINT();
113         // See if that frame is cached
114         std::list<std::pair<int,Surface> >::iterator iter;
115         for(iter=frame_cache.begin();iter!=frame_cache.end();++iter)
116         {
117                 if(iter->first==frame)
118                 {
119 //                      DEBUGPOINT();
120                         surface.mirror(iter->second);
121                         return static_cast<bool>(surface);
122                 }
123         }
124                 
125         Importer::Handle importer(Importer::open(filename_list[frame]));
126         
127 //      DEBUGPOINT();
128
129         if(!importer)
130         {
131                 if(cb)cb->error(_("Unable to open ")+filename_list[frame]);
132                 else sinfg::error(_("Unable to open ")+filename_list[frame]);
133                 return false;
134         }
135         
136 //      DEBUGPOINT();
137
138         if(!importer->get_frame(surface,0,cb))
139         {
140                 if(cb)cb->error(_("Unable to get frame from ")+filename_list[frame]);
141                 else sinfg::error(_("Unable to get frame from ")+filename_list[frame]);
142                 return false;
143         }
144                 
145 //      DEBUGPOINT();
146
147         if(frame_cache.size()>=LIST_IMPORTER_CACHE_SIZE)
148                 frame_cache.pop_front();
149
150 //      DEBUGPOINT();
151
152         frame_cache.push_back(std::pair<int,Surface>(frame,surface));   
153
154 //      DEBUGPOINT();
155
156         surface.mirror(frame_cache.back().second);
157
158 //      DEBUGPOINT();
159
160         return static_cast<bool>(surface);
161 }
162
163 bool
164 ListImporter::is_animated()
165 {
166         return true;
167 }