Isis 3 Programmer Reference
ProcessExportPds.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "ProcessExportPds.h"
8 
9 #include <cmath>
10 #include <iostream>
11 #include <sstream>
12 
13 #include "Endian.h"
14 #include "ExportPdsTable.h"
15 #include "FileName.h"
16 #include "IException.h"
17 #include "IString.h"
18 #include "PixelType.h"
19 #include "Projection.h"
20 #include "ProjectionFactory.h"
21 #include "Pvl.h"
22 #include "PvlFormat.h"
23 #include "PvlToPvlTranslationManager.h"
24 #include "PvlFormatPds.h"
25 #include "SpecialPixel.h"
26 #include "Table.h"
27 
28 
29 using namespace std;
30 
31 namespace Isis {
36  ProcessExportPds::ProcessExportPds() {
37  m_label = NULL;
38  m_formatter = NULL;
39  m_exportType = Stream;
40  m_exportResolution = Meter;
41 
42  m_forceBands = true;
43  m_forceBandName = true;
44  m_forceCenterFilterWavelength = true;
45  m_forceBandwidth = true;
46  m_forceBandStorageType = true;
47  m_forceOffset = true;
48  m_forceScalingFactor = true;
49  m_forceSampleBits = true;
50  m_forceSampleBitMask = true;
51  m_forceSampleType = true;
52  m_forceCoreNull = true;
53  m_forceCoreLrs = true;
54  m_forceCoreLis = true;
55  m_forceCoreHrs = true;
56  m_forceCoreHis = true;
57  m_detachedLabel = false;
58 
59  m_pdsFileType = Image;
60  m_tableRecords.clear();
61  m_tableBuffers.clear();
62  }
63 
68  ProcessExportPds::~ProcessExportPds() {
69  delete m_label;
70  delete m_formatter;
71  for (unsigned int i = 0; i < m_tableBuffers.size(); i++) {
72  delete [] m_tableBuffers[i];
73  m_tableBuffers[i] = NULL;
74  }
75  m_tableBuffers.clear();
76  }
77 
92  Pvl &ProcessExportPds::StandardPdsLabel(ProcessExportPds::PdsFileType type) {
93  m_label = new Pvl;
94 
95  m_pdsFileType = type;
96  if(m_pdsFileType == ProcessExportPds::JP2Image) {
97  setFormat(JP2);
98  }
99 
100  m_formatter = new PvlFormatPds("$ISISROOT/appdata/translations/pdsExportRootGen.typ");
101  m_label->setFormat(m_formatter);
102  m_label->setTerminator("END");
103 
104  if(type == ProcessExportPds::Image || type == ProcessExportPds::JP2Image) {
105  CreateImageLabel();
106  }
107  else {
108  QString msg = "Unsupported PDS output type";
109  throw IException(IException::User, msg, _FILEINFO_);
110  }
111 
112  return *m_label;
113  }
114 
115 
119  void ProcessExportPds::CreateImageLabel() {
120 
121  Pvl &mainPvl = *m_label;
122 
123  if(m_exportType == Stream) {
124  if(m_pdsFileType == ProcessExportPds::Image) {
125  StreamImageRoot(mainPvl);
126  }
127  else if(m_pdsFileType == ProcessExportPds::JP2Image) {
128  StreamJP2ImageRoot(mainPvl);
129  }
130  }
131  else if(m_exportType == Fixed) {
132  if(m_pdsFileType == ProcessExportPds::Image) {
133  FixedImageRoot(mainPvl);
134  }
135  else if(m_pdsFileType == ProcessExportPds::JP2Image) {
136  FixedJP2ImageRoot(mainPvl);
137  }
138  }
139  else {
140  QString msg = "Invalid PDS export type.";
141  throw IException(IException::Programmer, msg, _FILEINFO_);
142  }
143 
144  if(m_pdsFileType == ProcessExportPds::JP2Image) {
145  StandardJP2Image(mainPvl);
146  }
147  else {
148  StandardImageImage(mainPvl);
149  }
150 
151  // The IMAGE_MAP_PROJECTION group is located in the ROOT for PDS IMAGEs. The
152  // standard routines will add the IMAGE_MAP_PROJECTION correctly
153  StandardAllMapping(mainPvl);
154  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportAllMapping.typ");
155  }
156 
157 
161  void ProcessExportPds::CreateQubeLabel() {
162  Pvl &mainPvl = *m_label;
163 
164 // StandardQubeRoot (mainPvl);
165 // StandardQubeQube (mainPvl);
166 
167  // The IMAGE_MAP_PROJECTION group is located inside the QUBE object for PDS
168  // QUBEs. Create a temporary PVL so the StandardAllMapping member can add an
169  // IMAGE_MAP_PROJECTION group then later it can be extracted and added to
170  // the output PDS label.
171  Pvl mapTmp;
172  StandardAllMapping(mapTmp);
173  if(mapTmp.hasObject("IMAGE_MAP_PROJECTION")) {
174  mainPvl.findObject("QUBE").addObject(mapTmp.findObject("IMAGE_MAP_PROJECTION"));
175  }
176  }
177 
178 
182  void ProcessExportPds::CreateSpectralQubeLabel() {
183  Pvl &mainPvl = *m_label;
184 
185 // StandardSpectralQubeRoot (mainPvl);
186 // StandardSpectralQubeSpectralQube (mainPvl);
187 
188  // The IMAGE_MAP_PROJECTION group is located inside the SPECTRAL_QUBE object
189  // for PDS SPECTRAL_QUBEs. Create a temporary PVL so the StandardAllMapping
190  // member can add an IMAGE_MAP_PROJECTION group then later it can be
191  // extracted and added to the output PDS label.
192  Pvl mapTmp;
193  StandardAllMapping(mapTmp);
194  if(mapTmp.hasObject("IMAGE_MAP_PROJECTION")) {
195  mainPvl.findObject("QUBE").addObject(mapTmp.findObject("IMAGE_MAP_PROJECTION"));
196  }
197  }
198 
199 
205  void ProcessExportPds::StreamImageRoot(Pvl &mainPvl) {
206  // Create standard ROOT object keywords
207  mainPvl += PvlKeyword("PDS_VERSION_ID", "PDS3");
208  mainPvl += PvlKeyword("RECORD_TYPE", "UNDEFINED");
209  // NOTE: WARNING: If the number of "?"s in the next few lines changes, you
210  // must also changes the corresponding lines in the OutputLabel member
211  mainPvl += PvlKeyword("LABEL_RECORDS", "???????", "BYTES");
212  if(m_detachedLabel) {
213  QString sImageFile = m_detachedPdsLabelFile;
214  int iFound = sImageFile.indexOf(".lbl");
215  if(iFound != -1) {
216  sImageFile.replace(iFound, 4, ".img");
217  }
218  else {
219  sImageFile += ".img";
220  }
221  FileName outFile(sImageFile);
222  mainPvl += PvlKeyword("^IMAGE", outFile.name());
223  }
224  else {
225  mainPvl += PvlKeyword("^IMAGE", "???????", "BYTES");
226  }
227  // MD5 checksums are 128-bit -> 32 characters when stringified from hex.
228  if (canGenerateChecksum()) {
229  mainPvl += PvlKeyword("CHECKSUM", "????????????????????????????????");
230  }
231  }
232 
233 
239  void ProcessExportPds::StreamJP2ImageRoot(Pvl &mainPvl) {
240  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageJP2.typ");
241  // Create standard ROOT object keywords
242  mainPvl += PvlKeyword("PDS_VERSION_ID", "PDS3");
243  QString sImageFile = m_detachedPdsLabelFile;
244  if(m_detachedLabel) {
245  int iFound = sImageFile.indexOf(".lbl");
246  if(iFound != -1) {
247  sImageFile.replace(iFound, 4, ".jp2");
248  }
249  else {
250  sImageFile += ".jp2";
251  }
252  }
253  else {
254  QString msg = "Labels must be detached for JP2 files.";
255  throw IException(IException::Programmer, msg, _FILEINFO_);
256  }
257  FileName outFile(sImageFile);
258  PvlObject cmpObj("COMPRESSED_FILE");
259  cmpObj += PvlKeyword("FILE_NAME", outFile.name());
260  cmpObj += PvlKeyword("RECORD_TYPE", "UNDEFINED");
261  cmpObj += PvlKeyword("ENCODING_TYPE", "JP2");
262  cmpObj += PvlKeyword("ENCODING_TYPE_VERSION_NAME", "ISO/IEC15444-1:2004");
263  cmpObj += PvlKeyword("INTERCHANGE_FORMAT", "BINARY");
264  FileName infilename(InputCubes[0]->fileName());
265  cmpObj += PvlKeyword("UNCOMPRESSED_FILE_NAME", infilename.name());
266  int storagebytes = InputCubes[0]->sampleCount() * InputCubes[0]->lineCount();
267  if(p_pixelType == Isis::Real) {
268  QString msg = "JPEG2000 does not support floating point data.";
269  throw IException(IException::Programmer, msg, _FILEINFO_);
270  }
271  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
272  storagebytes = storagebytes * 2;
273  }
274  cmpObj += PvlKeyword("REQUIRED_STORAGE_BYTES", toString(storagebytes));
275  mainPvl.addObject(cmpObj);
276  PvlObject ucmpObj("UNCOMPRESSED_FILE");
277  ucmpObj += PvlKeyword("FILE_NAME", infilename.name());
278  ucmpObj += PvlKeyword("RECORD_TYPE", "FIXED_LENGTH");
279  int recordbytes = InputCubes[0]->sampleCount();
280  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
281  recordbytes = recordbytes * 2;
282  }
283  ucmpObj += PvlKeyword("RECORD_BYTES", toString(recordbytes));
284  ucmpObj += PvlKeyword("FILE_RECORDS", toString(InputCubes[0]->lineCount()));
285  ucmpObj += PvlKeyword("^IMAGE", infilename.name());
286  mainPvl.addObject(ucmpObj);
287  }
288 
289 
295  void ProcessExportPds::FixedImageRoot(Pvl &mainPvl) {
296  //Create fixed ROOT object keywords
297  mainPvl += PvlKeyword("PDS_VERSION_ID", "PDS3");
298  mainPvl += PvlKeyword("RECORD_TYPE", "FIXED_LENGTH");
299  // NOTE: WARNING: If the number of "?"s in the next few lines changes, you
300  // must also changes the corresponding lines in the OutputLabel member
301  mainPvl += PvlKeyword("RECORD_BYTES", "???????");
302  mainPvl += PvlKeyword("FILE_RECORDS", "???????");
303  mainPvl += PvlKeyword("LABEL_RECORDS", "????");
304  if(m_detachedLabel) {
305  QString sImageFile = m_detachedPdsLabelFile;
306  int iFound = sImageFile.indexOf(".lbl");
307  if(iFound != -1) {
308  sImageFile.replace(iFound, 4, ".img");
309  }
310  else {
311  sImageFile += ".img";
312  }
313  FileName outFile(sImageFile);
314  mainPvl += PvlKeyword("^IMAGE", outFile.name());
315  }
316  else {
317  mainPvl += PvlKeyword("^IMAGE", "???");
318  }
319  if (canGenerateChecksum()) {
320  mainPvl += PvlKeyword("CHECKSUM", "????????????????????????????????");
321  }
322  }
323 
324 
330  void ProcessExportPds::FixedJP2ImageRoot(Pvl &mainPvl) {
331  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageJP2.typ");
332  //Create fixed ROOT object keywords
333  mainPvl += PvlKeyword("PDS_VERSION_ID", "PDS3");
334  QString sImageFile = m_detachedPdsLabelFile;
335  if(m_detachedLabel) {
336  int iFound = sImageFile.indexOf(".lbl");
337  if(iFound != -1) {
338  sImageFile.replace(iFound, 4, ".jp2");
339  }
340  else {
341  sImageFile += ".jp2";
342  }
343  }
344  else {
345  QString msg = "Labels must be detached for JP2 files.";
346  throw IException(IException::Programmer, msg, _FILEINFO_);
347  }
348  FileName outFile(sImageFile);
349  PvlObject cmpObj("COMPRESSED_FILE");
350  cmpObj += PvlKeyword("FILE_NAME", outFile.name());
351  cmpObj += PvlKeyword("RECORD_TYPE", "UNDEFINED");
352  cmpObj += PvlKeyword("ENCODING_TYPE", "JP2");
353  cmpObj += PvlKeyword("ENCODING_TYPE_VERSION_NAME", "ISO/IEC15444-1:2004");
354  cmpObj += PvlKeyword("INTERCHANGE_FORMAT", "BINARY");
355  FileName infilename(InputCubes[0]->fileName());
356  cmpObj += PvlKeyword("UNCOMPRESSED_FILE_NAME", infilename.name());
357  int storagebytes = InputCubes[0]->sampleCount() * InputCubes[0]->lineCount();
358  if(p_pixelType == Isis::Real) {
359  QString msg = "JPEG2000 does not support floating point data.";
360  throw IException(IException::Programmer, msg, _FILEINFO_);
361  }
362  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
363  storagebytes = storagebytes * 2;
364  }
365  cmpObj += PvlKeyword("REQUIRED_STORAGE_BYTES", toString(storagebytes));
366  mainPvl.addObject(cmpObj);
367  PvlObject ucmpObj("UNCOMPRESSED_FILE");
368  ucmpObj += PvlKeyword("FILE_NAME", infilename.name());
369  ucmpObj += PvlKeyword("RECORD_TYPE", "FIXED_LENGTH");
370  int recordbytes = InputCubes[0]->sampleCount();
371  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
372  recordbytes = recordbytes * 2;
373  }
374  ucmpObj += PvlKeyword("RECORD_BYTES", toString(recordbytes));
375  ucmpObj += PvlKeyword("FILE_RECORDS", toString(InputCubes[0]->lineCount()));
376  ucmpObj += PvlKeyword("^IMAGE", infilename.name());
377  mainPvl.addObject(ucmpObj);
378  }
379 
380 
390  void ProcessExportPds::StandardImageImage(Pvl &mainPvl) {
391  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImage.typ");
392  // Build up an IMAGE object:
393  // Auto translate standard keywords for the IMAGE object
394  Pvl *inputLabel = InputCubes[0]->label();
395  FileName transfile;
396  transfile = "$ISISROOT/appdata/translations/pdsExportImageImage.trn";
397  PvlToPvlTranslationManager Xlator(*inputLabel, transfile.expanded());
398  Xlator.Auto(mainPvl);
399 
400  // Calculate the core base/mult for this cube
401  double base = 0.0;
402  double multiplier = 1.0;
403  double x1, x2;
404 
405  double minimum = (p_inputMinimum.size()) ? p_inputMinimum[0] : 0.0;
406  double maximum = (p_inputMaximum.size()) ? p_inputMaximum[0] : 0.0;
407 
408  for(unsigned int i = 0; i < p_inputMinimum.size(); i ++) {
409  minimum = std::min(minimum, p_inputMinimum[i]);
410  maximum = std::max(maximum, p_inputMaximum[i]);
411  }
412 
413  x1 = p_outputMinimum;
414  x2 = p_outputMaximum;
415 
416  if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedByte) {
417  multiplier = (maximum - minimum) / (x2 - x1);
418  base = minimum - multiplier * x1;
419  }
420  else if(p_inputMinimum.size() && p_pixelType == Isis::SignedWord) {
421  multiplier = (maximum - minimum) / (x2 - x1);
422  base = minimum - multiplier * x1;
423  }
424  else if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedWord) {
425  multiplier = (maximum - minimum) / (x2 - x1);
426  base = minimum - multiplier * x1;
427  }
428 
429  // Manually set the keyword for the number of bits in a pixel
430  // NOTE: this is dependent on settings in ProcessExport and not the cube
431  PvlObject &imgObj = mainPvl.findObject("IMAGE");
432 
433  if(!m_forceBands) imgObj.deleteKeyword("BANDS");
434  if(!m_forceBandName && imgObj.hasKeyword("BAND_NAME")) imgObj.deleteKeyword("BAND_NAME");
435  if(!m_forceCenterFilterWavelength && imgObj.hasKeyword("CENTER_FILTER_WAVELENGTH")) imgObj.deleteKeyword("CENTER_FILTER_WAVELENGTH");
436  if(!m_forceBandwidth && imgObj.hasKeyword("BANDWIDTH")) imgObj.deleteKeyword("BANDWIDTH");
437 
438  if(m_forceBandStorageType) imgObj += PvlKeyword("BAND_STORAGE_TYPE", "BAND_SEQUENTIAL");
439  if(m_forceOffset) imgObj += PvlKeyword("OFFSET", toString(base));
440  if(m_forceScalingFactor) imgObj += PvlKeyword("SCALING_FACTOR", toString(multiplier));
441 
442  // Manually set the keyword for pixel type and special pixels
443  if(p_pixelType == Isis::UnsignedByte) {
444  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "8");
445  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xff));
446  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
447  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
448  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
449  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
450  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
451  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
452  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel8.typ");
453  }
454  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Msb)) {
455  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
456  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
457  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
458  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
459  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
460  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
461  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
462  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
463  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel16.typ");
464  }
465  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Lsb)) {
466  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
467  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
468  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_UNSIGNED_INTEGER");
469  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
470  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
471  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
472  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
473  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
474  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel16.typ");
475  }
476  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Msb)) {
477  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
478  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
479  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_INTEGER");
480  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
481  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
482  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
483  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
484  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
485  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel16.typ");
486  }
487  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Lsb)) {
488  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
489  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffff));
490  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_INTEGER");
491  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
492  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
493  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
494  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
495  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
496  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel16.typ");
497  }
498  else if(p_pixelType == Isis::Real) {
499  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "32");
500  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffffffff));
501 
502  if(p_endianType == Isis::Msb) {
503  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "IEEE_REAL");
504  }
505  else {
506  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "PC_REAL");
507  }
508  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString(Isis::INULL4));
509  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString(Isis::ILOW_REPR_SAT4));
510  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString(Isis::ILOW_INSTR_SAT4));
511  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString(Isis::IHIGH_REPR_SAT4));
512  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString(Isis::IHIGH_INSTR_SAT4));
513  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel32.typ");
514  }
515  else {
516  QString msg = "Unsupported PDS pixel type or sample size";
517  throw IException(IException::User, msg, _FILEINFO_);
518  }
519  }
520 
521 
531  void ProcessExportPds::StandardJP2Image(Pvl &mainPvl) {
532  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImage.typ");
533  if(m_pdsFileType == ProcessExportPds::JP2Image) {
534  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageJP2.typ");
535  }
536  // Build up a JP2 IMAGE object:
537  // Auto translate standard keywords for the IMAGE object
538  Pvl *inputLabel = InputCubes[0]->label();
539  FileName transfile;
540  transfile = "$ISISROOT/appdata/translations/pdsExportImageJP2.trn";
541  PvlToPvlTranslationManager Xlator(*inputLabel, transfile.expanded());
542  Xlator.Auto(mainPvl);
543 
544  // Calculate the core base/mult for this cube
545  double base = 0.0;
546  double multiplier = 1.0;
547  double x1, x2;
548 
549  double minimum = (p_inputMinimum.size()) ? p_inputMinimum[0] : 0.0;
550  double maximum = (p_inputMaximum.size()) ? p_inputMaximum[0] : 0.0;
551 
552  for(unsigned int i = 0; i < p_inputMinimum.size(); i ++) {
553  minimum = std::min(minimum, p_inputMinimum[i]);
554  maximum = std::max(maximum, p_inputMaximum[i]);
555  }
556 
557  x1 = p_outputMinimum;
558  x2 = p_outputMaximum;
559 
560  if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedByte) {
561  multiplier = (maximum - minimum) / (x2 - x1);
562  base = minimum - multiplier * x1;
563  }
564  else if(p_inputMinimum.size() && p_pixelType == Isis::SignedWord) {
565  multiplier = (maximum - minimum) / (x2 - x1);
566  base = minimum - multiplier * x1;
567  }
568  else if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedWord) {
569  multiplier = (maximum - minimum) / (x2 - x1);
570  base = minimum - multiplier * x1;
571  }
572 
573  // Manually set the keyword for the number of bits in a pixel
574  // NOTE: this is dependent on settings in ProcessExport and not the cube
575  PvlObject &imgObj = mainPvl.findObject("UNCOMPRESSED_FILE").findObject("IMAGE");
576 
577  if(!m_forceBands) imgObj.deleteKeyword("BANDS");
578  if(!m_forceBandName && imgObj.hasKeyword("BAND_NAME")) imgObj.deleteKeyword("BAND_NAME");
579  if(!m_forceCenterFilterWavelength && imgObj.hasKeyword("CENTER_FILTER_WAVELENGTH")) imgObj.deleteKeyword("CENTER_FILTER_WAVELENGTH");
580  if(!m_forceBandwidth && imgObj.hasKeyword("BANDWIDTH")) imgObj.deleteKeyword("BANDWIDTH");
581 
582  if(m_forceBandStorageType) imgObj += PvlKeyword("BAND_STORAGE_TYPE", "BAND_SEQUENTIAL");
583  if(m_forceOffset) imgObj += PvlKeyword("OFFSET", toString(base));
584  if(m_forceScalingFactor) imgObj += PvlKeyword("SCALING_FACTOR", toString(multiplier));
585 
586  // Manually set the keyword for pixel type and special pixels
587  if(p_pixelType == Isis::UnsignedByte) {
588  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "8");
589  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xff));
590  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
591  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
592  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
593  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
594  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
595  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
596  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel8.typ");
597  }
598  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Msb)) {
599  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
600  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
601  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
602  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
603  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
604  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
605  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
606  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
607  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel16.typ");
608  }
609  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Lsb)) {
610  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
611  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
612  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_UNSIGNED_INTEGER");
613  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
614  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
615  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
616  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
617  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
618  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel16.typ");
619  }
620  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Msb)) {
621  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
622  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
623  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_INTEGER");
624  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
625  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
626  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
627  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
628  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
629  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel16.typ");
630  }
631  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Lsb)) {
632  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
633  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffff));
634  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_INTEGER");
635  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
636  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
637  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
638  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
639  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
640  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel16.typ");
641  }
642  else if(p_pixelType == Isis::Real) {
643  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "32");
644  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffffffff));
645 
646  if(p_endianType == Isis::Msb) {
647  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "IEEE_REAL");
648  }
649  else {
650  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "PC_REAL");
651  }
652  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString(Isis::INULL4));
653  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString(Isis::ILOW_REPR_SAT4));
654  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString(Isis::ILOW_INSTR_SAT4));
655  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString(Isis::IHIGH_REPR_SAT4));
656  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString(Isis::IHIGH_INSTR_SAT4));
657  mainPvl.format()->add("$ISISROOT/appdata/translations/pdsExportImageImagePixel32.typ");
658  }
659  else {
660  QString msg = "Unsupported PDS pixel type or sample size";
661  throw IException(IException::User, msg, _FILEINFO_);
662  }
663  }
664 
665 
674  void ProcessExportPds::StandardAllMapping(Pvl &outputPvl) {
675 
676  // Get the input Isis cube label and find the Mapping group if it has one
677  Pvl *inputLabel = InputCubes[0]->label();
678  if(inputLabel->hasObject("IsisCube") &&
679  !(inputLabel->findObject("IsisCube").hasGroup("Mapping"))) return;
680  PvlGroup &inputMapping = inputLabel->findGroup("Mapping", Pvl::Traverse);
681 
682  // Translate the projection specific keywords for a PDS IMAGE_MAP_PROJECTION
683  QString projName = ProjectionName(*inputLabel);
684  PvlToPvlTranslationManager xlatSpecProj(*inputLabel,
685  "$ISISROOT/appdata/translations/pdsExport" + projName + ".trn");
686  xlatSpecProj.Auto(outputPvl);
687 
688  // Translate the target name
689  PvlToPvlTranslationManager xlatTarget(*inputLabel,
690  "$ISISROOT/appdata/translations/pdsExportTarget.trn");
691  xlatTarget.Auto(outputPvl);
692 
693  // Add keywords to the PDS labels that could not be handled automatically
694  PvlObject &pdsMapObj = outputPvl.findObject("IMAGE_MAP_PROJECTION");
695 
696  // Add the projection name
697 // pdsMapObj += PvlKeyword ("MAP_PROJECTION_TYPE", projName.toUpper());
698 
699  // Modify the radii to be km.
700  PvlKeyword &aRadius = pdsMapObj["A_AXIS_RADIUS"];
701  QString unit = aRadius.unit();
702  if( (unit.toUpper() == "METERS") || (unit == "") ) { //if no units, assume in meters
703  double dValue = (double)aRadius;
704  dValue /= 1000.0;
705  aRadius.setValue(toString(dValue), "KM");
706  }
707  PvlKeyword &bRadius = pdsMapObj["B_AXIS_RADIUS"];
708  unit = bRadius.unit();
709  if( (unit.toUpper() == "METERS") || (unit == "") ) {
710  double dValue = (double)bRadius;
711  dValue /= 1000.0;
712  bRadius.setValue(toString(dValue), "KM");
713  }
714  PvlKeyword &cRadius = pdsMapObj["C_AXIS_RADIUS"];
715  unit = cRadius.unit();
716  if( (unit.toUpper() == "METERS") || (unit == "") ) {
717  double dValue = (double)cRadius;
718  dValue /= 1000.0;
719  cRadius.setValue(toString(dValue), "KM");
720  }
721 
722  // Modify the units on MAP_SCALE and MAP_RESOLUTION
723  PvlKeyword &mapScale = pdsMapObj["MAP_SCALE"];
724  unit = mapScale.unit();
725  //if no units, assume in meters/pixel
726  if( (unit.toUpper() == "METERS/PIX") || (unit.toUpper() == "METERS/PIXEL") || (unit == "") ) {
727  if(m_exportResolution == Kilometer) {
728  double dValue = (double)mapScale;
729  dValue /= 1000.0;
730  mapScale.setValue(toString(dValue), "KM/PIXEL");
731  }
732  else {
733  mapScale.setValue(toString((double)mapScale), "METERS/PIXEL");
734  }
735  }
736  PvlKeyword &mapRes = pdsMapObj["MAP_RESOLUTION"];
737  unit = mapRes.unit();
738  //if no units, asume in pixels/degree
739  if( (unit.toUpper() == "PIXELS/DEGREE") || (unit == "") ) {
740  mapRes.setValue((QString)mapRes, "PIX/DEG");
741  }
742 
743  // Add the EASTERNMOST AND WESTERNMOST LONGITUDE keywords
744  PvlKeyword &isisLonDir = inputMapping.findKeyword("LongitudeDirection");
745  QString lonDir = isisLonDir[0];
746  lonDir = lonDir.toUpper();
747  if (inputMapping.hasKeyword("MaximumLongitude") && inputMapping.hasKeyword("MinimumLongitude")) {
748  double maxLon = inputMapping.findKeyword("MaximumLongitude");
749  double minLon = inputMapping.findKeyword("MinimumLongitude");
750  if(lonDir == "POSITIVEEAST") {
751  pdsMapObj += PvlKeyword("EASTERNMOST_LONGITUDE", toString(maxLon));
752  pdsMapObj += PvlKeyword("WESTERNMOST_LONGITUDE", toString(minLon));
753  }
754  else {
755  pdsMapObj += PvlKeyword("EASTERNMOST_LONGITUDE", toString(minLon));
756  pdsMapObj += PvlKeyword("WESTERNMOST_LONGITUDE", toString(maxLon));
757  }
758  }
759 
760  // Add the LINE_PROJECTION_OFFSET and SAMPLE_PROJECTION_OFFSET keywords
761  // These keywords are the distance from the origin of the image to the
762  // origin of the projection. The units are line or samples. The image origin
763  // is the middle of pixel (1,1)
764  double lineOffset = inputMapping.findKeyword("UpperLeftCornerY");
765  lineOffset /= (double)inputMapping.findKeyword("PixelResolution");
766  lineOffset *= 1.0;
767  lineOffset -= 0.5; // Add half a line to get to the center of (1,1)
768  pdsMapObj += PvlKeyword("LINE_PROJECTION_OFFSET", toString(lineOffset), "PIXEL");
769  double sampleOffset = inputMapping.findKeyword("UpperLeftCornerX");
770  sampleOffset /= (double)inputMapping.findKeyword("PixelResolution");
771  sampleOffset *= -1.0;
772  sampleOffset -= 0.5; // Add half a sample to get to the center of (1,1)
773  pdsMapObj += PvlKeyword("SAMPLE_PROJECTION_OFFSET", toString(sampleOffset), "PIXEL");
774 
775  // Add units to keywords already in the IMAGE_MAP_PROJECTION object as necessary
776  if(pdsMapObj.hasKeyword("CENTER_LATITUDE")) {
777  PvlKeyword &tempKey = pdsMapObj.findKeyword("CENTER_LATITUDE");
778  tempKey.setValue(tempKey[0], "DEG");
779  }
780  if(pdsMapObj.hasKeyword("CENTER_LONGITUDE")) {
781  PvlKeyword &tempKey = pdsMapObj.findKeyword("CENTER_LONGITUDE");
782  tempKey.setValue(tempKey[0], "DEG");
783  }
784 // if (pdsMapObj.hasKeyword("REFERENCE_LATITUDE")) {
785 // PvlKeyword &tempKey = pdsMapObj.findKeyword("REFERENCE_LATITUDE");
786 // tempKey.setValue(tempKey[0], "DEG");
787 // }
788  if(pdsMapObj.hasKeyword("REFERENCE_LONGITUDE")) {
789  PvlKeyword &tempKey = pdsMapObj.findKeyword("REFERENCE_LONGITUDE");
790  tempKey.setValue(tempKey[0], "DEG");
791  }
792  if(pdsMapObj.hasKeyword("MAXIMUM_LATITUDE")) {
793  PvlKeyword &tempKey = pdsMapObj.findKeyword("MAXIMUM_LATITUDE");
794  tempKey.setValue(tempKey[0], "DEG");
795  }
796  if(pdsMapObj.hasKeyword("MINIMUM_LATITUDE")) {
797  PvlKeyword &tempKey = pdsMapObj.findKeyword("MINIMUM_LATITUDE");
798  tempKey.setValue(tempKey[0], "DEG");
799  }
800  if(pdsMapObj.hasKeyword("EASTERNMOST_LONGITUDE")) {
801  PvlKeyword &tempKey = pdsMapObj.findKeyword("EASTERNMOST_LONGITUDE");
802  tempKey.setValue(tempKey[0], "DEG");
803  }
804  if(pdsMapObj.hasKeyword("WESTERNMOST_LONGITUDE")) {
805  PvlKeyword &tempKey = pdsMapObj.findKeyword("WESTERNMOST_LONGITUDE");
806  tempKey.setValue(tempKey[0], "DEG");
807  }
808  if(pdsMapObj.hasKeyword("MAP_PROJECTION_ROTATION")) {
809  PvlKeyword &tempKey = pdsMapObj.findKeyword("MAP_PROJECTION_ROTATION");
810  tempKey.setValue(tempKey[0], "DEG");
811  }
812 
813  }
814 
815 
823  QString ProcessExportPds::ProjectionName(Pvl &inputLabel) {
824  Projection *proj = ProjectionFactory::Create(inputLabel);
825  QString name = proj->Name();
826  delete proj;
827  return name;
828  }
829 
830 
837  int ProcessExportPds::LineBytes() {
838  Cube *cube = InputCubes[0];
839  int a = SizeOf(p_pixelType);
840  int b = cube->sampleCount();
841  return b * a ;
842  }
843 
844 
850  int ProcessExportPds::LabelSize() {
851  ostringstream temp;
852  if(m_label->format() != NULL) {
853  temp << *m_label << m_label->format()->formatEOL();
854  }
855  else {
856  temp << *m_label << endl;
857  }
858  return temp.tellp();
859  }
860 
866  void ProcessExportPds::OutputDetachedLabel() {
867  if(!m_detachedLabel) {
868  QString msg = "Unable to output detached label. Use "
869  "ProcessExportPds::SetDetached() to set the "
870  "output PDS label file name.";
871  throw IException(IException::Unknown, msg, _FILEINFO_);
872  }
873  std::ofstream sOutLabelStream(m_detachedPdsLabelFile.toLatin1().data());
874  OutputLabel(sOutLabelStream);
875  sOutLabelStream.close();
876  }
877 
885  void ProcessExportPds::OutputLabel(std::ofstream &os) {
886  int labSize = LabelSize(); // labSize will be the old label size with "?"
887  // NOTE: WARNING: If anything changes in the next two lines, you must also changes the
888  // corresponding lines in the StandardImageRoot member
889 
890  if(m_exportType == Stream) {
891  if(m_pdsFileType != ProcessExportPds::JP2Image) {
892  (*m_label)["LABEL_RECORDS"].setValue(toString(labSize), "BYTES");
893  if(!m_detachedLabel) {
894  (*m_label)["^IMAGE"].setValue(toString(labSize + 1), "BYTES");
895  }
896  }
897  if(m_label->format() != NULL) {
898  os << *m_label << m_label->format()->formatEOL();
899  }
900  else {
901  os << *m_label << endl;
902  }
903  // Fill the difference between the old and new label size with spaces.
904  if(m_pdsFileType != ProcessExportPds::JP2Image) {
905  for(int i = LabelSize(); i < labSize; ++i) os << ' ';
906  }
907  }
908  else if(m_exportType == Fixed) {
909  int lineBytes;
910  int labelRecords;
911  if(m_pdsFileType != ProcessExportPds::JP2Image) {
912  lineBytes = LineBytes();
913  (*m_label)["RECORD_BYTES"].setValue(toString(lineBytes));
914 
915  // The number of label records is dependent on the number of label bytes
916  // and the lint bytes
917  labelRecords = (int)ceil((double)labSize / (double)lineBytes);
918  if(m_label->hasKeyword("LABEL_RECORDS")) { //LRO MRF doesn't have this keyword
919  (*m_label)["LABEL_RECORDS"].setValue(toString(labelRecords));
920  }
921  int totalTableRecords = 0;
922  for (unsigned int i = 0; i < m_tableRecords.size(); i++) {
923  totalTableRecords += m_tableRecords[i];
924  }
925  int imageRecords = InputCubes[0]->lineCount()
926  * InputCubes[0]->bandCount();
927  int fileRecords = labelRecords + imageRecords + totalTableRecords;
928  (*m_label)["FILE_RECORDS"].setValue(toString(fileRecords));
929 
930  if(!m_detachedLabel) {
931  (*m_label)["^IMAGE"].setValue(toString(labelRecords + 1));
932  }
933  }
934  if(m_label->format() != NULL) {
935  os << *m_label << m_label->format()->formatEOL();
936  }
937  else {
938  os << *m_label << endl;
939  }
940  if(m_pdsFileType != ProcessExportPds::JP2Image) {
941  for(int i = LabelSize(); i < labelRecords * lineBytes; ++i) os << ' ';
942  }
943  }
944 
945  }
946 
947 
953  void ProcessExportPds::updateChecksumInLabel(std::ofstream &pdsFileStream) {
954  // This occurs after application has called its StartProcess and the checksum has been
955  // generated. We need to seek to the top of the file to rewrite the label. Since the
956  // CHECKSUM is MD5, we set aside 32 characters for the value of this keyword. Since
957  // OuputLabel() has already created the label and necessary padding, we can simply update
958  // the CHECKSUM value to the generated checksum and re-write the entire label.
959  pdsFileStream.seekp(0);
960  (*m_label)["CHECKSUM"].setValue(checksum());
961  pdsFileStream << *m_label;
962  }
963 
964 
996  void ProcessExportPds::ExportTable(Table isisTable, QString detachedPdsTableFileName) {
997 
998  if(Attached() && detachedPdsTableFileName != "") {
999  QString msg = "The output PDS file has been set to attached and a "
1000  "detached PDS table file name has been given. If detached "
1001  "is preferred, set the process to detached SetDetached() "
1002  "and call StandardPdsLabel() before calling ExportTable().";
1003  throw IException(IException::Unknown, msg, _FILEINFO_);
1004  }
1005 
1006  if(Detached() && detachedPdsTableFileName == "") {
1007  QString msg = "The output PDS file has been set to detached. A file name "
1008  "for the detached ouput PDS table file is required. "
1009  "If an attached output file is prefered, use the method "
1010  "ProcessExportPds::SetAttached() before calling ExportTable().";
1011  throw IException(IException::Unknown, msg, _FILEINFO_);
1012  }
1013 
1014  // create an ExportPdsTable to fill file stream with PDS Table info
1015  ExportPdsTable pdsTable(isisTable);
1016  int fileRecordBytes = LineBytes();
1017  // return metadata pvl containing needed information for the output label.
1018 
1019  char *tableBuffer = new char[isisTable.Records() * fileRecordBytes];
1020  PvlObject metadata = pdsTable.exportTable(tableBuffer,
1021  fileRecordBytes,
1022  ByteOrderName(p_endianType));
1023  QString pdsTableName = pdsTable.formatPdsTableName();
1024  Pvl &mainPvl = *m_label;
1025  if (Attached()) {
1026  m_tableBuffers.push_back(tableBuffer);
1027  int labSize = LabelSize(); // labSize will be the old label size with "?"
1028  int labelRecords = (int)ceil((double)labSize / (double)fileRecordBytes);
1029  int imageRecords = InputCubes[0]->lineCount()
1030  * InputCubes[0]->bandCount();
1031  int totalTableRecords = 0;
1032  for (unsigned int i = 0; i < m_tableRecords.size(); i++) {
1033  totalTableRecords += m_tableRecords[i];
1034  }
1035  // for start record values, indexing begins with 1
1036  int tableStartRecord = 1 + labelRecords + imageRecords + totalTableRecords;
1037  mainPvl += PvlKeyword("^" + pdsTableName, toString(tableStartRecord));
1038  }
1039  else {
1040  mainPvl += PvlKeyword("^" + pdsTableName, detachedPdsTableFileName);
1041  FileName labelFile(m_detachedPdsLabelFile);
1042  QString tableFileWithPath = labelFile.path() + "/"
1043  + detachedPdsTableFileName;
1044  ofstream os(tableFileWithPath.toLatin1().data());
1045  os.write(tableBuffer, isisTable.Records() * fileRecordBytes);
1046  os.close();
1047  }
1048  mainPvl.addObject(metadata);
1049  m_tableRecords.push_back(isisTable.Records());
1050  return;
1051  }
1052 
1061  void ProcessExportPds::SetDetached(QString detachedLabelFile) {
1062  m_detachedLabel = true;
1063  m_detachedPdsLabelFile = detachedLabelFile;
1064  return;
1065  }
1066 
1072  void ProcessExportPds::SetAttached() {
1073  m_detachedLabel = false;
1074  m_detachedPdsLabelFile = "";
1075  }
1076 
1082  bool ProcessExportPds::Detached() {
1083  return m_detachedLabel;
1084  }
1085 
1091  bool ProcessExportPds::Attached() {
1092  return !m_detachedLabel;
1093  }
1094 
1101  void ProcessExportPds::SetPdsResolution(PdsResolution resolutionUnits) {
1102  m_exportResolution = resolutionUnits;
1103  }
1104 
1112  void ProcessExportPds::SetExportType(PdsExportType recordFormat) {
1113  m_exportType = recordFormat;
1114  }
1115 
1124  void ProcessExportPds::ForceBands(bool force) {
1125  m_forceBands = force;
1126  }
1127 
1137  void ProcessExportPds::ForceBandName(bool force) {
1138  m_forceBandName = force;
1139  }
1140 
1150  void ProcessExportPds::ForceCenterFilterWavelength(bool force) {
1151  m_forceCenterFilterWavelength = force;
1152  }
1153 
1163  void ProcessExportPds::ForceBandwidth(bool force) {
1164  m_forceBandwidth = force;
1165  }
1166 
1176  void ProcessExportPds::ForceBandStorageType(bool force) {
1177  m_forceBandStorageType = force;
1178  }
1179 
1189  void ProcessExportPds::ForceOffset(bool force) {
1190  m_forceOffset = force;
1191  }
1192 
1202  void ProcessExportPds::ForceScalingFactor(bool force) {
1203  m_forceScalingFactor = force;
1204  }
1205 
1215  void ProcessExportPds::ForceSampleBits(bool force) {
1216  m_forceSampleBits = force;
1217  }
1218 
1228  void ProcessExportPds::ForceSampleBitMask(bool force) {
1229  m_forceSampleBitMask = force;
1230  }
1231 
1241  void ProcessExportPds::ForceSampleType(bool force) {
1242  m_forceSampleType = force;
1243  }
1244 
1254  void ProcessExportPds::ForceCoreNull(bool force) {
1255  m_forceCoreNull = force;
1256  }
1257 
1267  void ProcessExportPds::ForceCoreLrs(bool force) {
1268  m_forceCoreLrs = force;
1269  }
1270 
1281  void ProcessExportPds::ForceCoreLis(bool force) {
1282  m_forceCoreLis = force;
1283  }
1284 
1295  void ProcessExportPds::ForceCoreHrs(bool force) {
1296  m_forceCoreHrs = force;
1297  }
1298 
1309  void ProcessExportPds::ForceCoreHis(bool force) {
1310  m_forceCoreHis = force;
1311  }
1312 
1320  void ProcessExportPds::StartProcess(std::ofstream &fout) {
1321  ProcessExport::StartProcess(fout);
1322  if (!m_detachedLabel) {
1323  for (unsigned int i = 0; i < m_tableBuffers.size(); i++) {
1324  if (m_tableBuffers[i] == NULL) {
1325  QString msg = "Unable to add tables to PDS output file.";
1326  throw IException(IException::Unknown, msg, _FILEINFO_);
1327  }
1328  // write each table buffer to fout.
1329  // For each table, use (number of records)*(bytes per record) to
1330  // determine how many bytes to write out.
1331  fout.write(m_tableBuffers[i], m_tableRecords[i]*LineBytes());
1332  }
1333  }
1334  return;
1335  }
1336 
1337 } // End of Isis namespace
Isis::SizeOf
int SizeOf(Isis::PixelType pixelType)
Returns the number of bytes of the specified PixelType.
Definition: PixelType.h:46
Isis::ExportPdsTable
Export a PDS table from an ISIS Table.
Definition: ExportPdsTable.h:52
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::PvlObject
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:61
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::PvlFormatPds
Formats the value of a PvlKeyword into a PDS complient string.
Definition: PvlFormatPds.h:45
Isis::FileName::name
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:162
Isis::FileName
File name manipulation and expansion.
Definition: FileName.h:100
Isis::ProcessExportPds::PdsExportType
PdsExportType
Record format type of exported PDS file.
Definition: ProcessExportPds.h:110
Isis::Projection::Name
virtual QString Name() const =0
This method returns the name of the map projection.
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::ProcessExportPds::PdsResolution
PdsResolution
Resolution units per pixel of the exported PDS file.
Definition: ProcessExportPds.h:100
Isis::PvlObject::addObject
void addObject(const PvlObject &object)
Add a PvlObject.
Definition: PvlObject.h:307
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::ExportPdsTable::formatPdsTableName
QString formatPdsTableName()
Format the PDS table object name using the ISIS table name.
Definition: ExportPdsTable.cpp:205
Isis::PvlToPvlTranslationManager
Allows applications to translate simple text files.
Definition: PvlToPvlTranslationManager.h:65
Isis::ExportPdsTable::exportTable
PvlObject exportTable(char *pdsTableBuffer, int pdsFileRecordBytes, QString pdsByteOrder)
This methods fills the given buffer with the binary PDS table data and returns label information.
Definition: ExportPdsTable.cpp:67
Isis::FileName::expanded
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:196
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::PvlObject::hasKeyword
bool hasKeyword(const QString &kname, FindOptions opts) const
See if a keyword is in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within ...
Definition: PvlObject.cpp:236
Isis::Table
Class for storing Table blobs information.
Definition: Table.h:61
Isis::BigInt
long long int BigInt
Big int.
Definition: Constants.h:49
Isis::PvlObject::findObject
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:274
Isis::Cube::sampleCount
int sampleCount() const
Definition: Cube.cpp:1807
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::Image
This represents a cube in a project-based GUI interface.
Definition: Image.h:107
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::PvlKeyword::setValue
void setValue(QString value, QString unit="")
Sets new values.
Definition: PvlKeyword.cpp:155
Isis::PvlObject::hasObject
bool hasObject(const QString &name) const
Returns a boolean value based on whether the object exists in the current PvlObject or not.
Definition: PvlObject.h:323
Isis::PvlContainer::deleteKeyword
void deleteKeyword(const QString &name)
Remove a specified keyword.
Definition: PvlContainer.cpp:97
std
Namespace for the standard library.
Isis::PvlKeyword::unit
QString unit(const int index=0) const
Returns the units of measurement of the element of the array of values for the object at the specifie...
Definition: PvlKeyword.cpp:357
Isis::PvlObject::findKeyword
PvlKeyword & findKeyword(const QString &kname, FindOptions opts)
Finds a keyword in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within this...
Definition: PvlObject.cpp:177
Isis::PvlContainer::findKeyword
PvlKeyword & findKeyword(const QString &name)
Find a keyword with a specified name.
Definition: PvlContainer.cpp:62
Isis::Table::Records
int Records() const
Returns the number of records.
Definition: Table.cpp:313
Isis::ProcessExportPds::PdsFileType
PdsFileType
File type to be exported.
Definition: ProcessExportPds.h:84
Isis::Projection
Base class for Map Projections.
Definition: Projection.h:155
Isis::PvlToPvlTranslationManager::Auto
void Auto(Pvl &outputLabel)
Automatically translate all the output names found in the translation table If a output name does not...
Definition: PvlToPvlTranslationManager.cpp:199
Isis::FileName::path
QString path() const
Returns the path of the file name.
Definition: FileName.cpp:103
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16