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