OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimTiffInfo.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // License: MIT
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: David Burken
8 //
9 // Description: TIFF Info object.
10 //
11 //----------------------------------------------------------------------------
12 // $Id$
13 
15 
16 #include <ossim/base/ossimCommon.h>
17 #include <ossim/base/ossimDpt.h>
18 #include <ossim/base/ossimEndian.h>
22 #include <ossim/base/ossimNotify.h>
25 #include <ossim/base/ossimTrace.h>
32 #include <fstream>
33 #include <iostream>
34 #include <iomanip>
35 #include <sstream>
37 
38 // Static trace for debugging
39 static ossimTrace traceDebug("ossimTiffInfo:debug");
40 static ossimTrace traceDump("ossimTiffInfo:dump"); // This will dump offsets.
41 
42 static const std::string PHOTO_INTERP[] =
43 {
44  "MINISWHITE",
45  "MINISBLACK",
46  "RGB",
47  "PALETTE",
48  "MASK",
49  "SEPARATED",
50  "YCBCR",
51  "CIELAB"
52 };
53 
54 static const std::string ANGULAR_UNITS_KW = "angular_units";
55 static const std::string CENTER_LATITUDE__KW = "center_latitude";
56 static const std::string CENTER_LONGITUDE_KW = "center_longitude";
57 static const std::string COORD_TRANS_CODE_KW = "coord_trans_code";
58 static const std::string FALSE_ORIGIN_LONGITUDE_KW = "false_origin_longitude";
59 static const std::string FALSE_ORIGIN_LATITUDE_KW = "false_origin_latitude";
60 static const std::string FALSE_ORIGIN_EASTING_KW = "false_origin_easting";
61 static const std::string FALSE_ORIGIN_NORTHING_KW = "false_origin_northing";
62 static const std::string GEODETIC_DATUM_KW = "geodetic_datum";
63 static const std::string IMAGE_LENGTH_KW = "image_length";
64 static const std::string IMAGE_WIDTH_KW = "image_width";
65 static const std::string LINEAR_UNITS_KW = "linear_units";
66 static const std::string MODEL_PIXEL_SCALE_KW = "model_pixel_scale";
67 static const std::string MODEL_TIE_POINT_KW = "model_tie_point";
68 static const std::string MODEL_TRANSFORM_KW = "model_transform";
69 static const std::string MODEL_TYPE_KW = "model_type";
70 static const std::string ORIGIN_LATITUDE_KW = "origin_latitude";
71 static const std::string ORIGIN_LONGITUDE_KW = "origin_longitude";
72 static const std::string RASTER_TYPE_KW = "raster_type";
73 static const std::string VERTICAL_UNITS_KW = "vertical_units";
74 
75 
77  : ossimInfoBase(),
78  m_connectionString(),
79  m_endian(0)
80 {
81 }
82 
84 {
85  if (m_endian)
86  {
87  delete m_endian;
88  m_endian = 0;
89  }
90 }
91 
93 {
94  std::shared_ptr<ossim::istream> inStream = ossim::StreamFactoryRegistry::instance()->createIstream(file.c_str());
95  if(!inStream) return false;
96  return open(inStream, file.c_str());
97 }
98 
99 bool ossimTiffInfo::open( std::shared_ptr<ossim::istream>& str,
100  const std::string& connectionString )
101 {
102  bool result = false;
103 
104  //---
105  // Open the tif file.
106  //---
107  //std::ifstream str(file.c_str(), std::ios_base::binary|std::ios_base::in);
108  if (str&&str->good())
109  {
110  //---
111  // Get the byte order. First two byte should be "II" or "MM".
112  //---
113  char byteOrder[2];
114  str->read(byteOrder, 2); // Read the byte order.
115  ossimByteOrder sysByteOrder = ossim::byteOrder();
116  ossimByteOrder tifByteOrder = OSSIM_LITTLE_ENDIAN;
117  if (byteOrder[0] == 'M')
118  {
119  tifByteOrder = OSSIM_BIG_ENDIAN;
120  }
121 
122  if (sysByteOrder != tifByteOrder)
123  {
124  if(!m_endian)
125  {
126  m_endian = new ossimEndian();
127  }
128  }
129  else if (m_endian)
130  {
131  delete m_endian;
132  m_endian = 0;
133  }
134 
135  //--
136  // Get the version. Note m_endian must be set/unset before calling
137  // "readShort".
138  //---
139  ossim_uint16 version;
140  readShort(version, *str);
141 
142  if ( ( (byteOrder[0] == 'M') || (byteOrder[0] == 'I') ) &&
143  ( (version == 42) || (version == 43) ) )
144  {
145  result = true; // is a tif...
146  }
147  }
148 
149  if (result)
150  {
151  m_connectionString = connectionString;
152  m_inputStream = str;
153  }
154  else
155  {
156  m_connectionString.clear();
157  if (m_endian)
158  {
159  delete m_endian;
160  m_endian = 0;
161  }
162  }
163  return result;
164 }
165 
166 
168 {
169  static const char MODULE[] = "ossimTiffInfo::print";
170 
171  if (traceDebug())
172  {
174  << MODULE << " DEBUG Entered...\n";
175  }
176  //---
177  // Open the tif file.
178  //---
179  // std::ifstream str(theFile.c_str(), std::ios_base::binary|std::ios_base::in);
180  if (!m_inputStream)
181  {
182  if (traceDebug())
183  {
185  << MODULE << " Cannot open file: " << m_connectionString << std::endl;
186  }
187  return out;
188  }
189 
190  //---
191  // Get the byte order. First two byte should be "II" or "MM".
192  //---
193  char byteOrder[2];
194  m_inputStream->seekg(0);
195  m_inputStream->clear();
196 
197  m_inputStream->read(byteOrder, 2); // Read the byte order.
198  ossimByteOrder sysByteOrder = ossim::byteOrder();
199  ossimByteOrder tifByteOrder = OSSIM_LITTLE_ENDIAN;
200 
201  if (byteOrder[0] == 'M')
202  {
203  tifByteOrder = OSSIM_BIG_ENDIAN;
204  }
205  if (sysByteOrder != tifByteOrder)
206  {
207  if(!m_endian)
208  {
209  m_endian = new ossimEndian();
210  }
211  }
212  else if (m_endian)
213  {
214  delete m_endian;
215  m_endian = 0;
216  }
217 
218  //--
219  // Get the version. Note m_endian must be set/unset before calling
220  // "readShort".
221  //---
222  ossim_uint16 version;
223  readShort(version, *m_inputStream);
224 
225  // Set the tag value length.
226  ossim_uint64 tagValueLength;
227  if (version == 42)
228  {
229  tagValueLength = 4;
230  }
231  else
232  {
233  tagValueLength = 8;
234  }
235 
236  out << "tiff.version: " << int(version)
237  << ((version==42)?"(classic)\n":"(big)\n")
238  << "tiff.byte_order: ";
239 
240  if (byteOrder[0] == 'M')
241  {
242  out << "big_endian\n";
243  }
244  else // OSSIM_LITTLE_ENDIAN
245  {
246  out << "little_endian\n";
247  }
248 
249  if (traceDebug())
250  {
251  ossimNotify(ossimNotifyLevel_DEBUG)<< "system_byte_order: ";
253  {
254  ossimNotify(ossimNotifyLevel_DEBUG)<< "big_endian\n";
255  }
256  else // OSSIM_LITTLE_ENDIAN
257  {
258  ossimNotify(ossimNotifyLevel_DEBUG)<< "little_endian\n";
259  }
261  << "tiff.tag_value_length: " << tagValueLength << "\n";
262  }
263 
264  //---
265  // Variables used within the loop.
266  //---
267  std::streamoff seekOffset; // used throughout
268  std::streampos streamPosition; // used throughout
269 
270  if (version == 43)
271  {
272  // We must skip the first four bytes.
273  ossim_uint32 offsetSize;
274  readLong(offsetSize, *m_inputStream);
275  }
276 
277  // Get the offset.
278  if (getOffset(seekOffset, *m_inputStream, version) == false)
279  {
281  << MODULE << " FATAL ERROR - "
282  << "No offset to an image file directory found.\n"
283  << "Returning with error."
284  << std::endl;
285  return out;
286  }
287 
288  if (traceDebug())
289  {
291  << MODULE << " DEBUG: "
292  << "Offset to first ifd: " << seekOffset
293  << "\n";
294  }
295 
296  // Capture the original flags then set float output to full precision.
297  std::ios_base::fmtflags f = out.flags();
298  out << std::setprecision(15);
299 
300  // Image File Directory (IFD) loop.
301  ossim_int32 ifdIndex = 0;
302  while(seekOffset)
303  {
304  // directory prefix for prints.
305  std::string prefix = "tiff.";
306  getDirPrefix(ifdIndex, prefix);
307  out << prefix << "directory_offset: " << seekOffset << "\n";
308 
309  // Seek to the image file directory.
310  m_inputStream->seekg(seekOffset, std::ios_base::beg);
311 
312 
313  //---
314  // Things we need to save for printGeoKeys:
315  //---
316  ossim_uint16* geoKeyBlock = 0;
317  ossim_uint64 geoKeyLength = 0;
318  ossim_float64* geoDoubleBlock = 0;
319  ossim_uint64 geoDoubleLength = 0;
320  ossim_int8* geoAsciiBlock = 0;
321  ossim_uint64 geoAsciiLength = 0;
322 
323  //---
324  // Get the number of directories within the IFD.
325  //---
326  ossim_uint64 nTags; // Number of tags in an IFD.
327  if (getValue(nTags, *m_inputStream, TWO_OR_EIGHT, version) == false)
328  {
329  if(traceDebug())
330  {
332  << MODULE << " FATAL error reading number of direcories."
333  << std::endl;
334  }
335  m_inputStream.reset();
336  return out;
337  }
338 
339  if (traceDebug())
340  {
342  << MODULE << " DEBUG:\n"
343  << "ifd: " << seekOffset
344  << "\ntags in directory: " << nTags<< "\n";
345  }
346 
347  // Tag loop:
348  for (ossim_uint64 tagIdx = 0; tagIdx < nTags; ++tagIdx)
349  {
350  // Variables used within the loop.
351  ossim_uint16 tag = 0; // Tag number
352  ossim_uint16 type = 0; // Type(short, long...)
353  ossim_uint64 count = 0;
354  ossim_uint64 arraySizeInBytes = 0; //
355  ossim_uint8* valueArray = 0; // To hold value.
356 
357  //---
358  // Get the tag.
359  //---
360  readShort(tag, *m_inputStream);
361  if (!m_inputStream->good())
362  {
363  if(traceDebug())
364  {
366  << MODULE << " FATAL error reading tag number."
367  << std::endl;
368  }
369  return out;
370  }
371 
372  //---
373  // Get the type (byte, ascii, short...)
374  //---
375  readShort(type, *m_inputStream);
376  if (!m_inputStream->good())
377  {
378  if(traceDebug())
379  {
381  << MODULE << " FATAL error reading type number."
382  << std::endl;
383  }
384  m_inputStream.reset();
385  return out;
386  }
387 
388  //---
389  // Get the count. This is not in bytes. It is based on the
390  // type. So if the type is a short and the count is one then
391  // read "sizeof(short"(2) bytes.
392  //---
393  getValue(count, *m_inputStream, FOUR_OR_EIGHT, version);
394  if (!m_inputStream->good())
395  {
396  if(traceDebug())
397  {
399  << MODULE << " FATAL error reading count."
400  << std::endl;
401  }
402  m_inputStream.reset();
403  return out;
404  }
405  // Get the array size in bytes.
406  arraySizeInBytes = getArraySizeInBytes(count, type);
407  if (arraySizeInBytes == 0)
408  {
409  // Could be an unhandle type. Gobble the value.
410  eatValue(*m_inputStream, version);
411  }
412  else
413  {
414  // Allocate array.
415  if (valueArray) delete [] valueArray;
416  valueArray = new ossim_uint8[arraySizeInBytes];
417 
418  if (arraySizeInBytes <= tagValueLength)
419  {
420  // Read in the value(s).
421  m_inputStream->read((char*)valueArray, arraySizeInBytes);
422 
423  // Skip any byes left in the field.
424  if (arraySizeInBytes < tagValueLength)
425  {
426  // Skip these bytes.
427  m_inputStream->ignore(tagValueLength-arraySizeInBytes);
428  }
429  }
430  else // Data to big for field. Stored elsewhere...
431  {
432  // Get the offset to the data.
433  getOffset(seekOffset, *m_inputStream, version);
434 
435  // Capture the seek position to come back to.
436  streamPosition = m_inputStream->tellg();
437 
438  // Seek to the data.
439  m_inputStream->seekg(seekOffset, std::ios_base::beg);
440 
441  // Read in the value(s).
442  m_inputStream->read((char*)valueArray, arraySizeInBytes);
443 
444  // Seek back.
445  m_inputStream->seekg(streamPosition);
446  }
447 
448  // Swap the bytes if needed.
449  swapBytes(valueArray, type, count);
450  }
451 
452  if( traceDebug() )
453  {
455  << MODULE << " DEBUG:"
456  << "\ntag[" << tagIdx << "]:" << tag
457  << "\ntype: " << type
458  << "\ncount: " << count
459  << "\narray size in bytes: " << arraySizeInBytes
460  << "\n";
461  }
462 
464  {
465  // tag 34735 save for printGeoKeys
466  if ( geoKeyBlock )
467  {
468  delete [] geoKeyBlock;
469  }
470  geoKeyBlock = reinterpret_cast<ossim_uint16*>(valueArray);
471  geoKeyLength = count;
472  }
473  else if (tag == ossim::OGEO_DOUBLE_PARAMS_TAG)
474  {
475  // tag 34736 save for printGeoKeys
476  if ( geoDoubleBlock )
477  {
478  delete [] geoDoubleBlock;
479  }
480  geoDoubleBlock = reinterpret_cast<ossim_float64*>(valueArray);
481  geoDoubleLength = count;
482  }
483  else if (tag == ossim::OGEO_ASCII_PARAMS_TAG)
484  {
485  // tag 34737 save for printGeoKeys
486  if ( geoAsciiBlock )
487  {
488  delete [] geoAsciiBlock;
489  }
490  geoAsciiBlock = reinterpret_cast<ossim_int8*>(valueArray);
491  geoAsciiLength = count;
492  }
493  else
494  {
495  print(out,
496  prefix,
497  tagIdx,
498  tag,
499  type,
500  count,
501  arraySizeInBytes,
502  valueArray);
503 
504  // Free memory if allocated...
505  if (valueArray)
506  {
507  delete [] valueArray;
508  valueArray = 0;
509  }
510  }
511 
512  } // End of tag loop.
513 
514  //---
515  // If Geotiff Keys read them.
516  // This had to done last since the keys could
517  // have references to tags GEO_DOUBLE_PARAMS_TAG and
518  // GEO_ASCII_PARAMS_TAG.
519  //---
520  if (geoKeyBlock)
521  {
522  printGeoKeys(out, prefix, geoKeyLength, geoKeyBlock,
523  geoDoubleLength,geoDoubleBlock,
524  geoAsciiLength,geoAsciiBlock);
525 
526  delete [] geoKeyBlock;
527  geoKeyBlock = 0;
528  }
529 
530  if (geoDoubleBlock)
531  {
532  delete [] geoDoubleBlock;
533  geoDoubleBlock = 0;
534  }
535  if (geoAsciiBlock)
536  {
537  delete [] geoAsciiBlock;
538  geoAsciiBlock = 0;
539  }
540  geoKeyLength = 0;
541  geoDoubleLength = 0;
542  geoAsciiLength = 0;
543 
544  //---
545  // Get the next IFD offset. Continue this loop until the offset is
546  // zero.
547  //---
548  if (getOffset(seekOffset, *m_inputStream, version) == false)
549  {
550  if(traceDebug())
551  {
553  << MODULE << " No offset to an image file directory found.\n"
554  << "Returning with error."
555  << std::endl;
556  }
557  m_inputStream.reset();
558  return out;
559  }
560 
561  if (traceDebug())
562  {
564  << "DEBUG ossimTiffInfo::readTags: "
565  << "Next Image File Directory(IFD) offset = "
566  << seekOffset << "\n";
567  }
568 
569  ++ifdIndex; // next ifd
570 
571  //---
572  // Note this does NOT check to see if sub_file_type is '1' simply
573  // skips all directories past the first if theOverviewFlag is false.
574  //---
575  if ( ifdIndex && !theOverviewFlag) // Don't process overviews...
576  {
577  break;
578  }
579 
580  } // End of loop through the IFD's.
581 
582  out << std::endl;
583 
584  m_inputStream.reset();
585 
586  // Reset flags.
587  out.setf(f);
588 
589  if (traceDebug())
590  {
592  << MODULE << " DEBUG Exited..." << std::endl;
593  }
594 
595  return out;
596 }
597 
599  std::ostream& outStr) const
600 {
601  static const char MODULE[] = "ossimTiffInfo::print(std::istream&, std::ostream&)";
602  if (traceDebug())
603  {
604  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " DEBUG Entered...\n";
605  }
606 
607  std::streampos startPosition = inStr.tellg();
608 
609  //---
610  // Get the byte order. First two byte should be "II" or "MM".
611  //---
612  char byteOrder[2];
613  inStr.read(byteOrder, 2); // Read the byte order.
614  ossimByteOrder sysByteOrder = ossim::byteOrder();
615  ossimByteOrder tifByteOrder = OSSIM_LITTLE_ENDIAN;
616  if (byteOrder[0] == 'M')
617  {
618  tifByteOrder = OSSIM_BIG_ENDIAN;
619  }
620 
621  if (sysByteOrder != tifByteOrder)
622  {
623  if (!m_endian)
624  {
625  m_endian = new ossimEndian();
626  }
627  }
628  else if (m_endian) // No swapping required.
629  {
630  delete m_endian;
631  m_endian = 0;
632  }
633 
634  //--
635  // Get the version. Note m_endian must be set/unset before calling
636  // "readShort".
637  //---
638  ossim_uint16 version;
639  readShort(version, inStr);
640 
641  // Set the tag value length.
642  ossim_uint64 tagValueLength;
643  if (version == 42)
644  {
645  tagValueLength = 4;
646  }
647  else
648  {
649  tagValueLength = 8;
650  }
651 
652  outStr << "tiff.version: " << int(version)
653  << ((version==42)?"(classic)\n":"(big)\n")
654  << "tiff.byte_order: ";
655 
656  if (byteOrder[0] == 'M')
657  {
658  outStr << "big_endian\n";
659  }
660  else // OSSIM_LITTLE_ENDIAN
661  {
662  outStr << "little_endian\n";
663  }
664 
665  if (traceDebug())
666  {
667  ossimNotify(ossimNotifyLevel_DEBUG)<< "system_byte_order: ";
669  {
670  ossimNotify(ossimNotifyLevel_DEBUG)<< "big_endian\n";
671  }
672  else // OSSIM_LITTLE_ENDIAN
673  {
674  ossimNotify(ossimNotifyLevel_DEBUG)<< "little_endian\n";
675  }
677  << "tiff.tag_value_length: " << tagValueLength << "\n";
678  }
679 
680  //---
681  // Variables used within the loop.
682  //---
683  std::streamoff seekOffset; // used throughout
684  std::streampos streamPosition; // used throughout
685 
686  if (version == 43)
687  {
688  // We must skip the first four bytes.
689  ossim_uint32 offsetSize;
690  readLong(offsetSize, inStr);
691  }
692 
693  // Get the offset.
694  if (getOffset(seekOffset, inStr, version) == false)
695  {
696  if(traceDebug())
697  {
699  << MODULE << " FATAL ERROR - "
700  << "No offset to an image file directory found.\n"
701  << "Returning with error."
702  << std::endl;
703  }
704  return outStr;
705  }
706 
707  if (traceDebug())
708  {
709  if(traceDebug())
710  {
712  << MODULE << " DEBUG: "
713  << "Offset to first ifd: " << seekOffset
714  << "\n";
715  }
716  }
717 
718  // Capture the original flags then set float output to full precision.
719  std::ios_base::fmtflags f = outStr.flags();
720  outStr << std::setprecision(15);
721 
722  // Image File Directory (IFD) loop.
723  ossim_int32 ifdIndex = 0;
724  while(seekOffset)
725  {
726  // directory prefix for prints.
727  std::string prefix = "tiff.";
728  getDirPrefix(ifdIndex, prefix);
729 
730  outStr << prefix << "directory_offset: " << seekOffset << "\n";
731 
732  // Seek to the image file directory.
733  inStr.seekg(startPosition+seekOffset, std::ios_base::beg);
734 
735 
736  //---
737  // Things we need to save for printGeoKeys:
738  //---
739  ossim_uint16* geoKeyBlock = 0;
740  ossim_uint64 geoKeyLength = 0;
741  ossim_float64* geoDoubleBlock = 0;
742  ossim_uint64 geoDoubleLength = 0;
743  ossim_int8* geoAsciiBlock = 0;
744  ossim_uint64 geoAsciiLength = 0;
745 
746  //---
747  // Get the number of directories within the IFD.
748  //---
749  ossim_uint64 nTags; // Number of tags in an IFD.
750  if (getValue(nTags, inStr, TWO_OR_EIGHT, version) == false)
751  {
752  if(traceDebug())
753  {
755  << MODULE << " FATAL error reading number of direcories."
756  << std::endl;
757  }
758  return outStr;
759  }
760 
761  if (traceDebug())
762  {
763  if(traceDebug())
764  {
766  << MODULE << " DEBUG:\n"
767  << "ifd: " << seekOffset
768  << "\ntags in directory: " << nTags<< "\n";
769  }
770  }
771 
772  // Tag loop:
773  for (ossim_uint64 tagIdx = 0; tagIdx < nTags; ++tagIdx)
774  {
775  // Variables used within the loop.
776  ossim_uint16 tag = 0; // Tag number
777  ossim_uint16 type = 0; // Type(short, long...)
778  ossim_uint64 count = 0;
779  ossim_uint64 arraySizeInBytes = 0; //
780  ossim_uint8* valueArray = 0; // To hold value.
781 
782  //---
783  // Get the tag.
784  //---
785  readShort(tag, inStr);
786  if (!inStr)
787  {
788  if(traceDebug())
789  {
791  << MODULE << " FATAL error reading tag number."
792  << std::endl;
793  }
794  return outStr;
795  }
796 
797  //---
798  // Get the type (byte, ascii, short...)
799  //---
800  readShort(type, inStr);
801  if (!inStr)
802  {
803  if(traceDebug())
804  {
806  << MODULE << " FATAL error reading type number."
807  << std::endl;
808  }
809  return outStr;
810  }
811 
812  //---
813  // Get the count. This is not in bytes. It is based on the
814  // type. So if the type is a short and the count is one then
815  // read "sizeof(short"(2) bytes.
816  //---
817  getValue(count, inStr, FOUR_OR_EIGHT, version);
818  if (!inStr)
819  {
820  if(traceDebug())
821  {
823  << MODULE << " FATAL error reading count."
824  << std::endl;
825  }
826  return outStr;
827  }
828 
829  // Get the array size in bytes.
830  arraySizeInBytes = getArraySizeInBytes(count, type);
831  if (arraySizeInBytes == 0)
832  {
833  // Could be an unhandle type. Gobble the value.
834  eatValue(inStr, version);
835  }
836  else
837  {
838  // Allocate array.
839  if (valueArray) delete [] valueArray;
840  valueArray = new ossim_uint8[arraySizeInBytes];
841 
842  if (arraySizeInBytes <= tagValueLength)
843  {
844  // Read in the value(s).
845  inStr.read((char*)valueArray, arraySizeInBytes);
846 
847  // Skip any byes left in the field.
848  if (arraySizeInBytes < tagValueLength)
849  {
850  // Skip these bytes.
851  inStr.ignore(tagValueLength-arraySizeInBytes);
852  }
853  }
854  else // Data to big for field. Stored elsewhere...
855  {
856  // Get the offset to the data.
857  getOffset(seekOffset, inStr, version);
858 
859  // Capture the seek position to come back to.
860  streamPosition = inStr.tellg();
861 
862  // Seek to the data.
863  inStr.seekg(startPosition+seekOffset, std::ios_base::beg);
864 
865  // Read in the value(s).
866  inStr.read((char*)valueArray, arraySizeInBytes);
867 
868  // Seek back.
869  inStr.seekg(streamPosition);
870  }
871 
872  // Swap the bytes if needed.
873  swapBytes(valueArray, type, count);
874  }
875 
876  if( traceDebug() )
877  {
879  << MODULE << " DEBUG:"
880  << "\ntag[" << tagIdx << "]:" << tag
881  << "\ntype: " << type
882  << "\ncount: " << count
883  << "\narray size in bytes: " << arraySizeInBytes
884  << "\n";
885  }
886 
888  {
889  // tag 34735 save for printGeoKeys
890  geoKeyBlock = reinterpret_cast<ossim_uint16*>(valueArray);
891  geoKeyLength = count;
892  }
893  else if (tag == ossim::OGEO_DOUBLE_PARAMS_TAG)
894  {
895  // tag 34736 save for printGeoKeys
896  geoDoubleBlock = reinterpret_cast<ossim_float64*>(valueArray);
897  geoDoubleLength = count;
898  }
899  else if (tag == ossim::OGEO_ASCII_PARAMS_TAG)
900  {
901  // tag 34737 save for printGeoKeys
902  geoAsciiBlock = reinterpret_cast<ossim_int8*>(valueArray);
903  geoAsciiLength = count;
904  }
905  else
906  {
907  print(outStr,
908  prefix,
909  tagIdx,
910  tag,
911  type,
912  count,
913  arraySizeInBytes,
914  valueArray);
915 
916  // Free memory if allocated...
917  if (valueArray)
918  {
919  delete [] valueArray;
920  valueArray = 0;
921  }
922  }
923 
924  } // End of tag loop.
925 
926  //---
927  // If Geotiff Keys read them.
928  // This had to done last since the keys could
929  // have references to tags GEO_DOUBLE_PARAMS_TAG and
930  // GEO_ASCII_PARAMS_TAG.
931  //---
932  if (geoKeyBlock)
933  {
934  printGeoKeys(outStr, prefix, geoKeyLength, geoKeyBlock,
935  geoDoubleLength,geoDoubleBlock,
936  geoAsciiLength,geoAsciiBlock);
937 
938  delete [] geoKeyBlock;
939  geoKeyBlock = 0;
940  }
941 
942  if (geoDoubleBlock)
943  {
944  delete [] geoDoubleBlock;
945  geoDoubleBlock = 0;
946  }
947  if (geoAsciiBlock)
948  {
949  delete [] geoAsciiBlock;
950  geoAsciiBlock = 0;
951  }
952  geoKeyLength = 0;
953  geoDoubleLength = 0;
954  geoAsciiLength = 0;
955 
956  //---
957  // Get the next IFD offset. Continue this loop until the offset is
958  // zero.
959  //---
960  if (getOffset(seekOffset, inStr, version) == false)
961  {
962  if(traceDebug())
963  {
965  << MODULE << " No offset to an image file directory found.\n"
966  << "Returning with error."
967  << std::endl;
968  }
969  return outStr;
970  }
971 
972  if (traceDebug())
973  {
975  << "DEBUG ossimTiffInfo::readTags: "
976  << "Next Image File Directory(IFD) offset = "
977  << seekOffset << "\n";
978  }
979 
980  ++ifdIndex; // next ifd
981 
982  //---
983  // Note this does NOT check to see if sub_file_type is '1' simply
984  // skips all directories past the first if theOverviewFlag is false.
985  //---
986  if ( ifdIndex && !theOverviewFlag) // Don't process overviews...
987  {
988  break;
989  }
990 
991  } // End of loop through the IFD's.
992 
993  outStr << std::endl;
994 
995  // Reset flags.
996  outStr.setf(f);
997 
998  if (traceDebug())
999  {
1001  << MODULE << " DEBUG Exited..." << std::endl;
1002  }
1003 
1004  return outStr;
1005 }
1006 
1008  ossim_uint32 entryIndex) const
1009 {
1010  static const char MODULE[] = "ossimTiffInfo::getImageGeometry #1";
1011  if (traceDebug())
1012  {
1013  ossimNotify(ossimNotifyLevel_DEBUG) << " entered...\n";
1014  }
1015 
1016  bool result = false;
1017 
1018  // Open the file.
1019  // std::ifstream str;
1020  // m_inputStream->open(theFile.c_str(), ios::in | ios::binary);
1021 
1022  if ( m_inputStream->good() )
1023  {
1024  m_inputStream->seekg(0);
1025  m_inputStream->clear();
1026  result = getImageGeometry(*m_inputStream, geomKwl, entryIndex);
1027  }
1028 
1029  if (traceDebug())
1030  {
1032  << "geomKwl:\n"
1033  << geomKwl
1034  << MODULE << " exit status = " << (result?"true":"false") << "\n";
1035  }
1036 
1037  return result;
1038 }
1039 
1041  ossimKeywordlist& geomKwl,
1042  ossim_uint32 entryIndex) const
1043 {
1044  static const char M[] = "ossimTiffInfo::getImageGeometry #2";
1045  if ( traceDebug() )
1046  {
1047  ossimNotify(ossimNotifyLevel_DEBUG) << M << " entered...\n";
1048  }
1049 
1050  bool result = false;
1051 
1052  // Do a print to a memory stream.
1053  std::ostringstream out;
1054  print(inStr, out);
1055 
1056  // Open an input stream to pass to the keyword list.
1057  std::istringstream in( out.str() );
1058 
1059  // Since the print is in key:value format we can pass to a keyword list.
1060  ossimKeywordlist gtiffKwl;
1061  if ( gtiffKwl.parseStream(in) )
1062  {
1063  result = getImageGeometry(gtiffKwl, geomKwl, entryIndex);
1064  }
1065 
1066  if (traceDebug())
1067  {
1069  << "geomKwl:\n"
1070  << geomKwl
1071  << M << " exit status = " << (result?"true":"false") << "\n";
1072  }
1073 
1074  return result;
1075 }
1076 
1078  ossim_uint16* geoKeyBlock,
1079  ossim_uint64 geoDoubleLength,
1080  ossim_float64* geoDoubleBlock,
1081  ossim_uint64 geoAsciiLength,
1082  ossim_int8* geoAsciiBlock,
1083  ossimKeywordlist& geomKwl) const
1084 {
1085  static const char M[] = "ossimTiffInfo::getImageGeometry #3";
1086  if (traceDebug())
1087  {
1088  ossimNotify(ossimNotifyLevel_DEBUG) << M << " entered...\n";
1089  }
1090 
1091  // Dump the geotiff keys to memory.
1092  ostringstream out;
1093  printGeoKeys(out, std::string("tiff.image0."),
1094  geoKeyLength, geoKeyBlock,
1095  geoDoubleLength,geoDoubleBlock,
1096  geoAsciiLength,geoAsciiBlock);
1097 
1098  // Open an input stream to pass to the keyword list.
1099  std::istringstream in( out.str() );
1100 
1101  // Since the print is in key:value format we can pass to a keyword list.
1102  ossimKeywordlist gtiffKwl;
1103  if ( gtiffKwl.parseStream(in) )
1104  {
1105  getImageGeometry(gtiffKwl, geomKwl, 0);
1106  }
1107 
1108  if (traceDebug())
1109  {
1110  ossimNotify(ossimNotifyLevel_DEBUG) << M << " exited...\n";
1111  }
1112 }
1113 
1114 // Private method:
1116  ossimKeywordlist& geomKwl,
1117  ossim_uint32 entryIndex) const
1118 {
1119  static const char M[] = "ossimTiffInfo::getImageGeometry #4";
1120  if (traceDebug())
1121  {
1122  ossimNotify(ossimNotifyLevel_DEBUG) << M << " entered...\n";
1123  }
1124 
1125  //---
1126  // Start with a return status of true and set to false if something bad
1127  // happens.
1128  //---
1129  bool result = true;
1130 
1131  if ( traceDebug() )
1132  {
1133  ossimNotify(ossimNotifyLevel_DEBUG) << "tiffinfo dump to kwl:\n" << gtiffKwl << "\n";
1134  }
1135 
1136  ossimString gtiffPrefix = "tiff.image";
1137  gtiffPrefix += ossimString::toString(entryIndex);
1138  gtiffPrefix += ".";
1139  ossimString geomPrefix = "image";
1140  geomPrefix += ossimString::toString(entryIndex);
1141  geomPrefix += ".";
1142 
1143  // Get the pixel type.
1144  ossimString pixelType;
1145  if ( getPixelType(gtiffPrefix, gtiffKwl, pixelType) == false )
1146  {
1147  pixelType = "pixel_is_point"; // Not an error we'll make assumption?
1148  }
1149  geomKwl.add(geomPrefix.c_str(),
1151  pixelType.c_str());
1152 
1153  // Get the lines.
1154  ossim_uint32 height = getLines(gtiffPrefix, gtiffKwl);
1155  if (height)
1156  {
1157  geomKwl.add(geomPrefix.c_str(),
1159  height);
1160  }
1161  else
1162  {
1163  result = false;
1164  }
1165 
1166  // Get the samples.
1167  ossim_uint32 width = getSamples(gtiffPrefix, gtiffKwl);
1168  if (width)
1169  {
1170  geomKwl.add(geomPrefix.c_str(),
1172  width);
1173  }
1174  else
1175  {
1176  result = false;
1177  }
1178 
1179  // Add the pixel type.
1180  geomKwl.add(geomPrefix.c_str(),
1182  pixelType.c_str());
1183 
1184  // Set the projection type.
1185  bool isGeographic = false;
1186  ossimString pcsCode;
1187  ossimString ossimProjectionName = "";
1188  bool hasPcsCode = getPcsCode(gtiffPrefix, gtiffKwl, pcsCode);
1189 
1190  //---
1191  // The ossimEpsgProjectionFactory will not pick up the origin latitude if code is
1192  // 4326 (geographic) so we use the projection name; else, the origin_latitude will
1193  // always be 0. This is so the gsd comes out correct for scale.
1194  //---
1195  if ( hasPcsCode && ( pcsCode != "4326" ) )
1196  {
1197  // Add the pcs code.
1198  geomKwl.add(geomPrefix.c_str(),
1200  pcsCode.c_str());
1201  }
1202  else
1203  {
1204  if ( getOssimProjectionName(gtiffPrefix, gtiffKwl, ossimProjectionName) == false )
1205  {
1206  ossimProjectionName = "ossimEquDistCylProjection";
1207  }
1208  geomKwl.add(geomPrefix.c_str(), ossimKeywordNames::TYPE_KW, ossimProjectionName);
1209 
1210  if ( ossimProjectionName == "ossimEquDistCylProjection" )
1211  {
1212  isGeographic = true;
1213  }
1214  }
1215 
1216  // Get the units.
1217  ossimString units = "";
1218  getUnits(gtiffPrefix, gtiffKwl, units);
1219  if (units.empty() || (units.contains("unknown")))
1220  {
1221  // HACK: Encountered JP2 with geotiff info that did not specify units, so using projection
1222  // type to discern units if none explicitly specified. (OLK 05/11)
1223  if (ossimProjectionName == "ossimEquDistCylProjection")
1224  units = "degrees";
1225  }
1226 
1227  // Get the pixel scale.
1228  ossimDpt scale;
1229  bool hasScale = getPixelScale(gtiffPrefix, gtiffKwl, scale);
1230 
1231  // Get the tie point.
1232  std::vector<ossim_float64> ties;
1233  getTiePoint(gtiffPrefix, gtiffKwl, ties);
1234 
1235  //---
1236  // Tie count:
1237  // NOTE: It takes six doubles to make one tie point ie:
1238  // x,y,z,longitude,latitude,height or x,y,z,easting,northing,height
1239  //---
1240  ossim_uint32 tieCount = (ossim_uint32)ties.size()/6;
1241 
1242  // Get the model transform.
1243  std::vector<ossim_float64> xfrm;
1244  getModelTransform(gtiffPrefix, gtiffKwl, xfrm);
1245 
1246  bool useXfrm = false;
1247  if ( xfrm.size() == 16 )
1248  {
1249  // Need at least 24 (which is four ties) to use bilinear.
1250  if ( !hasScale && ties.size() < 24 )
1251  {
1252  useXfrm = true;
1253  }
1254  }
1255  if (useXfrm)
1256  {
1257  std::ostringstream out;
1258  out << std::setprecision(15); // To avoid truncating.
1259  ossim_uint32 idx = 0;
1260  for(idx =0; idx < 16; ++idx)
1261  {
1262  out << xfrm[idx] << " ";
1263  }
1264  geomKwl.add(geomPrefix.c_str(),
1266  out.str().c_str(), true);
1267  geomKwl.add(geomPrefix.c_str(),
1269  units.c_str(), true);
1270  }
1271  else // Use tie points.
1272  {
1273  if ( hasScale && (tieCount == 1) )
1274  {
1275  // Shift the tile to 0,0 pixel of image if not already there.
1276  ossimDpt tie;
1277  tie.x = ties[3] - ties[0] * scale.x;
1278  tie.y = ties[4] + ties[1] * scale.y;
1279  geomKwl.add(geomPrefix.c_str(),
1281  tie.toString().c_str());
1282  geomKwl.add(geomPrefix.c_str(),
1284  units.c_str());
1285 
1286  // Add the scale.
1287  geomKwl.add(geomPrefix.c_str(),
1289  scale.toString().c_str());
1290  geomKwl.add(geomPrefix.c_str(),
1292  units.c_str());
1293  }
1294  else if (tieCount > 1) // four or better tie points.
1295  {
1296  ossimTieGptSet tieSet;
1297  getTieSets(ties, width, height, tieSet);
1298 
1299  if(tieCount >= 4)
1300  {
1303  proj->optimizeFit(tieSet);
1304  proj->saveState(geomKwl, geomPrefix.c_str());
1305  if(traceDebug())
1306  {
1308  << "Creating a bilinear projection\n";
1309  }
1310  }
1311  else // Need at least four ties.
1312  {
1313  result = false;
1314  }
1315  }
1316  else
1317  {
1318  result = false;
1319  }
1320 
1321  } // matches: else Use tie points block.
1322 
1323  ossimString tmpStr;
1324  if ( getStdParallelOne(gtiffPrefix, gtiffKwl, tmpStr) )
1325  {
1326  geomKwl.add(geomPrefix.c_str(),
1328  tmpStr);
1329  }
1330 
1331  if ( getStdParallelTwo(gtiffPrefix, gtiffKwl, tmpStr) )
1332  {
1333  geomKwl.add(geomPrefix.c_str(),
1335  tmpStr);
1336  }
1337 
1338  ossimDpt eastingNorthing;
1339  if ( getFalseEastingNorthing(gtiffPrefix, gtiffKwl,
1340  eastingNorthing) )
1341  {
1342  geomKwl.add(geomPrefix.c_str(),
1344  eastingNorthing.toString());
1345  geomKwl.add(geomPrefix.c_str(),
1348  }
1349 
1350  ossim_float64 tmpDbl = ossim::nan();
1351 
1352  if ( getOriginLat(gtiffPrefix, gtiffKwl, tmpDbl) == false )
1353  {
1354  if ( isGeographic && hasScale && scale.x )
1355  {
1356  //---
1357  // ossimEquDistCylProjection uses the origin_latitude for meters per pixel (gsd)
1358  // computation. So is not set in tiff tags, compute to achieve the proper
1359  // horizontal scaling.
1360  //---
1361  tmpDbl = ossim::acosd(scale.y/scale.x);
1362  }
1363  }
1364  if ( !ossim::isnan(tmpDbl) )
1365  {
1366  geomKwl.add(geomPrefix.c_str(),
1368  tmpDbl);
1369  }
1370 
1371  if ( getCentralMeridian(gtiffPrefix, gtiffKwl, tmpDbl) )
1372  {
1373  geomKwl.add(geomPrefix.c_str(),
1375  tmpDbl);
1376  }
1377 
1378  if ( getScaleFactor(gtiffPrefix, gtiffKwl, tmpDbl) )
1379  {
1380  geomKwl.add(geomPrefix.c_str(),
1382  tmpDbl);
1383  }
1384 
1385  if ( getDatumCode(gtiffPrefix, gtiffKwl, tmpStr) )
1386  {
1387  geomKwl.add(geomPrefix.c_str(),
1389  tmpStr.c_str());
1390  }
1391 
1392  //---
1393  // Linear and vertical units not read by projection factories but added so external user could
1394  // query.
1395  //---
1396  if ( getLinearUnits(gtiffPrefix, gtiffKwl, tmpStr) )
1397  {
1398  geomKwl.add(geomPrefix.c_str(),
1399  LINEAR_UNITS_KW.c_str(),
1400  tmpStr.c_str());
1401  }
1402 
1403  if ( getVerticalUnits(gtiffPrefix, gtiffKwl, tmpStr) )
1404  {
1405  geomKwl.add(geomPrefix.c_str(),
1406  VERTICAL_UNITS_KW.c_str(),
1407  tmpStr.c_str());
1408  }
1409 
1410  if (traceDebug())
1411  {
1413  << "geomKwl:\n"
1414  << geomKwl << "\n"
1415  << M << " exit status = " << (result?"true":"false") << "\n";
1416  }
1417 
1418  return result;
1419 }
1420 
1422 {
1423  str.read((char*)&s, sizeof(s));
1424  if (m_endian)
1425  {
1426  m_endian->swap(s);
1427  }
1428 }
1429 
1431 {
1432  str.read((char*)&l, sizeof(l));
1433  if (m_endian)
1434  {
1435  m_endian->swap(l);
1436  }
1437 }
1438 
1440 {
1441  str.read((char*)&l, sizeof(l));
1442  if (m_endian)
1443  {
1444  m_endian->swap(l);
1445  }
1446 }
1447 
1448 
1449 
1451  std::streamoff& offset, std::istream& str, ossim_uint16 version) const
1452 {
1453  bool status = true;
1454  if (version == 42)
1455  {
1456  ossim_uint32 littleOffset;
1457  readLong(littleOffset, str);
1458  offset = littleOffset;
1459  }
1460  else
1461  {
1462  ossim_uint64 bigOffset;
1463  readLongLong(bigOffset, str);
1464  offset = bigOffset;
1465  }
1466  if (!str)
1467  {
1468  status = false;
1469  }
1470  return status;
1471 }
1472 
1474  std::istream& str,
1475  WordType type,
1476  ossim_uint16 version) const
1477 {
1478  bool status = true;
1479  if (version == 42)
1480  {
1481  if (type == TWO_OR_EIGHT)
1482  {
1483  ossim_uint16 i;
1484  readShort(i, str);
1485  value = i;
1486  }
1487  else
1488  {
1489  ossim_uint32 i;
1490  readLong(i, str);
1491  value = i;
1492  }
1493  }
1494  else
1495  {
1496  ossim_uint64 i;
1497  readLongLong(i, str);
1498  value = i;
1499  }
1500  if (!str)
1501  {
1502  status = false;
1503  }
1504  return status;
1505 }
1506 
1508  ossim_uint16 type) const
1509 {
1510  return length * getTypeByteSize(type);
1511 }
1512 
1514 {
1515  ossim_uint16 result = 0;
1516 
1517  switch (type)
1518  {
1519  case ossim::OTIFF_BYTE:
1520  case ossim::OTIFF_ASCII:
1521  case ossim::OTIFF_SBYTE:
1523  {
1524  result = 1;
1525  break;
1526  }
1527 
1528  case ossim::OTIFF_SHORT:
1529  case ossim::OTIFF_SSHORT:
1530  {
1531  result = 2;
1532  break;
1533  }
1534 
1535  case ossim::OTIFF_LONG:
1536  case ossim::OTIFF_SLONG:
1537  case ossim::OTIFF_IFD:
1538  case ossim::OTIFF_FLOAT:
1539  {
1540  result = 4;
1541  break;
1542  }
1543 
1544  case ossim::OTIFF_RATIONAL:
1546  case ossim::OTIFF_DOUBLE:
1547  case 16: // TIFF_LONG8 defined in big tiff only.
1548  case 17: // TIFF_SLONG8 defined in big tiff only.
1549  case 18: // TIFF_IFD8 defined in big tiff only.
1550  {
1551  result = 8;
1552  break;
1553  }
1554 
1555  default:
1556  {
1557  if (traceDebug())
1558  {
1560  << "ossimTiffInfo::getTypeByteSize DEBUG:"
1561  << "\nUnhandled type: " << int(type) << "\n";
1562  }
1563  break;
1564  }
1565  }
1566  return result;
1567 }
1568 
1570 {
1571  if (version == 42)
1572  {
1573  ossim_uint32 dummy;
1574  readLong(dummy, str);
1575  }
1576  else
1577  {
1578  ossim_uint64 dummy;
1579  readLongLong(dummy, str);
1580  }
1581 }
1582 
1584  ossim_uint16 type,
1585  ossim_uint64 count) const
1586 {
1587  if (m_endian)
1588  {
1589  ossim_uint32 byteSize = getTypeByteSize(type);
1590  switch(byteSize)
1591  {
1592  case 2:
1593  m_endian->swapTwoBytes(v, count);
1594  break;
1595  case 4:
1596  m_endian->swapFourBytes(v, count);
1597  break;
1598  case 8:
1599  m_endian->swapEightBytes(v, count);
1600  break;
1601  default:
1602  break;
1603  }
1604  }
1605 }
1606 
1607 template <class T> void ossimTiffInfo::getArrayValue(
1608  T& v,
1609  ossim_uint8* array,
1610  ossim_uint64 position) const
1611 {
1612  T* p = (T*)array;
1613  v = p[position];
1614 }
1615 
1617  const std::string& prefix,
1618  ossim_uint64 tagIdx,
1619  ossim_uint16 tag,
1620  ossim_uint16 type,
1621  ossim_uint64 count,
1622  ossim_uint64 arraySizeInBytes,
1623  ossim_uint8* valueArray) const
1624 {
1625  switch(tag)
1626  {
1627  case ossim::OTIFFTAG_SUBFILETYPE: // tag 254
1628  {
1629  out << prefix << "sub_file_type: ";
1630  printValue(out, type, valueArray);
1631  break;
1632  }
1633  case ossim::OTIFFTAG_IMAGEWIDTH: // tag 256
1634  {
1635  out << prefix << IMAGE_WIDTH_KW << ": ";
1636  printValue(out, type, valueArray);
1637  break;
1638  }
1639 
1640  case ossim::OTIFFTAG_IMAGELENGTH: // tag 257
1641  {
1642  out << prefix << IMAGE_LENGTH_KW << ": ";
1643  printValue(out, type, valueArray);
1644  break;
1645  }
1646 
1647  case ossim::OTIFFTAG_BITSPERSAMPLE: // tag 258
1648  {
1649  out << prefix << "bits_per_sample: ";
1650  if (count == 1)
1651  {
1652  printValue(out, type, valueArray);
1653  }
1654  else if (valueArray)
1655  {
1656  printArray(out, type, count, valueArray);
1657  }
1658  break;
1659  }
1660 
1661  case ossim::OTIFFTAG_COMPRESSION: // tag 259
1662  {
1663  if ( (count == 1) && (type == ossim::OTIFF_SHORT) )
1664  {
1665  out << prefix << "compression: ";
1666 
1667  ossim_uint16 s;
1668  getArrayValue(s, valueArray, 0);
1669  if (s == 1)
1670  {
1671  out << "false\n";
1672  }
1673  else
1674  {
1675  out << "true\n";
1676  }
1677  }
1678  break;
1679  }
1680 
1681  case ossim::OTIFFTAG_PHOTOMETRIC: // tag 262
1682  {
1683  out << prefix << "photo_interpretation: ";
1684 
1685  if ( (count == 1) && (type == ossim::OTIFF_SHORT) )
1686  {
1687  ossim_uint16 s;
1688  getArrayValue(s, valueArray, 0);
1689  if (s <= ossim::OPHOTO_CIELAB)
1690  {
1691  out << PHOTO_INTERP[s] << "\n";
1692  }
1693  else
1694  {
1695  out <<"range error!\n";
1696  }
1697  }
1698  break;
1699  }
1700 
1701  case ossim::OTIFFTAG_FILLORDER: // tag 266
1702  {
1703  if ( (count == 1) && (type == ossim::OTIFF_SHORT) )
1704  {
1705  out << prefix << "fill_order: ";
1706  ossim_uint16 s;
1707  getArrayValue(s, valueArray, 0);
1708  out << s << "\n";
1709 
1710  }
1711  break;
1712  }
1713 
1714  case ossim::OTIFFTAG_IMAGEDESCRIPTION: // tag 270
1715  {
1716  out << prefix << "image_description: ";
1717  printArray(out, type, count, valueArray);
1718  break;
1719  }
1720 
1721  case ossim::OTIFFTAG_MAKE: // tag 271
1722  {
1723  out << prefix << "make: ";
1724  printArray(out, type, count, valueArray);
1725  break;
1726  }
1727 
1728  case ossim::OTIFFTAG_MODEL: // tag 272
1729  {
1730  out << prefix << "model: ";
1731  printArray(out, type, count, valueArray);
1732  break;
1733  }
1734 
1735  case ossim::OTIFFTAG_STRIPOFFSETS: // tag 273
1736  {
1737  if (traceDump())
1738  {
1739  out << prefix << "bytes_per_strip: ";
1740 
1741  if (count == 1)
1742  {
1743  printValue(out, type, valueArray);
1744  }
1745  else
1746  {
1747  printArray(out, type, count, valueArray);
1748  }
1749  }
1750  break;
1751  }
1752  case ossim::OTIFFTAG_ORIENTATION: // tag 274
1753  {
1754  ossim_uint16 code;
1755  getArrayValue(code, valueArray, 0);
1756  printOrientation(out, prefix, code);
1757  break;
1758  }
1759 
1760  case ossim::OTIFFTAG_SAMPLESPERPIXEL: // tag 277
1761  {
1762  out << prefix << "samples_per_pixel: ";
1763  printValue(out, type, valueArray);
1764  break;
1765  }
1766 
1767  case ossim::OTIFFTAG_ROWSPERSTRIP: // tag 278
1768  {
1769  out << prefix << "rows_per_strip: ";
1770  printValue(out, type, valueArray);
1771  break;
1772  }
1773 
1774  case ossim::OTIFFTAG_STRIPBYTECOUNTS: // tag 279
1775  {
1776  if (traceDump())
1777  {
1778  out << prefix << "bytes_per_strip: ";
1779 
1780  if (count == 1)
1781  {
1782  printValue(out, type, valueArray);
1783  }
1784  else
1785  {
1786  printArray(out, type, count, valueArray);
1787  }
1788  }
1789  break;
1790  }
1791 
1792  case ossim::OTIFFTAG_MINSAMPLEVALUE: // tag 280
1793  {
1794  out << prefix << "min_sample_value: ";
1795  printValue(out, type, valueArray);
1796  break;
1797  }
1798  case ossim::OTIFFTAG_MAXSAMPLEVALUE: // tag 281
1799  {
1800  out << prefix << "max_sample_value: ";
1801  printValue(out, type, valueArray);
1802  break;
1803  }
1804 
1805  case ossim::OTIFFTAG_XRESOLUTION: // tag 282
1806  {
1807  out << prefix << "xresolution: ";
1808  printValue(out, type, valueArray);
1809  break;
1810  }
1811  case ossim::OTIFFTAG_YRESOLUTION: // tag 283
1812  {
1813  out << prefix << "yresolution: ";
1814  printValue(out, type, valueArray);
1815  break;
1816  }
1817 
1818  case ossim::OTIFFTAG_PLANARCONFIG: // tag 284
1819  {
1820  if ( (count == 1) && (type == ossim::OTIFF_SHORT) )
1821  {
1822  out << prefix << "planar_configuration: ";
1823  ossim_uint16 v;
1824  getArrayValue(v, valueArray, 0);
1825  if (v == 1)
1826  {
1827  out << "single image plane\n";
1828  }
1829  else if (v == 2)
1830  {
1831  out << "separate image planes\n";
1832  }
1833  else
1834  {
1835  out << "unknown planar value!\n";
1836  }
1837  }
1838  break;
1839  }
1840 
1841  case ossim::OTIFFTAG_RESOLUTIONUNIT: // tag 296
1842  {
1843  out << prefix << "resolution_units: ";
1844  ossim_uint16 v;
1845  getArrayValue(v, valueArray, 0);
1846  if (v == 2)
1847  {
1848  out << "inch\n";
1849  }
1850  else if (v == 3)
1851  {
1852  out << "cm\n";
1853  }
1854  else
1855  {
1856  out << "none\n";
1857  }
1858  break;
1859  }
1860 
1861  case ossim::OTIFFTAG_PAGENUMBER: // tag 297
1862  {
1863  if ( (count == 2) && (type == ossim::OTIFF_SHORT) )
1864  {
1865  out << prefix << "page_number: ";
1866  ossim_uint16 s;
1867  getArrayValue(s, valueArray, 0);
1868  out << s << "\n";
1869  out << prefix << "total_pages: ";
1870  getArrayValue(s, valueArray, 1);
1871  out << s << "\n";
1872  }
1873  break;
1874  }
1875 
1876  case ossim::OTIFFTAG_SOFTWARE: // tag 305
1877  {
1878  out << prefix << "software: ";
1879  printArray(out, type, count, valueArray);
1880  break;
1881  }
1882 
1883  case ossim::OTIFFTAG_DATETIME: // tag 306
1884  {
1885  out << prefix << "date_time: ";
1886  printArray(out, type, count, valueArray);
1887  break;
1888  }
1889 
1890  case ossim::OTIFFTAG_ARTIST: // tag 315
1891  {
1892  out << prefix << "artist: ";
1893  printArray(out, type, count, valueArray);
1894  break;
1895  }
1896 
1897  case ossim::OTIFFTAG_PREDICTOR: // tag 317
1898  {
1899  out << prefix << "predictor: ";
1900  printValue(out, type, valueArray);
1901  break;
1902  }
1903 
1904  case ossim::OTIFFTAG_TILEWIDTH: // tag 322
1905  {
1906  out << prefix << "tile_width: ";
1907  printValue(out, type, valueArray);
1908  break;
1909  }
1910  case ossim::OTIFFTAG_TILELENGTH: // tag 323
1911  {
1912  out << prefix << "tile_length: ";
1913  printValue(out, type, valueArray);
1914  break;
1915  }
1916  case ossim::OTIFFTAG_TILEOFFSETS: // tag 324
1917  {
1918  if (traceDump())
1919  {
1920  out << prefix << "tile_offsets: ";
1921  if (count == 1)
1922  {
1923  printValue(out, type, valueArray);
1924  }
1925  else
1926  {
1927  printArray(out, type, count, valueArray);
1928  }
1929  }
1930  break;
1931  }
1932  case ossim::OTIFFTAG_TILEBYTECOUNTS: // tag 325
1933  {
1934  if (traceDump())
1935  {
1936  out << prefix << "tile_byte_counts: ";
1937  if (count == 1)
1938  {
1939  printValue(out, type, valueArray);
1940  }
1941  else
1942  {
1943  printArray(out, type, count, valueArray);
1944  }
1945  }
1946  break;
1947  }
1948  case ossim::OTIFFTAG_SUBIFD: // tag 330
1949  {
1950  if ( (count == 1) && (type == ossim::OTIFF_IFD8) )
1951  {
1952  out << prefix << "subimage_descriptor: ";
1953  ossim_uint64 v;
1954  getArrayValue(v, valueArray, 0);
1955  out << v << "\n";
1956  }
1957  else
1958  {
1959  out << prefix << "tag 330 unhandled condition.\n";
1960  }
1961  break;
1962  }
1963  case ossim::OTIFFTAG_EXTRASAMPLES: // tag 338
1964  {
1965  out << prefix << "extra_samples: ";
1966  ossim_uint16 v;
1967  getArrayValue(v, valueArray, 0);
1968  switch (v)
1969  {
1970  case 1:
1971  {
1972  out << "associated_alpha_data\n";
1973  break;
1974  }
1975  case 2:
1976  {
1977  out << "unassociated_alpha_data\n";
1978  break;
1979  }
1980  default:
1981  {
1982  out << "unspecified_data\n";
1983  break;
1984  }
1985  }
1986  break;
1987  }
1988  case ossim::OTIFFTAG_SAMPLEFORMAT: // tag 339
1989  {
1990  out << prefix << "sample_format: ";
1991 
1992  if (count == 1)
1993  {
1994  printValue(out, type, valueArray);
1995  }
1996  else if (valueArray)
1997  {
1998  printArray(out, type, count, valueArray);
1999  }
2000  for (ossim_uint64 i = 0; i < count; ++i)
2001  {
2003  s << "sample_format_string";
2004  if (count > 1)
2005  {
2006  s << i;
2007  }
2008  out << prefix << s.str() << ": ";
2009 
2010  ossim_uint16 v;
2011  getArrayValue(v, valueArray, i);
2012  switch (v)
2013  {
2015  out << "unsigned integer data\n";
2016  break;
2018  out << "signed integer data\n";
2019  break;
2021  out << "IEEE floating point data\n";
2022  break;
2024  out << "complex signed int\n";
2025  break;
2027  out << "complex ieee floating\n";
2028  break;
2030  default:
2031  out << "untyped data\n";
2032  break;
2033  }
2034  }
2035  break;
2036  }
2037  case ossim::OTIFFTAG_SMINSAMPLEVALUE: // tag 340
2038  {
2039  out << prefix << "smin_sample_value: ";
2040  printValue(out, type, valueArray);
2041  break;
2042  }
2043  case ossim::OTIFFTAG_SMAXSAMPLEVALUE: // tag 341
2044  {
2045  out << prefix << "smax_sample_value: ";
2046  printValue(out, type, valueArray);
2047  break;
2048  }
2049 
2050  case ossim::OTIFFTAG_XMLPACKET: // tag 700
2051  {
2052  if (traceDebug())
2053  {
2055  << prefix << "xml: ";
2057  ossim::OTIFF_BYTE, count, valueArray);
2058  }
2059  printXmpMetadata(out, prefix, count, valueArray);
2060  break;
2061  }
2062 
2063  case ossim::OTIFFTAG_COPYRIGHT: // tag 33432
2064  {
2065  out << prefix << "copyright: ";
2066  printArray(out, type, count, valueArray);
2067  break;
2068  }
2069  case ossim::OMODEL_PIXEL_SCALE_TAG: // tag 33550
2070  {
2071  out << prefix << MODEL_PIXEL_SCALE_KW << ": ";
2072  printArray(out, type, count, valueArray);
2073  break;
2074  }
2075  case ossim::OMODEL_TIE_POINT_TAG: // tag 33992
2076  {
2077  out << prefix << MODEL_TIE_POINT_KW << ": ";
2078  printArray(out, type, count, valueArray);
2079  break;
2080  }
2081  case ossim::OMODEL_TRANSFORM_TAG: // tag 34264
2082  {
2083  out << prefix << MODEL_TRANSFORM_KW << ": ";
2084  printArray(out, type, count, valueArray);
2085  break;
2086  }
2087  case ossim::OTIFFTAG_PHOTOSHOP: // tag 34377
2088  {
2089  out << prefix << "photoshop_image_resource_blocks: found\n";
2090  break;
2091  }
2092  case ossim::OGEO_DOUBLE_PARAMS_TAG: // tag 34736
2093  {
2094  out << prefix << "double_params: ";
2095  printArray(out, type, count, valueArray);
2096  break;
2097  }
2098  case ossim::OGEO_ASCII_PARAMS_TAG: // tag 34737
2099  {
2100  out << prefix << "ascii_params: ";
2101  printArray(out, type, count, valueArray);
2102  break;
2103  }
2104  case ossim::OGDAL_METADATA_TAG: // tag 42112
2105  {
2106  printGdalMetadata(out, prefix, count, valueArray);
2107  break;
2108  }
2109  case ossim::OGDAL_NODATA: // tag 42113
2110  {
2111  out << prefix << "gdal_nodata: ";
2112  printArray(out, type, count, valueArray);
2113  break;
2114  }
2115 
2116  case ossim::ORPC_COEFFICIENT_TAG: // tag 50844
2117  {
2118  printRpcs(out, prefix, type, count, valueArray);
2119  break;
2120  }
2121 
2122  default:
2123  {
2124  out << prefix << "unhandled_tag: " << tag << "\n";
2125  if (traceDebug())
2126  {
2128  << "generic:"
2129  << "\ntag[" << tagIdx << "]: " << tag
2130  << "\ntype: " << type
2131  << "\ncount: " << count
2132  << "\narray size in bytes: " << arraySizeInBytes
2133  << "\n";
2134  printArray(out, type, count, valueArray);
2135  }
2136  break;
2137  }
2138 
2139  } // end of switch on tag...
2140 
2141  return out;
2142 
2143 } // end of print
2144 
2146  ossim_uint16 type,
2147  ossim_uint8* valueArray) const
2148 {
2149  switch (type)
2150  {
2151  case ossim::OTIFF_BYTE:
2152  {
2153  ossim_uint8 v;
2154  getArrayValue(v, valueArray, 0);
2155  out << (ossim_uint16)v << "\n";
2156  break;
2157  }
2158  case ossim::OTIFF_SHORT:
2159  {
2160  ossim_uint16 v;
2161  getArrayValue(v, valueArray, 0);
2162  out << v << "\n";
2163  break;
2164  }
2165  case ossim::OTIFF_SSHORT:
2166  {
2167  ossim_sint16 v;
2168  getArrayValue(v, valueArray, 0);
2169  out << v << "\n";
2170  break;
2171  }
2172  case ossim::OTIFF_LONG:
2173  {
2174  ossim_uint32 v;
2175  getArrayValue(v, valueArray, 0);
2176  out << v << "\n";
2177  break;
2178  }
2179  case ossim::OTIFF_RATIONAL: // two longs first=numerator, second=denominator
2180  {
2181  ossim_uint32 num;
2182  ossim_uint32 den;
2183 
2184  getArrayValue(num, valueArray, 0);
2185  getArrayValue(den, valueArray, 1);
2186 
2187  if ( den )
2188  {
2189  out << (num/den) << "\n";
2190  }
2191  else
2192  {
2193  out << num << " / " << den << "\n";
2194  }
2195 
2196  break;
2197 
2198  }
2199  case ossim::OTIFF_SLONG:
2200  {
2201  ossim_sint32 v;
2202  getArrayValue(v, valueArray, 0);
2203  out << v << "\n";
2204  break;
2205  }
2206  case ossim::OTIFF_FLOAT:
2207  {
2208  ossim_float32 v;
2209  getArrayValue(v, valueArray, 0);
2210  out << v << "\n";
2211  break;
2212  }
2213  case ossim::OTIFF_DOUBLE:
2214  {
2215  ossim_float64 v;
2216  getArrayValue(v, valueArray, 0);
2217  out << v << "\n";
2218  break;
2219  }
2220  default:
2221  {
2222  out << "print_value_unhandled type: " << type << "\n";
2223  break;
2224  }
2225  }
2226  return out;
2227 }
2228 
2230  ossim_uint16 type,
2231  ossim_uint64 arraySizeInBytes,
2232  ossim_uint8* valueArray) const
2233 {
2234  if (valueArray)
2235  {
2236  switch (type)
2237  {
2238  case ossim::OTIFF_BYTE:
2239  {
2240  for (ossim_uint64 i = 0; i < arraySizeInBytes; ++i)
2241  {
2242  out << ((ossim_uint8)valueArray[i]);
2243  }
2244  out << "\n";
2245  break;
2246  }
2247  case ossim::OTIFF_ASCII:
2248  {
2249  //---
2250  // Add tripple quotes front and back for ossimKeywordlist to handle multi-line
2251  // comments.
2252  //---
2253  out << "\"\"\"";
2254  for (ossim_uint64 i = 0; i < arraySizeInBytes; ++i)
2255  {
2256  //---
2257  // Test to avoid putting nulls in the ascii string out. Added to fix
2258  // ossimKeywordlist::parseStream returning false on trailing null Where array was
2259  // tagged as 11 bytes and ascii string was OrthoVista(10 bytes) and 11 byte was
2260  // ascii NUL '\0'.
2261  //---
2262  if ( valueArray[i] != 0 )
2263  {
2264  out << ((char)valueArray[i]);
2265  }
2266  }
2267  out << "\"\"\"\n";
2268  break;
2269  }
2270  case ossim::OTIFF_SHORT:
2271  {
2272  ossim_uint16* p = (ossim_uint16*)valueArray;
2273  for (ossim_uint64 i = 0; i < arraySizeInBytes; ++i)
2274  {
2275  out << p[i] << " ";
2276  }
2277  out << "\n";
2278  break;
2279  }
2280  case ossim::OTIFF_LONG:
2281  {
2282  ossim_uint32* p = (ossim_uint32*)valueArray;
2283  for (ossim_uint64 i = 0; i < arraySizeInBytes; ++i)
2284  {
2285  out << p[i] << " ";
2286  }
2287  out << "\n";
2288  break;
2289  }
2290  case ossim::OTIFF_LONG8:
2291  {
2292  ossim_uint64* p = (ossim_uint64*)valueArray;
2293  for (ossim_uint64 i = 0; i < arraySizeInBytes; ++i)
2294  {
2295  out << p[i] << " ";
2296  }
2297  out << "\n";
2298  break;
2299  }
2300  case ossim::OTIFF_DOUBLE:
2301  {
2302  ossim_float64* p = (ossim_float64*)valueArray;
2303  for (ossim_uint64 i = 0; i < arraySizeInBytes; ++i)
2304  {
2305  out << p[i] << " ";
2306  }
2307  out << "\n";
2308  break;
2309  }
2310  default:
2311  {
2312  out << "print_array_unhandled type: " << type << "\n";
2313  break;
2314  }
2315  }
2316  }
2317  else
2318  {
2319  out << "null array passed to ossimTiffInfo::printArray method." << "\n";
2320  }
2321  return out;
2322 }
2323 
2325  const std::string& prefix,
2326  ossim_uint64 count,
2327  ossim_uint8* valueArray) const
2328 {
2329  ossimString xmlString(valueArray, valueArray+count);
2330  ossimRefPtr<ossimXmlNode> xmlNode = new ossimXmlNode();
2331  std::istringstream in(xmlString);
2332  if(xmlNode->read(in))
2333  {
2334  const ossimXmlNode::ChildListType& children = xmlNode->getChildNodes();
2335 
2336  ossim_uint32 idx = 0;
2337  for(idx = 0; idx < children.size(); ++idx)
2338  {
2339  out << prefix << "gdalmetadata."
2340  << ossimString(children[idx]->getAttributeValue("name")).downcase()
2341  << ":" << children[idx]->getText() << std::endl;
2342  }
2343  }
2344  return out;
2345 }
2346 
2348  const std::string& prefix,
2349  ossim_uint64 count,
2350  ossim_uint8* valueArray) const
2351 {
2352  ossimString xmlString(valueArray, valueArray+count);
2353  ossimRefPtr<ossimXmlNode> xmlNode = new ossimXmlNode();
2354  std::istringstream in(xmlString);
2355 
2357 
2358  // Read the xml document:
2359  if ( xdoc->read( in ) )
2360  {
2361  std::vector<ossimRefPtr<ossimXmlNode> > xnodes;
2362 
2363  // Wavelength:
2364  ossimString path = "/x:xmpmeta/rdf:RDF/rdf:Description/Camera:CentralWavelength";
2365  ossimString result;
2366  xdoc->findNodes(path, xnodes);
2367  if ( xnodes.size() == 1 ) // Error if more than one.
2368  {
2369  if ( xnodes[0].valid() )
2370  {
2371  result = xnodes[0]->getText();
2372  if ( result.size() )
2373  {
2374  out << prefix << "xmp.camera.central_wavelength: " << result << "\n";
2375  }
2376  }
2377  }
2378 
2379  xnodes.clear();
2380  path = "/x:xmpmeta/rdf:RDF/rdf:Description/Camera:BandName";
2381  xdoc->findNodes(path, xnodes);
2382  if ( xnodes.size() == 1 ) // Error if more than one.
2383  {
2384  if ( xnodes[0].valid() )
2385  {
2386  result = xnodes[0]->getText();
2387  if ( result.size() )
2388  {
2389  out << prefix << "xmp.camera.band_name: " << result << "\n";
2390  }
2391  }
2392  }
2393 
2394  xnodes.clear();
2395  path = "/x:xmpmeta/rdf:RDF/rdf:Description/Camera:WavelengthFWHM";
2396  xdoc->findNodes(path, xnodes);
2397  if ( xnodes.size() == 1 ) // Error if more than one.
2398  {
2399  if ( xnodes[0].valid() )
2400  {
2401  result = xnodes[0]->getText();
2402  if ( result.size() )
2403  {
2404  out << prefix << "xmp.camera.wavelength_fwhm: " << result << "\n";
2405  }
2406  }
2407  }
2408 
2409  xnodes.clear();
2410  path = "/x:xmpmeta/rdf:RDF/rdf:Description/Camera:BandSensitivity";
2411  xdoc->findNodes(path, xnodes);
2412  if ( xnodes.size() == 1 ) // Error if more than one.
2413  {
2414  if ( xnodes[0].valid() )
2415  {
2416  result = xnodes[0]->getText();
2417  if ( result.size() )
2418  {
2419  out << prefix << "xmp.camera.band_sensitivity: " << result << "\n";
2420  }
2421  }
2422  }
2423 
2424  xnodes.clear();
2425  path = "/x:xmpmeta/rdf:RDF/rdf:Description/Camera:RigCameraIndex";
2426  xdoc->findNodes(path, xnodes);
2427  if ( xnodes.size() == 1 ) // Error if more than one.
2428  {
2429  if ( xnodes[0].valid() )
2430  {
2431  result = xnodes[0]->getText();
2432  if ( result.size() )
2433  {
2434  out << prefix << "xmp.camera.rig_camera_index: " << result << "\n";
2435  }
2436  }
2437  }
2438 
2439  xnodes.clear();
2440  path = "/x:xmpmeta/rdf:RDF/rdf:Description/Camera:Yaw";
2441  xdoc->findNodes(path, xnodes);
2442  if ( xnodes.size() == 1 ) // Error if more than one.
2443  {
2444  if ( xnodes[0].valid() )
2445  {
2446  result = xnodes[0]->getText();
2447  if ( result.size() )
2448  {
2449  out << prefix << "xmp.camera.yaw: " << result << "\n";
2450  }
2451  }
2452  }
2453 
2454  xnodes.clear();
2455  path = "/x:xmpmeta/rdf:RDF/rdf:Description/Camera:Pitch";
2456  xdoc->findNodes(path, xnodes);
2457  if ( xnodes.size() == 1 ) // Error if more than one.
2458  {
2459  if ( xnodes[0].valid() )
2460  {
2461  result = xnodes[0]->getText();
2462  if ( result.size() )
2463  {
2464  out << prefix << "xmp.camera.pitch: " << result << "\n";
2465  }
2466  }
2467  }
2468 
2469  xnodes.clear();
2470  path = "/x:xmpmeta/rdf:RDF/rdf:Description/Camera:Roll";
2471  xdoc->findNodes(path, xnodes);
2472  if ( xnodes.size() == 1 ) // Error if more than one.
2473  {
2474  if ( xnodes[0].valid() )
2475  {
2476  result = xnodes[0]->getText();
2477  if ( result.size() )
2478  {
2479  out << prefix << "xmp.camera.roll: " << result << "\n";
2480  }
2481  }
2482  }
2483  }
2484 
2485  return out;
2486 }
2487 
2489  std::ostream& out,
2490  const std::string& prefix,
2491  ossim_uint64 geoKeyLength,
2492  ossim_uint16* geoKeyBlock,
2493  ossim_uint64 geoDoubleLength,
2494  ossim_float64* geoDoubleBlock,
2495  ossim_uint64 geoAsciiLength,
2496  ossim_int8* geoAsciiBlock) const
2497 {
2498  if (geoKeyLength && geoKeyBlock)
2499  {
2500  //---
2501  // Length passed in is the total number of shorts in the geo key
2502  // directory. Each key has four short values; hence, "length/4".
2503  //---
2504  ossim_int32 index = 0;
2505  ossim_int32 tagCount = static_cast<ossim_int32>(geoKeyLength/4);
2506  for (ossim_int32 i = 0; i < tagCount; ++i)
2507  {
2508  //---
2509  // Each key contains four unsigned shorts:
2510  // GeoKey ID
2511  // TIFF Tag ID or 0
2512  // GeoKey value count
2513  // value or tag offset
2514  //---
2515  ossim_uint16 key = geoKeyBlock[index++];
2516  ossim_uint16 tag = geoKeyBlock[index++];
2517  ossim_uint16 count = geoKeyBlock[index++];
2518  ossim_uint16 code = geoKeyBlock[index++];
2519 
2520  if (traceDebug())
2521  {
2523  << "DEBUG ossimTiffInfo::printGeoKeys"
2524  << "\nKey index: " << i
2525  << "\ngeo key: " << key
2526  << "\ntag: " << tag
2527  << "\ncount: " << count
2528  << "\ncode: " << code
2529  << "\n";
2530  }
2531 
2532  //---
2533  // NOTE: Add tripple quotes front and back of ascii blocks for
2534  // ossimKeywordlist to handle multi-line comments.
2535  //---
2536 
2537  switch (key)
2538  {
2539  case ossim::OGT_MODEL_TYPE_GEO_KEY: // key 1024 Section 6.3.1.1 Codes
2540  {
2541  printModelType(out, prefix, code);
2542  break;
2543  }
2544  case ossim::OGT_RASTER_TYPE_GEO_KEY: // key 1025 Section 6.3.1.2 Code
2545  {
2546  printRasterType(out, prefix, code);
2547  break;
2548  }
2549 
2550  case ossim::OGT_CITATION_GEO_KEY: // key 1026
2551  {
2552  if (tag == 34737) // using ascii array
2553  {
2554  if (geoAsciiBlock && ( (code+count) <= geoAsciiLength ) )
2555  {
2556  std::string s;
2557  int i = 0;
2558  while (i < count)
2559  {
2560  s.push_back(geoAsciiBlock[code+i]);
2561  ++i;
2562  }
2563  out << prefix << "citation: \"\"\"" << s << "\"\"\"\n";
2564  }
2565  }
2566  break;
2567  }
2568 
2569  case ossim::OGEOGRAPHIC_TYPE_GEO_KEY: // key 2048 Section 6.3.2.1 Codes
2570  {
2571  out << prefix << ossimKeywordNames::GCS_CODE_KW << ": "
2572  << code << "\n";
2573  break;
2574  }
2575 
2576  case ossim::OGEOG_CITATION_GEO_KEY: // key 2049
2577  {
2578  if (tag == 34737) // using ascii array
2579  {
2580  if (geoAsciiBlock && ( (code+count) <= geoAsciiLength ) )
2581  {
2582  std::string s;
2583  int i = 0;
2584  while (i < count)
2585  {
2586  s.push_back(geoAsciiBlock[code+i]);
2587  ++i;
2588  }
2589  out << prefix << "geographic_citation: \"\"\"" << s << "\"\"\"\n";
2590  }
2591  }
2592  break;
2593  }
2594 
2595  case ossim::OGEOG_GEODETIC_DATUM_GEO_KEY:// key 2050 Section 6.3.2.2 Codes
2596  {
2597  out << prefix << GEODETIC_DATUM_KW << ": " << code << "\n";
2598  break;
2599  }
2600 
2601  case ossim::OGEOG_PRIME_MERIDIAN_GEOKEY:// key 2051 Section 6.3.2.4 Codes
2602  {
2603  out << prefix << "prime_meridian_code: " << code << "\n";
2604  break;
2605  }
2606 
2607  case ossim::OGEOG_LINEAR_UNITS_GEO_KEY:// key 2052 Section 6.3.1.3 Codes
2608  {
2609  out << prefix << "linear_units_code: " << code << "\n";
2610  printLinearUnits(out, prefix, LINEAR_UNITS_KW, code);
2611  break;
2612  }
2613 
2614  case ossim::OGEOG_ANGULAR_UNITS_GEO_KEY:// key 2054 Section 6.3.1.4 Codes
2615  {
2616  out << prefix << "angular_units_code: " << code << "\n";
2617  printAngularUnits(out, prefix, code);
2618  break;
2619  }
2620 
2621  case ossim::OGEOG_ANGULAR_UNIT_SIZE_GEO_KEY:// key 2055 Size in radians Section 6.2.2
2622  {
2623  if (tag == 34736) // using double array
2624  {
2625  // Code is index into array.
2626  if ( geoDoubleBlock && (code < geoDoubleLength) )
2627  {
2628  // Always count of one.
2629  out << prefix << "angular_units_size_radians: "
2630  << geoDoubleBlock[code] << "\n";
2631  }
2632  }
2633  break;
2634  }
2635 
2636  case ossim::OGEOG_ELLIPSOID_GEO_KEY:// key 2056 Section 6.3.23 Codes
2637  {
2638  out << prefix << "ellipsoid_code: " << code << "\n";
2639  break;
2640  }
2641 
2642  case ossim::OGEOG_SEMI_MAJOR_AXIS: // key 2057
2643  {
2644  if (tag == 34736) // using double array
2645  {
2646  // Code is index into array.
2647  if ( geoDoubleBlock && (code < geoDoubleLength) )
2648  {
2649  // Always count of one.
2650  out << prefix << "semi_major_axis: " << geoDoubleBlock[code] << "\n";
2651  }
2652  }
2653  break;
2654  }
2655 
2656  case ossim::OGEOG_SEMI_MINOR_AXIS: // key 2058
2657  {
2658  if (tag == 34736) // using double array
2659  {
2660  // Code is index into array.
2661  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2662  {
2663  // Always count of one.
2664  out << prefix << "semi_minor_axis: " << geoDoubleBlock[code] << "\n";
2665  }
2666  }
2667  break;
2668  }
2669 
2670  case ossim::OGEOG_INV_FLATTENING_GEO_KEY: // key 2059 ratio Section 6.2.2
2671  {
2672  if (tag == 34736) // using double array
2673  {
2674  // Code is index into array.
2675  if ( geoDoubleBlock && (code < geoDoubleLength) )
2676  {
2677  // Always count of one.
2678  out << prefix << "inverse_flattening_ratio: " << geoDoubleBlock[code] << "\n";
2679  }
2680  }
2681  break;
2682  }
2683 
2684  case ossim::OGEOG_PRIME_MERIDIAN_LONG_GEO_KEY: // key 2061 GeogAngularUnit Section 6.2.2
2685  {
2686  if (tag == 34736) // using double array
2687  {
2688  // Code is index into array.
2689  if ( geoDoubleBlock && (code < geoDoubleLength) )
2690  {
2691  // Always count of one.
2692  out << prefix << "prime_meridian_longitude: " << geoDoubleBlock[code] << "\n";
2693  }
2694  }
2695  break;
2696  }
2697 
2698  case ossim::OPROJECTED_CS_TYPE_GEO_KEY: // key 3072 Section 6.3.3.1 codes
2699  {
2700  out << prefix << "pcs_code: " << code << "\n";
2701  break;
2702  }
2703 
2704  case ossim::OPCS_CITATION_GEO_KEY: // key 3073 ascii
2705  {
2706  if (tag == 34737) // using ascii array
2707  {
2708  if (geoAsciiBlock && ( (code+count) <= geoAsciiLength ) )
2709  {
2710  std::string s;
2711  int i = 0;
2712  while (i < count)
2713  {
2714  s.push_back(geoAsciiBlock[code+i]);
2715  ++i;
2716  }
2717  out << prefix << "pcs_citation: \"\"\"" << s << "\"\"\"\n";
2718  }
2719  }
2720 
2721  break;
2722  }
2723 
2724  case ossim::OPROJECTION_GEO_KEY: // key 3074 Section 6.3.3.2 codes
2725  {
2726  out << prefix << "proj_code: " << code << "\n";
2727  break;
2728  }
2729 
2730  case ossim::OPROJ_COORD_TRANS_GEO_KEY: // key 3075 Section 6.3.3.3 codes
2731  {
2732  out << prefix << COORD_TRANS_CODE_KW << ": " << code << "\n";
2733  printCoordTrans(out, prefix, code);
2734  break;
2735  }
2736 
2737  case ossim::OPROJ_LINEAR_UNITS_GEO_KEY: // key 3076 Section 6.3.1.3 codes
2738  {
2739  out << prefix << "linear_units_code: " << code << "\n";
2740  printLinearUnits(out, prefix, std::string("linear_units"), code);
2741  break;
2742  }
2743 
2744  case ossim::OPROJ_LINEAR_UNIT_SIZE_GEO_KEY: // key 3077 meters Section 6.2.3
2745  {
2746  if (tag == 34736) // using double array
2747  {
2748  // Code is index into array.
2749  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2750  {
2751  // Always count of one.
2752  out << prefix << "linear_units_size: " << geoDoubleBlock[code] << "\n";
2753  }
2754  }
2755  break;
2756  }
2757 
2758  case ossim::OPROJ_STD_PARALLEL1_GEO_KEY: // key 3078
2759  {
2760  if (tag == 34736) // using double array
2761  {
2762  // Code is index into array.
2763  if ( geoDoubleBlock && (code < geoDoubleLength) )
2764  {
2765  // Always count of one.
2766  out << prefix
2768  << geoDoubleBlock[code] << "\n";
2769  }
2770  }
2771  break;
2772  }
2773 
2774  case ossim::OPROJ_STD_PARALLEL2_GEO_KEY: // key 3079
2775  {
2776  if (tag == 34736) // using double array
2777  {
2778  // Code is index into array.
2779  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2780  {
2781  // Always count of one.
2782  out << prefix
2784  << geoDoubleBlock[code] << "\n";
2785  }
2786  }
2787  break;
2788  }
2789 
2790  case ossim::OPROJ_NAT_ORIGIN_LONG_GEO_KEY: // key 3080
2791  {
2792  if (tag == 34736) // using double array
2793  {
2794  // Code is index into array.
2795  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2796  {
2797  // Always count of one.
2798  out << prefix << ORIGIN_LONGITUDE_KW << ": "
2799  << geoDoubleBlock[code] << "\n";
2800  }
2801  }
2802  break;
2803  }
2804 
2805  case ossim::OPROJ_NAT_ORIGIN_LAT_GEO_KEY: // key 3081
2806  {
2807  if (tag == 34736) // using double array
2808  {
2809  // Code is index into array.
2810  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2811  {
2812  // Always count of one.
2813  out << prefix << ORIGIN_LATITUDE_KW << ": "
2814  << geoDoubleBlock[code] << "\n";
2815  }
2816  }
2817  break;
2818  }
2819 
2820  case ossim::OPROJ_FALSE_EASTING_GEO_KEY: // key 3082
2821  {
2822  if (tag == 34736) // using double array
2823  {
2824  // Code is index into array.
2825  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2826  {
2827  // Always count of one.
2828  out << prefix
2830  << geoDoubleBlock[code] << "\n";
2831  }
2832  }
2833  break;
2834  }
2835 
2836  case ossim::OPROJ_FALSE_NORTHING_GEO_KEY: // key 3083
2837  {
2838  if (tag == 34736) // using double array
2839  {
2840  // Code is index into array.
2841  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2842  {
2843  // Always count of one.
2844  out << prefix
2846  << ": "
2847  << geoDoubleBlock[code] << "\n";
2848  }
2849  }
2850  break;
2851  }
2852 
2853  case ossim::OPROJ_FALSE_ORIGIN_LONG_GEO_KEY: // key 3084
2854  {
2855  if (tag == 34736) // using double array
2856  {
2857  // Code is index into array.
2858  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2859  {
2860  // Always count of one.
2861  out << prefix
2862  << FALSE_ORIGIN_LONGITUDE_KW << ": "
2863  << geoDoubleBlock[code] << "\n";
2864  }
2865  }
2866  break;
2867  }
2868 
2869  case ossim::OPROJ_FALSE_ORIGIN_LAT_GEO_KEY: // key 3085
2870  {
2871  if (tag == 34736) // using double array
2872  {
2873  // Code is index into array.
2874  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2875  {
2876  // Always count of one.
2877  out << prefix
2878  << FALSE_ORIGIN_LATITUDE_KW << ": "
2879  << geoDoubleBlock[code] << "\n";
2880  }
2881  }
2882  break;
2883  }
2884 
2886  {
2887  if (tag == 34736) // using double array
2888  {
2889  // Code is index into array.
2890  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2891  {
2892  // Always count of one.
2893  out << prefix
2894  << FALSE_ORIGIN_EASTING_KW<< ": "
2895  << geoDoubleBlock[code] << "\n";
2896  }
2897  }
2898  break;
2899  }
2900 
2902  {
2903  if (tag == 34736) // using double array
2904  {
2905  // Code is index into array.
2906  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2907  {
2908  // Always count of one.
2909  out << prefix
2910  << FALSE_ORIGIN_NORTHING_KW<< ": "
2911  << geoDoubleBlock[code] << "\n";
2912  }
2913  }
2914  break;
2915  }
2916 
2917  case ossim::OPROJ_CENTER_LONG_GEO_KEY: // key 3088
2918  {
2919  if (tag == 34736) // using double array
2920  {
2921  // Code is index into array.
2922  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2923  {
2924  // Always count of one.
2925  out << prefix << "center_longitude: "
2926  << geoDoubleBlock[code] << "\n";
2927  }
2928  }
2929  break;
2930  }
2931 
2932  case ossim::OPROJ_CENTER_LAT_GEO_KEY: // key 3089
2933  {
2934  if (tag == 34736) // using double array
2935  {
2936  // Code is index into array.
2937  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2938  {
2939  // Always count of one.
2940  out << prefix << "center_latitude: "
2941  << geoDoubleBlock[code] << "\n";
2942  }
2943  }
2944  break;
2945  }
2946 
2948  {
2949  if (tag == 34736) // using double array
2950  {
2951  // Code is index into array.
2952  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2953  {
2954  // Always count of one.
2955  out << prefix << ossimKeywordNames::SCALE_FACTOR_KW
2956  << ": "
2957  << geoDoubleBlock[code] << "\n";
2958  }
2959  }
2960  break;
2961  }
2962  case ossim::OPROJ_SCALE_AT_CENTER_GEO_KEY: // key 3093
2963  {
2964  if (tag == 34736) // using double array
2965  {
2966  // Code is index into array.
2967  if ( geoDoubleBlock && ( code < geoDoubleLength) )
2968  {
2969  // Always count of one.
2970  out << prefix << ossimKeywordNames::SCALE_FACTOR_KW
2971  << ": "
2972  << geoDoubleBlock[code] << "\n";
2973  }
2974  }
2975  break;
2976  }
2977 
2978  case ossim::OVERTICAL_CITATION_GEO_KEY: // key 4097
2979  {
2980  if (tag == 34737) // using ascii array
2981  {
2982  if (geoAsciiBlock && ( (code+count) <= geoAsciiLength ) )
2983  {
2984  std::string s;
2985  int i = 0;
2986  while (i < count)
2987  {
2988  s.push_back(geoAsciiBlock[code+i]);
2989  ++i;
2990  }
2991  out << prefix << "vertical_citation: \"\"\"" << s << "\"\"\"\n";
2992  }
2993  }
2994  break;
2995  }
2996 
2997  case ossim::OVERTICAL_UNITS_GEO_KEY: // key 4099 Section 6.3.1.3 Codes
2998  {
2999  out << prefix << "vertical_units_code: " << code << "\n";
3000  printLinearUnits(out, prefix, VERTICAL_UNITS_KW, code);
3001  break;
3002  }
3003 
3004  default:
3005  {
3006  if (key > 1)
3007  {
3008  if (tag == 34737) // using ascii array
3009  {
3010  if (geoAsciiBlock && ( (code+count) <= geoAsciiLength ) )
3011  {
3012  std::string s;
3013  int i = 0;
3014  while (i < count)
3015  {
3016  s.push_back(geoAsciiBlock[code+i]);
3017  ++i;
3018  }
3019  out << prefix << "key_" << key << ": \"\"\"" << s << "\"\"\"\n";
3020  }
3021  }
3022  else
3023  {
3024  out << prefix << "unhandle_key: " << key << "\n";
3025  }
3026  }
3027  break;
3028  }
3029 
3030  } // matches: switch(key)
3031 
3032  } // for (ossim_int32 i = 0; i < tagCount; ++i)
3033 
3034  if (traceDebug())
3035  {
3036  if (geoAsciiBlock && geoAsciiLength)
3037  {
3039  << "ossimTiffInfo::printGeoKeys DEBUG: geo ascii block: ";
3040  std::string s(geoAsciiBlock, static_cast<std::string::size_type>(geoAsciiLength));
3041  ossimNotify(ossimNotifyLevel_DEBUG)<< s << "\n";
3042  }
3043  }
3044 
3045  } // if (geoKeyLength && geoKeyBlock)
3046 
3047  return out;
3048 }
3049 
3051  const std::string& prefix,
3052  ossim_uint16 type,
3053  ossim_uint64 count,
3054  ossim_uint8* valueArray) const
3055 {
3056  if ( valueArray )
3057  {
3058  if ( count == 92 )
3059  {
3060  switch (type)
3061  {
3062  case ossim::OTIFF_DOUBLE:
3063  {
3064  ossim_float64* p = (ossim_float64*)valueArray;
3065 
3066  out << prefix << "rpc.bias_error: " << p[0] << "\n"
3067  << prefix << "rpc.rand_error: " << p[1] << "\n"
3068  << prefix << "rpc.line_off: " << p[2] << "\n"
3069  << prefix << "rpc.samp_off: " << p[3] << "\n"
3070  << prefix << "rpc.lat_off: " << p[4] << "\n"
3071  << prefix << "rpc.long_off: " << p[5] << "\n"
3072  << prefix << "rpc.height_off: " << p[6] << "\n"
3073  << prefix << "rpc.line_scale: " << p[7] << "\n"
3074  << prefix << "rpc.samp_scale: " << p[8] << "\n"
3075  << prefix << "rpc.lat_scale: " << p[9] << "\n"
3076  << prefix << "rpc.long_scale: " << p[10] << "\n"
3077  << prefix << "rpc.height_scale: " << p[11] << "\n";
3078 
3079  ossim_int32 i = 12;
3080  ossim_int32 coeff = 0;
3081 
3082  for (coeff = 0; coeff < 20; ++coeff)
3083  {
3084  out << prefix << "rpc.line_num_coeff_" << std::setfill('0')
3085  << std::setw(2) << coeff << ": " << p[i] << "\n";
3086  ++i;
3087  }
3088  for (coeff = 0; coeff < 20; ++coeff)
3089  {
3090  out << prefix << "rpc.line_den_coeff_" << std::setfill('0')
3091  << std::setw(2) << coeff << ": " << p[i] << "\n";
3092  ++i;
3093  }
3094  for (coeff = 0; coeff < 20; ++coeff)
3095  {
3096  out << prefix << "rpc.samp_num_coeff_" << std::setfill('0')
3097  << std::setw(2) << coeff << ": " << p[i] << "\n";
3098  ++i;
3099  }
3100  for (coeff = 0; coeff < 20; ++coeff)
3101  {
3102  out << prefix << "rpc.samp_den_coeff_" << std::setfill('0')
3103  << std::setw(2) << coeff << ": " << p[i] << "\n";
3104  ++i;
3105  }
3106  break;
3107  }
3108 
3109  default:
3110  {
3111  out << "print_rpcs_unhandled_type: " << type << "\n";
3112  break;
3113  }
3114  }
3115  }
3116  else
3117  {
3118  out << "print_rpcs_invalid_count: " << count << "\n";
3119  }
3120  }
3121  else
3122  {
3123  out << "print_rpcs_error: null_array\n";
3124  }
3125  return out;
3126 }
3127 
3129  const std::string& prefix,
3130  ossim_uint16 code) const
3131 {
3132  // key 1024 Section 6.3.1.1 Codes
3133  out << prefix << MODEL_TYPE_KW << ": ";
3134  if (code == 1)
3135  {
3136  out << "projected\n";
3137  }
3138  else if (code == 2)
3139  {
3140  out << "geographic\n";
3141  }
3142  else if (code == 2)
3143  {
3144  out << "geocentric\n";
3145  }
3146  else
3147  {
3148  out << "unknown\n";
3149  }
3150  return out;
3151 }
3152 
3154  const std::string& prefix,
3155  ossim_uint16 code) const
3156 {
3157  // key 1025 Section 6.3.1.2 Codes
3158  out << prefix << RASTER_TYPE_KW << ": ";
3159  if (code == 1)
3160  {
3161  out << "pixel_is_area\n";
3162  }
3163  else if (code == 2)
3164  {
3165  out << "pixel_is_point\n";
3166  }
3167  else
3168  {
3169  out << "unknown\n";
3170  }
3171  return out;
3172 }
3173 
3175  const std::string& prefix,
3176  ossim_uint16 code) const
3177 {
3178  // key 2054 Section 6.3.1.4 Codes
3179  out << prefix << ANGULAR_UNITS_KW << ": ";
3180  switch (code)
3181  {
3182  case 9101:
3183  {
3184  out << "radians\n";
3185  break;
3186  }
3187  case 9102:
3188  {
3189  out << "degrees\n";
3190  break;
3191  }
3192  case 9103:
3193  {
3194  out << "arc_minutes\n";
3195  break;
3196  }
3197  case 9104:
3198  {
3199  out << "arc_seconds\n";
3200  break;
3201  }
3202  case 9105:
3203  {
3204  out << "grad\n";
3205  break;
3206  }
3207  case 9106:
3208  {
3209  out << "gon\n";
3210  break;
3211  }
3212  case 9107:
3213  {
3214  out << "dms\n";
3215  break;
3216  }
3217  case 9108:
3218  {
3219  out << "dms_hemisphere\n";
3220  break;
3221  }
3222  default:
3223  {
3224  out << "unknown\n";
3225  break;
3226  }
3227  }
3228  return out;
3229 }
3230 
3232  const std::string& prefix,
3233  ossim_uint16 code) const
3234 {
3235  // key 3075 Section 6.3.3.3 Codes
3236  out << prefix << "coord_trans: ";
3237  switch (code)
3238  {
3239  case 1:
3240  {
3241  out << "TransverseMercator\n";
3242  break;
3243  }
3244  case 2:
3245  {
3246  out << "TransvMercator_Modified_Alaska\n";
3247  break;
3248  }
3249  case 3:
3250  {
3251  out << "ObliqueMercator\n";
3252  break;
3253  }
3254  case 4:
3255  {
3256  out << "ObliqueMercator_Laborde\n";
3257  break;
3258  }
3259  case 5:
3260  {
3261  out << "ObliqueMercator_Rosenmund\n";
3262  break;
3263  }
3264  case 6:
3265  {
3266  out << "ObliqueMercator_Spherical\n";
3267  break;
3268  }
3269  case 7:
3270  {
3271  out << "Mercator\n";
3272  break;
3273  }
3274  case 8:
3275  {
3276  out << "LambertConfConic_2SP\n";
3277  break;
3278  }
3279  case 9:
3280  {
3281  out << "LambertConfConic_Helmert\n";
3282  break;
3283  }
3284  case 10:
3285  {
3286  out << "LambertAzimEqualArea\n";
3287  break;
3288  }
3289  case 11:
3290  {
3291  out << "AlbersEqualArea\n";
3292  break;
3293  }
3294  case 12:
3295  {
3296  out << "AzimuthalEquidistant\n";
3297  break;
3298  }
3299  case 13:
3300  {
3301  out << "EquidistantConic\n";
3302  break;
3303  }
3304  case 14:
3305  {
3306  out << "Stereographic\n";
3307  break;
3308  }
3309  case 15:
3310  {
3311  out << "PolarStereographic\n";
3312  break;
3313  }
3314  case 16:
3315  {
3316  out << "ObliqueStereographic\n";
3317  break;
3318  }
3319  case 17:
3320  {
3321  out << "Equirectangular\n";
3322  break;
3323  }
3324  case 18:
3325  {
3326  out << "CassiniSoldner\n";
3327  break;
3328  }
3329  case 19:
3330  {
3331  out << "Gnomonic\n";
3332  break;
3333  }
3334  case 20:
3335  {
3336  out << "MillerCylindrical\n";
3337  break;
3338  }
3339  case 21:
3340  {
3341  out << "Orthographic\n";
3342  break;
3343  }
3344  case 22:
3345  {
3346  out << "Polyconic\n";
3347  break;
3348  }
3349  case 23:
3350  {
3351  out << "Robinson\n";
3352  break;
3353  }
3354  case 24:
3355  {
3356  out << "Sinusoidal\n";
3357  break;
3358  }
3359  case 25:
3360  {
3361  out << "VanDerGrinten\n";
3362  break;
3363  }
3364  case 26:
3365  {
3366  out << "NewZealandMapGrid\n";
3367  break;
3368  }
3369  case 27:
3370  {
3371  out << "TransvMercator_SouthOriented\n";
3372  break;
3373  }
3374  default:
3375  {
3376  out << code << " unknown\n";
3377  break;
3378  }
3379  }
3380  return out;
3381 }
3382 
3384  const std::string& prefix,
3385  const std::string& key,
3386  ossim_uint16 code) const
3387 {
3388  // key 3076 Section 6.3.1.3 Codes
3389  out << prefix << key << ": ";
3390  switch (code)
3391  {
3392  case 9001:
3393  {
3394  out << "meters\n";
3395  break;
3396  }
3397  case 9002:
3398  {
3399  out << "feet\n";
3400  break;
3401  }
3402  case 9003:
3403  {
3404  out << "us_survey_feet\n";
3405  break;
3406  }
3407  case 9004:
3408  {
3409  out << "foot_modified_american\n";
3410  break;
3411  }
3412  case 9005:
3413  {
3414  out << "foot_clarke\n";
3415  break;
3416  }
3417  case 9006:
3418  {
3419  out << "foot_indian\n";
3420  break;
3421  }
3422  case 9007:
3423  {
3424  out << "link\n";
3425  break;
3426  }
3427  case 9008:
3428  {
3429  out << "link_benoit\n";
3430  break;
3431  }
3432  case 9009:
3433  {
3434  out << "link_sears\n";
3435  break;
3436  }
3437  case 9010:
3438  {
3439  out << "chain_benoit\n";
3440  break;
3441  }
3442  case 9011:
3443  {
3444  out << "chain_sears\n";
3445  break;
3446  }
3447  case 9012:
3448  {
3449  out << "yard_sears\n";
3450  break;
3451  }
3452  case 9013:
3453  {
3454  out << "yard_indian\n";
3455  break;
3456  }
3457  case 9014:
3458  {
3459  out << "fathom\n";
3460  break;
3461  }
3462  case 9015:
3463  {
3464  out << "mile_international_nautical\n";
3465  break;
3466  }
3467  default:
3468  {
3469  out << code << " unknown\n";
3470  break;
3471  }
3472  }
3473  return out;
3474 }
3475 
3477  const std::string& prefix,
3478  ossim_uint16 code) const
3479 {
3480  // Tag 274:
3481  out << prefix << "orientation: ";
3482  switch (code)
3483  {
3484  case 1:
3485  {
3486  out << "top_left\n";
3487  break;
3488  }
3489  case 2:
3490  {
3491  out << "top_right\n";
3492  break;
3493  }
3494  case 3:
3495  {
3496  out << "bottom_right\n";
3497  break;
3498  }
3499  case 4:
3500  {
3501  out << "bottom_left\n";
3502  break;
3503  }
3504  case 5:
3505  {
3506  out << "left_top\n";
3507  break;
3508  }
3509  case 6:
3510  {
3511  out << "right_top\n";
3512  break;
3513  }
3514  case 7:
3515  {
3516  out << "right_bottom\n";
3517  break;
3518  }
3519  case 8:
3520  {
3521  out << "left_bottom\n";
3522  break;
3523  }
3524  default:
3525  {
3526  out << code << " unknown\n";
3527  break;
3528  }
3529  }
3530  return out;
3531 }
3532 
3534  std::string& prefix) const
3535 {
3536  prefix += "image";
3538  s << index;
3539  prefix += s.str();
3540  prefix += ".";
3541 }
3542 
3544  const ossimKeywordlist& gtiffKwl,
3545  ossimDpt& scale) const
3546 {
3547  bool result = false;
3548 
3549  std::vector<ossim_float64> floats;
3550  if ( getFloats(gtiffPrefix, MODEL_PIXEL_SCALE_KW, gtiffKwl, floats) )
3551  {
3552  if ( floats.size() == 3 )
3553  {
3554  scale.x = floats[0];
3555  scale.y = floats[1];
3556  result = true;
3557  }
3558  }
3559 
3560  return result;
3561 }
3562 
3563 bool ossimTiffInfo::getTiePoint(const ossimString& gtiffPrefix,
3564  const ossimKeywordlist& gtiffKwl,
3565  std::vector<ossim_float64>& ties) const
3566 {
3567  return getFloats(gtiffPrefix, MODEL_TIE_POINT_KW, gtiffKwl, ties);
3568 }
3569 
3571  const ossimKeywordlist& gtiffKwl,
3572  std::vector<ossim_float64>& xfrm) const
3573 {
3574  return getFloats(gtiffPrefix, MODEL_TRANSFORM_KW, gtiffKwl, xfrm);
3575 }
3576 
3577 bool ossimTiffInfo::getFloats(const ossimString& gtiffPrefix,
3578  const ossimString& key,
3579  const ossimKeywordlist& gtiffKwl,
3580  std::vector<ossim_float64>& floats) const
3581 {
3582  bool result = false;
3583 
3584  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), key.c_str());
3585  if ( lookup )
3586  {
3587  ossimString line = lookup;
3588  result = getFloats(line, floats);
3589  }
3590 
3591  return result;
3592 }
3593 
3595  std::vector<ossim_float64>& floats) const
3596 {
3597  bool result = false;
3598 
3599  floats.clear();
3600 
3601  if (line.size())
3602  {
3603  ossim_float64 f;
3604  std::istringstream is(line);
3605 
3606  is >> f; // Get the first double.
3607  while ( ! is.fail() )
3608  {
3609  floats.push_back(f);
3610  is >> f;
3611  }
3612  }
3613 
3614  if ( floats.size() )
3615  {
3616  result = true;
3617  }
3618 
3619  return result;
3620 }
3621 
3623  const ossimKeywordlist& gtiffKwl,
3624  ossimString& datumCode) const
3625 {
3626  bool result = false;
3627 
3628  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), GEODETIC_DATUM_KW.c_str());
3629 
3630  // There is some ambiguity in the definition of EPSG GCS code. Here both the datum code (6000-
3631  // series) and projection code (4000-series) are tested to get to the datum's native ascii code:
3632 
3633  // Look for GEODETIC_DATUM_KW code first:
3634  if (lookup)
3635  {
3636  ossim_int32 code = ossimString(lookup).toInt32();
3637  result = getDatumCode( code, datumCode );
3638  }
3639 
3640  if ( !result )
3641  {
3642  // Try GCS_CODE_KW:
3643  lookup = gtiffKwl.find(gtiffPrefix.c_str(), ossimKeywordNames::GCS_CODE_KW);
3644  if ( lookup )
3645  {
3646  ossim_int32 code = ossimString(lookup).toInt32();
3647  result = getDatumCode( code, datumCode );
3648  }
3649  }
3650  return result;
3651 }
3652 
3654 {
3655  bool result = false;
3656  datumCode.clear();
3657  switch(code)
3658  {
3659  case 4267:
3660  case 6267:
3661  {
3662  datumCode = "NAS-C";
3663  break;
3664  }
3665  case 4269:
3666  case 6269:
3667  {
3668  datumCode = "NAR-C";
3669  break;
3670  }
3671  case 4322:
3672  case 6322:
3673  {
3674  datumCode = "WGD";
3675  break;
3676  }
3677  case 4326:
3678  case 6326:
3679  {
3680  datumCode = "WGE";
3681  break;
3682  }
3683 
3684  } // matches: switch(code)
3685 
3686  if ( datumCode.size() )
3687  {
3688  result = true;
3689  }
3690  return result;
3691 }
3692 
3693 bool ossimTiffInfo::getPcsCode(const ossimString& gtiffPrefix,
3694  const ossimKeywordlist& gtiffKwl,
3695  ossimString& pcsCode) const
3696 {
3697  bool result = false;
3698 
3699  // Check for key "pcs_code":
3700  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), ossimKeywordNames::PCS_CODE_KW);
3701  if (lookup)
3702  {
3703  pcsCode = lookup;
3704 
3705  ossim_uint32 code = pcsCode.toUInt32();
3706  if ( code != 32767 )
3707  {
3708  // See if we handle this code in our projection factories.
3711  if (proj.valid())
3712  {
3713  proj = 0;
3714  result = true;
3715  }
3716  }
3717 
3718  }
3719 
3720  if (result == false)
3721  {
3722  // Check for key "pcs_citation":
3723  lookup = gtiffKwl.find(gtiffPrefix.c_str(), "pcs_citation");
3724  if ( lookup )
3725  {
3726  ossimString spec = lookup;
3727 
3728  // Strip commonly found or bar '|' from end if present.
3729  spec.trim(ossimString("|"));
3730 
3731  // See if we handle this code in our projection factories.
3734  if (proj.valid())
3735  {
3736  ossimMapProjection* mapProj = dynamic_cast<ossimMapProjection*>(proj.get());
3737  if ( mapProj )
3738  {
3739  ossim_uint32 intCode = mapProj->getPcsCode();
3740  if ( intCode != 32767 )
3741  {
3742  proj = 0;
3743  pcsCode = ossimString::toString(intCode);
3744  result = true;
3745  }
3746  }
3747  }
3748  }
3749  }
3750 
3751  return result;
3752 }
3753 
3754 bool ossimTiffInfo::getUnits(const ossimString& gtiffPrefix,
3755  const ossimKeywordlist& gtiffKwl,
3756  ossimString& units) const
3757 {
3758  bool result = true;
3759 
3760  ossimString linearUnits = "";
3761  getLinearUnits(gtiffPrefix, gtiffKwl, linearUnits);
3762 
3763  ossimString angularUnits = "";
3764  getAngularUnits(gtiffPrefix, gtiffKwl, angularUnits);
3765 
3766  ossimString modelType;
3767  getModelType(gtiffPrefix, gtiffKwl, modelType);
3768 
3769  if (modelType == "geographic")
3770  {
3771  if (angularUnits.size())
3772  {
3773  units = angularUnits;
3774  }
3775  else
3776  {
3777  units = "degrees";
3778  }
3779  }
3780  else if (modelType == "projected")
3781  {
3782  if (linearUnits.size())
3783  {
3784  units = linearUnits;
3785  }
3786  else
3787  {
3788  units = "meters";
3789  }
3790  }
3791  else
3792  {
3793  units = "meters";
3794  }
3795 
3796  return result;
3797 }
3798 
3799 
3801  const ossimKeywordlist& gtiffKwl,
3802  ossimString& linearUnits) const
3803 {
3804  bool result = false;
3805  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), LINEAR_UNITS_KW.c_str());
3806  if (lookup)
3807  {
3808  linearUnits = lookup;
3809  result = true;
3810  }
3811  return result;
3812 }
3813 
3815  const ossimKeywordlist& gtiffKwl,
3816  ossimString& verticalUnits) const
3817 {
3818  bool result = false;
3819  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), VERTICAL_UNITS_KW.c_str());
3820  if (lookup)
3821  {
3822  verticalUnits = lookup;
3823  result = true;
3824  }
3825  return result;
3826 }
3827 
3829  const ossimKeywordlist& gtiffKwl,
3830  ossimString& angularUnits) const
3831 {
3832  bool result = false;
3833  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), ANGULAR_UNITS_KW.c_str());
3834  if (lookup)
3835  {
3836  angularUnits = lookup;
3837  result = true;
3838  }
3839  return result;
3840 }
3841 
3843  const ossimKeywordlist& gtiffKwl,
3844  ossimString& pixelType) const
3845 {
3846  bool result = false;
3847  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), RASTER_TYPE_KW.c_str());
3848  if (lookup)
3849  {
3850  pixelType = lookup;
3851  result = true;
3852  }
3853  return result;
3854 }
3855 
3857  const ossimKeywordlist& gtiffKwl,
3858  ossimString& modelType) const
3859 {
3860  bool result = false;
3861  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), MODEL_TYPE_KW.c_str());
3862  if (lookup)
3863  {
3864  modelType = lookup;
3865  result = true;
3866  }
3867  return result;
3868 }
3869 
3871  const ossimKeywordlist& gtiffKwl,
3872  ossimString& ossimProj) const
3873 {
3874  bool result = false;
3875  ossimProj.clear();
3876  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), COORD_TRANS_CODE_KW.c_str());
3877  if (lookup)
3878  {
3879  ossim_uint32 code = ossimString(lookup).toUInt32();
3880 
3882 
3883  ossimProj = lut.getEntryString(code);
3884 
3885  if (ossimProj.size())
3886  {
3887  result = true;
3888  }
3889  }
3890  return result;
3891 }
3892 
3894  const ossimKeywordlist& gtiffKwl) const
3895 {
3896  ossim_uint32 result = 0;
3897  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), IMAGE_LENGTH_KW.c_str());
3898  if (lookup)
3899  {
3900  result = ossimString(lookup).toUInt32();
3901  }
3902  return result;
3903 }
3904 
3906  const ossimKeywordlist& gtiffKwl) const
3907 {
3908  ossim_uint32 result = 0;
3909  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), IMAGE_WIDTH_KW.c_str());
3910  if (lookup)
3911  {
3912  result = ossimString(lookup).toUInt32();
3913  }
3914  return result;
3915 }
3916 
3918  const ossimKeywordlist& gtiffKwl,
3919  ossimString& value) const
3920 {
3921  bool result = false;
3922  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), ossimKeywordNames::STD_PARALLEL_1_KW);
3923  if (lookup)
3924  {
3925  value = lookup;
3926  result = true;
3927  }
3928  return result;
3929 }
3930 
3932  const ossimKeywordlist& gtiffKwl,
3933  ossimString& value) const
3934 {
3935  bool result = false;
3936  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), ossimKeywordNames::STD_PARALLEL_2_KW);
3937  if (lookup)
3938  {
3939  value = lookup;
3940  result = true;
3941  }
3942  return result;
3943 }
3944 
3946  const ossimKeywordlist& gtiffKwl,
3947  ossimString& value) const
3948 {
3949  bool result = false;
3950  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), ossimKeywordNames::FALSE_EASTING_KW);
3951  if (lookup)
3952  {
3953  value = lookup;
3954  result = true;
3955  }
3956  return result;
3957 }
3958 
3960  const ossimKeywordlist& gtiffKwl,
3961  ossimString& value) const
3962 {
3963  bool result = false;
3964  const char* lookup = gtiffKwl.find(gtiffPrefix.c_str(), ossimKeywordNames::FALSE_NORTHING_KW);
3965  if (lookup)
3966  {
3967  value = lookup;
3968  result = true;
3969  }
3970  return result;
3971 }
3972 
3974  const ossimKeywordlist& gtiffKwl,
3975  ossimDpt& eastingNorthing) const
3976 {
3977  bool result = false;
3978  ossimString value;
3979  if ( getFalseEasting(gtiffPrefix, gtiffKwl, value) )
3980  {
3981  eastingNorthing.x = value.toFloat64();
3982 
3983  if ( getFalseNorthing(gtiffPrefix, gtiffKwl, value) )
3984  {
3985  eastingNorthing.y = value.toFloat64();
3986  result = true;
3987  }
3988  }
3989  return result;
3990 }
3991 
3993  const ossimKeywordlist& gtiffKwl,
3994  ossim_float64& value) const
3995 {
3996  bool result = false;
3997 
3998  const char* lookup =
3999  gtiffKwl.find(gtiffPrefix.c_str(), ossimKeywordNames::SCALE_FACTOR_KW);
4000 
4001  if (lookup)
4002  {
4003  value = ossimString(lookup).toFloat64();
4004  result = true;
4005  }
4006 
4007  return result;
4008 }
4009 
4011  const ossimKeywordlist& gtiffKwl,
4012  ossim_float64& value) const
4013 {
4014  bool result = false;
4015 
4016  //---
4017  // Not sure of the order of precedence here.
4018  //---
4019  const char* projOriginLatGeoKey =
4020  gtiffKwl.find(gtiffPrefix.c_str(), ORIGIN_LATITUDE_KW.c_str());
4021 
4022  //---
4023  // Go for this key first as it is used in geotiff spec example:
4024  // http://www.remotesensing.org/geotiff/spec/geotiff3.html#3.1.3.
4025  //---
4026  if (projOriginLatGeoKey)
4027  {
4028  value = ossimString(projOriginLatGeoKey).toFloat64();
4029  result = true;
4030  }
4031  else
4032  {
4033  const char* projCenterLatGeoKey =
4034  gtiffKwl.find(gtiffPrefix.c_str(), CENTER_LATITUDE__KW.c_str());
4035 
4036  if (projCenterLatGeoKey)
4037  {
4038  value = ossimString(projCenterLatGeoKey).toFloat64();
4039  result = true;
4040  }
4041  else
4042  {
4043  const char* projFalseOriginLatGeoKey =
4044  gtiffKwl.find(gtiffPrefix.c_str(),
4045  FALSE_ORIGIN_LATITUDE_KW.c_str());
4046 
4047  if (projFalseOriginLatGeoKey)
4048  {
4049  //---
4050  // Seems the term "false" implies it should be added to the real
4051  // origin?
4052  //---
4053  value = ossimString(projFalseOriginLatGeoKey).toFloat64();
4054  result = true;
4055  }
4056  }
4057  }
4058 
4059  return result;
4060 }
4061 
4063  const ossimKeywordlist& gtiffKwl,
4064  ossim_float64& value) const
4065 {
4066  bool result = false;
4067 
4068  //---
4069  // Not sure of the order of precedence here.
4070  //---
4071  const char* projCenterLongGeoKey =
4072  gtiffKwl.find(gtiffPrefix.c_str(), CENTER_LONGITUDE_KW.c_str());
4073 
4074  //---
4075  // Go for this key first as it is used in geotiff spec example:
4076  // http://www.remotesensing.org/geotiff/spec/geotiff3.html#3.1.3.
4077  //---
4078  if (projCenterLongGeoKey)
4079  {
4080  value = ossimString(projCenterLongGeoKey).toFloat64();
4081  result = true;
4082  }
4083  else
4084  {
4085  const char* projOriginLongGeoKey =
4086  gtiffKwl.find(gtiffPrefix.c_str(), ORIGIN_LONGITUDE_KW.c_str());
4087 
4088  if (projOriginLongGeoKey)
4089  {
4090  value = ossimString(projOriginLongGeoKey).toFloat64();
4091  result = true;
4092  }
4093  else
4094  {
4095  const char* projFalseOriginLongGeoKey =
4096  gtiffKwl.find(gtiffPrefix.c_str(),
4097  FALSE_ORIGIN_LONGITUDE_KW.c_str());
4098 
4099  if (projFalseOriginLongGeoKey)
4100  {
4101  //---
4102  // Seems the term "false" implies it should be added to the real
4103  // origin?
4104  //---
4105  value = ossimString(projFalseOriginLongGeoKey).toFloat64();
4106  result = true;
4107  }
4108  }
4109  }
4110 
4111  return result;
4112 }
4113 
4114 void ossimTiffInfo::getTieSets(const std::vector<ossim_float64>& ties,
4115  ossim_uint32 width,
4116  ossim_uint32 height,
4117  ossimTieGptSet& tieSet) const
4118 {
4119  ossim_uint32 idx = 0;
4120  ossim_uint32 tieCount = (ossim_uint32)ties.size()/6;
4121  const double* tiePointsPtr = &ties.front();
4122  double offset = 0;
4123  if (hasOneBasedTiePoints(ties, width, height))
4124  {
4125  offset = -1.0;
4126  }
4127 
4128  for(idx = 0; idx < tieCount; ++idx)
4129  {
4130  ossimDpt xyPixel(tiePointsPtr[0]+offset, tiePointsPtr[1]+offset);
4131  // tie[3] = x, tie[4]
4132  ossimGpt gpt(tiePointsPtr[4], tiePointsPtr[3], tiePointsPtr[5]);
4133 
4134  tieSet.addTiePoint(new ossimTieGpt(gpt, xyPixel, .5));
4135  tiePointsPtr+=6;
4136  }
4137 }
4138 
4140  const std::vector<ossim_float64>& ties,
4141  ossim_uint32 width, ossim_uint32 height) const
4142 {
4143  bool result = false;
4144 
4145  // Assuming ties of (x,y,z,lat,lon,hgt) so size should be divide by 3.
4146  if (ties.size()%6)
4147  {
4148  return result;
4149  }
4150 
4151  ossim_float64 minX = 999999.0;
4152  ossim_float64 minY = 999999.0;
4153  ossim_float64 maxX = 0.0;
4154  ossim_float64 maxY = 0.0;
4155 
4156  const ossim_uint32 SIZE = (ossim_uint32)ties.size();
4157  ossim_uint32 tieIndex = 0;
4158 
4159  while (tieIndex < SIZE)
4160  {
4161  if ( ties[tieIndex] < minX ) minX = ties[tieIndex];
4162  if ( ties[tieIndex] > maxX ) maxX = ties[tieIndex];
4163  if ( ties[tieIndex+1] < minY ) minY = ties[tieIndex+1];
4164  if ( ties[tieIndex+1] > maxY ) maxY = ties[tieIndex+1];
4165  tieIndex += 6;
4166  }
4167 
4168  if ( (minX == 1) && (maxX == width) &&
4169  (minY == 1) && (maxY == height) )
4170  {
4171  result = true;
4172  }
4173 
4174 #if 0
4175  if (traceDebug())
4176  {
4178  << "ossimGeoTiff::hasOneBasedTiePoints DEBUG:"
4179  << "\nminX: " << minX
4180  << "\nmaxX: " << maxX
4181  << "\nminY: " << minY
4182  << "\nmaxY: " << maxY
4183  << "\ntheWidth: " << theWidth
4184  << "\ntheLength: " << theLength
4185  << "\none based: " << (result?"true":"false")
4186  << std::endl;
4187  }
4188 #endif
4189 
4190  return result;
4191 }
bool getTiePoint(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, std::vector< ossim_float64 > &ties) const
Gets the model_tie_point array.
void swapFourBytes(void *data, ossim_uint32 size) const
Definition: ossimEndian.h:247
std::ostream & printRpcs(std::ostream &out, const std::string &prefix, ossim_uint16 type, ossim_uint64 count, ossim_uint8 *valueArray) const
Prints tag 50844.
void clear()
Erases the entire container.
Definition: ossimString.h:432
void swapTwoBytes(void *data, ossim_uint32 size) const
Definition: ossimEndian.h:238
char ossim_int8
Previous DLL import export section.
bool getFloats(const ossimString &gtiffPrefix, const ossimString &key, const ossimKeywordlist &gtiffKwl, std::vector< ossim_float64 > &floats) const
Extracts float values from keyword list that match key.
virtual ~ossimTiffInfo()
virtual destructor
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
void swapEightBytes(void *data, ossim_uint32 size) const
Definition: ossimEndian.h:260
static const char * DATUM_KW
std::ostream & printAngularUnits(std::ostream &out, const std::string &prefix, ossim_uint16 code) const
Prints key 2054.
static const char * FALSE_EASTING_NORTHING_UNITS_KW
static const char * CENTRAL_MERIDIAN_KW
std::ostream & printGdalMetadata(std::ostream &out, const std::string &prefix, ossim_uint64 count, ossim_uint8 *valueArray) const
bool getPixelType(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &pixelType) const
Gets the pixel type (point or area) from keyword list as a string.
Represents serializable keyword/value map.
bool valid() const
Definition: ossimRefPtr.h:75
bool getOffset(std::streamoff &offset, std::istream &str, ossim_uint16 version) const
This will read either 4 or 8 bytes depending on the version and initialize offset.
const char * find(const char *key) const
bool read(std::istream &in)
virtual ossim_uint32 getPcsCode() const
Returns the EPSG PCS code or 32767 if the projection is a custom (non-EPSG) projection.
float ossim_float32
virtual ossimString getEntryString(ossim_int32 entry_number) const
const ossimXmlNode::ChildListType & getChildNodes() const
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
static const char * IMAGE_MODEL_TRANSFORM_MATRIX_KW
double y
Definition: ossimDpt.h:165
bool contains(char aChar) const
Definition: ossimString.h:58
bool getImageGeometry(ossimKeywordlist &geomKwl, ossim_uint32 entryIndex) const
Extracts geometry info to keyword list.
static ossimString toString(bool aValue)
Numeric to string methods.
static const char * NUMBER_LINES_KW
bool getAngularUnits(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &units) const
Gets the units from keyword list as a string.
ossim_uint16 getTypeByteSize(ossim_uint16 type) const
void readLongLong(ossim_uint64 &l, std::istream &str) const
Initializes l reference.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
double acosd(double x)
Definition: ossimCommon.h:264
OSSIM_DLL ossimByteOrder byteOrder()
Definition: ossimCommon.cpp:54
std::string m_connectionString
ossim_uint32 toUInt32() const
std::shared_ptr< ossim::istream > m_inputStream
static StreamFactoryRegistry * instance()
bool getStdParallelTwo(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &value) const
Gets the second standard parallel from keyword list.
unsigned short ossim_uint16
bool getFalseEasting(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &value) const
Gets the false easting from keyword list.
void readLong(ossim_uint32 &l, std::istream &str) const
Initializes l reference.
static const char * TYPE_KW
bool getPixelScale(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimDpt &scale) const
Gets the required pixel scale from keyword list looking for the key model_pixel_scale.
virtual double optimizeFit(const ossimTieGptSet &tieSet, double *targetVariance=0)
static const char * GCS_CODE_KW
void readShort(ossim_uint16 &s, std::istream &str) const
Initializes s reference.
std::vector< ossimRefPtr< ossimXmlNode > > ChildListType
Definition: ossimXmlNode.h:30
void eatValue(std::istream &str, ossim_uint16 version) const
Eats the value field.
ossim_int32 toInt32() const
static const char * PIXEL_SCALE_XY_KW
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
ossim_uint64 getArraySizeInBytes(ossim_uint64 length, ossim_uint16 type) const
virtual bool open(const ossimFilename &file)
open method.
std::ostream & printModelType(std::ostream &out, const std::string &prefix, ossim_uint16 code) const
Prints key 1024.
void swapBytes(ossim_uint8 *v, ossim_uint16 type, ossim_uint64 count) const
ossim_uint32 getLines(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl) const
Gets the number of lines from keyword list.
std::ostream & printXmpMetadata(std::ostream &out, const std::string &prefix, ossim_uint64 count, ossim_uint8 *valueArray) const
Prints OTIFFTAG_XMLPACKET (700)
void getArrayValue(T &v, ossim_uint8 *array, ossim_uint64 position) const
Initializes v.
bool getScaleFactor(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossim_float64 &value) const
Gets the scale factor from keyword list.
static const char * TIE_POINT_XY_KW
signed short ossim_sint16
static const char * FALSE_NORTHING_KW
std::string::size_type size() const
Definition: ossimString.h:405
bool getOssimProjectionName(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &ossimProj) const
Gets the ossimProjection from keyword list as a string.
void getDirPrefix(ossim_int32 dirIndex, std::string &prefix) const
adds imageN.
unsigned long long ossim_uint64
unsigned int ossim_uint32
Info Base.
Definition: ossimInfoBase.h:32
bool hasOneBasedTiePoints(const std::vector< ossim_float64 > &ties, ossim_uint32 width, ossim_uint32 height) const
Check tie points to see if they are zero base or one based.
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
ossimTiffInfo()
default constructor
ossim_float64 toFloat64() const
signed int ossim_sint32
std::ostream & printGeoKeys(std::ostream &out, const std::string &prefix, ossim_uint64 geoKeyLength, ossim_uint16 *geoKeyBlock, ossim_uint64 geoDoubleLength, ossim_float64 *geoDoubleBlock, ossim_uint64 geoAsciiLength, ossim_int8 *geoAsciiBlock) const
Prints geo keys to stream.
std::ostream & printLinearUnits(std::ostream &out, const std::string &prefix, const std::string &key, ossim_uint16 code) const
Prints key from code from section 6.3.1.3.
static const char * STD_PARALLEL_1_KW
static const char * FALSE_EASTING_KW
bool getFalseEastingNorthing(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimDpt &eastingNorthing) const
Gets the false easting/northing from keyword list.
ossimByteOrder
bool getPcsCode(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &pcsCode) const
Gets the pcs code from the keyword list as a string.
bool getValue(ossim_uint64 &val, std::istream &str, WordType type, ossim_uint16 version) const
This will read either 2 , 4 or 8 bytes depending on the version and WORD_TYPE.
static const char * IMAGE_MODEL_TRANSFORM_UNIT_KW
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
static const char * FALSE_EASTING_NORTHING_KW
ossimEndian * m_endian
virtual std::ostream & print(std::ostream &out) const
Print method.
storage class for tie point between ground and image based on ossimGpt
Definition: ossimTieGpt.h:24
bool getStdParallelOne(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &value) const
Gets the first standard parallel from keyword list.
bool getLinearUnits(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &linearUnits) const
Gets the linear units from keyword list as a string.
static const char * ORIGIN_LATITUDE_KW
return status
ossim_uint32 getSamples(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl) const
Gets the number of samples from keyword list.
static const char * PCS_CODE_KW
void addTiePoint(ossimRefPtr< ossimTieGpt > aTiePt)
operations
std::basic_istream< char > istream
Base class for char input streams.
Definition: ossimIosFwd.h:20
ossimString toString(ossim_uint32 precision=15) const
Definition: ossimDpt.cpp:160
std::ostream & printArray(std::ostream &out, ossim_uint16 type, ossim_uint64 count, ossim_uint8 *valueArray) const
bool getModelTransform(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, std::vector< ossim_float64 > &xfrm) const
Gets the model_transform array.
bool getDatumCode(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &datumCode) const
Gets the datum code matching code from the keyword list as a string.
storage class for a set of geographic tie points, between master and slave images ...
static const char * PIXEL_TYPE_KW
std::ostream & printCoordTrans(std::ostream &out, const std::string &prefix, ossim_uint16 code) const
Prints key 3075.
bool getOriginLat(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossim_float64 &value) const
Gets the origin of latitude from keyword list.
double x
Definition: ossimDpt.h:164
bool getVerticalUnits(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &verticalUnits) const
Gets the vertical units from keyword list as a string.
std::ostream & printRasterType(std::ostream &out, const std::string &prefix, ossim_uint16 code) const
Prints key 1025.
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
bool empty() const
Definition: ossimString.h:411
virtual ossimProjection * createProjection(const ossimFilename &filename, ossim_uint32 entryIdx) const
STUB. Not implemented.
bool getUnits(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &units) const
Gets units from keyword list as a string.
bool read(std::istream &in)
bool getCentralMeridian(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossim_float64 &value) const
Gets the central meridian from keyword list.
bool getFalseNorthing(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &value) const
Gets the false northing from keyword list.
virtual std::shared_ptr< ossim::istream > createIstream(const std::string &connectionString, const ossimKeywordlist &options=ossimKeywordlist(), std::ios_base::openmode mode=std::ios_base::in|std::ios_base::binary) const
Will try to creates an istream interface to the connectionString passed in.
void findNodes(const ossimString &xpath, std::vector< ossimRefPtr< ossimXmlNode > > &nodelist) const
Appends any matching nodes to the list supplied (should be empty):
static const char * SCALE_FACTOR_KW
std::basic_istringstream< char > istringstream
Class for char input memory streams.
Definition: ossimIosFwd.h:32
std::ostream & printOrientation(std::ostream &out, const std::string &prefix, ossim_uint16 code) const
Prints tag 274.
static const char * STD_PARALLEL_2_KW
std::ostream & printValue(std::ostream &out, ossim_uint16 type, ossim_uint8 *valueArray) const
void swap(ossim_sint8 &)
Definition: ossimEndian.h:26
bool getModelType(const ossimString &gtiffPrefix, const ossimKeywordlist &gtiffKwl, ossimString &modeType) const
Gets the model type from keyword list as a string.
static const char * NUMBER_SAMPLES_KW
unsigned char ossim_uint8
static ossimEpsgProjectionFactory * instance()
Implements singleton pattern.
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
static const char * PIXEL_SCALE_UNITS_KW
static const char * TIE_POINT_UNITS_KW
void getTieSets(const std::vector< ossim_float64 > &ties, ossim_uint32 width, ossim_uint32 height, ossimTieGptSet &tieSet) const
Split tie points into sets of six tie sets.
int ossim_int32
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91