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