OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimRpfToc.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: Garrett Potts
8 //
9 // Description: Rpf support class
10 //
11 //********************************************************************
12 // $Id$
13 
31 #include <ossim/base/ossimTrace.h>
32 #include <iostream>
33 #include <fstream>
34 
35 static ossimTrace traceDebug("ossimRpfToc:debug");
36 
38 {
39  return data.print(out);
40 }
41 
43  :m_tocEntryList(),
44  m_filename(),
45  m_nitfFileHeader(0),
46  m_rpfHeader(0)
47 {
48 }
49 
51 {
52  deleteAll();
53 }
54 
55 ossimErrorCode ossimRpfToc::parseFile(const ossimFilename &fileName, bool keepFileHeader)
56 {
57  static const char MODULE[] = "ossimRpfToc::parseFile";
58 
59  if(traceDebug())
60  {
61  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered....." << std::endl;
62  }
63 
65 
66  clearAll();
67 
68  nitfFile->parseFile(fileName);
69 
70  m_nitfFileHeader = nitfFile->getHeader();
71 
72  m_rpfHeader = 0; // ossimRefPtr
73 
74  if( !m_nitfFileHeader.valid() )
75  {
76  nitfFile = 0;
77 
78  if(traceDebug())
79  {
81  << MODULE << " leaving with no nitf header found....." << std::endl;
82  }
84  }
85 
87  m_nitfFileHeader->getTag(info, "RPFHDR");
88 
89  if(traceDebug() && (info.getTagName() == "RPFHDR") )
90  {
92  << MODULE << " nitf file header print\n";
94  }
95 
96  if ( !keepFileHeader )
97  {
98  // we no longer need access to the nitf header. We got what we needed.
99  m_nitfFileHeader = 0;
100  }
101  nitfFile = 0;
102 
103  m_filename = fileName;
104 
105  if(info.getTagName() == "RPFHDR")
106  {
108 
109  std::ifstream in(m_filename.c_str(), std::ios::in|std::ios::binary);
110 
111  // set the get pointer for the stream to the start
112  // of the Rpf header data
113  in.seekg(info.getTagDataOffset(), std::ios::beg);
114 
115  // now get the header data. We do not need to pass in the byte order.
116  // this is grabbed from the first byte of the stream. To see this,
117  // Look at the RpfHeader implementation.
119 
120  if(traceDebug())
121  {
123  << MODULE << " DEBUG: Found RPF HEADER tag\n";
125  }
126 
127  }
128  else
129  {
130  if(traceDebug())
131  {
133  << "ossimRpfToc::parseFile: Leaving No RPFHDR tag found" << "\n";
134  }
136  }
137 
138  if( m_rpfHeader.valid() )
139  {
140  if(traceDebug())
141  {
142  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: Building toc list" << "\n";
143  }
145  }
146  else
147  {
148  if(traceDebug())
149  {
151  << "ossimRpfToc::parseFile: Leaving no RPFHDR " << __LINE__ << "\n";
152  }
154  }
155 
156  if(traceDebug())
157  {
159  << "ossimRpfToc::parseFile: Returning with OK." << std::endl;
160  }
161 
163 }
164 
166  const ossimFilename& outputDir )
167 {
168  static const char MODULE[] = "ossimRpfToc::createTocAndCopyFrames";
169 
170  if ( traceDebug() )
171  {
173  << MODULE << " entered..."
174  << "\ndot rpf file: " << dotRpfFile
175  << "\noutput directory: " << outputDir
176  << "\n";
177  }
178 
179  if ( outputDir.expand().exists() == false )
180  {
181  if ( !outputDir.createDirectory(true, 0775) )
182  {
183  std::string e = MODULE;
184  e += " ERROR:\nCould not create directory: ";
185  e+= outputDir.c_str();
186  throw ossimException(e);
187  }
188  }
189 
190  // Open the dot rpf file.
191  std::ifstream* dotRpfStr = new std::ifstream;
192  dotRpfStr->open(dotRpfFile.c_str(), ios_base::in);
193  if ( !dotRpfStr->good() )
194  {
195  delete dotRpfStr;
196  dotRpfStr = 0;
197 
198  std::string e = MODULE;
199  e += " ERROR:\nCould not open: ";
200  e += dotRpfFile.c_str();
201  throw ossimException(e);
202  }
203 
204  ossimFilename sourceADotTocFile = getSourceTocFile(*dotRpfStr);
205  if ( sourceADotTocFile.empty() )
206  {
207  delete dotRpfStr;
208  dotRpfStr = 0;
209 
210  std::string e = MODULE;
211  e += " ERROR:\nCould not deduce source a.toc file!";
212  throw ossimException(e);
213  }
214 
215  // Open the source a.toc file. Note the true flag is to keep the file header.
216  ossimRefPtr<ossimRpfToc> sourceADotToc = new ossimRpfToc;
217  if ( sourceADotToc->parseFile(sourceADotTocFile, true) != ossimErrorCodes::OSSIM_OK )
218  {
219  delete dotRpfStr;
220  dotRpfStr = 0;
221 
222  std::string e = MODULE;
223  e += " ERROR:\nCould not open: ";
224  e += sourceADotTocFile.c_str();
225  throw ossimException(e);
226  }
227 
228  ossimRefPtr<const ossimNitfFileHeader> sourceNitfFileHdr = sourceADotToc->getNitfFileHeader();
229  if ( !sourceNitfFileHdr.valid() )
230  {
231  delete dotRpfStr;
232  dotRpfStr = 0;
233 
234  std::string e = MODULE;
235  e += " ERROR:\nCould not get nitf file header from: ";
236  e += sourceADotTocFile.c_str();
237  throw ossimException(e);
238  }
239 
240  ossimRefPtr<const ossimRpfHeader> sourceRpfHdr = sourceADotToc->getRpfHeader();
241  if ( !sourceRpfHdr.valid() )
242  {
243  delete dotRpfStr;
244  dotRpfStr = 0;
245 
246  std::string e = MODULE;
247  e += " ERROR:\nCould not get rpf header from: ";
248  e += sourceADotTocFile.c_str();
249  throw ossimException(e);
250  }
251 
252  // Get the boundary rect sub header from the source a.toc.
253  ossimRefPtr<ossimRpfBoundaryRectSectionSubheader> boundaryRectSectionSubheader =
254  sourceRpfHdr->getNewBoundaryRectSectSubheader(sourceADotTocFile);
255  if ( !boundaryRectSectionSubheader.valid() )
256  {
257  delete dotRpfStr;
258  dotRpfStr = 0;
259 
260  std::string e = MODULE;
261  e += " ERROR:\nCould not pull boundary rect sub header from source file: ";
262  e += sourceADotTocFile.c_str();
263  throw ossimException(e);
264  }
265 
266  // Get the boundary rect table from the source a.toc.
267  ossimRefPtr<ossimRpfBoundaryRectTable> boundaryRectTable =
268  sourceRpfHdr->getNewBoundaryRectTable(sourceADotTocFile);
269  if ( !boundaryRectTable.valid() )
270  {
271  delete dotRpfStr;
272  dotRpfStr = 0;
273 
274  std::string e = MODULE;
275  e += " ERROR:\nCould not pull boundary rect table from source file: ";
276  e += sourceADotTocFile.c_str();
277  throw ossimException(e);
278  }
279 
280  // Get the frame file subheader from the source a.toc.
282  sourceRpfHdr->getNewFrameFileIndexSectionSubheader(sourceADotTocFile);
283  if ( !frameFileSubHeader.valid() )
284  {
285  delete dotRpfStr;
286  dotRpfStr = 0;
287 
288  std::string e = MODULE;
289  e += " ERROR:\nCould not pull frame file sub header from source file: ";
290  e += sourceADotTocFile.c_str();
291  throw ossimException(e);
292  }
293 
294  // Get the frame file subsection from the source a.toc.
296  sourceRpfHdr->getNewFileIndexSubsection(sourceADotTocFile);
297  if ( !frameFileSubSection.valid() )
298  {
299  delete dotRpfStr;
300  dotRpfStr = 0;
301 
302  std::string e = MODULE;
303  e += " ERROR:\nCould not pull frame file sub section from source file: ";
304  e += sourceADotTocFile.c_str();
305  throw ossimException(e);
306  }
307 
308  // Open the output file to write to.
309  const ossimFilename A_DOT_TOC_FILE = "a.toc";
310  ossimFilename dotTocFile = outputDir.dirCat(A_DOT_TOC_FILE);
311  std::ofstream* dotTocStr = new std::ofstream;
312  dotTocStr->open( dotTocFile.c_str(), ios::out|ios::binary );
313  if ( !dotTocStr->good() )
314  {
315  delete dotRpfStr;
316  dotRpfStr = 0;
317  delete dotTocStr;
318  dotTocStr =0;
319 
320  std::string e = MODULE;
321  e += " ERROR:\nCould not open: ";
322  e += dotTocFile.c_str();
323  throw ossimException(e);
324  }
325 
326  // Variables used throughout:
328  ossimString field;
329  ossimString s;
330  // std::streampos fileHeaderLength = 0;
331  // std::streampos fileLength = 0;
332 
334 
335  // Set the CLEVEL:
336  s = "01";
337  fileHdr->setComplexityLevel(s);
338 
339  // Set the OSTAID:
340  prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::OSTAID_KW);
341  fileHdr->setProperty(prop);
342 
343  // Set the FDT (date):
344  fileHdr->setDate();
345 
346  // Set the FTITLE:
347  s = "a.toc";
348  fileHdr->setTitle(s);
349 
350  // Set the FSCLAS:
351  prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::FSCLAS_KW);
352  fileHdr->setProperty(prop);
353 
354  // Set the FSCODE:
355  prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::FSCODE_KW);
356  fileHdr->setProperty(prop);
357 
358  // Set the FSCTLH:
359  prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::FSCTLH_KW);
360  fileHdr->setProperty(prop);
361 
362  // Set the ONAME:
363  prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::ONAME_KW);
364  fileHdr->setProperty(prop);
365 
366  // Set the OPHONE:
367  prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::OPHONE_KW);
368  fileHdr->setProperty(prop);
369 
370  // Add the rpf header.
371  ossimRpfHeader* rpfHdr = new ossimRpfHeader( *(sourceRpfHdr.get()) );
372 
373  ossimRefPtr<ossimNitfRegisteredTag> rpfHdrRp = rpfHdr;
374  ossimNitfTagInformation rpfHdrInfo(rpfHdrRp);
375  fileHdr->addTag(rpfHdrInfo);
376 
377  //---
378  // Write it out...
379  // The first write will be with an rpfheader with no location sections just
380  // to see where the end of the file header is.
381  //---
382  fileHdr->writeStream(*dotTocStr);
383 
384  //---
385  // End of file header. Get the header length. This will also be the
386  // start of the location section.
387  //---
388  std::streampos pos = dotTocStr->tellp();
389  std::streamoff locationSectionOffset = pos;
390 
391  // Set the header length:
392  fileHdr->setHeaderLength( static_cast<ossim_uint64>(locationSectionOffset) );
393 
394  // Set the location of the location section.
395  rpfHdr->setLocationSectionPos(locationSectionOffset);
396 
397  // Set the file name.
398  rpfHdr->setFilename(A_DOT_TOC_FILE);
399 
400  // Add the component location records to the header.
401  ossimRpfLocationSection* locSec = rpfHdr->getLocationSection();
402 
403  // Clear the records copied from the source a.toc.
404  locSec->clearFields();
405 
406  //---
407  // Set the length of the locSec to 74. The record itself is 14 bytes plus
408  // an additional 60 bytes for six location records ten bytes each.
409  //---
410  const ossim_uint16 LOCATION_SECTION_SIZE = 74;
411  locSec->setLocationSectionLength(LOCATION_SECTION_SIZE);
412 
413  // Set the offset which 14 bytes to get to the first record.
414  locSec->setLocationTableOffset(14);
415 
416  // Six records:
418 
419  // Each record 10 bytes:
420  locSec->setLocationRecordLength(10);
421 
422  // Don't know the aggregate length yet.
423 
425 
426  // Note: See ossimRpfConstants for enum ossimRpfComponentId
427 
428  const ossim_uint32 RPFHDR_SIZE = 48;
429  const ossim_uint32 LOCATION_SECTION_OFFSET = static_cast<ossim_uint32>(locationSectionOffset);
430  const ossim_uint32 BOUNDARY_SUBHEADER_SIZE = 8;
431  const ossim_uint32 BOUNDARY_RECORD_SIZE = 132;
432  const ossim_uint32 FILE_SUBHEADER_SIZE = 13;
433  // const ossim_uint32 = ;
434 
435  // Record 1 RPFHDR location:
436  ossim_uint32 rpfHdrOffset = 0;
437  if ( fileHdr->getTag(rpfHdrInfo, "RPFHDR") )
438  {
439  rpfHdrOffset = rpfHdrInfo.getTagDataOffset();
440  }
441 
443  locRec.m_componentLength = RPFHDR_SIZE;
444  locRec.m_componentLocation = static_cast<ossim_uint32>(rpfHdrInfo.getTagDataOffset());
445  locSec->addComponentRecord(locRec);
446 
447  if ( traceDebug() )
448  {
449  ossimNotify(ossimNotifyLevel_DEBUG)<< "rpf hdr offset: " << rpfHdrOffset << "\n";
451  }
452 
453  // Record 2 location section:
455  locRec.m_componentLength = LOCATION_SECTION_SIZE;
456  locRec.m_componentLocation = LOCATION_SECTION_OFFSET;
457  locSec->addComponentRecord(locRec);
458 
459  if ( traceDebug() )
460  {
462  }
463 
464  // Record 3 boundary rect sub header section:
466  locRec.m_componentLength = BOUNDARY_SUBHEADER_SIZE;
467  locRec.m_componentLocation = locRec.m_componentLocation + LOCATION_SECTION_SIZE;
468  locSec->addComponentRecord(locRec);
469 
470  if ( traceDebug() )
471  {
473  }
474 
475  // Capture the location.
476  std::streamoff boundaryRectPosition = locRec.m_componentLocation;
477 
478  // Record 4 boundary rect table:
480  locRec.m_componentLength = BOUNDARY_RECORD_SIZE;
481  locRec.m_componentLocation = locRec.m_componentLocation + BOUNDARY_SUBHEADER_SIZE;
482  locSec->addComponentRecord(locRec);
483 
484  if ( traceDebug() )
485  {
487  }
488 
489  // Record 5 file index sub header:
491  locRec.m_componentLength = FILE_SUBHEADER_SIZE;
492  locRec.m_componentLocation = locRec.m_componentLocation + BOUNDARY_RECORD_SIZE;
493  locSec->addComponentRecord(locRec);
494 
495  if ( traceDebug() )
496  {
498  }
499 
500  // Record 6 file index sub header:
502  locRec.m_componentLength = 0; // need to calculate.
503  locRec.m_componentLocation = locRec.m_componentLocation + FILE_SUBHEADER_SIZE;
504  locSec->addComponentRecord(locRec);
505 
506  if ( traceDebug() )
507  {
509  }
510 
511  // Seek back and re-write...
512  dotTocStr->seekp(0, ios::beg);
513  fileHdr->writeStream(*dotTocStr);
514 
515  dotTocStr->seekp(boundaryRectPosition, ios::beg);
516 
517  // Only writing one entry:
518  boundaryRectSectionSubheader->setNumberOfEntries(1);
519 
520  if ( traceDebug() )
521  {
523  << "writing boundaryRectSectionSubheader:\n" << *(boundaryRectSectionSubheader.get())
524  << "\n";
525  }
526 
527  //---
528  // Write the boundary rectangle section. This includes the subheader and subsection.
529  // These coorespond to location records 3 and 4 above.
530  //---
531  boundaryRectSectionSubheader->writeStream(*dotTocStr);
532 
533  if ( traceDebug() )
534  {
536  << "Original boundaryRectTable:\n" << *(boundaryRectTable.get()) << "\n";
537  }
538 
539  ossim_uint32 entry;
540  if ( getCorespondingEntry( frameFileSubSection.get(), *dotRpfStr, entry ) )
541  {
542  ossimRpfBoundaryRectRecord boundaryRectRecord;
543  if ( boundaryRectTable->getEntry( entry, boundaryRectRecord) )
544  {
545  if ( traceDebug() )
546  {
548  << "writing boundaryRectTable:\n" << boundaryRectRecord << "\n";
549  }
550 
551  boundaryRectRecord.writeStream(*dotTocStr);
552  }
553  else
554  {
555  std::string e = MODULE;
556  e += " ERROR:\nCould not get bounding rect record for entry: ";
557  e += ossimString::toString(entry).c_str();
558  throw ossimException(e);
559  }
560  }
561  else
562  {
563  std::string e = MODULE;
564  e += " ERROR:\nCould not deduce entry from frame list!";
565  throw ossimException(e);
566  }
567 
568  frameFileSubHeader->setNumberOfIndexRecords( getNumberOfFrames(*dotRpfStr) );
569  frameFileSubHeader->setNumberOfPathnameRecords(1);
570  const ossim_uint16 FRAME_FILE_INDEX_RECORD_LENGTH = 33;
571  frameFileSubHeader->setIndexRecordLength( FRAME_FILE_INDEX_RECORD_LENGTH );
572 
573  if ( traceDebug() )
574  {
576  << "writing frameFileSubHeader:\n" << *(frameFileSubHeader.get()) << "\n";
577  }
578  frameFileSubHeader->writeStream( *dotTocStr );
579 
580  if ( traceDebug() )
581  {
582  ossimNotify(ossimNotifyLevel_DEBUG) << "writing frameFileSubSection:\n";
583  }
584 
585  std::streamoff frameFileIndexSectionStartPos = dotTocStr->tellp();
586 
587  writeFrameFileIndexSection(frameFileSubSection.get(), *dotRpfStr, *dotTocStr);
588 
589  std::streamoff endOfFilePos = dotTocStr->tellp();
590 
591  // Update the location section length for the frame file index section.
592  locSec->getLocationRecordList()[5].m_componentLength =
593  static_cast<ossim_uint32>(endOfFilePos - frameFileIndexSectionStartPos);
594 
595  // Update the length of all location sections.
597  static_cast<ossim_uint32>(endOfFilePos) - rpfHdr->getLocationSectionLocation() );
598 
599 
600  fileHdr->setFileLength(static_cast<ossim_uint64>(endOfFilePos));
601  dotTocStr->seekp(0, ios::beg);
602  fileHdr->writeStream(*dotTocStr);
603 
604  ossimNotify(ossimNotifyLevel_DEBUG) << "Wrote file: " << dotTocFile << "\n";
605 
606  // Copy the frames to the output directory.
607  copyFrames(*dotRpfStr, outputDir);
608 
609  // Cleanup:
610  delete dotRpfStr;
611  dotRpfStr = 0;
612  delete dotTocStr;
613  dotTocStr =0;
614 }
615 
617  const std::string& prefix,
618  bool printOverviews) const
619 {
620  printHeader( out, prefix );
621 
622  //---
623  // Go through the entries... We're going to skip overviews here.
624  //---
625  for ( ossim_uint32 entryIndex = 0; entryIndex < m_tocEntryList.size(); ++entryIndex )
626  {
627  printTocEntry( out, entryIndex, prefix, printOverviews );
628  }
629 
630 
631  return out;
632 }
633 
635  const std::string& prefix ) const
636 {
637  if( m_rpfHeader.valid() )
638  {
639  m_rpfHeader->print(out, prefix);
640  }
641  return out;
642 }
643 
645  ossim_uint32 entryIndex,
646  const std::string& prefix,
647  bool printOverviews ) const
648 {
649  const ossimRpfTocEntry* tocEntry = getTocEntry( entryIndex );
650  if ( tocEntry )
651  {
652  if ( traceDebug() )
653  {
654  tocEntry->print(out, prefix);
655  }
656 
657  const ossimRpfBoundaryRectRecord REC = tocEntry->getBoundaryInformation();
658 
659  ossimString scale = REC.getScale();
660  if ( (scale.contains("OVERVIEW") == false) || printOverviews )
661  {
662  ossimString entryPrefix = prefix;
663  entryPrefix += "image";
664  entryPrefix += ossimString::toString(entryIndex);
665  entryPrefix += ".";
666  REC.print(out, entryPrefix);
667 
668  //---
669  // Get the first frame that exists so we can get to
670  // the attributes.
671  //---
672  ossimRpfFrameEntry frameEntry;
673  getFirstEntry( tocEntry, frameEntry);
674 
675  if (frameEntry.exists())
676  {
677  ossimRpfFrame rpfFrame;
678  if ( rpfFrame.parseFile(frameEntry.getFullPath())
680  {
681  rpfFrame.print(out, entryPrefix);
682  }
683  }
684  }
685  }
686  return out;
687 }
688 
690 {
691  return static_cast<ossim_uint32>(m_tocEntryList.size());
692 }
693 
695 {
696  if(index < m_tocEntryList.size())
697  {
698  return m_tocEntryList[index];
699  }
700  return 0;
701 }
702 
704 
705 {
706  for(ossim_int32 i = 0; i < (ossim_int32)m_tocEntryList.size(); ++i)
707  {
708  if(m_tocEntryList[i] == entry)
709  {
710  return i;
711  }
712  }
713 
714  return -1;
715 }
716 
718 {
719  return m_nitfFileHeader.get();
720 }
721 
723 {
724  return m_rpfHeader.get();
725 }
726 
728 {
729  ossim_uint32 nFrames = 0;
730  const ossimRpfTocEntry* pEntry = getTocEntry( idx );
731  if ( pEntry != NULL )
732  {
733  nFrames = pEntry->getNumberOfFramesHorizontal();
734  }
735  return nFrames;
736 }
737 
739 {
740  ossim_uint32 nFrames = 0;
741  const ossimRpfTocEntry* pEntry = getTocEntry( idx );
742  if ( pEntry != NULL )
743  {
744  nFrames = pEntry->getNumberOfFramesVertical();
745  }
746  return nFrames;
747 }
748 
750  ossim_uint32 row,
751  ossim_uint32 col,
752  ossimRpfFrameEntry& result)const
753 {
754  const ossimRpfTocEntry* pEntry = getTocEntry( entryIdx );
755  if ( pEntry != NULL )
756  {
757  return pEntry->getEntry( row, col, result );
758  }
759  return false;
760 }
761 
763  ossim_uint32 row,
764  ossim_uint32 col) const
765 {
766  ossimRpfFrameEntry frameEntry;
767  bool bResult = getRpfFrameEntry( entryIdx, row, col, frameEntry );
768  if ( bResult == true )
769  {
770  return frameEntry.getPathToFrameFileFromRoot();
771  }
772  return ossimString("");
773 }
774 
776 {
777  m_rpfHeader = 0;
778 
780 }
781 
783 {
785  m_filename = "";
786 }
787 
789 {
790  std::vector< ossimRpfTocEntry*>::iterator tocEntry =
791  m_tocEntryList.begin();
792  while(tocEntry != m_tocEntryList.end())
793  {
794  if(*tocEntry)
795  {
796  delete (*tocEntry);
797  *tocEntry = NULL;
798  }
799  ++tocEntry;
800  }
801  m_tocEntryList.clear();
802 }
803 
805 {
806  if(traceDebug())
807  {
809  << "ossimRpfToc::buildTocEntryList: entered.....\n";
810  }
811  std::ifstream in(m_filename.c_str(), std::ios::in | std::ios::binary);
812 
813  if(!in)
814  {
815  if(traceDebug())
816  {
818  << "ossimRpfToc::buildTocEntryList: invalid input leaving..... " << std::endl;
819  }
820  return;
821  }
822 
823  if(rpfHeader)
824  {
825  if(traceDebug())
826  {
828  }
829 
832  rpfHeader->getNewBoundaryRectSectSubheader(in);
833 
834  if(boundaryRect)
835  {
836  if(traceDebug())
837  {
838  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: Got boundary rect\n";
839  }
840  std::streamoff current = in.tellg();
841 
842  // they give the offset from the
843  // end of the boundary subheader to the start of the
844  // entry table. We have to create an absolute
845  // offset.
846  current += boundaryRect->getTableOffset();
847 
848  // take to the start of the table entries
849  in.seekg(current, ios::beg);
850  allocateTocEntryList(boundaryRect->getNumberOfEntries());
851 
852  // now we can read the entries
853  if(m_tocEntryList.size() > 0)
854  {
855  for(ossim_uint32 index = 0; index < m_tocEntryList.size(); index++)
856  {
857  m_tocEntryList[index]->parseStream(in, rpfHeader->getByteOrder());
858  }
859  }
860 
862  // get the offset to the table
863  long offsetToIndexSubsection = in.tellg();
864  if(frameFileIndexHead)
865  {
866  ossimRpfFrameFileIndexRecord tempIndexRec;
867  ossimRpfPathnameRecord tempPathNameRec;
868 
869  ossim_int32 count = frameFileIndexHead->getNumberOfIndexRecords();
870  while(count > 0)
871  {
872  tempIndexRec.parseStream(in, rpfHeader->getByteOrder() );
873 
874  // get the path information. we must seek to a different location
875  // within the file. So we must remember where we currently are at
876  std::streamoff currentPosition = in.tellg();
877 
878  in.seekg(offsetToIndexSubsection + tempIndexRec.getPathnameRecordOffset(), ios::beg);
879  tempPathNameRec.parseStream(in, rpfHeader->getByteOrder());
880 
881  // We have the root directory where all frame files are subfiles of
882 // ossimString rootDirectory(ossimFilename(m_filename.path())+
883  // ossimFilename(ossimFilename::thePathSeparator));
884  ossimFilename rootDirectory;
885  getRootDirectory(rootDirectory);
886 
887  // we have the actual path from the root directory to the
888  // frame file. We must separate the two. There have been
889  // occurrences where the path in the A.TOC file
890  // is upper case but the path in the directory on the file
891  // system is lower case. This
892  // will fool the system in thinking the file does not exist
893  // when it actually does.
894  ossimString pathToFrameFile( ossimFilename(tempPathNameRec.getPathname()) +
895  tempIndexRec.getFilename());
896 
897  ossimRpfFrameEntry entry(rootDirectory,
898  pathToFrameFile);
899  m_tocEntryList[tempIndexRec.getBoundaryRecNumber()]->setEntry(entry,
900  tempIndexRec.getLocationRowNumber(),
901  tempIndexRec.getLocationColNumber());
902  // now go back to where we were
903  in.seekg(currentPosition, ios::beg);
904 
905  --count;
906  }
907  delete frameFileIndexHead;
908  frameFileIndexHead = 0;
909  }
910  }
911  delete boundaryRect;
912  boundaryRect = NULL;
913  }
914  if(traceDebug())
915  {
917  << "ossimRpfToc::buildTocEntryList: leaving....." << std::endl;
918  }
919 }
920 
922 {
923  if(m_tocEntryList.size() > 0)
924  {
926  }
927  for(ossim_uint32 index = 0; index < numberOfEntries; index++)
928  {
929  m_tocEntryList.push_back(new ossimRpfTocEntry);
930  }
931 }
932 
934 {
935  dir = m_filename.expand().path();
936 }
937 
939  ossimRpfFrameEntry& frameEntry) const
940 {
941  if (rpfTocEntry)
942  {
943  ossim_int32 framesHorizontal =
944  rpfTocEntry->getNumberOfFramesHorizontal();
945  ossim_int32 framesVertical =
946  rpfTocEntry->getNumberOfFramesVertical();
947 
948  bool foundEntry = false;
949  for (ossim_int32 v = 0; v < framesVertical; ++v)
950  {
951  for (ossim_int32 h = 0; h < framesHorizontal; ++h)
952  {
953  rpfTocEntry->getEntry(v, h, frameEntry);
954  if (frameEntry.exists())
955  {
956  foundEntry = true;
957  break;
958  }
959  }
960  if (foundEntry)
961  {
962  break;
963  }
964  }
965  }
966 }
967 
969  std::ifstream& dotRpfStr,
970  std::ofstream& dotTocStr)
971 {
972  static const char MODULE[] = "ossimRpfToc::writeFrameFileIndexSection";
973 
974  if(traceDebug())
975  {
976  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
977  }
978 
979  const ossim_uint16 FRAME_FILE_INDEX_RECORD_LENGTH = 33;
980  ossim_uint32 frames = getNumberOfFrames(dotRpfStr);
981  ossim_uint32 pathnameRecordOffset = FRAME_FILE_INDEX_RECORD_LENGTH * frames;
982 
983  if(traceDebug())
984  {
985  ossimNotify(ossimNotifyLevel_DEBUG) << "frames: " << frames << "\n";
986  }
987 
988  if ( !dotRpfStr.good() )
989  {
990  // see if we can clear it. Someone might have hit end of file(eof).
991  dotRpfStr.clear();
992  }
993 
994  dotRpfStr.seekg(0, ios_base::beg);
995 
996  std::string line;
997  ossimFilename file;
999  ossim_uint32 framesWritten = 0;
1000 
1001  // Eat the first line which is the bounding rect line
1002  std::getline(dotRpfStr, line);
1003 
1004  while( dotRpfStr.good() )
1005  {
1006  std::getline(dotRpfStr, line);
1007 
1008  if ( dotRpfStr.good() )
1009  {
1010  if ( getFile(line, file) )
1011  {
1012  if ( frameFileSubSection->getFrameFileIndexRecordFromFile(file.file(), record) )
1013  {
1014  // Always single entry.
1015  record.setBoundaryRecNumber(0);
1016 
1017  record.setPathnameRecordOffset(pathnameRecordOffset);
1018  record.writeStream(dotTocStr);
1019  ++framesWritten;
1020 
1021  if ( traceDebug() )
1022  {
1023  ossimNotify(ossimNotifyLevel_DEBUG) << "wrote record:\n" << record << "\n";
1024  }
1025  }
1026  }
1027  }
1028  }
1029 
1030  // Now set the path record.
1031  ossimFilename d = file.path();
1032  ossimString s = "./";
1033  s += d.file();
1034  s += "/";
1035  ossimRpfPathnameRecord pathRecord;
1036  pathRecord.setPathName(s);
1037  pathRecord.writeStream(dotTocStr);
1038 
1039  if (traceDebug())
1040  {
1042  << "frames written: " << framesWritten
1043  << "\nwrote record:\n" << pathRecord
1044  << "\n";
1045  }
1046 
1047  dotRpfStr.clear();
1048  dotRpfStr.seekg(0, ios_base::beg);
1049 
1050  if(traceDebug())
1051  {
1052  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited..." << std::endl;
1053  }
1054 }
1055 
1056 void ossimRpfToc::copyFrames(std::ifstream& dotRpfStr, const ossimFilename& outputDir)
1057 {
1058  static const char MODULE[] = "ossimRpfToc::copyFrames";
1059 
1060  if(traceDebug())
1061  {
1062  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1063  }
1064 
1065  ossim_uint32 frames = getNumberOfFrames(dotRpfStr);
1066 
1067  if(traceDebug())
1068  {
1069  ossimNotify(ossimNotifyLevel_DEBUG) << "frames to copy: " << frames << "\n";
1070  }
1071 
1072  if ( !dotRpfStr.good() )
1073  {
1074  // see if we can clear it. Someone might have hit end of file(eof).
1075  dotRpfStr.clear();
1076  }
1077 
1078  dotRpfStr.seekg(0, ios_base::beg);
1079 
1080  std::string line;
1081  ossimFilename file;
1082  ossimFilename destinationFile;
1083  ossimFilename subDir;
1084  ossim_uint32 framesCopied = 0;
1085 
1086  // Eat the first line which is the bounding rect line
1087  std::getline(dotRpfStr, line);
1088 
1089  // Get the second line which is first file.
1090  std::getline(dotRpfStr, line);
1091 
1092  // Get the file name and make the sub directory if needed.
1093  if ( getFile(line, file) )
1094  {
1095  destinationFile = outputDir;
1096  subDir = file.path();
1097  subDir = subDir.file();
1098  destinationFile = destinationFile.dirCat( subDir );
1099 
1100  // This is output_dir/subdir. See if subdir exist:
1101  if ( !destinationFile.exists() )
1102  {
1103  destinationFile.createDirectory();
1104  }
1105  }
1106 
1107  // Start over:
1108  if ( !dotRpfStr.good() )
1109  {
1110  // see if we can clear it. Someone might have hit end of file(eof).
1111  dotRpfStr.clear();
1112  }
1113  dotRpfStr.seekg(0, ios_base::beg);
1114 
1115  // Eat the first line which is the bounding rect line
1116  std::getline(dotRpfStr, line);
1117 
1118  while( dotRpfStr.good() )
1119  {
1120  std::getline(dotRpfStr, line);
1121 
1122  if ( dotRpfStr.good() )
1123  {
1124  if ( getFile(line, file) )
1125  {
1126  destinationFile = outputDir;
1127  subDir = file.path();
1128  subDir = subDir.file();
1129  destinationFile = destinationFile.dirCat( subDir );
1130  destinationFile = destinationFile.dirCat( file.file() );
1131 
1132  if ( file.copyFileTo(destinationFile) )
1133  {
1134  ++framesCopied;
1135  }
1136  if ( traceDebug() )
1137  {
1138  ossimNotify(ossimNotifyLevel_DEBUG) << "Copied frame: " << destinationFile << "\n";
1139  }
1140  }
1141  }
1142  }
1143 
1144  ossimNotify(ossimNotifyLevel_NOTICE) << "Frames copied: " << framesCopied << std::endl;
1145 
1146  dotRpfStr.clear();
1147  dotRpfStr.seekg(0, ios_base::beg);
1148 
1149  if(traceDebug())
1150  {
1151  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited..." << std::endl;
1152  }
1153 }
1154 
1156 {
1157  ossim_uint32 result = 0;
1158 
1159  if ( !dotRpfStr.good() )
1160  {
1161  // see if we can clear it. Someone might have hit end of file(eof).
1162  dotRpfStr.clear();
1163  }
1164 
1165  dotRpfStr.seekg(0, ios_base::beg);
1166 
1167  // Eat the first line which is the bounding rect.
1168  std::string line;
1169  std::getline(dotRpfStr, line);
1170 
1171  while( dotRpfStr.good() )
1172  {
1173  std::getline(dotRpfStr, line);
1174 
1175  if ( dotRpfStr.good() )
1176  {
1177  ++result;
1178  }
1179  }
1180 
1181  dotRpfStr.clear();
1182  dotRpfStr.seekg(0, ios_base::beg);
1183 
1184  return result;
1185 }
1186 
1188 {
1189  ossimFilename tocFile;
1190 
1191  if ( !dotRpfStr.good() )
1192  {
1193  dotRpfStr.clear();
1194  }
1195 
1196  dotRpfStr.seekg(0, ios_base::beg);
1197 
1198  // Eat the first line which is the bounding rect.
1199  std::string line;
1200  std::getline(dotRpfStr, line);
1201 
1202  // Get the second line which is first file.
1203  std::getline(dotRpfStr, line);
1204 
1205  // Get the file name and make the sub directory if needed.
1206  ossimFilename file;
1207  if ( getFile(line, file) )
1208  {
1209  ossimFilename subDir = file.path();
1210  tocFile = subDir.dirCat("a.toc");
1211  if ( !tocFile.exists() )
1212  {
1213  tocFile = subDir.dirCat("A.TOC");
1214  if ( !tocFile.exists() )
1215  {
1216  subDir = subDir.path();
1217  tocFile = subDir.dirCat("a.toc");
1218  if ( !tocFile.exists() )
1219  {
1220  tocFile = subDir.dirCat("A.TOC");
1221  if ( !tocFile.exists() )
1222  {
1223  tocFile.clear();
1224  }
1225  }
1226  }
1227  }
1228  }
1229 
1230  if ( !dotRpfStr.good() )
1231  {
1232  dotRpfStr.clear();
1233  }
1234  dotRpfStr.seekg(0, ios_base::beg);
1235 
1236  if ( traceDebug() )
1237  {
1238  ossimNotify(ossimNotifyLevel_DEBUG) << "ossimRpfToc::getSourceTocFile result: " << tocFile << "\n";
1239  }
1240 
1241  return tocFile;
1242 }
1243 
1245  ossimRpfFrameFileIndexSubsection* frameFileSubSection,
1246  std::ifstream& dotRpfStr, ossim_uint32& entry) const
1247 {
1248  bool result = false;
1249 
1250  if ( !dotRpfStr.good() )
1251  {
1252  // see if we can clear it. Someone might have hit end of file(eof).
1253  dotRpfStr.clear();
1254  }
1255 
1256  dotRpfStr.seekg(0, ios_base::beg);
1257 
1258  std::string line;
1259  ossimFilename file;
1261 
1262  // Eat the first line which is the bounding rect line
1263  std::getline(dotRpfStr, line);
1264 
1265  std::getline(dotRpfStr, line);
1266 
1267  if ( getFile(line, file) )
1268  {
1269  if ( frameFileSubSection->getFrameFileIndexRecordFromFile(file.file(), record) )
1270  {
1271  entry = record.getBoundaryRecNumber();
1272  result = true;
1273  }
1274  }
1275 
1276  if ( !dotRpfStr.good() )
1277  {
1278  dotRpfStr.clear();
1279  }
1280 
1281  dotRpfStr.seekg(0, ios_base::beg);
1282  return result;
1283 }
1284 
1285 bool ossimRpfToc::getFile(const std::string& line, ossimFilename& file) const
1286 {
1287  //---
1288  // line form:
1289  // /some_path/N03E030/006EZC1B.I21|30.4654240835311,3.59074642049858|30.5401678385356,3.65984532949882
1290  // <file> <lr_lon> <lr_lat> <ur_lon> <ur_lat>
1291  //---
1292 
1293  bool result = false;
1294  if ( line.size() )
1295  {
1296  ossimString os(line);
1297  std::vector<ossimString> lineArray;
1298  os.split(lineArray, "|");
1299  if ( lineArray.size() )
1300  {
1301  file = lineArray[0];
1302  result = true;
1303  }
1304  }
1305  return result;
1306 }
void clear()
Erases the entire container.
Definition: ossimString.h:432
void addComponentRecord(const ossimRpfComponentLocationRecord &record)
Method to add a component location record.
ossim_int32 ossimErrorCode
ossimFilename m_filename
Definition: ossimRpfToc.h:255
bool getFrameFileIndexRecordFromFile(const ossimFilename &file, ossimRpfFrameFileIndexRecord &record) const
Gets the record matching file.
virtual std::ostream & print(std::ostream &out, const std::string &prefix=std::string()) const
Print method that outputs a key/value type format adding prefix to keys.
ossimErrorCode parseStream(std::istream &in, ossimByteOrder byteOrder)
ossim_uint32 getNumberOfEntries() const
bool getCorespondingEntry(ossimRpfFrameFileIndexSubsection *frameFileSubSection, std::ifstream &dotRpfStr, ossim_uint32 &entry) const
Gets the zero based entry number for the first file in the dot rpf file.
ossimRpfFrameFileIndexSectionSubheader * getNewFrameFileIndexSectionSubheader(std::istream &in) const
ossimFilename getSourceTocFile(std::ifstream &dotRpfStr) const
Get a.toc file from the dot rpf file.
std::ostream & operator<<(std::ostream &out, const ossimRpfToc &data)
Definition: ossimRpfToc.cpp:37
ossim_uint32 getNumberOfFrames(std::ifstream &dotRpfStr) const
Get the number of frames from the dot rpf file.
std::ostream & print(std::ostream &out, const std::string &prefix=std::string()) const
print method that outputs a key/value type format adding prefix to keys.
static const ossimErrorCode OSSIM_OK
void setDate(const ossimLocalTm &d)
Sets field FDT.
virtual ~ossimRpfToc()
Definition: ossimRpfToc.cpp:50
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
bool valid() const
Definition: ossimRefPtr.h:75
ossim_uint64 getTagDataOffset() const
ossimFilename expand() const
Method to do file name expansion.
std::ostream & print(std::ostream &out, const std::string &prefix=std::string(), bool printOverviews=false) const
print method that outputs a key/value type format adding prefix to keys.
ossim_uint32 getNumberOfFramesVertical() const
bool contains(char aChar) const
Definition: ossimString.h:58
const ossimString getRelativeFramePath(ossim_uint32 entryIdx, ossim_uint32 row, ossim_uint32 col) const
For the given entry index, frame row, and frame column, this routine returns the corresponding name o...
void clearAll()
static ossimString toString(bool aValue)
Numeric to string methods.
std::vector< ossimRpfTocEntry * > m_tocEntryList
Definition: ossimRpfToc.h:250
void allocateTocEntryList(ossim_uint32 numberOfEntries)
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
ossimRefPtr< const ossimNitfFileHeader > m_nitfFileHeader
Definition: ossimRpfToc.h:257
static const ossimErrorCode OSSIM_ERROR
std::istream & getline(std::istream &is, ossimString &str, char delim)
Definition: ossimString.h:916
std::ostream & print(std::ostream &out, const std::string &prefix=std::string()) const
print method that outputs a key/value type format adding prefix to keys.
static const ossimString FSCLAS_KW
const ossimRpfHeader * getRpfHeader() const
unsigned short ossim_uint16
ossim_uint32 getLocationSectionLocation() const
returns the byte position of the location section.
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
ossim_uint32 getNumberOfFramesHorizontal(ossim_uint32 idx) const
For the given entry index, this routine returns the number of frames that exist in the horizontal dir...
const ossimRpfBoundaryRectRecord & getBoundaryInformation() const
void setLocationSectionLength(ossim_uint16 length)
const ossimRpfLocationSection * getLocationSection() const
ossimErrorCode parseStream(std::istream &in, ossimByteOrder byteOrder)
const ossimString getPathToFrameFileFromRoot() const
static const ossimString OSTAID_KW
virtual void setHeaderLength(ossim_uint64 headerLength)
Sets header length (HL) field.
void setTitle(const ossimString &title)
bool copyFileTo(const ossimFilename &outputFile) const
Copies this file to output file.
std::vector< ossimRpfComponentLocationRecord > & getLocationRecordList()
Brief Direct access to the list of records.
void setPathnameRecordOffset(ossim_uint32 offset)
void setLocationRecordLength(ossim_uint16 length)
virtual bool getTag(ossimNitfTagInformation &tagInfo, const ossimString &tagName) const
void deleteTocEntryList()
void writeStream(std::ostream &out)
Write method.
static const ossimString ONAME_KW
static const ossimString FSCODE_KW
ossimRpfBoundaryRectSectionSubheader * getNewBoundaryRectSectSubheader(std::istream &in) const
std::ostream & print(std::ostream &out, const std::string &prefix=std::string()) const
print method that outputs a key/value type format adding prefix to keys.
bool exists() const
void writeFrameFileIndexSection(ossimRpfFrameFileIndexSubsection *frameFileSubSection, std::ifstream &dotRpfStr, std::ofstream &dotTocStr)
Writes the frame file sub section of an a.toc.
ossimRpfBoundaryRectTable * getNewBoundaryRectTable(std::istream &in) const
virtual void setProperty(ossimRefPtr< ossimProperty > property)
const ossimNitfFileHeader * getHeader() const
unsigned int ossim_uint32
void setComponentAggregateLength(ossim_uint32 length)
bool getEntry(ossim_uint32 entry, ossimRpfBoundaryRectRecord &record) const
Gets record for entry.
const ossimRpfTocEntry * getTocEntry(ossim_uint32 index) const
virtual void setFileLength(ossim_uint64 fileLength)
Sets file length (FL) field.
std::ostream & print(std::ostream &out, const std::string &prefix=std::string()) const
print method that outputs a key/value type format adding prefix to keys.
void setBoundaryRecNumber(ossim_uint16 entry)
Sets the zero based entry number.
ossimErrorCode parseFile(const ossimFilename &fileName, bool keepFileHeader=false)
Parses a.toc file.
Definition: ossimRpfToc.cpp:55
ossimRefPtr< ossimRpfHeader > m_rpfHeader
Definition: ossimRpfToc.h:259
virtual void writeStream(ossim::ostream &out)
void setLocationSectionPos(std::streamoff off)
bool getRpfFrameEntry(ossim_uint32 entryIdx, ossim_uint32 row, ossim_uint32 col, ossimRpfFrameEntry &result) const
For the given entry index, frame row, and frame column, this routine returns the corresponding ossimR...
void createTocAndCopyFrames(const ossimFilename &dotRpfFile, const ossimFilename &outputDir)
Creates a new a.toc file from list of rpf frames in output directory.
virtual void parseStream(std::istream &in)
Parse method.
ossim_uint32 getNumberOfFramesHorizontal() const
ossimErrorCode parseFile(const ossimFilename &filename, bool minimalParse=false)
void getRootDirectory(ossimFilename &dir) const
Method to get the root directory from the a.toc file name.
void copyFrames(std::ifstream &dotRpfStr, const ossimFilename &outputDir)
Copies frame to output directory.
void setComplexityLevel(const ossimString &level)
void writeStream(std::ostream &out)
Write method.
static const ossimString OPHONE_KW
static const ossimString FSCTLH_KW
const ossimNitfFileHeader * getNitfFileHeader() const
Get the nitf file header.
virtual ossimByteOrder getByteOrder() const
ossimRpfFrameFileIndexSubsection * getNewFileIndexSubsection(std::istream &in) const
ossimFilename dirCat(const ossimFilename &file) const
void setPathName(const ossimString &path)
Set the pathname and length from string size.
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
void buildTocEntryList(ossimRpfHeader *rpfHeader)
void deleteAll()
ossimFilename file() const
bool parseFile(const ossimFilename &file)
std::basic_ofstream< char > ofstream
Class for char output file streams.
Definition: ossimIosFwd.h:47
bool getEntry(long row, long col, ossimRpfFrameEntry &result) const
void setLocationTableOffset(ossim_uint32 offset)
bool getFile(const std::string &line, ossimFilename &file) const
Gets the filename from line in.
void setFilename(const ossimString &file)
ossim_uint32 getNumberOfFramesVertical(ossim_uint32 idx) const
For the given entry index, this routine returns the number of frames that exist in the vertical direc...
std::ostream & printHeader(std::ostream &out, const std::string &prefix=std::string()) const
print method that outputs a key/value type format adding prefix to keys.
bool createDirectory(bool recurseFlag=true, int perm=0775) const
ossim_int32 getTocEntryIndex(const ossimRpfTocEntry *entry)
Returns -1 if not found.
ossimFilename path() const
const ossimFilename & getFullPath() const
void writeStream(std::ostream &out)
Write method.
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
void getFirstEntry(const ossimRpfTocEntry *rpfTocEntry, ossimRpfFrameEntry &frameEntry) const
Walks through frames to find the first entry that exists...
void clearFields()
Clears records and fields.
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
void addTag(const ossimNitfTagInformation &tag, bool unique=true)
int ossim_int32
void setNumberOfComponentLocationRecords(ossim_uint16 count)
std::ostream & printTocEntry(std::ostream &out, ossim_uint32 entryIndex, const std::string &prefix=std::string(), bool printOverviews=false) const
print method that outputs a key/value type format adding prefix to keys.
std::ostream & print(std::ostream &out, ossimString prefix) const
prints to out.