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 in "<<cetag<<".\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), true)
00232 .field("TGT_n_CAT", "Target Classification Category",
00233 NITF_ENUM(1, vil_nitf2_enum_values()
00234 .value("H", "Helicopter")
00235 .value("T", "Tracked")
00236 .value("U", "Unknown")
00237 .value("W", "Wheeled")),
00238 true))
00239 .field("TEST_NEG_COND", "Test False Condition", NITF_STR_BCSA(14), false,
00240 0, new vil_nitf2_field_value_greater_than<int>("MTI_DP", 5))
00241 .field("TEST_POS_COND", "Test True Condition", NITF_STR_BCSA(14), false,
00242 0, new vil_nitf2_field_value_greater_than<int>("MTI_DP", 1))
00243 .field("CLASS", "Security Classification",
00244 NITF_ENUM(1, vil_nitf2_enum_values()
00245 .value("T", "Top Secret")
00246 .value("S", "Secret")
00247 .value("C", "Confindential")
00248 .value("R", "Restricted")
00249 .value("U", "Unclassified")),
00250 true, 0, 0)
00251 .field("CODEW", "Code Words", NITF_STR_BCSA(15), false,
00252 0, new vil_nitf2_field_value_one_of<vcl_string>( "CLASS", "T" ) )
00253 .field("CWTEST", "Another Code Word Test", NITF_STR_BCSA(15), false,
00254 0, new vil_nitf2_field_value_one_of<vcl_string>( "CLASS", "U" ) )
00255 .field("NBANDS", "Number of bands", NITF_INT(1), false,
00256 0, 0 )
00257 .field("XBANDS", "Large number of bands", NITF_INT(2), false,
00258 0, new vil_nitf2_field_value_one_of<int>("NBANDS",0))
00259 .repeat(new vil_nitf2_choose_field_value<int>("NBANDS", "XBANDS",
00260 new vil_nitf2_field_value_greater_than<int>("NBANDS", 0)),
00261 vil_nitf2_field_definitions()
00262 .field("BAND_LTR", "Band Description", NITF_CHAR(), true,
00263 0)
00264 )
00265 .field( "EXP_TEST", "Exponential format test", NITF_EXP(6,1))
00266
00267
00268 .field( "N", "Test repeat N", NITF_INT(1))
00269 .repeat(new vil_nitf2_field_value<int>("N"), vil_nitf2_field_definitions()
00270 .field("A", "Test repeat A", NITF_INT(1))
00271 .repeat(new vil_nitf2_field_value<int>("N"), vil_nitf2_field_definitions()
00272 .field("S", "Test repeat S", NITF_STR(3)))
00273 .repeat(new vil_nitf2_field_value<int>("A"), vil_nitf2_field_definitions()
00274 .field("B", "Test repeat B", NITF_STR_BCSA(3))
00275 .repeat(new vil_nitf2_field_value<int>("A"), vil_nitf2_field_definitions()
00276 .field("C", "Test repeat C", NITF_STR_BCSA(4)))))
00277
00278 .repeat(4, vil_nitf2_field_definitions()
00279 .field("D", "Test fixed repeat", NITF_INT(1))
00280 )
00281 .end();
00282
00283 vcl_string testFieldsStr =
00284 "02"
00285 "003"
00286
00287 " "
00288 "+89.111111-159.222222"
00289 "890102.33N0091122.00W"
00290 "-60.00"
00291 "003"
00292 " "
00293 "2222" "H"
00294 " " " "
00295 "4444" "T"
00296 ""
00297 "True Condition"
00298 "T"
00299 "RandomCodeWords"
00300 ""
00301 "0"
00302 "12"
00303 "abcdefghijkl"
00304 "+1.234567E-8"
00305
00306 "2"
00307
00308 "1"
00309 "S00"
00310 "S01"
00311
00312 "B00"
00313
00314 "C000"
00315
00316 "2"
00317 "S10"
00318 "S11"
00319
00320 "B10"
00321
00322 "C100"
00323 "C101"
00324 "B11"
00325 "C110"
00326 "C111"
00327
00328 "7890"
00329 ;
00330 vcl_stringstream test_stream;
00331 test_stream << test_tre_tag;
00332 test_stream << vcl_setw(5) << vcl_setfill('0') << testFieldsStr.length();
00333 test_stream << testFieldsStr;
00334 vcl_string read_string = test_stream.str();
00335
00336 vil_stream_core* vs = new vil_stream_core();
00337 vs->write(read_string.c_str(), read_string.length());
00338 vs->seek(0);
00339 vil_stream_section* vss = new vil_stream_section(vs, 0, read_string.length());
00340
00341 vil_nitf2_tagged_record* record = vil_nitf2_tagged_record::create(*vss);
00342 if (record)
00343 {
00344 vcl_cerr << *record << vcl_endl;
00345
00346 vcl_cerr << "\nOriginal string:\n" << read_string
00347 << "\nWrite() output:\n";
00348 vil_stream_core* vs2 = new vil_stream_core();
00349 record->write(*(vil_stream*)vs2);
00350 vil_streampos bufsize = vs2->file_size();
00351 char* buf = new char[(unsigned int)bufsize + 1];
00352 vs2->seek(0);
00353 vs2->read(buf, bufsize);
00354 buf[bufsize]='\0';
00355 vcl_string write_string = vcl_string(buf);
00356 vcl_cerr << write_string << vcl_endl;
00357 if (read_string != write_string) {
00358 vcl_cerr << "\nWrite failed!\n";
00359 error = true;
00360 }
00361 delete buf;
00362 vcl_cerr << "Testing get_value:\n";
00363 int mti_dp;
00364 if (!record->get_value("MTI_DP", mti_dp) || mti_dp!=2) {
00365 vcl_cerr << "Get value failed!\n";
00366 error = true;
00367 } else {
00368 vcl_cerr << "MTI_DP = " << mti_dp << vcl_endl;
00369 }
00370 int tgt_speed[4];
00371 if (!record->get_value("TGT_n_SPEED", vil_nitf2_index_vector(0), tgt_speed[0]) ||
00372 tgt_speed[0] != 2222 ||
00373 record->get_value("TGT_n_SPEED", vil_nitf2_index_vector(1), tgt_speed[1]) ||
00374 !record->get_value("TGT_n_SPEED", vil_nitf2_index_vector(2), tgt_speed[2]) ||
00375 tgt_speed[2] != 4444) {
00376 vcl_cerr << "Get vector value test failed!\n";
00377 error = true;
00378 } else {
00379 vcl_cerr << "TGT_2_SPEED = " << tgt_speed[2] << vcl_endl;
00380 }
00381 int d2;
00382 if (!record->get_value("D", vil_nitf2_index_vector(2), d2) || d2 != 9) {
00383 vcl_cerr << "Get fixed repeat count test failed!\n";
00384 error = true;
00385 }
00386
00387 vcl_cerr << "Testing get_values (all values)...\n";
00388 vcl_vector<vcl_string> c_values;
00389 if (!record->get_values("C", c_values) ||
00390 c_values.size() != 5 ||
00391 c_values[0]!="C000" ||
00392 c_values[1]!="C100" ||
00393 c_values[2]!="C101" ||
00394 c_values[3]!="C110" ||
00395 c_values[4]!="C111") {
00396 vcl_cerr << "failed!\n\n";
00397 error = true;
00398 }
00399
00400 vcl_cerr << "Get values (partial index)...\n";
00401 vil_nitf2_index_vector indexes;
00402 vcl_vector<int> a_values;
00403 indexes.push_back(1);
00404 if (!record->get_values("A", indexes, a_values) ||
00405 a_values.size() != 1 ||
00406 a_values[0] != 2) {
00407 vcl_cerr << "failed!\n\n";
00408 error = true;
00409 }
00410
00411 if (!record->get_values("C", indexes, c_values) ||
00412 c_values.size() != 4 ||
00413 c_values[0]!="C100" ||
00414 c_values[1]!="C101" ||
00415 c_values[2]!="C110" ||
00416 c_values[3]!="C111")
00417 {
00418 vcl_cerr << "failed!\n\n";
00419 }
00420 } else {
00421 vcl_cerr << "Didn't create record!\n";
00422 error = true;
00423 }
00424
00425 vcl_cerr << "Output of vector field C:\n"
00426 << *(record->get_field("C"));
00427
00428 if (!vil_nitf2_tagged_record_definition::undefine(test_tre_tag)) {
00429 vcl_cerr << "Error undefining TRE.\n";
00430 error = true;
00431 }
00432 return !error;
00433 }
00434
00435 vcl_ostream& vil_nitf2_tagged_record::output(vcl_ostream& os) const
00436 {
00437 os << "CETAG: " << name() << vcl_endl
00438 << "CELEN: " << length() << vcl_endl;
00439 for (vil_nitf2_field_definitions::iterator fieldNode = m_definition->m_field_definitions->begin();
00440 fieldNode != m_definition->m_field_definitions->end(); ++fieldNode)
00441 {
00442 vil_nitf2_field_definition* field_def = (*fieldNode)->field_definition();
00443
00444 if (!field_def) break;
00445 vil_nitf2_field* field = get_field(field_def->tag);
00446 os << field_def->tag << ": ";
00447 if (field) {
00448 os << *field << vcl_endl;
00449 } else {
00450 os << "(undefined)" << vcl_endl;
00451 }
00452 }
00453 return os;
00454 }
00455
00456 bool vil_nitf2_tagged_record::write(vil_nitf2_ostream& output)
00457 {
00458
00459 vil_streampos start = output.tell();
00460
00461 if (m_tag_field && m_length_field) {
00462 m_tag_field->write(output);
00463 m_length_field->write(output);
00464 } else return false;
00465
00466 m_field_sequence->write(output);
00467
00468 vil_streampos end = output.tell();
00469 vil_streampos length_written = end - start;
00470 int expected_length = s_tag_formatter().field_width + s_length_formatter().field_width
00471 + length();
00472 return length_written == expected_length;
00473 }
00474
00475 vil_nitf2_tagged_record::~vil_nitf2_tagged_record()
00476 {
00477 delete m_field_sequence;
00478 }
00479
00480 vil_nitf2_field_definition* vil_nitf2_field_sequence::find_field_definition(vcl_string tag)
00481 {
00482 for (vil_nitf2_field_definitions::const_iterator node = m_field_definitions->begin();
00483 node != m_field_definitions->end(); ++node)
00484 {
00485 vil_nitf2_field_definition* field_def = (*node)->field_definition();
00486
00487 if (!field_def) break;
00488
00489 if (field_def->tag == tag) {
00490 return field_def;
00491 }
00492 }
00493
00494 return 0;
00495 }
00496
00497 vil_nitf2_field::field_tree* vil_nitf2_tagged_record::get_tree() const
00498 {
00499
00500
00501
00502 vil_nitf2_field::field_tree* tr;
00503 if ( m_field_sequence ) {
00504 tr = m_field_sequence->get_tree();
00505 } else {
00506 tr = new vil_nitf2_field::field_tree;
00507 vil_nitf2_field::field_tree* skipped_node = new vil_nitf2_field::field_tree;
00508 skipped_node->columns.push_back( "CEDATA" );
00509 skipped_node->columns.push_back( "<skipped unknown TRE>" );
00510 tr->children.push_back( skipped_node );
00511 }
00512
00513
00514 tr->columns.push_back( name() );
00515 tr->columns.push_back( pretty_name() );
00516
00517 vil_nitf2_field::field_tree* first_child = new vil_nitf2_field::field_tree;
00518 first_child->columns.push_back( "CEL" );
00519 first_child->columns.push_back( "Extension Length" );
00520 vcl_stringstream len_stream;
00521 len_stream << length();
00522 first_child->columns.push_back( len_stream.str() );
00523 tr->children.insert( tr->children.begin(), first_child );
00524 return tr;
00525 }
00526
00527 vcl_ostream& operator << (vcl_ostream& os, const vil_nitf2_tagged_record& record)
00528 {
00529 return record.output(os);
00530 }
00531
00532
00533
00534 vcl_ostream& operator << (vcl_ostream& os, const vil_nitf2_tagged_record_sequence& seq)
00535 {
00536 os << seq.size() << " TRE's:" << vcl_endl;
00537 vil_nitf2_tagged_record_sequence::const_iterator it;
00538 for (it = seq.begin(); it != seq.end(); ++it) {
00539 os << *it << vcl_endl;
00540 }
00541 return os;
00542 }