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