OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimNitfImageHeaderV2_1.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: MIT
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: Garrett Potts
8 //
9 // Description: Nitf support class
10 //
11 //********************************************************************
12 // $Id$
13 
14 #include <ossim/base/ossimTrace.h>
15 #include <ossim/base/ossimString.h>
16 #include <ossim/base/ossimDms.h>
17 #include <ossim/base/ossimIrect.h>
21 #include <ossim/base/ossimEndian.h>
27 
28 #include <sstream>
29 #include <iomanip>
30 #include <cstring> // for memset
31 
33  "ossimNitfImageHeaderV2_1",
35 
52 const ossimString NBANDS_KW = "nbands";
53 
54 static const
55 ossimTrace traceDebug(ossimString("ossimNitfImageHeaderV2_1:debug"));
56 
58 {
59  clearFields();
60 }
62 {
63 }
64 
66 {
67  parseStream(in, NULL);
68 }
69 
71 {
72  if (!in)
73  {
74  return;
75  }
76  clearFields();
77  theTagList.clear();
78  in.read(theType, 2);
79  in.read(theImageId, 10);
80  in.read(theDateTime,14);
81  in.read(theTargetId, 17);
82  in.read(theTitle, 80);
83  in.read(theSecurityClassification, 1);
84  in.read(theSecurityClassificationSys, 2);
85  in.read(theCodewords, 11);
86  in.read(theControlAndHandling, 2);
87  in.read(theReleasingInstructions, 20);
88  in.read(theDeclassificationType, 2);
89  in.read(theDeclassificationDate, 8);
90  in.read(theDeclassificationExempt, 4);
91  in.read(theDowngrade, 1);
92  in.read(theDowngradeDate, 8);
93  in.read(theClassificationText, 43);
94  in.read(theClassificationAuthType, 1);
95  in.read(theClassificationAuthority, 40);
96  in.read(theClassificationReason, 1);
97  in.read(theSecuritySourceDate, 8);
98  in.read(theSecurityControlNumber, 15);
99  in.read(theEncryption, 1);
100  in.read(theImageSource, 42);
101  in.read(theSignificantRows, 8);
102  in.read(theSignificantCols, 8);
103  in.read(thePixelValueType, 3);
104  in.read(theRepresentation, 8);
105  in.read(theCategory, 8);
106  in.read(theActualBitsPerPixelPerBand, 2);
107  in.read(theJustification, 1);
108  in.read(theCoordinateSystem, 1);
109  // if it's not blank then read coordinates
110  if(theCoordinateSystem[0] != ' ')
111  {
112  in.read(theGeographicLocation, 60);
113  }
114 
115  // Up to 3 80 character comments treated as a single comment.
116  in.read(theNumberOfComments, 1);
117  ossim_int32 numberOfComments = ossimString(theNumberOfComments).toInt32();
118  if(numberOfComments > 0)
119  {
120  theImageComments.resize(numberOfComments);
121  for (ossim_uint32 i=0; i < numberOfComments; ++i)
122  {
123  char comment[81];
124  memset(comment, ' ', 80);
125  comment[80] = '\0';
126  in.read(comment, 80);
127  theImageComments[i] = ossimString(comment).trim();
128  }
129  }
130 
131  in.read(theCompression, 2);
132 
133  // only need the Rate code if its not
134  // NC (No compression)
136  if((temp != "NC") &&
137  (temp != "NM"))
138  {
139  in.read(theCompressionRateCode, 4);
140  }
141  in.read(theNumberOfBands, 1);
142  // check to see if multi spectral bands
143  // exceed 9. A value of 0 indicates this
144  ossim_int32 numberOfBands = ossimString(theNumberOfBands).toInt32();
145  if (numberOfBands == 0)
146  {
147  in.read(theNumberOfMultispectralBands, 5);
149  }
150  theImageBands.clear();
151  theImageBands.resize(numberOfBands);
152  for (ossim_int32 band = 0; band < numberOfBands; ++band)
153  {
155  theImageBands[band]->parseStream(in);
156  }
157  in.read(theImageSyncCode, 1);
158  in.read(theImageMode, 1);
159  in.read(theNumberOfBlocksPerRow, 4);
160  in.read(theNumberOfBlocksPerCol, 4);
161  in.read(theNumberOfPixelsPerBlockHoriz, 4);
162  in.read(theNumberOfPixelsPerBlockVert, 4);
163  in.read(theNumberOfBitsPerPixelPerBand, 2);
164  in.read(theDisplayLevel, 3);
165  in.read(theAttachmentLevel, 3);
166  in.read(theImageLocation, 10);
167  in.read(theImageMagnification, 4);
168  in.read(theUserDefinedImageDataLength, 5);
169 
170  ossimNitfTagInformation headerTag;
171  std::streampos start = in.tellg();
172  std::streampos current = in.tellg();
173 
174  std::streampos userDefinedDataLen
176  if(userDefinedDataLen > 0)
177  {
178  in.read(theUserDefinedOverflow, 3);
179  current = in.tellg();
180 
181  while((current - start) < userDefinedDataLen)
182  {
183  headerTag.parseStream(in);
184  theTagList.push_back(headerTag);
185  headerTag.setTagType("UDID");
186  // in.ignore(headerTag.getTagLength());
187  // headerTag.clearFields();
188  current = in.tellg();
189  }
190 // in.seekg(start + userDefinedDataLen);
192  if (overflow != 0 && file != NULL)
193  {
194  ossimNitfDataExtensionSegment *des = file->getNewDataExtensionSegment(overflow-1, in);
195  if (des != NULL)
196  {
197  const vector<ossimNitfTagInformation> &desTags = des->getTagList();
198  for (vector<ossimNitfTagInformation>::const_iterator iter = desTags.begin(); iter != desTags.end(); ++iter)
199  {
200  iter->setTagType("UDID");
201  theTagList.push_back(*iter);
202  }
203  }
204  delete des;
205  }
206  ossimIFStream64::seekg64(in, start + userDefinedDataLen, ios::beg);
207  }
208  in.read(theExtendedSubheaderDataLen, 5);
209  std::streampos extSubHeadLen = ossimString(theExtendedSubheaderDataLen).toInt32();
210  start = in.tellg();
211  current = in.tellg();
212  if(extSubHeadLen > 0)
213  {
214  in.read(theExtendedSubheaderOverflow, 3);
215  current = in.tellg();
216  while((current - start) < extSubHeadLen)
217  {
218  headerTag.parseStream(in);
219  headerTag.setTagType("IXSHD");
220  theTagList.push_back(headerTag);
221 
222  // in.ignore(headerTag.getTagLength());
223  // headerTag.clearFields();
224  current = in.tellg();
225  }
226 // in.seekg(start + extSubHeadLen);
228  if (overflow != 0 && file != NULL)
229  {
230  ossimNitfDataExtensionSegment *des = file->getNewDataExtensionSegment(overflow-1, in);
231  if (des != NULL)
232  {
233  const vector<ossimNitfTagInformation> &desTags = des->getTagList();
234  for (vector<ossimNitfTagInformation>::const_iterator iter = desTags.begin(); iter != desTags.end(); ++iter)
235  {
236  iter->setTagType("IXSHD");
237  theTagList.push_back(*iter);
238  }
239  delete des;
240  }
241  }
242  ossimIFStream64::seekg64(in, start + extSubHeadLen, ios::beg);
243  }
244  ossimString compressionType = theCompression;
245  compressionType = compressionType.trim().upcase();
246  ossimEndian endian;
247 
248  //---
249  // Note: "C4" added to skip over the image data mask subheader.
250  // See MIL-STD-2500C paragraph 5.4.3.2
251  //---
252  if((compressionType == "NM")||
253  (compressionType == "M1")||
254  (compressionType == "M3")||
255  (compressionType == "M4")||
256  (compressionType == "M5")||
257  (compressionType == "C4"))
258  {
259  ossim_uint64 locationBefore = in.tellg();
260  in.read((char*)(&theBlockedImageDataOffset), 4);
261  in.read((char*)(&theBlockMaskRecordLength),2);
262  in.read((char*)(&thePadPixelMaskRecordLength), 2);
263  in.read((char*)(&theTransparentOutputPixelCodeLength), 2);
264 
265 
267  {
272  }
274  {
276  {
277  ossim_uint8 padOutputPixelCode;
278  in.read((char*)(&padOutputPixelCode), 1);
279  thePadOutputPixelCode = padOutputPixelCode;
280  }
281  }
282  else
283  {
284  in.read((char*)(&thePadOutputPixelCode), 2);
286  {
287  endian.swap(thePadOutputPixelCode);
288  }
289  // I need to add code here to check for justification when its 2 bytes
290  // but the code length is less than 16 bits.
291  //
292  }
294  {
295  ossim_uint32 totalNumber = 0;
296  if(theImageMode[0] == 'S')
297  {
299  }
300  else
301  {
303  }
304  ossim_uint32 *blockRead = new ossim_uint32[totalNumber];
305  ossim_uint32 idx = 0;
306  theBlockMaskRecords.resize(totalNumber);
307  in.read((char*)(blockRead), totalNumber*4);
308  for(idx = 0; idx < totalNumber; ++idx)
309  {
311  {
312  endian.swap(blockRead[idx]);
313  }
314  theBlockMaskRecords[idx] = blockRead[idx];
315  }
316  delete [] blockRead;
317  }
318  if( (thePadPixelMaskRecordLength > 0) ||
319  ( (getCompressionCode().upcase() == "M3") && (thePadPixelMaskRecordLength == 0) ) )
320  {
321  ossim_uint32 totalNumber = 0;
322  if(theImageMode[0] == 'S')
323  {
325  }
326  else
327  {
329  }
330  ossim_uint32 *blockRead = new ossim_uint32[totalNumber];
331  ossim_uint32 idx = 0;
332  thePadPixelMaskRecords.resize(totalNumber);
333  in.read((char*)(blockRead), totalNumber*4);
334  for(idx = 0; idx < totalNumber; ++idx)
335  {
337  {
338  endian.swap(blockRead[idx]);
339  }
340  thePadPixelMaskRecords[idx] = blockRead[idx];
341  }
342  delete [] blockRead;
343  }
345  if((getCompressionCode() == "C4")||
346  (getCompressionCode() == "M4"))
347  {
349  compressionHeader->parseStream(in);
350  // do a check to see if the compression header is good
351  //
352  if(compressionHeader->getCompressionAlgorithmId()!= 1)
353  {
354  compressionHeader = 0;
355  }
356  theCompressionHeader = compressionHeader.get();
357  }
358 
359  ossim_uint64 delta = (ossim_uint64)in.tellg() - locationBefore;
360  if(delta < theBlockedImageDataOffset)
361  {
362  in.ignore(theBlockedImageDataOffset-delta);
363  }
364  }
365  //***
366  // The stream should now be at the start of the data location so capture
367  // it.
368  //***
369  theDataLocation = in.tellg();
370 }
371 
373 {
374  out.write(theType, 2);
375  out.write(theImageId, 10);
376  out.write(theDateTime,14);
377  out.write(theTargetId, 17);
378  out.write(theTitle, 80);
379  out.write(theSecurityClassification, 1);
380  out.write(theSecurityClassificationSys, 2);
381  out.write(theCodewords, 11);
382  out.write(theControlAndHandling, 2);
383  out.write(theReleasingInstructions, 20);
384  out.write(theDeclassificationType, 2);
385  out.write(theDeclassificationDate, 8);
386  out.write(theDeclassificationExempt, 4);
387  out.write(theDowngrade, 1);
388  out.write(theDowngradeDate, 8);
389  out.write(theClassificationText, 43);
390  out.write(theClassificationAuthType, 1);
391  out.write(theClassificationAuthority, 40);
392  out.write(theClassificationReason, 1);
393  out.write(theSecuritySourceDate, 8);
394  out.write(theSecurityControlNumber, 15);
395  out.write(theEncryption, 1);
396  out.write(theImageSource, 42);
397  out.write(theSignificantRows, 8);
398  out.write(theSignificantCols, 8);
399  out.write(thePixelValueType, 3);
400  out.write(theRepresentation, 8);
401  out.write(theCategory, 8);
402  out.write(theActualBitsPerPixelPerBand, 2);
403  out.write(theJustification, 1);
404  out.write(theCoordinateSystem, 1);
405 
406  if(theCoordinateSystem[0] != ' ')
407  {
408  out.write(theGeographicLocation, 60);
409  }
410 
411  out.write(theNumberOfComments, 1);
412 
413  if (ossimString(theNumberOfComments).toUInt32() > 0)
414  {
415  for (ossim_uint32 i=0; i < theImageComments.size(); ++i)
416  {
417  char icom[81];
418  memset(icom, ' ', 80);
419  icom[80] = '\0';
420  strcpy(icom, theImageComments[i].c_str());
421  out.write(icom, 80);
422  }
423  }
424 
425  out.write(theCompression, 2);
426  ossimString compressionTest = theCompression;
427  if(compressionTest != "NC" &&
428  compressionTest != "NM")
429  {
430  out.write(theCompressionRateCode, 4);
431  }
432 
433  out.write(theNumberOfBands, 1);
434 
435  if(ossimString(theNumberOfBands).toInt32() == 0)
436  {
437  out.write(theNumberOfMultispectralBands, 5);
438  }
439 
440  if(theImageBands.size())
441  {
442  ossim_uint32 idx = 0;
443  for(idx = 0; idx < theImageBands.size(); ++idx)
444  {
445  if (theImageBands[idx].valid() == false)
446  {
448  }
449  theImageBands[idx]->writeStream(out);
450  }
451  }
452 
453  out.write(theImageSyncCode, 1);
454  out.write(theImageMode, 1);
455  out.write(theNumberOfBlocksPerRow, 4);
456  out.write(theNumberOfBlocksPerCol, 4);
457  out.write(theNumberOfPixelsPerBlockHoriz, 4);
458  out.write(theNumberOfPixelsPerBlockVert, 4);
459  out.write(theNumberOfBitsPerPixelPerBand, 2);
460  out.write(theDisplayLevel, 3);
461  out.write(theAttachmentLevel, 3);
462  out.write(theImageLocation, 10);
463  out.write(theImageMagnification, 4);
464  out.write(theUserDefinedImageDataLength, 5);
465 
466  if(ossimString(theUserDefinedImageDataLength).toInt32() > 0)
467  {
468  out.write(theUserDefinedOverflow, 3);
469  }
470 
471  // need to output tagged data
472  // here
473  //
474  ossim_uint32 totalLength = getTotalTagLength();
475 
476  if (totalLength == 0)
477  {
478  out.write(theExtendedSubheaderDataLen, 5);
479  }
480  else
481  {
482  totalLength += 3; // per Table A-3 of MIL-STD-2500B
483 
484  if(totalLength <= 99999)
485  {
486  std::ostringstream tempOut;
487 
488  tempOut << std::setw(5)
489  << std::setfill('0')
490  << std::setiosflags(ios::right)
491  << totalLength;
492 
493  memcpy(theExtendedSubheaderDataLen, tempOut.str().c_str(), 5);
494 
495  out.write(theExtendedSubheaderDataLen, 5);
496  ossim_uint32 theExtendedSubheaderDataLenBytes = ossimString(theExtendedSubheaderDataLen).toUInt32();
497 
498  if (theExtendedSubheaderDataLenBytes > 0)
499  {
500  strcpy(theExtendedSubheaderOverflow, ossimString("001").c_str());
501  }
502  else
503  {
504  memset(theExtendedSubheaderOverflow, '0', 3);
505  }
506 
507  if(totalLength > 0)
508  {
509  out.write(theExtendedSubheaderOverflow, 3);
510 
511  ossim_uint32 i = 0;
512 
513  for(i = 0; i < theTagList.size(); ++i)
514  {
515  theTagList[i].writeStream(out);
516  }
517  }
518  }
519  else
520  {
522  << "WARNING ossimNitfFileHeaderV2_1::writeStream: Only support writing of total tag length < 99999" << std::endl;
523  }
524  }
525 }
526 
528  const std::string& prefix) const
529 {
530  out << setiosflags(ios::left)
531  << prefix << setw(24)
532  << "IM:" << theType << "\n"
533  << prefix << setw(24)
534  << "IID1:" << theImageId << "\n"
535  << prefix << setw(24)
536  << "IDATIM:" << theDateTime << "\n"
537  << prefix << setw(24)
538  << "TGTID:" << theTargetId << "\n"
539  << prefix << setw(24)
540  << "IID2:" << theTitle << "\n"
541  << prefix << setw(24)
542  << "ISCLAS:" << theSecurityClassification << "\n"
543  << prefix << setw(24)
544  << "ISCLSY:" << theSecurityClassificationSys << "\n"
545  << prefix << setw(24)
546  << "ISCODE:" << theCodewords << "\n"
547  << prefix << setw(24)
548  << "ISCTLH:" << theControlAndHandling << "\n"
549  << prefix << setw(24)
550  << "ISREL:" << theReleasingInstructions << "\n"
551  << prefix << setw(24)
552  << "ISDCTP:" << theDeclassificationType << "\n"
553  << prefix << setw(24)
554  << "ISDCDT:" << theDeclassificationDate << "\n"
555  << prefix << setw(24)
556  << "ISDCXM:" << theDeclassificationExempt << "\n"
557  << prefix << setw(24)
558  << "ISDG:" << theDowngrade << "\n"
559  << prefix << setw(24)
560  << "ISDGDT:" << theDowngradeDate << "\n"
561  << prefix << setw(24)
562  << "ISCLTX:" << theClassificationText << "\n"
563  << prefix << setw(24)
564  << "ISCATP:" << theClassificationAuthType << "\n"
565  << prefix << setw(24)
566  << "ISCAUT:" << theClassificationAuthority << "\n"
567  << prefix << setw(24)
568  << "ISCRSN:" << theClassificationReason << "\n"
569  << prefix << setw(24)
570  << "ISSRDT:" << theSecuritySourceDate << "\n"
571  << prefix << setw(24)
572  << "ISCTLN:" << theSecurityControlNumber << "\n"
573  << prefix << setw(24)
574  << "ENCRYP:" << theEncryption << "\n"
575  << prefix << setw(24)
576  << "ISORCE:" << theImageSource << "\n"
577  << prefix << setw(24)
578  << "NROWS:" << theSignificantRows << "\n"
579  << prefix << setw(24)
580  << "NCOLS:" << theSignificantCols << "\n"
581  << prefix << setw(24)
582  << "PVTYPE:" << thePixelValueType << "\n"
583  << prefix << setw(24)
584  << "IREP:" << theRepresentation << "\n"
585  << prefix << setw(24)
586  << "ICAT:" << theCategory << "\n"
587  << prefix << setw(24)
588  << "ABPP:" << theActualBitsPerPixelPerBand << "\n"
589  << prefix << setw(24)
590  << "PJUST:" << theJustification << "\n"
591  << prefix << setw(24)
592  << "ICORDS:" << theCoordinateSystem << "\n"
593  << prefix << setw(24)
594  << "IGEOLO:" << theGeographicLocation << "\n"
595  << prefix << setw(24)
596  << "NICOM:" << theNumberOfComments << "\n";
597 
598  ossim_uint32 idx = 0;
599  for(idx = 0; idx < theImageComments.size(); ++idx)
600  {
601  ossimString icpre = "ICOM" + ossimString::toString(idx) + ":";
602  out << prefix << std::setw(24) << icpre << theImageComments[idx].trim() << "\n";
603  }
604 
605  out << prefix << setw(24)
606  << "IC:" << theCompression << "\n"
607  << prefix << setw(24)
608  << "COMRAT:" << theCompressionRateCode << "\n"
609  << prefix << setw(24)
610  << "NBANDS:" << theNumberOfBands << "\n"
611  << prefix << setw(24)
612  << "XBANDS:" << theNumberOfMultispectralBands << "\n";
613 
614  for(idx = 0; idx < theImageBands.size(); ++idx)
615  {
616  if(theImageBands[idx].valid())
617  {
618  theImageBands[idx]->print(out, prefix, idx);
619  }
620  }
621 
622  out << prefix << setw(24)
623  << "ISYNC:" << theImageSyncCode << "\n"
624  << prefix << setw(24)
625  << "IMODE:" << theImageMode << "\n"
626  << prefix << setw(24)
627  << "NBPR:" << theNumberOfBlocksPerRow << "\n"
628  << prefix << setw(24)
629  << "NBPC:" << theNumberOfBlocksPerCol << "\n"
630  << prefix << setw(24)
631  << "NPPBH:" << theNumberOfPixelsPerBlockHoriz << "\n"
632  << prefix << setw(24)
633  << "NPPBV:" << theNumberOfPixelsPerBlockVert << "\n"
634  << prefix << setw(24)
635  << "NBPP:" << theNumberOfBitsPerPixelPerBand << "\n"
636  << prefix << setw(24)
637  << "IDLVL:" << theDisplayLevel << "\n"
638  << prefix << setw(24)
639  << "IALVL:" << theAttachmentLevel << "\n"
640  << prefix << setw(24)
641  << "ILOC:" << theImageLocation << "\n"
642  << prefix << setw(24)
643  << "IMAG:" << theImageMagnification << "\n"
644  << prefix << setw(24)
645  << "UDIDL:" << theUserDefinedImageDataLength << "\n"
646  << prefix << setw(24)
647  << "UDOFL:" << theUserDefinedOverflow << "\n"
648  << prefix << setw(24)
649  << "IXSHDL:" << theExtendedSubheaderDataLen << "\n"
650  << prefix << setw(24)
651  << "IXSOFL:" << theExtendedSubheaderOverflow << "\n"
652  << prefix << setw(24)
653  << "IMDATOFF:" << theBlockedImageDataOffset << "\n"
654  << prefix << setw(24)
655  << "BMRLNTH:" << theBlockMaskRecordLength << "\n"
656  << prefix << setw(24)
657  << "TMRLNTH:" << thePadPixelMaskRecordLength << "\n"
658  << prefix << setw(24)
659  << "TPXCDLNTH:" << theTransparentOutputPixelCodeLength << "\n"
660  << prefix << setw(24)
661  << "TPXCD:" << thePadOutputPixelCode << "\n";
662 
663  if ( traceDebug() )
664  {
665  out << prefix << setw(24)
666  << "theDataLocation:" << theDataLocation << "\n";
667  }
668 
669  out << std::endl;
670 
671  return printTags(out, prefix);
672 }
673 
674 
676 {
678 
679  kwl.add(prefix, "ISCLSY", theSecurityClassificationSys);
680  kwl.add(prefix, "ISCODE", theCodewords);
681  kwl.add(prefix, "ISCTLH", theControlAndHandling);
682  kwl.add(prefix, "ISREL", theReleasingInstructions);
683  kwl.add(prefix, "ISDCTP", theDeclassificationType);
684  kwl.add(prefix, "ISDCDT", theDeclassificationDate);
685  kwl.add(prefix, "ISDCXM", theDeclassificationExempt);
686  kwl.add(prefix, "ISDG", theDowngrade);
687  kwl.add(prefix, "ISDGDT", theDowngradeDate);
688  kwl.add(prefix, "ISCLTX", theClassificationText);
689  kwl.add(prefix, "ISCATP", theClassificationAuthType);
690  kwl.add(prefix, "ISCAUT", theClassificationAuthority);
691  kwl.add(prefix, "ISCRSN", theClassificationReason);
692  kwl.add(prefix, "ISSRDT", theSecuritySourceDate);
693  kwl.add(prefix, "ISCTLN", theSecurityControlNumber);
694  kwl.add(prefix, "XBANDS", theNumberOfMultispectralBands);
695 
696  ossim_uint32 idx = 0;
697 
698  std::ostringstream out;
700  {
701  theCompressionHeader->saveState(kwl, prefix);
702  }
703 
704  for(idx = 0; idx < theImageBands.size(); ++idx)
705  {
706  if(theImageBands[idx].valid())
707  {
708  theImageBands[idx]->print(out, "", idx);
709  }
710  }
711 
712  out << std::endl;
713 
714  ossimKeywordlist kwlTemp;
715 
716  std::istringstream in(out.str());
717  if(kwlTemp.parseStream(in))
718  {
719  kwl.add(prefix, kwlTemp);
720  }
721 
722  return true;
723 }
724 
726 {
727  bool result = ossimNitfImageHeaderV2_X::isValid();
728 
729  if(result)
730  {
731 
732  }
733 
734  return result;
735 }
736 
737 bool ossimNitfImageHeaderV2_1::loadState(const ossimKeywordlist& kwl, const char* prefix)
738 {
739  // Note: Currently not looking up all fieds only ones that make sense.
740 
741  const char* lookup;
742 
743  lookup = kwl.find( prefix, ISCLSY_KW );
744  if ( lookup )
745  {
747  }
748  lookup = kwl.find( prefix, ISCODE_KW );
749  if ( lookup )
750  {
751  setCodewords( ossimString(lookup) );
752  }
753  lookup = kwl.find( prefix, ISCTLH_KW );
754  if ( lookup )
755  {
757  }
758  lookup = kwl.find( prefix, ISREL_KW);
759  if ( lookup )
760  {
762  }
763  lookup = kwl.find( prefix, ISDCTP_KW );
764  if ( lookup )
765  {
767  }
768  lookup = kwl.find( prefix, ISDCDT_KW );
769  if ( lookup )
770  {
772  }
773  lookup = kwl.find( prefix, ISDCXM_KW );
774  if ( lookup )
775  {
777  }
778  lookup = kwl.find( prefix, ISDG_KW );
779  if ( lookup )
780  {
781  setDowngrade( ossimString(lookup) );
782  }
783  lookup = kwl.find( prefix, ISDGDT_KW );
784  if ( lookup )
785  {
786  setDowngradeDate( ossimString(lookup) );
787  }
788  lookup = kwl.find( prefix, ISCLTX_KW );
789  if ( lookup )
790  {
792  }
793  lookup = kwl.find( prefix, ISCATP_KW );
794  if ( lookup )
795  {
797  }
798  lookup = kwl.find( prefix, ISCAUT_KW );
799  if ( lookup )
800  {
802  }
803  lookup = kwl.find( prefix, ISCRSN_KW );
804  if ( lookup )
805  {
807  }
808  lookup = kwl.find( prefix, ISSRDT_KW );
809  if ( lookup )
810  {
812  }
813  lookup = kwl.find( prefix, ISCTLN_KW );
814  if ( lookup )
815  {
817  }
818  lookup = kwl.find( prefix, NBANDS_KW );
819  if ( lookup )
820  {
821  setNumberOfBands( ossimString(lookup).toUInt32() );
822  }
823  /* Setting this in the writer versus loadstate right now
824  for (int i=0; i < theImageBands.size(); ++i)
825  {
826  theImageBands[i]->loadState(kwl, prefix, i);
827  }
828  */
829 
830  return ossimNitfImageHeaderV2_X::loadState(kwl, prefix);
831 }
832 
834 {
836  temp = temp.trim();
837  return ((temp != "NC") && (temp != "NM"));
838 }
839 
841 {
842  return (theEncryption[0] == '1');
843 }
844 
846 {
847  if(theNumberOfBands[0] == '0')
848  {
850  }
851  else
852  {
854  }
855 }
856 
858 {
860 }
861 
863 {
865 }
866 
868 {
869  return theImageId;
870 }
871 
873 {
875 }
876 
878 {
880 }
881 
883 {
884  return ossimString(theImageMode).trim();
885 }
886 
888 {
890 }
891 
893 {
894  return ossimString(theDateTime);
895 }
896 
898 {
899  ossimString result;
900 
901  result += ossimString(theDateTime + 4,
902  theDateTime + 6);
903  result += ossimString(separationChar);
904  result += ossimString(theDateTime + 6,
905  theDateTime + 8);
906  result += ossimString(separationChar);
907  result += ossimString(theDateTime,
908  theDateTime + 4);
909 
910  return result;
911 }
912 
914 {
915  return theCategory;
916 }
917 
919 {
920  return theImageSource;
921 }
922 
924 {
925  return theRepresentation;
926 }
927 
929 {
930  return theCoordinateSystem;
931 }
933 {
934  return theGeographicLocation;
935 }
936 
938 {
939  return (theBlockMaskRecords.size() > 0);
940 }
941 
943 {
944  return (thePadPixelMaskRecords.size()>0);
945 }
946 
948 {
950 }
951 
953 {
954  return thePadOutputPixelCode;
955 }
956 
958  ossim_uint32 bandNumber)const
959 {
961  ossim_uint32 result = 0xffffffff;
962 
963  if((hasBlockMaskRecords())&&
964  (blockNumber < maxBlock))
965  {
966  if(theImageMode[0] == 'S')
967  {
968  if(bandNumber < (ossim_uint32)getNumberOfBands())
969  {
970  result = theBlockMaskRecords[bandNumber*maxBlock + blockNumber];
971  }
972  }
973  else
974  {
975  result = theBlockMaskRecords[blockNumber];
976  }
977  }
978 
979  return result;
980 }
981 
983  ossim_uint32 bandNumber)const
984 {
986  ossim_uint32 result = 0xffffffff;
987 
988  if((hasPadPixelMaskRecords())&&
989  (blockNumber < maxBlock))
990  {
991  if(theImageMode[0] == 'S')
992  {
993  if(bandNumber < (ossim_uint32)getNumberOfBands())
994  {
995  result = thePadPixelMaskRecords[bandNumber*maxBlock + blockNumber];
996  }
997  }
998  else
999  {
1000  result = thePadPixelMaskRecords[blockNumber];
1001  }
1002  }
1003 
1004  return result;
1005 }
1006 
1007 
1009 {
1010  memcpy(theType, "IM", 2);
1011  memset(theImageId, ' ',10);
1012  memset(theDateTime, '-',14);
1013  memset(theTargetId, ' ',17);
1014  memset(theTitle, ' ',80);
1015  memset(theSecurityClassification, ' ',1);
1016  memset(theSecurityClassificationSys, ' ',2);
1017  memset(theCodewords, ' ',11);
1018  memset(theControlAndHandling, ' ',2);
1019  memset(theReleasingInstructions, ' ',20);
1020  memset(theDeclassificationType, ' ',2);
1021  memset(theDeclassificationDate, ' ',8);
1022  memset(theDeclassificationExempt, ' ',4);
1023  memset(theDowngrade, ' ',1);
1024  memset(theDowngradeDate, ' ',8);
1025  memset(theClassificationText, ' ',43);
1026  memset(theClassificationAuthType, ' ',1);
1027  memset(theClassificationAuthority, ' ',40);
1028  memset(theClassificationReason, ' ',1);
1029  memset(theSecuritySourceDate, ' ',8);
1030  memset(theSecurityControlNumber, ' ',15);
1031  memset(theEncryption, '0',1);
1032  memset(theImageSource, ' ',42);
1033  memset(theSignificantRows, '0',8);
1034  memset(theSignificantCols, '0',8);
1035  memset(thePixelValueType, ' ',3);
1036  memset(theRepresentation, ' ',8);
1037  memset(theCategory, ' ',8);
1038  memset(theActualBitsPerPixelPerBand, ' ',2);
1039  memset(theJustification, 'R',1);
1040  memset(theCoordinateSystem, ' ',1);
1041  memset(theGeographicLocation, ' ',60);
1042  memset(theNumberOfComments, '0', 1);
1043  theImageComments.clear();
1044  memcpy(theCompression, "NC",2);
1045  memset(theCompressionRateCode, ' ',4);
1046  memset(theNumberOfBands, '0',1);
1047  memset(theNumberOfMultispectralBands, ' ',5);
1048  memset(theImageSyncCode, '0', 1);
1049  memset(theImageMode, 'B', 1);
1050  memset(theNumberOfBlocksPerRow, '0', 4);
1051  memset(theNumberOfBlocksPerCol, '0', 4);
1052  memset(theNumberOfPixelsPerBlockHoriz, '0', 4);
1053  memset(theNumberOfPixelsPerBlockVert, '0', 4);
1054  memset(theNumberOfBitsPerPixelPerBand, '0', 2);
1055  memcpy(theDisplayLevel, "001", 3);
1056  memset(theAttachmentLevel, '0', 3);
1057  memset(theImageLocation, '0', 10);
1058  memcpy(theImageMagnification, "1.0 ", 4);
1059 
1060  memset(theUserDefinedImageDataLength,'0', 5);
1061  memset(theUserDefinedOverflow, '0', 3);
1062  memset(theExtendedSubheaderDataLen, '0', 5);
1063  memset(theExtendedSubheaderOverflow, '0', 3);
1064  theBlockMaskRecords.clear();
1065  thePadPixelMaskRecords.clear();
1066 
1072 
1074 
1075  theType[2] = '\0';
1076  theImageId[10] = '\0';
1077  theDateTime[14] = '\0';
1078  theTargetId[17] = '\0';
1079  theTitle[80] = '\0';
1080  theSecurityClassification[1] = '\0';
1081  theSecurityClassificationSys[2] = '\0';
1082  theCodewords[11] = '\0';
1083  theControlAndHandling[2] = '\0';
1084  theReleasingInstructions[20] = '\0';
1085  theDeclassificationType[2] = '\0';
1086  theDeclassificationDate[8] = '\0';
1087  theDeclassificationExempt[4] = '\0';
1088  theDowngrade[1] = '\0';
1089  theDowngradeDate[8] = '\0';
1090  theClassificationText[43] = '\0';
1091  theClassificationAuthType[1] = '\0';
1092  theClassificationAuthority[40] = '\0';
1093  theClassificationReason[1] = '\0';
1094  theSecuritySourceDate[8] = '\0';
1095  theSecurityControlNumber[15] = '\0';
1096  theEncryption[1] = '\0';
1097  theImageSource[42] = '\0';
1098  theSignificantRows[8] = '\0';
1099  theSignificantCols[8] = '\0';
1100  thePixelValueType[3] = '\0';
1101  theRepresentation[8] = '\0';
1102  theCategory[8] = '\0';
1103  theActualBitsPerPixelPerBand[2] = '\0';
1104  theJustification[1] = '\0';
1105  theCoordinateSystem[1] = '\0';
1106  theGeographicLocation[60] = '\0';
1107  theNumberOfComments[1] = '\0';
1108  theCompression[2] = '\0';
1109  theCompressionRateCode[4] = '\0';
1110  theNumberOfBands[1] = '\0';
1112  theImageSyncCode[1] = '\0';
1113  theImageMode[1] = '\0';
1114  theNumberOfBlocksPerRow[4] = '\0';
1115  theNumberOfBlocksPerCol[4] = '\0';
1119  theDisplayLevel[3] = '\0';
1120  theAttachmentLevel[3] = '\0';
1121  theImageLocation[10] = '\0';
1122  theImageMagnification[4] = '\0';
1124  theUserDefinedOverflow[3] = '\0';
1125  theExtendedSubheaderDataLen[5] = '\0';
1126  theExtendedSubheaderOverflow[3] = '\0';
1127 
1128  theDataLocation = 0;
1129 }
1130 
1132 {
1134 }
1135 
1137 {
1139 }
1140 
1142 {
1143  // return ossimString(theNumberOfPixelsPerBlockHoriz).toInt32();
1145  if ((rval == 0) && (getNumberOfBlocksPerCol() == 1))
1146  {
1147  rval = getNumberOfCols();
1148  }
1149  return rval;
1150 
1151 }
1152 
1154 {
1155 // return ossimString(theNumberOfPixelsPerBlockVert).toInt32();
1157  if ((rval == 0) && (getNumberOfBlocksPerRow() == 1))
1158  {
1159  rval = getNumberOfRows();
1160  }
1161  return rval;
1162 }
1163 
1165 {
1166 // ossimDpt ul(ossimString((char*)(&theImageLocation[5])).toDouble(),
1167 // ossimString((char*)theImageLocation,
1168 // (char*)(&theImageLocation[5])).toDouble());
1169  ossimDpt ul(0.0,0.0);
1170  double rows = ossimString(theSignificantRows).toDouble();
1171  double cols = ossimString(theSignificantCols).toDouble();
1172 
1173 // ossimDpt lr(ul.x + cols-1,
1174 // ul.y + rows-1);
1175  ossimDpt lr(cols-1,
1176  rows-1);
1177 
1178  return ossimIrect(ul, lr);
1179 }
1180 
1182 {
1183 // ossimDpt ul(ossimString((char*)(&theImageLocation[5])).toDouble(),
1184 // ossimString((char*)theImageLocation,
1185 //g (char*)(&theImageLocation[5])).toDouble());
1186  ossimDpt ul(0.0,0.0);
1187 
1190 
1191 // ossimDpt lr(ul.x + cols-1,
1192 // ul.y + rows-1);
1193  ossimDpt lr(cols-1,
1194  rows-1);
1195 
1196  return ossimIrect(ul, lr);
1197 }
1198 
1199 
1201 {
1203 }
1204 
1205 
1207 {
1208  std::ostringstream out;
1209 
1210  if(nbands > 9)
1211  {
1212  out << std::setw(5)
1213  << std::setfill('0')
1214  << std::setiosflags(ios::right)
1215  << nbands;
1216 
1217  theNumberOfBands[0] = '0';
1218  memcpy(theNumberOfMultispectralBands, out.str().c_str(), 5);
1219  }
1220  else
1221  {
1222  out << nbands;
1223  theNumberOfBands[0] = out.str().c_str()[0];
1224  }
1225 
1226  theImageBands.resize(getNumberOfBands());
1227 }
1228 
1230  const ossimNitfImageBandV2_1& info)
1231 {
1232  if(idx < theImageBands.size())
1233  {
1234  if(!theImageBands[idx].valid())
1235  {
1237  }
1238  (*theImageBands[idx]) = info;
1239  }
1240 }
1241 
1243 {
1244  std::ostringstream out;
1245  if(rows > 99999999) rows = 99999999;
1246 
1247  out << rows;
1248  ossimNitfCommon::setField(theSignificantRows, out.str(), 8, ios::right, '0');
1249 }
1250 
1252 {
1253  std::ostringstream out;
1254  if(cols > 99999999) cols = 99999999;
1255 
1256  out << cols;
1257  ossimNitfCommon::setField(theSignificantCols, out.str(), 8, ios::right, '0');
1258 }
1259 
1261  const ossimDpt& ur,
1262  const ossimDpt& lr,
1263  const ossimDpt& ll)
1264 {
1265  if (traceDebug())
1266  {
1268  << ossimDms(ul.y, true).toString("ddmmss.ssssC").c_str()
1269  << ossimDms(ul.x, false).toString("dddmmss.ssssC").c_str()
1270  << ossimDms(ur.y, true).toString("ddmmss.ssssC").c_str()
1271  << ossimDms(ur.x, false).toString("dddmmss.ssssC").c_str()
1272  << ossimDms(lr.y, true).toString("ddmmss.ssssC").c_str()
1273  << ossimDms(lr.x, false).toString("dddmmss.ssssC").c_str()
1274  << ossimDms(ll.y, true).toString("ddmmss.ssssC").c_str()
1275  << ossimDms(ll.x, false).toString("dddmmss.ssssC").c_str()
1276  << std::endl;
1277 
1282  }
1283 
1284  theCoordinateSystem[0] = 'G';
1285  std::ostringstream out;
1286 
1287  out << ossimDms(ul.y, true).toString("ddmmssC").c_str();
1288  out << ossimDms(ul.x, false).toString("dddmmssC").c_str();
1289  out << ossimDms(ur.y, true).toString("ddmmssC").c_str();
1290  out << ossimDms(ur.x, false).toString("dddmmssC").c_str();
1291  out << ossimDms(lr.y, true).toString("ddmmssC").c_str();
1292  out << ossimDms(lr.x, false).toString("dddmmssC").c_str();
1293  out << ossimDms(ll.y, true).toString("ddmmssC").c_str();
1294  out << ossimDms(ll.x, false).toString("dddmmssC").c_str();
1295 
1296  memcpy(theGeographicLocation, out.str().c_str(), 60);
1297 }
1298 
1300  const ossimDpt& ul,
1301  const ossimDpt& ur,
1302  const ossimDpt& lr,
1303  const ossimDpt& ll)
1304 {
1305  theCoordinateSystem[0] = 'D';
1306  ostringstream out;
1307 
1308  out << (ul.lat >= 0.0?"+":"")
1309  << std::setw(6)
1310  << std::setfill('0')
1311  << std::setprecision(3)
1312  << std::setiosflags(std::ios::fixed)
1313  << ul.lat
1314  << (ul.lon >= 0.0?"+":"")
1315  << std::setw(7)
1316  << std::setfill('0')
1317  << std::setprecision(3)
1318  << std::setiosflags(std::ios::fixed)
1319  << ul.lon;
1320  out << (ur.lat >= 0.0?"+":"")
1321  << std::setw(6)
1322  << std::setfill('0')
1323  << std::setprecision(3)
1324  << std::setiosflags(std::ios::fixed)
1325  << ur.lat
1326  << (ur.lon >= 0.0?"+":"")
1327  << std::setw(7)
1328  << std::setfill('0')
1329  << std::setprecision(3)
1330  << std::setiosflags(std::ios::fixed)
1331  << ur.lon;
1332  out << (lr.lat >= 0.0?"+":"")
1333  << std::setw(6)
1334  << std::setfill('0')
1335  << std::setprecision(3)
1336  << std::setiosflags(std::ios::fixed)
1337  << lr.lat
1338  << (lr.lon >= 0.0?"+":"")
1339  << std::setw(7)
1340  << std::setfill('0')
1341  << std::setprecision(3)
1342  << std::setiosflags(std::ios::fixed)
1343  << lr.lon;
1344  out << (ll.lat >= 0.0?"+":"")
1345  << std::setw(6)
1346  << std::setfill('0')
1347  << std::setprecision(3)
1348  << std::setiosflags(std::ios::fixed)
1349  << ll.lat
1350  << (ll.lon >= 0.0?"+":"")
1351  << std::setw(7)
1352  << std::setfill('0')
1353  << std::setprecision(3)
1354  << std::setiosflags(std::ios::fixed)
1355  << ll.lon;
1356 
1357  memcpy(theGeographicLocation, out.str().c_str(), 60);
1358 }
1359 
1361  const ossimDpt& ul,
1362  const ossimDpt& ur,
1363  const ossimDpt& lr,
1364  const ossimDpt& ll)
1365 {
1366  theCoordinateSystem[0] = 'N';
1367 
1368  memcpy(theGeographicLocation,
1369  encodeUtm(zone, ul, ur, lr, ll).c_str(), 60);
1370 }
1371 
1373  const ossimDpt& ul,
1374  const ossimDpt& ur,
1375  const ossimDpt& lr,
1376  const ossimDpt& ll)
1377 {
1378  theCoordinateSystem[0] = 'S';
1379 
1380  memcpy(theGeographicLocation,
1381  encodeUtm(zone, ul, ur, lr, ll).c_str(), 60);
1382 }
1383 
1384 
1386 {
1388 }
1389 
1391 {
1393 }
1394 
1396 {
1398 }
1399 
1401 {
1403 }
1404 
1406 {
1408 }
1409 
1411 {
1413 }
1414 
1416 {
1418 }
1419 
1421 {
1423 }
1424 
1426 {
1428 }
1429 
1431 {
1433 }
1434 
1436 {
1438 }
1439 
1441 {
1443 }
1444 
1446 {
1448 }
1449 
1451 {
1453 }
1454 
1456 {
1458 }
1459 
1461 {
1463 }
1464 
1466 {
1467  ossimString name = property->getName();
1468 
1469  // Make case insensitive:
1470  name.downcase();
1471 
1472  std::ostringstream out;
1473 
1474  if(!property) return;
1475 
1476  if(name.contains(ISCLSY_KW))
1477  {
1479  }
1480  else if(name.contains(ISCODE_KW))
1481  {
1482  setCodewords(property->valueToString());
1483  }
1484  else if(name.contains(ISCTLH_KW))
1485  {
1486  setControlAndHandling(property->valueToString());
1487  }
1488  else if(name.contains(ISREL_KW))
1489  {
1491  }
1492  else if(name.contains(ISDCTP_KW))
1493  {
1495  }
1496  else if(name.contains(ISDCDT_KW))
1497  {
1499  }
1500  else if(name.contains(ISDCXM_KW))
1501  {
1503  }
1504  else if(name.contains(ISDGDT_KW)) // Must be before: "ISDG_KW"
1505  {
1506  setDowngradeDate(property->valueToString());
1507  }
1508  else if(name.contains(ISDG_KW))
1509  {
1510  setDowngrade(property->valueToString());
1511  }
1512  else if(name.contains(ISCLTX_KW))
1513  {
1514  setClassificationText(property->valueToString());
1515  }
1516  else if(name.contains(ISCATP_KW))
1517  {
1519  }
1520  else if(name.contains(ISCAUT_KW))
1521  {
1523  }
1524  else if(name.contains(ISCRSN_KW))
1525  {
1527  }
1528  else if(name == ISCRSN_KW)
1529  {
1530  property = new ossimStringProperty(name,
1532  }
1533  else if(name.contains(ISSRDT_KW))
1534  {
1535  setSecuritySourceDate(property->valueToString());
1536  }
1537  else if(name.contains(ISCTLN_KW))
1538  {
1540  }
1541  else
1542  {
1544  }
1545 }
1546 
1548 {
1549  ossimProperty* property = 0;
1550 
1551  if(name == ISCLSY_KW)
1552  {
1553  property = new ossimStringProperty(name,
1555  }
1556  else if(name == ISCODE_KW)
1557  {
1558  property = new ossimStringProperty(name,
1559  ossimString(theCodewords).trim());
1560  }
1561  else if(name == ISCTLH_KW)
1562  {
1563  property = new ossimStringProperty(name,
1565  }
1566  else if(name == ISREL_KW)
1567  {
1568  property = new ossimStringProperty(name,
1570  }
1571  else if(name == ISDCTP_KW)
1572  {
1573  property = new ossimStringProperty(name,
1575  }
1576  else if(name == ISDCDT_KW)
1577  {
1578  property = new ossimStringProperty(name,
1580  }
1581  else if(name == ISDCXM_KW)
1582  {
1583  property = new ossimStringProperty(name,
1585  }
1586  else if(name == ISDG_KW)
1587  {
1588  property = new ossimStringProperty(name,
1589  ossimString(theDowngrade).trim());
1590  }
1591  else if(name == ISDGDT_KW)
1592  {
1593  property = new ossimStringProperty(name,
1594  ossimString(theDowngradeDate).trim());
1595  }
1596  else if(name == ISCLTX_KW)
1597  {
1598  property = new ossimStringProperty(name,
1600  }
1601  else if(name == ISCATP_KW)
1602  {
1603  property = new ossimStringProperty(name,
1605  }
1606  else if(name == ISCAUT_KW)
1607  {
1608  property = new ossimStringProperty(name,
1610  }
1611  else if(name == ISCRSN_KW)
1612  {
1613  property = new ossimStringProperty(name,
1615  }
1616  else if(name == ISSRDT_KW)
1617  {
1618  property = new ossimStringProperty(name,
1620  }
1621  else if(name == ISCTLN_KW)
1622  {
1623  property = new ossimStringProperty(name,
1625  }
1626  else
1627  {
1629  }
1630 
1631  return property;
1632 }
1633 
1634 void ossimNitfImageHeaderV2_1::getPropertyNames(std::vector<ossimString>& propertyNames)const
1635 {
1637 
1638  propertyNames.push_back(ISCLSY_KW);
1639  propertyNames.push_back(ISCODE_KW);
1640  propertyNames.push_back(ISCTLH_KW);
1641  propertyNames.push_back(ISREL_KW);
1642  propertyNames.push_back(ISDCTP_KW);
1643  propertyNames.push_back(ISDCDT_KW);
1644  propertyNames.push_back(ISDCXM_KW);
1645  propertyNames.push_back(ISDG_KW);
1646  propertyNames.push_back(ISDGDT_KW);
1647  propertyNames.push_back(ISCLTX_KW);
1648  propertyNames.push_back(ISCATP_KW);
1649  propertyNames.push_back(ISCAUT_KW);
1650  propertyNames.push_back(ISCRSN_KW);
1651  propertyNames.push_back(ISSRDT_KW);
1652  propertyNames.push_back(ISCTLN_KW);
1653  propertyNames.push_back(XBANDS_KW);
1654 }
1655 
1657 {
1658  return theCompressionHeader;
1659 }
1660 
1662 {
1663  if(idx < theImageBands.size())
1664  {
1665  return (ossimNitfImageBand*)theImageBands[idx].get();
1666  }
1667 
1668  return 0;
1669 }
1670 
1671 
1673  ossim_uint32 zone,
1674  const ossimDpt& ul,
1675  const ossimDpt& ur,
1676  const ossimDpt& lr,
1677  const ossimDpt& ll) const
1678 {
1679  ostringstream out;
1680 
1681  if(zone > 60)
1682  {
1683  std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUTM zone greate than 60!";
1684  if (traceDebug())
1685  {
1686  ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
1687  }
1688  throw std::out_of_range(s);
1689  }
1690 
1691  ossim_float64 east = ul.x;
1692  ossim_float64 north = ul.y;
1693 
1694  if((ossim_uint32)(east+.5) > 999999)
1695  {
1696  std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper left easting too large for NITF field!";
1697  if (traceDebug())
1698  {
1699  ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
1700  }
1701  throw std::out_of_range(s);
1702  }
1703 
1704  if((ossim_uint32)(north+.5) > 9999999)
1705  {
1706  std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper left northing too large for NITF field!";
1707  if (traceDebug())
1708  {
1709  ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
1710  }
1711  throw std::out_of_range(s);
1712  }
1713 
1714  out << setw(2)
1715  << setfill('0')
1716  << zone
1717  << setw(6)
1718  << setfill('0')
1719  <<(ossim_uint32)(east+.5)
1720  << setw(7)
1721  << setfill('0')
1722  <<(ossim_uint32)(north+.5);
1723 
1724 
1725  east = ur.x;
1726  north = ur.y;
1727 
1728  if((ossim_uint32)(east+.5) > 999999)
1729  {
1730  std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper right easting too large for NITF field!";
1731  if (traceDebug())
1732  {
1733  ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
1734  }
1735  throw std::out_of_range(s);
1736  }
1737 
1738  if((ossim_uint32)(north+.5) > 9999999)
1739  {
1740  std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper right northing too large for NITF field!";
1741  if (traceDebug())
1742  {
1743  ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
1744  }
1745  throw std::out_of_range(s);
1746  }
1747 
1748  out << setw(2)
1749  << setfill('0')
1750  << zone
1751  << setw(6)
1752  << setfill('0')
1753  <<(ossim_uint32)(east+.5)
1754  << setw(7)
1755  << setfill('0')
1756  <<(ossim_uint32)(north+.5);
1757  east = lr.x;
1758  north = lr.y;
1759 
1760  if((ossim_uint32)(east+.5) > 999999)
1761  {
1762  std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower right easting too large for NITF field!";
1763  if (traceDebug())
1764  {
1765  ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
1766  }
1767  throw std::out_of_range(s);
1768  }
1769 
1770  if((ossim_uint32)(north+.5) > 9999999)
1771  {
1772  std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower right northing too large for NITF field!";
1773  if (traceDebug())
1774  {
1775  ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
1776  }
1777  throw std::out_of_range(s);
1778  }
1779 
1780  out << setw(2)
1781  << setfill('0')
1782  << zone
1783  << setw(6)
1784  << setfill('0')
1785  <<(ossim_uint32)(east+.5)
1786  << setw(7)
1787  << setfill('0')
1788  <<(ossim_uint32)(north+.5);
1789 
1790  east = ll.x;
1791  north = ll.y;
1792 
1793  if((ossim_uint32)(east+.5) > 999999)
1794  {
1795  std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower left easting too large for NITF field!";
1796  if (traceDebug())
1797  {
1798  ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
1799  }
1800  throw std::out_of_range(s);
1801  }
1802 
1803  if((ossim_uint32)(north+.5) > 9999999)
1804  {
1805  std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower left northing too large for NITF field!";
1806  if (traceDebug())
1807  {
1808  ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
1809  }
1810  throw std::out_of_range(s);
1811  }
1812 
1813  out << setw(2)
1814  << setfill('0')
1815  << zone
1816  << setw(6)
1817  << setfill('0')
1818  <<(ossim_uint32)(east+.5)
1819  << setw(7)
1820  << setfill('0')
1821  <<(ossim_uint32)(north+.5);
1822 
1823  return out.str().c_str();
1824 }
1825 
1826 bool ossimNitfImageHeaderV2_1::takeOverflowTags(std::vector<ossimNitfTagInformation> &overflowTags,
1827  ossim_uint32 potentialDesIndex, bool userDefinedTags)
1828 {
1829  overflowTags.clear();
1830  std::vector<ossimNitfTagInformation>::iterator iter;
1831  std::vector<ossimNitfTagInformation> specifiedTags;
1832  const ossimString tagType(userDefinedTags ? "UDID" : "IXSHD");
1833  for (iter = theTagList.begin(); iter != theTagList.end(); ++iter)
1834  {
1835  if (iter->getTagType() == tagType)
1836  {
1837  specifiedTags.push_back(*iter);
1838  }
1839  }
1840 
1841  std::sort(specifiedTags.begin(), specifiedTags.end());
1842 
1843  ossim_uint32 totalSize = 0;
1844  const ossim_uint32 maxSize = 9996;
1845  for (iter = specifiedTags.begin(); iter != specifiedTags.end() &&
1846  totalSize + iter->getTotalTagLength() <= maxSize; ++iter)
1847  {
1848  totalSize += iter->getTotalTagLength();
1849  }
1850 
1851  for (; iter != specifiedTags.end(); ++iter)
1852  {
1853  overflowTags.push_back(*iter);
1854  removeTag(iter->getTagName());
1855  }
1856 
1857  // If there are no overflow tags, then no DES is required
1858  if (overflowTags.empty() == true)
1859  {
1860  potentialDesIndex = 0;
1861  }
1862 
1863  std::ostringstream overflowDes;
1864  overflowDes << std::setw(3)
1865  << std::setfill('0')
1866  << std::setiosflags(ios::right)
1867  << potentialDesIndex;
1868 
1869  std::ostringstream tagLength;
1870  tagLength << std::setw(5)
1871  << std::setfill('0')
1872  << std::setiosflags(ios::right)
1873  << totalSize;
1874 
1875  if (userDefinedTags)
1876  {
1877  strcpy(theUserDefinedOverflow, overflowDes.str().c_str());
1878  strcpy(theUserDefinedImageDataLength, tagLength.str().c_str());
1879  }
1880  else
1881  {
1882  strcpy(theExtendedSubheaderOverflow, overflowDes.str().c_str());
1883  strcpy(theExtendedSubheaderDataLen, tagLength.str().c_str());
1884  }
1885 
1886  return (overflowTags.empty() == false);
1887 }
1888 
char theSignificantRows[9]
FIELD: NROWS.
virtual void valueToString(ossimString &valueResult) const =0
virtual ossim_int32 getNumberOfBlocksPerCol() const
ossim_uint16 theBlockMaskRecordLength
FIELD NAME: BMRLNTH.
char theNumberOfMultispectralBands[6]
FIELD: XBANDS.
virtual const ossimRefPtr< ossimNitfCompressionHeader > getCompressionHeader() const
char theReleasingInstructions[21]
FIELD: ISREL.
virtual bool takeOverflowTags(std::vector< ossimNitfTagInformation > &overflowTags, ossim_uint32 potentialDesIndex, bool userDefinedTags=false)
virtual ossim_uint32 getTotalTagLength() const
char theNumberOfPixelsPerBlockVert[5]
FIELD: NPPBV.
virtual void setClassificationAuthorityType(const ossimString &value)
static ossimString upcase(const ossimString &aString)
Definition: ossimString.cpp:34
char theNumberOfPixelsPerBlockHoriz[5]
FIELD: NPPBH.
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
ossimString encodeUtm(ossim_uint32 zone, const ossimDpt &ul, const ossimDpt &ur, const ossimDpt &lr, const ossimDpt &ll) const
virtual ossim_uint32 getTransparentCode() const
char theCompressionRateCode[5]
FIELD COMRAT.
ossim_uint32 theBlockedImageDataOffset
FIELD NAME: IMDATOFF.
virtual void setProperty(ossimRefPtr< ossimProperty > property)
static const ossimString ISDGDT_KW
virtual void setNumberOfBands(ossim_uint32 nbands)
virtual ossimIrect getImageRect() const
Returns the zero based image rectangle.
char theRepresentation[9]
FIELD: IREP.
char theClassificationAuthority[41]
FIELD: ISCAUT.
virtual bool saveState(ossimKeywordlist &kwl, const ossimString &prefix="") const
Represents serializable keyword/value map.
virtual void setProperty(ossimRefPtr< ossimProperty > property)
ossim_uint16 thePadPixelMaskRecordLength
FIELD: TMRLNTH.
bool valid() const
Definition: ossimRefPtr.h:75
static const ossimString ISCODE_KW
char theNumberOfBands[2]
FIELD: NBANDS.
const char * find(const char *key) const
virtual bool isValid() const
isValid will test if the fields are valid and will return true or false.
char theSecuritySourceDate[9]
FIELD: ISSRDT.
virtual void parseStream(ossim::istream &in)
virtual void setGeographicLocationDms(const ossimDpt &ul, const ossimDpt &ur, const ossimDpt &lr, const ossimDpt &ll)
virtual void setClassificationReason(const ossimString &value)
virtual void writeStream(std::ostream &out)
virtual void setDeclassificationDate(const ossimString &value)
static const ossimString ISCLSY_KW
static const ossimString ISDCTP_KW
char theUserDefinedImageDataLength[6]
FIELD: UDIDL.
double y
Definition: ossimDpt.h:165
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
bool contains(char aChar) const
Definition: ossimString.h:58
ossim_uint16 thePadOutputPixelCode
FIELD: TPXCD.
static ossimString toString(bool aValue)
Numeric to string methods.
std::vector< ossimRefPtr< ossimNitfImageBandV2_1 > > theImageBands
void setTagType(const ossimString &tagType) const
virtual bool hasBlockMaskRecords() const
static const ossimString ISSRDT_KW
char theActualBitsPerPixelPerBand[3]
FIELD: ABPP.
static const ossimString XBANDS_KW
char theCodewords[12]
FIELD: ISCODE.
ossimRefPtr< ossimNitfCompressionHeader > theCompressionHeader
ossim_uint32 toUInt32() const
char theNumberOfBitsPerPixelPerBand[3]
FIELD: NBPP.
virtual ossim_int32 getNumberOfCols() const
char theNumberOfBlocksPerRow[5]
FIELD: NBPR.
virtual void parseStream(std::istream &in, const ossimNitfFileHeaderV2_1 *file)
virtual ossim_uint32 getBlockMaskRecordOffset(ossim_uint32 blockNumber, ossim_uint32 bandNumber) const
char theGeographicLocation[61]
FIELD: IGEOLO.
virtual ossim_uint32 getPadPixelMaskRecordOffset(ossim_uint32 blockNumber, ossim_uint32 bandNumber) const
virtual void removeTag(const ossimString &tagName)
char theControlAndHandling[3]
FIELD: ISCTLH.
virtual void setUtmNorth(ossim_uint32 zone, const ossimDpt &ul, const ossimDpt &ur, const ossimDpt &lr, const ossimDpt &ll)
virtual ossimIrect getBlockImageRect() const
Returns the zero based image rectangle expanded out to block boundaries.
char theSecurityClassificationSys[3]
FIELD: ISCLSY.
char theClassificationReason[2]
FIELD: ISCRSN.
virtual void setControlAndHandling(const ossimString &value)
char theDeclassificationDate[9]
FIELD: ISDCDT.
void checkForGeographicTiePointTruncation(const ossimDpt &tie) const
Method to check tie point to see if it will be truncated in field IGEOLO which has only arc second re...
char theImageId[11]
FIELD: IID1 Is a required 10 Alphanumeric value.
ossim_int32 toInt32() const
char theSecurityControlNumber[16]
FIELD: ISCTLN.
virtual ossim_int32 getNumberOfBands() const
std::vector< ossim_uint32 > thePadPixelMaskRecords
virtual bool saveState(ossimKeywordlist &kwl, const ossimString &prefix="") const
char theExtendedSubheaderDataLen[6]
FIELD: IXSHDL.
virtual void setSecuritySourceDate(const ossimString &value)
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
std::vector< ossimNitfTagInformation > theTagList
char theImageMode[2]
FIELD: IMODE.
char theTargetId[18]
FIELD: TGTID.
char theImageLocation[11]
FIELD: ILOC.
virtual void setDeclassificationExempt(const ossimString &value)
char theImageSyncCode[2]
FIELD: ISYNC.
virtual ossim_int32 getActualBitsPerPixelPerBand() const
double lat
Definition: ossimDpt.h:165
static const ossimString ISDCDT_KW
char theDeclassificationType[3]
FIELD: ISDCTP.
static const ossimString ISREL_KW
virtual void setClassificationText(const ossimString &value)
virtual ossimString getImageDateAndTime() const
virtual void setCodewords(const ossimString &value)
char theAttachmentLevel[4]
FIELD: IALVL.
char theJustification[2]
FIELD: PJUST.
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
unsigned long long ossim_uint64
virtual ossim_int32 getNumberOfBlocksPerRow() const
virtual ossim_int32 getNumberOfPixelsPerBlockVert() const
unsigned int ossim_uint32
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
char theUserDefinedOverflow[4]
FIELD: UDOFL.
virtual ossim_uint32 getCompressionAlgorithmId() const
double toDouble() const
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
virtual void setDeclassificationType(const ossimString &value)
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
char theDeclassificationExempt[5]
FIELD: ISDCXM.
virtual void parseStream(std::istream &in)
virtual void setReleasingInstructions(const ossimString &value)
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
char theNumberOfBlocksPerCol[5]
FIELD: NBPC.
static const ossimString ISCTLH_KW
virtual void setDowngradeDate(const ossimString &value)
virtual bool hasPadPixelMaskRecords() const
virtual void setClassificationAuthority(const ossimString &value)
char theDisplayLevel[4]
FIELD: IDLVL.
double lon
Definition: ossimDpt.h:164
virtual ossimString getAcquisitionDateMonthDayYear(ossim_uint8 separationChar='-') const
char theDowngradeDate[9]
FIELD: ISDGDT.
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to set fields from a keyword list.
virtual void setNumberOfRows(ossim_uint32 rows)
ossimByteOrder getSystemEndianType() const
Definition: ossimEndian.h:78
char theImageSource[43]
FIELD: ISORCE.
virtual ossimString getPixelValueType() const
static const ossimString ISCAUT_KW
virtual void setNumberOfCols(ossim_uint32 cols)
static const ossimString ISCRSN_KW
void seekg64(off_type off, ios_base::seekdir way)
std::basic_istream< char > istream
Base class for char input streams.
Definition: ossimIosFwd.h:20
long toLong() const
toLong&#39;s deprecated, please use the toInts...
virtual ossim_int32 getBitsPerPixelPerBand() const
static const ossimString ISDCXM_KW
std::vector< ossim_uint32 > theBlockMaskRecords
virtual bool isValid() const
isValid will test if the fields are valid and will return true or false.
virtual ossimString getGeographicLocation() const
virtual void setSecurityControlNumber(const ossimString &value)
virtual ossimString getSecurityClassification() const
static const ossimString NBANDS_KW
virtual ossim_int32 getNumberOfRows() const
virtual ossim_int32 getNumberOfPixelsPerBlockHoriz() const
char theSecurityClassification[2]
FIELD: ISCLAS.
virtual ossimString getImageSource() const
static const ossimString ISCTLN_KW
virtual ossimString getCategory() const
virtual ossimString getRepresentation() const
ossim_uint16 theTransparentOutputPixelCodeLength
FIELD: TPXCDLNTH.
virtual bool parseStream(ossim::istream &is, bool ignoreBinaryChars)
deprecated method
double x
Definition: ossimDpt.h:164
static void setField(void *fieldDestination, const ossimString &src, std::streamsize width, std::ios_base::fmtflags ioflags=std::ios::left, char fill=' ')
Sets a field with a given string, width, and IOS flags.
virtual void setUtmSouth(ossim_uint32 zone, const ossimDpt &ul, const ossimDpt &ur, const ossimDpt &lr, const ossimDpt &ll)
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
virtual void setGeographicLocationDecimalDegrees(const ossimDpt &ul, const ossimDpt &ur, const ossimDpt &lr, const ossimDpt &ll)
char theCoordinateSystem[2]
FIELD: ICORDS.
const ossimString NBANDS_KW
static const ossimString ISCATP_KW
virtual const ossimRefPtr< ossimNitfImageBand > getBandInformation(ossim_uint32 idx) const
static const ossimString ISCLTX_KW
char theSignificantCols[9]
FIELD: NCOLS.
static const ossimString ISDG_KW
virtual const std::vector< ossimNitfTagInformation > & getTagList() const =0
char theClassificationText[44]
FIELD: ISCLTX.
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
std::basic_istringstream< char > istringstream
Class for char input memory streams.
Definition: ossimIosFwd.h:32
virtual std::ostream & printTags(std::ostream &out, const std::string &prefix=std::string()) const
print method that outputs a key/value type format adding prefix to keys.
virtual bool hasTransparentCode() const
virtual ossimNitfDataExtensionSegment * getNewDataExtensionSegment(ossim_int32 dataExtNumber, ossim::istream &in) const
virtual ossimString getCoordinateSystem() const
virtual void setSecurityClassificationSystem(const ossimString &value)
void swap(ossim_sint8 &)
Definition: ossimEndian.h:26
virtual void setImageMagnification(const ossimString &value)
virtual ossimString getImageId() const
char theExtendedSubheaderOverflow[4]
FIELD: IXSOFL.
unsigned char ossim_uint8
virtual std::ostream & print(std::ostream &out, const std::string &prefix) const
print method that outputs a key/value type format adding prefix to keys.
virtual ossimString getIMode() const
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
std::vector< ossimString > theImageComments
char thePixelValueType[4]
FIELD: PVTYPE.
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to set fields from a keyword list.
char theClassificationAuthType[2]
FIELD: ISCATP.
int ossim_int32
virtual bool saveState(ossimKeywordlist &kwl, const ossimString &prefix="") const
ossimString toString(const ossimString &formatString=ossimString("")) const
You can specify a number of different formats.
Definition: ossimDms.cpp:294
char theImageMagnification[5]
FIELD: IMAG.
virtual void setBandInfo(ossim_uint32 idx, const ossimNitfImageBandV2_1 &info)
virtual void setDowngrade(const ossimString &value)