1 //--- 2 // License: MIT 3 // 4 // Author: David Burken 5 // 6 // Description: 7 // 8 // Class to fill a patch from input tiles requested on even tile boundaries with 9 // a tile size typically matching the input, with some output tile size 10 // different from the input. 11 // 12 //--- 13 // $Id$ 14 15 #include <ossim/imaging/ossimTiledImagePatch.h> 16 #include <ossim/base/ossimIrect.h> 17 #include <ossim/imaging/ossimImageDataFactory.h> 18 19 RTTI_DEF1(ossimTiledImagePatch, "ossimTiledImagePatch", ossimImageSourceFilter) 20 21 ossimTiledImagePatch::ossimTiledImagePatch() 22 : 23 ossimImageSourceFilter(), // base class 24 m_tile(0), 25 m_inputTileSize() 26 { 27 m_inputTileSize.makeNan(); 28 } 29 30 ossimTiledImagePatch::~ossimTiledImagePatch() 31 { 32 } 33 34 void ossimTiledImagePatch::initialize() 35 { 36 //--- 37 // Call the base class initialize. 38 // Note: This will reset "theInputConnection" if it changed... 39 //--- 40 ossimImageSourceFilter::initialize(); 41 42 // Clear everything. The tile will be allocated on first getTile call. 43 m_tile = 0; 44 ossimTiledImageHandler()45 // Get the input tile sizes: 46 if ( theInputConnection ) 47 { 48 if ( m_inputTileSize.hasNans() ) 49 { 50 m_inputTileSize.x = theInputConnection->getTileWidth(); 51 m_inputTileSize.y = theInputConnection->getTileHeight(); 52 } 53 } 54 } 55 56 ossimRefPtr<ossimImageData> ossimTiledImagePatch::getTile( 57 const ossimIrect& tileRect, ossim_uint32 resLevel) 58 { 59 if ( m_tile.valid() == false ) 60 { ~ossimTiledImageHandler()61 allocateTile(); // First time through... 62 } 63 64 if ( m_tile.valid() ) 65 { 66 // Image rectangle must be set prior to calling getTile. 67 m_tile->setImageRectangle(tileRect); 68 69 if ( getTile( m_tile.get(), resLevel ) == false ) close()70 { 71 if (m_tile->getDataObjectStatus() != OSSIM_NULL) 72 { 73 m_tile->makeBlank(); 74 } 75 } 76 } 77 78 return m_tile; 79 } 80 81 bool ossimTiledImagePatch::getTile(ossimImageData* result, ossim_uint32 resLevel) 82 { 83 bool status = false; 84 isOpen() const85 if ( isSourceEnabled() && theInputConnection && isValidRLevel(resLevel) && 86 result && (m_inputTileSize.hasNans() == false) ) 87 { 88 status = true; 89 90 // See if any point of the requested tile is in the image. 91 ossimIrect tile_rect = result->getImageRectangle(); 92 93 ossimIrect input_rect; 94 theInputConnection->getBoundingRect( input_rect, resLevel ); 95 96 if ( tile_rect.intersects( input_rect ) ) 97 { 98 // Initialize the tile if needed as we're going to stuff it. 99 if (result->getDataObjectStatus() == OSSIM_NULL) 100 { 101 result->initialize(); 102 } 103 104 // If empty imput tiles are pulled the entire output tile might not be filled. 105 result->makeBlank(); 106 107 // Clip rect: 108 ossimIrect clip_rect = tile_rect.clipToRect( input_rect ); 109 110 // Zero based start point. 111 ossimIpt inputOrigin = clip_rect.ul() - input_rect.ul(); 112 113 // Zero based point on input tile boundary. 114 inputOrigin.x = (inputOrigin.x / m_inputTileSize.x) * m_inputTileSize.x; 115 inputOrigin.y = (inputOrigin.y / m_inputTileSize.y) * m_inputTileSize.y; 116 117 // Shift back to original space: 118 inputOrigin += input_rect.ul(); 119 120 // Line loop: 121 for ( ossim_int32 y = inputOrigin.y; y < clip_rect.lr().y; y += m_inputTileSize.y ) 122 { 123 // Sample loop: 124 for ( ossim_int32 x = inputOrigin.x; x < clip_rect.lr().x; x += m_inputTileSize.x ) 125 { 126 ossimIrect rect( x, y, x + m_inputTileSize.x - 1, y + m_inputTileSize.y - 1 ); 127 128 ossimRefPtr<ossimImageData> tile = theInputConnection->getTile( rect, resLevel ); 129 if ( tile.valid() ) 130 { 131 if ( (tile->getDataObjectStatus() != OSSIM_NULL) && 132 (tile->getDataObjectStatus() != OSSIM_EMPTY) ) 133 { 134 result->loadTile( tile.get() ); 135 } 136 } 137 } 138 } 139 140 result->validate(); 141 142 } 143 else 144 { 145 // No part of requested tile within the image rectangle. 146 result->makeBlank(); 147 } 148 149 } // matches: if( isOpen() && isSourceEnabled() && isValidRLevel(level) ) 150 151 return status; 152 } 153 154 ossimString ossimTiledImagePatch::getClassName() const 155 { 156 return ossimString("ossimTiledImagePatch"); 157 } 158 159 ossimString ossimTiledImagePatch::getLongName()const 160 { 161 return ossimString("OSSIM tiled image patch"); 162 } 163 164 ossimString ossimTiledImagePatch::getShortName()const 165 { 166 return ossimString("tiled_image_patch"); 167 } 168 169 const ossimIpt& ossimTiledImagePatch::getInputTileSize() const 170 { 171 return m_inputTileSize; 172 } 173 174 bool ossimTiledImagePatch::setInputTileSize( const ossimIpt& tileSize ) 175 { 176 bool status = true; 177 if ( ( tileSize.hasNans() == false ) && (tileSize.x > 0) && (tileSize.y > 0) ) 178 { 179 m_inputTileSize = tileSize; 180 } 181 else 182 { 183 m_inputTileSize.makeNan(); 184 status = false; 185 } 186 return status; 187 } 188 189 bool ossimTiledImagePatch::loadState(const ossimKeywordlist& kwl, const char* prefix) 190 { 191 std::string myPrefix = (prefix ? prefix : "" ); 192 std::string key = "tile_size"; 193 std::string value = kwl.findKey( myPrefix, key ); 194 if ( value.size() ) 195 { 196 m_inputTileSize.toPoint( value ); 197 } 198 return ossimImageSourceFilter::loadState(kwl, prefix); 199 } 200 201 bool ossimTiledImagePatch::saveState(ossimKeywordlist& kwl, const char* prefix)const 202 { 203 std::string myPrefix = (prefix ? prefix : "" ); 204 std::string key = "tile_size"; 205 kwl.addPair( myPrefix, key, m_inputTileSize.toString().string() ); 206 return ossimImageSourceFilter::saveState(kwl, prefix); 207 } 208 209 void ossimTiledImagePatch::allocateTile() 210 { 211 m_tile = ossimImageDataFactory::instance()->create(this,this); 212 m_tile->initialize(); 213 } 214 215 bool ossimTiledImagePatch::isValidRLevel(ossim_uint32 resLevel) const 216 { 217 // return (resLevel < m_inputBoundingRect.size()); 218 return (resLevel < theInputConnection->getNumberOfDecimationLevels()); 219 } 220 221 // Private to disallow use... 222 ossimTiledImagePatch::ossimTiledImagePatch(const ossimTiledImagePatch&) 223 : m_tile(0), 224 m_inputTileSize() 225 { 226 } 227 228 // Private to disallow use... 229 ossimTiledImagePatch& ossimTiledImagePatch::operator=(const ossimTiledImagePatch&) 230 { 231 return *this; 232 } 233 234 235