Ejemplo n.º 1
0
// Note: throws ossimException on error.
void ossimRpfUtil::writeDotRpfFiles( const ossimFilename& aDotTocFile,
                                     const ossimFilename& outputDir )
{
   static const char MODULE[] = "ossimRpfUtil::writeDotRpfFiles";

   if ( traceDebug() )
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << MODULE << " entered..."
         << "\na.toc file:        " << aDotTocFile
         << "\noutput directory:  " << outputDir
         << "\n";
   }
   
   // Parse the a.toc file:
   ossimRefPtr<ossimRpfToc> toc = new ossimRpfToc();
   
   if ( toc->parseFile(aDotTocFile) != ossimErrorCodes::OSSIM_OK )
   {
      std::string e = MODULE;
      e += " ERROR:\nCould not open: ";
      e+= aDotTocFile.string();
      throw ossimException(e);
   }

   if ( outputDir.expand().exists() == false )
   {
      if ( !outputDir.createDirectory(true, 0775) )
      {
         std::string e = MODULE;
         e += " ERROR:\nCould not create directory: ";
         e+= outputDir.c_str();
         throw ossimException(e);
      }
   }

   //---
   // Go through the entries...
   //---
   ossim_uint32 entries = toc->getNumberOfEntries();
   for (ossim_uint32 entry = 0; entry < entries; ++entry)
   {
      const ossimRpfTocEntry* tocEntry = toc->getTocEntry(entry);
      if (tocEntry)
      {
         if ( tocEntry->isEmpty() == false )
         {
            writeDotRpfFile(toc.get(), tocEntry, outputDir, entry);
         }
      }
      else
      {
         std::string e = MODULE;
         e += " ERROR:  Null entry: ";
         e += ossimString::toString(entry).string();
         throw ossimException(e);
      }
   }
   
} // End: ossimRpfUtil::writeDotRpfFiles
Ejemplo n.º 2
0
void ossimRpfToc::createTocAndCopyFrames( const ossimFilename& dotRpfFile,
                                          const ossimFilename& outputDir )
{
   static const char MODULE[] = "ossimRpfToc::createTocAndCopyFrames";

   if ( traceDebug() )
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << MODULE << " entered..."
         << "\ndot rpf file:      " << dotRpfFile
         << "\noutput directory:  " << outputDir
         << "\n";
   }

   if ( outputDir.expand().exists() == false )
   {
      if ( !outputDir.createDirectory(true, 0775) )
      {
         std::string e = MODULE;
         e += " ERROR:\nCould not create directory: ";
         e+= outputDir.c_str();
         throw ossimException(e);
      }
   }

   // Open the dot rpf file.
   std::ifstream* dotRpfStr = new std::ifstream;
   dotRpfStr->open(dotRpfFile, ios_base::in);
   if ( !dotRpfStr->good() )
   {
      delete dotRpfStr;
      dotRpfStr = 0;

      std::string e = MODULE;
      e += " ERROR:\nCould not open: ";
      e += dotRpfFile.c_str();
      throw ossimException(e);
   }

   ossimFilename sourceADotTocFile = getSourceTocFile(*dotRpfStr);
   if ( sourceADotTocFile.empty() )
   {
      delete dotRpfStr;
      dotRpfStr = 0;

      std::string e = MODULE;
      e += " ERROR:\nCould not deduce source a.toc file!";
      throw ossimException(e);
   }
   
   // Open the source a.toc file. Note the true flag is to keep the file header.
   ossimRefPtr<ossimRpfToc> sourceADotToc = new ossimRpfToc;
   if ( sourceADotToc->parseFile(sourceADotTocFile, true) != ossimErrorCodes::OSSIM_OK )
   {
      delete dotRpfStr;
      dotRpfStr = 0;
 
      std::string e = MODULE;
      e += " ERROR:\nCould not open: ";
      e += sourceADotTocFile.c_str();
      throw ossimException(e);
   }

   ossimRefPtr<const ossimNitfFileHeader> sourceNitfFileHdr = sourceADotToc->getNitfFileHeader();
   if ( !sourceNitfFileHdr.valid() )
   {
      delete dotRpfStr;
      dotRpfStr = 0;        

      std::string e = MODULE;
      e += " ERROR:\nCould not get nitf file header from: ";
      e += sourceADotTocFile.c_str();
      throw ossimException(e);
   }
   
   ossimRefPtr<const ossimRpfHeader> sourceRpfHdr = sourceADotToc->getRpfHeader();
   if ( !sourceRpfHdr.valid() )
   {
      delete dotRpfStr;
      dotRpfStr = 0;
      
      std::string e = MODULE;
      e += " ERROR:\nCould not get rpf header from: ";
      e += sourceADotTocFile.c_str();
      throw ossimException(e);
   }

   // Get the boundary rect sub header from the source a.toc.
   ossimRefPtr<ossimRpfBoundaryRectSectionSubheader> boundaryRectSectionSubheader =
      sourceRpfHdr->getNewBoundaryRectSectSubheader(sourceADotTocFile);
   if ( !boundaryRectSectionSubheader.valid() )
   {
      delete dotRpfStr;
      dotRpfStr = 0;

      std::string e = MODULE;
      e += " ERROR:\nCould not pull boundary rect sub header from source file: ";
      e += sourceADotTocFile.c_str();
      throw ossimException(e);
   }   

   // Get the boundary rect table from the source a.toc.
   ossimRefPtr<ossimRpfBoundaryRectTable> boundaryRectTable =
      sourceRpfHdr->getNewBoundaryRectTable(sourceADotTocFile);
   if ( !boundaryRectTable.valid() )
   {
      delete dotRpfStr;
      dotRpfStr = 0;
      
      std::string e = MODULE;
      e += " ERROR:\nCould not pull boundary rect table from source file: ";
      e += sourceADotTocFile.c_str();
      throw ossimException(e);
   }
   
   // Get the frame file subheader from the source a.toc.
   ossimRefPtr<ossimRpfFrameFileIndexSectionSubheader> frameFileSubHeader =
      sourceRpfHdr->getNewFrameFileIndexSectionSubheader(sourceADotTocFile);
   if ( !frameFileSubHeader.valid() )
   {
      delete dotRpfStr;
      dotRpfStr = 0;

      std::string e = MODULE;
      e += " ERROR:\nCould not pull frame file sub header from source file: ";
      e += sourceADotTocFile.c_str();
      throw ossimException(e);
   }

   // Get the frame file subsection from the source a.toc.
   ossimRefPtr<ossimRpfFrameFileIndexSubsection> frameFileSubSection =
      sourceRpfHdr->getNewFileIndexSubsection(sourceADotTocFile);
   if ( !frameFileSubSection.valid() )
   {
      delete dotRpfStr;
      dotRpfStr = 0;

      std::string e = MODULE;
      e += " ERROR:\nCould not pull frame file sub section from source file: ";
      e += sourceADotTocFile.c_str();
      throw ossimException(e); 
   }
   
   // Open the output file to write to.
   const ossimFilename A_DOT_TOC_FILE = "a.toc";
   ossimFilename dotTocFile = outputDir.dirCat(A_DOT_TOC_FILE);
   std::ofstream* dotTocStr = new std::ofstream;
   dotTocStr->open( dotTocFile.c_str(), ios::out|ios::binary );
   if ( !dotTocStr->good() )
   {
      delete dotRpfStr;
      dotRpfStr = 0;
      delete dotTocStr;
      dotTocStr =0;

      std::string e = MODULE;
      e += " ERROR:\nCould not open: ";
      e += dotTocFile.c_str();
      throw ossimException(e);
   }
   
   // Variables used throughout:
   ossimRefPtr<ossimProperty> prop = new ossimStringProperty();
   ossimString field;
   ossimString s;
   std::streampos fileHeaderLength = 0;
   std::streampos fileLength = 0;
      
   ossimRefPtr<ossimNitfFileHeaderV2_0> fileHdr = new ossimNitfFileHeaderV2_0();
   
   // Set the CLEVEL:
   s = "01";
   fileHdr->setComplexityLevel(s);
   
   // Set the OSTAID:
   prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::OSTAID_KW);
   fileHdr->setProperty(prop);
   
   // Set the FDT (date):
   fileHdr->setDate();
   
   // Set the FTITLE:
   s = "a.toc";
   fileHdr->setTitle(s);
   
   // Set the FSCLAS:
   prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::FSCLAS_KW);
   fileHdr->setProperty(prop);
   
   // Set the FSCODE:
   prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::FSCODE_KW);
   fileHdr->setProperty(prop);
   
   // Set the FSCTLH:
   prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::FSCTLH_KW);
   fileHdr->setProperty(prop);
   
   // Set the ONAME:
   prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::ONAME_KW);
   fileHdr->setProperty(prop);
   
   // Set the OPHONE:
   prop = sourceNitfFileHdr->getProperty(ossimNitfFileHeaderV2_X::OPHONE_KW);
   fileHdr->setProperty(prop);
   
   // Add the rpf header.
   ossimRpfHeader* rpfHdr = new ossimRpfHeader( *(sourceRpfHdr.get()) );
   
   ossimRefPtr<ossimNitfRegisteredTag> rpfHdrRp = rpfHdr;
   ossimNitfTagInformation rpfHdrInfo(rpfHdrRp);
   fileHdr->addTag(rpfHdrInfo);
   
   //---
   // Write it out...
   // The first write will be with an rpfheader with no location sections just
   // to see where the end of the file header is.
   //---
   fileHdr->writeStream(*dotTocStr);
   
   //---
   // End of file header. Get the header length. This will also be the
   // start of the location section.
   //---
   std::streampos pos = dotTocStr->tellp();
   std::streamoff locationSectionOffset = pos;
   
   // Set the header length:
   fileHdr->setHeaderLength( static_cast<ossim_uint64>(locationSectionOffset) );
   
   // Set the location of the location section.
   rpfHdr->setLocationSectionPos(locationSectionOffset);

   // Set the file name.
   rpfHdr->setFilename(A_DOT_TOC_FILE);
   
   // Add the component location records to the header.
   ossimRpfLocationSection* locSec = rpfHdr->getLocationSection();
   
   // Clear the records copied from the source a.toc.
   locSec->clearFields();
   
   //---
   // Set the length of the locSec to 74.  The record itself is 14 bytes plus
   // an additional 60 bytes for six location records ten bytes each.
   //---
   const ossim_uint16 LOCATION_SECTION_SIZE = 74;
   locSec->setLocationSectionLength(LOCATION_SECTION_SIZE);
   
   // Set the offset which 14 bytes to get to the first record.
   locSec->setLocationTableOffset(14);
   
   // Six records:
   locSec->setNumberOfComponentLocationRecords(6);
   
   // Each record 10 bytes:
   locSec->setLocationRecordLength(10);
   
   // Don't know the aggregate length yet.
   
   ossimRpfComponentLocationRecord locRec;
   
   // Note: See ossimRpfConstants for enum ossimRpfComponentId
   
   const ossim_uint32 RPFHDR_SIZE = 48;
   const ossim_uint32 LOCATION_SECTION_OFFSET = static_cast<ossim_uint32>(locationSectionOffset);
   const ossim_uint32 BOUNDARY_SUBHEADER_SIZE = 8;
   const ossim_uint32 BOUNDARY_RECORD_SIZE = 132;
   const ossim_uint32 FILE_SUBHEADER_SIZE = 13;
   // const ossim_uint32 = ;
   
   // Record 1 RPFHDR location:
   ossim_uint32 rpfHdrOffset = 0;
   if ( fileHdr->getTag(rpfHdrInfo, "RPFHDR") )
   {
      rpfHdrOffset = rpfHdrInfo.getTagDataOffset();
   }

   locRec.m_componentId = OSSIM_RPF_HEADER_COMPONENT; // 128
   locRec.m_componentLength = RPFHDR_SIZE;
   locRec.m_componentLocation = static_cast<ossim_uint32>(rpfHdrInfo.getTagDataOffset());
   locSec->addComponentRecord(locRec);

   if ( traceDebug() )
   {
      ossimNotify(ossimNotifyLevel_DEBUG)<< "rpf hdr offset: " << rpfHdrOffset << "\n";
      locRec.print( ossimNotify(ossimNotifyLevel_DEBUG) );
   }
   
   // Record 2 location section:
   locRec.m_componentId = OSSIM_RPF_LOCATION_COMPONENT; // 129
   locRec.m_componentLength = LOCATION_SECTION_SIZE;
   locRec.m_componentLocation = LOCATION_SECTION_OFFSET;
   locSec->addComponentRecord(locRec);

   if ( traceDebug() )
   {
      locRec.print( ossimNotify(ossimNotifyLevel_DEBUG) );
   }
   
   // Record 3 boundary rect sub header section:
   locRec.m_componentId = OSSIM_RPF_BOUNDARY_RECT_SECTION_SUBHEADER; // 148
   locRec.m_componentLength = BOUNDARY_SUBHEADER_SIZE;
   locRec.m_componentLocation = locRec.m_componentLocation + LOCATION_SECTION_SIZE;
   locSec->addComponentRecord(locRec);

   if ( traceDebug() )
   {
      locRec.print( ossimNotify(ossimNotifyLevel_DEBUG) );
   }
   
   // Capture the location.
   std::streamoff boundaryRectPosition = locRec.m_componentLocation;
   
   // Record 4 boundary rect table:
   locRec.m_componentId = OSSIM_RPF_BOUNDARY_RECT_TABLE; // 149
   locRec.m_componentLength = BOUNDARY_RECORD_SIZE;
   locRec.m_componentLocation = locRec.m_componentLocation + BOUNDARY_SUBHEADER_SIZE;
   locSec->addComponentRecord(locRec);

   if ( traceDebug() )
   {
      locRec.print( ossimNotify(ossimNotifyLevel_DEBUG) );
   }
   
   // Record 5 file index sub header:
   locRec.m_componentId = OSSIM_RPF_FRAME_FILE_INDEX_SECTION_SUBHEADER; // 150
   locRec.m_componentLength = FILE_SUBHEADER_SIZE;
   locRec.m_componentLocation = locRec.m_componentLocation + BOUNDARY_RECORD_SIZE;
   locSec->addComponentRecord(locRec);

   if ( traceDebug() )
   {
      locRec.print( ossimNotify(ossimNotifyLevel_DEBUG) );
   }
    
   // Record 6 file index sub header:
   locRec.m_componentId = OSSIM_RPF_FRAME_FILE_INDEX_SUBSECTION; // 151
   locRec.m_componentLength = 0;  // need to calculate.
   locRec.m_componentLocation = locRec.m_componentLocation + FILE_SUBHEADER_SIZE;
   locSec->addComponentRecord(locRec);

   if ( traceDebug() )
   {
      locRec.print( ossimNotify(ossimNotifyLevel_DEBUG) );
   }
   
   // Seek back and re-write...
   dotTocStr->seekp(0, ios::beg);
   fileHdr->writeStream(*dotTocStr);
   
   dotTocStr->seekp(boundaryRectPosition, ios::beg);

   // Only writing one entry:
   boundaryRectSectionSubheader->setNumberOfEntries(1);

   if ( traceDebug() )
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << "writing boundaryRectSectionSubheader:\n" << *(boundaryRectSectionSubheader.get())
         << "\n";
   }

   //---
   // Write the boundary rectangle section.  This includes the subheader and subsection.
   // These coorespond to location records 3 and 4 above.
   //---
   boundaryRectSectionSubheader->writeStream(*dotTocStr);

   if ( traceDebug() )
   {
      ossimNotify(ossimNotifyLevel_DEBUG) 
         << "Original boundaryRectTable:\n" << *(boundaryRectTable.get()) << "\n";
   }

   ossim_uint32 entry;
   if ( getCorespondingEntry( frameFileSubSection.get(), *dotRpfStr, entry ) )
   {
      ossimRpfBoundaryRectRecord boundaryRectRecord;
      if ( boundaryRectTable->getEntry( entry, boundaryRectRecord) )
      {
         if ( traceDebug() )
         {
            ossimNotify(ossimNotifyLevel_DEBUG) 
               << "writing boundaryRectTable:\n" << boundaryRectRecord << "\n";
         }
         
         boundaryRectRecord.writeStream(*dotTocStr);
      }
      else
      {
         std::string e = MODULE;
         e += " ERROR:\nCould not get bounding rect record for entry: ";
         e += ossimString::toString(entry).c_str();
         throw ossimException(e);
      }
   }
   else
   {
      std::string e = MODULE;
      e += " ERROR:\nCould not deduce entry from frame list!";
      throw ossimException(e);
   }

   frameFileSubHeader->setNumberOfIndexRecords( getNumberOfFrames(*dotRpfStr) );
   frameFileSubHeader->setNumberOfPathnameRecords(1);
   const ossim_uint16 FRAME_FILE_INDEX_RECORD_LENGTH = 33;
   frameFileSubHeader->setIndexRecordLength( FRAME_FILE_INDEX_RECORD_LENGTH );

   if ( traceDebug() )
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << "writing frameFileSubHeader:\n" << *(frameFileSubHeader.get()) << "\n";
   }
   frameFileSubHeader->writeStream( *dotTocStr );

   if ( traceDebug() )
   {
      ossimNotify(ossimNotifyLevel_DEBUG) << "writing frameFileSubSection:\n";
   }

   std::streamoff frameFileIndexSectionStartPos = dotTocStr->tellp();
   
   writeFrameFileIndexSection(frameFileSubSection.get(), *dotRpfStr, *dotTocStr);
   
   std::streamoff endOfFilePos = dotTocStr->tellp();

   // Update the location section length for the frame file index section.
   locSec->getLocationRecordList()[5].m_componentLength =
      static_cast<ossim_uint32>(endOfFilePos - frameFileIndexSectionStartPos);

   // Update the length of all location sections.
   locSec->setComponentAggregateLength(
      static_cast<ossim_uint32>(endOfFilePos) - rpfHdr->getLocationSectionLocation() );
   

   fileHdr->setFileLength(static_cast<ossim_uint64>(endOfFilePos));
   dotTocStr->seekp(0, ios::beg);
   fileHdr->writeStream(*dotTocStr);

   ossimNotify(ossimNotifyLevel_DEBUG) << "Wrote file: " << dotTocFile << "\n";

   // Copy the frames to the output directory.
   copyFrames(*dotRpfStr, outputDir);

   // Cleanup:
   delete dotRpfStr;
   dotRpfStr = 0;
   delete dotTocStr;
   dotTocStr =0;
}