00001
00002
00003
00004
00005 #include "vil_nitf2_image.h"
00006
00007
00008
00009
00010 #include <vcl_cassert.h>
00011 #include <vcl_cstring.h>
00012 #include <vcl_algorithm.h>
00013 #include <vil/vil_stream_fstream.h>
00014 #include <vil/vil_image_view.h>
00015 #include <vil/vil_property.h>
00016 #include "vil_nitf2_data_mask_table.h"
00017 #include "vil_nitf2_des.h"
00018
00019 #if HAS_J2K
00020 #include "vil_j2k_image.h"
00021 #endif //HAS_J2K
00022
00023 int debug_level = 0;
00024
00025
00026
00027
00028 static char const nitf2_string[] = "nitf";
00029
00030 char const* vil_nitf2_file_format::tag() const
00031 {
00032 return nitf2_string;
00033 }
00034
00035 vil_image_resource_sptr vil_nitf2_file_format::make_input_image(vil_stream *vs)
00036 {
00037 vil_nitf2_image* im = new vil_nitf2_image( vs );
00038 if ( !im->parse_headers() ) {
00039 delete im;
00040 im = 0;
00041 }
00042 return im;
00043 }
00044
00045 vil_image_resource_sptr
00046 vil_nitf2_file_format::make_output_image(vil_stream* ,
00047 unsigned ,
00048 unsigned ,
00049 unsigned ,
00050 enum vil_pixel_format )
00051 {
00052
00053 return 0;
00054 }
00055
00056
00057
00058
00059 vil_streampos vil_nitf2_image::get_offset_to( vil_nitf2_header::section_type sec,
00060 vil_nitf2_header::portion_type por,
00061 unsigned int index ) const
00062 {
00063 vil_streampos p;
00064 if ( sec == vil_nitf2_header::enum_file_header ) {
00065
00066
00067 assert( por == vil_nitf2_header::enum_subheader );
00068 assert( index == 0 );
00069
00070 p = 0;
00071 } else {
00072 vil_nitf2_header::section_type preceding_section = (vil_nitf2_header::section_type)(sec-1);
00073 p = get_offset_to( preceding_section, vil_nitf2_header::enum_subheader, 0 ) +
00074 size_to( preceding_section, vil_nitf2_header::enum_subheader, -1 ) +
00075 size_to( sec, por, index );
00076 }
00077 return p;
00078 }
00079
00080 vil_streampos vil_nitf2_image::size_to(vil_nitf2_header::section_type sec,
00081 vil_nitf2_header::portion_type por,
00082 int index ) const
00083 {
00084 if ( sec == vil_nitf2_header::enum_file_header ) {
00085 if ( index == -1 ) {
00086 int file_header_size;
00087 m_file_header.get_property("HL", file_header_size);
00088 return (vil_streampos)file_header_size;
00089 } else {
00090 return 0;
00091 }
00092 }
00093
00094 vil_streampos offset = 0;
00095
00096
00097 bool going_past_end = false;
00098 if ( index == -1 ) {
00099 int num_segments;
00100 m_file_header.get_property(vil_nitf2_header::section_num_tag(sec), num_segments);
00101 index = num_segments;
00102 going_past_end = true;
00103 }
00104 vcl_string sh = vil_nitf2_header::section_len_header_tag( sec );
00105 vcl_string s = vil_nitf2_header::section_len_data_tag( sec );
00106 int i;
00107 for (i = 0 ; i < index ; i++) {
00108 int current_header_size;
00109 m_file_header.get_property(sh, i, current_header_size);
00110 offset += current_header_size;
00111 if ( sec == vil_nitf2_header::enum_image_segments ){
00112 vil_nitf2_long current_data_size;
00113 m_file_header.get_property(s, i, current_data_size);
00114 offset += current_data_size;
00115 } else {
00116 int current_data_size;
00117 m_file_header.get_property(s, i, current_data_size);
00118 offset += current_data_size;
00119 }
00120 }
00121
00122
00123 if ( por == vil_nitf2_header::enum_data ) {
00124
00125
00126 if ( going_past_end ) { assert(!"skipped past all segments"); return 0L; }
00127 int current_header_size;
00128 m_file_header.get_property(sh, i, current_header_size);
00129 offset += current_header_size;
00130 }
00131 return offset;
00132 }
00133
00134 vil_image_view_base_sptr ( *vil_nitf2_image::s_decode_jpeg_2000 )
00135 ( vil_stream* vs, unsigned i0, unsigned ni, unsigned j0, unsigned nj, double i_factor, double j_factor ) = 0;
00136
00137 vil_nitf2_image::vil_nitf2_image(vil_stream* is)
00138 : m_stream(is),
00139 m_current_image_index(0)
00140 {
00141 m_stream->ref();
00142 }
00143
00144 vil_nitf2_image::vil_nitf2_image(const vcl_string& filePath, const char* mode)
00145 : m_current_image_index(0)
00146 {
00147 #ifdef VIL_USE_FSTREAM64
00148 m_stream = new vil_stream_fstream64(filePath.c_str(), mode);
00149 #else //VIL_USE_FSTREAM64
00150 m_stream = new vil_stream_fstream(filePath.c_str(), mode);
00151 #endif //VIL_USE_FSTREAM64
00152 m_stream->ref();
00153 }
00154
00155 void vil_nitf2_image::clear_image_headers()
00156 {
00157 for (unsigned int i = 0 ; i < m_image_headers.size() ; i++) {
00158 delete m_image_headers[i];
00159 }
00160 m_image_headers.clear();
00161 }
00162
00163 void vil_nitf2_image::clear_des()
00164 {
00165 for (unsigned int i = 0 ; i < m_des.size() ; i++) {
00166 delete m_des[i];
00167 }
00168 m_des.clear();
00169 }
00170
00171
00172 vil_nitf2_image::~vil_nitf2_image()
00173 {
00174 m_stream->unref();
00175 clear_image_headers();
00176 clear_des();
00177 }
00178
00179 unsigned int vil_nitf2_image::current_image() const
00180 {
00181 return m_current_image_index;
00182 }
00183
00184 void vil_nitf2_image::set_current_image(unsigned int index)
00185 {
00186 assert(index < m_image_headers.size());
00187 m_current_image_index = index;
00188 }
00189
00190 unsigned int vil_nitf2_image::nimages() const
00191 {
00192 int num_images;
00193 if (m_file_header.get_property("NUMI", num_images)) return num_images;
00194 else return 0;
00195 }
00196
00197 vil_streampos vil_nitf2_image::get_offset_to_image_data_block_band(
00198 unsigned int image_index, unsigned int block_index_x,unsigned int block_index_y, int bandIndex) const
00199 {
00200
00201 vcl_string i_mode;
00202 current_image_header()->get_property("IMODE", i_mode);
00203
00204
00205
00206 vil_streampos offset =
00207 get_offset_to( vil_nitf2_header::enum_image_segments, vil_nitf2_header::enum_data, image_index );
00208
00209
00210
00211
00212 int bits_per_pixel_per_band;
00213 current_image_header()->get_property("NBPP", bits_per_pixel_per_band);
00214
00215 #if 0 //Not valid if blocks are partially filled (JLM 11/03/07)
00216 unsigned int bytes_per_band = ni() * nj() * bits_per_pixel_per_band / 8;
00217 #endif
00218
00219 unsigned int nbi = n_block_i(), nbj = n_block_j();
00220 unsigned int sbi = size_block_i(), sbj = size_block_j();
00221 unsigned int bytes_per_band = nbi*nbj*sbi*sbj*bits_per_pixel_per_band/8;
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 const vil_nitf2_data_mask_table* data_mask_table = current_image_header()->data_mask_table();
00235 if (data_mask_table) {
00236 offset += data_mask_table->blocked_image_data_offset();
00237 }
00238 if (data_mask_table && data_mask_table->has_offset_table()) {
00239
00240 int bI = i_mode == "S" ? bandIndex : -1;
00241 if (data_mask_table->block_band_present(block_index_x, block_index_y, bI))
00242 {
00243 return 0;
00244 }
00245 offset += data_mask_table->block_band_offset(block_index_x, block_index_y, bI);
00246 } else {
00247 unsigned int pixels_per_block = size_block_i() * size_block_j();
00248 unsigned int bits_per_band = pixels_per_block * bits_per_pixel_per_band;
00249 unsigned int bytes_per_block_per_band = bits_per_band / 8;
00250
00251
00252 if (bits_per_band % 8 != 0) bytes_per_block_per_band++;
00253 if (i_mode == "S") {
00254
00255 unsigned int offset_to_desired_band = bandIndex * bytes_per_band;
00256 unsigned int offset_to_desired_block = bytes_per_block_per_band * (block_index_y * n_block_i() + block_index_x);
00257 offset += offset_to_desired_band + offset_to_desired_block;
00258 } else {
00259
00260 unsigned int block_size_bytes = bytes_per_block_per_band * nplanes();
00261 unsigned int offset_to_desired_block = block_size_bytes * (block_index_y * n_block_i() + block_index_x);
00262 offset += offset_to_desired_block;
00263 }
00264 }
00265 if (i_mode != "S") {
00266
00267
00268
00269 unsigned int offset_to_desired_band = bandIndex * bytes_per_band;
00270 offset += offset_to_desired_band;
00271 }
00272 return offset;
00273 }
00274
00275 bool vil_nitf2_image::parse_headers()
00276 {
00277 if (!m_stream->ok()) return false;
00278
00279 m_stream->seek(0);
00280 if (!m_file_header.read(m_stream)) {
00281 return false;
00282 }
00283
00284 clear_image_headers();
00285 m_image_headers.resize(nimages());
00286 for (unsigned int i = 0 ; i < nimages() ; i++) {
00287 vil_streampos offset = get_offset_to( vil_nitf2_header::enum_image_segments, vil_nitf2_header::enum_subheader, i);
00288 m_stream->seek(offset);
00289 m_image_headers[i] = new vil_nitf2_image_subheader(file_version());
00290 if (!m_image_headers[i]->read(m_stream)) return false;
00291 }
00292
00293
00294 clear_des();
00295 int num_des;
00296 m_file_header.get_property( "NUMDES", num_des );
00297 m_des.resize( num_des );
00298 for ( int j = 0 ; j < num_des ; j++ ){
00299 vil_streampos offset = get_offset_to( vil_nitf2_header::enum_data_extension_segments, vil_nitf2_header::enum_subheader, j);
00300 m_stream->seek(offset);
00301 int data_width;
00302 m_file_header.get_property( "LD", j, data_width );
00303 m_des[j] = new vil_nitf2_des(file_version(), data_width);
00304 if (!m_des[j]->read(m_stream)) return false;
00305 }
00306 return true;
00307 }
00308
00309 vil_nitf2_classification::file_version vil_nitf2_image::file_version() const
00310 {
00311 return m_file_header.file_version();
00312 }
00313
00314 char const * vil_nitf2_image::file_format() const
00315 {
00316 vil_nitf2_classification::file_version v = file_version();
00317 switch (v)
00318 {
00319 case vil_nitf2_classification::V_UNKNOWN :
00320 return "unknown";
00321 case vil_nitf2_classification::V_NITF_10 :
00322 return "nitf10";
00323 case vil_nitf2_classification::V_NITF_20 :
00324 return "nitf20";
00325 case vil_nitf2_classification::V_NITF_21 :
00326 return "nitf21";
00327 default:
00328 return "unknown";
00329 }
00330 }
00331
00332 const vil_nitf2_image_subheader* vil_nitf2_image::current_image_header() const
00333 {
00334 assert(m_current_image_index < m_image_headers.size());
00335 return m_image_headers[ m_current_image_index ];
00336 }
00337
00338 unsigned vil_nitf2_image::nplanes() const
00339 {
00340 return current_image_header()->nplanes();
00341 }
00342
00343 unsigned vil_nitf2_image::ni() const
00344 {
00345
00346
00347
00348
00349 int num_significant_cols;
00350 if (current_image_header()->get_property("NCOLS", num_significant_cols))
00351 {
00352 return num_significant_cols;
00353 }
00354 return 0;
00355 }
00356
00357 unsigned vil_nitf2_image::nj() const
00358 {
00359
00360
00361
00362
00363 int num_significant_rows;
00364 if (current_image_header()->get_property("NROWS", num_significant_rows))
00365 {
00366 return num_significant_rows;
00367 }
00368 return 0;
00369 }
00370
00371 enum vil_pixel_format vil_nitf2_image::pixel_format () const
00372 {
00373 vcl_string pixel_type;
00374 int bits_per_pixel;
00375 if (current_image_header()->get_property("PVTYPE", pixel_type) &&
00376 current_image_header()->get_property("NBPP", bits_per_pixel))
00377 {
00378
00379 int bytesPerPixel = bits_per_pixel / 8;
00380 if (bits_per_pixel % 8 != 0) bytesPerPixel++;
00381 bits_per_pixel = bytesPerPixel * 8;
00382 if (pixel_type == "INT") {
00383 if (bits_per_pixel == 8) {
00384 return VIL_PIXEL_FORMAT_BYTE;
00385 } else if (bits_per_pixel == 16) {
00386 return VIL_PIXEL_FORMAT_UINT_16;
00387 } else if (bits_per_pixel == 32) {
00388 return VIL_PIXEL_FORMAT_UINT_32;
00389 }
00390 #if VXL_HAS_INT_64
00391 else if (bits_per_pixel == 64) {
00392 return VIL_PIXEL_FORMAT_UINT_64;
00393 }
00394 #endif //VXL_HAS_INT_64
00395 } else if (pixel_type == "B") {
00396 return VIL_PIXEL_FORMAT_BOOL;
00397 } else if (pixel_type == "SI") {
00398 if (bits_per_pixel == 8) {
00399 return VIL_PIXEL_FORMAT_SBYTE;
00400 } else if (bits_per_pixel == 16) {
00401 return VIL_PIXEL_FORMAT_INT_16;
00402 } else if (bits_per_pixel == 32) {
00403 return VIL_PIXEL_FORMAT_INT_32;
00404 }
00405 #if VXL_HAS_INT_64
00406 else if (bits_per_pixel == 64) {
00407 return VIL_PIXEL_FORMAT_INT_64;
00408 }
00409 #endif //VXL_HAS_INT_64
00410 } else if (pixel_type == "R") {
00411 if (bits_per_pixel == 32) {
00412 return VIL_PIXEL_FORMAT_FLOAT;
00413 } else if (bits_per_pixel == 64) {
00414 return VIL_PIXEL_FORMAT_DOUBLE;
00415 }
00416 } else if (pixel_type == "C") {
00417
00418 if (bits_per_pixel == 64) {
00419 return VIL_PIXEL_FORMAT_COMPLEX_FLOAT;
00420 }
00421
00422
00423 }
00424 }
00425 return VIL_PIXEL_FORMAT_UNKNOWN;
00426 }
00427
00428 unsigned int vil_nitf2_image::size_block_i() const
00429 {
00430 return current_image_header()->get_pixels_per_block_x();
00431 }
00432
00433 unsigned int vil_nitf2_image::size_block_j() const
00434 {
00435 return current_image_header()->get_pixels_per_block_y();
00436 }
00437
00438 unsigned int vil_nitf2_image::n_block_i() const
00439 {
00440 return current_image_header()->get_num_blocks_x();
00441 }
00442
00443 unsigned int vil_nitf2_image::n_block_j() const
00444 {
00445 return current_image_header()->get_num_blocks_y();
00446 }
00447
00448 void compute_block_and_offset(unsigned j0, unsigned long block_size,
00449 unsigned int& block, unsigned int& offset)
00450 {
00451 block = 0;
00452 offset = 0;
00453
00454 if (j0 != 0) {
00455 block = (j0 / block_size);
00456 if (j0 > 0 && j0 % block_size != 0) {
00457 offset = j0 - (block * block_size);
00458 }
00459 }
00460 }
00461
00462 bool vil_nitf2_image::is_jpeg_2000_compressed() const
00463 {
00464 vcl_string compression_type;
00465
00466
00467
00468 return ( current_image_header()->get_property("IC", compression_type) ) &&
00469 ( compression_type == "C8" || compression_type == "M8" );
00470 }
00471
00472 vil_image_view_base_sptr vil_nitf2_image::get_copy_view_decimated_j2k(
00473 unsigned start_i, unsigned num_i, unsigned start_j, unsigned num_j, double i_factor, double j_factor ) const
00474 {
00475
00476 if ((start_i + num_i > ni()) || (start_j + num_j > nj())) {
00477 return 0;
00478 }
00479 assert( is_jpeg_2000_compressed() );
00480 if ( ! s_decode_jpeg_2000 ) {
00481 #if HAS_J2K
00482 s_decode_jpeg_2000 = vil_j2k_image::s_decode_jpeg_2000;
00483 #else //HAS_J2K
00484 return 0;
00485 #endif //HAS_J2K
00486 }
00487
00488
00489
00490
00491 m_stream->seek(get_offset_to( vil_nitf2_header::enum_image_segments, vil_nitf2_header::enum_data, m_current_image_index));
00492 return s_decode_jpeg_2000( m_stream, start_i, num_i, start_j, num_j, i_factor, j_factor );
00493 }
00494
00495 vil_image_view_base_sptr vil_nitf2_image::get_copy_view(unsigned start_i, unsigned num_i,
00496 unsigned start_j, unsigned num_j) const
00497 {
00498
00499 if ((start_i + num_i > ni()) || (start_j + num_j > nj())) {
00500 return 0;
00501 }
00502
00503 vcl_string compression_type;
00504 if (!current_image_header()->get_property("IC", compression_type)) return 0;
00505
00506
00507 if (compression_type == "NC" || compression_type == "NM") {
00508 return get_copy_view_uncompressed(start_i, num_i, start_j, num_j);
00509 } else if ( is_jpeg_2000_compressed() ) {
00510 return get_copy_view_decimated_j2k( start_i, num_i, start_j, num_j, 1.0, 1.0 );
00511 } else {
00512 return 0;
00513 }
00514 }
00515
00516 vil_image_view_base_sptr vil_nitf2_image::get_copy_view_uncompressed(unsigned start_i, unsigned num_i,
00517 unsigned start_j, unsigned num_j) const
00518 {
00519 return vil_blocked_image_resource::get_copy_view(start_i, num_i, start_j, num_j);
00520 }
00521
00522 template< class T >
00523 vil_memory_chunk_sptr maybe_byte_align_data(vil_memory_chunk_sptr in_data, unsigned int num_samples,
00524 unsigned int in_bits_per_sample, T )
00525 {
00526 if (in_bits_per_sample != sizeof(T)*8) {
00527 vil_memory_chunk_sptr new_memory = new vil_memory_chunk(num_samples*sizeof(T), in_data->pixel_format());
00528 byte_align_data((T*)in_data->data(), num_samples, in_bits_per_sample, (T*)new_memory->data());
00529 return new_memory;
00530 }
00531 return in_data;
00532 }
00533
00534
00535 template<> vil_memory_chunk_sptr maybe_byte_align_data<float> (
00536 vil_memory_chunk_sptr in_data, unsigned int , unsigned int , float )
00537 { return in_data; }
00538
00539 template<> vil_memory_chunk_sptr maybe_byte_align_data<double> (
00540 vil_memory_chunk_sptr in_data, unsigned int , unsigned int , double )
00541 { return in_data; }
00542
00543 template<> vil_memory_chunk_sptr maybe_byte_align_data< vcl_complex< float > > (
00544 vil_memory_chunk_sptr in_data, unsigned int , unsigned int , vcl_complex<float> )
00545 { return in_data; }
00546
00547
00548
00549
00550
00551
00552
00553
00554 template< class T >
00555 void right_justify(T* data, unsigned int num_samples, unsigned int bitsToMove)
00556 {
00557 for (unsigned int i = 0 ; i < num_samples ; i++) {
00558 data[i] = data[i] >> bitsToMove;
00559 }
00560 }
00561
00562
00563 template<> void right_justify<bool>(bool* , unsigned int , unsigned int ) {}
00564 template<> void right_justify<float>(float* , unsigned int , unsigned int ) {}
00565 template<> void right_justify<double>(double* , unsigned int , unsigned int ) {}
00566 template<> void right_justify< vcl_complex< float > >(vcl_complex< float >* , unsigned int ,
00567 unsigned int ) {}
00568
00569 template< class T >
00570 unsigned int get_index(T in_val)
00571 { return (T)in_val; }
00572
00573 template<> unsigned int get_index<bool>(bool in_val)
00574 { return in_val ? 1 : 0; }
00575
00576 template< class T >
00577 vil_image_view_base_sptr get_block_vcl_internal(vil_pixel_format pix_format, vil_memory_chunk_sptr image_memory,
00578 unsigned int pixels_per_block_x, unsigned int pixels_per_block_y,
00579 unsigned int nplanes,
00580 unsigned int i_step, unsigned int j_step, unsigned int plane_step,
00581 bool need_to_right_justify,
00582 unsigned int extra_bits, unsigned int bits_per_pixel_per_band,
00583 bool data_is_all_blank, const vil_nitf2_image_subheader* , T dummy)
00584 {
00585
00586 unsigned int num_samples = pixels_per_block_x * pixels_per_block_y * nplanes;
00587
00588 if (data_is_all_blank) {
00589
00590 T* data_ptr = reinterpret_cast<T*>(image_memory->data());
00591 for (unsigned int i = 0 ;
00592 i < pixels_per_block_x * pixels_per_block_y * nplanes ;
00593 i++)
00594 {
00595 data_ptr[i] = (T)0;
00596 }
00597 } else {
00598
00599
00600 if (need_to_right_justify)
00601 right_justify<T>(static_cast<T*>(image_memory->data()), image_memory->size()/sizeof(T), extra_bits);
00602
00603 vil_nitf2_data_mask_table::maybe_endian_swap(static_cast< char* >(image_memory->data()), image_memory->size(), pix_format);
00604
00605
00606 image_memory = maybe_byte_align_data(image_memory, num_samples, bits_per_pixel_per_band, dummy);
00607 }
00608
00609 vil_image_view< T >* result =
00610 new vil_image_view< T > (image_memory, reinterpret_cast<T*>(image_memory->data()),
00611 pixels_per_block_x, pixels_per_block_y, nplanes, i_step, j_step, plane_step);
00612
00613 return result;
00614 }
00615
00616 vil_image_view_base_sptr vil_nitf2_image::get_block_j2k( unsigned int blockIndexX, unsigned int blockIndexY ) const
00617 {
00618 if( ! is_jpeg_2000_compressed() ) return 0;
00619 if( blockIndexX >= n_block_i() ) return 0;
00620 if( blockIndexY >= n_block_j() ) return 0;
00621
00622
00623
00624
00625
00626 unsigned int i0 = vcl_min( blockIndexX * size_block_i(), ni() );
00627 unsigned int num_i = vcl_min( size_block_i(), ni() - i0 );
00628 unsigned int j0 = vcl_min( blockIndexY * size_block_j(), nj() );
00629 unsigned int num_j = vcl_min( size_block_j(), nj() - j0 );
00630 return get_copy_view( i0, num_i, j0, num_j );
00631 }
00632
00633 vil_image_view_base_sptr vil_nitf2_image::get_block(unsigned int block_index_x, unsigned int block_index_y) const
00634 {
00635 if (pixel_format() == VIL_PIXEL_FORMAT_UNKNOWN) return 0;
00636
00637 if( is_jpeg_2000_compressed() ){
00638 return get_block_j2k( block_index_x, block_index_y );
00639 }
00640
00641 vcl_string image_mode_type;
00642 if (!current_image_header()->get_property("IMODE", image_mode_type)) return 0;
00643
00644
00645 int bits_per_pixel_per_band, actualBitsPerPixelPerBand;
00646 vcl_string bitJustification;
00647 if (!current_image_header()->get_property("NBPP", bits_per_pixel_per_band) ||
00648 !current_image_header()->get_property("ABPP", actualBitsPerPixelPerBand) ||
00649 !current_image_header()->get_property("PJUST", bitJustification)) {
00650 return 0;
00651 }
00652 int extra_bits = bits_per_pixel_per_band - actualBitsPerPixelPerBand;
00653 bool need_to_right_justify = bitJustification == "L" && (extra_bits > 0);
00654
00655
00656
00657
00658
00659 unsigned int pixels_per_block = size_block_i() * size_block_j();
00660 unsigned int bits_per_band = pixels_per_block * bits_per_pixel_per_band;
00661 unsigned int bytes_per_block_per_band = bits_per_band / 8;
00662 if (bits_per_band % 8 != 0) bytes_per_block_per_band++;
00663 unsigned int block_size_bytes = bytes_per_block_per_band * nplanes();
00664
00665 vil_memory_chunk_sptr image_memory = new vil_memory_chunk(block_size_bytes, pixel_format());
00666
00667
00668 unsigned int i_step(0), j_step(0), plane_step(0);
00669 bool data_is_all_blank = false;
00670 if (image_mode_type == "S") {
00671 #if 0 // NOT USED
00672 unsigned int bytes_per_band = ni() * nj() * bits_per_pixel_per_band / 8;
00673 unsigned int offset_to_desired_block = bytes_per_block_per_band * (block_index_y * n_block_i() + block_index_x);
00674 #endif // 0
00675
00676 for (unsigned int i = 0 ; i < nplanes() ; i++) {
00677 vil_streampos current_offset = get_offset_to_image_data_block_band(m_current_image_index, block_index_x, block_index_y, i);
00678 if (current_offset == 0) {
00679
00680 data_is_all_blank = true;
00681 } else {
00682 m_stream->seek(current_offset);
00683 char* position_to_read_to = static_cast<char*>(image_memory->data());
00684 position_to_read_to += i*bytes_per_block_per_band;
00685 if (m_stream->read((void*)position_to_read_to, bytes_per_block_per_band) != static_cast<int>(bytes_per_block_per_band)) {
00686 return 0;
00687 }
00688 }
00689 }
00690 i_step = 1;
00691 j_step = size_block_i();
00692 plane_step = size_block_i() * size_block_j();
00693 } else {
00694
00695 vil_streampos current_offset = get_offset_to_image_data_block_band(m_current_image_index, block_index_x, block_index_y, 0);
00696 if (current_offset == 0) {
00697
00698 data_is_all_blank = true;
00699 } else {
00700
00701 m_stream->seek(current_offset);
00702
00703 if (m_stream->read(image_memory->data(), block_size_bytes) != static_cast<int>(block_size_bytes)) {
00704 return 0;
00705 }
00706 }
00707
00708
00709 if (image_mode_type == "B") {
00710
00711 i_step = 1;
00712 j_step = size_block_i();
00713 plane_step = size_block_i() * size_block_j();
00714 } else if (image_mode_type == "P") {
00715
00716 i_step = nplanes();
00717 j_step = nplanes() * size_block_i();
00718 plane_step = 1;
00719 } else if (image_mode_type == "R") {
00720
00721 i_step = 1;
00722 j_step = nplanes() * size_block_i();
00723 plane_step = size_block_i();
00724 }
00725 }
00726
00727
00728 vil_image_view_base_sptr view = 0;
00729 switch (vil_pixel_format_component_format(image_memory->pixel_format()))
00730 {
00731 #define GET_BLOCK_CASE(FORMAT, T)\
00732 case FORMAT:{ \
00733 T t= (T)0; \
00734 return get_block_vcl_internal(\
00735 FORMAT, image_memory, size_block_i(),size_block_j(), nplanes(),\
00736 i_step, j_step, plane_step, need_to_right_justify, extra_bits, bits_per_pixel_per_band,\
00737 data_is_all_blank, current_image_header(), t);\
00738 } break
00739
00740 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_BYTE, vxl_byte);
00741 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte);
00742
00743 #if VXL_HAS_INT_64
00744 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_64, vxl_uint_64);
00745 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_64, vxl_int_64);
00746 #endif
00747 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32);
00748 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_32, vxl_int_32);
00749 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_16, vxl_uint_16);
00750 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_16, vxl_int_16);
00751 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_BOOL, bool);
00752 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_FLOAT, float);
00753 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_DOUBLE, double);
00754 GET_BLOCK_CASE(VIL_PIXEL_FORMAT_COMPLEX_FLOAT, vcl_complex<float>);
00755 #undef GET_BLOCK_CASE
00756
00757 default:
00758 assert(!"Unknown vil data type.");
00759 break;
00760 }
00761 return view;
00762 }
00763
00764 template<> bool* byte_align_data<bool>(bool* in_data, unsigned int num_samples, unsigned int in_bits_per_sample, bool* out_data)
00765 {
00766 switch (sizeof(bool))
00767 {
00768 case 1:
00769 byte_align_data((vxl_byte*)in_data, num_samples, in_bits_per_sample, (vxl_byte*)out_data);
00770 break;
00771 case 2:
00772 byte_align_data((vxl_uint_16*)in_data, num_samples, in_bits_per_sample, (vxl_uint_16*)out_data);
00773 break;
00774 case 4:
00775 byte_align_data((vxl_uint_32*)in_data, num_samples, in_bits_per_sample, (vxl_uint_32*)out_data);
00776 break;
00777 #if VXL_HAS_INT_64
00778 case 8:
00779 byte_align_data((vxl_uint_64*)in_data, num_samples, in_bits_per_sample, (vxl_uint_64*)out_data);
00780 break;
00781 #endif //VXL_HAS_INT_64
00782 default:
00783 assert(!"Unsupported size of bool.");
00784 }
00785
00786 #if 0
00787
00788 vcl_cout << "\nBools: ";
00789 for (unsigned int i = 0 ; i < num_samples ; i++) {
00790 vcl_cout << (out_data[i] ? '1' : '0');
00791 }
00792 vcl_cout << vcl_endl;
00793 #endif //0
00794 return out_data;
00795 }
00796
00797 bool vil_nitf2_image::get_property (char const *tag, void *property_value) const
00798 {
00799 if (vcl_strcmp(vil_property_size_block_i, tag)==0)
00800 {
00801 if (property_value)
00802 *static_cast<unsigned*>(property_value) = this->size_block_i();
00803 return true;
00804 }
00805
00806 if (vcl_strcmp(vil_property_size_block_j, tag)==0)
00807 {
00808 if (property_value)
00809 *static_cast<unsigned*>(property_value) = this->size_block_j();
00810 return true;
00811 }
00812 vcl_string result;
00813 if (m_file_header.get_property(tag, result) ||
00814 (current_image_header() && current_image_header()->get_property(tag, result)))
00815 {
00816 property_value = malloc(result.size());
00817 vcl_memcpy(property_value, result.c_str(), result.size());
00818 return true;
00819 }
00820 return false;
00821 }
00822
00823 vil_nitf2_field::field_tree* vil_nitf2_image::get_tree( ) const
00824 {
00825 vil_nitf2_field::field_tree* t = new vil_nitf2_field::field_tree;
00826 t->columns.push_back( "NITF File" );
00827 t->children.push_back( get_header().get_tree() );
00828 unsigned int i;
00829 for ( i = 0 ; i < m_image_headers.size() ; i++ ){
00830 t->children.push_back( m_image_headers[i]->get_tree(i+1) );
00831 }
00832 for ( i = 0 ; i < m_des.size() ; i++ ){
00833 t->children.push_back( m_des[i]->get_tree(i+1) );
00834 }
00835 return t;
00836 }
00837