TuttleOFX  1
ClipImage.hpp
Go to the documentation of this file.
00001 #ifndef _TUTTLE_HOST_CORE_CLIPIMAGE_HPP_
00002 #define _TUTTLE_HOST_CORE_CLIPIMAGE_HPP_
00003 
00004 #include "Attribute.hpp"
00005 
00006 #include <tuttle/host/attribute/Image.hpp>
00007 #include <tuttle/host/INode.hpp>
00008 #include <tuttle/host/memory/IMemoryCache.hpp>
00009 #include <tuttle/host/ofx/attribute/OfxhClipImage.hpp>
00010 
00011 #include <boost/cstdint.hpp>
00012 
00013 #define SOFXCLIPLENGTH 1
00014 
00015 namespace tuttle {
00016 namespace host {
00017 namespace attribute {
00018 
00019 /**
00020  *
00021  *
00022  */
00023 class ClipImage : public Attribute
00024         , public ofx::attribute::OfxhClipImage
00025 {
00026 friend class INode;
00027 
00028 protected:
00029         std::string _name;
00030         bool _isConnected;
00031         bool _continuousSamples;
00032         memory::IMemoryCache& _memoryCache;
00033 
00034         const ClipImage* _connectedClip; ///< @warning HACK ! to keep the connection @todo remove this !!!!
00035 
00036 public:
00037         ClipImage( INode& effect, const ofx::attribute::OfxhClipImageDescriptor& desc );
00038         
00039         ClipImage( const ClipImage& other );
00040         
00041         ~ClipImage();
00042 
00043 private:
00044         ClipImage& operator=( const ClipImage& other );
00045         
00046 public:
00047         ClipImage* clone() const { return new ClipImage( *this ); }
00048 
00049         const std::string& getName() const { return ofx::attribute::OfxhAttributeAccessor::getName(); }
00050 
00051         /// @warning HACK ! to keep the connection
00052         /// @todo remove this !!!!
00053         void setConnectedClip( const ClipImage& other )
00054         {
00055                 if( isOutput() )
00056                 {
00057                         BOOST_THROW_EXCEPTION( exception::Logic()
00058                             << exception::user( "You can't connect an output Clip !" ) );
00059                 }
00060                 if( !other.isOutput() )
00061                 {
00062                         BOOST_THROW_EXCEPTION( exception::Logic()
00063                             << exception::user( "You can't connect to an input Clip !" ) );
00064                 }
00065                 //TUTTLE_TLOG( TUTTLE_TRACE, "== setConnectedClip: " );
00066                 //TUTTLE_TLOG_VAR( TUTTLE_TRACE, getFullName() );
00067                 //TUTTLE_TLOG_VAR( TUTTLE_TRACE, other.getFullName() );
00068                 
00069                 _connectedClip = &other;
00070                 setConnected();
00071 
00072                 getEditableProperties().setStringProperty( "TuttleFullName", getFullName() );
00073                 getEditableProperties().setStringProperty( "TuttleIdentifier", getClipIdentifier() );
00074         }
00075 
00076         void setUnconnected() { _connectedClip = NULL; setConnected( false ); }
00077 
00078         std::string getFullName() const;
00079 
00080         OfxTime getRemappedTime( const OfxTime time ) const;
00081 
00082         std::string getConnectedClipFullName() const
00083         {
00084                 if( isOutput() || !isConnected() || _connectedClip->getFullName().size() == 0 )
00085                 {
00086                         BOOST_THROW_EXCEPTION( exception::Logic()
00087                             << exception::user( "Input clip " + getFullName() + " is not connected !" ) );
00088                 }
00089                 return _connectedClip->getFullName();
00090         }
00091 
00092         std::string getClipIdentifier() const
00093         {
00094                 if( isOutput() || ! isConnected() )
00095                         return getFullName();
00096                 else
00097                         return getConnectedClipFullName();
00098         }
00099 
00100         /// @todo tuttle: this is really bad...
00101         ClipImage& getConnectedClip()
00102         {
00103                 return const_cast<ClipImage&>( *_connectedClip );
00104         }
00105 
00106         const ClipImage& getConnectedClip() const
00107         {
00108                 return *_connectedClip;
00109         }
00110 
00111         /**
00112          * @brief Get the Raw Unmapped Pixel Depth from the host
00113          *  @returns
00114          *     - kOfxBitDepthNone (implying a clip is unconnected image)
00115          *     - kOfxBitDepthByte
00116          *     - kOfxBitDepthShort
00117          *     - kOfxBitDepthFloat
00118          */
00119         const std::string& getUnmappedBitDepth() const;
00120 
00121         /**
00122          * @brief Get the Raw Unmapped Components from the host
00123          * @returns
00124          *      - kOfxImageComponentNone (implying a clip is unconnected, not valid for an image)
00125          *      - kOfxImageComponentRGBA
00126          *      - kOfxImageComponentRGB
00127          *      - kOfxImageComponentAlpha
00128          */
00129         const std::string& getUnmappedComponents() const;
00130 
00131         #if 0
00132         /**
00133          * @brief PreMultiplication
00134          *      - kOfxImageOpaque - the image is opaque and so has no premultiplication state
00135          *      - kOfxImagePreMultiplied - the image is premultiplied by it's alpha
00136          *      - kOfxImageUnPreMultiplied - the image is unpremultiplied
00137          */
00138         const std::string& getPremult() const { return getNode().getOutputPreMultiplication(); }
00139 
00140         /**
00141          * @brief Field Order - Which spatial field occurs temporally first in a frame.
00142          * @returns
00143          *  - kOfxImageFieldNone - the clip material is unfielded
00144          *  - kOfxImageFieldLower - the clip material is fielded, with image rows 0,2,4.... occuring first in a frame
00145          *  - kOfxImageFieldUpper - the clip material is fielded, with image rows line 1,3,5.... occuring first in a frame
00146          */
00147         const std::string& getFieldOrder() const
00148         {
00149                 /// our clip is pretending to be progressive PAL SD, so return kOfxImageFieldNone
00150                 static const std::string v( kOfxImageFieldNone );
00151 
00152                 return v;
00153         }
00154 
00155         /**
00156          * @brief Continuous Samples
00157          *  0 if the images can only be sampled at discreet times (eg: the clip is a sequence of frames),
00158          *  1 if the images can only be sampled continuously (eg: the clip is infact an animating roto spline and can be rendered anywhen).
00159          */
00160         const bool getContinuousSamples() const                         { return _continuousSamples; }
00161         void       setContinuousSamples( const bool continuousSamples ) { _continuousSamples = continuousSamples; }
00162 
00163         #endif
00164 
00165         /**
00166          * @brief Frame Rate
00167          * The frame rate of a clip or instance's project.
00168          */
00169         double getFrameRate() const;
00170         
00171         void setFrameRate( const double fps );
00172 
00173         /**
00174          * @brief Frame Range (startFrame, endFrame)
00175          * The frame range over which a clip has images.
00176          */
00177         void setFrameRange( const double startFrame, const double endFrame );
00178 
00179         /**
00180          * @brief Unmapped Frame Rate
00181          */
00182         const double getUnmappedFrameRate() const;
00183 
00184         /**
00185          * @brief Unmapped Frame Range -
00186          * The unmaped frame range over which an output clip has images.
00187          */
00188         void setUnmappedFrameRange( const double unmappedStartFrame, const double unmappedEndFrame );
00189 
00190         /**
00191          * @brief override this to fill in the image at the given time.
00192          * The bounds of the image on the image plane should be
00193          * appropriate', typically the value returned in getRegionsOfInterest
00194          * on the effect instance. Outside a render call, the optionalBounds should
00195          * be 'appropriate' for the.
00196          * If bounds is not null, fetch the indicated section of the canonical image plane.
00197          */
00198         tuttle::host::ofx::imageEffect::OfxhImage* getImage( const OfxTime time, const OfxRectD* optionalBounds = NULL );
00199 
00200         /**
00201          * @brief override this to return the rod on the clip
00202          */
00203         OfxRectD fetchRegionOfDefinition( const OfxTime time ) const;
00204 };
00205 
00206 }
00207 }
00208 }
00209 
00210 #endif
00211