vil_nitf2_header.cxx
Go to the documentation of this file.
1 // vil_nitf2: Written by Rob Radtke (rob@) and Harry Voorhees (hlv@) of
2 // Stellar Science Ltd. Co. (stellarscience.com) for
3 // Air Force Research Laboratory, 2005.
4 
5 #include "vil_nitf2_header.h"
6 
10 
11 #include <cassert>
12 #ifdef _MSC_VER
13 # include <vcl_msvc_warnings.h>
14 #endif
15 
19 
21  : m_field_sequence1(*get_field_definitions_1()),
22  m_field_sequence2(nullptr),
23  m_field_sequence_classification(nullptr)
24 { }
25 
27 {
28  delete m_field_sequence2;
30 }
31 
33 {
34  switch (sec) {
35  case enum_file_header: assert(0); return "";
36  case enum_image_segments: return "NUMI";
37  case enum_graphic_segments: return "NUMS";
38  case enum_label_segments: return "NUML";
39  case enum_text_segments: return "NUMT";
40  case enum_data_extension_segments: return "NUMDES";
41  case enum_reserved_extension_segments: return "NUMRES";
42  default: return "";
43  }
44 }
45 
47 {
48  switch (sec) {
49  case enum_file_header: assert(0); return "";
50  case enum_image_segments: return "LISH";
51  case enum_graphic_segments: return "LSSH";
52  case enum_label_segments: return "LLSH";
53  case enum_text_segments: return "LTSH";
54  case enum_data_extension_segments: return "LDSH";
55  case enum_reserved_extension_segments: return "LRESH";
56  default: return "";
57  }
58 }
59 
61 {
62  switch (sec) {
63  case enum_file_header: assert(0); return "";
64  case enum_image_segments: return "LI";
65  case enum_graphic_segments: return "LS";
66  case enum_label_segments: return "LL";
67  case enum_text_segments: return "LT";
68  case enum_data_extension_segments: return "LD";
69  case enum_reserved_extension_segments: return "LRE";
70  default: return "";
71  }
72 }
73 
75 {
76  // Read the first part of the header
77  bool success = m_field_sequence1.read(*stream) &&
78  // If the version is not recognized, it may not even be a NITF file
80 
81  // Now read the classification stuff whose format depends on the NITF version
82  if (success) {
86  success &= m_field_sequence_classification->read(*stream);
87  }
88 
89  // Now read in the rest of the header
90  if (success) {
93  success &= m_field_sequence2->read(*stream);
94  }
95 
96  return success;
97 }
98 
101 {
102  // Check if previously computed
106  if (field_defs) return field_defs;
107 
108  // Compute field definitions
109  field_defs = new vil_nitf2_field_definitions();
110 
111  (*field_defs)
112  .field("FSCOP", "File Copy Number", NITF_INT(5), true /*in NITF2.0*/, nullptr, nullptr)
113  .field("FSCPYS", "File Number of Copies", NITF_INT(5), true /*in NITF2.0*/, nullptr, nullptr)
114  .field("ENCRYP", "Encryption", NITF_INT(1), false, nullptr, nullptr);
115 
116  if (version == vil_nitf2_classification::V_NITF_20) {
117  (*field_defs)
118  .field("ONAME", "Originator's Name", NITF_STR_ECSA(27), true, nullptr, nullptr);
119  } else {
120  // TODO: These next three values should actually be read in as a std::vector of 3 (8bit) unsigned binary integers
121  (*field_defs)
122  .field("FBKGC", "File Background Color 1", NITF_BIN(3), true, nullptr, nullptr)
123  .field("ONAME", "Originator's Name", NITF_STR_ECSA(24), true, nullptr, nullptr);
124  }
125 
126  (*field_defs)
127  .field("OPHONE", "Originator's Phone Number", NITF_STR_ECSA(18), true, nullptr, nullptr)
128  .field("FL", "File Length", NITF_LONG(12), false, nullptr, nullptr)
129  .field("HL", "NITF File Header Length", NITF_INT(6), false, nullptr, nullptr)
130 
131  .field("NUMI", "Number of Image Segments", NITF_INT(3), false, nullptr, nullptr)
132  .repeat("NUMI", vil_nitf2_field_definitions()
133 
134  .field("LISH", "Lengh of Image Subheader", NITF_INT(6), false, nullptr, nullptr)
135  .field("LI", "Length of Image Segment", NITF_LONG(10), false, nullptr, nullptr))
136 
137  .field("NUMS", "Number of Graphic Segments", NITF_INT(3), false, nullptr, nullptr)
138  .repeat("NUMS", vil_nitf2_field_definitions()
139 
140  .field("LSSH", "Length of Graphic Subheader", NITF_INT(4), false, nullptr, nullptr)
141  .field("LS", "Length of Graphic Segment", NITF_INT(6), false, nullptr, nullptr))
142 
143  .field("NUML", "Number of Label Segments", NITF_INT(3), false, nullptr, nullptr)
144  .repeat("NUML", vil_nitf2_field_definitions()
145 
146  .field("LLSH", "Length of Label Subheader", NITF_INT(4), false, nullptr, nullptr)
147  .field("LL", "Length of Label Segment", NITF_INT(3), false, nullptr, nullptr))
148 
149  .field("NUMT", "Number of Text Segments", NITF_INT(3), false, nullptr, nullptr)
150  .repeat("NUMT", vil_nitf2_field_definitions()
151 
152  .field("LTSH", "Length of Text Subheader", NITF_INT(4), false, nullptr, nullptr)
153  .field("LT", "Length of Text Segment", NITF_INT(5), false, nullptr, nullptr))
154 
155  .field("NUMDES", "Number of Data Extension Segments", NITF_INT(3), false, nullptr, nullptr)
156  .repeat("NUMDES", vil_nitf2_field_definitions()
157 
158  .field("LDSH", "Length of Data Extension Subheader", NITF_INT(4), false, nullptr, nullptr)
159  .field("LD", "Length of Data Extension Segment", NITF_INT(9), false, nullptr, nullptr))
160 
161  .field("NUMRES", "Number of Reserved Extension Segments", NITF_INT(3), false, nullptr, nullptr)
162  .repeat("NUMRES", vil_nitf2_field_definitions()
163 
164  .field("LRESH", "Length of Reserved Extension Subheader", NITF_INT(4), false, nullptr, nullptr)
165  .field("LRE", "Length of Reserved Extension Segment", NITF_INT(7), false, nullptr, nullptr))
166 
167  .field("UDHDL", "User Defined Header Data Length", NITF_INT(5), false, nullptr, nullptr) // range [00000,00003-99999]
168 
169  .field("UDHOFL", "User Defined Header Overflow", NITF_INT(3), false, nullptr,
171 
172  .field("UDHD", "User Defined Header Data", NITF_TRES(), false,
173  new vil_nitf2_max_field_value_plus_offset_and_threshold("UDHDL", -3), nullptr)
174 
175  .field("XHDL", "Extended Header Data Length", NITF_INT(5), false, nullptr, nullptr)
176 
177  .field("XHDLOFL", "Extended Header Data Overflow", NITF_INT(3), false, nullptr,
179 
180  .field("XHD", "Extended Header Data", NITF_TRES(), false,
181  new vil_nitf2_max_field_value_plus_offset_and_threshold("XHDL", -3), nullptr);
182 
183  // Save them for future use
184  if (version == vil_nitf2_classification::V_NITF_20) {
185  s_field_definitions_20 = field_defs;
186  } else {
187  s_field_definitions_21 = field_defs;
188  }
189  return field_defs;
190 }
191 
193 {
194  if (!s_field_definitions_1) {
197  field_defs
198  .field("FHDR", "File Profile Name",
200  .value("NITF", "NITF File")
201  .value("NSIF", "NSIF File")),
202  false, nullptr, nullptr)
203  .field("FVER", "File Version", NITF_STR_BCSA(5), false, nullptr, nullptr)
204  .field("CLEVEL", "Complexity Level", NITF_INT(2), false, nullptr, nullptr)
205  // NITF2.1 - BF01, NITF2.0: <blank>
206  .field("STYPE", "Standard Type",
208  .value("BF01", "ISO/IEC IS 12087-5")),
209  true, nullptr, nullptr)
210  .field("OSTAID", "Operating Station ID", NITF_STR_BCSA(10), false, nullptr, nullptr)
211  // order of data/time depends on NITF2.1 or NITF2.0, so just read in as string for now
212  //.field("FDT", "File date and time", NITF_DAT(14), false, 0, 0));
213  .field("FDT", "File Date and Time", NITF_STR_BCSA(14), false, nullptr, nullptr)
214  .field("FTITLE", "File Title", NITF_STR_ECSA(80), true, nullptr, nullptr);
215  }
216  return s_field_definitions_1;
217 }
218 
220 {
221  std::string file_profile;
222  std::string file_version;
223  if (get_property("FHDR", file_profile) && get_property("FVER", file_version)) {
224  if (file_profile == "NSIF" && file_version == "01.00") return vil_nitf2_classification::V_NSIF_10;
225  if (file_profile == "NITF" && file_version == "01.00") return vil_nitf2_classification::V_NITF_10;
226  if (file_profile == "NITF" && file_version == "02.00") return vil_nitf2_classification::V_NITF_20;
227  if (file_profile == "NITF" && file_version == "02.10") return vil_nitf2_classification::V_NITF_21;
228  }
230 }
231 
233 {
234  auto* t = new vil_nitf2_field::field_tree;
235  t->columns.emplace_back("File Header" );
239  return t;
240 }
Functor vil_nitf2_max_field_value_plus_offset_and_threshold defines a function that sets its out para...
static vil_nitf2_field_definitions * s_field_definitions_21
bool read(vil_nitf2_istream &input, const vil_nitf2_field_definitions *field_defs=nullptr, const vil_nitf2_index_vector &indexes=vil_nitf2_index_vector())
#define NITF_INT
static vil_nitf2_field_definitions * get_field_definitions_2(vil_nitf2_classification::file_version version)
std::vector< std::string > columns
#define NITF_STR_BCSA(LEN)
#define NITF_TRES
static vil_nitf2_field_definitions * s_field_definitions_1
#define NITF_BIN
vil_nitf2_classification::file_version file_version() const
static std::string section_len_data_tag(section_type sec)
virtual vil_nitf2_field::field_tree * get_tree() const
Stream interface for VIL image loaders.
Definition: vil_stream.h:21
virtual bool read(vil_stream *stream)
vil_nitf2_field_definitions & field(std::string tag, std::string pretty_name, vil_nitf2_field_formatter *formatter, bool blanks_ok=false, vil_nitf2_field_functor< int > *width_functor=nullptr, vil_nitf2_field_functor< bool > *condition_functor=nullptr, std::string units="", std::string description="")
vil_nitf2_field_sequence * m_field_sequence_classification
virtual ~vil_nitf2_header()
vil_nitf2_field_sequence * m_field_sequence2
#define NITF_LONG
static const vil_nitf2_field_definitions * get_field_definitions(const file_version &version, std::string tag_prefix, std::string pretty_name_prefix)
static std::string section_len_header_tag(section_type sec)
static vil_nitf2_field_definitions * s_field_definitions_20
Functors used by NITF classes.
static std::string section_num_tag(section_type sec)
virtual vil_nitf2_field::field_tree * get_tree(vil_nitf2_field::field_tree *tr=nullptr) const
Functor vil_nitf2_field_value_greater_than defines a comparison predicate that sets its out parameter...
#define NITF_STR_ECSA(LEN)
bool get_property(std::string tag, T &out_value) const
#define NITF_ENUM
vil_nitf2_field_sequence m_field_sequence1
static vil_nitf2_field_definitions * get_field_definitions_1()