1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License: LGPL
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author: Garrett Potts
9 //
10 //*************************************************************************
11 // $Id: ossimRectangleCutFilter.cpp 22953 2014-11-05 19:19:28Z dburken $
12 #include <ossim/imaging/ossimRectangleCutFilter.h>
13 #include <ossim/base/ossimTrace.h>
14 #include <ossim/base/ossimNotifyContext.h>
15 #include <ossim/base/ossimCommon.h>
16 #include <ossim/imaging/ossimImageData.h>
17 #include <ossim/imaging/ossimImageGeometry.h>
18
19 using namespace std;
20
21 static ossimTrace traceDebug("ossimRectangleCutFilter:debug");
22
23 RTTI_DEF1(ossimRectangleCutFilter,
24 "ossimRectangleCutFilter",
25 ossimImageSourceFilter);
26
ossimRectangleCutFilter(ossimObject * owner,ossimImageSource * inputSource)27 ossimRectangleCutFilter::ossimRectangleCutFilter(ossimObject* owner,
28 ossimImageSource* inputSource)
29 :ossimImageSourceFilter(owner, inputSource),
30 theCutType(OSSIM_RECTANGLE_NULL_OUTSIDE)
31 {
32 theRectangle.makeNan();
33 }
34
ossimRectangleCutFilter(ossimImageSource * inputSource)35 ossimRectangleCutFilter::ossimRectangleCutFilter(ossimImageSource* inputSource)
36 :ossimImageSourceFilter(NULL, inputSource),
37 theCutType(OSSIM_RECTANGLE_NULL_OUTSIDE)
38 {
39 theRectangle.makeNan();
40 }
41
42
getTile(const ossimIrect & rect,ossim_uint32 resLevel)43 ossimRefPtr<ossimImageData> ossimRectangleCutFilter::getTile(
44 const ossimIrect& rect,
45 ossim_uint32 resLevel)
46 {
47 ossimRefPtr<ossimImageData> tile = 0;
48
49 if ( theInputConnection && isSourceEnabled() && ( theRectangle.hasNans() == false ) )
50 {
51 ossim_int32 decimationIndex = min((ossim_int32)resLevel,
52 (ossim_int32)theDecimationList.size()-1);
53
54 // Compute cut rect for resLevel:
55 ossimIrect cutRect = theRectangle*theDecimationList[decimationIndex];
56
57 // Check intersection of our cut rect:
58 bool requestIntersects = rect.intersects( cutRect );
59 bool requestCompletelyWithin = rect.completely_within(cutRect);
60
61 if ( ( ( theCutType == OSSIM_RECTANGLE_NULL_OUTSIDE ) && requestIntersects ) ||
62 ( ( theCutType == OSSIM_RECTANGLE_NULL_INSIDE ) && !requestCompletelyWithin ) )
63 {
64 // Grab tile from the input.
65 tile = theInputConnection->getTile(rect, resLevel);
66
67 if ( tile.valid() )
68 {
69 if ( tile->getDataObjectStatus() != OSSIM_NULL &&
70 tile->getDataObjectStatus() != OSSIM_EMPTY )
71 {
72 ossimIrect inputRectangle = tile->getImageRectangle();
73
74 if( theCutType == OSSIM_RECTANGLE_NULL_OUTSIDE ) // Typical case...
75 {
76 if ( !requestCompletelyWithin )
77 {
78 // Clip the tile:
79 ossim_int32 ulx = inputRectangle.ul().x;
80 ossim_int32 uly = inputRectangle.ul().y;
81 ossim_int32 w = tile->getWidth();
82 ossim_int32 h = tile->getHeight();
83 ossim_int32 offset = 0;
84 ossimIpt tempPoint(ulx, uly);
85
86 for(ossim_int32 y = 0; y < h; ++tempPoint.y,++y)
87 {
88 tempPoint.x = ulx;
89 for(ossim_int32 x = 0; x < w; ++tempPoint.x,++x)
90 {
91 if(!cutRect.pointWithin(tempPoint))
92 {
93 tile->setNull(offset);
94 }
95 ++offset;
96 }
97 }
98 tile->validate();
99 }
100 }
101 else // Null inside...
102 {
103 // Note if complete within requested rect this block was bypassed entirely.
104 ossim_int32 ulx = inputRectangle.ul().x;
105 ossim_int32 uly = inputRectangle.ul().y;
106 ossim_int32 w = tile->getWidth();
107 ossim_int32 h = tile->getHeight();
108 ossim_int32 offset = 0;
109 ossimIpt tempPoint(ulx, uly);
110
111 for(ossim_int32 y = 0; y < h; ++tempPoint.y,++y)
112 {
113 tempPoint.x = ulx;
114 for(ossim_int32 x = 0; x < w; ++tempPoint.x,++x)
115 {
116 if(cutRect.pointWithin(tempPoint))
117 {
118 tile->setNull(offset);
119 }
120 ++offset;
121 }
122 }
123 tile->validate();
124 }
125
126 } // Matches: if ( tile->getDataObjectStatus() ...
127
128 } // Matches: if ( tile.valid() )
129
130 } // Matches: if ( ( ( theCutType == OSSI ...
131
132 } // Matches: if ( theInputConnection && enabled && ...
133
134 return tile;
135 } // End: ossimRectangleCutFilter::getTile( ... )
136
setRectangle(const ossimIrect & rect)137 void ossimRectangleCutFilter::setRectangle(const ossimIrect& rect)
138 {
139 theRectangle = rect;
140
141 if(theRectangle.hasNans())
142 {
143 if(theInputConnection)
144 {
145 theRectangle = theInputConnection->getBoundingRect();
146 }
147 }
148 }
149
getValidImageVertices(vector<ossimIpt> & validVertices,ossimVertexOrdering ordering,ossim_uint32) const150 void ossimRectangleCutFilter::getValidImageVertices(
151 vector<ossimIpt>& validVertices,
152 ossimVertexOrdering ordering,
153 ossim_uint32 /* resLevel */)const
154 {
155 ossimIrect rect = getBoundingRect();
156
157 if(ordering == OSSIM_CLOCKWISE_ORDER)
158 {
159 validVertices.push_back(rect.ul());
160 validVertices.push_back(rect.ur());
161 validVertices.push_back(rect.lr());
162 validVertices.push_back(rect.ll());
163 }
164 else
165 {
166 validVertices.push_back(rect.ul());
167 validVertices.push_back(rect.ll());
168 validVertices.push_back(rect.lr());
169 validVertices.push_back(rect.ur());
170 }
171 }
172
getBoundingRect(ossim_uint32 resLevel) const173 ossimIrect ossimRectangleCutFilter::getBoundingRect(ossim_uint32 resLevel)const
174 {
175 if(traceDebug())
176 {
177 ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRectangleCutFilter::getBoundingRect DEBUG: entered..." << std::endl;
178 }
179 ossimIrect result;
180
181 result.makeNan();
182 if(!theInputConnection)
183 {
184 if(traceDebug())
185 {
186 ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRectangleCutFilter::getBoundingRect DEBUG: Input connection was not valid so leaving" << std::endl;
187 }
188 return result;
189 }
190
191 result = theInputConnection->getBoundingRect(resLevel);
192 if(isSourceEnabled())
193 {
194 if(theCutType == OSSIM_RECTANGLE_NULL_OUTSIDE)
195 {
196 ossimDpt decimation;
197 getDecimationFactor(resLevel, decimation);
198 ossimIrect cutRect = theRectangle;
199 if(!decimation.hasNans())
200 {
201 cutRect = theRectangle*decimation;
202 }
203 result = cutRect;
204 }
205 }
206
207 if(traceDebug())
208 {
209 ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRectangleCutFilter::getBoundingRect DEBUG: cut rect = " << result << std::endl;
210 }
211 return result;
212 }
213
initialize()214 void ossimRectangleCutFilter::initialize()
215 {
216 theDecimationList.clear();
217 if(theInputConnection)
218 {
219 getDecimationFactors(theDecimationList);
220 }
221 if(theDecimationList.empty())
222 {
223 theDecimationList.push_back(ossimDpt(1,1));
224 }
225 if(theRectangle.hasNans())
226 {
227 setRectangle(theRectangle);
228 }
229 }
230
saveState(ossimKeywordlist & kwl,const char * prefix) const231 bool ossimRectangleCutFilter::saveState(ossimKeywordlist& kwl,
232 const char* prefix)const
233 {
234 ossimString newPrefix = prefix;
235 newPrefix+="clip_rect.";
236
237 theRectangle.saveState(kwl, newPrefix);
238
239 if(theCutType == OSSIM_RECTANGLE_NULL_INSIDE)
240 {
241 kwl.add(prefix,
242 "cut_type",
243 "null_inside",
244 true);
245 }
246 else if(theCutType == OSSIM_RECTANGLE_NULL_OUTSIDE)
247 {
248 kwl.add(prefix,
249 "cut_type",
250 "null_outside",
251 true);
252 }
253
254 return ossimImageSourceFilter::saveState(kwl, prefix);
255 }
256
loadState(const ossimKeywordlist & kwl,const char * prefix)257 bool ossimRectangleCutFilter::loadState(const ossimKeywordlist& kwl,
258 const char* prefix)
259 {
260 ossimString newPrefix = prefix;
261
262 ossimString rect = kwl.find(prefix, "rect");
263 if(!rect.empty())
264 {
265 theRectangle.toRect(rect);
266 }
267 else
268 {
269 newPrefix+="clip_rect.";
270
271 theRectangle.loadState(kwl, newPrefix.c_str());
272 }
273
274 const char* cutType = kwl.find(prefix, "cut_type");
275 if(cutType)
276 {
277 ossimString c = cutType;
278 if(c == "null_inside")
279 {
280 theCutType = OSSIM_RECTANGLE_NULL_INSIDE;
281 }
282 else if(c == "null_outside")
283 {
284 theCutType = OSSIM_RECTANGLE_NULL_OUTSIDE;
285 }
286 else
287 {
288 theCutType = static_cast<ossimRectangleCutType>(ossimString(cutType).toLong());
289 }
290 }
291
292 return ossimImageSourceFilter::loadState(kwl, prefix);
293 }
294
getRectangle() const295 const ossimIrect& ossimRectangleCutFilter::getRectangle()const
296 {
297 return theRectangle;
298 }
299
getCutType() const300 ossimRectangleCutFilter::ossimRectangleCutType ossimRectangleCutFilter::getCutType()const
301 {
302 return theCutType;
303 }
304
setCutType(ossimRectangleCutType cutType)305 void ossimRectangleCutFilter::setCutType(ossimRectangleCutType cutType)
306 {
307 theCutType = cutType;
308 }
309