00001
00002
00003
00004
00005 #include "vil_nitf2_tagged_record.h"
00006
00007 #include <vcl_sstream.h>
00008 #include <vcl_iomanip.h>
00009 #include <vcl_iostream.h>
00010 #include <vcl_string.h>
00011
00012 #include <vil/vil_stream_core.h>
00013 #include <vil/vil_stream_section.h>
00014
00015 #include "vil_nitf2_tagged_record_definition.h"
00016 #include "vil_nitf2_field_definition.h"
00017 #include "vil_nitf2_field_sequence.h"
00018 #include "vil_nitf2_index_vector.h"
00019 #include "vil_nitf2_typed_field_formatter.h"
00020 #include "vil_nitf2_scalar_field.h"
00021
00022 vil_nitf2_field_definition& vil_nitf2_tagged_record::s_length_definition()
00023 {
00024 static vil_nitf2_field_definition length_definition(
00025 "CEL", "Extension Length", new vil_nitf2_integer_formatter(5));
00026 return length_definition;
00027 }
00028
00029 vil_nitf2_field_definition& vil_nitf2_tagged_record::s_tag_definition()
00030 {
00031 static vil_nitf2_field_definition tag_definition (
00032 "CETAG", "Extension Tag", new vil_nitf2_string_formatter(6));
00033 return tag_definition;
00034 }
00035
00036 vil_nitf2_integer_formatter& vil_nitf2_tagged_record::s_length_formatter()
00037 {
00038 static vil_nitf2_integer_formatter length_formatter(5);
00039 return length_formatter;
00040 }
00041
00042 vil_nitf2_string_formatter& vil_nitf2_tagged_record::s_tag_formatter()
00043 {
00044 static vil_nitf2_string_formatter tag_formatter(6);
00045 return tag_formatter;
00046 }
00047
00048 vcl_string vil_nitf2_tagged_record::name() const
00049 {
00050 vcl_string cetag;
00051 if ( m_tag_field->value(cetag) ) return cetag;
00052 else return "<Unknown>";
00053 }
00054
00055 vcl_string vil_nitf2_tagged_record::pretty_name() const
00056 {
00057 if ( m_definition ) return m_definition->m_pretty_name;
00058 else return "<unknown>";
00059 }
00060
00061 vil_nitf2_tagged_record* vil_nitf2_tagged_record::create(vil_nitf2_istream& input)
00062 {
00063 vil_nitf2_tagged_record* record = new vil_nitf2_tagged_record();
00064 if (record->read(input)) {
00065 return record;
00066 } else {
00067 delete record;
00068 return 0;
00069 }
00070 }
00071
00072 bool vil_nitf2_tagged_record::read(vil_nitf2_istream& input)
00073 {
00074
00075 m_tag_field = vil_nitf2_scalar_field::read(input, &s_tag_definition());
00076 if (!m_tag_field) {
00077 vcl_cerr << "Error reading extension tag at offset " << input.tell() << ".\n";
00078
00079 return false;
00080 }
00081 vcl_string cetag;
00082 m_tag_field->value(cetag);
00083
00084
00085 m_length_field = vil_nitf2_scalar_field::read(input, &s_length_definition());
00086 if (!m_length_field) {
00087 vcl_cerr << "Error reading extension length for tag " << cetag << ".\n";
00088
00089 return false;
00090 }
00091 m_length_field->value(m_length);
00092
00093
00094 vil_nitf2_tagged_record_definition* record_definition =
00095 vil_nitf2_tagged_record_definition::find(cetag);
00096
00097
00098 if (record_definition == 0) {
00099 VIL_NITF2_LOG(log_info) << "Skipping unknown record " << cetag << ".\n";
00100
00101
00102 input.seek(input.tell()+m_length);
00103 return input.ok();
00104 }
00105
00106
00107 vil_streampos record_data_start_pos = input.tell();
00108 m_definition = record_definition;
00109 m_field_sequence = new vil_nitf2_field_sequence(record_definition->field_definitions());
00110 m_field_sequence->read(input);
00111
00112
00113 vil_streampos expected_pos = record_data_start_pos;
00114 expected_pos += m_length;
00115 if (input.tell() != expected_pos) {
00116 vcl_cerr << "vil_nitf2_tagged_record::read(): Read " << input.tell() - record_data_start_pos
00117 << " bytes instead of " << m_length << " as expected.\n";
00118
00119
00120 input.seek(expected_pos);
00121 return input.ok();
00122 }
00123
00124 return true;
00125 }
00126
00127 bool vil_nitf2_tagged_record::get_value(vcl_string tag, int& out_value) const
00128 { return m_field_sequence->get_value(tag, out_value); }
00129
00130 bool vil_nitf2_tagged_record::get_value(vcl_string tag, double& out_value) const
00131 { return m_field_sequence->get_value(tag, out_value); }
00132
00133 bool vil_nitf2_tagged_record::get_value(vcl_string tag, char& out_value) const
00134 { return m_field_sequence->get_value(tag, out_value); }
00135 bool vil_nitf2_tagged_record::get_value(vcl_string tag, void*& out_value) const
00136 { return m_field_sequence->get_value(tag, out_value); }
00137
00138 bool vil_nitf2_tagged_record::get_value(vcl_string tag, vcl_string& out_value) const
00139 { return m_field_sequence->get_value(tag, out_value); }
00140
00141 bool vil_nitf2_tagged_record::get_value(vcl_string tag, vil_nitf2_location*& out_value) const
00142 { return m_field_sequence->get_value(tag, out_value); }
00143
00144 bool vil_nitf2_tagged_record::get_value(vcl_string tag, vil_nitf2_date_time& out_value) const
00145 { return m_field_sequence->get_value(tag, out_value); }
00146
00147 #if VXL_HAS_INT_64
00148
00149
00150 bool vil_nitf2_tagged_record::get_value(vcl_string tag, vil_nitf2_long& out_value) const
00151 { return m_field_sequence->get_value(tag, out_value); }
00152 #endif
00153
00154 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, int& out_value) const
00155 { return m_field_sequence->get_value(tag, indexes, out_value); }
00156
00157 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, double& out_value) const
00158 { return m_field_sequence->get_value(tag, indexes, out_value); }
00159
00160 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, char& out_value) const
00161 { return m_field_sequence->get_value(tag, indexes, out_value); }
00162
00163 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, void*& out_value) const
00164 { return m_field_sequence->get_value(tag, indexes, out_value); }
00165
00166 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, vcl_string& out_value) const
00167 { return m_field_sequence->get_value(tag, indexes, out_value); }
00168
00169 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, vil_nitf2_location*& out_value) const
00170 { return m_field_sequence->get_value(tag, indexes, out_value); }
00171
00172 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, vil_nitf2_date_time& out_value) const
00173 { return m_field_sequence->get_value(tag, indexes, out_value); }
00174
00175 #if VXL_HAS_INT_64
00176
00177
00178 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, vil_nitf2_long& out_value) const
00179 { return m_field_sequence->get_value(tag, indexes, out_value); }
00180 #endif
00181
00182
00183 #define VIL_NITF2_TAGGED_RECORD_GET_VALUES(T) \
00184 bool vil_nitf2_tagged_record::get_values(vcl_string tag, const vil_nitf2_index_vector& indexes, \
00185 vcl_vector<T>& out_values, bool clear_out_values) const \
00186 { return m_field_sequence->get_values(tag, indexes, out_values, clear_out_values); } \
00187 bool vil_nitf2_tagged_record::get_values(vcl_string tag, vcl_vector<T>& out_values) const \
00188 { return m_field_sequence->get_values(tag, out_values); }
00189
00190 VIL_NITF2_TAGGED_RECORD_GET_VALUES(int);
00191 VIL_NITF2_TAGGED_RECORD_GET_VALUES(double);
00192 VIL_NITF2_TAGGED_RECORD_GET_VALUES(char);
00193 VIL_NITF2_TAGGED_RECORD_GET_VALUES(void*);
00194 VIL_NITF2_TAGGED_RECORD_GET_VALUES(vcl_string);
00195 VIL_NITF2_TAGGED_RECORD_GET_VALUES(vil_nitf2_location*);
00196 VIL_NITF2_TAGGED_RECORD_GET_VALUES(vil_nitf2_date_time);
00197 #if VXL_HAS_INT_64
00198 VIL_NITF2_TAGGED_RECORD_GET_VALUES(vil_nitf2_long);
00199 #endif
00200
00201
00202 vil_nitf2_tagged_record::vil_nitf2_tagged_record()
00203 : m_length_field(0), m_tag_field(0), m_length(0), m_definition(0), m_field_sequence(0)
00204 {}
00205
00206
00207
00208 bool vil_nitf2_tagged_record::test()
00209 {
00210 bool error = false;
00211 const char* test_tre_tag = "@TEST@";
00212
00213 vil_nitf2_tagged_record_definition::define(test_tre_tag, "Test Definition" )
00214 .field("MTI_DP", "Destination Point", NITF_INT(2))
00215 .field("MTI_PACKET_ID", "MTI Packed ID Number", NITF_INT(3))
00216 .field("DATIME", "Scan Date & Time", NITF_DAT(14), true)
00217 .field("ACFT_LOC", "Aircraft Position", NITF_LOC(21))
00218 .field("ACFT_LOC2", "Aircraft Position 2", NITF_LOC(21))
00219 .field("SQUINT_ANGLE", "Squint Angle", NITF_DBL(6, 2, true), true)
00220 .field("NO_VALID_TARGETS", "Number of Targets", NITF_INT(3))
00221 .field("TGT_CAT", "Target Classification Category",
00222 NITF_ENUM(1, vil_nitf2_enum_values()
00223 .value("H", "Helicopter")
00224 .value("T", "Tracked")
00225 .value("U", "Unknown")
00226 .value("W", "Wheeled")
00227 .value("TOO LONG", "Too long value test")
00228 .value("T", "Duplicate value test")))
00229 .repeat(new vil_nitf2_field_value<int>("NO_VALID_TARGETS"),
00230 vil_nitf2_field_definitions()
00231 .field("TGT_n_SPEED", "Target Estimated Ground Speed", NITF_INT(4),
00232 true)
00233 .field("TGT_n_CAT", "Target Classification Category",
00234 NITF_ENUM(1, vil_nitf2_enum_values()
00235 .value("H", "Helicopter")
00236 .value("T", "Tracked")
00237 .value("U", "Unknown")
00238 .value("W", "Wheeled")),
00239 true))
00240 .field("TEST_NEG_COND", "Test False Condition", NITF_STR_BCSA(14), false,
00241 0, new vil_nitf2_field_value_greater_than<int>("MTI_DP", 5))
00242 .field("TEST_POS_COND", "Test True Condition", NITF_STR_BCSA(14), false,
00243 0, new vil_nitf2_field_value_greater_than<int>("MTI_DP", 1))
00244 .field("CLASS", "Security Classification",
00245 NITF_ENUM(1, vil_nitf2_enum_values()
00246 .value("T", "Top Secret")
00247 .value("S", "Secret")
00248 .value("C", "Confindential")
00249 .value("R", "Restricted")
00250 .value("U", "Unclassified")),
00251 true, 0, 0)
00252 .field("CODEW", "Code Words", NITF_STR_BCSA(15), false,
00253 0, new vil_nitf2_field_value_one_of<vcl_string>( "CLASS", "T" ) )
00254 .field("CWTEST", "Another Code Word Test", NITF_STR_BCSA(15), false,
00255 0, new vil_nitf2_field_value_one_of<vcl_string>( "CLASS", "U" ) )
00256 .field("NBANDS", "Number of bands", NITF_INT(1), false,
00257 0, 0 )
00258 .field("XBANDS", "Large number of bands", NITF_INT(2), false,
00259 0, new vil_nitf2_field_value_one_of<int>("NBANDS",0))
00260 .repeat(new vil_nitf2_choose_field_value<int>("NBANDS", "XBANDS",
00261 new vil_nitf2_field_value_greater_than<int>("NBANDS", 0)),
00262 vil_nitf2_field_definitions()
00263 .field("BAND_LTR", "Band Description", NITF_CHAR(), true,
00264 0)
00265 )
00266 .field( "EXP_TEST", "Exponential format test", NITF_EXP(6,1))
00267
00268
00269 .field( "N", "Test repeat N", NITF_INT(1))
00270 .repeat(new vil_nitf2_field_value<int>("N"), vil_nitf2_field_definitions()
00271 .field("A", "Test repeat A", NITF_INT(1))
00272 .repeat(new vil_nitf2_field_value<int>("N"), vil_nitf2_field_definitions()
00273 .field("S", "Test repeat S", NITF_STR(3))
00274 )
00275 .repeat(new vil_nitf2_field_value<int>("A"), vil_nitf2_field_definitions()
00276 .field("B", "Test repeat B", NITF_STR_BCSA(3))
00277 .repeat(new vil_nitf2_field_value<int>("A"), vil_nitf2_field_definitions()
00278 .field("C", "Test repeat C", NITF_STR_BCSA(4))
00279 )
00280 )
00281 )
00282
00283 .repeat(4, vil_nitf2_field_definitions()
00284 .field("D", "Test fixed repeat", NITF_INT(1))
00285 )
00286 .end();
00287
00288 vcl_string testFieldsStr =
00289 "02"
00290 "003"
00291
00292 " "
00293 "+89.111111-159.222222"
00294 "890102.33N0091122.00W"
00295 "-60.00"
00296 "003"
00297 " "
00298 "2222" "H"
00299 " " " "
00300 "4444" "T"
00301 ""
00302 "True Condition"
00303 "T"
00304 "RandomCodeWords"
00305 ""
00306 "0"
00307 "12"
00308 "abcdefghijkl"
00309 "+1.234567E-8"
00310
00311 "2"
00312
00313 "1"
00314 "S00"
00315 "S01"
00316
00317 "B00"
00318
00319 "C000"
00320
00321 "2"
00322 "S10"
00323 "S11"
00324
00325 "B10"
00326
00327 "C100"
00328 "C101"
00329 "B11"
00330 "C110"
00331 "C111"
00332
00333 "7890"
00334 ;
00335 vcl_stringstream test_stream;
00336 test_stream << test_tre_tag;
00337 test_stream << vcl_setw(5) << vcl_setfill('0') << testFieldsStr.length();
00338 test_stream << testFieldsStr;
00339 vcl_string read_string = test_stream.str();
00340
00341 vil_stream_core* vs = new vil_stream_core();
00342 vs->write(read_string.c_str(), read_string.length());
00343 vs->seek(0);
00344 vil_stream_section* vss = new vil_stream_section(vs, 0, read_string.length());
00345
00346 vil_nitf2_tagged_record* record = vil_nitf2_tagged_record::create(*vss);
00347 if (record)
00348 {
00349 vcl_cerr << *record << vcl_endl;
00350
00351 vcl_cerr << "\nOriginal string:\n" << read_string
00352 << "\nWrite() output:\n";
00353 vil_stream_core* vs2 = new vil_stream_core();
00354 record->write(*(vil_stream*)vs2);
00355 vil_streampos bufsize = vs2->file_size();
00356 char* buf = new char[(unsigned int)bufsize + 1];
00357 vs2->seek(0);
00358 vs2->read(buf, bufsize);
00359 buf[bufsize]='\0';
00360 vcl_string write_string = vcl_string(buf);
00361 vcl_cerr << write_string << vcl_endl;
00362 if (read_string != write_string) {
00363 vcl_cerr << "\nWrite failed!\n";
00364 error = true;
00365 }
00366 delete buf;
00367 vcl_cerr << "Testing get_value:\n";
00368 int mti_dp;
00369 if (!record->get_value("MTI_DP", mti_dp) || mti_dp!=2) {
00370 vcl_cerr << "Get value failed!\n";
00371 error = true;
00372 } else {
00373 vcl_cerr << "MTI_DP = " << mti_dp << vcl_endl;
00374 }
00375 int tgt_speed[4];
00376 if (!record->get_value("TGT_n_SPEED", vil_nitf2_index_vector(0), tgt_speed[0]) ||
00377 tgt_speed[0] != 2222 ||
00378 record->get_value("TGT_n_SPEED", vil_nitf2_index_vector(1), tgt_speed[1]) ||
00379 !record->get_value("TGT_n_SPEED", vil_nitf2_index_vector(2), tgt_speed[2]) ||
00380 tgt_speed[2] != 4444) {
00381 vcl_cerr << "Get vector value test failed!\n";
00382 error = true;
00383 } else {
00384 vcl_cerr << "TGT_2_SPEED = " << tgt_speed[2] << vcl_endl;
00385 }
00386 int d2;
00387 if (!record->get_value("D", vil_nitf2_index_vector(2), d2) || d2 != 9) {
00388 vcl_cerr << "Get fixed repeat count test failed!\n";
00389 error = true;
00390 }
00391
00392 vcl_cerr << "Testing get_values (all values)...\n";
00393 vcl_vector<vcl_string> c_values;
00394 if (!record->get_values("C", c_values) ||
00395 c_values.size() != 5 ||
00396 c_values[0]!="C000" ||
00397 c_values[1]!="C100" ||
00398 c_values[2]!="C101" ||
00399 c_values[3]!="C110" ||
00400 c_values[4]!="C111") {
00401 vcl_cerr << "failed!\n\n";
00402 error = true;
00403 }
00404
00405 vcl_cerr << "Get values (partial index)...\n";
00406 vil_nitf2_index_vector indexes;
00407 vcl_vector<int> a_values;
00408 indexes.push_back(1);
00409 if (!record->get_values("A", indexes, a_values) ||
00410 a_values.size() != 1 ||
00411 a_values[0] != 2) {
00412 vcl_cerr << "failed!\n\n";
00413 error = true;
00414 }
00415
00416 if (!record->get_values("C", indexes, c_values) ||
00417 c_values.size() != 4 ||
00418 c_values[0]!="C100" ||
00419 c_values[1]!="C101" ||
00420 c_values[2]!="C110" ||
00421 c_values[3]!="C111")
00422 {
00423 vcl_cerr << "failed!\n\n";
00424 }
00425 } else {
00426 vcl_cerr << "Didn't create record!\n";
00427 error = true;
00428 }
00429
00430 vcl_cerr << "Output of vector field C:\n"
00431 << *(record->get_field("C"));
00432
00433 if (!vil_nitf2_tagged_record_definition::undefine(test_tre_tag)) {
00434 vcl_cerr << "Error undefining TRE.\n";
00435 error = true;
00436 }
00437 return !error;
00438 }
00439
00440 vcl_ostream& vil_nitf2_tagged_record::output(vcl_ostream& os) const
00441 {
00442 os << "CETAG: " << name() << vcl_endl
00443 << "CELEN: " << length() << vcl_endl;
00444 for (vil_nitf2_field_definitions::iterator fieldNode = m_definition->m_field_definitions->begin();
00445 fieldNode != m_definition->m_field_definitions->end(); ++fieldNode)
00446 {
00447 vil_nitf2_field_definition* field_def = (*fieldNode)->field_definition();
00448
00449 if (!field_def) break;
00450 vil_nitf2_field* field = get_field(field_def->tag);
00451 os << field_def->tag << ": ";
00452 if (field) {
00453 os << *field << vcl_endl;
00454 } else {
00455 os << "(undefined)" << vcl_endl;
00456 }
00457 }
00458 return os;
00459 }
00460
00461 bool vil_nitf2_tagged_record::write(vil_nitf2_ostream& output)
00462 {
00463
00464 vil_streampos start = output.tell();
00465
00466 if (m_tag_field && m_length_field) {
00467 m_tag_field->write(output);
00468 m_length_field->write(output);
00469 } else return false;
00470
00471 m_field_sequence->write(output);
00472
00473 vil_streampos end = output.tell();
00474 vil_streampos length_written = end - start;
00475 int expected_length = s_tag_formatter().field_width + s_length_formatter().field_width
00476 + length();
00477 return length_written == expected_length;
00478 }
00479
00480 vil_nitf2_tagged_record::~vil_nitf2_tagged_record()
00481 {
00482 delete m_field_sequence;
00483 }
00484
00485 vil_nitf2_field_definition* vil_nitf2_field_sequence::find_field_definition(vcl_string tag)
00486 {
00487 for (vil_nitf2_field_definitions::const_iterator node = m_field_definitions->begin();
00488 node != m_field_definitions->end(); ++node)
00489 {
00490 vil_nitf2_field_definition* field_def = (*node)->field_definition();
00491
00492 if (!field_def) break;
00493
00494 if (field_def->tag == tag) {
00495 return field_def;
00496 }
00497 }
00498
00499 return 0;
00500 }
00501
00502 vil_nitf2_field::field_tree* vil_nitf2_tagged_record::get_tree() const
00503 {
00504
00505
00506
00507 vil_nitf2_field::field_tree* tr;
00508 if ( m_field_sequence ) {
00509 tr = m_field_sequence->get_tree();
00510 } else {
00511 tr = new vil_nitf2_field::field_tree;
00512 vil_nitf2_field::field_tree* skipped_node = new vil_nitf2_field::field_tree;
00513 skipped_node->columns.push_back( "CEDATA" );
00514 skipped_node->columns.push_back( "<skipped unknown TRE>" );
00515 tr->children.push_back( skipped_node );
00516 }
00517
00518
00519 tr->columns.push_back( name() );
00520 tr->columns.push_back( pretty_name() );
00521
00522 vil_nitf2_field::field_tree* first_child = new vil_nitf2_field::field_tree;
00523 first_child->columns.push_back( "CEL" );
00524 first_child->columns.push_back( "Extension Length" );
00525 vcl_stringstream len_stream;
00526 len_stream << length();
00527 first_child->columns.push_back( len_stream.str() );
00528 tr->children.insert( tr->children.begin(), first_child );
00529 return tr;
00530 }
00531
00532 vcl_ostream& operator << (vcl_ostream& os, const vil_nitf2_tagged_record& record)
00533 {
00534 return record.output(os);
00535 }
00536
00537
00538
00539 vcl_ostream& operator << (vcl_ostream& os, const vil_nitf2_tagged_record_sequence& seq)
00540 {
00541 os << seq.size() << " TRE's:" << vcl_endl;
00542 vil_nitf2_tagged_record_sequence::const_iterator it;
00543 for (it = seq.begin(); it != seq.end(); ++it) {
00544 os << *it << vcl_endl;
00545 }
00546 return os;
00547 }