1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License: See top level LICENSE.txt file.
5 //
6 // Author: Garrett Potts
7 //
8 // Description:
9 //
10 // Contains class definition for ossimImageMetaData.
11 //
12 //*******************************************************************
13 // $Id: ossimImageMetaData.cpp 21745 2012-09-16 15:21:53Z dburken $
14
15 #include <ossim/support_data/ossimImageMetaData.h>
16 #include <ossim/base/ossimCommon.h>
17 #include <ossim/base/ossimKeywordlist.h>
18 #include <ossim/base/ossimKeywordNames.h>
19 #include <ossim/base/ossimString.h>
20 #include <ossim/base/ossimScalarTypeLut.h>
21 #include <ossim/base/ossimTrace.h>
22 #include <algorithm>
23 #include <iostream>
24 #include <vector>
25
26 static ossimTrace traceDebug("ossimImageMetaData:debug");
27
ossimImageMetaData()28 ossimImageMetaData::ossimImageMetaData()
29 :theNullPixelArray(0),
30 theMinPixelArray(0),
31 theMaxPixelArray(0),
32 theMinValuesValidFlag(false),
33 theMaxValuesValidFlag(false),
34 theNullValuesValidFlag(false),
35 theScalarType(OSSIM_SCALAR_UNKNOWN),
36 theBytesPerPixel(0),
37 theNumberOfBands(0),
38 theRgbBands()
39 {
40 }
41
ossimImageMetaData(ossimScalarType aType,ossim_uint32 numberOfBands)42 ossimImageMetaData::ossimImageMetaData(ossimScalarType aType,
43 ossim_uint32 numberOfBands)
44 :theNullPixelArray(0),
45 theMinPixelArray(0),
46 theMaxPixelArray(0),
47 theMinValuesValidFlag(false),
48 theMaxValuesValidFlag(false),
49 theNullValuesValidFlag(false),
50 theScalarType(aType),
51 theBytesPerPixel(0),
52 theNumberOfBands(numberOfBands),
53 theRgbBands()
54 {
55 if(theNumberOfBands)
56 {
57 theNullPixelArray = new double[theNumberOfBands];
58 theMinPixelArray = new double[theNumberOfBands];
59 theMaxPixelArray = new double[theNumberOfBands];
60
61 setDefaultsForArrays();
62 }
63 theBytesPerPixel = ossim::scalarSizeInBytes( aType );
64 }
65
ossimImageMetaData(const ossimImageMetaData & rhs)66 ossimImageMetaData::ossimImageMetaData(const ossimImageMetaData& rhs)
67 :
68 theNullPixelArray(0),
69 theMinPixelArray(0),
70 theMaxPixelArray(0),
71 theMinValuesValidFlag(rhs.theMinValuesValidFlag),
72 theMaxValuesValidFlag(rhs.theMaxValuesValidFlag),
73 theNullValuesValidFlag(rhs.theNullValuesValidFlag),
74 theScalarType(rhs.theScalarType),
75 theBytesPerPixel(rhs.theBytesPerPixel),
76 theNumberOfBands(rhs.theNumberOfBands),
77 theRgbBands(rhs.theRgbBands)
78 {
79 if(theNumberOfBands)
80 {
81 theNullPixelArray = new double[theNumberOfBands];
82 theMinPixelArray = new double[theNumberOfBands];
83 theMaxPixelArray = new double[theNumberOfBands];
84
85 std::copy(rhs.theNullPixelArray,
86 rhs.theNullPixelArray+theNumberOfBands,
87 theNullPixelArray);
88 std::copy(rhs.theMinPixelArray,
89 rhs.theMinPixelArray+theNumberOfBands,
90 theMinPixelArray);
91 std::copy(rhs.theMaxPixelArray,
92 rhs.theMaxPixelArray+theNumberOfBands,
93 theMaxPixelArray);
94 }
95 }
96
operator =(const ossimImageMetaData & rhs)97 const ossimImageMetaData& ossimImageMetaData::operator=( const ossimImageMetaData& rhs )
98 {
99 if( this != &rhs )
100 {
101 clear();
102 theMinValuesValidFlag = rhs.theMinValuesValidFlag;
103 theMaxValuesValidFlag = rhs.theMaxValuesValidFlag;
104 theNullValuesValidFlag = rhs.theNullValuesValidFlag;
105 theNumberOfBands = rhs.theNumberOfBands;
106 theScalarType = rhs.theScalarType;
107 theBytesPerPixel = rhs.theBytesPerPixel;
108 if(theNumberOfBands)
109 {
110 theNullPixelArray = new double[theNumberOfBands];
111 theMinPixelArray = new double[theNumberOfBands];
112 theMaxPixelArray = new double[theNumberOfBands];
113
114 std::copy(rhs.theNullPixelArray,
115 rhs.theNullPixelArray+theNumberOfBands,
116 theNullPixelArray);
117 std::copy(rhs.theMinPixelArray,
118 rhs.theMinPixelArray+theNumberOfBands,
119 theMinPixelArray);
120 std::copy(rhs.theMaxPixelArray,
121 rhs.theMaxPixelArray+theNumberOfBands,
122 theMaxPixelArray);
123 }
124 theRgbBands = rhs.theRgbBands;
125 }
126 return *this;
127 }
128
~ossimImageMetaData()129 ossimImageMetaData::~ossimImageMetaData()
130 {
131 clear();
132 }
133
clear()134 void ossimImageMetaData::clear()
135 {
136 if(theNullPixelArray)
137 {
138 delete [] theNullPixelArray;
139 theNullPixelArray = 0;
140 }
141 if(theMinPixelArray)
142 {
143 delete [] theMinPixelArray;
144 theMinPixelArray = 0;
145 }
146 if(theMaxPixelArray)
147 {
148 delete [] theMaxPixelArray;
149 theMaxPixelArray = 0;
150 }
151 theScalarType = OSSIM_SCALAR_UNKNOWN;
152 theBytesPerPixel = 0;
153 theNumberOfBands = 0;
154 theRgbBands.clear();
155 }
156
setDefaultsForArrays()157 void ossimImageMetaData::setDefaultsForArrays()
158 {
159 ossim_uint32 i=0;
160
161 for(i = 0; i < theNumberOfBands; ++i)
162 {
163 theNullPixelArray[i] = ossim::defaultNull(theScalarType);
164 theMinPixelArray[i] = ossim::defaultMin(theScalarType);
165 theMaxPixelArray[i] = ossim::defaultMax(theScalarType);
166 }
167 }
168
setNumberOfBands(ossim_uint32 numberOfBands)169 void ossimImageMetaData::setNumberOfBands(ossim_uint32 numberOfBands)
170 {
171 if(theNullPixelArray)
172 {
173 delete [] theNullPixelArray;
174 theNullPixelArray = 0;
175 }
176 if(theMinPixelArray)
177 {
178 delete [] theMinPixelArray;
179 theMinPixelArray = 0;
180 }
181 if(theMaxPixelArray)
182 {
183 delete [] theMaxPixelArray;
184 theMaxPixelArray = 0;
185 }
186
187 theNumberOfBands = numberOfBands;
188
189 if(theNumberOfBands)
190 {
191 theNullPixelArray = new double[theNumberOfBands];
192 theMinPixelArray = new double[theNumberOfBands];
193 theMaxPixelArray = new double[theNumberOfBands];
194
195 setDefaultsForArrays();
196 }
197 }
198
loadState(const ossimKeywordlist & kwl,const char * prefix)199 bool ossimImageMetaData::loadState(const ossimKeywordlist& kwl, const char* prefix)
200 {
201 bool result = false; // return status
202
203 // Clear the object:
204 clear();
205
206 std::string pfx = ( prefix ? prefix : "" );
207
208 theRgbBands = kwl.findKey( pfx, std::string("rgb_bands") );
209
210 ossim_uint32 bands = getBandCount( kwl, pfx );
211 if ( bands )
212 {
213 result = true;
214
215 setNumberOfBands( bands );
216
217 theMinValuesValidFlag = true;
218 theMaxValuesValidFlag = true;
219 theNullValuesValidFlag = true;
220
221 updateMetaData( kwl, pfx ); // Initializes the rest of object.
222 }
223 else
224 {
225 if (traceDebug())
226 {
227 ossimNotify(ossimNotifyLevel_WARN)
228 << " ERROR:\n"
229 << "Required keyword not found: " << ossimKeywordNames::NUMBER_BANDS_KW << std::endl;
230 }
231 }
232
233 if (traceDebug())
234 {
235 print( ossimNotify(ossimNotifyLevel_DEBUG) );
236 }
237
238 return result;
239 }
240
saveState(ossimKeywordlist & kwl,const char * prefix) const241 bool ossimImageMetaData::saveState(ossimKeywordlist& kwl,
242 const char* prefix)const
243 {
244 kwl.add(prefix, "type", "ossimImageMetaData", true);
245 if ( theNumberOfBands )
246 {
247 ossim_uint32 band = 0;
248
249 for (band=0; band < theNumberOfBands; ++band)
250 {
251 ossimString kwMin = (ossimKeywordNames::BAND_KW +
252 ossimString::toString(band+1) + "." +
253 ossimKeywordNames::MIN_VALUE_KW);
254 ossimString kwMax = (ossimKeywordNames::BAND_KW +
255 ossimString::toString(band+1) + "." +
256 ossimKeywordNames::MAX_VALUE_KW);
257 ossimString kwNull = (ossimKeywordNames::BAND_KW +
258 ossimString::toString(band+1) + "." +
259 ossimKeywordNames::NULL_VALUE_KW);
260
261 kwl.add(prefix,
262 kwMin.c_str(),
263 theMinPixelArray[band],
264 true);
265 kwl.add(prefix,
266 kwMax.c_str(),
267 theMaxPixelArray[band],
268 true);
269 kwl.add(prefix,
270 kwNull.c_str(),
271 theNullPixelArray[band],
272 true);
273 }
274 // std::cout << "added bands ******************" << std::endl;
275 kwl.add(prefix,
276 ossimKeywordNames::NUMBER_BANDS_KW,
277 theNumberOfBands,
278 true);
279 kwl.add(prefix,
280 ossimKeywordNames::SCALAR_TYPE_KW,
281 (ossimScalarTypeLut::instance()->getEntryString(theScalarType)),
282 true);
283
284 kwl.add( prefix, "bytes_per_pixel", theBytesPerPixel, true );
285 }
286
287 if ( theRgbBands.size() )
288 {
289 kwl.add( prefix, "rgb_bands", theRgbBands.c_str(), true );
290 }
291
292 return true;
293 }
294
getNumberOfBands() const295 ossim_uint32 ossimImageMetaData::getNumberOfBands()const
296 {
297 return theNumberOfBands;
298 }
299
getRgbBands() const300 const std::string& ossimImageMetaData::getRgbBands() const
301 {
302 return theRgbBands;
303 }
304
getRgbBands(std::vector<ossim_uint32> & bandList) const305 bool ossimImageMetaData::getRgbBands(std::vector<ossim_uint32>& bandList) const
306 {
307 bool result = false;
308 if ( ( theNumberOfBands > 2) && theRgbBands.size() )
309 {
310 ossim::toSimpleVector( bandList, ossimString(theRgbBands) );
311 if ( bandList.size() == 3 )
312 {
313 result = true;
314 }
315 else
316 {
317 bandList.clear();
318 }
319 }
320 return result;
321 }
322
setScalarType(ossimScalarType aType)323 void ossimImageMetaData::setScalarType(ossimScalarType aType)
324 {
325 theScalarType = aType;
326 theBytesPerPixel = ossim::scalarSizeInBytes( aType );
327 }
328
getScalarType() const329 ossimScalarType ossimImageMetaData::getScalarType()const
330 {
331 return theScalarType;
332 }
333
getBytesPerPixel() const334 ossim_uint32 ossimImageMetaData::getBytesPerPixel() const
335 {
336 return theBytesPerPixel;
337 }
338
setMinPix(ossim_uint32 band,double pix)339 void ossimImageMetaData::setMinPix(ossim_uint32 band, double pix)
340 {
341 if((band < theNumberOfBands)&&(theMinPixelArray))
342 {
343 theMinPixelArray[band] = pix;
344 }
345 }
346
setMaxPix(ossim_uint32 band,double pix)347 void ossimImageMetaData::setMaxPix(ossim_uint32 band, double pix)
348 {
349 if((band < theNumberOfBands) && theMaxPixelArray)
350 {
351 theMaxPixelArray[band] = pix;
352 }
353 }
354
setNullPix(ossim_uint32 band,double pix)355 void ossimImageMetaData::setNullPix(ossim_uint32 band, double pix)
356 {
357 if((band < theNumberOfBands)&&(theNullPixelArray))
358 {
359 theNullPixelArray[band] = pix;
360 }
361 }
362
getMinPix(ossim_uint32 band) const363 double ossimImageMetaData::getMinPix(ossim_uint32 band)const
364 {
365 if(theNumberOfBands&&theMinPixelArray)
366 {
367 ossim_uint32 i = ossim::min(band, (ossim_uint32)(theNumberOfBands-1));
368
369 return theMinPixelArray[i];
370 }
371 return ossim::defaultMin(theScalarType);
372 }
373
getMaxPix(ossim_uint32 band) const374 double ossimImageMetaData::getMaxPix(ossim_uint32 band)const
375 {
376 if(theNumberOfBands&&theMaxPixelArray)
377 {
378 ossim_uint32 i = ossim::min(band, (ossim_uint32)(theNumberOfBands-1));
379
380 return theMaxPixelArray[i];
381 }
382 return ossim::defaultMax(theScalarType);
383 }
384
getNullPix(ossim_uint32 band) const385 double ossimImageMetaData::getNullPix(ossim_uint32 band)const
386 {
387 if(theNumberOfBands&&theNullPixelArray)
388 {
389 ossim_uint32 i = ossim::min(band, (ossim_uint32)(theNumberOfBands-1));
390
391 return theNullPixelArray[i];
392 }
393 return ossim::defaultNull(theScalarType);
394 }
395
getMinPixelArray() const396 const double* ossimImageMetaData::getMinPixelArray()const
397 {
398 return theMinPixelArray;
399 }
getMaxPixelArray() const400 const double* ossimImageMetaData::getMaxPixelArray()const
401 {
402 return theMaxPixelArray;
403 }
404
getNullPixelArray() const405 const double* ossimImageMetaData::getNullPixelArray()const
406 {
407 return theNullPixelArray;
408 }
409
setMinValuesValid(bool flag)410 void ossimImageMetaData::setMinValuesValid(bool flag)
411 {
412 theMinValuesValidFlag = flag;
413 }
414
setMaxValuesValid(bool flag)415 void ossimImageMetaData::setMaxValuesValid(bool flag)
416 {
417 theMaxValuesValidFlag = flag;
418 }
419
setNullValuesValid(bool flag)420 void ossimImageMetaData::setNullValuesValid(bool flag)
421 {
422 theNullValuesValidFlag = flag;
423 }
424
getMinValuesValidFlag() const425 bool ossimImageMetaData::getMinValuesValidFlag()const
426 {
427 return theMinValuesValidFlag;
428 }
429
getMaxValuesValidFlag() const430 bool ossimImageMetaData::getMaxValuesValidFlag()const
431 {
432 return theMaxValuesValidFlag;
433 }
434
getNullValuesValidFlag() const435 bool ossimImageMetaData::getNullValuesValidFlag()const
436 {
437 return theNullValuesValidFlag;
438 }
439
isValid() const440 bool ossimImageMetaData::isValid()const
441 {
442 return (theNumberOfBands > 0);
443 // return ((theNumberOfBands>0)&&
444 // (theScalarType != OSSIM_SCALAR_UNKNOWN));
445 }
446
updateMetaData(const ossimKeywordlist & kwl,const std::string & prefix)447 void ossimImageMetaData::updateMetaData(
448 const ossimKeywordlist& kwl, const std::string& prefix )
449 {
450 ossimString value;
451 std::string key;
452
453 // Get the bands:
454 if ( !theNumberOfBands )
455 {
456 ossim_uint32 bands = getBandCount( kwl, prefix );
457 if ( bands )
458 {
459 setNumberOfBands( bands );
460 }
461 }
462
463 if ( theNumberOfBands )
464 {
465 //---
466 // See if bands are zero or one based. Bands are ONE based in the "omd"
467 // file! If band0 is present assume zero based.
468 //---
469
470 ossimString regExpression = std::string("^(") + prefix + std::string("band0+.)");
471 std::vector<ossimString> keys = kwl.getSubstringKeyList( regExpression );
472
473 ossim_uint32 startBand = (keys.size() ? 0 : 1);
474
475 ossim_uint32 limit = theNumberOfBands+startBand; // For for loop:
476
477 std::string bs = "band"; // band sting
478 std::string base;
479
480 for ( ossim_uint32 band = startBand; band < limit; ++band )
481 {
482 base = bs + ossimString::toString( band ).string() + std::string(".") ;
483
484 // Min:
485 key = base + std::string(ossimKeywordNames::MIN_VALUE_KW);
486 value = kwl.findKey( prefix, key );
487
488 if ( value.size() )
489 {
490 theMinPixelArray[ band - startBand ] = value.toFloat64();
491 }
492
493 // Max:
494 key = base + std::string(ossimKeywordNames::MAX_VALUE_KW);
495 value = kwl.findKey( prefix, key );
496 if ( value.size() )
497 {
498 theMaxPixelArray[ band - startBand ] = value.toFloat64();
499 }
500
501 // Null:
502 key = base + std::string(ossimKeywordNames::NULL_VALUE_KW);
503 value = kwl.findKey( prefix, key );
504 if ( value.size() )
505 {
506 theNullPixelArray[ band - startBand ] = value.toFloat64();
507 }
508 }
509 }
510
511
512 // Scalar, only look for if not set.
513 if ( theScalarType == OSSIM_SCALAR_UNKNOWN )
514 {
515 key = ossimKeywordNames::SCALAR_TYPE_KW; // "scalar_type"
516 value.string() = kwl.findKey( prefix, key );
517 if ( value.empty() )
518 {
519 key = "radiometry";
520 value.string() = kwl.findKey( prefix, key );
521 }
522 if ( value.size() )
523 {
524 theScalarType = ossimScalarTypeLut::instance()->getScalarTypeFromString( value );
525 }
526
527 if ( theScalarType != OSSIM_SCALAR_UNKNOWN )
528 {
529 theBytesPerPixel = ossim::scalarSizeInBytes( theScalarType );
530 }
531 }
532
533 if (traceDebug())
534 {
535 ossimNotify(ossimNotifyLevel_DEBUG)
536 << "ossimImageMetaData::updateMetaData DEBUG"
537 << *this << std::endl;
538 }
539 }
540
print(std::ostream & out) const541 std::ostream& ossimImageMetaData::print(std::ostream& out) const
542 {
543 ossimKeywordlist kwl;
544 saveState( kwl, 0 );
545 out << kwl << std::endl;
546 return out;
547 }
548
operator <<(std::ostream & out,const ossimImageMetaData & obj)549 std::ostream& operator<<(std::ostream& out, const ossimImageMetaData& obj)
550 {
551 return obj.print( out );
552 }
553
getBandCount(const ossimKeywordlist & kwl,const std::string & prefix) const554 ossim_uint32 ossimImageMetaData::getBandCount(const ossimKeywordlist& kwl,
555 const std::string& prefix) const
556 {
557 ossim_uint32 result = 0;
558
559 ossimString value;
560 value.string() = kwl.findKey( prefix, std::string(ossimKeywordNames::NUMBER_BANDS_KW) );
561 if ( value.size() )
562 {
563 result = value.toUInt32();
564 }
565 else
566 {
567 value.string() = std::string("^(") + prefix + std::string("band[0-9]+.)");
568 std::vector<ossimString> keys = kwl.getSubstringKeyList( value );
569 result = static_cast<ossim_uint32>( keys.size() );
570 }
571 return result;
572 }
573