TuttleOFX
1
|
00001 #ifndef _TUTTLE_OFXTOGIL_IMAGE_HPP_ 00002 #define _TUTTLE_OFXTOGIL_IMAGE_HPP_ 00003 00004 #include <tuttle/plugin/image.hpp> 00005 00006 #include <ofxsImageEffect.h> 00007 00008 #include <boost/gil/utilities.hpp> 00009 #include <boost/gil/image.hpp> 00010 #include <boost/gil/image_view.hpp> 00011 #include <boost/gil/image_view_factory.hpp> 00012 00013 00014 namespace tuttle { 00015 namespace plugin { 00016 00017 /** 00018 * @brief Return a full gil view of an image. 00019 * If we only have a tiled image, we use subimage_view to fit to the rod. 00020 * @param img the ofx image object 00021 * @param rod normally we don't need this parameter because we can get it from the image, 00022 * but there is a bug in nuke (which return the bounds), 00023 * so we need to use the rod of the clip and not from the image. 00024 */ 00025 template<class View> 00026 View getGilView( OFX::Image* img, const OfxRectI& pixelRod, const EImageOrientation orientation ) 00027 { 00028 using namespace boost::gil; 00029 typedef typename View::value_type Pixel; 00030 //TUTTLE_TLOG( TUTTLE_TRACE, "getGilView => " << img->getUniqueIdentifier() ); 00031 00032 // OfxRectI imgrod = img->getRegionOfDefinition(); // bug in nuke returns bounds... not the clip rod with renderscale... 00033 const OfxRectI bounds = img->getBounds(); 00034 // TUTTLE_TLOG_VAR( TUTTLE_TRACE, bounds ); 00035 // TUTTLE_TLOG_VAR( TUTTLE_TRACE, imgrod ); 00036 // TUTTLE_TLOG_VAR( TUTTLE_TRACE, rod ); 00037 const point2<int> tileSize = point2<int>( bounds.x2 - bounds.x1, 00038 bounds.y2 - bounds.y1 ); 00039 00040 // Build view 00041 /** 00042 * About image ordering from OpenFX documentation: 00043 * 00044 * Images are always left to right, bottom to top, 00045 * with the pixel data pointer being at the bottom left of the image. 00046 * The pixels in a scan line are contiguously packed. 00047 * Scanlines need not be contiguously packed. 00048 * The number of bytes between between a pixel in the same column, 00049 * but separated by a scan line is known as the rowbytes of an image. 00050 * Rowbytes can be negative, allowing for compositing systems with a native 00051 * top to bottom scanline order to trivially support bottom to top images. 00052 */ 00053 View tileView = interleaved_view( tileSize.x, tileSize.y, 00054 static_cast<Pixel*>( img->getPixelData() ), 00055 img->getRowDistanceBytes() ); 00056 00057 TUTTLE_TLOG( TUTTLE_INFO, "[OFX to Gil] Row distance from image " << img->getRowDistanceBytes() << " bytes" ); 00058 TUTTLE_TLOG( TUTTLE_INFO, "[OFX to Gil] Tile view, row size = " << tileView.pixels().row_size() ); 00059 00060 View fullView; 00061 const bool isTile = ( 00062 bounds.x1 != pixelRod.x1 || bounds.y1 != pixelRod.y1 || 00063 bounds.x2 != pixelRod.x2 || bounds.y2 != pixelRod.y2 ); 00064 // if the tile is equals to the full image 00065 // directly return the tile 00066 if( ! isTile ) 00067 { 00068 TUTTLE_TLOG( TUTTLE_INFO, "[OFX to Gil] Tile is equal to the full view" ); 00069 fullView = tileView; 00070 } 00071 else 00072 { 00073 // view the tile as a full image 00074 ////TUTTLE_TLOG( TUTTLE_TRACE, "Tile to full view" ); 00075 fullView = subimage_view( tileView, pixelRod.x1 - bounds.x1, pixelRod.y1 - bounds.y1, pixelRod.x2 - pixelRod.x1, pixelRod.y2 - pixelRod.y1 ); 00076 } 00077 00078 TUTTLE_TLOG( TUTTLE_INFO, "[OFX to Gil] Full view, row size = " << fullView.pixels().row_size() ); 00079 00080 View resView = fullView; 00081 switch( orientation ) 00082 { 00083 case eImageOrientationIndependant: // use memory order 00084 { 00085 TUTTLE_TLOG( TUTTLE_INFO, "[OFX to Gil] Image orientation independant" ); 00086 if( isTile ) // can't manage ordering 00087 break; 00088 00089 if( img->getRowDistanceBytes() < 0 ) // if the host use buffer ordered from top to bottom 00090 { 00091 resView = flipped_up_down_view( fullView ); 00092 } 00093 break; 00094 } 00095 case eImageOrientationFromTopToBottom: 00096 { 00097 TUTTLE_TLOG( TUTTLE_INFO, "[OFX to Gil] Image orientation from top to bottom" ); 00098 BOOST_ASSERT( ! isTile ); // can't manage ordering with tiles currently (no RoW information in OpenFX) 00099 00100 resView = flipped_up_down_view( fullView ); 00101 break; 00102 } 00103 case eImageOrientationFromBottomToTop: 00104 { 00105 TUTTLE_TLOG( TUTTLE_INFO, "[OFX to Gil] Image orientation from bottom to top" ); 00106 // by default in OpenFX we are in this order 00107 break; 00108 } 00109 } 00110 00111 ////TUTTLE_TLOG_VAR( TUTTLE_TRACE, resView.pixels().row_size() ); 00112 return resView; 00113 } 00114 00115 00116 } 00117 } 00118 00119 00120 00121 #endif 00122