Thanks Riccardo, change now merged and submitted to SVN.  I have also
added this extension into the alias map in Registry.cpp so it'll now
automatically map to the quicktime plugin.

On Wed, Sep 24, 2008 at 2:53 PM, Riccardo Corsi <[EMAIL PROTECTED]> wrote:
> Hi Robert,
>
> attached you'll find a modified version of the QuickTime plugin - the
> only change is that now it includes the ".3gp" movie extension among
> those accepted.
> I tested it on my Widows XP box, and the plugin perfectly handles the
> 3gp movies.
>
> Thanks,
> Ricky
>
> #include "osg/Image"
> #include "osg/Notify"
>
> #include <osg/Geode>
>
> #include <osg/observer_ptr>
>
> #include "osg/GL"
>
> #include "osgDB/FileNameUtils"
> #include "osgDB/Registry"
> #include "osgDB/FileUtils"
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sstream>
>
>
> #ifndef __APPLE__
> #include "Components.h"
> #include "QuickTimeComponents.h"
> #else
> #include <QuickTime/QuickTime.h>
> #endif
>
> #ifndef SEEK_SET
> #  define SEEK_SET 0
> #endif
> #include "QTUtils.h"
> #include "QTLiveUtils.h"
> #include "QTImportExport.h"
> #include "QuicktimeImageStream.h"
> #include "QuicktimeLiveImageStream.h"
>
>
> using namespace osg;
>
> // This class is used as a helper to de-initialize
> // properly quicktime, when the last media loaded
> // with the quicktime plugin is released.
> // All loaded media must be added to the observer
> // (see ReaderWriterQT::readImage() function)
> class QuicktimeExitObserver : public osg::Observer
> {
> public:
>
>   QuicktimeExitObserver () : _instanceCount(0)
>   {
>   }
>   virtual ~QuicktimeExitObserver()
>   {
>   };
>
>   void addMedia(Image* ptr)
>   {
>      ptr->addObserver(this);
>      ++ _instanceCount;
>   }
>
>   virtual void objectDeleted(void*)
>   {
>      -- _instanceCount;
>      if(_instanceCount== 0)
>         exitQuicktime();
>   }
>
> private:
>   unsigned int _instanceCount;
> };
>
>
>
> class ReaderWriterQT : public osgDB::ReaderWriter
> {
> public:
>    ReaderWriterQT::ReaderWriterQT()
>    {
>        supportsExtension("mov","Movie format");
>        supportsExtension("mpg","Movie format");
>        supportsExtension("mpv","Movie format");
>        supportsExtension("mp4","Movie format");
>        supportsExtension("m4v","Movie format");
>        supportsExtension("dv","Movie format");
>        supportsExtension("avi","Movie format");
>        supportsExtension("flv","Movie format");
>        supportsExtension("swf","Movie format");
>        supportsExtension("3gp","Mobile movie format");
>
>        supportsExtension("live","Live video streaming");
>
>        #ifdef QT_HANDLE_IMAGES_ALSO
>        supportsExtension("rgb","rgb image format");
>        supportsExtension("rgba","rgba image format");
>        supportsExtension("jpg","jpg image format");
>        supportsExtension("jpeg","jpeg image format");
>        supportsExtension("tif","tif image format");
>        supportsExtension("tiff","tiff image format");
>        supportsExtension("gif","gif image format");
>        supportsExtension("png","png image format");
>        supportsExtension("pict","pict image format");
>        supportsExtension("pct","pct image format");
>        supportsExtension("tga","tga image format");
>        supportsExtension("psd","psd image format");
>        #endif
>    }
>
>    ReaderWriterQT::~ReaderWriterQT()
>    {
>    }
>
>
>   virtual const char* className() const { return "Default Quicktime Image 
> Reader/Writer"; }
>
>   virtual bool acceptsMovieExtension(const std::string& extension) const
>   {
>      return osgDB::equalCaseInsensitive(extension,"mov") ||
>         osgDB::equalCaseInsensitive(extension,"mpg") ||
>         osgDB::equalCaseInsensitive(extension,"mpv") ||
>         osgDB::equalCaseInsensitive(extension,"mp4") ||
>         osgDB::equalCaseInsensitive(extension,"m4v") ||
>         osgDB::equalCaseInsensitive(extension,"dv")  ||
>         osgDB::equalCaseInsensitive(extension,"avi") ||
>         osgDB::equalCaseInsensitive(extension,"flv") ||
>         osgDB::equalCaseInsensitive(extension,"swf") ||
>         osgDB::equalCaseInsensitive(extension,"3gp");
>   }
>
>   virtual bool acceptsLiveExtension(const std::string& extension) const
>   {
>       return osgDB::equalCaseInsensitive(extension,"live");
>   }
>
>   virtual bool acceptsExtension(const std::string& extension) const
>   {
>      // this should be the only image importer required on the Mac
>      // dont know what else it supports, but these will do
>      return
>
>         #ifdef QT_HANDLE_IMAGES_ALSO
>         osgDB::equalCaseInsensitive(extension,"rgb") ||
>         osgDB::equalCaseInsensitive(extension,"rgba") ||
>         osgDB::equalCaseInsensitive(extension,"jpg") ||
>         osgDB::equalCaseInsensitive(extension,"jpeg") ||
>         osgDB::equalCaseInsensitive(extension,"tif") ||
>         osgDB::equalCaseInsensitive(extension,"tiff") ||
>         osgDB::equalCaseInsensitive(extension,"gif") ||
>         osgDB::equalCaseInsensitive(extension,"png") ||
>         osgDB::equalCaseInsensitive(extension,"pict") ||
>         osgDB::equalCaseInsensitive(extension,"pct") ||
>         osgDB::equalCaseInsensitive(extension,"tga") ||
>         osgDB::equalCaseInsensitive(extension,"psd") ||
>         #endif
>
>         acceptsMovieExtension(extension) ||
>         acceptsLiveExtension(extension);
>   }
>
>   virtual ReadResult readImage(const std::string& file, const 
> osgDB::ReaderWriter::Options* options) const
>   {
>      std::string ext = osgDB::getLowerCaseFileExtension(file);
>      if (osgDB::equalCaseInsensitive(ext,"qt"))
>      {
>         return readImage(osgDB::getNameLessExtension(file),options);
>      }
>
>      if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
>
>      // if the file is a ".live" video encoded string then load as an 
> ImageStream
>      if (acceptsLiveExtension(ext))
>      {
>          long num_video_components;
>          {
>              // Begin QuickTime
>              QTScopedQTMLInitialiser  qt_init;
>              QTScopedMovieInitialiser qt_movie_init;
>              //
>              ComponentDescription video_component_description;
>              video_component_description.componentType         = 'vdig';  /* 
> A unique 4-byte code indentifying the command set */
>              video_component_description.componentSubType      = 0L;      /* 
> Particular flavor of this instance */
>              video_component_description.componentManufacturer = 0L;      /* 
> Vendor indentification */
>              video_component_description.componentFlags        = 0L;      /* 
> 8 each for Component,Type,SubType,Manuf/revision */
>              video_component_description.componentFlagsMask    = 0L;      /* 
> Mask for specifying which flags to consider in search, zero during 
> registration */
>              num_video_components = CountComponents 
> (&video_component_description);
>          }
>          if (osgDB::getNameLessExtension(file) == "devices")
>          {
>              osg::notify(osg::ALWAYS) << " available Video 
> DigitizerComponents : " << num_video_components << std::endl;
>              if (num_video_components)
>              {
>                  // Probe Video Dig
>                  probe_video_digitizer_components();
>                  // Probe SG
>                  std::vector<OSG_SGDeviceList> devices_list = 
> probe_sequence_grabber_components();
>                  if (devices_list.size())
>                  {
>                      // Video
>                      OSG_SGDeviceList& video_device_list = devices_list[0];
>                      // Print
>                      osg::notify(osg::ALWAYS) << std::endl;
>                      osg::notify(osg::ALWAYS) << "Video Component/Input IDs 
> follow: " << std::endl;
>                      osg::notify(osg::ALWAYS) << std::endl;
>                      for (unsigned int device_input = 0; device_input < 
> video_device_list.size(); ++device_input)
>                      {
>                          OSG_SGDevicePair device_pair = 
> video_device_list[device_input];
>                          osg::notify(osg::ALWAYS) << 
> device_pair.first.c_str() << "    " << device_pair.second.c_str() << 
> std::endl;
>                      }
>                  }
>                  if (devices_list.size() > 1)
>                  {
>                      // Audio
>                      OSG_SGDeviceList& audio_device_list = devices_list[1];
>                      // Print
>                      osg::notify(osg::ALWAYS) << std::endl;
>                      osg::notify(osg::ALWAYS) << "Audio Component/Input IDs 
> follow: " << std::endl;
>                      osg::notify(osg::ALWAYS) << std::endl;
>                      for (unsigned int device_input = 0; device_input < 
> audio_device_list.size(); ++device_input)
>                      {
>                          OSG_SGDevicePair device_pair = 
> audio_device_list[device_input];
>                          osg::notify(osg::ALWAYS) << 
> device_pair.first.c_str() << "    " << device_pair.second.c_str() << 
> std::endl;
>                      }
>                  }
>              }
>              return ReadResult::FILE_NOT_HANDLED;
>          }
>          else
>          {
>              osg::notify(osg::DEBUG_INFO) << " available Video 
> DigitizerComponents : " << num_video_components << std::endl;
>              if (num_video_components)
>              {
>                  // Note from Riccardo Corsi
>                  // Quicktime initialization is done here, when a media is 
> found
>                  // and before any image or movie is loaded.
>                  // After the first call the function does nothing.
>                  // The cleaning up is left to the QuicktimeExitObserver (see 
> below)
>                  initQuicktime();
>                  //
>                  QuicktimeLiveImageStream* p_qt_image_stream = new 
> QuicktimeLiveImageStream(osgDB::getNameLessExtension(file));
>                  // add the media to the observer for proper clean up on exit
>                  _qtExitObserver.addMedia(p_qt_image_stream);
>                  return p_qt_image_stream;
>              }
>              else
>              {
>                  osg::notify(osg::DEBUG_INFO) << "No available Video 
> DigitizerComponents : " <<  std::endl;
>                  return ReadResult::FILE_NOT_HANDLED;
>              }
>          }
>      }
>
>      // Not an encoded "live" psuedo file - so check a real file exists
>      std::string fileName = osgDB::findDataFile( file,  options);
>      if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
>
>      // Note from Riccardo Corsi
>      // Quicktime initialization is done here, when a media is found
>      // and before any image or movie is loaded.
>      // After the first call the function does nothing.
>      // The cleaning up is left to the QuicktimeExitObserver (see below)
>      initQuicktime();
>
>
>      // if the file is a movie file then load as an ImageStream.
>      if (acceptsMovieExtension(ext))
>      {
>         // note from Robert Osfield when integrating, we should probably have 
> so
>         // error handling mechanism here.  Possibly move the load from
>         // the constructor to a seperate load method, and have a valid
>         // state on the ImageStream... will integrated as is right now
>         // to get things off the ground.
>         QuicktimeImageStream* moov = new QuicktimeImageStream(fileName);
>         // moov->play();
>
>         // add the media to the observer for proper clean up on exit
>         _qtExitObserver.addMedia(moov);
>
>         return moov;
>      }
>
>        QuicktimeImportExport importer;
>
>        std::ifstream is;
>        is.open (fileName.c_str(), std::ios::binary | std::ios::in );
>        is.seekg (0, std::ios::end);
>        long length = is.tellg();
>        is.seekg (0, std::ios::beg);
>
>        osg::ref_ptr<osg::Image> image = importer.readFromStream(is, fileName, 
> length);
>        is.close();
>        if (!importer.success() || (image == NULL)) {
>            osg::notify(osg::WARN) << "Error reading file " << file << " : " 
> << importer.getLastErrorString() << std::endl;
>            return ReadResult::ERROR_IN_READING_FILE;
>        }
>
>      _qtExitObserver.addMedia(image.get());
>
>      return image.release();
>   }
>
>    virtual ReadResult readImage (std::istream& is, const 
> osgDB::ReaderWriter::Options* options=NULL) const
>    {
>        std::string filename = "";
>        long sizeHint(0);
>        // check options for a file-type-hint
>        if (options) {
>            std::istringstream iss(options->getOptionString());
>            std::string opt;
>            while (iss >> opt)
>            {
>                int index = opt.find( "=" );
>                if( opt.substr( 0, index ) == "filename" ||
>                    opt.substr( 0, index ) == "FILENAME" )
>                {
>                    filename = opt.substr( index+1 );
>                } else if( opt.substr( 0, index ) == "size" ||
>                    opt.substr( 0, index ) == "SIZE" )
>                {
>                    std::string sizestr = opt.substr( index+1 );
>                    sizeHint = atol(sizestr.c_str());
>                }
>            }
>        }
>
>        QuicktimeImportExport importer;
>        osg::ref_ptr<osg::Image> image = importer.readFromStream(is, filename, 
> sizeHint);
>
>        if (!importer.success() || (image == NULL)) {
>            osg::notify(osg::WARN) << "Error reading from stream "  << 
> importer.getLastErrorString() << std::endl;
>            return ReadResult::ERROR_IN_READING_FILE;
>        }
>        _qtExitObserver.addMedia(image.get());
>        return image.release();
>
>    }
>
>    virtual WriteResult writeImage(const osg::Image &img,const std::string& 
> fileName, const osgDB::ReaderWriter::Options*) const
>    {
>        std::string ext = osgDB::getFileExtension(fileName);
>        if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
>
>        initQuicktime();
>
>        //Buidl map  of extension <-> osFileTypes
>        std::map<std::string, OSType> extmap;
>
>        extmap.insert(std::pair<std::string, OSType>("jpg",  kQTFileTypeJPEG));
>        extmap.insert(std::pair<std::string, OSType>("jpeg", kQTFileTypeJPEG));
>        extmap.insert(std::pair<std::string, OSType>("bmp",  kQTFileTypeBMP));
>        extmap.insert(std::pair<std::string, OSType>("tif",  kQTFileTypeTIFF));
>        extmap.insert(std::pair<std::string, OSType>("tiff", kQTFileTypeTIFF));
>        extmap.insert(std::pair<std::string, OSType>("png",  kQTFileTypePNG));
>        extmap.insert(std::pair<std::string, OSType>("gif",  kQTFileTypeGIF));
>        extmap.insert(std::pair<std::string, OSType>("psd",  
> kQTFileTypePhotoShop));
>        extmap.insert(std::pair<std::string, OSType>("sgi",  
> kQTFileTypeSGIImage));
>        extmap.insert(std::pair<std::string, OSType>("rgb",  
> kQTFileTypeSGIImage));
>        extmap.insert(std::pair<std::string, OSType>("rgba", 
> kQTFileTypeSGIImage));
>
>        std::map<std::string, OSType>::iterator cur = extmap.find(ext);
>
>        // can not handle this type of file, perhaps a movie?
>        if (cur == extmap.end())
>         return WriteResult::FILE_NOT_HANDLED;
>
>        std::ofstream os(fileName.c_str(), std::ios::binary | std::ios::trunc 
> | std::ios::out);
>        if(os.good())
>        {
>            QuicktimeImportExport exporter;
>            exporter.writeToStream(os, const_cast<osg::Image*>(&img), 
> fileName);
>
>            if (exporter.success())
>                return WriteResult::FILE_SAVED;
>        }
>
>        return WriteResult::ERROR_IN_WRITING_FILE;
>    }
>
>    virtual WriteResult writeImage (const osg::Image& img, std::ostream& os, 
> const Options* options=NULL) const
>    {
>        std::string filename = "file.jpg"; // use jpeg if not otherwise 
> specified
>
>        if (options) {
>            std::istringstream iss(options->getOptionString());
>            std::string opt;
>            while (iss >> opt)
>            {
>                int index = opt.find( "=" );
>                if( opt.substr( 0, index ) == "filename" ||
>                    opt.substr( 0, index ) == "FILENAME" )
>                {
>                    filename = opt.substr( index+1 );
>                }
>            }
>        }
>
>        QuicktimeImportExport exporter;
>        exporter.writeToStream(os, const_cast<osg::Image*>(&img), filename);
>
>        if (exporter.success())
>            return WriteResult::FILE_SAVED;
>
>        return WriteResult::ERROR_IN_WRITING_FILE;
>    }
>
>
>    mutable QuicktimeExitObserver _qtExitObserver;
> };
>
> // now register with Registry to instantiate the above
> // reader/writer.
> REGISTER_OSGPLUGIN(quicktime, ReaderWriterQT)
>
> _______________________________________________
> osg-submissions mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
>
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to