Gnash 0.8.9
|
00001 // 00002 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 00003 // 2011 Free Software Foundation, Inc 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 // The SWFMovieDefinition is the 'root' definition of a SWF movie, including 00020 // movies loaded into another SWF file. Each self-contained SWF file has exactly 00021 // one SWFMovieDefinition. 00022 00023 #ifndef GNASH_SWF_MOVIE_DEFINITION_H 00024 #define GNASH_SWF_MOVIE_DEFINITION_H 00025 00026 #ifdef HAVE_CONFIG_H 00027 #include "gnashconfig.h" // for USE_SWFTREE 00028 #endif 00029 00030 #include "smart_ptr.h" 00031 #include "movie_definition.h" // for inheritance 00032 #include "DefinitionTag.h" // for boost::intrusive_ptr visibility of dtor 00033 #include "StringPredicates.h" 00034 #include "SWFRect.h" 00035 #include "GnashNumeric.h" 00036 #include "GnashAlgorithm.h" 00037 00038 #include <boost/intrusive_ptr.hpp> 00039 #include <vector> 00040 #include <map> 00041 #include <set> 00042 #include <string> 00043 #include <memory> 00044 #include <boost/thread/thread.hpp> 00045 #include <boost/thread/condition.hpp> 00046 #include <boost/thread/barrier.hpp> 00047 #include <boost/scoped_ptr.hpp> 00048 00049 // Forward declarations 00050 namespace gnash { 00051 namespace image { 00052 class JpegInput; 00053 } 00054 class IOChannel; 00055 class SWFMovieDefinition; 00056 class SWFStream; 00057 class movie_root; 00058 class MovieClip; 00059 class SWFMovie; 00060 class RunResources; 00061 class Font; 00062 } 00063 00064 namespace gnash { 00065 00067 class SWFMovieLoader 00068 { 00069 public: 00070 00071 SWFMovieLoader(SWFMovieDefinition& md); 00072 00073 ~SWFMovieLoader(); 00074 00076 // 00081 bool start(); 00082 00084 bool started() const; 00085 00087 bool isSelfThread() const; 00088 00089 private: 00090 00091 SWFMovieDefinition& _movie_def; 00092 00093 mutable boost::mutex _mutex; 00094 std::auto_ptr<boost::thread> _thread; 00095 00096 // Barrier to ensure that _thread 00097 // is initialized before the loader thread 00098 // continues execution 00099 boost::barrier _barrier; 00100 00102 static void execute(SWFMovieLoader& ml, SWFMovieDefinition* md); 00103 00104 }; 00105 00107 // 00111 class CharacterDictionary 00112 { 00113 public: 00114 00116 // 00119 typedef std::map<int, boost::intrusive_ptr<SWF::DefinitionTag> > 00120 CharacterContainer; 00121 00122 typedef CharacterContainer::iterator CharacterIterator; 00123 00124 typedef CharacterContainer::const_iterator CharacterConstIterator; 00125 00127 // 00130 boost::intrusive_ptr<SWF::DefinitionTag> getDisplayObject(int id) const; 00131 00133 // 00136 void addDisplayObject(int id, boost::intrusive_ptr<SWF::DefinitionTag> c); 00137 00139 CharacterIterator begin() { return _map.begin(); } 00140 00142 CharacterConstIterator begin() const { return _map.begin(); } 00143 00145 CharacterIterator end() { return _map.end(); } 00146 00148 CharacterConstIterator end() const { return _map.end(); } 00149 00150 friend std::ostream& operator<<(std::ostream& o, 00151 const CharacterDictionary& cd); 00152 00153 private: 00154 00155 CharacterContainer _map; 00156 00157 }; 00158 00159 00161 // 00165 class SWFMovieDefinition : public movie_definition 00166 { 00167 public: 00168 00170 // 00173 SWFMovieDefinition(const RunResources& runResources); 00174 00175 ~SWFMovieDefinition(); 00176 00178 size_t get_frame_count() const { 00179 return m_frame_count; 00180 } 00181 00183 float get_frame_rate() const { 00184 return m_frame_rate; 00185 } 00186 00188 const SWFRect& get_frame_size() const { 00189 return m_frame_size; 00190 } 00191 00192 size_t get_width_pixels() const { 00193 return std::ceil(twipsToPixels(m_frame_size.width())); 00194 } 00195 00196 size_t get_height_pixels() const { 00197 return std::ceil(twipsToPixels(m_frame_size.height())); 00198 } 00199 00201 void setAS3() { 00202 _as3 = true; 00203 } 00204 00206 bool isAS3() const { 00207 return _as3; 00208 } 00209 00211 // 00214 virtual int get_version() const { return m_version; } 00215 00217 // 00225 virtual size_t get_loading_frame() const; 00226 00228 // 00231 size_t get_bytes_loaded() const { 00232 boost::mutex::scoped_lock lock(_bytes_loaded_mutex); 00233 return _bytes_loaded; 00234 } 00235 00237 size_t get_bytes_total() const { 00238 return m_file_length; 00239 } 00240 00241 virtual void importResources(boost::intrusive_ptr<movie_definition> source, 00242 const Imports& imports); 00243 00244 virtual void addDisplayObject(boost::uint16_t id, SWF::DefinitionTag* c); 00245 00247 SWF::DefinitionTag* getDefinitionTag(boost::uint16_t id) const; 00248 00249 // See dox in movie_definition 00250 // 00251 // locks _namedFramesMutex 00252 bool get_labeled_frame(const std::string& label, size_t& frame_number) 00253 const; 00254 00255 void add_font(int font_id, boost::intrusive_ptr<Font> f); 00256 00257 Font* get_font(int font_id) const; 00258 00259 Font* get_font(const std::string& name, bool bold, bool italic) const; 00260 00261 // See dox in movie_definition.h 00262 CachedBitmap* getBitmap(int DisplayObject_id) const; 00263 00264 // See dox in movie_definition.h 00265 void addBitmap(int DisplayObject_id, boost::intrusive_ptr<CachedBitmap> im); 00266 00267 // See dox in movie_definition.h 00268 sound_sample* get_sound_sample(int DisplayObject_id) const; 00269 00270 // See dox in movie_definition.h 00271 virtual void add_sound_sample(int DisplayObject_id, sound_sample* sam); 00272 00273 // See dox in movie_definition.h 00274 virtual void set_loading_sound_stream_id(int id) { 00275 m_loading_sound_stream = id; 00276 } 00277 00278 // See dox in movie_definition.h 00279 int get_loading_sound_stream_id() const { 00280 return m_loading_sound_stream; 00281 } 00282 00283 // See dox in movie_definition.h 00284 void addControlTag(boost::intrusive_ptr<SWF::ControlTag> tag) { 00285 assert(tag); 00286 boost::mutex::scoped_lock lock(_frames_loaded_mutex); 00287 m_playlist[_frames_loaded].push_back(tag); 00288 } 00289 00290 // See dox in movie_definition.h 00291 // 00292 // locks _namedFramesMutex and _frames_loaded_mutex 00293 // 00294 void add_frame_name(const std::string& name); 00295 00298 void set_jpeg_loader(std::auto_ptr<image::JpegInput> j_in); 00299 00300 // See dox in movie_definition.h 00301 image::JpegInput* get_jpeg_loader() const { 00302 return m_jpeg_in.get(); 00303 } 00304 00305 virtual const PlayList* getPlaylist(size_t frame_number) const { 00306 00307 #ifndef NDEBUG 00308 boost::mutex::scoped_lock lock(_frames_loaded_mutex); 00309 assert(frame_number <= _frames_loaded); 00310 #endif 00311 00312 PlayListMap::const_iterator it = m_playlist.find(frame_number); 00313 if ( it == m_playlist.end() ) return NULL; 00314 else return &(it->second); 00315 } 00316 00318 // 00326 bool readHeader(std::auto_ptr<IOChannel> in, const std::string& url); 00327 00329 // 00335 bool completeLoad(); 00336 00340 bool ensure_frame_loaded(size_t framenum) const; 00341 00343 // 00348 void read_all_swf(); 00349 00351 // 00359 Movie* createMovie(Global_as& gl, DisplayObject* parent = 0); 00360 00361 virtual DisplayObject* createDisplayObject(Global_as&, DisplayObject*) 00362 const { 00363 return 0; 00364 } 00365 00366 virtual const std::string& get_url() const { return _url; } 00367 00369 // 00371 // 00376 boost::uint16_t exportID(const std::string& symbol) const; 00377 00379 // 00381 // 00385 void registerExport(const std::string& symbol, boost::uint16_t id); 00386 00387 00388 #ifdef USE_SWFTREE 00389 00390 // These methods attach the contents of the METADATA tag 00391 // to a movie_definition. 00392 virtual void storeDescriptiveMetadata(const std::string& data) { 00393 _metadata = data; 00394 } 00395 00396 virtual const std::string& getDescriptiveMetadata() const { 00397 return _metadata; 00398 } 00399 00400 #endif 00401 00402 private: 00403 00404 #ifdef USE_SWFTREE 00405 // For storing descriptive metadata (information only) 00406 std::string _metadata; 00407 #endif 00408 00410 CharacterDictionary _dictionary; 00411 00413 mutable boost::mutex _dictionaryMutex; 00414 00415 typedef std::map<int, boost::intrusive_ptr<Font> > FontMap; 00416 FontMap m_fonts; 00417 00418 typedef std::map<int, boost::intrusive_ptr<CachedBitmap> > Bitmaps; 00419 Bitmaps _bitmaps; 00420 00421 typedef std::map<int, boost::intrusive_ptr<sound_sample> > SoundSampleMap; 00422 SoundSampleMap m_sound_samples; 00423 00424 typedef std::map<size_t, PlayList> PlayListMap; 00425 00427 PlayListMap m_playlist; 00428 00430 typedef std::map<std::string, size_t, StringNoCaseLessThan> NamedFrameMap; 00431 NamedFrameMap _namedFrames; 00432 00433 // Mutex protecting access to _namedFrames 00434 mutable boost::mutex _namedFramesMutex; 00435 00437 typedef std::map<std::string, boost::uint16_t, 00438 StringNoCaseLessThan> Exports; 00439 00441 Exports _exportTable; 00442 00443 // Mutex protecting access to the export map. 00444 mutable boost::mutex _exportedResourcesMutex; 00445 00448 typedef std::vector<boost::intrusive_ptr<movie_definition> > ImportVect; 00449 ImportVect m_import_source_movies; 00450 00451 SWFRect m_frame_size; 00452 float m_frame_rate; 00453 size_t m_frame_count; 00454 int m_version; 00455 00457 size_t _frames_loaded; 00458 00460 // 00464 mutable boost::mutex _frames_loaded_mutex; 00465 00467 mutable boost::condition _frame_reached_condition; 00468 00470 // 00473 mutable size_t _waiting_for_frame; 00474 00476 unsigned long _bytes_loaded; 00477 00479 // 00483 mutable boost::mutex _bytes_loaded_mutex; 00484 00485 int m_loading_sound_stream; 00486 00487 boost::uint32_t m_file_length; 00488 00489 std::auto_ptr<image::JpegInput> m_jpeg_in; 00490 00491 std::string _url; 00492 00494 boost::scoped_ptr<SWFStream> _str; 00495 00496 std::auto_ptr<IOChannel> _in; 00497 00499 size_t _swf_end_pos; 00500 00502 SWFMovieLoader _loader; 00503 00511 virtual void incrementLoadedFrames(); 00512 00514 // 00516 void setBytesLoaded(unsigned long bytes) 00517 { 00518 boost::mutex::scoped_lock lock(_bytes_loaded_mutex); 00519 _bytes_loaded=bytes; 00520 } 00521 00523 bool _loadingCanceled; 00524 00526 std::set< boost::intrusive_ptr<movie_definition> > _importSources; 00527 00528 private: 00529 00532 // 00536 const RunResources& _runResources; 00537 00538 bool _as3; 00539 00540 }; 00541 00542 } // namespace gnash 00543 00544 #endif