bool LandsatEtmPlusImporter::createRasterPager(RasterElement* pRaster) const
{
   string srcFile = pRaster->getFilename();
   if (srcFile.empty())
   {
      return false;
   }
   {
      //scoping to ensure the file is closed before creating the pager
      LargeFileResource srcFileRes;
      if (!srcFileRes.open(srcFile, O_RDONLY | O_BINARY, S_IREAD))
      {
         return false;
      }
   }
   // create the pager
   ExecutableResource pPager("BandResamplePager");
   VERIFY(pPager->getPlugIn() != NULL);
   bool isWritable = false;
   bool useDataDescriptor = false;
   FactoryResource<Filename> pFilename;
   VERIFY(pFilename.get() != NULL);
   pFilename->setFullPathAndName(pRaster->getFilename());

   pPager->getInArgList().setPlugInArgValue("Raster Element", pRaster);
   pPager->getInArgList().setPlugInArgValue("Filename", pFilename.get());
   pPager->getInArgList().setPlugInArgValue("isWritable", &isWritable);
   pPager->getInArgList().setPlugInArgValue("Use Data Descriptor", &useDataDescriptor);
   RasterDataDescriptor* pDescriptor = static_cast<RasterDataDescriptor*>(pRaster->getDataDescriptor());
   VERIFY(pDescriptor != NULL);
   RasterFileDescriptor* pFileDescriptor = static_cast<RasterFileDescriptor*>(pDescriptor->getFileDescriptor());
   VERIFY(pFileDescriptor != NULL);
   unsigned int band = 5, rows = mB6Rows, cols = mB6Cols;
   pPager->getInArgList().setPlugInArgValue("Band", &band);
   pPager->getInArgList().setPlugInArgValue("Rows", &rows);
   pPager->getInArgList().setPlugInArgValue("Columns", &cols);
   if (!pPager->execute())
   {
      return false;
   }
   RasterPager* pRasterPager = dynamic_cast<RasterPager*>(pPager->getPlugIn());
   if (pRasterPager != NULL)
   {
      pPager->releasePlugIn();
   }
   else
   {
      return false;
   }

   pRaster->setPager(pRasterPager);
   return true;
}
bool RasterElementImporterShell::createRasterPager(RasterElement* pRaster) const
{
   string srcFile = pRaster->getFilename();
   if (srcFile.empty())
   {
      return false;
   }
   {
      //scoping to ensure the file is closed before calling createMemoryMappedPager
      LargeFileResource srcFileRes;
      if (!srcFileRes.open(srcFile, O_RDONLY | O_BINARY, S_IREAD))
      {
         return false;
      }
   }
   mUsingMemoryMappedPager = pRaster->createMemoryMappedPager();
   return mUsingMemoryMappedPager;
}
bool LandsatEtmPlusImporter::readHeader(const string& strInFstHeaderFileName)
{
   if (strInFstHeaderFileName.empty())
   {
      return false;
   }

   //The HTM header file contains information for Band 6 Channel 1 and 2. 
   //This set extracts the info needed to process HTM(band 6) header
   mFieldHTM.clear();
   string baseFileName = strInFstHeaderFileName.substr(0, strInFstHeaderFileName.length() - 7);
   FactoryResource<Filename> filename;
   filename->setFullPathAndName(baseFileName);
   FactoryResource<FileFinder> fileFinder;
   string htmFileName = filename->getFileName() + "HTM.FST";
   if (fileFinder->findFile(filename->getPath(), htmFileName))
   {
      fileFinder->findNextFile();
      fileFinder->getFullPath(htmFileName);
   }

   LargeFileResource htmFile;
   if (htmFile.open(htmFileName, O_RDONLY, S_IREAD))
   {
      //process HTM header
      vector<char> buf(5120);
      size_t count = static_cast<size_t>(htmFile.read(&buf.front(), 5120));
      VERIFY(htmFile.eof());
      string htmHeaderFull(&buf.front(), count);
      vector<string> htmHeaderLines = StringUtilities::split(htmHeaderFull, '\n');

      if (!parseHeader(htmHeaderLines, mFieldHTM)) //parse band 6 header
      {
         mFieldHTM.clear();
      }
   }
   htmFile.close();

   // The HRF Header file contains the parameters for Bands 1-5 and 7.  
   mFieldHRF.clear();
   string hrfFileName = filename->getFileName() + "HRF.FST";
   if (fileFinder->findFile(filename->getPath(), hrfFileName))
   {
      fileFinder->findNextFile();
      fileFinder->getFullPath(hrfFileName);
   }

   LargeFileResource hrfFile;
   if (hrfFile.open(hrfFileName, O_RDONLY, S_IREAD))
   {
      //process HRF header
      vector<char> buf(5120);
      size_t count = static_cast<size_t>(hrfFile.read(&buf.front(), 5120));
      VERIFY(hrfFile.eof());
      string hrfHeaderFull(&buf.front(), count);
      vector<string> hrfHeaderLines = StringUtilities::split(hrfHeaderFull, '\n');

      if (!parseHeader(hrfHeaderLines, mFieldHRF)) //parse bands 1-5 and 7 header
      {
         mFieldHRF.clear();
      }
   }
   hrfFile.close();

   // The HPN Header file contains the parameters for Band 8.
   mFieldHPN.clear();
   string hpnFileName = filename->getFileName() + "HPN.FST";
   if (fileFinder->findFile(filename->getPath(), hpnFileName))
   {
      fileFinder->findNextFile();
      fileFinder->getFullPath(hpnFileName);
   }

   LargeFileResource hpnFile;
   if (hpnFile.open(hpnFileName, O_RDONLY, S_IREAD))
   {
      //process HPN header
      vector<char> buf(5120);
      size_t count = static_cast<size_t>(hpnFile.read(&buf.front(), 5120));
      VERIFY(hpnFile.eof());
      string hpnHeaderFull(&buf.front(), count);
      vector<string> hpnHeaderLines = StringUtilities::split(hpnHeaderFull, '\n');

      if (!parseHeader(hpnHeaderLines, mFieldHPN)) //parse band 8 header
      {
         mFieldHPN.clear();
      }
   }
   hpnFile.close();

   return (!mFieldHRF.empty() || !mFieldHTM.empty() || !mFieldHPN.empty());
}
vector<ImportDescriptor*> SignatureImporter::getImportDescriptors(const string& filename)
{
   vector<ImportDescriptor*> descriptors;
   if (filename.empty())
   {
      return descriptors;
   }

   LargeFileResource pSigFile;
   if (!pSigFile.open(filename, O_RDONLY | O_BINARY, S_IREAD))
   {
      return descriptors;
   }

   // load the data
   FactoryResource<DynamicObject> pMetadata;
   VERIFYRV(pMetadata.get() != NULL, descriptors);

   bool readError = false;
   string line;
   string unitName("Reflectance");
   UnitType unitType(REFLECTANCE);
   double unitScale(1.0);

   // parse the metadata
   for (line = pSigFile.readLine(&readError);
      (readError == false) && (line.find('=') != string::npos);
      line = pSigFile.readLine(&readError))
   {
      vector<string> metadataEntry;

      trim(line);
      split(metadataEntry, line, is_any_of("="));
      if (metadataEntry.size() == 2)
      {
         string key = metadataEntry[0];
         string value = metadataEntry[1];
         trim(key);
         trim(value);
         if (ends_with(key, "Bands") || key == "Pixels")
         {
            pMetadata->setAttribute(key, StringUtilities::fromXmlString<unsigned long>(value));
         }
         else if (key == "UnitName")
         {
            unitName = value;
         }
         else if (key == "UnitType")
         {
            unitType = StringUtilities::fromXmlString<UnitType>(value);
         }
         else if (key == "UnitScale")
         {
            unitScale = StringUtilities::fromXmlString<double>(value);
         }
         else
         {
            pMetadata->setAttribute(key, value);
         }
      }
   }
   if ((readError == true) && (pSigFile.eof() != 1))
   {
      return descriptors;
   }
   // Verify that the next line contains float float pairs
   vector<string> dataEntry;

   trim(line);
   split(dataEntry, line, is_space());
   if (dataEntry.size() != 2)
   {
      return descriptors;
   }
   bool error = false;
   StringUtilities::fromXmlString<float>(dataEntry[0], &error);
   !error && StringUtilities::fromXmlString<float>(dataEntry[1], &error);
   if (error)
   {
      return descriptors;
   }

   string datasetName = dv_cast<string>(pMetadata->getAttribute("Name"), filename);

   ImportDescriptorResource pImportDescriptor(datasetName, "Signature");
   VERIFYRV(pImportDescriptor.get() != NULL, descriptors);
   SignatureDataDescriptor* pDataDescriptor =
      dynamic_cast<SignatureDataDescriptor*>(pImportDescriptor->getDataDescriptor());
   VERIFYRV(pDataDescriptor != NULL, descriptors);

   FactoryResource<SignatureFileDescriptor> pFileDescriptor;
   VERIFYRV(pFileDescriptor.get() != NULL, descriptors);
   pFileDescriptor->setFilename(filename);

   FactoryResource<Units> pReflectanceUnits;
   VERIFYRV(pReflectanceUnits.get() != NULL, descriptors);
   pReflectanceUnits->setUnitName(unitName);
   pReflectanceUnits->setUnitType(unitType);
   if (unitScale != 0.0)
   {
      pReflectanceUnits->setScaleFromStandard(1.0 / unitScale);
   }
   pDataDescriptor->setUnits("Reflectance", pReflectanceUnits.get());
   pFileDescriptor->setUnits("Reflectance", pReflectanceUnits.get());

   pDataDescriptor->setFileDescriptor(pFileDescriptor.get());
   pDataDescriptor->setMetadata(pMetadata.get());
   descriptors.push_back(pImportDescriptor.release());
   return descriptors;
}
bool SignatureImporter::execute(PlugInArgList* pInArgList, PlugInArgList* OutArgList)
{
   VERIFY(pInArgList != NULL);
   ProgressTracker progress(pInArgList->getPlugInArgValue<Progress>(Executable::ProgressArg()),
      "Loading spectral signature", "spectral", "5A9F8379-7D7D-4575-B78B-305AE0DFC66D");

   Signature* pSignature = pInArgList->getPlugInArgValue<Signature>(Importer::ImportElementArg());
   VERIFY(pSignature != NULL);
   DataDescriptor* pDataDescriptor = pSignature->getDataDescriptor();
   VERIFY(pDataDescriptor != NULL);
   FileDescriptor* pFileDescriptor = pDataDescriptor->getFileDescriptor();
   VERIFY(pFileDescriptor != NULL);

   progress.getCurrentStep()->addProperty("filename", pFileDescriptor->getFilename().getFullPathAndName());
   
   DynamicObject* pMetadata = pSignature->getMetadata();
   VERIFY(pMetadata != NULL);
   string warningMsg;

   LargeFileResource pSigFile;
   VERIFY(pSigFile.open(pFileDescriptor->getFilename().getFullPathAndName(), O_RDONLY | O_BINARY, S_IREAD));

   const Units* pUnits = pSignature->getUnits("Reflectance");
   VERIFY(pUnits != NULL);

   // Read the signature data
   vector<double> wavelengthData, reflectanceData;

   int64_t fileSize = pSigFile.fileLength();
   bool readError = false;
   size_t largeValueCount(0);
   for (string line = pSigFile.readLine(&readError); readError == false; line = pSigFile.readLine(&readError))
   {
      if (isAborted())
      {
         progress.report("Importer aborted", 0, ABORT, true);
         return false;
      }

      int64_t fileLocation = pSigFile.tell();
      progress.report("Loading signature data", static_cast<int>(fileLocation * 100.0 / fileSize), NORMAL);

      trim(line);
      if (line.empty())
      {
         continue;
      }
      if (line.find('=') == string::npos)
      {
         double wavelength = 0.0, reflectance = 0.0;
         vector<string> dataEntry;
         split(dataEntry, line, is_space());
         bool error = true;
         if (dataEntry.size() >= 1)
         {
            wavelength = StringUtilities::fromXmlString<double>(dataEntry[0], &error);
            if (wavelength > 50.0)
            {
               // Assume wavelength values are in nanometers and convert to microns
               wavelength = Wavelengths::convertValue(wavelength, NANOMETERS, MICRONS);
            }
         }
         if (!error && dataEntry.size() == 2)
         {
            reflectance = StringUtilities::fromXmlString<double>(dataEntry[1], &error);

            // Since the signature file may not have contained info on units and unitScale (defaults to values of
            // "REFLECTANCE" and "1.0"), we need to check that the reflectance value is properly scaled.
            // In theory, a valid reflectance value should be between 0 and 1, but real data may extend beyond these
            // limits due to errors that occurred in collection, calibration, conversion, etc. We're assuming that a
            // value greater than 2.0 indicates that the value was scaled by a factor other than 1.0 - a common data
            // collection practice is to store a data value as an integer value equal to the actual value multiplied
            // by a scaling factor. This saves storage space while preserving precision. 10000 is a very common
            // scaling factor and the one we will assume was used. Right now we'll just count the number of large values.
            // If more than half the values are large, we will assume they were scaled and divide all the values by 10000.
            if (pUnits->getUnitType() == REFLECTANCE && pUnits->getScaleFromStandard() == 1.0
               && fabs(reflectance) > 2.0)
            {
               ++largeValueCount;
            }
         }
         if (error)
         {
            progress.report("Error parsing signature data", 0, ERRORS, true);
         }

         wavelengthData.push_back(wavelength);
         reflectanceData.push_back(reflectance);
      }
   }

   if ((readError == true) && (pSigFile.eof() != 1))
   {
      progress.report("Unable to read signature file", 0, ERRORS, true);
      return false;
   }

   // check for need to scale the values, i.e., at least half the values are large
   if (reflectanceData.empty() == false && largeValueCount > 0 && largeValueCount >= (reflectanceData.size() / 2))
   {
      warningMsg += (warningMsg.empty() ? "" : "\n");
      warningMsg += "Values appear to have been scaled - values have been divided by 10000";
      for (vector<double>::iterator it = reflectanceData.begin(); it != reflectanceData.end(); ++it)
      {
         *it *= 0.0001;  // divide by 10000
      }
   }
   pSignature->setData("Wavelength", wavelengthData);
   pSignature->setData("Reflectance", reflectanceData);
   if (warningMsg.empty())
   {
      progress.report("Spectral signature loaded", 100, NORMAL);
   }
   else
   {
      progress.report(warningMsg, 100, WARNING);
      progress.getCurrentStep()->addMessage(warningMsg, "spectral", "770EB61A-71CD-4f83-8C7B-E0FEF3D7EB8D");
   }
   progress.upALevel();
   return true;
}
Exemple #6
0
bool DicomImporter::validateDefaultOnDiskReadOnly(const DataDescriptor *pDescriptor, std::string &errorMessage) const
{
   const RasterDataDescriptor *pRasterDescriptor = dynamic_cast<const RasterDataDescriptor*>(pDescriptor);
   if(pRasterDescriptor == NULL)
   {
      errorMessage = "The data descriptor is invalid.";
      return false;
   }

   const RasterFileDescriptor *pFileDescriptor =
      dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor());
   if(pFileDescriptor == NULL)
   {
      errorMessage = "The file descriptor is invalid.";
      return false;
   }

   ProcessingLocation loc = pDescriptor->getProcessingLocation();
   if (loc == ON_DISK_READ_ONLY)
   {
      // Invalid filename
      const Filename &filename = pFileDescriptor->getFilename();
      if(filename.getFullPathAndName().empty())
      {
         errorMessage = "The filename is invalid.";
         return false;
      }

      // Existing file
      LargeFileResource file;
      if(!file.open(filename.getFullPathAndName(), O_RDONLY | O_BINARY, S_IREAD))
      {
         errorMessage = "The file: " + std::string(filename) + " does not exist.";
         return false;
      }

      // Data can be decoded
      DicomImage img(filename.getFullPathAndName().c_str());
      if(img.getStatus() != EIS_Normal)
      {
         errorMessage = std::string("Unable to decode dataset: ") + DicomImage::getString(img.getStatus());
         return false;
      }

      // Interleave conversions
      InterleaveFormatType dataInterleave = pRasterDescriptor->getInterleaveFormat();
      InterleaveFormatType fileInterleave = pFileDescriptor->getInterleaveFormat();
      if(dataInterleave != fileInterleave)
      {
         errorMessage = "Interleave format conversions are not supported with on-disk read-only processing.";
         return false;
      }

      //Subset
      unsigned int loadedBands = pRasterDescriptor->getBandCount();
      unsigned int fileBands = pFileDescriptor->getBandCount();

      unsigned int skipFactor = 0;
      if(!RasterUtilities::determineSkipFactor(pRasterDescriptor->getRows(), skipFactor) || skipFactor != 0)
      {
         errorMessage = "Skip factors are not supported for rows or columns with on-disk read-only processing.";
         return false;
      }
      if(!RasterUtilities::determineSkipFactor(pRasterDescriptor->getColumns(), skipFactor) || skipFactor != 0)
      {
         errorMessage = "Skip factors are not supported for rows or columns with on-disk read-only processing.";
         return false;
      }
   }

   return true;
}
Exemple #7
0
bool ImporterShell::validate(const DataDescriptor* pDescriptor, string& errorMessage) const
{
   mValidationError = ValidationTest();

   // Check for no validation
   int validationTest = getValidationTest(pDescriptor);
   if (validationTest == NO_VALIDATION)
   {
      return true;
   }

   // Always validate the data descriptor and file descriptor
   if (pDescriptor == NULL)
   {
      errorMessage = "The data set information is invalid.";
      return false;
   }

   const FileDescriptor* pFileDescriptor = pDescriptor->getFileDescriptor();
   if (pFileDescriptor == NULL)
   {
      errorMessage = "The data set does not contain valid file information.";
      return false;
   }

   // Existing file
   const string& filename = pFileDescriptor->getFilename();
   if (validationTest & EXISTING_FILE)
   {
      // Valid filename
      if (filename.empty() == true)
      {
         errorMessage = "The filename is invalid.";
         mValidationError = EXISTING_FILE;
         return false;
      }

      // Existing file
      LargeFileResource file(true);
      if (!file.open(filename.c_str(), O_RDONLY | O_BINARY, S_IREAD))
      {
         errorMessage = "The file: " + filename + " does not exist.";
         mValidationError = EXISTING_FILE;
         return false;
      }
   }

   // Existing data element
   if (validationTest & NO_EXISTING_DATA_ELEMENT)
   {
      const string& name = pDescriptor->getName();
      const string& type = pDescriptor->getType();
      DataElement* pParent = pDescriptor->getParent();

      Service<ModelServices> pModel;
      if (pModel->getElement(name, type, pParent) != NULL)
      {
         errorMessage = "The data set currently exists.  It may have already been imported.";
         mValidationError = NO_EXISTING_DATA_ELEMENT;
         return false;
      }
   }

   // Valid classification
   Service<UtilityServices> pUtilities;
   if (validationTest & VALID_CLASSIFICATION)
   {
      // Existing Classification object
      const Classification* pClassification = pDescriptor->getClassification();
      if (pClassification == NULL)
      {
         errorMessage = "The required classification does not exist.";
         mValidationError = VALID_CLASSIFICATION;
         return false;
      }

      // Unauthorized classification level on the system - warn the user, but continue to load the file
      FactoryResource<Classification> pSystemClassification;
      pSystemClassification->setLevel(pUtilities->getDefaultClassification());
      if (pClassification->hasGreaterLevel(pSystemClassification.get()) == true)
      {
         errorMessage = "THIS FILE CONTAINS CLASSIFIED INFORMATION WHICH SHOULD NOT BE PROCESSED ON THIS SYSTEM!\n"
            "THIS MAY CONSTITUTE A SECURITY VIOLATION WHICH SHOULD BE REPORTED TO YOUR SECURITY OFFICER!\n";
         StepResource pStep("Validate", "app", "1A881267-6A96-4eb2-A9D3-7D30334B0A0B", errorMessage);
      }
   }

   // Valid metadata
   if (validationTest & VALID_METADATA)
   {
      if (pDescriptor->getMetadata() == NULL)
      {
         errorMessage = "The required metadata does not exist.";
         mValidationError = VALID_METADATA;
         return false;
      }
   }

   // Processing location
   if (validationTest & VALID_PROCESSING_LOCATION)
   {
      if (isProcessingLocationSupported(pDescriptor->getProcessingLocation()) == false)
      {
         errorMessage = "The specified processing location is not supported.";
         mValidationError = VALID_PROCESSING_LOCATION;
         return false;
      }
   }

   // If no RasterDataDescriptor or RasterFileDescriptor tests are performed, end here
   if (validationTest < RASTER_SIZE)
   {
      return true;
   }

   // Since raster tests have been specified, always validate the raster data descriptor and raster file descriptor
   const RasterDataDescriptor* pRasterDescriptor = dynamic_cast<const RasterDataDescriptor*>(pDescriptor);
   if (pRasterDescriptor == NULL)
   {
      errorMessage = "The data set does not contain raster information.";
      return false;
   }

   const RasterFileDescriptor* pRasterFileDescriptor =
      dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor());
   if (pRasterFileDescriptor == NULL)
   {
      errorMessage = "The file does not contain valid raster data.";
      return false;
   }

   // Raster size
   if (validationTest & RASTER_SIZE)
   {
      // Data set size
      unsigned int loadedRows = pRasterDescriptor->getRowCount();
      unsigned int loadedColumns = pRasterDescriptor->getColumnCount();
      unsigned int loadedBands = pRasterDescriptor->getBandCount();

      if ((loadedRows == 0) || (loadedColumns == 0) || (loadedBands == 0))
      {
         errorMessage = "The data set is empty.  Check the size of the rows, columns, and bands.";
         mValidationError = RASTER_SIZE;
         return false;
      }

      // Pixel size
      if (pRasterFileDescriptor->getBitsPerElement() == 0)
      {
         errorMessage = "The number of bits per element is invalid.";
         mValidationError = RASTER_SIZE;
         return false;
      }
   }

   // Data type
   if (validationTest & VALID_DATA_TYPE)
   {
      const std::vector<EncodingType>& dataTypes = pRasterDescriptor->getValidDataTypes();
      if (std::find(dataTypes.begin(), dataTypes.end(), pRasterDescriptor->getDataType()) == dataTypes.end())
      {
         errorMessage = "The data type is not valid for this data set.";
         mValidationError = VALID_DATA_TYPE;
         return false;
      }
   }

   // Header bytes
   if (validationTest & NO_HEADER_BYTES)
   {
      if (pRasterFileDescriptor->getHeaderBytes() > 0)
      {
         errorMessage = "The file has an invalid number of header bytes.";
         mValidationError = NO_HEADER_BYTES;
         return false;
      }
   }

   // Preline and postline bytes
   if (validationTest & NO_PRE_POST_LINE_BYTES)
   {
      if ((pRasterFileDescriptor->getPrelineBytes() > 0) || (pRasterFileDescriptor->getPostlineBytes() > 0))
      {
         errorMessage = "The file has an invalid number of preline and/or postline bytes.";
         mValidationError = NO_PRE_POST_LINE_BYTES;
         return false;
      }
   }

   // Preband and postband bytes
   if (validationTest & NO_PRE_POST_BAND_BYTES)
   {
      if ((pRasterFileDescriptor->getPrebandBytes() > 0) || (pRasterFileDescriptor->getPostbandBytes() > 0))
      {
         errorMessage = "The file has an invalid number of preband and/or postband bytes.";
         mValidationError = NO_PRE_POST_BAND_BYTES;
         return false;
      }
   }

   // Trailer bytes
   if (validationTest & NO_TRAILER_BYTES)
   {
      if (pRasterFileDescriptor->getTrailerBytes() > 0)
      {
         errorMessage = "The file has an invalid number of trailer bytes.";
         mValidationError = NO_TRAILER_BYTES;
         return false;
      }
   }

   // File size
   int64_t requiredSize = RasterUtilities::calculateFileSize(pRasterFileDescriptor);
   if ((validationTest & FILE_SIZE) == FILE_SIZE)
   {
      // Existing file
      LargeFileResource file;
      VERIFY(file.open(filename, O_RDONLY | O_BINARY, S_IREAD) == true);

      // File size
      if (requiredSize < 0)
      {
         errorMessage = "Unable to determine the required file size.";
         mValidationError = FILE_SIZE;
         return false;
      }

      if (file.fileLength() < requiredSize)
      {
         errorMessage = "The size of the file does not match the current parameters.";
         mValidationError = FILE_SIZE;
         return false;
      }
   }

   // Band files
   const vector<const Filename*>& bandFiles = pRasterFileDescriptor->getBandFiles();
   if (validationTest & NO_BAND_FILES)
   {
      if (bandFiles.empty() == false)
      {
         errorMessage = "This data set cannot have band data in multiple files.";
         mValidationError = NO_BAND_FILES;
         return false;
      }
   }

   // Existing band files and band file sizes
   if (validationTest & EXISTING_BAND_FILES)
   {
      // Enough band files for all bands
      unsigned int numBands = pRasterFileDescriptor->getBandCount();
      if (bandFiles.size() < numBands)
      {
         errorMessage = "The number of band files specified is less than the total number of bands to be loaded.";
         mValidationError = EXISTING_BAND_FILES;
         return false;
      }

      // Invalid file for imported bands
      for (vector<const Filename*>::size_type i = 0; i < bandFiles.size(); ++i)
      {
         const Filename* pFilename = bandFiles[i];
         if (pFilename == NULL)
         {
            stringstream streamMessage;
            streamMessage << "Band filename " << i + 1 << " is missing.";
            errorMessage = streamMessage.str();
            mValidationError = EXISTING_BAND_FILES;
            return false;
         }

         // Invalid filename
         string bandFilename = pFilename->getFullPathAndName();
         if (bandFilename.empty() == true)
         {
            stringstream streamMessage;
            streamMessage << "Band filename " << i + 1 << " is invalid.";
            errorMessage = streamMessage.str();
            mValidationError = EXISTING_BAND_FILES;
            return false;
         }

         // Existing file
         LargeFileResource bandFile;
         if (!bandFile.open(bandFilename, O_RDONLY | O_BINARY, S_IREAD))
         {
            stringstream streamMessage;
            streamMessage << "Band file " << i + 1 << " does not exist.";
            errorMessage = streamMessage.str();
            mValidationError = EXISTING_BAND_FILES;
            return false;
         }

         // File size
         if ((validationTest & BAND_FILE_SIZES) == BAND_FILE_SIZES)
         {
            if (requiredSize < 0)
            {
               errorMessage = "Unable to determine the required band file size.";
               mValidationError = BAND_FILE_SIZES;
               return false;
            }

            if (bandFile.fileLength() < requiredSize)
            {
               stringstream streamMessage;
               streamMessage << "The size of band file " << i + 1 << " does not match the required size "
                  "for the current parameters.";
               errorMessage = streamMessage.str();
               mValidationError = BAND_FILE_SIZES;
               return false;
            }
         }
      }
   }

   // Band names
   const DynamicObject* pMetadata = pRasterDescriptor->getMetadata();
   if ((validationTest & VALID_BAND_NAMES) == VALID_BAND_NAMES)
   {
      VERIFY(pMetadata != NULL);

      string namesPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, NAMES_METADATA_NAME, END_METADATA_NAME };

      // If band names are present in the metadata, check the number of names against the number of bands
      // If band names are not present in the metadata, then succeed
      const vector<string>* pBandNames = dv_cast<vector<string> >(&pMetadata->getAttributeByPath(namesPath));
      if (pBandNames != NULL)
      {
         if (pBandNames->size() != pRasterFileDescriptor->getBandCount())
         {
            errorMessage = "The number of band names in the metadata does not match the number of bands.";
            mValidationError = VALID_BAND_NAMES;
            return false;
         }
      }
   }

   // Wavelengths
   if ((validationTest & VALID_WAVELENGTHS) == VALID_WAVELENGTHS)
   {
      VERIFY(pMetadata != NULL);

      // If wavelengths are present in the metadata, check the number of wavelengths against the number of bands
      // If wavelengths are not present in the metadata, then succeed
      FactoryResource<Wavelengths> pWavelengths;
      if (pWavelengths->initializeFromDynamicObject(pMetadata, false) == true)
      {
         if (pWavelengths->getNumWavelengths() != pRasterFileDescriptor->getBandCount())
         {
            errorMessage = "The number of wavelengths in the metadata does not match the number of bands.";
            mValidationError = VALID_WAVELENGTHS;
            return false;
         }
      }
   }

   // Interleave conversions
   if (validationTest & NO_INTERLEAVE_CONVERSIONS)
   {
      InterleaveFormatType dataInterleave = pRasterDescriptor->getInterleaveFormat();
      InterleaveFormatType fileInterleave = pRasterFileDescriptor->getInterleaveFormat();
      if ((pRasterFileDescriptor->getBandCount() > 1) && (dataInterleave != fileInterleave))
      {
         errorMessage = "Interleave format conversions are not supported.";
         mValidationError = NO_INTERLEAVE_CONVERSIONS;
         return false;
      }
   }

   // Skip factors
   if (validationTest & NO_ROW_SKIP_FACTOR)
   {
      if (pRasterDescriptor->getRowSkipFactor() > 0)
      {
         errorMessage = "Row skip factors are not supported.";
         mValidationError = NO_ROW_SKIP_FACTOR;
         return false;
      }
   }

   if (validationTest & NO_COLUMN_SKIP_FACTOR)
   {
      if (pRasterDescriptor->getColumnSkipFactor() > 0)
      {
         errorMessage = "Column skip factors are not supported.";
         mValidationError = NO_COLUMN_SKIP_FACTOR;
         return false;
      }
   }

   // Subsets
   if (validationTest & NO_ROW_SUBSETS)
   {
      if (pRasterDescriptor->getRowCount() != pRasterFileDescriptor->getRowCount())
      {
         errorMessage = "Row subsets are not supported.";
         mValidationError = NO_ROW_SUBSETS;
         return false;
      }
   }

   if (validationTest & NO_COLUMN_SUBSETS)
   {
      if (pRasterDescriptor->getColumnCount() != pRasterFileDescriptor->getColumnCount())
      {
         errorMessage = "Column subsets are not supported.";
         mValidationError = NO_COLUMN_SUBSETS;
         return false;
      }
   }

   if (validationTest & NO_BAND_SUBSETS)
   {
      if (pRasterDescriptor->getBandCount() != pRasterFileDescriptor->getBandCount())
      {
         errorMessage = "Band subsets are not supported.";
         mValidationError = NO_BAND_SUBSETS;
         return false;
      }
   }

   // Available memory
   if (validationTest & AVAILABLE_MEMORY)
   {
      unsigned int loadedRows = pRasterDescriptor->getRowCount();
      unsigned int loadedColumns = pRasterDescriptor->getColumnCount();
      unsigned int loadedBands = pRasterDescriptor->getBandCount();
      unsigned int bytesPerElement = pRasterDescriptor->getBytesPerElement();

      uint64_t dataSize = loadedRows * loadedColumns * loadedBands * bytesPerElement;
      uint64_t maxMemoryAvail = pUtilities->getMaxMemoryBlockSize();
#if PTR_SIZE > 4
      uint64_t totalRam = pUtilities->getTotalPhysicalMemory();
      if (totalRam < maxMemoryAvail)
      {
         maxMemoryAvail = totalRam;
      }
#endif

      if (dataSize > maxMemoryAvail)
      {
         errorMessage = "The data set cannot be loaded into memory.  Use a different "
            "processing location or specify a subset.";
         mValidationError = AVAILABLE_MEMORY;
         return false;
      }
   }

   return true;
}