1 //*******************************************************************
2 //
3 // License: MIT
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: Garrett Potts
8 //
9 // Description: Nitf support class
10 //
11 //********************************************************************
12 // $Id$
13
14 #include <ossim/support_data/ossimNitfImageHeader.h>
15 #include <ossim/base/ossimContainerProperty.h>
ossimNitfImageDataMaskV2_1()16 #include <ossim/base/ossimDrect.h>
17 #include <ossim/base/ossimIrect.h>
18 #include <ossim/base/ossimNotifyContext.h>
19
20 #include <cmath> /* for fmod */
21 #include <iomanip>
22 #include <ostream>
23 #include <sstream>
24
25 RTTI_DEF2(ossimNitfImageHeader,
26 "ossimNitfImageHeader",
27 ossimObject,
28 ossimPropertyInterface)
29
30 static const char* TAGS_KW = "tags";
31
32 ossimNitfImageHeader::ossimNitfImageHeader()
33 {
34 }
35
36 ossimNitfImageHeader::~ossimNitfImageHeader()
37 {
writeStream(std::ostream & out)38 }
39
40 bool ossimNitfImageHeader::getTagInformation(ossimNitfTagInformation& tagInfo,
41 const ossimString& tagName)const
42 {
43 if(theTagList.size())
44 {
45 for(ossim_uint32 idx = 0; idx < theTagList.size(); ++idx)
46 {
47 if(theTagList[idx].getTagName() == tagName)
48 {
49 tagInfo = theTagList[idx];
50 return true;
51 }
52 }
53 }
54
55 return false;
56 }
57
58 bool ossimNitfImageHeader::getTagInformation(
59 ossimNitfTagInformation& tagInfo, ossim_uint32 idx) const
60 {
61 bool result = false;
62
63 if(idx < theTagList.size())
64 {
65 tagInfo = theTagList[idx];
66 result = true;
67 }
68
69 return result;
70 }
71
72 ossimRefPtr<ossimNitfRegisteredTag> ossimNitfImageHeader::getTagData(
73 const ossimString& tagName)
74 {
75 if(theTagList.size())
76 {
77 for(ossim_uint32 idx = 0; idx < theTagList.size(); ++idx)
78 {
79 if(theTagList[idx].getTagName() == tagName)
80 {
81 return theTagList[idx].getTagData();
82 }
83 }
84 }
85
86 return ossimRefPtr<ossimNitfRegisteredTag>();
87 }
88
89 const ossimRefPtr<ossimNitfRegisteredTag> ossimNitfImageHeader::getTagData(
90 const ossimString& tagName) const
91 {
92 if(theTagList.size())
93 {
94 for(ossim_uint32 idx = 0; idx < theTagList.size(); ++idx)
95 {
96 if(theTagList[idx].getTagName() == tagName)
97 {
98 return theTagList[idx].getTagData();
99 }
100 }
101 }
102
103 return ossimRefPtr<ossimNitfRegisteredTag>();
104 }
105
106 void ossimNitfImageHeader::getTagData(
107 const ossimString& tagName,
108 std::vector< const ossimNitfRegisteredTag* > &tags ) const
109 {
110 tags.clear();
111 if(theTagList.size())
112 {
113 for(ossim_uint32 idx = 0; idx < theTagList.size(); ++idx)
114 {
115 if(theTagList[idx].getTagName() == tagName)
116 {
117 tags.push_back( theTagList[idx].getTagData().get() );
118 }
119 }
120 }
121 }
122
123 ossim_uint32 ossimNitfImageHeader::getNumberOfTags()const
124 {
125 return static_cast<ossim_uint32>(theTagList.size());
126 }
127
128 void ossimNitfImageHeader::addTag(const ossimNitfTagInformation& tag, bool unique)
129 {
130 if(unique)
131 {
132 removeTag(tag.getTagName());
133 }
134 theTagList.push_back(tag);
135 }
136
137 void ossimNitfImageHeader::removeTag(const ossimString& tagName)
138 {
139 ossim_uint32 idx = 0;
140 for(idx = 0; idx < theTagList.size(); ++idx)
141 {
142 if(theTagList[idx].getTagName() == tagName)
143 {
144 theTagList.erase(theTagList.begin() + idx);
145 return;
146 }
147 }
148 }
149
150 bool ossimNitfImageHeader::isSameAs(const ossimNitfImageHeader* hdr) const
151 {
152 if (!hdr) return false;
153
154 return ( (isCompressed() == hdr->isCompressed()) &&
155 (getNumberOfRows() == hdr->getNumberOfRows()) &&
156 (getNumberOfBands() == hdr->getNumberOfBands()) &&
157 (getNumberOfCols() == hdr->getNumberOfCols()) &&
158 (getNumberOfBlocksPerRow() == hdr->getNumberOfBlocksPerRow()) &&
159 (getNumberOfBlocksPerCol() == hdr->getNumberOfBlocksPerCol()) &&
160 (getNumberOfPixelsPerBlockHoriz() ==
161 hdr->getNumberOfPixelsPerBlockHoriz()) &&
162 (getNumberOfPixelsPerBlockVert() ==
163 hdr->getNumberOfPixelsPerBlockVert()) &&
164 (getBitsPerPixelPerBand() == hdr->getBitsPerPixelPerBand()) &&
165 (getImageRect() == hdr->getImageRect()) &&
166 (getIMode() == hdr->getIMode()) &&
167 (getCoordinateSystem() == hdr->getCoordinateSystem()) &&
168 (getGeographicLocation() == hdr->getGeographicLocation()) );
169 }
170
171
172 void ossimNitfImageHeader::setProperty(ossimRefPtr<ossimProperty> /* property */)
173 {
174 }
175
176 ossimRefPtr<ossimProperty> ossimNitfImageHeader::getProperty(const ossimString& name)const
177 {
178 ossimProperty* result = 0;
179
180 if(name == TAGS_KW)
181 {
182 ossim_uint32 idxMax = getNumberOfTags();
183 if(idxMax > 0)
184 {
185 ossimContainerProperty* containerProperty = new ossimContainerProperty;
186 containerProperty->setName(name);
187 ossim_uint32 idx = 0;
188
189 result = containerProperty;
190 for(idx = 0; idx < idxMax; ++idx)
191 {
192 ossimNitfTagInformation tagInfo;
193 getTagInformation(tagInfo, idx);
194
195 const ossimRefPtr<ossimNitfRegisteredTag> tagData = tagInfo.getTagData();
196 if(tagData.valid())
197 {
198 ossimContainerProperty* containerPropertyTag = new ossimContainerProperty;
199 containerPropertyTag->setName(tagInfo.getTagName());
200 std::vector<ossimRefPtr<ossimProperty> > propertyList;
201 tagData->getPropertyList(propertyList);
202
203 containerPropertyTag->addChildren(propertyList);
204 containerProperty->addChild(containerPropertyTag);
205 }
206 else
207 {
208 containerProperty->addStringProperty(tagInfo.getTagName(), "", true);
209 }
210 }
211 }
212 }
213
214 return result;
215 }
216
217 void ossimNitfImageHeader::getPropertyNames(std::vector<ossimString>& propertyNames)const
218 {
219 propertyNames.push_back(TAGS_KW);
220
221 }
222
223 ossim_uint32 ossimNitfImageHeader::getTotalTagLength()const
224 {
225 ossim_uint32 tagLength = 0;
226
227 for(ossim_uint32 i = 0; i < theTagList.size(); ++i)
228 {
229 tagLength += theTagList[i].getTotalTagLength();
230 }
231
232 return tagLength;
233 }
234
235 std::ostream& ossimNitfImageHeader::printTags(std::ostream& out,
236 const std::string& prefix)const
237 {
238 for(ossim_uint32 i = 0; i < theTagList.size(); ++i)
239 {
240 ossimRefPtr<ossimNitfRegisteredTag> tag = theTagList[i].getTagData();
241 if (tag.valid())
242 {
243 tag->print(out, prefix);
244 }
245 }
246 return out;
247 }
248
249 void ossimNitfImageHeader::getMetadata(ossimKeywordlist& kwl,
250 const char* prefix) const
251 {
252 kwl.add(prefix, "source",
253 getImageSource().c_str(),
254 false);
255 kwl.add(prefix,
256 "image_date",
257 getAcquisitionDateMonthDayYear().c_str(),
258 false);
259 kwl.add(prefix,
260 "image_title",
261 getTitle().c_str(),
262 false);
263 }
264
265 bool ossimNitfImageHeader::hasLut() const
266 {
267 bool result = false;
268
269 const ossim_uint32 BANDS = static_cast<ossim_uint32>(getNumberOfBands());
270 for (ossim_uint32 band = 0; band < BANDS; ++band)
271 {
272 const ossimRefPtr<ossimNitfImageBand> imgBand = getBandInformation(band);
273 if(imgBand.valid())
274 {
275 ossim_uint32 luts = imgBand->getNumberOfLuts();
276 if(luts > 0)
277 {
278 if(imgBand->getLut(0).valid())
279 {
280 result = true;
281 break;
282 }
283 }
284 }
285 }
286
287 return result;
288 }
289
290 ossimRefPtr<ossimNBandLutDataObject> ossimNitfImageHeader::createLut(
291 ossim_uint32 bandIdx)const
292 {
293 ossimRefPtr<ossimNBandLutDataObject> result;
294
295 if(bandIdx < (ossim_uint32)getNumberOfBands())
296 {
297 const ossimRefPtr<ossimNitfImageBand> band = getBandInformation(bandIdx);
298 if(band.valid())
299 {
300 ossim_uint32 bands = band->getNumberOfLuts();
301 if(bands > 0)
302 {
303 if(band->getLut(0).valid())
304 {
305 ossim_uint32 entries = band->getLut(0)->getNumberOfEntries();
306
307 result = new ossimNBandLutDataObject();
308 result->create(entries, band->getNumberOfLuts());
309 ossim_uint32 bIdx;
310 ossim_uint32 entryIdx;
311
312 for(bIdx = 0; bIdx < bands; ++bIdx)
313 {
314 const ossimRefPtr<ossimNitfImageLut> lut = band->getLut(bIdx);
315 if(lut.valid())
316 {
317 for(entryIdx = 0; entryIdx < entries; ++entryIdx)
318 {
319 (*result)[entryIdx][bIdx] = (ossimNBandLutDataObject::LUT_ENTRY_TYPE)(lut->getValue(entryIdx));
320 }
321 }
322 }
323 }
324 }
325 }
326 }
327
328 return result;
329 }
330
331
332 void ossimNitfImageHeader::checkForGeographicTiePointTruncation(
333 const ossimDpt& tie) const
334 {
335 // One arc second in decimal degrees.
336 const ossim_float64 ARC_SECOND = 1.0/3600.0;
337
338 // Very small number.
339 const ossim_float64 FUDGE_FACTOR = 0.000000001;
340
341 // Remainder portion of latitude divided by an arc second.
342 ossim_float64 y = std::fmod(tie.y, ARC_SECOND);
343
344 // Remainder portion of longitue divided by an arc second.
345 ossim_float64 x = std::fmod(tie.x, ARC_SECOND);
346
347 if ( (std::fabs(y) > FUDGE_FACTOR) || (std::fabs(x) > FUDGE_FACTOR) )
348 {
349 ossimNotify(ossimNotifyLevel_WARN)
350 << "ossimNitfImageHeader WARNING:\n"
351 << "Tie point will be truncated in image header: "
352 << tie
353 << std::endl;
354 }
355 }
356
357 void ossimNitfImageHeader::getDecimationFactor(ossim_float64& result) const
358 {
359 //---
360 // Look for string like:
361 //
362 // "/2" = 1/2
363 // "/4 = 1/4
364 // ...
365 // "/16 = 1/16
366 //
367 // If it is full resolution it should be "1.0"
368 //
369 // or
370 //
371 // "0.5" which is the same as "/2"
372 // "0.25" which is the same as "/4"
373 //---
374 ossimString os = getImageMagnification();
375
376 // Spec says to fill with spaces so strip them.
377 os.trim(ossimString(" "));
378
379 if (os.size())
380 {
381 if ( os.contains("/") )
382 {
383 os = os.after("/");
384 result = os.toFloat64();
385 if (result)
386 {
387 result = 1.0 / result;
388 }
389 }
390 else
391 {
392 result = os.toFloat64();
393 }
394 }
395 else
396 {
397 result = ossim::nan();
398 }
399 }
400
401
402 bool ossimNitfImageHeader::saveState(ossimKeywordlist& kwl, const ossimString& prefix)const
403 {
404 if(!ossimObject::saveState(kwl, prefix)) return false;
405 ossimString tagsPrefix = prefix;
406
407 for(ossim_uint32 i = 0; i < theTagList.size(); ++i)
408 {
409 ossimRefPtr<ossimNitfRegisteredTag> tag = theTagList[i].getTagData();
410 if (tag.valid())
411 {
412 if(!tag->saveState(kwl, tagsPrefix))
413 {
414 return false;
415 }
416 }
417 }
418 return true;
419 }
420