Isis 3 Programmer Reference
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"
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  // MD5 checksums are 128-bit -> 32 characters when stringified from hex.
240  if (canGenerateChecksum()) {
241  mainPvl += PvlKeyword("CHECKSUM", "????????????????????????????????");
242  }
243  }
244 
245 
251  void ProcessExportPds::StreamJP2ImageRoot(Pvl &mainPvl) {
252  mainPvl.format()->add("$base/translations/pdsExportImageJP2.typ");
253  // Create standard ROOT object keywords
254  mainPvl += PvlKeyword("PDS_VERSION_ID", "PDS3");
255  QString sImageFile = m_detachedPdsLabelFile;
256  if(m_detachedLabel) {
257  int iFound = sImageFile.indexOf(".lbl");
258  if(iFound != -1) {
259  sImageFile.replace(iFound, 4, ".jp2");
260  }
261  else {
262  sImageFile += ".jp2";
263  }
264  }
265  else {
266  QString msg = "Labels must be detached for JP2 files.";
267  throw IException(IException::Programmer, msg, _FILEINFO_);
268  }
269  FileName outFile(sImageFile);
270  PvlObject cmpObj("COMPRESSED_FILE");
271  cmpObj += PvlKeyword("FILE_NAME", outFile.name());
272  cmpObj += PvlKeyword("RECORD_TYPE", "UNDEFINED");
273  cmpObj += PvlKeyword("ENCODING_TYPE", "JP2");
274  cmpObj += PvlKeyword("ENCODING_TYPE_VERSION_NAME", "ISO/IEC15444-1:2004");
275  cmpObj += PvlKeyword("INTERCHANGE_FORMAT", "BINARY");
276  FileName infilename(InputCubes[0]->fileName());
277  cmpObj += PvlKeyword("UNCOMPRESSED_FILE_NAME", infilename.name());
278  int storagebytes = InputCubes[0]->sampleCount() * InputCubes[0]->lineCount();
279  if(p_pixelType == Isis::Real) {
280  QString msg = "JPEG2000 does not support floating point data.";
281  throw IException(IException::Programmer, msg, _FILEINFO_);
282  }
283  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
284  storagebytes = storagebytes * 2;
285  }
286  cmpObj += PvlKeyword("REQUIRED_STORAGE_BYTES", toString(storagebytes));
287  mainPvl.addObject(cmpObj);
288  PvlObject ucmpObj("UNCOMPRESSED_FILE");
289  ucmpObj += PvlKeyword("FILE_NAME", infilename.name());
290  ucmpObj += PvlKeyword("RECORD_TYPE", "FIXED_LENGTH");
291  int recordbytes = InputCubes[0]->sampleCount();
292  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
293  recordbytes = recordbytes * 2;
294  }
295  ucmpObj += PvlKeyword("RECORD_BYTES", toString(recordbytes));
296  ucmpObj += PvlKeyword("FILE_RECORDS", toString(InputCubes[0]->lineCount()));
297  ucmpObj += PvlKeyword("^IMAGE", infilename.name());
298  mainPvl.addObject(ucmpObj);
299  }
300 
301 
307  void ProcessExportPds::FixedImageRoot(Pvl &mainPvl) {
308  //Create fixed ROOT object keywords
309  mainPvl += PvlKeyword("PDS_VERSION_ID", "PDS3");
310  mainPvl += PvlKeyword("RECORD_TYPE", "FIXED_LENGTH");
311  // NOTE: WARNING: If the number of "?"s in the next few lines changes, you
312  // must also changes the corresponding lines in the OutputLabel member
313  mainPvl += PvlKeyword("RECORD_BYTES", "???????");
314  mainPvl += PvlKeyword("FILE_RECORDS", "???????");
315  mainPvl += PvlKeyword("LABEL_RECORDS", "????");
316  if(m_detachedLabel) {
317  QString sImageFile = m_detachedPdsLabelFile;
318  int iFound = sImageFile.indexOf(".lbl");
319  if(iFound != -1) {
320  sImageFile.replace(iFound, 4, ".img");
321  }
322  else {
323  sImageFile += ".img";
324  }
325  FileName outFile(sImageFile);
326  mainPvl += PvlKeyword("^IMAGE", outFile.name());
327  }
328  else {
329  mainPvl += PvlKeyword("^IMAGE", "???");
330  }
331  if (canGenerateChecksum()) {
332  mainPvl += PvlKeyword("CHECKSUM", "????????????????????????????????");
333  }
334  }
335 
336 
342  void ProcessExportPds::FixedJP2ImageRoot(Pvl &mainPvl) {
343  mainPvl.format()->add("$base/translations/pdsExportImageJP2.typ");
344  //Create fixed ROOT object keywords
345  mainPvl += PvlKeyword("PDS_VERSION_ID", "PDS3");
346  QString sImageFile = m_detachedPdsLabelFile;
347  if(m_detachedLabel) {
348  int iFound = sImageFile.indexOf(".lbl");
349  if(iFound != -1) {
350  sImageFile.replace(iFound, 4, ".jp2");
351  }
352  else {
353  sImageFile += ".jp2";
354  }
355  }
356  else {
357  QString msg = "Labels must be detached for JP2 files.";
358  throw IException(IException::Programmer, msg, _FILEINFO_);
359  }
360  FileName outFile(sImageFile);
361  PvlObject cmpObj("COMPRESSED_FILE");
362  cmpObj += PvlKeyword("FILE_NAME", outFile.name());
363  cmpObj += PvlKeyword("RECORD_TYPE", "UNDEFINED");
364  cmpObj += PvlKeyword("ENCODING_TYPE", "JP2");
365  cmpObj += PvlKeyword("ENCODING_TYPE_VERSION_NAME", "ISO/IEC15444-1:2004");
366  cmpObj += PvlKeyword("INTERCHANGE_FORMAT", "BINARY");
367  FileName infilename(InputCubes[0]->fileName());
368  cmpObj += PvlKeyword("UNCOMPRESSED_FILE_NAME", infilename.name());
369  int storagebytes = InputCubes[0]->sampleCount() * InputCubes[0]->lineCount();
370  if(p_pixelType == Isis::Real) {
371  QString msg = "JPEG2000 does not support floating point data.";
372  throw IException(IException::Programmer, msg, _FILEINFO_);
373  }
374  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
375  storagebytes = storagebytes * 2;
376  }
377  cmpObj += PvlKeyword("REQUIRED_STORAGE_BYTES", toString(storagebytes));
378  mainPvl.addObject(cmpObj);
379  PvlObject ucmpObj("UNCOMPRESSED_FILE");
380  ucmpObj += PvlKeyword("FILE_NAME", infilename.name());
381  ucmpObj += PvlKeyword("RECORD_TYPE", "FIXED_LENGTH");
382  int recordbytes = InputCubes[0]->sampleCount();
383  if(p_pixelType == Isis::UnsignedWord || p_pixelType == Isis::SignedWord) {
384  recordbytes = recordbytes * 2;
385  }
386  ucmpObj += PvlKeyword("RECORD_BYTES", toString(recordbytes));
387  ucmpObj += PvlKeyword("FILE_RECORDS", toString(InputCubes[0]->lineCount()));
388  ucmpObj += PvlKeyword("^IMAGE", infilename.name());
389  mainPvl.addObject(ucmpObj);
390  }
391 
392 
402  void ProcessExportPds::StandardImageImage(Pvl &mainPvl) {
403  mainPvl.format()->add("$base/translations/pdsExportImageImage.typ");
404  // Build up an IMAGE object:
405  // Auto translate standard keywords for the IMAGE object
406  Pvl *inputLabel = InputCubes[0]->label();
407  FileName transfile;
408  transfile = "$base/translations/pdsExportImageImage.trn";
409  PvlToPvlTranslationManager Xlator(*inputLabel, transfile.expanded());
410  Xlator.Auto(mainPvl);
411 
412  // Calculate the core base/mult for this cube
413  double base = 0.0;
414  double multiplier = 1.0;
415  double x1, x2;
416 
417  double minimum = (p_inputMinimum.size()) ? p_inputMinimum[0] : 0.0;
418  double maximum = (p_inputMaximum.size()) ? p_inputMaximum[0] : 0.0;
419 
420  for(unsigned int i = 0; i < p_inputMinimum.size(); i ++) {
421  minimum = std::min(minimum, p_inputMinimum[i]);
422  maximum = std::max(maximum, p_inputMaximum[i]);
423  }
424 
425  x1 = p_outputMinimum;
426  x2 = p_outputMaximum;
427 
428  if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedByte) {
429  multiplier = (maximum - minimum) / (x2 - x1);
430  base = minimum - multiplier * x1;
431  }
432  else if(p_inputMinimum.size() && p_pixelType == Isis::SignedWord) {
433  multiplier = (maximum - minimum) / (x2 - x1);
434  base = minimum - multiplier * x1;
435  }
436  else if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedWord) {
437  multiplier = (maximum - minimum) / (x2 - x1);
438  base = minimum - multiplier * x1;
439  }
440 
441  // Manually set the keyword for the number of bits in a pixel
442  // NOTE: this is dependent on settings in ProcessExport and not the cube
443  PvlObject &imgObj = mainPvl.findObject("IMAGE");
444 
445  if(!m_forceBands) imgObj.deleteKeyword("BANDS");
446  if(!m_forceBandName && imgObj.hasKeyword("BAND_NAME")) imgObj.deleteKeyword("BAND_NAME");
447  if(!m_forceCenterFilterWavelength && imgObj.hasKeyword("CENTER_FILTER_WAVELENGTH")) imgObj.deleteKeyword("CENTER_FILTER_WAVELENGTH");
448  if(!m_forceBandwidth && imgObj.hasKeyword("BANDWIDTH")) imgObj.deleteKeyword("BANDWIDTH");
449 
450  if(m_forceBandStorageType) imgObj += PvlKeyword("BAND_STORAGE_TYPE", "BAND_SEQUENTIAL");
451  if(m_forceOffset) imgObj += PvlKeyword("OFFSET", toString(base));
452  if(m_forceScalingFactor) imgObj += PvlKeyword("SCALING_FACTOR", toString(multiplier));
453 
454  // Manually set the keyword for pixel type and special pixels
455  if(p_pixelType == Isis::UnsignedByte) {
456  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "8");
457  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xff));
458  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
459  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
460  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
461  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
462  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
463  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
464  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel8.typ");
465  }
466  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Msb)) {
467  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
468  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
469  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
470  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
471  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
472  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
473  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
474  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
475  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
476  }
477  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Lsb)) {
478  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
479  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
480  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_UNSIGNED_INTEGER");
481  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
482  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
483  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
484  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
485  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
486  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
487  }
488  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Msb)) {
489  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
490  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
491  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_INTEGER");
492  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
493  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
494  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
495  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
496  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
497  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
498  }
499  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Lsb)) {
500  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
501  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffff));
502  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_INTEGER");
503  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
504  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
505  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
506  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
507  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
508  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
509  }
510  else if(p_pixelType == Isis::Real) {
511  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "32");
512  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffffffff));
513 
514  if(p_endianType == Isis::Msb) {
515  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "IEEE_REAL");
516  }
517  else {
518  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "PC_REAL");
519  }
520  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString(Isis::INULL4));
521  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString(Isis::ILOW_REPR_SAT4));
522  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString(Isis::ILOW_INSTR_SAT4));
523  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString(Isis::IHIGH_REPR_SAT4));
524  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString(Isis::IHIGH_INSTR_SAT4));
525  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel32.typ");
526  }
527  else {
528  QString msg = "Unsupported PDS pixel type or sample size";
529  throw IException(IException::User, msg, _FILEINFO_);
530  }
531  }
532 
533 
543  void ProcessExportPds::StandardJP2Image(Pvl &mainPvl) {
544  mainPvl.format()->add("$base/translations/pdsExportImageImage.typ");
545  if(m_pdsFileType == ProcessExportPds::JP2Image) {
546  mainPvl.format()->add("$base/translations/pdsExportImageJP2.typ");
547  }
548  // Build up a JP2 IMAGE object:
549  // Auto translate standard keywords for the IMAGE object
550  Pvl *inputLabel = InputCubes[0]->label();
551  FileName transfile;
552  transfile = "$base/translations/pdsExportImageJP2.trn";
553  PvlToPvlTranslationManager Xlator(*inputLabel, transfile.expanded());
554  Xlator.Auto(mainPvl);
555 
556  // Calculate the core base/mult for this cube
557  double base = 0.0;
558  double multiplier = 1.0;
559  double x1, x2;
560 
561  double minimum = (p_inputMinimum.size()) ? p_inputMinimum[0] : 0.0;
562  double maximum = (p_inputMaximum.size()) ? p_inputMaximum[0] : 0.0;
563 
564  for(unsigned int i = 0; i < p_inputMinimum.size(); i ++) {
565  minimum = std::min(minimum, p_inputMinimum[i]);
566  maximum = std::max(maximum, p_inputMaximum[i]);
567  }
568 
569  x1 = p_outputMinimum;
570  x2 = p_outputMaximum;
571 
572  if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedByte) {
573  multiplier = (maximum - minimum) / (x2 - x1);
574  base = minimum - multiplier * x1;
575  }
576  else if(p_inputMinimum.size() && p_pixelType == Isis::SignedWord) {
577  multiplier = (maximum - minimum) / (x2 - x1);
578  base = minimum - multiplier * x1;
579  }
580  else if(p_inputMinimum.size() && p_pixelType == Isis::UnsignedWord) {
581  multiplier = (maximum - minimum) / (x2 - x1);
582  base = minimum - multiplier * x1;
583  }
584 
585  // Manually set the keyword for the number of bits in a pixel
586  // NOTE: this is dependent on settings in ProcessExport and not the cube
587  PvlObject &imgObj = mainPvl.findObject("UNCOMPRESSED_FILE").findObject("IMAGE");
588 
589  if(!m_forceBands) imgObj.deleteKeyword("BANDS");
590  if(!m_forceBandName && imgObj.hasKeyword("BAND_NAME")) imgObj.deleteKeyword("BAND_NAME");
591  if(!m_forceCenterFilterWavelength && imgObj.hasKeyword("CENTER_FILTER_WAVELENGTH")) imgObj.deleteKeyword("CENTER_FILTER_WAVELENGTH");
592  if(!m_forceBandwidth && imgObj.hasKeyword("BANDWIDTH")) imgObj.deleteKeyword("BANDWIDTH");
593 
594  if(m_forceBandStorageType) imgObj += PvlKeyword("BAND_STORAGE_TYPE", "BAND_SEQUENTIAL");
595  if(m_forceOffset) imgObj += PvlKeyword("OFFSET", toString(base));
596  if(m_forceScalingFactor) imgObj += PvlKeyword("SCALING_FACTOR", toString(multiplier));
597 
598  // Manually set the keyword for pixel type and special pixels
599  if(p_pixelType == Isis::UnsignedByte) {
600  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "8");
601  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xff));
602  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
603  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
604  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
605  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
606  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
607  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
608  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel8.typ");
609  }
610  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Msb)) {
611  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
612  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
613  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_UNSIGNED_INTEGER");
614  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
615  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
616  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
617  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
618  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
619  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
620  }
621  else if((p_pixelType == Isis::UnsignedWord) && (p_endianType == Isis::Lsb)) {
622  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
623  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
624  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_UNSIGNED_INTEGER");
625  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
626  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
627  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
628  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
629  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
630  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
631  }
632  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Msb)) {
633  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
634  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString(0xffff));
635  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "MSB_INTEGER");
636  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
637  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
638  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
639  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
640  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
641  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
642  }
643  else if((p_pixelType == Isis::SignedWord) && (p_endianType == Isis::Lsb)) {
644  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "16");
645  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffff));
646  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "LSB_INTEGER");
647  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString((int)OutputNull()));
648  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString((int)OutputLrs()));
649  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString((int)OutputLis()));
650  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString((int)OutputHrs()));
651  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString((int)OutputHis()));
652  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel16.typ");
653  }
654  else if(p_pixelType == Isis::Real) {
655  if(m_forceSampleBits) imgObj += PvlKeyword("SAMPLE_BITS", "32");
656  if(m_forceSampleBitMask) imgObj += PvlKeyword("SAMPLE_BIT_MASK", toString((BigInt)0xffffffff));
657 
658  if(p_endianType == Isis::Msb) {
659  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "IEEE_REAL");
660  }
661  else {
662  if(m_forceSampleType) imgObj += PvlKeyword("SAMPLE_TYPE", "PC_REAL");
663  }
664  if(m_forceCoreNull) imgObj += PvlKeyword("CORE_NULL", toString(Isis::INULL4));
665  if(m_forceCoreLrs) imgObj += PvlKeyword("CORE_LOW_REPR_SATURATION", toString(Isis::ILOW_REPR_SAT4));
666  if(m_forceCoreLis) imgObj += PvlKeyword("CORE_LOW_INSTR_SATURATION", toString(Isis::ILOW_INSTR_SAT4));
667  if(m_forceCoreHrs) imgObj += PvlKeyword("CORE_HIGH_REPR_SATURATION", toString(Isis::IHIGH_REPR_SAT4));
668  if(m_forceCoreHis) imgObj += PvlKeyword("CORE_HIGH_INSTR_SATURATION", toString(Isis::IHIGH_INSTR_SAT4));
669  mainPvl.format()->add("$base/translations/pdsExportImageImagePixel32.typ");
670  }
671  else {
672  QString msg = "Unsupported PDS pixel type or sample size";
673  throw IException(IException::User, msg, _FILEINFO_);
674  }
675  }
676 
677 
686  void ProcessExportPds::StandardAllMapping(Pvl &outputPvl) {
687 
688  // Get the input Isis cube label and find the Mapping group if it has one
689  Pvl *inputLabel = InputCubes[0]->label();
690  if(inputLabel->hasObject("IsisCube") &&
691  !(inputLabel->findObject("IsisCube").hasGroup("Mapping"))) return;
692  PvlGroup &inputMapping = inputLabel->findGroup("Mapping", Pvl::Traverse);
693 
694  // Translate the projection specific keywords for a PDS IMAGE_MAP_PROJECTION
695  QString projName = ProjectionName(*inputLabel);
696  PvlToPvlTranslationManager xlatSpecProj(*inputLabel,
697  "$base/translations/pdsExport" + projName + ".trn");
698  xlatSpecProj.Auto(outputPvl);
699 
700  // Translate the target name
701  PvlToPvlTranslationManager xlatTarget(*inputLabel,
702  "$base/translations/pdsExportTarget.trn");
703  xlatTarget.Auto(outputPvl);
704 
705  // Add keywords to the PDS labels that could not be handled automatically
706  PvlObject &pdsMapObj = outputPvl.findObject("IMAGE_MAP_PROJECTION");
707 
708  // Add the projection name
709 // pdsMapObj += PvlKeyword ("MAP_PROJECTION_TYPE", projName.toUpper());
710 
711  // Modify the radii to be km.
712  PvlKeyword &aRadius = pdsMapObj["A_AXIS_RADIUS"];
713  QString unit = aRadius.unit();
714  if( (unit.toUpper() == "METERS") || (unit == "") ) { //if no units, assume in meters
715  double dValue = (double)aRadius;
716  dValue /= 1000.0;
717  aRadius.setValue(toString(dValue), "KM");
718  }
719  PvlKeyword &bRadius = pdsMapObj["B_AXIS_RADIUS"];
720  unit = bRadius.unit();
721  if( (unit.toUpper() == "METERS") || (unit == "") ) {
722  double dValue = (double)bRadius;
723  dValue /= 1000.0;
724  bRadius.setValue(toString(dValue), "KM");
725  }
726  PvlKeyword &cRadius = pdsMapObj["C_AXIS_RADIUS"];
727  unit = cRadius.unit();
728  if( (unit.toUpper() == "METERS") || (unit == "") ) {
729  double dValue = (double)cRadius;
730  dValue /= 1000.0;
731  cRadius.setValue(toString(dValue), "KM");
732  }
733 
734  // Modify the units on MAP_SCALE and MAP_RESOLUTION
735  PvlKeyword &mapScale = pdsMapObj["MAP_SCALE"];
736  unit = mapScale.unit();
737  //if no units, assume in meters/pixel
738  if( (unit.toUpper() == "METERS/PIX") || (unit.toUpper() == "METERS/PIXEL") || (unit == "") ) {
739  if(m_exportResolution == Kilometer) {
740  double dValue = (double)mapScale;
741  dValue /= 1000.0;
742  mapScale.setValue(toString(dValue), "KM/PIXEL");
743  }
744  else {
745  mapScale.setValue(toString((double)mapScale), "METERS/PIXEL");
746  }
747  }
748  PvlKeyword &mapRes = pdsMapObj["MAP_RESOLUTION"];
749  unit = mapRes.unit();
750  //if no units, asume in pixels/degree
751  if( (unit.toUpper() == "PIXELS/DEGREE") || (unit == "") ) {
752  mapRes.setValue((QString)mapRes, "PIX/DEG");
753  }
754 
755  // Add the EASTERNMOST AND WESTERNMOST LONGITUDE keywords
756  PvlKeyword &isisLonDir = inputMapping.findKeyword("LongitudeDirection");
757  QString lonDir = isisLonDir[0];
758  lonDir = lonDir.toUpper();
759  if (inputMapping.hasKeyword("MaximumLongitude") && inputMapping.hasKeyword("MinimumLongitude")) {
760  double maxLon = inputMapping.findKeyword("MaximumLongitude");
761  double minLon = inputMapping.findKeyword("MinimumLongitude");
762  if(lonDir == "POSITIVEEAST") {
763  pdsMapObj += PvlKeyword("EASTERNMOST_LONGITUDE", toString(maxLon));
764  pdsMapObj += PvlKeyword("WESTERNMOST_LONGITUDE", toString(minLon));
765  }
766  else {
767  pdsMapObj += PvlKeyword("EASTERNMOST_LONGITUDE", toString(minLon));
768  pdsMapObj += PvlKeyword("WESTERNMOST_LONGITUDE", toString(maxLon));
769  }
770  }
771 
772  // Add the LINE_PROJECTION_OFFSET and SAMPLE_PROJECTION_OFFSET keywords
773  // These keywords are the distance from the origin of the image to the
774  // origin of the projection. The units are line or samples. The image origin
775  // is the middle of pixel (1,1)
776  double lineOffset = inputMapping.findKeyword("UpperLeftCornerY");
777  lineOffset /= (double)inputMapping.findKeyword("PixelResolution");
778  lineOffset *= 1.0;
779  lineOffset -= 0.5; // Add half a line to get to the center of (1,1)
780  pdsMapObj += PvlKeyword("LINE_PROJECTION_OFFSET", toString(lineOffset), "PIXEL");
781  double sampleOffset = inputMapping.findKeyword("UpperLeftCornerX");
782  sampleOffset /= (double)inputMapping.findKeyword("PixelResolution");
783  sampleOffset *= -1.0;
784  sampleOffset -= 0.5; // Add half a sample to get to the center of (1,1)
785  pdsMapObj += PvlKeyword("SAMPLE_PROJECTION_OFFSET", toString(sampleOffset), "PIXEL");
786 
787  // Add units to keywords already in the IMAGE_MAP_PROJECTION object as necessary
788  if(pdsMapObj.hasKeyword("CENTER_LATITUDE")) {
789  PvlKeyword &tempKey = pdsMapObj.findKeyword("CENTER_LATITUDE");
790  tempKey.setValue(tempKey[0], "DEG");
791  }
792  if(pdsMapObj.hasKeyword("CENTER_LONGITUDE")) {
793  PvlKeyword &tempKey = pdsMapObj.findKeyword("CENTER_LONGITUDE");
794  tempKey.setValue(tempKey[0], "DEG");
795  }
796 // if (pdsMapObj.hasKeyword("REFERENCE_LATITUDE")) {
797 // PvlKeyword &tempKey = pdsMapObj.findKeyword("REFERENCE_LATITUDE");
798 // tempKey.setValue(tempKey[0], "DEG");
799 // }
800  if(pdsMapObj.hasKeyword("REFERENCE_LONGITUDE")) {
801  PvlKeyword &tempKey = pdsMapObj.findKeyword("REFERENCE_LONGITUDE");
802  tempKey.setValue(tempKey[0], "DEG");
803  }
804  if(pdsMapObj.hasKeyword("MAXIMUM_LATITUDE")) {
805  PvlKeyword &tempKey = pdsMapObj.findKeyword("MAXIMUM_LATITUDE");
806  tempKey.setValue(tempKey[0], "DEG");
807  }
808  if(pdsMapObj.hasKeyword("MINIMUM_LATITUDE")) {
809  PvlKeyword &tempKey = pdsMapObj.findKeyword("MINIMUM_LATITUDE");
810  tempKey.setValue(tempKey[0], "DEG");
811  }
812  if(pdsMapObj.hasKeyword("EASTERNMOST_LONGITUDE")) {
813  PvlKeyword &tempKey = pdsMapObj.findKeyword("EASTERNMOST_LONGITUDE");
814  tempKey.setValue(tempKey[0], "DEG");
815  }
816  if(pdsMapObj.hasKeyword("WESTERNMOST_LONGITUDE")) {
817  PvlKeyword &tempKey = pdsMapObj.findKeyword("WESTERNMOST_LONGITUDE");
818  tempKey.setValue(tempKey[0], "DEG");
819  }
820  if(pdsMapObj.hasKeyword("MAP_PROJECTION_ROTATION")) {
821  PvlKeyword &tempKey = pdsMapObj.findKeyword("MAP_PROJECTION_ROTATION");
822  tempKey.setValue(tempKey[0], "DEG");
823  }
824 
825  }
826 
827 
835  QString ProcessExportPds::ProjectionName(Pvl &inputLabel) {
836  Projection *proj = ProjectionFactory::Create(inputLabel);
837  QString name = proj->Name();
838  delete proj;
839  return name;
840  }
841 
842 
849  int ProcessExportPds::LineBytes() {
850  Cube *cube = InputCubes[0];
851  int a = SizeOf(p_pixelType);
852  int b = cube->sampleCount();
853  return b * a ;
854  }
855 
856 
862  int ProcessExportPds::LabelSize() {
863  ostringstream temp;
864  if(m_label->format() != NULL) {
865  temp << *m_label << m_label->format()->formatEOL();
866  }
867  else {
868  temp << *m_label << endl;
869  }
870  return temp.tellp();
871  }
872 
878  void ProcessExportPds::OutputDetachedLabel() {
879  if(!m_detachedLabel) {
880  QString msg = "Unable to output detached label. Use "
881  "ProcessExportPds::SetDetached() to set the "
882  "output PDS label file name.";
883  throw IException(IException::Unknown, msg, _FILEINFO_);
884  }
885  std::ofstream sOutLabelStream(m_detachedPdsLabelFile.toLatin1().data());
886  OutputLabel(sOutLabelStream);
887  sOutLabelStream.close();
888  }
889 
897  void ProcessExportPds::OutputLabel(std::ofstream &os) {
898  int labSize = LabelSize(); // labSize will be the old label size with "?"
899  // NOTE: WARNING: If anything changes in the next two lines, you must also changes the
900  // corresponding lines in the StandardImageRoot member
901 
902  if(m_exportType == Stream) {
903  if(m_pdsFileType != ProcessExportPds::JP2Image) {
904  (*m_label)["LABEL_RECORDS"].setValue(toString(labSize), "BYTES");
905  if(!m_detachedLabel) {
906  (*m_label)["^IMAGE"].setValue(toString(labSize + 1), "BYTES");
907  }
908  }
909  if(m_label->format() != NULL) {
910  os << *m_label << m_label->format()->formatEOL();
911  }
912  else {
913  os << *m_label << endl;
914  }
915  // Fill the difference between the old and new label size with spaces.
916  if(m_pdsFileType != ProcessExportPds::JP2Image) {
917  for(int i = LabelSize(); i < labSize; ++i) os << ' ';
918  }
919  }
920  else if(m_exportType == Fixed) {
921  int lineBytes;
922  int labelRecords;
923  if(m_pdsFileType != ProcessExportPds::JP2Image) {
924  lineBytes = LineBytes();
925  (*m_label)["RECORD_BYTES"].setValue(toString(lineBytes));
926 
927  // The number of label records is dependent on the number of label bytes
928  // and the lint bytes
929  labelRecords = (int)ceil((double)labSize / (double)lineBytes);
930  if(m_label->hasKeyword("LABEL_RECORDS")) { //LRO MRF doesn't have this keyword
931  (*m_label)["LABEL_RECORDS"].setValue(toString(labelRecords));
932  }
933  int totalTableRecords = 0;
934  for (unsigned int i = 0; i < m_tableRecords.size(); i++) {
935  totalTableRecords += m_tableRecords[i];
936  }
937  int imageRecords = InputCubes[0]->lineCount()
938  * InputCubes[0]->bandCount();
939  int fileRecords = labelRecords + imageRecords + totalTableRecords;
940  (*m_label)["FILE_RECORDS"].setValue(toString(fileRecords));
941 
942  if(!m_detachedLabel) {
943  (*m_label)["^IMAGE"].setValue(toString(labelRecords + 1));
944  }
945  }
946  if(m_label->format() != NULL) {
947  os << *m_label << m_label->format()->formatEOL();
948  }
949  else {
950  os << *m_label << endl;
951  }
952  if(m_pdsFileType != ProcessExportPds::JP2Image) {
953  for(int i = LabelSize(); i < labelRecords * lineBytes; ++i) os << ' ';
954  }
955  }
956 
957  }
958 
959 
965  void ProcessExportPds::updateChecksumInLabel(std::ofstream &pdsFileStream) {
966  // This occurs after application has called its StartProcess and the checksum has been
967  // generated. We need to seek to the top of the file to rewrite the label. Since the
968  // CHECKSUM is MD5, we set aside 32 characters for the value of this keyword. Since
969  // OuputLabel() has already created the label and necessary padding, we can simply update
970  // the CHECKSUM value to the generated checksum and re-write the entire label.
971  pdsFileStream.seekp(0);
972  (*m_label)["CHECKSUM"].setValue(checksum());
973  pdsFileStream << *m_label;
974  }
975 
976 
1008  void ProcessExportPds::ExportTable(Table isisTable, QString detachedPdsTableFileName) {
1009 
1010  if(Attached() && detachedPdsTableFileName != "") {
1011  QString msg = "The output PDS file has been set to attached and a "
1012  "detached PDS table file name has been given. If detached "
1013  "is preferred, set the process to detached SetDetached() "
1014  "and call StandardPdsLabel() before calling ExportTable().";
1015  throw IException(IException::Unknown, msg, _FILEINFO_);
1016  }
1017 
1018  if(Detached() && detachedPdsTableFileName == "") {
1019  QString msg = "The output PDS file has been set to detached. A file name "
1020  "for the detached ouput PDS table file is required. "
1021  "If an attached output file is prefered, use the method "
1022  "ProcessExportPds::SetAttached() before calling ExportTable().";
1023  throw IException(IException::Unknown, msg, _FILEINFO_);
1024  }
1025 
1026  // create an ExportPdsTable to fill file stream with PDS Table info
1027  ExportPdsTable pdsTable(isisTable);
1028  int fileRecordBytes = LineBytes();
1029  // return metadata pvl containing needed information for the output label.
1030 
1031  char *tableBuffer = new char[isisTable.Records() * fileRecordBytes];
1032  PvlObject metadata = pdsTable.exportTable(tableBuffer,
1033  fileRecordBytes,
1034  ByteOrderName(p_endianType));
1035  QString pdsTableName = pdsTable.formatPdsTableName();
1036  Pvl &mainPvl = *m_label;
1037  if (Attached()) {
1038  m_tableBuffers.push_back(tableBuffer);
1039  int labSize = LabelSize(); // labSize will be the old label size with "?"
1040  int labelRecords = (int)ceil((double)labSize / (double)fileRecordBytes);
1041  int imageRecords = InputCubes[0]->lineCount()
1042  * InputCubes[0]->bandCount();
1043  int totalTableRecords = 0;
1044  for (unsigned int i = 0; i < m_tableRecords.size(); i++) {
1045  totalTableRecords += m_tableRecords[i];
1046  }
1047  // for start record values, indexing begins with 1
1048  int tableStartRecord = 1 + labelRecords + imageRecords + totalTableRecords;
1049  mainPvl += PvlKeyword("^" + pdsTableName, toString(tableStartRecord));
1050  }
1051  else {
1052  mainPvl += PvlKeyword("^" + pdsTableName, detachedPdsTableFileName);
1053  FileName labelFile(m_detachedPdsLabelFile);
1054  QString tableFileWithPath = labelFile.path() + "/"
1055  + detachedPdsTableFileName;
1056  ofstream os(tableFileWithPath.toLatin1().data());
1057  os.write(tableBuffer, isisTable.Records() * fileRecordBytes);
1058  os.close();
1059  }
1060  mainPvl.addObject(metadata);
1061  m_tableRecords.push_back(isisTable.Records());
1062  return;
1063  }
1064 
1073  void ProcessExportPds::SetDetached(QString detachedLabelFile) {
1074  m_detachedLabel = true;
1075  m_detachedPdsLabelFile = detachedLabelFile;
1076  return;
1077  }
1078 
1084  void ProcessExportPds::SetAttached() {
1085  m_detachedLabel = false;
1086  m_detachedPdsLabelFile = "";
1087  }
1088 
1094  bool ProcessExportPds::Detached() {
1095  return m_detachedLabel;
1096  }
1097 
1103  bool ProcessExportPds::Attached() {
1104  return !m_detachedLabel;
1105  }
1106 
1113  void ProcessExportPds::SetPdsResolution(PdsResolution resolutionUnits) {
1114  m_exportResolution = resolutionUnits;
1115  }
1116 
1124  void ProcessExportPds::SetExportType(PdsExportType recordFormat) {
1125  m_exportType = recordFormat;
1126  }
1127 
1136  void ProcessExportPds::ForceBands(bool force) {
1137  m_forceBands = force;
1138  }
1139 
1149  void ProcessExportPds::ForceBandName(bool force) {
1150  m_forceBandName = force;
1151  }
1152 
1162  void ProcessExportPds::ForceCenterFilterWavelength(bool force) {
1163  m_forceCenterFilterWavelength = force;
1164  }
1165 
1175  void ProcessExportPds::ForceBandwidth(bool force) {
1176  m_forceBandwidth = force;
1177  }
1178 
1188  void ProcessExportPds::ForceBandStorageType(bool force) {
1189  m_forceBandStorageType = force;
1190  }
1191 
1201  void ProcessExportPds::ForceOffset(bool force) {
1202  m_forceOffset = force;
1203  }
1204 
1214  void ProcessExportPds::ForceScalingFactor(bool force) {
1215  m_forceScalingFactor = force;
1216  }
1217 
1227  void ProcessExportPds::ForceSampleBits(bool force) {
1228  m_forceSampleBits = force;
1229  }
1230 
1240  void ProcessExportPds::ForceSampleBitMask(bool force) {
1241  m_forceSampleBitMask = force;
1242  }
1243 
1253  void ProcessExportPds::ForceSampleType(bool force) {
1254  m_forceSampleType = force;
1255  }
1256 
1266  void ProcessExportPds::ForceCoreNull(bool force) {
1267  m_forceCoreNull = force;
1268  }
1269 
1279  void ProcessExportPds::ForceCoreLrs(bool force) {
1280  m_forceCoreLrs = force;
1281  }
1282 
1293  void ProcessExportPds::ForceCoreLis(bool force) {
1294  m_forceCoreLis = force;
1295  }
1296 
1307  void ProcessExportPds::ForceCoreHrs(bool force) {
1308  m_forceCoreHrs = force;
1309  }
1310 
1321  void ProcessExportPds::ForceCoreHis(bool force) {
1322  m_forceCoreHis = force;
1323  }
1324 
1332  void ProcessExportPds::StartProcess(std::ofstream &fout) {
1333  ProcessExport::StartProcess(fout);
1334  if (!m_detachedLabel) {
1335  for (unsigned int i = 0; i < m_tableBuffers.size(); i++) {
1336  if (m_tableBuffers[i] == NULL) {
1337  QString msg = "Unable to add tables to PDS output file.";
1338  throw IException(IException::Unknown, msg, _FILEINFO_);
1339  }
1340  // write each table buffer to fout.
1341  // For each table, use (number of records)*(bytes per record) to
1342  // determine how many bytes to write out.
1343  fout.write(m_tableBuffers[i], m_tableRecords[i]*LineBytes());
1344  }
1345  }
1346  return;
1347  }
1348 
1349 } // End of Isis namespace
long long int BigInt
Big int.
Definition: Constants.h:65
int Records() const
Returns the number of records.
Definition: Table.cpp:224
QString path() const
Returns the path of the file name.
Definition: FileName.cpp:119
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
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:373
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
File name manipulation and expansion.
Definition: FileName.h:116
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:286
int sampleCount() const
Definition: Cube.cpp:1452
int SizeOf(Isis::PixelType pixelType)
Returns the number of bytes of the specified PixelType.
Definition: PixelType.h:62
Namespace for the standard library.
PdsFileType
File type to be exported.
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:178
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
Allows applications to translate simple text files.
Formats the value of a PvlKeyword into a PDS complient string.
Definition: PvlFormatPds.h:61
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:207
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:335
void addObject(const PvlObject &object)
Add a PvlObject.
Definition: PvlObject.h:319
PvlObject exportTable(char *pdsTableBuffer, int pdsFileRecordBytes, QString pdsByteOrder)
This methods fills the given buffer with the binary PDS table data and returns label information...
Base class for Map Projections.
Definition: Projection.h:171
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:148
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A single keyword-value pair.
Definition: PvlKeyword.h:98
PdsExportType
Record format type of exported PDS file.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
This represents a cube in a project-based GUI interface.
Definition: Image.h:107
Container for cube-like labels.
Definition: Pvl.h:135
PvlKeyword & findKeyword(const QString &name)
Find a keyword with a specified name.
Class for storing Table blobs information.
Definition: Table.h:77
PdsResolution
Resolution units per pixel of the exported PDS file.
QString formatPdsTableName()
Format the PDS table object name using the Isis3 table name.
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
void Auto(Pvl &outputLabel)
Automatically translate all the output names found in the translation table If a output name does not...
Export a PDS table from an Isis3 Table.
void setValue(QString value, QString unit="")
Sets new values.
Definition: PvlKeyword.cpp:171
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:74
virtual QString Name() const =0
This method returns the name of the map projection.
void deleteKeyword(const QString &name)
Remove a specified keyword.
IO Handler for Isis Cubes.
Definition: Cube.h:170