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 }
00067 else {
00068 delete record;
00069 return 0;
00070 }
00071 }
00072
00073 bool vil_nitf2_tagged_record::read(vil_nitf2_istream& input)
00074 {
00075
00076 m_tag_field = vil_nitf2_scalar_field::read(input, &s_tag_definition());
00077 if (!m_tag_field) {
00078 vcl_cerr << "Error reading extension tag at offset " << input.tell() << ".\n";
00079
00080 return false;
00081 }
00082 vcl_string cetag;
00083 m_tag_field->value(cetag);
00084
00085
00086 m_length_field = vil_nitf2_scalar_field::read(input, &s_length_definition());
00087 if (!m_length_field) {
00088 vcl_cerr << "Error reading extension length for tag " << cetag << ".\n";
00089
00090 return false;
00091 }
00092 m_length_field->value(m_length);
00093
00094
00095 vil_nitf2_tagged_record_definition* record_definition =
00096 vil_nitf2_tagged_record_definition::find(cetag);
00097
00098
00099 if (record_definition == 0) {
00100 VIL_NITF2_LOG(log_info) << "Skipping unknown record " << cetag << ".\n";
00101
00102
00103 input.seek(input.tell()+m_length);
00104 return input.ok();
00105 }
00106
00107
00108 vil_streampos record_data_start_pos = input.tell();
00109 m_definition = record_definition;
00110 m_field_sequence = new vil_nitf2_field_sequence(record_definition->field_definitions());
00111 m_field_sequence->read(input);
00112
00113
00114 vil_streampos expected_pos = record_data_start_pos;
00115 expected_pos += m_length;
00116 if (input.tell() != expected_pos) {
00117 vcl_cerr << "vil_nitf2_tagged_record::read(): Read " << input.tell() - record_data_start_pos
00118 << " bytes instead of " << m_length << " as expected in "<<cetag<<".\n";
00119
00120
00121 input.seek(expected_pos);
00122 return input.ok();
00123 }
00124
00125 return true;
00126 }
00127
00128 bool vil_nitf2_tagged_record::get_value(vcl_string tag, int& out_value) const
00129 { return m_field_sequence->get_value(tag, out_value); }
00130
00131 bool vil_nitf2_tagged_record::get_value(vcl_string tag, double& out_value) const
00132 { return m_field_sequence->get_value(tag, out_value); }
00133
00134 bool vil_nitf2_tagged_record::get_value(vcl_string tag, char& out_value) const
00135 { return m_field_sequence->get_value(tag, out_value); }
00136 bool vil_nitf2_tagged_record::get_value(vcl_string tag, void*& out_value) const
00137 { return m_field_sequence->get_value(tag, out_value); }
00138
00139 bool vil_nitf2_tagged_record::get_value(vcl_string tag, vcl_string& out_value) const
00140 { return m_field_sequence->get_value(tag, out_value); }
00141
00142 bool vil_nitf2_tagged_record::get_value(vcl_string tag, vil_nitf2_location*& out_value) const
00143 { return m_field_sequence->get_value(tag, out_value); }
00144
00145 bool vil_nitf2_tagged_record::get_value(vcl_string tag, vil_nitf2_date_time& out_value) const
00146 { return m_field_sequence->get_value(tag, out_value); }
00147
00148 #if VXL_HAS_INT_64
00149
00150
00151 bool vil_nitf2_tagged_record::get_value(vcl_string tag, vil_nitf2_long& out_value) const
00152 { return m_field_sequence->get_value(tag, out_value); }
00153 #endif
00154
00155 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, int& out_value) const
00156 { return m_field_sequence->get_value(tag, indexes, out_value); }
00157
00158 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, double& out_value) const
00159 { return m_field_sequence->get_value(tag, indexes, out_value); }
00160
00161 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, char& out_value) const
00162 { return m_field_sequence->get_value(tag, indexes, out_value); }
00163
00164 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, void*& out_value) const
00165 { return m_field_sequence->get_value(tag, indexes, out_value); }
00166
00167 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, vcl_string& out_value) const
00168 { return m_field_sequence->get_value(tag, indexes, out_value); }
00169
00170 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, vil_nitf2_location*& out_value) const
00171 { return m_field_sequence->get_value(tag, indexes, out_value); }
00172
00173 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, vil_nitf2_date_time& out_value) const
00174 { return m_field_sequence->get_value(tag, indexes, out_value); }
00175
00176 #if VXL_HAS_INT_64
00177
00178
00179 bool vil_nitf2_tagged_record::get_value(vcl_string tag, const vil_nitf2_index_vector& indexes, vil_nitf2_long& out_value) const
00180 { return m_field_sequence->get_value(tag, indexes, out_value); }
00181 #endif
00182
00183
00184 #define VIL_NITF2_TAGGED_RECORD_GET_VALUES(T) \
00185 bool vil_nitf2_tagged_record::get_values(vcl_string tag, const vil_nitf2_index_vector& indexes, \
00186 vcl_vector<T>& out_values, bool clear_out_values) const \
00187 { return m_field_sequence->get_values(tag, indexes, out_values, clear_out_values); } \
00188 bool vil_nitf2_tagged_record::get_values(vcl_string tag, vcl_vector<T>& out_values) const \
00189 { return m_field_sequence->get_values(tag, out_values); }
00190
00191 VIL_NITF2_TAGGED_RECORD_GET_VALUES(int);
00192 VIL_NITF2_TAGGED_RECORD_GET_VALUES(double);
00193 VIL_NITF2_TAGGED_RECORD_GET_VALUES(char);
00194 VIL_NITF2_TAGGED_RECORD_GET_VALUES(void*);
00195 VIL_NITF2_TAGGED_RECORD_GET_VALUES(vcl_string);
00196 VIL_NITF2_TAGGED_RECORD_GET_VALUES(vil_nitf2_location*);
00197 VIL_NITF2_TAGGED_RECORD_GET_VALUES(vil_nitf2_date_time);
00198 #if VXL_HAS_INT_64
00199 VIL_NITF2_TAGGED_RECORD_GET_VALUES(vil_nitf2_long);
00200 #endif
00201
00202
00203 vil_nitf2_tagged_record::vil_nitf2_tagged_record()
00204 : m_length_field(0), m_tag_field(0), m_length(0), m_definition(0), m_field_sequence(0)
00205 {}
00206
00207
00208
00209 bool vil_nitf2_tagged_record::test()
00210 {
00211 bool error = false;
00212 const char* test_tre_tag = "@TEST@";
00213
00214 vil_nitf2_tagged_record_definition::define(test_tre_tag, "Test Definition" )
00215 .field("MTI_DP", "Destination Point", NITF_INT(2))
00216 .field("MTI_PACKET_ID", "MTI Packed ID Number", NITF_INT(3))
00217 .field("DATIME", "Scan Date & Time", NITF_DAT(14), true)
00218 .field("ACFT_LOC", "Aircraft Position", NITF_LOC(21))
00219 .field("ACFT_LOC2", "Aircraft Position 2", NITF_LOC(21))
00220 .field("SQUINT_ANGLE", "Squint Angle", NITF_DBL(6, 2, true), true)
00221 .field("NO_VALID_TARGETS", "Number of Targets", NITF_INT(3))
00222 .field("TGT_CAT", "Target Classification Category",
00223 NITF_ENUM(1, vil_nitf2_enum_values()
00224 .value("H", "Helicopter")
00225 .value("T", "Tracked")
00226 .value("U", "Unknown")
00227 .value("W", "Wheeled")
00228 .value("TOO LONG", "Too long value test")
00229 .value("T", "Duplicate value test")))
00230 .repeat(new vil_nitf2_field_value<int>("NO_VALID_TARGETS"),
00231 vil_nitf2_field_definitions()
00232 .field("TGT_n_SPEED", "Target Estimated Ground Speed", NITF_INT(4), 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 .repeat(new vil_nitf2_field_value<int>("A"), vil_nitf2_field_definitions()
00275 .field("B", "Test repeat B", NITF_STR_BCSA(3))
00276 .repeat(new vil_nitf2_field_value<int>("A"), vil_nitf2_field_definitions()
00277 .field("C", "Test repeat C", NITF_STR_BCSA(4)))))
00278
00279 .repeat(4, vil_nitf2_field_definitions()
00280 .field("D", "Test fixed repeat", NITF_INT(1))
00281 )
00282 .end();
00283
00284 vcl_string testFieldsStr =
00285 "02"
00286 "003"
00287
00288 " "
00289 "+89.111111-159.222222"
00290 "890102.33N0091122.00W"
00291 "-60.00"
00292 "003"
00293 " "
00294 "2222" "H"
00295 " " " "
00296 "4444" "T"
00297 ""
00298 "True Condition"
00299 "T"
00300 "RandomCodeWords"
00301 ""
00302 "0"
00303 "12"
00304 "abcdefghijkl"
00305 "+1.234567E-8"
00306
00307 "2"
00308
00309 "1"
00310 "S00"
00311 "S01"
00312
00313 "B00"
00314
00315 "C000"
00316
00317 "2"
00318 "S10"
00319 "S11"
00320
00321 "B10"
00322
00323 "C100"
00324 "C101"
00325 "B11"
00326 "C110"
00327 "C111"
00328
00329 "7890"
00330 ;
00331 vcl_stringstream test_stream;
00332 test_stream << test_tre_tag;
00333 test_stream << vcl_setw(5) << vcl_setfill('0') << testFieldsStr.length();
00334 test_stream << testFieldsStr;
00335 vcl_string read_string = test_stream.str();
00336
00337 vil_stream_core* vs = new vil_stream_core();
00338 vs->write(read_string.c_str(), read_string.length());
00339 vs->seek(0);
00340 vil_stream_section* vss = new vil_stream_section(vs, 0, int(read_string.length()));
00341
00342 vil_nitf2_tagged_record* record = vil_nitf2_tagged_record::create(*vss);
00343 if (record)
00344 {
00345 vcl_cerr << *record << '\n';
00346
00347 vcl_cerr << "\nOriginal string:\n" << read_string
00348 << "\nWrite() output:\n";
00349 vil_stream_core* vs2 = new vil_stream_core();
00350 record->write(*(vil_stream*)vs2);
00351 vil_streampos bufsize = vs2->file_size();
00352 char* buf = new char[(unsigned int)bufsize + 1];
00353 vs2->seek(0);
00354 vs2->read(buf, bufsize);
00355 buf[bufsize]='\0';
00356 vcl_string write_string = vcl_string(buf);
00357 vcl_cerr << write_string << '\n';
00358 if (read_string != write_string) {
00359 vcl_cerr << "\nWrite failed!\n";
00360 error = true;
00361 }
00362 delete buf;
00363 vcl_cerr << "Testing get_value:\n";
00364 int mti_dp;
00365 if (!record->get_value("MTI_DP", mti_dp) || mti_dp!=2) {
00366 vcl_cerr << "Get value failed!\n";
00367 error = true;
00368 }
00369 else {
00370 vcl_cerr << "MTI_DP = " << mti_dp << '\n';
00371 }
00372 int tgt_speed[4];
00373 if (!record->get_value("TGT_n_SPEED", vil_nitf2_index_vector(0), tgt_speed[0]) ||
00374 tgt_speed[0] != 2222 ||
00375 record->get_value("TGT_n_SPEED", vil_nitf2_index_vector(1), tgt_speed[1]) ||
00376 !record->get_value("TGT_n_SPEED", vil_nitf2_index_vector(2), tgt_speed[2]) ||
00377 tgt_speed[2] != 4444) {
00378 vcl_cerr << "Get vector value test failed!\n";
00379 error = true;
00380 }
00381 else {
00382 vcl_cerr << "TGT_2_SPEED = " << tgt_speed[2] << '\n';
00383 }
00384 int d2;
00385 if (!record->get_value("D", vil_nitf2_index_vector(2), d2) || d2 != 9) {
00386 vcl_cerr << "Get fixed repeat count test failed!\n";
00387 error = true;
00388 }
00389
00390 vcl_cerr << "Testing get_values (all values)...\n";
00391 vcl_vector<vcl_string> c_values;
00392 if (!record->get_values("C", c_values) ||
00393 c_values.size() != 5 ||
00394 c_values[0]!="C000" ||
00395 c_values[1]!="C100" ||
00396 c_values[2]!="C101" ||
00397 c_values[3]!="C110" ||
00398 c_values[4]!="C111") {
00399 vcl_cerr << "failed!\n\n";
00400 error = true;
00401 }
00402
00403 vcl_cerr << "Get values (partial index)...\n";
00404 vil_nitf2_index_vector indexes;
00405 vcl_vector<int> a_values;
00406 indexes.push_back(1);
00407 if (!record->get_values("A", indexes, a_values) ||
00408 a_values.size() != 1 ||
00409 a_values[0] != 2) {
00410 vcl_cerr << "failed!\n\n";
00411 error = true;
00412 }
00413
00414 if (!record->get_values("C", indexes, c_values) ||
00415 c_values.size() != 4 ||
00416 c_values[0]!="C100" ||
00417 c_values[1]!="C101" ||
00418 c_values[2]!="C110" ||
00419 c_values[3]!="C111")
00420 {
00421 vcl_cerr << "failed!\n\n";
00422 }
00423 }
00424 else {
00425 vcl_cerr << "Didn't create record!\n";
00426 error = true;
00427 }
00428
00429 vcl_cerr << "Output of vector field C:\n"
00430 << *(record->get_field("C"));
00431
00432 if (!vil_nitf2_tagged_record_definition::undefine(test_tre_tag)) {
00433 vcl_cerr << "Error undefining TRE.\n";
00434 error = true;
00435 }
00436 return !error;
00437 }
00438
00439 vcl_ostream& vil_nitf2_tagged_record::output(vcl_ostream& os) const
00440 {
00441 os << "CETAG: " << name() << '\n'
00442 << "CELEN: " << length() << vcl_endl;
00443 for (vil_nitf2_field_definitions::iterator fieldNode = m_definition->m_field_definitions->begin();
00444 fieldNode != m_definition->m_field_definitions->end(); ++fieldNode)
00445 {
00446 vil_nitf2_field_definition* field_def = (*fieldNode)->field_definition();
00447
00448 if (!field_def) break;
00449 vil_nitf2_field* field = get_field(field_def->tag);
00450 os << field_def->tag << ": ";
00451 if (field) {
00452 os << *field << vcl_endl;
00453 }
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 }
00470 else return false;
00471
00472 m_field_sequence->write(output);
00473
00474 vil_streampos end = output.tell();
00475 vil_streampos length_written = end - start;
00476 int expected_length = s_tag_formatter().field_width + s_length_formatter().field_width
00477 + length();
00478 return length_written == expected_length;
00479 }
00480
00481 vil_nitf2_tagged_record::~vil_nitf2_tagged_record()
00482 {
00483 delete m_field_sequence;
00484 }
00485
00486 vil_nitf2_field_definition* vil_nitf2_field_sequence::find_field_definition(vcl_string tag)
00487 {
00488 for (vil_nitf2_field_definitions::const_iterator node = m_field_definitions->begin();
00489 node != m_field_definitions->end(); ++node)
00490 {
00491 vil_nitf2_field_definition* field_def = (*node)->field_definition();
00492
00493 if (!field_def) break;
00494
00495 if (field_def->tag == tag) {
00496 return field_def;
00497 }
00498 }
00499
00500 return 0;
00501 }
00502
00503 vil_nitf2_field::field_tree* vil_nitf2_tagged_record::get_tree() const
00504 {
00505
00506
00507
00508 vil_nitf2_field::field_tree* tr;
00509 if ( m_field_sequence ) {
00510 tr = m_field_sequence->get_tree();
00511 }
00512 else {
00513 tr = new vil_nitf2_field::field_tree;
00514 vil_nitf2_field::field_tree* skipped_node = new vil_nitf2_field::field_tree;
00515 skipped_node->columns.push_back( "CEDATA" );
00516 skipped_node->columns.push_back( "<skipped unknown TRE>" );
00517 tr->children.push_back( skipped_node );
00518 }
00519
00520
00521 tr->columns.push_back( name() );
00522 tr->columns.push_back( pretty_name() );
00523
00524 vil_nitf2_field::field_tree* first_child = new vil_nitf2_field::field_tree;
00525 first_child->columns.push_back( "CEL" );
00526 first_child->columns.push_back( "Extension Length" );
00527 vcl_stringstream len_stream;
00528 len_stream << length();
00529 first_child->columns.push_back( len_stream.str() );
00530 tr->children.insert( tr->children.begin(), first_child );
00531 return tr;
00532 }
00533
00534 vcl_ostream& operator << (vcl_ostream& os, const vil_nitf2_tagged_record& record)
00535 {
00536 return record.output(os);
00537 }
00538
00539
00540
00541 vcl_ostream& operator << (vcl_ostream& os, const vil_nitf2_tagged_record_sequence& seq)
00542 {
00543 os << seq.size() << " TRE's:" << vcl_endl;
00544 vil_nitf2_tagged_record_sequence::const_iterator it;
00545 for (it = seq.begin(); it != seq.end(); ++it) {
00546 os << *it << vcl_endl;
00547 }
00548 return os;
00549 }