00001 //: 00002 // \file 00003 // vil_nitf2: Written by Rob Radtke (rob@) and Harry Voorhees (hlv@) of 00004 // Stellar Science Ltd. Co. (stellarscience.com) for 00005 // Air Force Research Laboratory, 2005. 00006 00007 #ifndef VIL_NITF2_IMAGE_H 00008 #define VIL_NITF2_IMAGE_H 00009 00010 #include <vil/vil_blocked_image_resource.h> 00011 00012 #include <vcl_vector.h> 00013 #include <vcl_cassert.h> 00014 00015 #include <vil/vil_stream.h> 00016 00017 #include "vil_nitf2_image_subheader.h" 00018 #include "vil_nitf2_header.h" 00019 00020 #include <vil/vil_file_format.h> 00021 00022 class vil_nitf2_des; 00023 00024 class vil_nitf2_file_format : public vil_file_format 00025 { 00026 public: 00027 virtual char const *tag() const; 00028 virtual vil_image_resource_sptr make_input_image(vil_stream *vs); 00029 virtual vil_image_resource_sptr make_output_image(vil_stream* vs, 00030 unsigned nx, 00031 unsigned ny, 00032 unsigned nplanes, 00033 enum vil_pixel_format); 00034 }; 00035 00036 //: Class for reading NITF 2.1 imagery files. 00037 // It works just like any other vil_image_resource class except that it does 00038 // support retrieving multiple images from the same file. 00039 // Call nimages() to find out how many images are in this resource, and then call 00040 // set_current_image() to tell the class which image you want to work with presently. 00041 // All regular vil_image_resource functions will operate on the current image. 00042 // 00043 // You can access image header information through get_image_headers() and file 00044 // header information through get_header(). 00045 // 00046 // Known reading limitations: 00047 // - The only supported compression schemes are uncompressed (all 4 different 00048 // types of data layouts: band sequential, band interleaved, band interleaved 00049 // by row, and band interleaved by pixel) and JPEG 2000 compression (via plugin). 00050 // Other forms of compression do not work (eg. JPEG (regular, non-j2k) 00051 // - Writing is unsupported at this time 00052 // - graphic segments are not read in 00053 // - text segments are not read in 00054 // - The class was designed to handle images with PVTYPE=C (complex), but images of 00055 // this type are completely untested. 00056 // 00057 // Things that do work: 00058 // - Reading uncompressed and image data (ints, shorts, 8 bit int, floats etc) 00059 // - parsing and validating file headers, and image headers 00060 // - enum_data masks (and pad pixels) are supported through vil_nitf2_data_mask_table 00061 // - PJUST = L 00062 // - Images with LUTS will read in correctly, but you will need to apply the LUT 00063 // yourself. You can access the lut information for p-th band of the current image by calling 00064 // current_image_header()->get_lut_info(p, out_n_luts, out_ne_lut, out_lut_data) 00065 // - The class does not have built-in support for JPEG2000 compressed NITF files 00066 // Using cmake though, you can configure VXL to link against Er Mapper's freely 00067 // available ECW JPEG2000 SDK (http://ermapper.com/downloads/sdks.aspx#16). If you 00068 // do that, then this class will automatically be able to read NITF files that are 00069 // JPEG 2000 compressed. 00070 // 00071 class vil_nitf2_image : public vil_blocked_image_resource 00072 { 00073 public: 00074 //: Instantiate an image resource, but doesn't read anything. 00075 // You'll want to call parse_headers() before you do anything with me 00076 // (eg. before you ask for any image data). 00077 // If that returns false, then I am invalid and useless to you in every way. 00078 vil_nitf2_image( vil_stream* is ); 00079 vil_nitf2_image( const vcl_string& filePath, const char* mode ); 00080 00081 virtual ~vil_nitf2_image(); 00082 00083 //:return the image info of the current image 00084 virtual unsigned nplanes() const; 00085 virtual unsigned ni() const; 00086 virtual unsigned nj() const; 00087 virtual enum vil_pixel_format pixel_format () const; 00088 00089 //: Block size in columns 00090 virtual unsigned size_block_i() const; 00091 00092 //: Block size in rows 00093 virtual unsigned size_block_j() const; 00094 00095 //: Number of blocks in image width 00096 virtual unsigned n_block_i() const; 00097 00098 //: Number of blocks in image height 00099 virtual unsigned n_block_j() const; 00100 00101 //: returns "nitf vM.N" 00102 char const * file_format() const; 00103 00104 00105 // is the current image JPEG 2000 compressed 00106 bool is_jpeg_2000_compressed() const; 00107 00108 // This function is sort of a hack. It will return a decimated version 00109 // of the region specified by (i0,j0){i0+ni,j0+nj). It will be decimated by i_factorXj_factor. 00110 // That is the image returned will have size (ni/i_factor, nj/j_factor). 00111 // The reason this function is a hack is because it only works for jpeg 2000 compressed 00112 // NITF files (that is, is_jpeg_2000_compressed() returns true). You would normally want to use 00113 // vil_decimate_image_resource to obtain decimated images. That will work for jpeg2000 00114 // compressed NITF files too, but that class/function doesn't take advantage of the JPEG 2000 00115 // spec's built in optimization for obtaining decimated versions of large images. This function 00116 // does. Well, more accurately, it can. It depends on the implementation of the s_decode_jpeg_2000() 00117 // function you've provided. 00118 virtual vil_image_view_base_sptr get_copy_view_decimated_j2k( unsigned i0, unsigned ni, 00119 unsigned j0, unsigned nj, 00120 double i_factor, double j_factor ) const; 00121 virtual vil_image_view_base_sptr get_copy_view_decimated_j2k( double i_factor, double j_factor ) const 00122 { return get_copy_view_decimated_j2k( 0, ni(), 0, nj(), i_factor, j_factor ); } 00123 00124 virtual vil_image_view_base_sptr get_copy_view(unsigned i0, unsigned ni, 00125 unsigned j0, unsigned nj) const; 00126 virtual vil_image_view_base_sptr get_copy_view( ) const 00127 { return get_copy_view( 0, ni(), 0, nj() ); } 00128 00129 virtual bool put_view (const vil_image_view_base& /* im */, unsigned /* i0 */, unsigned /* j0 */ ) 00130 { return false; } 00131 00132 virtual bool put_block(unsigned /*block_index_i*/, unsigned /*block_index_j*/, 00133 const vil_image_view_base& /*blk*/ ) 00134 { return false; } 00135 00136 virtual vil_image_view_base_sptr get_block( unsigned int blockIndexX, unsigned int blockIndexY ) const; 00137 00138 virtual bool get_property (char const *tag, void *property_value=0) const; 00139 00140 //const vil_nitf2_header& getFileHeader() const; 00141 const vcl_vector< vil_nitf2_image_subheader* >& get_image_headers() const 00142 { return m_image_headers; } 00143 const vil_nitf2_header& get_header() const 00144 { return m_file_header; } 00145 const vcl_vector< vil_nitf2_des* >& get_des() const 00146 { return m_des; } 00147 00148 //: 00149 // Since the VIL API (eg. get_view()) for retrieving image data 00150 // doesn't support files with multiple images, clients will 00151 // need to call this function to tell get_view() which image to read in. 00152 // 00153 // Overloaded from vil_image_resource. The NITF 2.x file format does support 00154 // multiple images per file and you can use this API to access each and every 00155 // one of them. 00156 // 00157 // Note: By default, the first image is always used. If you don't call this 00158 // function at all, then you will only see the first image in a given file. 00159 virtual void set_current_image( unsigned int index ); 00160 virtual unsigned int current_image() const; 00161 virtual unsigned int nimages() const; 00162 00163 bool parse_headers(); 00164 vil_nitf2_classification::file_version file_version() const; 00165 00166 //: 00167 // All instances of vil_nitf2_image will use s_decode_jpeg_2000() to decode 00168 // JPEG 2000 streams if you set the function. If unset, then the library 00169 // will not be able to read JPEG 2000 compressed NITF files. 00170 // 00171 static vil_image_view_base_sptr ( *s_decode_jpeg_2000 )( vil_stream* vs, 00172 unsigned i0, unsigned ni, 00173 unsigned j0, unsigned nj, 00174 double i_factor, double j_factor ); 00175 00176 // I allocate the return value, but you own it after I return it to you 00177 // so you need to delete it. 00178 virtual vil_nitf2_field::field_tree* get_tree() const; 00179 00180 protected: 00181 virtual vil_image_view_base_sptr get_block_j2k( unsigned int blockIndexX, unsigned int blockIndexY ) const; 00182 virtual vil_image_view_base_sptr get_copy_view_uncompressed(unsigned i0, unsigned ni, 00183 unsigned j0, unsigned nj) const; 00184 00185 00186 // Returns the offset (in bytes) from the beginning of the NITF file 00187 // to the beginning of the specified portion of the NITF stream. For example: 00188 // 00189 // get_offset_to( enum_text_segments, Header, 0) will return the offset from the 00190 // beginning of the NITF stream to the beginning of the first text segment's 00191 // subheader. You'd better make sure there is at least one text segment before 00192 // you call this. 00193 // 00194 // get_offset_to( enum_image_segments, enum_data, 3) will return the offset from the 00195 // beginning of the NITF stream to the beginning of the fourth image segment's 00196 // data section. You'd better make sure there is at least four image segments before 00197 // you call this. 00198 vil_streampos get_offset_to( vil_nitf2_header::section_type sec, vil_nitf2_header::portion_type por, unsigned int index = 0 ) const; 00199 // Returns the offset (in bytes) from the beginning of section_type 'sec' and the beginning of the specified portion 00200 // (subheader or data). If more then one of these segments exist, then use 'index' to select which one you want. 00201 vil_streampos size_to( vil_nitf2_header::section_type sec, vil_nitf2_header::portion_type por, int index ) const; 00202 00203 // Returns the overall offset to the specified image/block/band combination. 00204 // If this block isn't present in the stream (ie. it's all blank), then 00205 // I'll return 0; 00206 vil_streampos get_offset_to_image_data_block_band( unsigned int imageIndex, 00207 unsigned int blockIndexX, 00208 unsigned int blockIndexY, 00209 int bandIndex ) const; 00210 00211 //main file header 00212 vil_nitf2_header m_file_header; 00213 //image header(s) 00214 vcl_vector< vil_nitf2_image_subheader* > m_image_headers; 00215 void clear_image_headers(); 00216 const vil_nitf2_image_subheader* current_image_header() const; 00217 //DESs (if any) 00218 vcl_vector< vil_nitf2_des* > m_des; 00219 void clear_des(); 00220 00221 vil_stream* m_stream; 00222 unsigned int m_current_image_index; 00223 }; 00224 00225 //: This function does a lot of work for \sa byte_align_data(). 00226 // It will strip one value of ni bits and return it as a value of type T 00227 // (with zero padding on the MSBs). 00228 // Both io and ni are lengths (in bits - not bytes). 00229 // 00230 // \param i0: Offset (in bits - not bytes) from in_val[0]. This will be the start 00231 // of the bits extracted from in_val. 00232 // \param ni: number of bits (starting from i0) that will be extracted from in_val. 00233 template< class T > 00234 T get_bits( const T* in_val, unsigned int i0, unsigned int ni ) 00235 { 00236 unsigned int sample_offset = i0 / ( sizeof(T)*8 ); 00237 unsigned int bit_offset = i0 % ( sizeof(T)*8 ); 00238 00239 unsigned int strip_left = bit_offset; 00240 int strip_right = ( sizeof( T ) * 8 ) - ( bit_offset + ni ); 00241 T temp = in_val[sample_offset]; 00242 if ( strip_left > 0 ){ 00243 //strip off the appropriate bits from the vcl_left (replacing them with zeros) 00244 temp = temp << strip_left; 00245 temp = temp >> strip_left; 00246 } 00247 if ( strip_right > 0 ){ 00248 //strip off the appropriate bits from the vcl_right 00249 //the bit shift operator wasn't having the correct effect, so that'w 00250 //why the for loop 00251 for ( int i = 0 ; i < strip_right ; i++ ) temp /= 2; 00252 //temp = temp >> strip_right; 00253 } 00254 else if ( strip_right < 0 ){ 00255 //we didn't have enough bits in the first element of the in_val array 00256 //need to get some from the next element 00257 for ( int i = 0 ; i < (-strip_right) ; i++ ) temp *= 2; 00258 temp += get_bits<T>( in_val+sample_offset+1, 0, -strip_right ); 00259 } 00260 return temp; 00261 } 00262 00263 //: This function will byte align the data in in_data and store the result in out_data. 00264 // For example, let's say that you had in_data is of type unsigned char 00265 // and contains the following data: 110010111001111010000110. 00266 // In other words: 00267 // in_data[0] = 203 (11001011) 00268 // in_data[1] = 158 (10011110) 00269 // in_data[2] = 134 (10000110) 00270 // Let's further say you called this function like this: byte_align_data( in_data, 8, 3, out_data ). 00271 // Then, when the function finished, out_data would look like this: 00272 // out_data[0] = 6 (00000110) 00273 // out_data[1] = 2 (00000010) 00274 // out_data[2] = 7 (00000111) 00275 // out_data[3] = 1 (00000001) 00276 // out_data[4] = 7 (00000111) 00277 // out_data[5] = 2 (00000010) 00278 // out_data[6] = 0 (00000000) 00279 // out_data[7] = 6 (00000110) 00280 // 00281 // Basically, what the function did was group the bitstream into groups of three and then store all of the 00282 // values into out_data. It had to zero pad all the values (on the MSB side) to get them into out_data. That's 00283 // why out_data is bigger. 00284 // 00285 // This function works with other unsigned types of data too. For example, let's say in_data was of type unsigned int 00286 // and contained the following bits: 0100110010111000 0111101100000000 1111000011110000 (note that this bitstream is shown 00287 // in big endian notation, that will not be the case if you are on a little endian machine -- this is just for illustration) 00288 // in other words: 00289 // in_data[0] = 19640 (0100110010111000) [shown in big endian for illustrative purposes only] 00290 // in_data[1] = 31488 (0111101100000000) [shown in big endian for illustrative purposes only] 00291 // in_data[2] = 61680 (1111000011110000) [shown in big endian for illustrative purposes only] 00292 // Let's further say, you called this function like this byte_align_data( in_data, 4, 12, out_data ). 00293 // Then out_data would be aligned along two byte (sixteen bit) boundaries and would look like this: 00294 // out_data[0] = 1227 (0000010011001011) [shown in big endian for illustrative purposes only] 00295 // out_data[1] = 2171 (0000100001111011) [shown in big endian for illustrative purposes only] 00296 // out_data[2] = 15 (0000000000001111) [shown in big endian for illustrative purposes only] 00297 // out_data[3] = 240 (0000000011110000) [shown in big endian for illustrative purposes only] 00298 // 00299 // Because of the fact that this function uses bit shifting operators, and the behavior of the vcl_right 00300 // shift operator is implementation specific when applied to a negative number, you should probably 00301 // only use this function on unsigned data. 00302 // 00303 // \param in_data: The input data. It must be at least (num_samples*in_bits_per_sample\8) bytes long. 00304 // The values should have the endianness of your platform. 00305 // \param num_samples: The number of actual samples in in_data. 00306 // \param in_bits_per_sample: The bits per sample in in_data 00307 // \param out_data: I'll store the output data here. It must be at least (num_samples*sizeof(T)) bytes long 00308 // The values will have the endianness of your platform. 00309 // 00310 // Note that inBitsPerSampe must not be >= sizeof(T). If they were to be equal, then this function 00311 // would have nothing to do (in_data is already byte aligned). If in_bits_per_sample were less than sizeof(T), 00312 // then each element of out_data would be too small to store the corresponding elements in in_data. 00313 // 00314 // Note that there is a specialization for the bool case which just casts it to an 8 bit quantity then calls 00315 // this same function. This is because the logic in get_bits<> doesn't work for the bool case. 00316 template< class T > 00317 T* byte_align_data( T* in_data, unsigned int num_samples, unsigned int in_bits_per_sample, T* out_data ) 00318 { 00319 assert( in_bits_per_sample < sizeof(T)*8 ); 00320 00321 //grab each value from the bitstream (in_data) that we need... one at a time 00322 unsigned int bit_offset = 0; 00323 for ( unsigned int o = 0 ; o < num_samples ; o++ ){ 00324 out_data[o] = get_bits<T>( in_data, bit_offset, in_bits_per_sample ); 00325 bit_offset+=in_bits_per_sample; 00326 } 00327 00328 return out_data; 00329 } 00330 00331 template<> bool* byte_align_data<bool>( bool* in_data, unsigned int num_samples, unsigned int in_bits_per_sample, bool* out_data ); 00332 00333 #endif // VIL_NITF2_IMAGE_H