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