USGS

Isis 3.0 Object Programmers' Reference

Home

ProcessExportPds.cpp
1 
19 #include "ProcessExportPds.h"
20 
21 #include <cmath>
22 #include <iostream>
23 #include <sstream>
24 
25 #include "Endian.h"
26 #include "ExportPdsTable.h"
27 #include "FileName.h"
28 #include "IException.h"
29 #include "IString.h"
30 #include "PixelType.h"
31 #include "Projection.h"
32 #include "ProjectionFactory.h"
33 #include "Pvl.h"
34 #include "PvlFormat.h"
35 #include "PvlTranslationManager.h"
36 #include "PvlFormatPds.h"
37 #include "SpecialPixel.h"
38 #include "Table.h"
39 
40 
41 using namespace std;
42 
43 namespace Isis {
48  ProcessExportPds::ProcessExportPds() {
49  m_label = NULL;
50  m_formatter = NULL;
51  m_exportType = Stream;
52  m_exportResolution = Meter;
53 
54  m_forceBands = true;
55  m_forceBandName = true;
56  m_forceCenterFilterWavelength = true;
57  m_forceBandwidth = true;
58  m_forceBandStorageType = true;
59  m_forceOffset = true;
60  m_forceScalingFactor = true;
61  m_forceSampleBits = true;
62  m_forceSampleBitMask = true;
63  m_forceSampleType = true;
64  m_forceCoreNull = true;
65  m_forceCoreLrs = true;
66  m_forceCoreLis = true;
67  m_forceCoreHrs = true;
68  m_forceCoreHis = true;
69  m_detachedLabel = false;
70 
71  m_pdsFileType = Image;
72  m_tableRecords.clear();
73  m_tableBuffers.clear();
74  }
75 
80  ProcessExportPds::~ProcessExportPds() {
81  delete m_label;
82  delete m_formatter;
83  for (unsigned int i = 0; i < m_tableBuffers.size(); i++) {
84  delete [] m_tableBuffers[i];
85  m_tableBuffers[i] = NULL;
86  }
87  m_tableBuffers.clear();
88  }
89 
104  Pvl &ProcessExportPds::StandardPdsLabel(ProcessExportPds::PdsFileType type) {
105  m_label = new Pvl;
106 
107  m_pdsFileType = type;
108  if(m_pdsFileType == ProcessExportPds::JP2Image) {
109  setFormat(JP2);
110  }
111 
112  m_formatter = new PvlFormatPds("$base/translations/pdsExportRootGen.typ");
113  m_label->setFormat(m_formatter);
114  m_label->setTerminator("END");
115 
116  if(type == ProcessExportPds::Image || type == ProcessExportPds::JP2Image) {
117  CreateImageLabel();
118  }
119  else {
120  QString msg = "Unsupported PDS output type";
121  throw IException(IException::User, msg, _FILEINFO_);
122  }
123 
124  return *m_label;
125  }
126 
127 
131  void ProcessExportPds::CreateImageLabel() {
132 
133  Pvl &mainPvl = *m_label;
134 
135  if(m_exportType == Stream) {
136  if(m_pdsFileType == ProcessExportPds::Image) {
137  StreamImageRoot(mainPvl);
138  }
139  else if(m_pdsFileType == ProcessExportPds::JP2Image) {
140  StreamJP2ImageRoot(mainPvl);
141  }
142  }
143  else if(m_exportType == Fixed) {
144  if(m_pdsFileType == ProcessExportPds::Image) {
145  FixedImageRoot(mainPvl);
146  }
147  else if(m_pdsFileType == ProcessExportPds::JP2Image) {
148  FixedJP2ImageRoot(mainPvl);
149  }
150  }
151  else {
152  QString msg = "Invalid PDS export type";
153  throw IException(IException::Programmer, msg, _FILEINFO_);
154  }
155 
156  if(m_pdsFileType == ProcessExportPds::JP2Image) {
157  StandardJP2Image(mainPvl);
158  }
159  else {
160  StandardImageImage(mainPvl);
161  }
162 
163  // The IMAGE_MAP_PROJECTION group is located in the ROOT for PDS IMAGEs. The
164  // standard routines will add the IMAGE_MAP_PROJECTION correctly
165  StandardAllMapping(mainPvl);
166  mainPvl.format()->add("$base/translations/pdsExportAllMapping.typ");
167  }
168 
169 
173  void ProcessExportPds::CreateQubeLabel() {
174  Pvl &mainPvl = *m_label;
175 
176 // StandardQubeRoot (mainPvl);
177 // StandardQubeQube (mainPvl);
178 
179  // The IMAGE_MAP_PROJECTION group is located inside the QUBE object for PDS
180  // QUBEs. Create a temporary PVL so the StandardAllMapping member can add an
181  // IMAGE_MAP_PROJECTION group then later it can be extracted and added to
182  // the output PDS label.
183  Pvl mapTmp;
184  StandardAllMapping(mapTmp);
185  if(mapTmp.hasObject("IMAGE_MAP_PROJECTION")) {
186  mainPvl.findObject("QUBE").addObject(mapTmp.findObject("IMAGE_MAP_PROJECTION"));
187  }
188  }
189 
190 
194  void ProcessExportPds::CreateSpectralQubeLabel() {
195  Pvl &mainPvl = *m_label;
196 
197 // StandardSpectralQubeRoot (mainPvl);
198 // StandardSpectralQubeSpectralQube (mainPvl);
199 
200  // The IMAGE_MAP_PROJECTION group is located inside the SPECTRAL_QUBE object
201  // for PDS SPECTRAL_QUBEs. Create a temporary PVL so the StandardAllMapping
202  // member can add an IMAGE_MAP_PROJECTION group then later it can be
203  // extracted and added to the output PDS label.
204  Pvl mapTmp;
205  StandardAllMapping(mapTmp);
206  if(mapTmp.hasObject("IMAGE_MAP_PROJECTION")) {
207  mainPvl.findObject("QUBE").addObject(mapTmp.findObject("IMAGE_MAP_PROJECTION"));
208  }
209  }
210 
211 
217  void ProcessExportPds::StreamImageRoot(Pvl &mainPvl) {
218  // Create standard ROOT object keywords
219  mainPvl += PvlKeyword("PDS_VERSION_ID", "PDS3");
220  mainPvl += PvlKeyword("RECORD_TYPE", "UNDEFINED");
221  // NOTE: WARNING: If the number of "?"s in the next few lines changes, you
222  // must also changes the corresponding lines in the OutputLabel member
223  mainPvl += PvlKeyword("LABEL_RECORDS", "???????", "BYTES");
224  if(m_detachedLabel) {
225  QString sImageFile = m_detachedPdsLabelFile;
226  int iFound = sImageFile.indexOf(".lbl");
227  if(iFound != -1) {
228  sImageFile.replace(iFound, 4, ".img");
229  }
230  else {
231  sImageFile += ".img";
232  }
233  FileName outFile(sImageFile);
234  mainPvl += PvlKeyword("^IMAGE", outFile.name());
235  }
236  else {
237  mainPvl += PvlKeyword("^IMAGE", "???????", "BYTES");
238  }
239  }
240 
241 
247  void ProcessExportPds::StreamJP2ImageRoot(Pvl &mainPvl) {
248  mainPvl.format()->add("$base/translations/pdsExportImageJP2.typ");
249  // Create standard ROOT object keywords
250  mainPvl += PvlKeyword("PDS_VERSION_ID", "PDS3");
251  QString sImageFile = m_detachedPdsLabelFile;
252  if(m_detachedLabel) {
253  int iFound = sImageFile.indexOf(".lbl");
254  if(iFound != -1) {
255  sImageFile.replace(iFound, 4, ".jp2");
256  }
257  else {
258  sImageFile += ".jp2";
259  }
260  }
261  else {
262  QString msg = "Labels must be detached for JP2 files";
263  throw IException(IException::Programmer, msg, _FILEINFO_);
264  }
265  FileName outFile(sImageFile);
266  PvlObject cmpObj("COMPRESSED_FILE");
267  cmpObj += PvlKeyword("FILE_NAME", outFile.name());
268  cmpObj += PvlKeyword("RECORD_TYPE", "UNDEFINED");
269  cmpObj += PvlKeyword("ENCODING_TYPE", "JP2");
270  cmpObj += PvlKeyword("ENCODING_TYPE_VERSION_NAME", "ISO/IEC15444-1:2004");
271  cmpObj += PvlKeyword("INTERCHANGE_FORMAT", "BINARY");
272  FileName infilename(InputCubes[0]->fileName());
273  cmpObj += PvlKeyword("UNCOMPRESSED_FILE_NAME", infilename.name());
274  int storagebytes = InputCubes[0]->sampleCount() * InputCubes[0]->lineCount();
275  if(p_pixelType == Isis::Real) {
276  QString msg = "JPEG2000 does not support floating point data";
277  throw IException(IException::Programmer, msg, _FILEINFO_);
278  }
279  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
280  storagebytes = storagebytes * 2;
281  }
282  cmpObj += PvlKeyword("REQUIRED_STORAGE_BYTES", toString(storagebytes));
283  mainPvl.addObject(cmpObj);
284  PvlObject ucmpObj("UNCOMPRESSED_FILE");
285  ucmpObj += PvlKeyword("FILE_NAME", infilename.name());
286  ucmpObj += PvlKeyword("RECORD_TYPE", "FIXED_LENGTH");
287  int recordbytes = InputCubes[0]->sampleCount();
288  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
289  recordbytes = recordbytes * 2;
290  }
291  ucmpObj += PvlKeyword("RECORD_BYTES", toString(recordbytes));
292  ucmpObj += PvlKeyword("FILE_RECORDS", toString(InputCubes[0]->lineCount()));
293  ucmpObj += PvlKeyword("^IMAGE", infilename.name());
294  mainPvl.addObject(ucmpObj);
295  }
296 
297 
303  void ProcessExportPds::FixedImageRoot(Pvl &mainPvl) {
304  //Create fixed ROOT object keywords
305  mainPvl += PvlKeyword("PDS_VERSION_ID", "PDS3");
306  mainPvl += PvlKeyword("RECORD_TYPE", "FIXED_LENGTH");
307  // NOTE: WARNING: If the number of "?"s in the next few lines changes, you
308  // must also changes the corresponding lines in the OutputLabel member
309  mainPvl += PvlKeyword("RECORD_BYTES", "???????");
310  mainPvl += PvlKeyword("FILE_RECORDS", "???????");
311  mainPvl += PvlKeyword("LABEL_RECORDS", "????");
312  if(m_detachedLabel) {
313  QString sImageFile = m_detachedPdsLabelFile;
314  int iFound = sImageFile.indexOf(".lbl");
315  if(iFound != -1) {
316  sImageFile.replace(iFound, 4, ".img");
317  }
318  else {
319  sImageFile += ".img";
320  }
321  FileName outFile(sImageFile);
322  mainPvl += PvlKeyword("^IMAGE", outFile.name());
323  }
324  else {
325  mainPvl += PvlKeyword("^IMAGE", "???");
326  }
327  }
328 
329 
335  void ProcessExportPds::FixedJP2ImageRoot(Pvl &mainPvl) {
336  mainPvl.format()->add("$base/translations/pdsExportImageJP2.typ");
337  //Create fixed ROOT object keywords
338  mainPvl += PvlKeyword("PDS_VERSION_ID", "PDS3");
339  QString sImageFile = m_detachedPdsLabelFile;
340  if(m_detachedLabel) {
341  int iFound = sImageFile.indexOf(".lbl");
342  if(iFound != -1) {
343  sImageFile.replace(iFound, 4, ".jp2");
344  }
345  else {
346  sImageFile += ".jp2";
347  }
348  }
349  else {
350  QString msg = "Labels must be detached for JP2 files";
351  throw IException(IException::Programmer, msg, _FILEINFO_);
352  }
353  FileName outFile(sImageFile);
354  PvlObject cmpObj("COMPRESSED_FILE");
355  cmpObj += PvlKeyword("FILE_NAME", outFile.name());
356  cmpObj += PvlKeyword("RECORD_TYPE", "UNDEFINED");
357  cmpObj += PvlKeyword("ENCODING_TYPE", "JP2");
358  cmpObj += PvlKeyword("ENCODING_TYPE_VERSION_NAME", "ISO/IEC15444-1:2004");
359  cmpObj += PvlKeyword("INTERCHANGE_FORMAT", "BINARY");
360  FileName infilename(InputCubes[0]->fileName());
361  cmpObj += PvlKeyword("UNCOMPRESSED_FILE_NAME", infilename.name());
362  int storagebytes = InputCubes[0]->sampleCount() * InputCubes[0]->lineCount();
363  if(p_pixelType == Isis::Real) {
364  QString msg = "JPEG2000 does not support floating point data";
365  throw IException(IException::Programmer, msg, _FILEINFO_);
366  }
367  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
368  storagebytes = storagebytes * 2;
369  }
370  cmpObj += PvlKeyword("REQUIRED_STORAGE_BYTES", toString(storagebytes));
371  mainPvl.addObject(cmpObj);
372  PvlObject ucmpObj("UNCOMPRESSED_FILE");
373  ucmpObj += PvlKeyword("FILE_NAME", infilename.name());
374  ucmpObj += PvlKeyword("RECORD_TYPE", "FIXED_LENGTH");
375  int recordbytes = InputCubes[0]->sampleCount();
376  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
377  recordbytes = recordbytes * 2;
378  }
379  ucmpObj += PvlKeyword("RECORD_BYTES", toString(recordbytes));
380  ucmpObj += PvlKeyword("FILE_RECORDS", toString(InputCubes[0]->lineCount()));
381  ucmpObj += PvlKeyword("^IMAGE", infilename.name());
382  mainPvl.addObject(ucmpObj);
383  }
384 
385 
395  void ProcessExportPds::StandardImageImage(Pvl &mainPvl) {
396  mainPvl.format()->add("$base/translations/pdsExportImageImage.typ");
397  // Build up an IMAGE object:
398  // Auto translate standard keywords for the IMAGE object
399  Pvl *inputLabel = InputCubes[0]->label();
400  FileName transfile;
401  transfile = "$base/translations/pdsExportImageImage.trn";
402  PvlTranslationManager Xlator(*inputLabel, transfile.expanded());
403  Xlator.Auto(mainPvl);
404 
405  // Calculate the core base/mult for this cube
406  double base = 0.0;
407  double multiplier = 1.0;
408  double x1, x2;
409 
410  double minimum = (p_inputMinimum.size()) ? p_inputMinimum[0] : 0.0;
411  double maximum = (p_inputMaximum.size()) ? p_inputMaximum[0] : 0.0;
412 
413  for(unsigned int i = 0; i < p_inputMinimum.size(); i ++) {
414  minimum = std::min(minimum, p_inputMinimum[i]);
415  maximum = std::max(maximum, p_inputMaximum[i]);
416  }
417 
418  x1 = p_outputMinimum;
419  x2 = p_outputMaximum;
420 
421  if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedByte) {
422  multiplier = (maximum - minimum) / (x2 - x1);
423  base = minimum - multiplier * x1;
424  }
425  else if(p_inputMinimum.size() && p_pixelType == Isis::SignedWord) {
426  multiplier = (maximum - minimum) / (x2 - x1);
427  base = minimum - multiplier * x1;
428  }
429  else if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedWord) {
430  multiplier = (maximum - minimum) / (x2 - x1);
431  base = minimum - multiplier * x1;
432  }
433 
434  // Manually set the keyword for the number of bits in a pixel
435  // NOTE: this is dependent on settings in ProcessExport and not the cube
436  PvlObject &imgObj = mainPvl.findObject("IMAGE");
437 
438  if(!m_forceBands) imgObj.deleteKeyword("BANDS");
439  if(!m_forceBandName && imgObj.hasKeyword("BAND_NAME")) imgObj.deleteKeyword("BAND_NAME");
440  if(!m_forceCenterFilterWavelength && imgObj.hasKeyword("CENTER_FILTER_WAVELENGTH")) imgObj.deleteKeyword("CENTER_FILTER_WAVELENGTH");
441  if(!m_forceBandwidth && imgObj.hasKeyword("BANDWIDTH")) imgObj.deleteKeyword("BANDWIDTH");
442 
443  if(m_forceBandStorageType) imgObj += PvlKeyword("BAND_STORAGE_TYPE", "BAND_SEQUENTIAL");
444  if(m_forceOffset) imgObj += PvlKeyword("OFFSET", toString(base));
445  if(m_forceScalingFactor) imgObj += PvlKeyword("SCALING_FACTOR", toString(multiplier));
446 
447  // Manually set the keyword for pixel type and special pixels
448  if(p_pixelType == Isis::UnsignedByte) {
449  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "8");
450  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xff));
451  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
452  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
453  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
454  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
455  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
456  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
457  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel8.typ");
458  }
459  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Msb)) {
460  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
461  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
462  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
463  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
464  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
465  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
466  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
467  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
468  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
469  }
470  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Lsb)) {
471  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
472  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
473  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_UNSIGNED_INTEGER");
474  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
475  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
476  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
477  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
478  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
479  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
480  }
481  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Msb)) {
482  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
483  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
484  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_INTEGER");
485  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
486  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
487  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
488  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
489  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
490  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
491  }
492  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Lsb)) {
493  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
494  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffff));
495  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_INTEGER");
496  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
497  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
498  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
499  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
500  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
501  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
502  }
503  else if(p_pixelType == Isis::Real) {
504  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "32");
505  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffffffff));
506 
507  if(p_endianType == Isis::Msb) {
508  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "IEEE_REAL");
509  }
510  else {
511  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "PC_REAL");
512  }
513  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString(Isis::INULL4));
514  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString(Isis::ILOW_REPR_SAT4));
515  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString(Isis::ILOW_INSTR_SAT4));
516  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString(Isis::IHIGH_REPR_SAT4));
517  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString(Isis::IHIGH_INSTR_SAT4));
518  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel32.typ");
519  }
520  else {
521  QString msg = "Unsupported PDS pixel type or sample size";
522  throw IException(IException::User, msg, _FILEINFO_);
523  }
524  }
525 
526 
536  void ProcessExportPds::StandardJP2Image(Pvl &mainPvl) {
537  mainPvl.format()->add("$base/translations/pdsExportImageImage.typ");
538  if(m_pdsFileType == ProcessExportPds::JP2Image) {
539  mainPvl.format()->add("$base/translations/pdsExportImageJP2.typ");
540  }
541  // Build up a JP2 IMAGE object:
542  // Auto translate standard keywords for the IMAGE object
543  Pvl *inputLabel = InputCubes[0]->label();
544  FileName transfile;
545  transfile = "$base/translations/pdsExportImageJP2.trn";
546  PvlTranslationManager Xlator(*inputLabel, transfile.expanded());
547  Xlator.Auto(mainPvl);
548 
549  // Calculate the core base/mult for this cube
550  double base = 0.0;
551  double multiplier = 1.0;
552  double x1, x2;
553 
554  double minimum = (p_inputMinimum.size()) ? p_inputMinimum[0] : 0.0;
555  double maximum = (p_inputMaximum.size()) ? p_inputMaximum[0] : 0.0;
556 
557  for(unsigned int i = 0; i < p_inputMinimum.size(); i ++) {
558  minimum = std::min(minimum, p_inputMinimum[i]);
559  maximum = std::max(maximum, p_inputMaximum[i]);
560  }
561 
562  x1 = p_outputMinimum;
563  x2 = p_outputMaximum;
564 
565  if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedByte) {
566  multiplier = (maximum - minimum) / (x2 - x1);
567  base = minimum - multiplier * x1;
568  }
569  else if(p_inputMinimum.size() && p_pixelType == Isis::SignedWord) {
570  multiplier = (maximum - minimum) / (x2 - x1);
571  base = minimum - multiplier * x1;
572  }
573  else if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedWord) {
574  multiplier = (maximum - minimum) / (x2 - x1);
575  base = minimum - multiplier * x1;
576  }
577 
578  // Manually set the keyword for the number of bits in a pixel
579  // NOTE: this is dependent on settings in ProcessExport and not the cube
580  PvlObject &imgObj = mainPvl.findObject("UNCOMPRESSED_FILE").findObject("IMAGE");
581 
582  if(!m_forceBands) imgObj.deleteKeyword("BANDS");
583  if(!m_forceBandName && imgObj.hasKeyword("BAND_NAME")) imgObj.deleteKeyword("BAND_NAME");
584  if(!m_forceCenterFilterWavelength && imgObj.hasKeyword("CENTER_FILTER_WAVELENGTH")) imgObj.deleteKeyword("CENTER_FILTER_WAVELENGTH");
585  if(!m_forceBandwidth && imgObj.hasKeyword("BANDWIDTH")) imgObj.deleteKeyword("BANDWIDTH");
586 
587  if(m_forceBandStorageType) imgObj += PvlKeyword("BAND_STORAGE_TYPE", "BAND_SEQUENTIAL");
588  if(m_forceOffset) imgObj += PvlKeyword("OFFSET", toString(base));
589  if(m_forceScalingFactor) imgObj += PvlKeyword("SCALING_FACTOR", toString(multiplier));
590 
591  // Manually set the keyword for pixel type and special pixels
592  if(p_pixelType == Isis::UnsignedByte) {
593  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "8");
594  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xff));
595  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
596  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
597  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
598  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
599  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
600  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
601  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel8.typ");
602  }
603  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Msb)) {
604  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
605  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
606  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
607  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
608  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
609  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
610  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
611  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
612  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
613  }
614  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Lsb)) {
615  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
616  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
617  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_UNSIGNED_INTEGER");
618  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
619  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
620  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
621  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
622  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
623  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
624  }
625  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Msb)) {
626  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
627  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
628  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_INTEGER");
629  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
630  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
631  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
632  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
633  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
634  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
635  }
636  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Lsb)) {
637  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
638  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffff));
639  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_INTEGER");
640  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
641  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
642  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
643  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
644  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
645  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
646  }
647  else if(p_pixelType == Isis::Real) {
648  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "32");
649  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffffffff));
650 
651  if(p_endianType == Isis::Msb) {
652  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "IEEE_REAL");
653  }
654  else {
655  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "PC_REAL");
656  }
657  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString(Isis::INULL4));
658  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString(Isis::ILOW_REPR_SAT4));
659  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString(Isis::ILOW_INSTR_SAT4));
660  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString(Isis::IHIGH_REPR_SAT4));
661  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString(Isis::IHIGH_INSTR_SAT4));
662  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel32.typ");
663  }
664  else {
665  QString msg = "Unsupported PDS pixel type or sample size";
666  throw IException(IException::User, msg, _FILEINFO_);
667  }
668  }
669 
670 
679  void ProcessExportPds::StandardAllMapping(Pvl &outputPvl) {
680 
681  // Get the input Isis cube label and find the Mapping group if it has one
682  Pvl *inputLabel = InputCubes[0]->label();
683  if(inputLabel->hasObject("IsisCube") &&
684  !(inputLabel->findObject("IsisCube").hasGroup("Mapping"))) return;
685  PvlGroup &inputMapping = inputLabel->findGroup("Mapping", Pvl::Traverse);
686  // Translate the common keywords for a PDS IMAGE_MAP_PROJECTION
687  PvlTranslationManager xlatGenProj(*inputLabel,
688  "$base/translations/pdsExportAllMapping.trn");
689  xlatGenProj.Auto(outputPvl);
690 
691  // Translate the projection specific keywords for a PDS IMAGE_MAP_PROJECTION
692  QString projName = ProjectionName(*inputLabel);
693  PvlTranslationManager xlatSpecProj(*inputLabel,
694  "$base/translations/pdsExport" + projName + ".trn");
695  xlatSpecProj.Auto(outputPvl);
696 
697  // Translate the target name
698  PvlTranslationManager xlatTarget(*inputLabel,
699  "$base/translations/pdsExportTarget.trn");
700  xlatTarget.Auto(outputPvl);
701 
702  // Add keywords to the PDS labels that could not be handled automatically
703  PvlObject &pdsMapObj = outputPvl.findObject("IMAGE_MAP_PROJECTION");
704 
705  // Add the projection name
706 // pdsMapObj += PvlKeyword ("MAP_PROJECTION_TYPE", projName.toUpper());
707 
708  // Modify the radii to be km.
709  PvlKeyword &aRadius = pdsMapObj["A_AXIS_RADIUS"];
710  QString unit = aRadius.unit();
711  if( (unit.toUpper() == "METERS") || (unit == "") ) { //if no units, assume in meters
712  double dValue = (double)aRadius;
713  dValue /= 1000.0;
714  aRadius.setValue(toString(dValue), "KM");
715  }
716  PvlKeyword &bRadius = pdsMapObj["B_AXIS_RADIUS"];
717  unit = bRadius.unit();
718  if( (unit.toUpper() == "METERS") || (unit == "") ) {
719  double dValue = (double)bRadius;
720  dValue /= 1000.0;
721  bRadius.setValue(toString(dValue), "KM");
722  }
723  PvlKeyword &cRadius = pdsMapObj["C_AXIS_RADIUS"];
724  unit = cRadius.unit();
725  if( (unit.toUpper() == "METERS") || (unit == "") ) {
726  double dValue = (double)cRadius;
727  dValue /= 1000.0;
728  cRadius.setValue(toString(dValue), "KM");
729  }
730 
731  // Modify the units on MAP_SCALE and MAP_RESOLUTION
732  PvlKeyword &mapScale = pdsMapObj["MAP_SCALE"];
733  unit = mapScale.unit();
734  //if no units, assume in meters/pixel
735  if( (unit.toUpper() == "METERS/PIX") || (unit.toUpper() == "METERS/PIXEL") || (unit == "") ) {
736  if(m_exportResolution == Kilometer) {
737  double dValue = (double)mapScale;
738  dValue /= 1000.0;
739  mapScale.setValue(toString(dValue), "KM/PIXEL");
740  }
741  else {
742  mapScale.setValue(toString((double)mapScale), "METERS/PIXEL");
743  }
744  }
745  PvlKeyword &mapRes = pdsMapObj["MAP_RESOLUTION"];
746  unit = mapRes.unit();
747  //if no units, asume in pixels/degree
748  if( (unit.toUpper() == "PIXELS/DEGREE") || (unit == "") ) {
749  mapRes.setValue((QString)mapRes, "PIX/DEG");
750  }
751 
752  // Add the EASTERNMOST AND WESTERNMOST LONGITUDE keywords
753  PvlKeyword &isisLonDir = inputMapping.findKeyword("LongitudeDirection");
754  QString lonDir = isisLonDir[0];
755  lonDir = lonDir.toUpper();
756  if(lonDir == "POSITIVEEAST") {
757  double maxLon = inputMapping.findKeyword("MaximumLongitude");
758  pdsMapObj += PvlKeyword("EASTERNMOST_LONGITUDE", toString(maxLon));
759  double minLon = inputMapping.findKeyword("MinimumLongitude");
760  pdsMapObj += PvlKeyword("WESTERNMOST_LONGITUDE", toString(minLon));
761  }
762  else {
763  double minLon = inputMapping.findKeyword("MinimumLongitude");
764  pdsMapObj += PvlKeyword("EASTERNMOST_LONGITUDE", toString(minLon));
765  double maxLon = inputMapping.findKeyword("MaximumLongitude");
766  pdsMapObj += PvlKeyword("WESTERNMOST_LONGITUDE", toString(maxLon));
767  }
768 
769  // Add the LINE_PROJECTION_OFFSET and SAMPLE_PROJECTION_OFFSET keywords
770  // These keywords are the distance from the origin of the image to the
771  // origin of the projection. The units are line or samples. The image origin
772  // is the middle of pixel (1,1)
773  double lineOffset = inputMapping.findKeyword("UpperLeftCornerY");
774  lineOffset /= (double)inputMapping.findKeyword("PixelResolution");
775  lineOffset *= 1.0;
776  lineOffset += 0.5; // Add half a line to get to the center of (1,1)
777  pdsMapObj += PvlKeyword("LINE_PROJECTION_OFFSET", toString(lineOffset), "PIXEL");
778  double sampleOffset = inputMapping.findKeyword("UpperLeftCornerX");
779  sampleOffset /= (double)inputMapping.findKeyword("PixelResolution");
780  sampleOffset *= -1.0;
781  sampleOffset += 0.5; // Add half a sample to get to the center of (1,1)
782  pdsMapObj += PvlKeyword("SAMPLE_PROJECTION_OFFSET", toString(sampleOffset), "PIXEL");
783 
784  // Add units to keywords already in the IMAGE_MAP_PROJECTION object as necessary
785  if(pdsMapObj.hasKeyword("CENTER_LATITUDE")) {
786  PvlKeyword &tempKey = pdsMapObj.findKeyword("CENTER_LATITUDE");
787  tempKey.setValue(tempKey[0], "DEG");
788  }
789  if(pdsMapObj.hasKeyword("CENTER_LONGITUDE")) {
790  PvlKeyword &tempKey = pdsMapObj.findKeyword("CENTER_LONGITUDE");
791  tempKey.setValue(tempKey[0], "DEG");
792  }
793 // if (pdsMapObj.hasKeyword("REFERENCE_LATITUDE")) {
794 // PvlKeyword &tempKey = pdsMapObj.findKeyword("REFERENCE_LATITUDE");
795 // tempKey.setValue(tempKey[0], "DEG");
796 // }
797  if(pdsMapObj.hasKeyword("REFERENCE_LONGITUDE")) {
798  PvlKeyword &tempKey = pdsMapObj.findKeyword("REFERENCE_LONGITUDE");
799  tempKey.setValue(tempKey[0], "DEG");
800  }
801  if(pdsMapObj.hasKeyword("MAXIMUM_LATITUDE")) {
802  PvlKeyword &tempKey = pdsMapObj.findKeyword("MAXIMUM_LATITUDE");
803  tempKey.setValue(tempKey[0], "DEG");
804  }
805  if(pdsMapObj.hasKeyword("MINIMUM_LATITUDE")) {
806  PvlKeyword &tempKey = pdsMapObj.findKeyword("MINIMUM_LATITUDE");
807  tempKey.setValue(tempKey[0], "DEG");
808  }
809  if(pdsMapObj.hasKeyword("EASTERNMOST_LONGITUDE")) {
810  PvlKeyword &tempKey = pdsMapObj.findKeyword("EASTERNMOST_LONGITUDE");
811  tempKey.setValue(tempKey[0], "DEG");
812  }
813  if(pdsMapObj.hasKeyword("WESTERNMOST_LONGITUDE")) {
814  PvlKeyword &tempKey = pdsMapObj.findKeyword("WESTERNMOST_LONGITUDE");
815  tempKey.setValue(tempKey[0], "DEG");
816  }
817  if(pdsMapObj.hasKeyword("MAP_PROJECTION_ROTATION")) {
818  PvlKeyword &tempKey = pdsMapObj.findKeyword("MAP_PROJECTION_ROTATION");
819  tempKey.setValue(tempKey[0], "DEG");
820  }
821 
822  }
823 
824 
832  QString ProcessExportPds::ProjectionName(Pvl &inputLabel) {
833  Projection *proj = ProjectionFactory::Create(inputLabel);
834  QString name = proj->Name();
835  delete proj;
836  return name;
837  }
838 
839 
846  int ProcessExportPds::LineBytes() {
847  Cube *cube = InputCubes[0];
848  int a = SizeOf(p_pixelType);
849  int b = cube->sampleCount();
850  return b * a ;
851  }
852 
853 
859  int ProcessExportPds::LabelSize() {
860  ostringstream temp;
861  if(m_label->format() != NULL) {
862  temp << *m_label << m_label->format()->formatEOL();
863  }
864  else {
865  temp << *m_label << endl;
866  }
867  return temp.tellp();
868  }
869 
875  void ProcessExportPds::OutputDetachedLabel() {
876  if(!m_detachedLabel) {
877  QString msg = "Unable to output detached label. Use "
878  "ProcessExportPds::SetDetached() to set the "
879  "output PDS label file name.";
880  throw IException(IException::Unknown, msg, _FILEINFO_);
881  }
882  std::ofstream sOutLabelStream(m_detachedPdsLabelFile.toAscii().data());
883  OutputLabel(sOutLabelStream);
884  sOutLabelStream.close();
885  }
886 
894  void ProcessExportPds::OutputLabel(std::ofstream &os) {
895  int labSize = LabelSize(); // labSize will be the old label size with "?"
896  // NOTE: WARNING: If anything changes in the next two lines, you must also changes the
897  // corresponding lines in the StandardImageRoot member
898  if(m_exportType == Stream) {
899  if(m_pdsFileType != ProcessExportPds::JP2Image) {
900  (*m_label)["LABEL_RECORDS"].setValue(toString(labSize), "BYTES");
901  if(!m_detachedLabel) {
902  (*m_label)["^IMAGE"].setValue(toString(labSize + 1), "BYTES");
903  }
904  }
905  if(m_label->format() != NULL) {
906  os << *m_label << m_label->format()->formatEOL();
907  }
908  else {
909  os << *m_label << endl;
910  }
911  // Fill the difference between the old and new label size with spaces.
912  if(m_pdsFileType != ProcessExportPds::JP2Image) {
913  for(int i = LabelSize(); i < labSize; ++i) os << ' ';
914  }
915  }
916  else if(m_exportType == Fixed) {
917  int lineBytes;
918  int labelRecords;
919  if(m_pdsFileType != ProcessExportPds::JP2Image) {
920  lineBytes = LineBytes();
921  (*m_label)["RECORD_BYTES"].setValue(toString(lineBytes));
922 
923  // The number of label records is dependent on the number of label bytes
924  // and the lint bytes
925  labelRecords = (int)ceil((double)labSize / (double)lineBytes);
926  if(m_label->hasKeyword("LABEL_RECORDS")) { //LRO MRF doesn't have this keyword
927  (*m_label)["LABEL_RECORDS"].setValue(toString(labelRecords));
928  }
929  int totalTableRecords = 0;
930  for (unsigned int i = 0; i < m_tableRecords.size(); i++) {
931  totalTableRecords += m_tableRecords[i];
932  }
933  int imageRecords = InputCubes[0]->lineCount()
934  * InputCubes[0]->bandCount();
935  int fileRecords = labelRecords + imageRecords + totalTableRecords;
936  (*m_label)["FILE_RECORDS"].setValue(toString(fileRecords));
937 
938  if(!m_detachedLabel) {
939  (*m_label)["^IMAGE"].setValue(toString(labelRecords + 1));
940  }
941  }
942  if(m_label->format() != NULL) {
943  os << *m_label << m_label->format()->formatEOL();
944  }
945  else {
946  os << *m_label << endl;
947  }
948  if(m_pdsFileType != ProcessExportPds::JP2Image) {
949  for(int i = LabelSize(); i < labelRecords * lineBytes; ++i) os << ' ';
950  }
951  }
952 
953  }
954 
986  void ProcessExportPds::ExportTable(Table isisTable, QString detachedPdsTableFileName) {
987 
988  if(Attached() && detachedPdsTableFileName != "") {
989  QString msg = "The output PDS file has been set to attached and a "
990  "detached PDS table file name has been given. If detached "
991  "is preferred, set the process to detached SetDetached() "
992  "and call StandardPdsLabel() before calling ExportTable().";
993  throw IException(IException::Unknown, msg, _FILEINFO_);
994  }
995 
996  if(Detached() && detachedPdsTableFileName == "") {
997  QString msg = "The output PDS file has been set to detached. A file name "
998  "for the detached ouput PDS table file is required. "
999  "If an attached output file is prefered, use the method "
1000  "ProcessExportPds::SetAttached() before calling ExportTable().";
1001  throw IException(IException::Unknown, msg, _FILEINFO_);
1002  }
1003 
1004  // create an ExportPdsTable to fill file stream with PDS Table info
1005  ExportPdsTable pdsTable(isisTable);
1006  int fileRecordBytes = LineBytes();
1007  // return metadata pvl containing needed information for the output label.
1008 
1009  char *tableBuffer = new char[isisTable.Records() * fileRecordBytes];
1010  PvlObject metadata = pdsTable.exportTable(tableBuffer,
1011  fileRecordBytes,
1012  ByteOrderName(p_endianType));
1013  QString pdsTableName = pdsTable.formatPdsTableName();
1014  Pvl &mainPvl = *m_label;
1015  if (Attached()) {
1016  m_tableBuffers.push_back(tableBuffer);
1017  int labSize = LabelSize(); // labSize will be the old label size with "?"
1018  int labelRecords = (int)ceil((double)labSize / (double)fileRecordBytes);
1019  int imageRecords = InputCubes[0]->lineCount()
1020  * InputCubes[0]->bandCount();
1021  int totalTableRecords = 0;
1022  for (unsigned int i = 0; i < m_tableRecords.size(); i++) {
1023  totalTableRecords += m_tableRecords[i];
1024  }
1025  // for start record values, indexing begins with 1
1026  int tableStartRecord = 1 + labelRecords + imageRecords + totalTableRecords;
1027  mainPvl += PvlKeyword("^" + pdsTableName, toString(tableStartRecord));
1028  }
1029  else {
1030  mainPvl += PvlKeyword("^" + pdsTableName, detachedPdsTableFileName);
1031  FileName labelFile(m_detachedPdsLabelFile);
1032  QString tableFileWithPath = labelFile.path() + "/"
1033  + detachedPdsTableFileName;
1034  ofstream os(tableFileWithPath.toAscii().data());
1035  os.write(tableBuffer, isisTable.Records() * fileRecordBytes);
1036  os.close();
1037  }
1038  mainPvl.addObject(metadata);
1039  m_tableRecords.push_back(isisTable.Records());
1040  return;
1041  }
1042 
1051  void ProcessExportPds::SetDetached(QString detachedLabelFile) {
1052  m_detachedLabel = true;
1053  m_detachedPdsLabelFile = detachedLabelFile;
1054  return;
1055  }
1056 
1062  void ProcessExportPds::SetAttached() {
1063  m_detachedLabel = false;
1064  m_detachedPdsLabelFile = "";
1065  }
1066 
1072  bool ProcessExportPds::Detached() {
1073  return m_detachedLabel;
1074  }
1075 
1081  bool ProcessExportPds::Attached() {
1082  return !m_detachedLabel;
1083  }
1084 
1091  void ProcessExportPds::SetPdsResolution(PdsResolution resolutionUnits) {
1092  m_exportResolution = resolutionUnits;
1093  }
1094 
1102  void ProcessExportPds::SetExportType(PdsExportType recordFormat) {
1103  m_exportType = recordFormat;
1104  }
1105 
1114  void ProcessExportPds::ForceBands(bool force) {
1115  m_forceBands = force;
1116  }
1117 
1127  void ProcessExportPds::ForceBandName(bool force) {
1128  m_forceBandName = force;
1129  }
1130 
1140  void ProcessExportPds::ForceCenterFilterWavelength(bool force) {
1141  m_forceCenterFilterWavelength = force;
1142  }
1143 
1153  void ProcessExportPds::ForceBandwidth(bool force) {
1154  m_forceBandwidth = force;
1155  }
1156 
1166  void ProcessExportPds::ForceBandStorageType(bool force) {
1167  m_forceBandStorageType = force;
1168  }
1169 
1179  void ProcessExportPds::ForceOffset(bool force) {
1180  m_forceOffset = force;
1181  }
1182 
1192  void ProcessExportPds::ForceScalingFactor(bool force) {
1193  m_forceScalingFactor = force;
1194  }
1195 
1205  void ProcessExportPds::ForceSampleBits(bool force) {
1206  m_forceSampleBits = force;
1207  }
1208 
1218  void ProcessExportPds::ForceSampleBitMask(bool force) {
1219  m_forceSampleBitMask = force;
1220  }
1221 
1231  void ProcessExportPds::ForceSampleType(bool force) {
1232  m_forceSampleType = force;
1233  }
1234 
1244  void ProcessExportPds::ForceCoreNull(bool force) {
1245  m_forceCoreNull = force;
1246  }
1247 
1257  void ProcessExportPds::ForceCoreLrs(bool force) {
1258  m_forceCoreLrs = force;
1259  }
1260 
1271  void ProcessExportPds::ForceCoreLis(bool force) {
1272  m_forceCoreLis = force;
1273  }
1274 
1285  void ProcessExportPds::ForceCoreHrs(bool force) {
1286  m_forceCoreHrs = force;
1287  }
1288 
1299  void ProcessExportPds::ForceCoreHis(bool force) {
1300  m_forceCoreHis = force;
1301  }
1302 
1310  void ProcessExportPds::StartProcess(std::ofstream &fout) {
1311  ProcessExport::StartProcess(fout);
1312  if (!m_detachedLabel) {
1313  for (unsigned int i = 0; i < m_tableBuffers.size(); i++) {
1314  if (m_tableBuffers[i] == NULL) {
1315  QString msg = "Unable to add tables to PDS output file.";
1316  throw IException(IException::Unknown, msg, _FILEINFO_);
1317  }
1318  // write each table buffer to fout.
1319  // For each table, use (number of records)*(bytes per record) to
1320  // determine how many bytes to write out.
1321  fout.write(m_tableBuffers[i], m_tableRecords[i]*LineBytes());
1322  }
1323  }
1324  return;
1325  }
1326 
1327 } // End of Isis namespace