isis/src/mex/apps/hrsc2isis/main.cpp
void ImportHrscStereoImage(ProcessImportPds &p, Pvl &label) {

  UserInterface &ui = Application::GetUserInterface();

  lineInFile.clear();
  numLinesSkipped = 0;

  CubeAttributeOutput outAtt(ui.GetFileName("TO"));
  outCube = new Cube();

  outCube->setByteOrder(outAtt.byteOrder());
  outCube->setFormat(outAtt.fileFormat());
  outCube->setLabelsAttached(outAtt.labelAttachment() == AttachedLabel);

  TableField ephTimeField("EphemerisTime", TableField::Double);
  TableField expTimeField("ExposureTime", TableField::Double);
  TableField lineStartField("LineStart", TableField::Integer);

  TableRecord timesRecord;
  timesRecord += ephTimeField;
  timesRecord += expTimeField;
  timesRecord += lineStartField;

  Table timesTable("LineScanTimes", timesRecord);

  p.SetDataPrefixBytes((int)label.findObject("IMAGE")["LINE_PREFIX_BYTES"]);
  p.SaveDataPrefix();

  p.Progress()->SetText("Reading Prefix Data");
  p.StartProcess(IgnoreData);

  // Get the prefix data from the Process
  // The prefix data is always in LSB format, regardless of the overall file format
  EndianSwapper swapper("LSB");

  std::vector<double> ephemerisTimes;
  std::vector<double> exposureTimes;
  std::vector< std::vector<char *> > prefix = p.DataPrefix();

  for (int line = 0; line < p.Lines(); line++) {
    double ephTime = swapper.Double((double *)prefix[0][line]);
    double expTime = swapper.Float((float *)(prefix[0][line] + 8)) / 1000.0;

    if (line > 0) {
      /**
       * We know how many skipped lines with this equation. We take the
       * difference in the current line and the last line's time, which will
       * ideally be equal to the last line's exposure duration. We divide this by
       * the last line's exposure duration, and the result is the 1-based count of
       * how many exposures there were between the last line and the current line.
       * We subtract one in order to remove the known exposure, and the remaining should
       * be the 1-based count of how many lines were skipped. Add 0.5 to round up.
       */
      int skippedLines = (int)((ephTime - ephemerisTimes.back()) / exposureTimes.back() - 1.0 + 0.5);

      for (int i = 0; i < skippedLines; i++) {
        ephemerisTimes.push_back(ephemerisTimes.back() + exposureTimes.back());
        exposureTimes.push_back(exposureTimes.back());
        lineInFile.push_back(false);
      }
    }

    ephemerisTimes.push_back(ephTime);
    exposureTimes.push_back(expTime);
    lineInFile.push_back(true);
  }

  double lastExp = 0.0;
  for (unsigned int i = 0; i < ephemerisTimes.size(); i++) {
    if (lastExp != exposureTimes[i]) {
      lastExp = exposureTimes[i];
      timesRecord[0] = ephemerisTimes[i];
      timesRecord[1] = exposureTimes[i];
      timesRecord[2] = (int)i + 1;
      timesTable += timesRecord;
    }
  }

  outCube->setDimensions(p.Samples(), lineInFile.size(), p.Bands());

  p.Progress()->SetText("Importing");
  outCube->create(ui.GetFileName("TO"));
  p.StartProcess(WriteOutput);

  outCube->write(timesTable);

  // Translate the PDS labels into ISIS labels and add them to the cube
  Pvl otherLabels;

  TranslateHrscLabels(label, otherLabels);

  if (otherLabels.hasGroup("Instrument") &&
      (otherLabels.findGroup("Instrument").keywords() > 0)) {
    outCube->putGroup(otherLabels.findGroup("Instrument"));
  }

  if (otherLabels.hasGroup("BandBin") &&
      (otherLabels.findGroup("BandBin").keywords() > 0)) {
    outCube->putGroup(otherLabels.findGroup("BandBin"));
  }

  if (otherLabels.hasGroup("Archive") &&
      (otherLabels.findGroup("Archive").keywords() > 0)) {
    outCube->putGroup(otherLabels.findGroup("Archive"));
  }

  if (otherLabels.hasGroup("Kernels") &&
      (otherLabels.findGroup("Kernels").keywords() > 0)) {
    outCube->putGroup(otherLabels.findGroup("Kernels"));
  }

  p.EndProcess();

  outCube->close();
  delete outCube;
  outCube = NULL;
  lineInFile.clear();
}
/**
 * This function reads Mars Express HRSC Stereo files
 *
 * First pass through the file is a Process called with the IgnoreData() function in order to
 * get the import class to collect prefix data. Once the prefix data is populated, we look for
 * "gaps" - HRSC files with prefix data give us a time and exposure duration for each line, we
 * look for where the time + exposure duration != next line's time. We populate a table
 * (LineScanTimes) with the prefix data and lineInFile with whether or not a missing line should
 * be inserted.
 *                                                                      
 * Second pass through the file is a Process called with the WriteOutput function. If there were
 * gaps, WriteOutput will add lines at the appropriate positions in the output cube. Finally, we
 * translate the labels and put the LineScanTimes (if necessary) in the output cube.
 *
 * This is a two-pass system for files with prefix data, one-pass for files without.
 *  
 * NOTE: Regardless of the input file's byte order IMAGE-SAMPLE_TYPE, the prefix data byte order
 * is always LSB.
 */
This function reads Mars Express HRSC Stereo files
First pass through the file is a Process called with the IgnoreData() function in order to
get the import class to collect prefix data. Once the prefix data is populated, we look for
"gaps" - HRSC files with prefix data give us a time and exposure duration for each line, we
look for where the time + exposure duration != next line's time. We populate a table
(LineScanTimes) with the prefix data and lineInFile with whether or not a missing line should
be inserted.

Second pass through the file is a Process called with the WriteOutput function. If there were
gaps, WriteOutput will add lines at the appropriate positions in the output cube. Finally, we
translate the labels and put the LineScanTimes (if necessary) in the output cube.

This is a two-pass system for files with prefix data, one-pass for files without.

Regardless of the input file's byte order IMAGE-SAMPLE_TYPE, the prefix data byte order
is always LSB.
This function reads Mars Express HRSC Stereo files First pass through the file is a Process called with the IgnoreData () function in order to get the import class to collect prefix data . Once the prefix data is populated we look for " gaps " - HRSC files with prefix data give us a time and exposure duration for each line we look for where the time + exposure duration ! = next line ' s time . We populate a table ( LineScanTimes ) with the prefix data and lineInFile with whether or not a missing line should be inserted . Second pass through the file is a Process called with the WriteOutput function . If there were gaps WriteOutput will add lines at the appropriate positions in the output cube . Finally we translate the labels and put the LineScanTimes ( if necessary ) in the output cube . This is a two - pass system for files with prefix data one - pass for files without . Regardless of the input file ' s byte order IMAGE - SAMPLE_TYPE the prefix data byte order is always LSB .
void ImportHrscStereoImage(ProcessImportPds &p, Pvl &label) {
  UserInterface &ui = Application::GetUserInterface();
  lineInFile.clear();
  numLinesSkipped = 0;
  CubeAttributeOutput outAtt(ui.GetFileName("TO"));
  outCube = new Cube();
  outCube->setByteOrder(outAtt.byteOrder());
  outCube->setFormat(outAtt.fileFormat());
  outCube->setLabelsAttached(outAtt.labelAttachment() == AttachedLabel);
  TableField ephTimeField("EphemerisTime", TableField::Double);
  TableField expTimeField("ExposureTime", TableField::Double);
  TableField lineStartField("LineStart", TableField::Integer);
  TableRecord timesRecord;
  timesRecord += ephTimeField;
  timesRecord += expTimeField;
  timesRecord += lineStartField;
  Table timesTable("LineScanTimes", timesRecord);
  p.SetDataPrefixBytes((int)label.findObject("IMAGE")["LINE_PREFIX_BYTES"]);
  p.SaveDataPrefix();
  p.Progress()->SetText("Reading Prefix Data");
  p.StartProcess(IgnoreData);
  EndianSwapper swapper("LSB");
  std::vector<double> ephemerisTimes;
  std::vector<double> exposureTimes;
  std::vector< std::vector<char *> > prefix = p.DataPrefix();
  for (int line = 0; line < p.Lines(); line++) {
    double ephTime = swapper.Double((double *)prefix[0][line]);
    double expTime = swapper.Float((float *)(prefix[0][line] + 8)) / 1000.0;
    if (line > 0) {
      int skippedLines = (int)((ephTime - ephemerisTimes.back()) / exposureTimes.back() - 1.0 + 0.5);
      for (int i = 0; i < skippedLines; i++) {
        ephemerisTimes.push_back(ephemerisTimes.back() + exposureTimes.back());
        exposureTimes.push_back(exposureTimes.back());
        lineInFile.push_back(false);
      }
    }
    ephemerisTimes.push_back(ephTime);
    exposureTimes.push_back(expTime);
    lineInFile.push_back(true);
  }
  double lastExp = 0.0;
  for (unsigned int i = 0; i < ephemerisTimes.size(); i++) {
    if (lastExp != exposureTimes[i]) {
      lastExp = exposureTimes[i];
      timesRecord[0] = ephemerisTimes[i];
      timesRecord[1] = exposureTimes[i];
      timesRecord[2] = (int)i + 1;
      timesTable += timesRecord;
    }
  }
  outCube->setDimensions(p.Samples(), lineInFile.size(), p.Bands());
  p.Progress()->SetText("Importing");
  outCube->create(ui.GetFileName("TO"));
  p.StartProcess(WriteOutput);
  outCube->write(timesTable);
  Pvl otherLabels;
  TranslateHrscLabels(label, otherLabels);
  if (otherLabels.hasGroup("Instrument") &&
      (otherLabels.findGroup("Instrument").keywords() > 0)) {
    outCube->putGroup(otherLabels.findGroup("Instrument"));
  }
  if (otherLabels.hasGroup("BandBin") &&
      (otherLabels.findGroup("BandBin").keywords() > 0)) {
    outCube->putGroup(otherLabels.findGroup("BandBin"));
  }
  if (otherLabels.hasGroup("Archive") &&
      (otherLabels.findGroup("Archive").keywords() > 0)) {
    outCube->putGroup(otherLabels.findGroup("Archive"));
  }
  if (otherLabels.hasGroup("Kernels") &&
      (otherLabels.findGroup("Kernels").keywords() > 0)) {
    outCube->putGroup(otherLabels.findGroup("Kernels"));
  }
  p.EndProcess();
  outCube->close();
  delete outCube;
  outCube = NULL;
  lineInFile.clear();
}
void ImportHrscStereoImage ( ProcessImportPds & p , Pvl & label ) { UserInterface & ui = Application :: GetUserInterface ( ) ; lineInFile . clear ( ) ; numLinesSkipped = 0 ; CubeAttributeOutput outAtt ( ui . GetFileName ( " " ) ) ; outCube = new Cube ( ) ; outCube -> setByteOrder ( outAtt . byteOrder ( ) ) ; outCube -> setFormat ( outAtt . fileFormat ( ) ) ; outCube -> setLabelsAttached ( outAtt . labelAttachment ( ) == AttachedLabel ) ; TableField ephTimeField ( " " , TableField :: Double ) ; TableField expTimeField ( " " , TableField :: Double ) ; TableField lineStartField ( " " , TableField :: Integer ) ; TableRecord timesRecord ; timesRecord += ephTimeField ; timesRecord += expTimeField ; timesRecord += lineStartField ; Table timesTable ( " " , timesRecord ) ; p . SetDataPrefixBytes ( ( int ) label . findObject ( " " ) [ " " ] ) ; p . SaveDataPrefix ( ) ; p . Progress ( ) -> SetText ( " " ) ; p . StartProcess ( IgnoreData ) ; EndianSwapper swapper ( " " ) ; std :: vector < double > ephemerisTimes ; std :: vector < double > exposureTimes ; std :: vector < std :: vector < char * > > prefix = p . DataPrefix ( ) ; for ( int line = 0 ; line < p . Lines ( ) ; line ++ ) { double ephTime = swapper . Double ( ( double * ) prefix [ 0 ] [ line ] ) ; double expTime = swapper . Float ( ( float * ) ( prefix [ 0 ] [ line ] + 8 ) ) / 1000.0 ; if ( line > 0 ) { int skippedLines = ( int ) ( ( ephTime - ephemerisTimes . back ( ) ) / exposureTimes . back ( ) - 1.0 + 0.5 ) ; for ( int i = 0 ; i < skippedLines ; i ++ ) { ephemerisTimes . push_back ( ephemerisTimes . back ( ) + exposureTimes . back ( ) ) ; exposureTimes . push_back ( exposureTimes . back ( ) ) ; lineInFile . push_back ( false ) ; } } ephemerisTimes . push_back ( ephTime ) ; exposureTimes . push_back ( expTime ) ; lineInFile . push_back ( true ) ; } double lastExp = 0.0 ; for ( unsigned int i = 0 ; i < ephemerisTimes . size ( ) ; i ++ ) { if ( lastExp != exposureTimes [ i ] ) { lastExp = exposureTimes [ i ] ; timesRecord [ 0 ] = ephemerisTimes [ i ] ; timesRecord [ 1 ] = exposureTimes [ i ] ; timesRecord [ 2 ] = ( int ) i + 1 ; timesTable += timesRecord ; } } outCube -> setDimensions ( p . Samples ( ) , lineInFile . size ( ) , p . Bands ( ) ) ; p . Progress ( ) -> SetText ( " " ) ; outCube -> create ( ui . GetFileName ( " " ) ) ; p . StartProcess ( WriteOutput ) ; outCube -> write ( timesTable ) ; Pvl otherLabels ; TranslateHrscLabels ( label , otherLabels ) ; if ( otherLabels . hasGroup ( " " ) && ( otherLabels . findGroup ( " " ) . keywords ( ) > 0 ) ) { outCube -> putGroup ( otherLabels . findGroup ( " " ) ) ; } if ( otherLabels . hasGroup ( " " ) && ( otherLabels . findGroup ( " " ) . keywords ( ) > 0 ) ) { outCube -> putGroup ( otherLabels . findGroup ( " " ) ) ; } if ( otherLabels . hasGroup ( " " ) && ( otherLabels . findGroup ( " " ) . keywords ( ) > 0 ) ) { outCube -> putGroup ( otherLabels . findGroup ( " " ) ) ; } if ( otherLabels . hasGroup ( " " ) && ( otherLabels . findGroup ( " " ) . keywords ( ) > 0 ) ) { outCube -> putGroup ( otherLabels . findGroup ( " " ) ) ; } p . EndProcess ( ) ; outCube -> close ( ) ; delete outCube ; outCube = NULL ; lineInFile . clear ( ) ; }
This function reads Mars Express HRSC Stereo files
 First pass through the file is a Process called with the IgnoreData() function in order to
 get the import class to collect prefix data.
This function reads Mars Express HRSC Stereo files First pass through the file is a Process called with the IgnoreData () function in order to get the import class to collect prefix data .
// Get the prefix data from the Process // The prefix data is always in LSB format, regardless of the overall file format /**
       * We know how many skipped lines with this equation. We take the
       * difference in the current line and the last line's time, which will
       * ideally be equal to the last line's exposure duration. We divide this by
       * the last line's exposure duration, and the result is the 1-based count of
       * how many exposures there were between the last line and the current line.
       * We subtract one in order to remove the known exposure, and the remaining should
       * be the 1-based count of how many lines were skipped. Add 0.5 to round up.
       */ // Translate the PDS labels into ISIS labels and add them to the cube