vil_nitf2_image_subheader.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 #include <sstream>
5 #include <cstdlib>
7 //:
8 // \file
13 #include "vil_nitf2_index_vector.h"
14 // for TREs
16 
17 #include <cassert>
18 #ifdef _MSC_VER
19 # include <vcl_msvc_warnings.h>
20 #endif
21 
24 
26  : m_field_sequence(version == vil_nitf2_classification::V_NITF_20 ?
27  *get_field_definitions_20() :
28  *get_field_definitions_21()),
29  m_data_mask_table(nullptr),
30  m_version(version)
31 {
38 }
39 
41 {
42  if (m_data_mask_table) delete m_data_mask_table;//jlm
46  }
47 }
48 
50 {
51  bool success = m_field_sequence.read(*stream);
52 
53  if (success)
54  {
55  // If this image has a data mask, we need to parse that too
56  std::string compression_code;
57  get_property("IC", compression_code);
58  if (compression_code.find_first_of('M') != std::string::npos) {
59  std::string imode;
60  get_property("IMODE", imode);
63  if (!m_data_mask_table->parse(stream)) return false;
64  }
65  }
66  return success;
67 }
68 
70 {
78  }
80 }
81 
83 {
91  }
93 }
94 
97 {
98  (*defs)
99  .field("NICOM", "Number of Image Comments", NITF_INT(1), false, nullptr, nullptr)
100 
101  //TODO: does it make any sense for a std::vector to have blank entries???? For now, I'm saying no (false parameter)
102  .repeat("NICOM", vil_nitf2_field_definitions()
103 
104  .field("ICOMn", "Image Comment n", NITF_STR_ECSA(80), false, nullptr, nullptr))
105 
106  .field("IC", "Image Compression",
108  .value("NC", "Not compressed")
109  .value("NM", "Uncompressed - contains block mask and/or pad pixel mask")
110  .value("C1", "Bi-level")
111  .value("C3", "JPEG")
112  .value("C4", "Vector Quantization")
113  .value("C5", "Lossless JPEG")
114  .value("C6", "Reserved - future correlated multicomponent compression")
115  .value("C7", "Reserved - future SAR compression")
116  .value("C8", "JPEG2000")
117  .value("I1", "Downsampled JPEG")
118  .value("M1", "Compressed - contains block mask and/or pad pixel mask")
119  .value("M3", "Compressed - contains block mask and/or pad pixel mask")
120  .value("M4", "Compressed - contains block mask and/or pad pixel mask")
121  .value("M5", "Compressed - contains block mask and/or pad pixel mask")
122  .value("M6", "Reserved - future correlated multicomponent compression")
123  .value("M7", "Reserved - future SAR compression")
124  .value("M8", "JPEG2000 - contains block mask and/or pad pixel mask")),
125  false, nullptr, nullptr);
126 
127  std::vector<std::string> comp_ic_values;
128  comp_ic_values.emplace_back("C1");
129  comp_ic_values.emplace_back("C3");
130  comp_ic_values.emplace_back("C4");
131  comp_ic_values.emplace_back("C5");
132  comp_ic_values.emplace_back("C8");
133  comp_ic_values.emplace_back("M1");
134  comp_ic_values.emplace_back("M3");
135  comp_ic_values.emplace_back("M4");
136  comp_ic_values.emplace_back("M5");
137  comp_ic_values.emplace_back("M8");
138  comp_ic_values.emplace_back("I1");
139 
140  // Using string because the valid enum values are different based on the content of IC
141  (*defs)
142  .field("COMRAT", "Compression Rate Code", NITF_STR_BCSA(4),true, nullptr,
143  new vil_nitf2_field_value_one_of<std::string>("IC", comp_ic_values))
144 
145  // The value of IREP determines which values are acceptable here
146  // (e.g., if IREP=MONO, then this must equal 1)
147  .field("NBANDS", "Number of Bands", NITF_INT(1), false, nullptr, nullptr)
148 
149  // Acceptable range [00010-99999]... only used if NBANDS=0
150  .field("XBANDS", "Number of multispectral bands", NITF_INT(5), true, nullptr,
151  new vil_nitf2_field_value_one_of<int>("NBANDS",0))
152 
154  "NBANDS", "XBANDS", new vil_nitf2_field_value_greater_than<int>("NBANDS", 0)),
156 
157  .field("IREPBAND", "nth Band Representation", NITF_STR_BCSA(2), true, nullptr, nullptr)
158  .field("ISUBCAT", "nth Band Subcategory", NITF_STR_BCSA(6), true, nullptr, nullptr)
159  .field("IFC", "nth Image Filter Condition", NITF_STR_BCSA(1), false, nullptr, nullptr)
160  .field("IMFLT", "nth Band Standard Image Filter Code", NITF_STR_BCSA(3), true, nullptr, nullptr)
161  .field("NLUTS", "Number of LUTS for the nth Image Band", NITF_INT(1, false), false, nullptr, nullptr)
162  .field("NELUT", "Number of LUT Entries for the nth Image Band", NITF_INT(5, false), false, nullptr,
163  new vil_nitf2_field_value_greater_than<int>("NLUTS", 0) /*condition*/ )
164 
166 
167  .field("LUTDnm", "nth Image Band, mth LUT", NITF_BIN(1), false,
168  new vil_nitf2_field_value<int>("NELUT"), nullptr))
169  )
170 
171  .field("ISYNC", "Image Sync Code", NITF_INT(1), false, nullptr, nullptr)
172  .field("IMODE", "Image Mode",
174  .value("B", "Band interleaved by block")
175  .value("P", "Band interleaved by pixel")
176  .value("R", "Band interleaved by row")
177  .value("S", "Band sequential")),
178  false, nullptr, nullptr)
179 
180  .field("NBPR", "Number of Blocks per Row", NITF_INT(4), false, nullptr, nullptr)
181  .field("NBPC", "Number of Blocks per Column", NITF_INT(4), false, nullptr, nullptr)
182  .field("NPPBH", "Number of Pixels per Block Horizontal", NITF_INT(4), false, nullptr, nullptr) //[0000-8192]
183  .field("NPPBV", "Number of Pixels per Block Vertical", NITF_INT(4), false, nullptr, nullptr) //[0000-8192]
184  .field("NBPP", "Number of Bits per Pixel per Band", NITF_INT(2), false, nullptr, nullptr) //[01-96]
185  .field("IDLVL", "Image Display Level", NITF_INT(3), false, nullptr, nullptr)
186  .field("IALVL", "Attachment Level", NITF_INT(3), false, nullptr, nullptr) //[000-998]
187 
188  // TODO: Enter these two values as ints with optional sign (once supported)
189  // Actually, since they are both in one field, maybe we'd want to make it one
190  // compound field (in the new tree format)
191  .field("ILOC_ROW", "Image Location Row", NITF_STR_BCSA(5), false, nullptr, nullptr)
192  .field("ILOC_COL", "Image Location Column", NITF_STR_BCSA(5), false, nullptr, nullptr)
193 
194  // TODO: THis should be a decimal field that supports non-negative power of two
195  // fractions (eg '/2 ' means 1/2, '/16 'means 1/16
196  .field("IMAG", "Image Magnification", NITF_STR_BCSA(4), false, nullptr, nullptr)
197  .field("UDIDL", "User Defined Image Data Length", NITF_INT(5), false, nullptr, nullptr) //[00000,00003-99999]
198 
199  .field("UDOFL", "User Defined Overflow", NITF_INT(3), false, nullptr,
201 
202  .field("UDID", "User Defined Image Data", NITF_TRES(), false,
203  new vil_nitf2_max_field_value_plus_offset_and_threshold("UDIDL", -3), nullptr)
204 
205  .field("IXSHDL", "Image Extended Subheader Data Length", NITF_INT(5), false, nullptr, nullptr)
206 
207  .field("IXSOFL", "Image Extended Subheader Overflow", NITF_INT(3), false, nullptr,
209 
210  .field("IXSHD", "Image Extended Subheader Data", NITF_TRES(), false,
211  new vil_nitf2_max_field_value_plus_offset_and_threshold("IXSHDL", -3), nullptr);
212 }
213 
216 {
217  switch (version)
218  {
220  {
221  (*defs)
222  .field("ICORDS", "Image Coordinate Representation",
224  .value("U", "UTM")
225  .value("G", "Geodetic/Geographic")
226  .value("N", "None")
227  .value("C", "Geocentric")),
228  false, nullptr, nullptr);
229 
230  std::vector<std::string> igeolo_icords;
231  igeolo_icords.emplace_back("U");
232  igeolo_icords.emplace_back("G");
233  igeolo_icords.emplace_back("C");
234 
235  (*defs)
236  .field("IGEOLO", "Image Geographic Location", NITF_STR_BCSA(60), false, nullptr,
237  new vil_nitf2_field_value_one_of<std::string>("ICORDS", igeolo_icords));
238  break;
239  }
241  {
242  (*defs)
243  .field("ICORDS", "Image Coordinate Representation",
245  .value("U", "UTM expressed in MGRS form")
246  .value("G", "Geographic")
247  .value("N", "UTM/UPS (Northern hemisphere)") // actually means None for Nitf 2.0
248  .value("S", "UTM/UPS (Southern hemisphere)") // NITF 2.1 only
249  .value("D", "Decimal degrees")), // NITF 2.1 only
250  true, nullptr, nullptr)
251 
252  .field("IGEOLO", "Image Geographic Location", NITF_STR_BCSA(60), false, nullptr,
253  new vil_nitf2_field_specified("ICORDS"));
254  break;
255  }
256  default:
257  assert(!"unsupported case");
258  } // end switch
259 }
260 
262 {
263  (*defs)
264  .field("ENCRYP", "Encryption",
266  // Only one valid value, until the spec gets updated
267  .value("0", "Not Encrypted")),
268  false, nullptr, nullptr)
269  .field("ISORCE", "Image Source", NITF_STR_ECSA(42), true, nullptr, nullptr)
270  //TODO: only allow range [00000001-99999999]
271  .field("NROWS", "Number of Significant Rows in Image", NITF_INT(8, false), false, nullptr, nullptr)
272  //TODO: only allow range [00000001-99999999]
273  .field("NCOLS", "Number of Significant Columns in Image", NITF_INT(8, false), false, nullptr, nullptr)
274  .field("PVTYPE", "Pixel Value Type",
276  .value("INT", "Integer")
277  .value("B", "Bi-level")
278  .value("SI", "2's complement signed integer")
279  .value("R", "Real")
280  .value("C", "Complex")),
281  false, nullptr, nullptr)
282  .field("IREP", "Image Representation",
284  .value("MONO", "Monochrome")
285  .value("RGB", "Red, green, blue true color")
286  .value("RGB/LUT", "Red, green, blue mapped Color")
287  .value("MULTI", "Multiband imagery")
288  .value("NODISPLY", "Not intended for display")
289  .value("NVECTOR", "Cartesian coordinates")
290  .value("POLAR", "Polar coordinates")
291  .value("VPH", "SAR video phase history")
292  .value("YCbCr601", "BT.601-5 color space")),
293  false, nullptr, nullptr)
294 #ifdef UNCLASS_ONLY
295  .field("ICAT", "Image Category",
297  .value("VIS", "Visible imagery")
298  .value("SL", "Side-looking radar")
299  .value("TI", "Thermal infrared")
300  .value("FL", "Forward-looking radar")
301  .value("RD", "Radar")
302  .value("EO", "Electro-optical")
303  .value("OP", "Optical")
304  .value("HR", "High-resolution radar")
305  .value("HS", "Hyperspectral")
306  .value("CP", "Color frame photography")
307  .value("BP", "Black/white frame photography")
308  .value("SARIQ", "SAR radio hologram")
309  .value("SAR", "Synthetic aperture radar")
310  .value("IR", "Infrared")
311  .value("MS", "Multispectral")
312  .value("FP", "Fingerprints")
313  .value("MRI", "Magnetic resonance imagery")
314  .value("XRAY", "X-ray")
315  .value("CAT", "CAT scan")
316  .value("VD", "Video")
317  .value("BARO", "Barometric pressure")
318  .value("CURRENT","Water current")
319  .value("DEPTH", "Water depth")
320  .value("MAP", "Raster map")
321  .value("PAT", "Color patch")
322  .value("LEG", "Legends")
323  .value("DTEM", "Elevation models")
324  .value("MATR", "Matrix data (other types)")
325  .value("LOCG", "Location Grids")),
326  false, 0, 0)
327 #else
328  .field("ICAT", "Image Category", NITF_STR_ECSA(8), false, nullptr, nullptr)
329 #endif //UNCLASS_ONLY
330 
331  .field("ABPP", "Actual Bits Per Pixel per Band", NITF_INT(2), false, nullptr, nullptr) //[1-96]
332  .field("PJUST", "Pixel Justification",
334  .value("L", "Left-justified")
335  .value("R", "Right-justified")),
336  false, nullptr, nullptr);
337 }
338 
340 {
341  (*defs)
342  .field("IM", "File Part Type",
344  .value("IM", "Image Header")))
345  .field("IID1", "Image Identifier 1", NITF_STR_BCSA(10))
346 
347  // order of data/time depends on NITF2.1 or NITF2.0, so just read in as string for now
348  //.field("IDATIM", "Image Date and Time", NITF_DAT(14)));
349  .field("IDATIM", "Image Date and Time", NITF_STR_BCSA(14))
350  .field("TGTID", "Target Identifier", NITF_STR_BCSA(17), true)
351  .field("IID2", "Image Identifier 2", NITF_STR_ECSA(80), true);
352 }
353 
354 #if 0 // get_date_time() commented out
356 get_date_time(int& year, int& month, int& day, int& hour, int& min)
357 {
358  std::cout << "In vil_nitf2_image_subheader::get_date_time!\n";
359  std::string date_time = "";
360  bool success = this->get_property("IDATIM", date_time);
361  if (!success) {
362  std::cout << "IDATIM Property failed in vil_nitf2_image_subheader\n";
363  return false;
364  }
365  std::cout << "In vil_nitf2_image_subheader::get_date_time!\n";
366  //d==day,h==hour,n==min,ss==sec,Z==zulu,m==month, y==year suffix
367  // format is ddhhnnssZmmmyy
368  std::string s_day, s_hour, s_min, s_month, s_year_suff;
369  s_day = date_time.substr(0,2);
370  s_hour = date_time.substr(2,2);
371  s_min = date_time.substr(4,2);
372  s_month = date_time.substr(9,3);
373  s_year_suff = date_time.substr(12,2);
374  std::string months[]={"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG",
375  "SEP", "OCT", "NOV", "DEC"};
376  bool found = false;
377  std::cout << date_time << '\n'
378  << s_day << ' ' << s_hour << ' ' << s_min
379  << ' ' << s_month << ' ' << s_year_suff << std::endl;
380  for (int i = 0; (i<12)&&(!found); ++i)
381  if (s_month==months[i]){
382  found = true;
383  month = i+1;
384  }
385  if (!found)
386  return false;
387  day = std::atoi(s_day.c_str());
388  hour = std::atoi(s_hour.c_str());
389  min = std::atoi(s_min.c_str());
390  year = std::atoi(s_year_suff.c_str());
391  year += 2000;//good until the next millenium
392  return true;
393 }
394 #endif // 0
395 
397 get_date_time(int& year, int& month, int& day, int& hour, int& min, int& sec)
398 {
399  std::string date_time = "";
400  bool success = this->get_property("IDATIM", date_time);
401  if (!success) {
402  std::cout << "IDATIM Property failed in vil_nitf2_image_subheader\n";
403  return false;
404  }
405  //d==day,h==hour,n==min,ss==sec,Z==zulu,m==month, y==year
406  // format is ddhhnnssZmmmyy OR yyyymmddhhnnss (the NITF 2.1 Commercial format)
407  std::string s_day, s_hour, s_min, s_month, s_year, s_sec;
408  // try ddhhnnssZmmmyy first
409  std::string s_zulu = date_time.substr(8,1);
410  if (s_zulu=="Z") {
411  s_day = date_time.substr(0,2);
412  s_hour = date_time.substr(2,2);
413  s_min = date_time.substr(4,2);
414  s_sec = date_time.substr(6,2);
415  s_month = date_time.substr(9,3);
416  s_year = date_time.substr(12,2);
417  std::string months[]={"JAN", "FEB", "MAR", "APR",
418  "MAY", "JUN", "JUL", "AUG",
419  "SEP", "OCT", "NOV", "DEC"};
420  bool found = false;
421  for (int i = 0; (i<12)&&(!found); ++i) {
422  if (s_month==months[i]){
423  found = true;
424  month = i+1;
425  }
426  }
427  if (!found) {
428  return false;
429  }
430  }
431  else { // try yyyymmddhhnnss
432  s_year = date_time.substr(0,4);
433  s_month = date_time.substr(4,2);
434  s_day = date_time.substr(6,2);
435  s_hour = date_time.substr(8,2);
436  s_min = date_time.substr(10,2);
437  s_sec = date_time.substr(12,2);
438  month = std::atoi(s_month.c_str());
439  }
440  day = std::atoi(s_day.c_str());
441  hour = std::atoi(s_hour.c_str());
442  min = std::atoi(s_min.c_str());
443  sec = std::atoi(s_sec.c_str());
444  year = std::atoi(s_year.c_str());
445  if (year < 100)
446  year += 2000;//good until the next millenium
447  return true;
448 }
449 
451 {
452  //the number of image bands is stored in NBANDS unless NBANDS=0.
453  //in that case, then it's stored under XBANDS. That's why we have
454  //to potentially try both
455  int numBands;
456  if (get_property("NBANDS", numBands))
457  {
458  if (numBands > 0 ||
459  get_property("XBANDS", numBands))
460  {
461  return numBands;
462  }
463  }
464  return 0;
465 }
466 
468 {
469  int pixels_per_block;
470  if (get_property("NPPBH", pixels_per_block)) {
471 
472  // Fix added 4/12/17 by tpollard to conform to NITF spec 5.4.2.2d in
473  // special case of single block image and width/height > 8192
474  if (pixels_per_block == 0) {
475 
476  int blocks_per_row = 0;
477  get_property("NBPR", blocks_per_row);
478  if (blocks_per_row != 1) return 0;
479 
480  if (get_property("NCOLS", pixels_per_block))
481  return pixels_per_block;
482  return 0;
483 
484  // Standard case
485  } else
486  return pixels_per_block;
487  }
488  return 0;
489 }
490 
492 {
493  int pixels_per_block;
494  if (get_property("NPPBV", pixels_per_block)) {
495 
496  // Fix added 4/12/17 by tpollard to conform to NITF spec 5.4.2.2d in
497  // special case of single block image and width/height > 8192
498  if (pixels_per_block == 0) {
499 
500  int blocks_per_col = 0;
501  get_property("NBPC", blocks_per_col);
502  if (blocks_per_col != 1) return 0;
503 
504  if (get_property("NROWS", pixels_per_block))
505  return pixels_per_block;
506  return 0;
507 
508  // Standard case
509  } else
510  return pixels_per_block;
511  }
512  return 0;
513 }
514 
516 {
517  int blocks_per_row;
518  if (get_property("NBPR", blocks_per_row)) {
519  return blocks_per_row;
520  }
521  return 0;
522 }
523 
525 {
526  int blocks_per_col;
527  if (get_property("NBPC", blocks_per_col)) {
528  return blocks_per_col;
529  }
530  return 0;
531 }
532 
534 {
535  int bits_per_pixel;
536  if (get_property("ABPP", bits_per_pixel)) {
537  return bits_per_pixel;
538  }
539  return 0;
540 }
541 
543 {
544  std::string source;
545  if (get_property("ISORCE", source)) {
546  return source;
547  }
548  return "";
549 }
550 
552 {
553  std::string id;
554  if (get_property("IREP", id)) {
555  return id;
556  }
557  return "";
558 }
559 
561  int& n_luts, int& ne_lut,
562  std::vector< std::vector< unsigned char > >& lut_d) const
563 {
564  if (!m_field_sequence.get_value("NLUTS", vil_nitf2_index_vector(band), n_luts) ||
565  !m_field_sequence.get_value("NELUT", vil_nitf2_index_vector(band), ne_lut)) {
566  return false;
567  }
568  lut_d.clear();
569  lut_d.resize(n_luts);
570  void* raw_lut_data;
571  for (int lut_index = 0 ; lut_index < n_luts ; lut_index++) {
572  lut_d[lut_index].resize(ne_lut);
573  //get the lut_index'th lut for the given image band
574  vil_nitf2_index_vector index( band, lut_index );
575  if (m_field_sequence.get_value("LUTDnm", index, raw_lut_data )) {
576  for ( int el_index = 0 ; el_index < ne_lut ; el_index++ ) {
577  lut_d[lut_index][el_index] = static_cast<unsigned char*>(raw_lut_data)[el_index];
578  }
579  }
580  else {
581  break;
582  }
583  }
584  return true;
585 }
586 
588 {
589  auto* t = new vil_nitf2_field::field_tree;
590  std::stringstream name_stream;
591  name_stream << "Image Subheader";
592  if ( i > 0 ) name_stream << " #" << i;
593  t->columns.push_back( name_stream.str() );
595  return t;
596 }
597 
598 // Add definitions for rational polynomial coefficients
600 {
603  if (!tr)
604  {
605  vil_nitf2_tagged_record_definition::define("RPC00B", "Rational Polynomial Coefficients Type B" )
606 
607  // These are the "offset and scale" fields that precede the polynomial coefficients
608  .field("SUCCESS", "Success parameter", NITF_INT(1)) // not used, but must read
609  .field("ERR_BIAS", "ERR_BIAS", NITF_DBL(7, 2, false), true) // not used, but must read
610  .field("ERR_RAND", "ERR_RAND", NITF_DBL(7, 2, false), true) // not used
611  .field("LINE_OFF", "Line Offset", NITF_INT(6))
612  .field("SAMP_OFF", "Sample Offset", NITF_INT(5))
613  .field("LAT_OFF", "Latitude Offset", NITF_DBL(8, 4, true), false)
614  .field("LON_OFF", "Longitude offset", NITF_DBL(9, 4, true), false)
615  .field("HEIGHT_OFF", "Height Offset", NITF_INT(5, true))
616  .field("LINE_SCALE", "Line Scale", NITF_INT(6))
617  .field("SAMP_SCALE", "Sample Scale", NITF_INT(5))
618  .field("LAT_SCALE", "Latitude Scale", NITF_DBL(8, 4, true), false)
619  .field("LON_SCALE", "Longitude Scale", NITF_DBL(9, 4, true), false)
620  .field("HEIGHT_SCALE", "Height Scale", NITF_INT(5, true))
621 
622  // Now come the 4 sequential groups of (20 each) polynomial coefficients
623  // for line number, line density, sample number and sample density.
624  // As these values are in <+/->n.nnnnnnE<+/->n (exponential) format,
625  // let's just read as strings now and convert into doubles later.
626 
628  .field("LNC", "Line Number Coefficient", NITF_EXP(6,1))
629  )
631  .field("LDC", "Line Density Coefficient", NITF_EXP(6,1))
632  )
634  .field("SNC", "Sample Number Coefficient", NITF_EXP(6,1))
635  )
637  .field("SDC", "Sample Density Coefficient", NITF_EXP(6,1))
638  )
639  .end(); // of RPC TRE
640  }
642  if (!tr)
643  {
644  vil_nitf2_tagged_record_definition::define("RPC00A", "Rational Polynomial Coefficients Type A" )
645 
646  // These are the "offset and scale" fields that precede the polynomial coefficients
647  .field("SUCCESS", "Success parameter", NITF_INT(1)) // not used, but must read
648  .field("ERR_BIAS", "ERR_BIAS", NITF_DBL(7, 2, false), true) // not used, but must read
649  .field("ERR_RAND", "ERR_RAND", NITF_DBL(7, 2, false), true) // not used
650  .field("LINE_OFF", "Line Offset", NITF_INT(6))
651  .field("SAMP_OFF", "Sample Offset", NITF_INT(5))
652  .field("LAT_OFF", "Latitude Offset", NITF_DBL(8, 4, true), false)
653  .field("LON_OFF", "Longitude offset", NITF_DBL(9, 4, true), false)
654  .field("HEIGHT_OFF", "Height Offset", NITF_INT(5, true))
655  .field("LINE_SCALE", "Line Scale", NITF_INT(6))
656  .field("SAMP_SCALE", "Sample Scale", NITF_INT(5))
657  .field("LAT_SCALE", "Latitude Scale", NITF_DBL(8, 4, true), false)
658  .field("LON_SCALE", "Longitude Scale", NITF_DBL(9, 4, true), false)
659  .field("HEIGHT_SCALE", "Height Scale", NITF_INT(5, true))
660 
661  // Now come the 4 sequential groups of (20 each) polynomial coefficients
662  // for line number, line density, sample number and sample density.
663  // As these values are in <+/->n.nnnnnnE<+/->n (exponential) format,
664  // let's just read as strings now and convert into doubles later.
665 
667  .field("LNC", "Line Number Coefficient", NITF_EXP(6,1))
668  )
670  .field("LDC", "Line Density Coefficient", NITF_EXP(6,1))
671  )
673  .field("SNC", "Sample Number Coefficient", NITF_EXP(6,1))
674  )
676  .field("SDC", "Sample Density Coefficient", NITF_EXP(6,1))
677  )
678  .end(); // of RPCA TRE
679  }
680 }
681 
683 {
685  if (!tr)
686  {
687  vil_nitf2_tagged_record_definition::define("USE00A", "EXPLOITATION USABILITY EXTENSION FORMAT" )
688 
689  .field("ANGLE_TO_NORTH","Angle to North", NITF_INT(3)) // not used, but must read
690  .field("MEAN_GSD", "Mean Ground Sample Distance",NITF_DBL(5, 1, false), false) // not used, but must read
691  .field("Reserved1", "",NITF_STR(1), false)
692  .field("DYNAMIC_RANGE", "Dynamic Range",NITF_LONG(5, false), true) // not used
693  .field("Reserved2", "",NITF_STR(7), false)
694  .field("OBL_ANG", "Obliquity Angle", NITF_DBL(5,2,false), true)
695  .field("ROLL_ANG", "Roll Angle", NITF_DBL(6,2,true), true)
696  .field("Reserved3", "",NITF_STR(37), false)
697  .field("N_REF", "Number of Reference Lines.", NITF_INT(2, false), false)
698  .field("REV_NUM", "Revolution Number", NITF_LONG(5, false), false)
699  .field("N_SEG", "Number of Segments", NITF_INT(3, false), false)
700  .field("MAX_LP_SEG", "Maximum Lines Per Segment", NITF_LONG(6,false), true)
701  .field("Reserved4", "",NITF_STR(12), false)
702  .field("SUN_EL", "Sun Elevation", NITF_DBL(5,1,true),false)
703  .field("SUN_AZ", "Sun Azimuth", NITF_DBL(5,1,false),false)
704 
705 
706  .end(); // of USE00A TRE
707  }
708 }
709 
710 // Collect the Sun angles
712 get_sun_params( double& sun_el, double& sun_az)
713 {
714  // Now get the sub-header TRE parameters
716  vil_nitf2_tagged_record_sequence::iterator tres_itr;
717  this->get_property("IXSHD", isxhd_tres);
718 
719 
720  bool success=false;
721  // Check through the TREs to find "RPC"
722  for (tres_itr = isxhd_tres.begin(); tres_itr != isxhd_tres.end(); ++tres_itr)
723  {
724  std::string type = (*tres_itr)->name();
725  if ( type == "USE00A")
726  {
727  success = (*tres_itr)->get_value("SUN_EL", sun_el);
728  success = success && (*tres_itr)->get_value("SUN_AZ", sun_az);
729  if (!success)
730  std::cout<<"\n Error reading USE00A\n";
731  else
732  return success;
733  }
734  else if ( type == "MPD26A")
735  {
736  success = (*tres_itr)->get_value("SUN_EL", sun_el);
737  success = success && (*tres_itr)->get_value("SUN_AZ", sun_az);
738  if (!success)
739  std::cout<<"\n Error reading MPD26A\n";
740  else
741  return success;
742  }
743  }
744  return success;
745 }
746 
748 {
750  if (!tr)
751  {
752  vil_nitf2_tagged_record_definition::define("ICHIPB", "ICHIPB SUPPORT DATA EXTENSION" )
753 
754  .field("XFRM_FLAG", "Non-linear Transformation Flag", NITF_INT(2),false) // not used, but must read
755  .field("SCALE_FACTOR", "Scale Factor Relative to R0",NITF_DBL(10, 5, false), false) // not used, but must read
756  .field("ANAMRPH_CORR", "Anamorphic Correction Indicator", NITF_INT(2),false)
757  .field("SCANBLK_NUM", "Scan Block Number",NITF_INT(2, false), true) // not used
758  //: intelligent data
759  .field("OP_ROW_11", "Output product row number component of grid point index (1,1)",NITF_DBL(12,3,false), false)
760  .field("OP_COL_11", "Output product column number component of grid point index (1,1)",NITF_DBL(12,3,false), false)
761 
762  .field("OP_ROW_12", "Output product row number component of grid point index (1,2)",NITF_DBL(12,3,false), false)
763  .field("OP_COL_12", "Output product column number component of grid point index (1,2)",NITF_DBL(12,3,false), false)
764 
765  .field("OP_ROW_21", "Output product row number component of grid point index (2,1)",NITF_DBL(12,3,false), false)
766  .field("OP_COL_21", "Output product column number component of grid point index (2,1)",NITF_DBL(12,3,false), false)
767 
768  .field("OP_ROW_22", "Output product row number component of grid point index (2,2)",NITF_DBL(12,3,false), false)
769  .field("OP_COL_22", "Output product column number component of grid point index (2,2)",NITF_DBL(12,3,false), false)
770 
771  //: full image coordinate system
772  .field("FI_ROW_11", "Output product row number component of grid point index (1,1)",NITF_DBL(12,3,false), false)
773  .field("FI_COL_11", "Output product column number component of grid point index (1,1)",NITF_DBL(12,3,false), false)
774 
775  .field("FI_ROW_12", "Output product row number component of grid point index (1,2)",NITF_DBL(12,3,false), false)
776  .field("FI_COL_12", "Output product column number component of grid point index (1,2)",NITF_DBL(12,3,false), false)
777 
778  .field("FI_ROW_21", "Output product row number component of grid point index (2,1)",NITF_DBL(12,3,false), false)
779  .field("FI_COL_21", "Output product column number component of grid point index (2,1)",NITF_DBL(12,3,false), false)
780 
781  .field("FI_ROW_22", "Output product row number component of grid point index (2,2)",NITF_DBL(12,3,false), false)
782  .field("FI_COL_22", "Output product column number component of grid point index (2,2)",NITF_DBL(12,3,false), false)
783 
784  .field("FI_ROW", "Full Image Number of Rows", NITF_LONG(8,false), false)
785  .field("FI_COL", "Full Image Number of COlumns", NITF_LONG(8,false), false)
786 
787  .end(); // of ICHIPB TRE
788  }
789 }
790 
791 
793 {
795  if (!tr)
796  {
797  vil_nitf2_tagged_record_definition::define("STDIDC", "STDIDC SUPPORT DATA EXTENSION" )
798 
799  .field("ACQUISITION_DATE", "", NITF_STR(14),false) // not used, but must read
800  .field("MISSION", "",NITF_STR(14), false) // not used, but must read
801  .field("PASS", "", NITF_STR(2),false)
802  .field("OP_NUM", "",NITF_INT(3, false), false) // not used
803  .field("START_SEGMENT", "",NITF_STR(2), false)
804  .field("REPRO_NUM", "",NITF_INT(2,false), false)
805  .field("REPLAY_REGEN", "",NITF_STR(3), false)
806  .field("BLANK_FILL", "",NITF_STR(1), true)
807  .field("START_COLUMN", "",NITF_INT(3,false), false)
808  .field("START_ROW", "",NITF_INT(5,false), false)
809  .field("END_SEGMENT", "",NITF_STR(2), false)
810  .field("END_COLUMN", "",NITF_INT(3,false), false)
811  .field("END_ROW", "",NITF_INT(5,false), false)
812  .field("COUNTRY", "",NITF_STR(2), true)
813  .field("WAC", "",NITF_INT(4,false), true)
814  .field("LOCATION", "",NITF_STR(11), false)
815  .field("RESERVED1", "",NITF_STR(5), true)
816  .field("RESERVED2", "",NITF_STR(8), true)
817 
818  .end(); // of STDIDC TRE
819  }
820 }
821 
822 
824 {
826  if (!tr)
827  {
828  vil_nitf2_tagged_record_definition::define("STDIDB", "STDIDB SUPPORT DATA EXTENSION" )
829 
830  .field("unk1", "", NITF_INT(2,false),false) // not used, but must read
831  .field("unk2", "", NITF_STR(3),false) // not used, but must read
832  .field("unk3", "", NITF_INT(2,false),false) // not used, but must read
833  .field("unk4", "", NITF_INT(4,false),false) // not used, but must read
834  .field("unk5", "", NITF_STR(2),false) // not used, but must read
835  .field("unk6", "", NITF_INT(3,false),false) // not used, but must read
836  .field("unk7", "", NITF_STR(2),false) // not used, but must read
837  .field("unk8", "", NITF_INT(2,false),false)
838  .field("unk9", "", NITF_STR(3),false) // not used, but must read
839  .field("unk10", "", NITF_STR(1),false)
840  .field("START_COLUMN", "", NITF_STR(2),false)
841  .field("START_ROW", "", NITF_INT(5,false),false)
842  .field("unk11", "", NITF_STR(2),false) // not used, but must read
843  .field("unk12", "", NITF_STR(2),false) // not used, but must read
844  .field("unk13", "", NITF_INT(5,false),false) // not used, but must read
845  .field("unk14", "", NITF_STR(2),false) // not used, but must read
846  .field("unk15", "", NITF_INT(4,false),false) // not used, but must read
847  .field("unk16", "", NITF_STR(4),false) // not used, but must read
848  .field("unk17", "", NITF_STR(1),false) // not used, but must read
849  .field("unk18", "", NITF_STR(5),false)
850  .field("unk19", "", NITF_STR(1),false) // not used, but must read
851  .field("unk20", "", NITF_STR(5),false)
852  .field("unk21", "", NITF_STR(7),false)
853 
854  .end(); // of STDIDC TRE
855  }
856 }
857 
858 
860 {
862  if (!tr)
863  {
864  vil_nitf2_tagged_record_definition::define("MPD26A", "MPD26A SUPPORT DATA EXTENSION" )
865 
866  .field("UNK1", "Unknown ", NITF_DBL(11,7,true), false) // not used, but must read
867  .field("UNK2", "Unknown ", NITF_STR(2), false) // not used, but must read
868  .field("UNK3", "Unknown ", NITF_INT(7,false),false) // not used, but must read
869  .field("UNK31", "Unknown ", NITF_STR(10),false) // not used, but must read
870  .field("UNK4", "Unknown ", NITF_DBL(6,3,false), true) // not used, but must read
871  .field("UNK5", "Unknown ", NITF_DBL(9,5,false), false) // not used, but must read
872  .field("UNK6", "Unknown ", NITF_STR(3), false) // not used, but must read
873  .field("UNK7", "Unknown ", NITF_STR(1), false) // not used, but must read
874  .field("UNK8", "Unknown ", NITF_STR(1), false) // not used, but must read
875  .field("SUN_EL", "Sun Elevation angle", NITF_DBL(5,1,true),false)
876  .field("SUN_AZ", "Sun Azimuthal angle", NITF_DBL(5,1,false),false)
877  .field("UNK9", "Unknown ", NITF_STR(1), false) // not used, but must read
878  .field("UNK10", "Unknown ", NITF_STR(1), false) // not used, but must read
879  .field("UNK11", "Unknown ", NITF_INT(4,true), false) // not used, but must read
880  .field("UNK12", "Unknown ", NITF_INT(9,true), false) // not used, but must read
881  .field("UNK13", "Unknown ", NITF_INT(9,true), false) // not used, but must read
882  .field("UNK14", "Unknown ", NITF_INT(9,true), false) // not used, but must read
883  .field("UNK15", "Unknown ", NITF_STR(10), false) // not used, but must read
884  .field("UNK16", "Unknown ", NITF_INT(9,true), false) // not used, but must read
885  .field("UNK17", "Unknown ", NITF_INT(9,true), false) // not used, but must read
886  .field("UNK18", "Unknown ", NITF_INT(9,true), false) // not used, but must read
887  .field("UNK19", "Unknown ", NITF_INT(9,true), false) // not used, but must read
888  .field("UNK20", "Unknown ", NITF_INT(9,true), false) // not used, but must read
889  .field("UNK21", "Unknown ", NITF_INT(9,true), false) // not used, but must read
890  .field("UNK22", "Unknown ", NITF_INT(9,true), false) // not used, but must read
891  .field("UNK23", "Unknown ", NITF_INT(9,true), false) // not used, but must read
892  .field("UNK24", "Unknown ", NITF_INT(9,true), false) // not used, but must read
893  .field("UNK16", "Unknown ", NITF_INT(9,true), false) // not used, but must read
894  .field("UNK17", "Unknown ", NITF_INT(9,true), false) // not used, but must read
895  .field("UNK18", "Unknown ", NITF_INT(9,true), false) // not used, but must read
896  .field("UNK19", "Unknown ", NITF_INT(9,true), false) // not used, but must read
897  .field("UNK20", "Unknown ", NITF_INT(9,true), false) // not used, but must read
898  .field("UNK21", "Unknown ", NITF_INT(9,true), false) // not used, but must read
899  .field("UNK22", "Unknown ", NITF_INT(9,true), false) // not used, but must read
900  .field("UNK23", "Unknown ", NITF_INT(9,true), false) // not used, but must read
901  .field("UNK24", "Unknown ", NITF_INT(9,true), false) // not used, but must read
902  .field("UNK16", "Unknown ", NITF_INT(9,true), false) // not used, but must read
903  .field("UNK17", "Unknown ", NITF_INT(9,true), false) // not used, but must read
904  .field("UNK18", "Unknown ", NITF_INT(9,true), false) // not used, but must read
905  .field("UNK19", "Unknown ", NITF_INT(9,true), false) // not used, but must read
906  .field("UNK20", "Unknown ", NITF_INT(9,true), false) // not used, but must read
907  .field("UNK21", "Unknown ", NITF_INT(9,true), false) // not used, but must read
908  .field("UNK22", "Unknown ", NITF_INT(9,true), true) // not used, but must read
909  .field("UNK23", "Unknown ", NITF_INT(9,true), true) // not used, but must read
910  .field("UNK24", "Unknown ", NITF_INT(9,true), true) // not used, but must read
911 
912  .end(); // of MPD26A TRE
913  }
914 }
915 
916 
917 // obtain column and row offset from STDIDB /SDTDIDC
919 get_correction_offset(double & u_off, double & v_off)
920 {
921  // Now get the sub-header TRE parameters
923  vil_nitf2_tagged_record_sequence::iterator tres_itr;
924  this->get_property("IXSHD", isxhd_tres);
925 
926  double ulr=0;
927  double ulc=0;
928  // Check through the TREs to find "RPC"
929  for (tres_itr = isxhd_tres.begin(); tres_itr != isxhd_tres.end(); ++tres_itr)
930  {
931  std::string type = (*tres_itr)->name();
932  if ( type == "ICHIPB" )
933  {
934  double r_off=1.0; // dummy initialisation
935  double c_off=1.0; // to silence a compiler warning
936  if ( (*tres_itr)->get_value("FI_ROW_11", r_off) &&
937  (*tres_itr)->get_value("FI_COL_11", c_off) )
938  {
939  ulr+=r_off;
940  ulc+=c_off;
941  }
942  else
943  return false;
944  }
945  else if ( type == "STDIDC" )
946  {
947  int r_off=1;
948  int c_off=1;
949  if ( (*tres_itr)->get_value("START_ROW", r_off) &&
950  (*tres_itr)->get_value("START_COLUMN", c_off) )
951  {
952  ulr+=(double)((r_off-1)*get_pixels_per_block_y());
953  ulc+=(double)((c_off-1)*get_pixels_per_block_x());
954  }
955  else
956  return false;
957  }
958  else if ( type == "STDIDB" )
959  {
960  int r_off=1;
961  int c_off=1;
962  std::string temp_off;
963  if ( (*tres_itr)->get_value("START_ROW", r_off) &&
964  (*tres_itr)->get_value("START_COLUMN", temp_off) )
965  {
966  if ((int)temp_off[0]>=65)
967  c_off=((int)temp_off[0]-55)*10;
968  else
969  c_off=((int)temp_off[0]-48)*10;
970  c_off+=(int)temp_off[1]-48;
971  ulr+=(r_off-1)*get_pixels_per_block_y();
972  ulc+=(c_off-1)*get_pixels_per_block_x();
973  }
974  else
975  return false;
976  }
977  }
978  u_off=ulc;
979  v_off=ulr;
980  return true;
981 }
982 
983 // Collect the RPC parameters for the current image. Image corners are reported
984 // as a string of geographic coordinates,one for each image corner.
986 get_rpc_params( std::string& rpc_type, std::string& image_id,
987  std::string& image_corner_geo_locations,
988  double* rpc_data )
989 {
990  // Get image ID and location from main header values
991  std::string iid2 = "";
992  bool success = this->get_property("IID2", iid2);
993  if (!success) {
994  std::cout << "IID2 Property failed in vil_nitf2_image_subheader\n";
995  return false;
996  }
997  image_id = iid2.substr(0,39);// trim length to NN characters to match file ID
998  std::string igeolo = "";
999  success = this->get_property("IGEOLO", igeolo);
1000  if (!success) {
1001  std::cout << "IGEOLO Property failed in vil_nitf2_image_subheader\n";
1002  return false;
1003  }
1004  image_corner_geo_locations = igeolo;
1005 
1006  // Now get the sub-header TRE parameters
1008  vil_nitf2_tagged_record_sequence::iterator tres_itr;
1009  this->get_property("IXSHD", isxhd_tres);
1010 
1011 
1012  // Check through the TREs to find "RPC"
1013  for (tres_itr = isxhd_tres.begin(); tres_itr != isxhd_tres.end(); ++tres_itr)
1014  {
1015  std::string type = (*tres_itr)->name();
1016 
1017  if ( type == "RPC00B" || type == "RPC00A") // looking for "RPC..."
1018  {
1019  // set type in return value
1020  rpc_type = type;
1021 
1022  // get offsets and scales, print a couple to make sure values are correct
1023  int line_off;
1024  success = (*tres_itr)->get_value("LINE_OFF", line_off);
1025  if (!success) {
1026  std::cout << "LINE_OFF Property failed in vil_nitf2_image_subheader\n";
1027  return false;
1028  }
1029  rpc_data[80] = line_off;
1030 
1031  int samp_off;
1032  success = (*tres_itr)->get_value("SAMP_OFF", samp_off);
1033  if (!success) {
1034  std::cout << "SAMP_OFF Property failed in vil_nitf2_image_subheader\n";
1035  return false;
1036  }
1037  rpc_data[81] = samp_off;
1038 
1039  double lat_off;
1040  success = (*tres_itr)->get_value("LAT_OFF", lat_off);
1041  if (!success) {
1042  std::cout << "LAT_OFF Property failed in vil_nitf2_image_subheader\n";
1043  return false;
1044  }
1045  rpc_data[82] = lat_off;
1046 
1047  double lon_off;
1048  success = (*tres_itr)->get_value("LON_OFF", lon_off);
1049  if (!success) {
1050  std::cout << "LON_OFF Property failed in vil_nitf2_image_subheader\n";
1051  return false;
1052  }
1053  rpc_data[83] = lon_off;
1054 
1055  int height_off;
1056  success = (*tres_itr)->get_value("HEIGHT_OFF", height_off);
1057  if (!success) {
1058  std::cout << "HEIGHT_OFF Property failed in vil_nitf2_image_subheader\n";
1059  return false;
1060  }
1061  rpc_data[84] = height_off;
1062 
1063  int line_scale;
1064  success = (*tres_itr)->get_value("LINE_SCALE", line_scale);
1065  if (!success) {
1066  std::cout << "LINE_SCALE Property failed in vil_nitf2_image_subheader\n";
1067  return false;
1068  }
1069  rpc_data[85] = line_scale;
1070 
1071  int samp_scale;
1072  success = (*tres_itr)->get_value("SAMP_SCALE", samp_scale);
1073  if (!success) {
1074  std::cout << "SAMP_SCALE Property failed in vil_nitf2_image_subheader\n";
1075  return false;
1076  }
1077  rpc_data[86] = samp_scale;
1078 
1079  double lat_scale;
1080  success = (*tres_itr)->get_value("LAT_SCALE", lat_scale);
1081  if (!success) {
1082  std::cout << "LAT_SCALE Property failed in vil_nitf2_image_subheader\n";
1083  return false;
1084  }
1085  rpc_data[87] = lat_scale;
1086 
1087  double lon_scale;
1088  success = (*tres_itr)->get_value("LON_SCALE", lon_scale);
1089  if (!success) {
1090  std::cout << "LON_SCALE Property failed in vil_nitf2_image_subheader\n";
1091  return false;
1092  }
1093  rpc_data[88] = lon_scale;
1094 
1095  int height_scale;
1096  success = (*tres_itr)->get_value("HEIGHT_SCALE", height_scale);
1097  if (!success) {
1098  std::cout << "HEIGHT_SCALE Property failed in vil_nitf2_image_subheader\n";
1099  return false;
1100  }
1101  rpc_data[89] = height_scale;
1102 
1103  // finally get the 80 polynomial coefficients ##################
1104  std::vector<double> LNC;
1105  success = (*tres_itr)->get_values("LNC", LNC);
1106  if (!success) {
1107  std::cout << "LNC Property failed in vil_nitf2_image_subheader\n";
1108  return false;
1109  }
1110  for (int i = 0; i < 20; i++) {
1111  rpc_data[i] = LNC[i]; // copy from vector to regular array.
1112  }
1113 
1114  std::vector<double> LDC;
1115  success = (*tres_itr)->get_values("LDC", LDC);
1116  if (!success) {
1117  std::cout << "LDC Property failed in vil_nitf2_image_subheader\n";
1118  return false;
1119  }
1120  for (int i = 0; i < 20; i++) {
1121  rpc_data[i+20] = LDC[i]; // copy from vector to regular array.
1122  }
1123 
1124  std::vector<double> SNC;
1125  success = (*tres_itr)->get_values("SNC", SNC);
1126  if (!success) {
1127  std::cout << "SNC Property failed in vil_nitf2_image_subheader\n";
1128  return false;
1129  }
1130  for (int i = 0; i < 20; i++) {
1131  rpc_data[i+40] = SNC[i]; // copy from vector to regular array.
1132  }
1133 
1134  std::vector<double> SDC;
1135  success = (*tres_itr)->get_values("SDC", SDC);
1136  if (!success) {
1137  std::cout << "SDC Property failed in vil_nitf2_image_subheader\n";
1138  return false;
1139  }
1140  for (int i = 0; i < 20; i++) {
1141  rpc_data[i+60] = SDC[i]; // copy from vector to regular array.
1142  }
1143  }
1144  }
1145 
1146  return true;
1147 }
Functor vil_nitf2_field_value_one_of defines a predicate that sets its out parameter to true iff the ...
Functor vil_nitf2_max_field_value_plus_offset_and_threshold defines a function that sets its out para...
Functor vil_nitf2_field_value defines a function that sets its out parameter to a value of a field fr...
bool get_correction_offset(double &u_off, double &v_off)
bool read(vil_nitf2_istream &input, const vil_nitf2_field_definitions *field_defs=nullptr, const vil_nitf2_index_vector &indexes=vil_nitf2_index_vector())
This class is responsible for parsing a NITF 2.1 data mask table.
#define NITF_INT
static const vil_nitf2_field_definitions * get_field_definitions_20()
std::vector< std::string > columns
#define NITF_STR_BCSA(LEN)
#define NITF_TRES
void end()
Declares that definition is finished, preventing further invocations of field() or repeat().
static void add_shared_field_defs_1(vil_nitf2_field_definitions *defs)
#define NITF_STR
#define NITF_BIN
vil_nitf2_tagged_record_definition & field(std::string field_name, 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="")
Define a field. Assumes ownership of pointer arguments.
static vil_nitf2_field_definitions * s_field_definitions_20
static void add_shared_field_defs_3(vil_nitf2_field_definitions *defs)
#define NITF_EXP
static void add_field_defs(vil_nitf2_field_definitions *defs, const file_version &version, std::string prefix, const std::string &pretty_name_prefix)
unsigned int get_number_of_bits_per_pixel() const
static vil_nitf2_tagged_record_definition & define(std::string name, std::string pretty_name)
Factory method. Assumes ownership of optional pointer argument.
#define NITF_DBL
bool get_rpc_params(std::string &rpc_type, std::string &image_id, std::string &image_corner_geo_locations, double *rpc_data)
Get RPC parameters, if present. User provides rpc_data array.
Stream interface for VIL image loaders.
Definition: vil_stream.h:21
vil_nitf2_field_sequence m_field_sequence
static vil_nitf2_field_definitions * s_field_definitions_21
vil_nitf2: Written by Harry Voorhees (hlv@) and Rob Radtke (rob@) of Stellar Science Ltd.
vil_nitf2_tagged_record_definition defines a particular tagged record extension (TRE).
static void add_geo_field_defs(vil_nitf2_field_definitions *defs, const vil_nitf2_classification::file_version &version)
static tagged_record_definition_map & all_definitions()
All tagged record definitions.
bool get_sun_params(double &sun_el, double &sun_az)
Return the elevation and azimuth angles of the sun.
bool get_lut_info(unsigned int band, int &n_luts, int &ne_lut, std::vector< std::vector< unsigned char > > &lut_d) const
Returns true if the ith image band in this image subheader has LUT info and false otherwise.
virtual vil_nitf2_field::field_tree * get_tree(int i=0) const
#define NITF_LONG
static bool undefine(const std::string &name)
Undefines a TRE. Returns whether TRE with specified name was found.
unsigned int get_pixels_per_block_x() const
vil_nitf2_data_mask_table * m_data_mask_table
bool get_property(std::string tag, T &out_value) const
Sets out_value to the value of field specified by tag.
bool get_date_time(int &year, int &month, int &day, int &hour, int &min, int &sec)
Extract the date and time.
Functor vil_nitf2_choose_field_value defines a function that sets its out parameter to a value of one...
static vil_nitf2_tagged_record_definition * find(const std::string &name)
Look up a record definition.
vnl_decnum min(vnl_decnum const &x, vnl_decnum const &y)
bool get_value(std::string tag, int &out_value) const
Functors used by NITF classes.
static void add_shared_field_defs_2(vil_nitf2_field_definitions *defs)
vil_nitf2_tagged_record_definition & repeat(vil_nitf2_field_functor< int > *repeat_functor, vil_nitf2_field_definitions &field_definitions)
Define a repeat node. Assumes ownership of pointer argument.
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...
virtual bool read(vil_stream *stream)
Read the image header starting at stream's current position.
static const vil_nitf2_field_definitions * get_field_definitions_21()
vil_nitf2_image_subheader(vil_nitf2_classification::file_version version)
#define NITF_STR_ECSA(LEN)
unsigned int get_pixels_per_block_y() const
#define NITF_ENUM
Functor vil_nitf2_field_specified defines a comparison predicate that sets its out parameter to true ...