00001
00002
00003
00004 #include "vil_nitf2_image_subheader.h"
00005
00006
00007 #include "vil_nitf2_data_mask_table.h"
00008 #include "vil_nitf2_field_functor.h"
00009 #include "vil_nitf2_field_definition.h"
00010 #include "vil_nitf2_typed_field_formatter.h"
00011 #include "vil_nitf2_index_vector.h"
00012
00013 #include "vil_nitf2_tagged_record_definition.h"
00014
00015 #include <vcl_sstream.h>
00016 #include <vcl_cassert.h>
00017 #include <vcl_cstdlib.h>
00018
00019 vil_nitf2_field_definitions* vil_nitf2_image_subheader::s_field_definitions_21 = 0;
00020 vil_nitf2_field_definitions* vil_nitf2_image_subheader::s_field_definitions_20 = 0;
00021
00022 vil_nitf2_image_subheader::vil_nitf2_image_subheader(vil_nitf2_classification::file_version version)
00023 : m_field_sequence(version == vil_nitf2_classification::V_NITF_20 ?
00024 *get_field_definitions_20() :
00025 *get_field_definitions_21()),
00026 m_data_mask_table(0),
00027 m_version(version)
00028 {
00029 add_rpc_definitions();
00030 add_USE_definitions();
00031 add_ICHIPB_definitions();
00032 add_MPD26A_definitions();
00033 add_STDIDB_definitions();
00034 add_STDIDC_definitions();
00035 }
00036
00037 vil_nitf2_image_subheader::~vil_nitf2_image_subheader()
00038 {
00039 if (m_data_mask_table) delete m_data_mask_table;
00040 if (vil_nitf2_tagged_record_definition::all_definitions().size()) {
00041 vil_nitf2_tagged_record_definition::undefine("RPC00A");
00042 vil_nitf2_tagged_record_definition::undefine("RPC00B");
00043 }
00044 }
00045
00046 bool vil_nitf2_image_subheader::read(vil_stream* stream)
00047 {
00048 bool success = m_field_sequence.read(*stream);
00049
00050 if (success)
00051 {
00052
00053 vcl_string compression_code;
00054 get_property("IC", compression_code);
00055 if (compression_code.find_first_of("M") != vcl_string::npos) {
00056 vcl_string imode;
00057 get_property("IMODE", imode);
00058 m_data_mask_table = new vil_nitf2_data_mask_table(
00059 get_num_blocks_x(), get_num_blocks_y(), nplanes(), imode);
00060 if (!m_data_mask_table->parse(stream)) return false;
00061 }
00062 }
00063 return success;
00064 }
00065
00066 const vil_nitf2_field_definitions* vil_nitf2_image_subheader::get_field_definitions_21()
00067 {
00068 if (!s_field_definitions_21) {
00069 s_field_definitions_21 = new vil_nitf2_field_definitions();
00070 add_shared_field_defs_1(s_field_definitions_21);
00071 vil_nitf2_classification::add_field_defs(s_field_definitions_21, vil_nitf2_classification::V_NITF_21, "I", "Image");
00072 add_shared_field_defs_2(s_field_definitions_21);
00073 add_geo_field_defs(s_field_definitions_21, vil_nitf2_classification::V_NITF_21);
00074 add_shared_field_defs_3(s_field_definitions_21);
00075 }
00076 return s_field_definitions_21;
00077 }
00078
00079 const vil_nitf2_field_definitions* vil_nitf2_image_subheader::get_field_definitions_20()
00080 {
00081 if (!s_field_definitions_20) {
00082 s_field_definitions_20 = new vil_nitf2_field_definitions();
00083 add_shared_field_defs_1(s_field_definitions_20);
00084 vil_nitf2_classification::add_field_defs(s_field_definitions_20, vil_nitf2_classification::V_NITF_20, "I", "Image");
00085 add_shared_field_defs_2(s_field_definitions_20);
00086 add_geo_field_defs(s_field_definitions_20, vil_nitf2_classification::V_NITF_20);
00087 add_shared_field_defs_3(s_field_definitions_20);
00088 }
00089 return s_field_definitions_20;
00090 }
00091
00092 void vil_nitf2_image_subheader::
00093 add_shared_field_defs_3(vil_nitf2_field_definitions* defs)
00094 {
00095 (*defs)
00096 .field("NICOM", "Number of Image Comments", NITF_INT(1), false, 0, 0)
00097
00098
00099 .repeat("NICOM", vil_nitf2_field_definitions()
00100
00101 .field("ICOMn", "Image Comment n", NITF_STR_ECSA(80), false, 0, 0))
00102
00103 .field("IC", "Image Compression",
00104 NITF_ENUM(2, vil_nitf2_enum_values()
00105 .value("NC", "Not compressed")
00106 .value("NM", "Uncompressed - contains block mask and/or pad pixel mask")
00107 .value("C1", "Bi-level")
00108 .value("C3", "JPEG")
00109 .value("C4", "Vector Quantization")
00110 .value("C5", "Lossless JPEG")
00111 .value("C6", "Reserved - future correlated multicomponent compression")
00112 .value("C7", "Reserved - future SAR compression")
00113 .value("C8", "JPEG2000")
00114 .value("I1", "Downsampled JPEG")
00115 .value("M1", "Compressed - contains block mask and/or pad pixel mask")
00116 .value("M3", "Compressed - contains block mask and/or pad pixel mask")
00117 .value("M4", "Compressed - contains block mask and/or pad pixel mask")
00118 .value("M5", "Compressed - contains block mask and/or pad pixel mask")
00119 .value("M6", "Reserved - future correlated multicomponent compression")
00120 .value("M7", "Reserved - future SAR compression")
00121 .value("M8", "JPEG2000 - contains block mask and/or pad pixel mask")),
00122 false, 0, 0);
00123
00124 vcl_vector<vcl_string> comp_ic_values;
00125 comp_ic_values.push_back("C1");
00126 comp_ic_values.push_back("C3");
00127 comp_ic_values.push_back("C4");
00128 comp_ic_values.push_back("C5");
00129 comp_ic_values.push_back("C8");
00130 comp_ic_values.push_back("M1");
00131 comp_ic_values.push_back("M3");
00132 comp_ic_values.push_back("M4");
00133 comp_ic_values.push_back("M5");
00134 comp_ic_values.push_back("M8");
00135 comp_ic_values.push_back("I1");
00136
00137
00138 (*defs)
00139 .field("COMRAT", "Compression Rate Code", NITF_STR_BCSA(4),true, 0,
00140 new vil_nitf2_field_value_one_of<vcl_string>("IC", comp_ic_values))
00141
00142
00143
00144 .field("NBANDS", "Number of Bands", NITF_INT(1), false, 0, 0)
00145
00146
00147 .field("XBANDS", "Number of multispectral bands", NITF_INT(5), true, 0,
00148 new vil_nitf2_field_value_one_of<int>("NBANDS",0))
00149
00150 .repeat(new vil_nitf2_choose_field_value<int>(
00151 "NBANDS", "XBANDS", new vil_nitf2_field_value_greater_than<int>("NBANDS", 0)),
00152 vil_nitf2_field_definitions()
00153
00154 .field("IREPBAND", "nth Band Representation", NITF_STR_BCSA(2), true, 0, 0)
00155 .field("ISUBCAT", "nth Band Subcategory", NITF_STR_BCSA(6), true, 0, 0)
00156 .field("IFC", "nth Image Filter Condition", NITF_STR_BCSA(1), false, 0, 0)
00157 .field("IMFLT", "nth Band Standard Image Filter Code", NITF_STR_BCSA(3), true, 0, 0)
00158 .field("NLUTS", "Number of LUTS for the nth Image Band", NITF_INT(1, false), false, 0, 0)
00159 .field("NELUT", "Number of LUT Entries for the nth Image Band", NITF_INT(5, false), false, 0,
00160 new vil_nitf2_field_value_greater_than<int>("NLUTS", 0) )
00161
00162 .repeat(new vil_nitf2_field_value<int>("NLUTS"), vil_nitf2_field_definitions()
00163
00164 .field("LUTDnm", "nth Image Band, mth LUT", NITF_BIN(1), false,
00165 new vil_nitf2_field_value<int>("NELUT"), 0))
00166 )
00167
00168 .field("ISYNC", "Image Sync Code", NITF_INT(1), false, 0, 0)
00169 .field("IMODE", "Image Mode",
00170 NITF_ENUM(1, vil_nitf2_enum_values()
00171 .value("B", "Band interleaved by block")
00172 .value("P", "Band interleaved by pixel")
00173 .value("R", "Band interleaved by row")
00174 .value("S", "Band sequential")),
00175 false, 0, 0)
00176
00177 .field("NBPR", "Number of Blocks per Row", NITF_INT(4), false, 0, 0)
00178 .field("NBPC", "Number of Blocks per Column", NITF_INT(4), false, 0, 0)
00179 .field("NPPBH", "Number of Pixels per Block Horizontal", NITF_INT(4), false, 0, 0)
00180 .field("NPPBV", "Number of Pixels per Block Vertical", NITF_INT(4), false, 0, 0)
00181 .field("NBPP", "Number of Bits per Pixel per Band", NITF_INT(2), false, 0, 0)
00182 .field("IDLVL", "Image Display Level", NITF_INT(3), false, 0, 0)
00183 .field("IALVL", "Attachment Level", NITF_INT(3), false, 0, 0)
00184
00185
00186
00187
00188 .field("ILOC_ROW", "Image Location Row", NITF_STR_BCSA(5), false, 0, 0)
00189 .field("ILOC_COL", "Image Location Column", NITF_STR_BCSA(5), false, 0, 0)
00190
00191
00192
00193 .field("IMAG", "Image Magnification", NITF_STR_BCSA(4), false, 0, 0)
00194 .field("UDIDL", "User Defined Image Data Length", NITF_INT(5), false, 0, 0)
00195
00196 .field("UDOFL", "User Defined Overflow", NITF_INT(3), false, 0,
00197 new vil_nitf2_field_value_greater_than<int>("UDIDL", 0))
00198
00199 .field("UDID", "User Defined Image Data", NITF_TRES(), false,
00200 new vil_nitf2_max_field_value_plus_offset_and_threshold("UDIDL", -3), 0)
00201
00202 .field("IXSHDL", "Image Extended Subheader Data Length", NITF_INT(5), false, 0, 0)
00203
00204 .field("IXSOFL", "Image Extended Subheader Overflow", NITF_INT(3), false, 0,
00205 new vil_nitf2_field_value_greater_than<int>("IXSHDL", 0))
00206
00207 .field("IXSHD", "Image Extended Subheader Data", NITF_TRES(), false,
00208 new vil_nitf2_max_field_value_plus_offset_and_threshold("IXSHDL", -3), 0);
00209 }
00210
00211 void vil_nitf2_image_subheader::add_geo_field_defs(vil_nitf2_field_definitions* defs,
00212 const vil_nitf2_classification::file_version& version)
00213 {
00214 switch (version)
00215 {
00216 case vil_nitf2_classification::V_NITF_20:
00217 {
00218 (*defs)
00219 .field("ICORDS", "Image Coordinate Representation",
00220 NITF_ENUM(1, vil_nitf2_enum_values()
00221 .value("U", "UTM")
00222 .value("G", "Geodetic/Geographic")
00223 .value("N", "None")
00224 .value("C", "Geocentric")),
00225 false, 0, 0);
00226
00227 vcl_vector<vcl_string> igeolo_icords;
00228 igeolo_icords.push_back("U");
00229 igeolo_icords.push_back("G");
00230 igeolo_icords.push_back("C");
00231
00232 (*defs)
00233 .field("IGEOLO", "Image Geographic Location", NITF_STR_BCSA(60), false, 0,
00234 new vil_nitf2_field_value_one_of<vcl_string>("ICORDS", igeolo_icords));
00235 break;
00236 }
00237 case vil_nitf2_classification::V_NITF_21:
00238 {
00239 (*defs)
00240 .field("ICORDS", "Image Coordinate Representation",
00241 NITF_ENUM(1, vil_nitf2_enum_values()
00242 .value("U", "UTM expressed in MGRS form")
00243 .value("G", "Geographic")
00244 .value("N", "UTM/UPS (Northern hemisphere)")
00245 .value("S", "UTM/UPS (Southern hemisphere)")
00246 .value("D", "Decimal degrees")),
00247 true, 0, 0)
00248
00249 .field("IGEOLO", "Image Geographic Location", NITF_STR_BCSA(60), false, 0,
00250 new vil_nitf2_field_specified("ICORDS"));
00251 break;
00252 }
00253 default:
00254 assert(!"unsupported case");
00255 }
00256 }
00257
00258 void vil_nitf2_image_subheader::add_shared_field_defs_2(vil_nitf2_field_definitions* defs)
00259 {
00260 (*defs)
00261 .field("ENCRYP", "Encryption",
00262 NITF_ENUM(1, vil_nitf2_enum_values()
00263
00264 .value("0", "Not Encrypted")),
00265 false, 0, 0)
00266 .field("ISORCE", "Image Source", NITF_STR_ECSA(42), true, 0, 0)
00267
00268 .field("NROWS", "Number of Significant Rows in Image", NITF_INT(8, false), false, 0, 0)
00269
00270 .field("NCOLS", "Number of Significant Columns in Image", NITF_INT(8, false), false, 0, 0)
00271 .field("PVTYPE", "Pixel Value Type",
00272 NITF_ENUM(3, vil_nitf2_enum_values()
00273 .value("INT", "Integer")
00274 .value("B", "Bi-level")
00275 .value("SI", "2's complement signed integer")
00276 .value("R", "Real")
00277 .value("C", "Complex")),
00278 false, 0, 0)
00279 .field("IREP", "Image Representation",
00280 NITF_ENUM(8, vil_nitf2_enum_values()
00281 .value("MONO", "Monochrome")
00282 .value("RGB", "Red, green, blue true color")
00283 .value("RGB/LUT", "Red, green, blue mapped Color")
00284 .value("MULTI", "Multiband imagery")
00285 .value("NODISPLY", "Not intended for display")
00286 .value("NVECTOR", "Cartesian coordinates")
00287 .value("POLAR", "Polar coordinates")
00288 .value("VPH", "SAR video phase history")
00289 .value("YCbCr601", "BT.601-5 color space")),
00290 false, 0, 0)
00291 #ifdef UNCLASS_ONLY
00292 .field("ICAT", "Image Category",
00293 NITF_ENUM(8, vil_nitf2_enum_values()
00294 .value("VIS", "Visible imagery")
00295 .value("SL", "Side-looking radar")
00296 .value("TI", "Thermal infrared")
00297 .value("FL", "Forward-looking radar")
00298 .value("RD", "Radar")
00299 .value("EO", "Electro-optical")
00300 .value("OP", "Optical")
00301 .value("HR", "High-resolution radar")
00302 .value("HS", "Hyperspectral")
00303 .value("CP", "Color frame photography")
00304 .value("BP", "Black/white frame photography")
00305 .value("SARIQ", "SAR radio hologram")
00306 .value("SAR", "Synthetic aperture radar")
00307 .value("IR", "Infrared")
00308 .value("MS", "Multispectral")
00309 .value("FP", "Fingerprints")
00310 .value("MRI", "Magnetic resonance imagery")
00311 .value("XRAY", "X-ray")
00312 .value("CAT", "CAT scan")
00313 .value("VD", "Video")
00314 .value("BARO", "Barometric pressure")
00315 .value("CURRENT","Water current")
00316 .value("DEPTH", "Water depth")
00317 .value("MAP", "Raster map")
00318 .value("PAT", "Color patch")
00319 .value("LEG", "Legends")
00320 .value("DTEM", "Elevation models")
00321 .value("MATR", "Matrix data (other types)")
00322 .value("LOCG", "Location Grids")),
00323 false, 0, 0)
00324 #else
00325 .field("ICAT", "Image Category", NITF_STR_ECSA(8), false, 0, 0)
00326 #endif //UNCLASS_ONLY
00327
00328 .field("ABPP", "Actual Bits Per Pixel per Band", NITF_INT(2), false, 0, 0)
00329 .field("PJUST", "Pixel Justification",
00330 NITF_ENUM(1, vil_nitf2_enum_values()
00331 .value("L", "Left-justified")
00332 .value("R", "Right-justified")),
00333 false, 0, 0);
00334 }
00335
00336 void vil_nitf2_image_subheader::add_shared_field_defs_1(vil_nitf2_field_definitions* defs)
00337 {
00338 (*defs)
00339 .field("IM", "File Part Type",
00340 NITF_ENUM(2, vil_nitf2_enum_values()
00341 .value("IM", "Image Header")))
00342 .field("IID1", "Image Identifier 1", NITF_STR_BCSA(10))
00343
00344
00345
00346 .field("IDATIM", "Image Date and Time", NITF_STR_BCSA(14))
00347 .field("TGTID", "Target Identifier", NITF_STR_BCSA(17), true)
00348 .field("IID2", "Image Identifier 2", NITF_STR_ECSA(80), true);
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 bool vil_nitf2_image_subheader::
00391 get_date_time(int& year, int& month, int& day, int& hour, int& min)
00392 {
00393 vcl_string date_time = "";
00394 bool success = this->get_property("IDATIM", date_time);
00395 if (!success) {
00396 vcl_cout << "IDATIM Property failed in vil_nitf2_image_subheader\n";
00397 return false;
00398 }
00399
00400
00401 vcl_string s_day, s_hour, s_min, s_month, s_year;
00402
00403 vcl_string s_zulu = date_time.substr(8,1);
00404 if (s_zulu=="Z") {
00405 s_day = date_time.substr(0,2);
00406 s_hour = date_time.substr(2,2);
00407 s_min = date_time.substr(4,2);
00408 s_month = date_time.substr(9,3);
00409 s_year = date_time.substr(12,2);
00410 vcl_string months[]={"JAN", "FEB", "MAR", "APR",
00411 "MAY", "JUN", "JUL", "AUG",
00412 "SEP", "OCT", "NOV", "DEC"};
00413 bool found = false;
00414 for(int i = 0; (i<12)&&(!found); ++i) {
00415 if(s_month==months[i]){
00416 found = true;
00417 month = i+1;
00418 }
00419 }
00420 if(!found) {
00421 return false;
00422 }
00423 } else {
00424 s_year = date_time.substr(0,4);
00425 s_month = date_time.substr(4,2);
00426 s_day = date_time.substr(6,2);
00427 s_hour = date_time.substr(8,2);
00428 s_min = date_time.substr(10,2);
00429 month = vcl_atoi(s_month.c_str());
00430 }
00431 day = vcl_atoi(s_day.c_str());
00432 hour = vcl_atoi(s_hour.c_str());
00433 min = vcl_atoi(s_min.c_str());
00434 year = vcl_atoi(s_year.c_str());
00435 if (year < 100)
00436 year += 2000;
00437 return true;
00438 }
00439 unsigned vil_nitf2_image_subheader::nplanes() const
00440 {
00441
00442
00443
00444 int numBands;
00445 if (get_property("NBANDS", numBands))
00446 {
00447 if (numBands > 0 ||
00448 get_property("XBANDS", numBands))
00449 {
00450 return numBands;
00451 }
00452 }
00453 return 0;
00454 }
00455
00456 unsigned int vil_nitf2_image_subheader::get_pixels_per_block_x() const
00457 {
00458 int pixels_per_block;
00459 if (get_property("NPPBH", pixels_per_block)) {
00460 return pixels_per_block;
00461 }
00462 return 0;
00463 }
00464
00465 unsigned int vil_nitf2_image_subheader::get_pixels_per_block_y() const
00466 {
00467 int pixels_per_block;
00468 if (get_property("NPPBV", pixels_per_block)) {
00469 return pixels_per_block;
00470 }
00471 return 0;
00472 }
00473
00474 unsigned int vil_nitf2_image_subheader::get_num_blocks_x() const
00475 {
00476 int blocks_per_row;
00477 if (get_property("NBPR", blocks_per_row)) {
00478 return blocks_per_row;
00479 }
00480 return 0;
00481 }
00482
00483 unsigned int vil_nitf2_image_subheader::get_num_blocks_y() const
00484 {
00485 int blocks_per_col;
00486 if (get_property("NBPC", blocks_per_col)) {
00487 return blocks_per_col;
00488 }
00489 return 0;
00490 }
00491 unsigned int vil_nitf2_image_subheader::get_number_of_bits_per_pixel() const
00492 {
00493 int bits_per_pixel;
00494 if (get_property("ABPP", bits_per_pixel)) {
00495 return bits_per_pixel;
00496 }
00497 return 0;
00498 }
00499 vcl_string vil_nitf2_image_subheader::get_image_source() const
00500 {
00501 vcl_string source;
00502 if (get_property("ISORCE", source)) {
00503 return source;
00504 }
00505 return "";
00506 }
00507 vcl_string vil_nitf2_image_subheader::get_image_type() const
00508 {
00509 vcl_string id;
00510 if (get_property("IREP", id)) {
00511 return id;
00512 }
00513 return "";
00514 }
00515
00516 bool vil_nitf2_image_subheader::get_lut_info(unsigned int band,
00517 int& n_luts, int& ne_lut,
00518 vcl_vector< vcl_vector< unsigned char > >& lut_d) const
00519 {
00520 if (!m_field_sequence.get_value("NLUTS", vil_nitf2_index_vector(band), n_luts) ||
00521 !m_field_sequence.get_value("NELUT", vil_nitf2_index_vector(band), ne_lut)) {
00522 return false;
00523 }
00524 lut_d.clear();
00525 lut_d.resize(n_luts);
00526 void* raw_lut_data;
00527 for (int lut_index = 0 ; lut_index < n_luts ; lut_index++) {
00528 lut_d[lut_index].resize(ne_lut);
00529
00530 vil_nitf2_index_vector index( band, lut_index );
00531 if (m_field_sequence.get_value("LUTDnm", index, raw_lut_data )) {
00532 for ( int el_index = 0 ; el_index < ne_lut ; el_index++ ) {
00533 lut_d[lut_index][el_index] = static_cast<unsigned char*>(raw_lut_data)[el_index];
00534 }
00535 }
00536 else {
00537 break;
00538 }
00539 }
00540 return true;
00541 }
00542
00543 vil_nitf2_field::field_tree* vil_nitf2_image_subheader::get_tree( int i ) const
00544 {
00545 vil_nitf2_field::field_tree* t = new vil_nitf2_field::field_tree;
00546 vcl_stringstream name_stream;
00547 name_stream << "Image Subheader";
00548 if ( i > 0 ) name_stream << " #" << i;
00549 t->columns.push_back( name_stream.str() );
00550 m_field_sequence.get_tree( t );
00551 return t;
00552 }
00553
00554
00555 void vil_nitf2_image_subheader::add_rpc_definitions()
00556 {
00557 vil_nitf2_tagged_record_definition* tr =
00558 vil_nitf2_tagged_record_definition::find("RPC00B");
00559 if (!tr)
00560 {
00561 vil_nitf2_tagged_record_definition::define("RPC00B", "Rational Polynomial Coefficients Type B" )
00562
00563
00564 .field("SUCCESS", "Success parameter", NITF_INT(1))
00565 .field("ERR_BIAS", "ERR_BIAS", NITF_DBL(7, 2, false), true)
00566 .field("ERR_RAND", "ERR_RAND", NITF_DBL(7, 2, false), true)
00567 .field("LINE_OFF", "Line Offset", NITF_INT(6))
00568 .field("SAMP_OFF", "Sample Offset", NITF_INT(5))
00569 .field("LAT_OFF", "Latitude Offset", NITF_DBL(8, 4, true), false)
00570 .field("LON_OFF", "Longitude offset", NITF_DBL(9, 4, true), false)
00571 .field("HEIGHT_OFF", "Height Offset", NITF_INT(5, true))
00572 .field("LINE_SCALE", "Line Scale", NITF_INT(6))
00573 .field("SAMP_SCALE", "Sample Scale", NITF_INT(5))
00574 .field("LAT_SCALE", "Latitude Scale", NITF_DBL(8, 4, true), false)
00575 .field("LON_SCALE", "Longitude Scale", NITF_DBL(9, 4, true), false)
00576 .field("HEIGHT_SCALE", "Height Scale", NITF_INT(5, true))
00577
00578
00579
00580
00581
00582
00583 .repeat(20, vil_nitf2_field_definitions()
00584 .field("LNC", "Line Number Coefficient", NITF_EXP(6,1))
00585 )
00586 .repeat(20, vil_nitf2_field_definitions()
00587 .field("LDC", "Line Density Coefficient", NITF_EXP(6,1))
00588 )
00589 .repeat(20, vil_nitf2_field_definitions()
00590 .field("SNC", "Sample Number Coefficient", NITF_EXP(6,1))
00591 )
00592 .repeat(20, vil_nitf2_field_definitions()
00593 .field("SDC", "Sample Density Coefficient", NITF_EXP(6,1))
00594 )
00595 .end();
00596 }
00597 tr =vil_nitf2_tagged_record_definition::find("RPC00A");
00598 if (!tr)
00599 {
00600 vil_nitf2_tagged_record_definition::define("RPC00A", "Rational Polynomial Coefficients Type A" )
00601
00602
00603 .field("SUCCESS", "Success parameter", NITF_INT(1))
00604 .field("ERR_BIAS", "ERR_BIAS", NITF_DBL(7, 2, false), true)
00605 .field("ERR_RAND", "ERR_RAND", NITF_DBL(7, 2, false), true)
00606 .field("LINE_OFF", "Line Offset", NITF_INT(6))
00607 .field("SAMP_OFF", "Sample Offset", NITF_INT(5))
00608 .field("LAT_OFF", "Latitude Offset", NITF_DBL(8, 4, true), false)
00609 .field("LON_OFF", "Longitude offset", NITF_DBL(9, 4, true), false)
00610 .field("HEIGHT_OFF", "Height Offset", NITF_INT(5, true))
00611 .field("LINE_SCALE", "Line Scale", NITF_INT(6))
00612 .field("SAMP_SCALE", "Sample Scale", NITF_INT(5))
00613 .field("LAT_SCALE", "Latitude Scale", NITF_DBL(8, 4, true), false)
00614 .field("LON_SCALE", "Longitude Scale", NITF_DBL(9, 4, true), false)
00615 .field("HEIGHT_SCALE", "Height Scale", NITF_INT(5, true))
00616
00617
00618
00619
00620
00621
00622 .repeat(20, vil_nitf2_field_definitions()
00623 .field("LNC", "Line Number Coefficient", NITF_EXP(6,1))
00624 )
00625 .repeat(20, vil_nitf2_field_definitions()
00626 .field("LDC", "Line Density Coefficient", NITF_EXP(6,1))
00627 )
00628 .repeat(20, vil_nitf2_field_definitions()
00629 .field("SNC", "Sample Number Coefficient", NITF_EXP(6,1))
00630 )
00631 .repeat(20, vil_nitf2_field_definitions()
00632 .field("SDC", "Sample Density Coefficient", NITF_EXP(6,1))
00633 )
00634 .end();
00635 }
00636 }
00637
00638 void vil_nitf2_image_subheader::add_USE_definitions()
00639 {
00640 vil_nitf2_tagged_record_definition* tr =vil_nitf2_tagged_record_definition::find("USE00A");
00641 if (!tr)
00642 {
00643 vil_nitf2_tagged_record_definition::define("USE00A", "EXPLOITATION USABILITY EXTENSION FORMAT" )
00644
00645 .field("ANGLE_TO_NORTH","Angle to North", NITF_INT(3))
00646 .field("MEAN_GSD", "Mean Ground Sample Distance",NITF_DBL(5, 1, false), false)
00647 .field("Reserved1", "",NITF_STR(1), false)
00648 .field("DYNAMIC_RANGE", "Dynamic Range",NITF_LONG(5, false), true)
00649 .field("Reserved2", "",NITF_STR(7), false)
00650 .field("OBL_ANG", "Obliquity Angle", NITF_DBL(5,2,false), true)
00651 .field("ROLL_ANG", "Roll Angle", NITF_DBL(6,2,true), true)
00652 .field("Reserved3", "",NITF_STR(37), false)
00653 .field("N_REF", "Number of Reference Lines.", NITF_INT(2, false), false)
00654 .field("REV_NUM", "Revolution Number", NITF_LONG(5, false), false)
00655 .field("N_SEG", "Number of Segments", NITF_INT(3, false), false)
00656 .field("MAX_LP_SEG", "Maximum Lines Per Segment", NITF_LONG(6,false), true)
00657 .field("Reserved4", "",NITF_STR(12), false)
00658 .field("SUN_EL", "Sun Elevation", NITF_DBL(5,1,true),false)
00659 .field("SUN_AZ", "Sun Azimuth", NITF_DBL(5,1,false),false)
00660
00661
00662 .end();
00663 }
00664 }
00665
00666
00667 bool vil_nitf2_image_subheader::
00668 get_sun_params( double& sun_el, double& sun_az)
00669 {
00670
00671 vil_nitf2_tagged_record_sequence isxhd_tres;
00672 vil_nitf2_tagged_record_sequence::iterator tres_itr;
00673 this->get_property("IXSHD", isxhd_tres);
00674
00675
00676 bool success=false;
00677
00678 for (tres_itr = isxhd_tres.begin(); tres_itr != isxhd_tres.end(); ++tres_itr)
00679 {
00680 vcl_string type = (*tres_itr)->name();
00681 if ( type == "USE00A")
00682 {
00683 success = (*tres_itr)->get_value("SUN_EL", sun_el);
00684 success = success && (*tres_itr)->get_value("SUN_AZ", sun_az);
00685 if (!success)
00686 vcl_cout<<"\n Error reading USE00A\n";
00687 else
00688 return success;
00689 }
00690 else if ( type == "MPD26A")
00691 {
00692 success = (*tres_itr)->get_value("SUN_EL", sun_el);
00693 success = success && (*tres_itr)->get_value("SUN_AZ", sun_az);
00694 if (!success)
00695 vcl_cout<<"\n Error reading MPD26A\n";
00696 else
00697 return success;
00698 }
00699 }
00700 return success;
00701 }
00702
00703 void vil_nitf2_image_subheader::add_ICHIPB_definitions()
00704 {
00705 vil_nitf2_tagged_record_definition* tr =vil_nitf2_tagged_record_definition::find("ICHIPB");
00706 if (!tr)
00707 {
00708 vil_nitf2_tagged_record_definition::define("ICHIPB", "ICHIPB SUPPORT DATA EXTENSION" )
00709
00710 .field("XFRM_FLAG", "Non-linear Transformation Flag", NITF_INT(2),false)
00711 .field("SCALE_FACTOR", "Scale Factor Relative to R0",NITF_DBL(10, 5, false), false)
00712 .field("ANAMRPH_CORR", "Anamorphic Correction Indicator", NITF_INT(2),false)
00713 .field("SCANBLK_NUM", "Scan Block Number",NITF_INT(2, false), true)
00714
00715 .field("OP_ROW_11", "Output product row number component of grid point index (1,1)",NITF_DBL(12,3,false), false)
00716 .field("OP_COL_11", "Output product column number component of grid point index (1,1)",NITF_DBL(12,3,false), false)
00717
00718 .field("OP_ROW_12", "Output product row number component of grid point index (1,2)",NITF_DBL(12,3,false), false)
00719 .field("OP_COL_12", "Output product column number component of grid point index (1,2)",NITF_DBL(12,3,false), false)
00720
00721 .field("OP_ROW_21", "Output product row number component of grid point index (2,1)",NITF_DBL(12,3,false), false)
00722 .field("OP_COL_21", "Output product column number component of grid point index (2,1)",NITF_DBL(12,3,false), false)
00723
00724 .field("OP_ROW_22", "Output product row number component of grid point index (2,2)",NITF_DBL(12,3,false), false)
00725 .field("OP_COL_22", "Output product column number component of grid point index (2,2)",NITF_DBL(12,3,false), false)
00726
00727
00728 .field("FI_ROW_11", "Output product row number component of grid point index (1,1)",NITF_DBL(12,3,false), false)
00729 .field("FI_COL_11", "Output product column number component of grid point index (1,1)",NITF_DBL(12,3,false), false)
00730
00731 .field("FI_ROW_12", "Output product row number component of grid point index (1,2)",NITF_DBL(12,3,false), false)
00732 .field("FI_COL_12", "Output product column number component of grid point index (1,2)",NITF_DBL(12,3,false), false)
00733
00734 .field("FI_ROW_21", "Output product row number component of grid point index (2,1)",NITF_DBL(12,3,false), false)
00735 .field("FI_COL_21", "Output product column number component of grid point index (2,1)",NITF_DBL(12,3,false), false)
00736
00737 .field("FI_ROW_22", "Output product row number component of grid point index (2,2)",NITF_DBL(12,3,false), false)
00738 .field("FI_COL_22", "Output product column number component of grid point index (2,2)",NITF_DBL(12,3,false), false)
00739
00740 .field("FI_ROW", "Full Image Number of Rows", NITF_LONG(8,false), false)
00741 .field("FI_COL", "Full Image Number of COlumns", NITF_LONG(8,false), false)
00742
00743 .end();
00744 }
00745 }
00746
00747
00748 void vil_nitf2_image_subheader::add_STDIDC_definitions()
00749 {
00750 vil_nitf2_tagged_record_definition* tr =vil_nitf2_tagged_record_definition::find("STDIDC");
00751 if (!tr)
00752 {
00753 vil_nitf2_tagged_record_definition::define("STDIDC", "STDIDC SUPPORT DATA EXTENSION" )
00754
00755 .field("ACQUISITION_DATE", "", NITF_STR(14),false)
00756 .field("MISSION", "",NITF_STR(14), false)
00757 .field("PASS", "", NITF_STR(2),false)
00758 .field("OP_NUM", "",NITF_INT(3, false), false)
00759 .field("START_SEGMENT", "",NITF_STR(2), false)
00760 .field("REPRO_NUM", "",NITF_INT(2,false), false)
00761 .field("REPLAY_REGEN", "",NITF_STR(3), false)
00762 .field("BLANK_FILL", "",NITF_STR(1), true)
00763 .field("START_COLUMN", "",NITF_INT(3,false), false)
00764 .field("START_ROW", "",NITF_INT(5,false), false)
00765 .field("END_SEGMENT", "",NITF_STR(2), false)
00766 .field("END_COLUMN", "",NITF_INT(3,false), false)
00767 .field("END_ROW", "",NITF_INT(5,false), false)
00768 .field("COUNTRY", "",NITF_STR(2), true)
00769 .field("WAC", "",NITF_INT(4,false), true)
00770 .field("LOCATION", "",NITF_STR(11), false)
00771 .field("RESERVED1", "",NITF_STR(5), true)
00772 .field("RESERVED2", "",NITF_STR(8), true)
00773
00774 .end();
00775 }
00776 }
00777
00778
00779 void vil_nitf2_image_subheader::add_STDIDB_definitions()
00780 {
00781 vil_nitf2_tagged_record_definition* tr =vil_nitf2_tagged_record_definition::find("STDIDB");
00782 if (!tr)
00783 {
00784 vil_nitf2_tagged_record_definition::define("STDIDB", "STDIDB SUPPORT DATA EXTENSION" )
00785
00786 .field("unk1", "", NITF_INT(2,false),false)
00787 .field("unk2", "", NITF_STR(3),false)
00788 .field("unk3", "", NITF_INT(2,false),false)
00789 .field("unk4", "", NITF_INT(4,false),false)
00790 .field("unk5", "", NITF_STR(2),false)
00791 .field("unk6", "", NITF_INT(3,false),false)
00792 .field("unk7", "", NITF_STR(2),false)
00793 .field("unk8", "", NITF_INT(2,false),false)
00794 .field("unk9", "", NITF_STR(3),false)
00795 .field("unk10", "", NITF_STR(1),false)
00796 .field("START_COLUMN", "", NITF_STR(2),false)
00797 .field("START_ROW", "", NITF_INT(5,false),false)
00798 .field("unk11", "", NITF_STR(2),false)
00799 .field("unk12", "", NITF_STR(2),false)
00800 .field("unk13", "", NITF_INT(5,false),false)
00801 .field("unk14", "", NITF_STR(2),false)
00802 .field("unk15", "", NITF_INT(4,false),false)
00803 .field("unk16", "", NITF_STR(4),false)
00804 .field("unk17", "", NITF_STR(1),false)
00805 .field("unk18", "", NITF_STR(5),false)
00806 .field("unk19", "", NITF_STR(1),false)
00807 .field("unk20", "", NITF_STR(5),false)
00808 .field("unk21", "", NITF_STR(7),false)
00809
00810 .end();
00811 }
00812 }
00813
00814
00815 void vil_nitf2_image_subheader::add_MPD26A_definitions()
00816 {
00817 vil_nitf2_tagged_record_definition* tr =vil_nitf2_tagged_record_definition::find("MPD26A");
00818 if (!tr)
00819 {
00820 vil_nitf2_tagged_record_definition::define("MPD26A", "MPD26A SUPPORT DATA EXTENSION" )
00821
00822 .field("UNK1", "Unknown ", NITF_DBL(11,1,false), false)
00823 .field("UNK2", "Unknown ", NITF_STR(2), false)
00824 .field("UNK3", "Unknown ", NITF_INT(7,false),false)
00825 .field("UNK31", "Unknown ", NITF_STR(10),false)
00826 .field("UNK4", "Unknown ", NITF_DBL(6,1,false), true)
00827 .field("UNK5", "Unknown ", NITF_DBL(9,1,false), false)
00828 .field("UNK6", "Unknown ", NITF_STR(3), false)
00829 .field("UNK7", "Unknown ", NITF_STR(1), false)
00830 .field("UNK8", "Unknown ", NITF_STR(1), false)
00831 .field("SUN_EL", "Sun Elevation angle", NITF_DBL(5,1,true),false)
00832 .field("SUN_AZ", "Sun Azimuthal angle", NITF_DBL(5,1,false),false)
00833 .field("UNK9", "Unknown ", NITF_INT(1,false), false)
00834 .field("UNK10", "Unknown ", NITF_INT(1,false), false)
00835 .field("UNK11", "Unknown ", NITF_INT(4,false), false)
00836 .field("UNK12", "Unknown ", NITF_DBL(9,1,false), false)
00837 .field("UNK13", "Unknown ", NITF_DBL(9,1,false), false)
00838 .field("UNK14", "Unknown ", NITF_DBL(9,1,false), false)
00839 .field("UNK15", "Unknown ", NITF_STR(10), false)
00840 .field("UNK16", "Unknown ", NITF_DBL(9,1,false), false)
00841 .field("UNK17", "Unknown ", NITF_DBL(9,1,false), false)
00842 .field("UNK18", "Unknown ", NITF_DBL(9,1,false), false)
00843 .field("UNK19", "Unknown ", NITF_DBL(9,1,false), false)
00844 .field("UNK20", "Unknown ", NITF_DBL(9,1,false), false)
00845 .field("UNK21", "Unknown ", NITF_DBL(9,1,false), false)
00846 .field("UNK22", "Unknown ", NITF_DBL(9,1,false), false)
00847 .field("UNK23", "Unknown ", NITF_DBL(9,1,false), false)
00848 .field("UNK24", "Unknown ", NITF_DBL(9,1,false), false)
00849 .field("UNK16", "Unknown ", NITF_DBL(9,1,false), false)
00850 .field("UNK17", "Unknown ", NITF_DBL(9,1,false), false)
00851 .field("UNK18", "Unknown ", NITF_DBL(9,1,false), false)
00852 .field("UNK19", "Unknown ", NITF_DBL(9,1,false), false)
00853 .field("UNK20", "Unknown ", NITF_DBL(9,1,false), false)
00854 .field("UNK21", "Unknown ", NITF_DBL(9,1,false), false)
00855 .field("UNK22", "Unknown ", NITF_DBL(9,1,false), false)
00856 .field("UNK23", "Unknown ", NITF_DBL(9,1,false), false)
00857 .field("UNK24", "Unknown ", NITF_DBL(9,1,false), false)
00858 .field("UNK16", "Unknown ", NITF_DBL(9,1,false), false)
00859 .field("UNK17", "Unknown ", NITF_DBL(9,1,false), false)
00860 .field("UNK18", "Unknown ", NITF_DBL(9,1,false), false)
00861 .field("UNK19", "Unknown ", NITF_DBL(9,1,false), false)
00862 .field("UNK20", "Unknown ", NITF_DBL(9,1,false), false)
00863 .field("UNK21", "Unknown ", NITF_DBL(9,1,false), false)
00864 .field("UNK22", "Unknown ", NITF_DBL(9,1,false), false)
00865 .field("UNK23", "Unknown ", NITF_DBL(9,1,false), false)
00866 .field("UNK24", "Unknown ", NITF_DBL(9,1,false), false)
00867
00868 .end();
00869 }
00870 }
00871
00872
00873
00874 bool vil_nitf2_image_subheader::
00875 get_correction_offset(double & u_off, double & v_off)
00876 {
00877
00878 vil_nitf2_tagged_record_sequence isxhd_tres;
00879 vil_nitf2_tagged_record_sequence::iterator tres_itr;
00880 this->get_property("IXSHD", isxhd_tres);
00881
00882 double ulr=0;
00883 double ulc=0;
00884
00885 for (tres_itr = isxhd_tres.begin(); tres_itr != isxhd_tres.end(); ++tres_itr)
00886 {
00887 vcl_string type = (*tres_itr)->name();
00888 if ( type == "ICHIPB" )
00889 {
00890 double r_off=1.0;
00891 double c_off=1.0;
00892 if ( (*tres_itr)->get_value("FI_ROW_11", r_off) &&
00893 (*tres_itr)->get_value("FI_COL_11", c_off) )
00894 {
00895 ulr+=r_off;
00896 ulc+=c_off;
00897 }
00898 else
00899 return false;
00900 }
00901 else if ( type == "STDIDC" )
00902 {
00903 int r_off=1;
00904 int c_off=1;
00905 if ( (*tres_itr)->get_value("START_ROW", r_off) &&
00906 (*tres_itr)->get_value("START_COLUMN", c_off) )
00907 {
00908 ulr+=(double)((r_off-1)*get_pixels_per_block_y());
00909 ulc+=(double)((c_off-1)*get_pixels_per_block_x());
00910 }
00911 else
00912 return false;
00913 }
00914 else if ( type == "STDIDB" )
00915 {
00916 int r_off=1;
00917 int c_off=1;
00918 vcl_string temp_off;
00919 if ( (*tres_itr)->get_value("START_ROW", r_off) &&
00920 (*tres_itr)->get_value("START_COLUMN", temp_off) )
00921 {
00922 if ((int)temp_off[0]>=65)
00923 c_off=((int)temp_off[0]-55)*10;
00924 else
00925 c_off=((int)temp_off[0]-48)*10;
00926 c_off+=(int)temp_off[1]-48;
00927 ulr+=(r_off-1)*get_pixels_per_block_y();
00928 ulc+=(c_off-1)*get_pixels_per_block_x();
00929 }
00930 else
00931 return false;
00932 }
00933 }
00934 u_off=ulc;
00935 v_off=ulr;
00936 return true;
00937 }
00938
00939
00940
00941 bool vil_nitf2_image_subheader::
00942 get_rpc_params( vcl_string& rpc_type, vcl_string& image_id,
00943 vcl_string& image_corner_geo_locations,
00944 double* rpc_data )
00945 {
00946
00947 vcl_string iid2 = "";
00948 bool success = this->get_property("IID2", iid2);
00949 if (!success) {
00950 vcl_cout << "IID2 Property failed in vil_nitf2_image_subheader\n";
00951 return false;
00952 }
00953 image_id = iid2.substr(0,39);
00954 vcl_string igeolo = "";
00955 success = this->get_property("IGEOLO", igeolo);
00956 if (!success) {
00957 vcl_cout << "IGEOLO Property failed in vil_nitf2_image_subheader\n";
00958 return false;
00959 }
00960 image_corner_geo_locations = igeolo;
00961
00962
00963 vil_nitf2_tagged_record_sequence isxhd_tres;
00964 vil_nitf2_tagged_record_sequence::iterator tres_itr;
00965 this->get_property("IXSHD", isxhd_tres);
00966
00967
00968
00969 for (tres_itr = isxhd_tres.begin(); tres_itr != isxhd_tres.end(); ++tres_itr)
00970 {
00971 vcl_string type = (*tres_itr)->name();
00972
00973 if ( type == "RPC00B" || type == "RPC00A")
00974 {
00975
00976 rpc_type = type;
00977
00978
00979 int line_off;
00980 success = (*tres_itr)->get_value("LINE_OFF", line_off);
00981 if (!success) {
00982 vcl_cout << "LINE_OFF Property failed in vil_nitf2_image_subheader\n";
00983 return false;
00984 }
00985 rpc_data[80] = line_off;
00986
00987 int samp_off;
00988 success = (*tres_itr)->get_value("SAMP_OFF", samp_off);
00989 if (!success) {
00990 vcl_cout << "SAMP_OFF Property failed in vil_nitf2_image_subheader\n";
00991 return false;
00992 }
00993 rpc_data[81] = samp_off;
00994
00995 double lat_off;
00996 success = (*tres_itr)->get_value("LAT_OFF", lat_off);
00997 if (!success) {
00998 vcl_cout << "LAT_OFF Property failed in vil_nitf2_image_subheader\n";
00999 return false;
01000 }
01001 rpc_data[82] = lat_off;
01002
01003 double lon_off;
01004 success = (*tres_itr)->get_value("LON_OFF", lon_off);
01005 if (!success) {
01006 vcl_cout << "LON_OFF Property failed in vil_nitf2_image_subheader\n";
01007 return false;
01008 }
01009 rpc_data[83] = lon_off;
01010
01011 int height_off;
01012 success = (*tres_itr)->get_value("HEIGHT_OFF", height_off);
01013 if (!success) {
01014 vcl_cout << "HEIGHT_OFF Property failed in vil_nitf2_image_subheader\n";
01015 return false;
01016 }
01017 rpc_data[84] = height_off;
01018
01019 int line_scale;
01020 success = (*tres_itr)->get_value("LINE_SCALE", line_scale);
01021 if (!success) {
01022 vcl_cout << "LINE_SCALE Property failed in vil_nitf2_image_subheader\n";
01023 return false;
01024 }
01025 rpc_data[85] = line_scale;
01026
01027 int samp_scale;
01028 success = (*tres_itr)->get_value("SAMP_SCALE", samp_scale);
01029 if (!success) {
01030 vcl_cout << "SAMP_SCALE Property failed in vil_nitf2_image_subheader\n";
01031 return false;
01032 }
01033 rpc_data[86] = samp_scale;
01034
01035 double lat_scale;
01036 success = (*tres_itr)->get_value("LAT_SCALE", lat_scale);
01037 if (!success) {
01038 vcl_cout << "LAT_SCALE Property failed in vil_nitf2_image_subheader\n";
01039 return false;
01040 }
01041 rpc_data[87] = lat_scale;
01042
01043 double lon_scale;
01044 success = (*tres_itr)->get_value("LON_SCALE", lon_scale);
01045 if (!success) {
01046 vcl_cout << "LON_SCALE Property failed in vil_nitf2_image_subheader\n";
01047 return false;
01048 }
01049 rpc_data[88] = lon_scale;
01050
01051 int height_scale;
01052 success = (*tres_itr)->get_value("HEIGHT_SCALE", height_scale);
01053 if (!success) {
01054 vcl_cout << "HEIGHT_SCALE Property failed in vil_nitf2_image_subheader\n";
01055 return false;
01056 }
01057 rpc_data[89] = height_scale;
01058
01059
01060 vcl_vector<double> LNC;
01061 success = (*tres_itr)->get_values("LNC", LNC);
01062 if (!success) {
01063 vcl_cout << "LNC Property failed in vil_nitf2_image_subheader\n";
01064 return false;
01065 }
01066 for (int i = 0; i < 20; i++) {
01067 rpc_data[i] = LNC[i];
01068 }
01069
01070 vcl_vector<double> LDC;
01071 success = (*tres_itr)->get_values("LDC", LDC);
01072 if (!success) {
01073 vcl_cout << "LDC Property failed in vil_nitf2_image_subheader\n";
01074 return false;
01075 }
01076 for (int i = 0; i < 20; i++) {
01077 rpc_data[i+20] = LDC[i];
01078 }
01079
01080 vcl_vector<double> SNC;
01081 success = (*tres_itr)->get_values("SNC", SNC);
01082 if (!success) {
01083 vcl_cout << "SNC Property failed in vil_nitf2_image_subheader\n";
01084 return false;
01085 }
01086 for (int i = 0; i < 20; i++) {
01087 rpc_data[i+40] = SNC[i];
01088 }
01089
01090 vcl_vector<double> SDC;
01091 success = (*tres_itr)->get_values("SDC", SDC);
01092 if (!success) {
01093 vcl_cout << "SDC Property failed in vil_nitf2_image_subheader\n";
01094 return false;
01095 }
01096 for (int i = 0; i < 20; i++) {
01097 rpc_data[i+60] = SDC[i];
01098 }
01099 }
01100 }
01101
01102 return true;
01103 }