1 //:
2 // \file
3 // vil_nitf2: Written by Rob Radtke (rob@) and Harry Voorhees (hlv@) of
4 // Stellar Science Ltd. Co. (stellarscience.com) for
5 // Air Force Research Laboratory, 2005.
6 
7 #ifndef VIL_NITF2_IMAGE_H
8 #define VIL_NITF2_IMAGE_H
9 
10 #include <vector>
11 #include <vil/vil_blocked_image_resource.h>
12 
13 #ifdef _MSC_VER
14 #  include <vcl_msvc_warnings.h>
15 #endif
16 #include <cassert>
17 
18 #include <vil/vil_stream.h>
19 
20 #include "vil_nitf2_image_subheader.h"
21 #include "vil_nitf2_header.h"
22 
23 #include <vil/vil_file_format.h>
24 
25 class vil_nitf2_des;
26 
27 class vil_nitf2_file_format : public vil_file_format
28 {
29  public:
30   char const *tag() const override;
31   vil_image_resource_sptr make_input_image(vil_stream *vs) override;
32   vil_image_resource_sptr make_output_image(vil_stream* vs,
33                                                     unsigned nx,
34                                                     unsigned ny,
35                                                     unsigned nplanes,
36                                                     enum vil_pixel_format) override;
37 };
38 
39 //: Class for reading NITF 2.1 imagery files.
40 // It works just like any other vil_image_resource class except that it does
41 // support retrieving multiple images from the same file.
42 // Call nimages() to find out how many images are in this resource, and then call
43 // set_current_image() to tell the class which image you want to work with presently.
44 // All regular vil_image_resource functions will operate on the current image.
45 //
46 // You can access image header information through get_image_headers() and file
47 // header information through get_header().
48 //
49 // Known reading limitations:
50 //  - The only supported compression schemes are uncompressed (all 4 different
51 //    types of data layouts: band sequential, band interleaved, band interleaved
52 //    by row, and band interleaved by pixel) and JPEG 2000 compression (via plugin).
53 //  Other forms of compression do not work (eg. JPEG (regular, non-j2k)
54 //  - Writing is unsupported at this time
55 //  - graphic segments are not read in
56 //  - text segments are not read in
57 //  - The class was designed to handle images with PVTYPE=C (complex), but images of
58 //    this type are completely untested.
59 //
60 // Things that do work:
61 //  - Reading uncompressed and image data (ints, shorts, 8 bit int, floats etc)
62 //  - parsing and validating file headers, and image headers
63 //  - enum_data masks (and pad pixels) are supported through vil_nitf2_data_mask_table
64 //  - PJUST = L
65 //  - Images with LUTS will read in correctly, but you will need to apply the LUT
66 //    yourself.  You can access the lut information for p-th band of the current image by calling
67 //    current_image_header()->get_lut_info(p, out_n_luts, out_ne_lut, out_lut_data)
68 //  - The class does not have built-in support for JPEG2000 compressed NITF files
69 //    Using cmake though, you can configure VXL to link against Er Mapper's freely
70 //    available ECW JPEG2000 SDK (http://ermapper.com/downloads/sdks.aspx#16).  If you
71 //    do that, then this class will automatically be able to read NITF files that are
72 //    JPEG 2000 compressed.
73 //
74 class vil_nitf2_image : public vil_blocked_image_resource
75 {
76  public:
77   //: Instantiate an image resource, but doesn't read anything.
78   // You'll want to call parse_headers() before you do anything with me
79   // (eg. before you ask for any image data).
80   // If that returns false, then I am invalid and useless to you in every way.
81   vil_nitf2_image( vil_stream* is );
82   vil_nitf2_image( const std::string& filePath, const char* mode );
83 
84   ~vil_nitf2_image() override;
85 
86   //:return the image info of the current image
87   unsigned nplanes() const override;
88   unsigned ni() const override;
89   unsigned nj() const override;
90   enum vil_pixel_format pixel_format () const override;
91 
92   //: Block size in columns
93   unsigned size_block_i() const override;
94 
95   //: Block size in rows
96   unsigned size_block_j() const override;
97 
98   //: Number of blocks in image width
99   unsigned n_block_i() const override;
100 
101   //: Number of blocks in image height
102   unsigned n_block_j() const override;
103 
104   //: returns "nitf vM.N"
105   char const * file_format() const override;
106 
107 
108   // is the current image JPEG 2000 compressed
109   bool is_jpeg_2000_compressed() const;
110 
111   // This function is sort of a hack.  It will return a decimated version
112   // of the region specified by (i0,j0){i0+ni,j0+nj).  It will be decimated by i_factorXj_factor.
113   // That is the image returned will have size (ni/i_factor, nj/j_factor).
114   // The reason this function is a hack is because it only works for jpeg 2000 compressed
115   // NITF files (that is, is_jpeg_2000_compressed() returns true).  You would normally want to use
116   // vil_decimate_image_resource to obtain decimated images.  That will work for jpeg2000
117   // compressed NITF files too, but that class/function doesn't take advantage of the JPEG 2000
118   // spec's built in optimization for obtaining decimated versions of large images.  This function
119   // does.  Well, more accurately, it can.  It depends on the implementation of the s_decode_jpeg_2000()
120   // function you've provided.
121   virtual vil_image_view_base_sptr get_copy_view_decimated_j2k( unsigned i0, unsigned ni,
122                                                                 unsigned j0, unsigned nj,
123                                                                 double i_factor, double j_factor ) const;
get_copy_view_decimated_j2k(double i_factor,double j_factor)124   virtual vil_image_view_base_sptr get_copy_view_decimated_j2k( double i_factor, double j_factor ) const
125   { return get_copy_view_decimated_j2k( 0, ni(), 0, nj(), i_factor, j_factor ); }
126 
127   vil_image_view_base_sptr get_copy_view(unsigned i0, unsigned ni,
128                                                  unsigned j0, unsigned nj) const override;
get_copy_view()129   virtual vil_image_view_base_sptr get_copy_view( ) const
130   { return get_copy_view( 0, ni(), 0, nj() ); }
131 
put_view(const vil_image_view_base &,unsigned,unsigned)132   bool put_view (const vil_image_view_base& /* im */, unsigned /* i0 */, unsigned /* j0 */ ) override
133   { return false; }
134 
put_block(unsigned,unsigned,const vil_image_view_base &)135   bool put_block(unsigned  /*block_index_i*/, unsigned  /*block_index_j*/,
136                          const vil_image_view_base& /*blk*/ ) override
137   { return false; }
138 
139   vil_image_view_base_sptr get_block( unsigned int blockIndexX, unsigned int blockIndexY ) const override;
140 
141   bool get_property (char const *tag, void *property_value=nullptr) const override;
142 
143   //const vil_nitf2_header& getFileHeader() const;
get_image_headers()144   const std::vector< vil_nitf2_image_subheader* >& get_image_headers() const
145   { return m_image_headers; }
get_header()146   const vil_nitf2_header& get_header() const
147   { return m_file_header; }
get_des()148   const std::vector< vil_nitf2_des* >& get_des() const
149   { return m_des; }
150 
151   //:
152   //  Since the VIL API (eg. get_view()) for retrieving image data
153   //  doesn't support files with multiple images, clients will
154   //  need to call this function to tell get_view() which image to read in.
155   //
156   //  Overloaded from vil_image_resource.  The NITF 2.x file format does support
157   //  multiple images per file and you can use this API to access each and every
158   //  one of them.
159   //
160   //  Note: By default, the first image is always used.  If you don't call this
161   //  function at all, then you will only see the first image in a given file.
162   virtual void set_current_image( unsigned int index );
163   virtual unsigned int current_image() const;
164   virtual unsigned int nimages() const;
165 
166   bool parse_headers();
167   vil_nitf2_classification::file_version file_version() const;
168 
169   //:
170   // All instances of vil_nitf2_image will use s_decode_jpeg_2000() to decode
171   // JPEG 2000 streams if you set the function.  If unset, then the library
172   // will not be able to read JPEG 2000 compressed NITF files.
173   //
174   static vil_image_view_base_sptr ( *s_decode_jpeg_2000 )( vil_stream* vs,
175                                                            unsigned i0, unsigned ni,
176                                                            unsigned j0, unsigned nj,
177                                                            double i_factor, double j_factor );
178 
179   // I allocate the return value, but you own it after I return it to you
180   // so you need to delete it.
181   virtual vil_nitf2_field::field_tree* get_tree() const;
182 
183  protected:
184   virtual vil_image_view_base_sptr get_block_j2k( unsigned int blockIndexX, unsigned int blockIndexY ) const;
185   virtual vil_image_view_base_sptr get_copy_view_uncompressed(unsigned i0, unsigned ni,
186                                                               unsigned j0, unsigned nj) const;
187 
188 
189   // Returns the offset (in bytes) from the beginning of the NITF file
190   // to the beginning of the specified portion of the NITF stream.  For example:
191   //
192   // get_offset_to( enum_text_segments, Header, 0) will return the offset from the
193   // beginning of the NITF stream to the beginning of the first text segment's
194   // subheader.  You'd better make sure there is at least one text segment before
195   // you call this.
196   //
197   // get_offset_to( enum_image_segments, enum_data, 3) will return the offset from the
198   // beginning of the NITF stream to the beginning of the fourth image segment's
199   // data section.  You'd better make sure there is at least four image segments before
200   // you call this.
201   vil_streampos get_offset_to( vil_nitf2_header::section_type sec, vil_nitf2_header::portion_type por, unsigned int index = 0 ) const;
202   // Returns the offset (in bytes) from the beginning of section_type 'sec' and the beginning of the specified portion
203   // (subheader or data).  If more then one of these segments exist, then use 'index' to select which one you want.
204   vil_streampos size_to( vil_nitf2_header::section_type sec, vil_nitf2_header::portion_type por, int index ) const;
205 
206   // Returns the overall offset to the specified image/block/band combination.
207   // If this block isn't present in the stream (ie. it's all blank), then
208   // I'll return 0;
209   vil_streampos get_offset_to_image_data_block_band( unsigned int imageIndex,
210                                                      unsigned int blockIndexX,
211                                                      unsigned int blockIndexY,
212                                                      int bandIndex ) const;
213 
214   //main file header
215   vil_nitf2_header m_file_header;
216   //image header(s)
217   std::vector< vil_nitf2_image_subheader* > m_image_headers;
218   void clear_image_headers();
219   const vil_nitf2_image_subheader* current_image_header() const;
220   //DESs (if any)
221   std::vector< vil_nitf2_des* > m_des;
222   void clear_des();
223 
224   vil_stream* m_stream;
225   unsigned int m_current_image_index;
226 };
227 
228 //: This function does a lot of work for \sa byte_align_data().
229 // It will strip one value of ni bits and return it as a value of type T
230 // (with zero padding on the MSBs).
231 // Both io and ni are lengths (in bits - not bytes).
232 //
233 // \param i0: Offset (in bits - not bytes) from in_val[0].  This will be the start
234 //            of the bits extracted from in_val.
235 // \param ni: number of bits (starting from i0) that will be extracted from in_val.
236 template< class T >
get_bits(const T * in_val,unsigned int i0,unsigned int ni)237 T get_bits( const T* in_val, unsigned int i0, unsigned int ni )
238 {
239   unsigned int sample_offset = i0 / ( sizeof(T)*8 );
240   unsigned int bit_offset = i0 % ( sizeof(T)*8 );
241 
242   unsigned int strip_left = bit_offset;
243   int strip_right = ( sizeof( T ) * 8 ) - ( bit_offset + ni );
244   T temp = in_val[sample_offset];
245   if ( strip_left > 0 ){
246     //strip off the appropriate bits from the std::left (replacing them with zeros)
247     temp = temp << strip_left;
248     temp = temp >> strip_left;
249   }
250   if ( strip_right > 0 ){
251     //strip off the appropriate bits from the std::right
252     //the bit shift operator wasn't having the correct effect, so that'w
253     //why the for loop
254     for ( int i = 0 ; i < strip_right ; i++ ) temp /= 2;
255     //temp = temp >> strip_right;
256   }
257   else if ( strip_right < 0 ){
258     //we didn't have enough bits in the first element of the in_val array
259     //need to get some from the next element
260     for ( int i = 0 ; i < (-strip_right) ; i++ ) temp *= 2;
261     temp += get_bits<T>( in_val+sample_offset+1, 0, -strip_right );
262   }
263   return temp;
264 }
265 
266 //: This function will byte align the data in in_data and store the result in out_data.
267 // For example, let's say that you had in_data is of type unsigned char
268 // and contains the following data: 110010111001111010000110.
269 // In other words:
270 // in_data[0] = 203 (11001011)
271 // in_data[1] = 158 (10011110)
272 // in_data[2] = 134 (10000110)
273 // Let's further say you called this function like this: byte_align_data( in_data, 8, 3, out_data ).
274 // Then, when the function finished, out_data would look like this:
275 // out_data[0] = 6 (00000110)
276 // out_data[1] = 2 (00000010)
277 // out_data[2] = 7 (00000111)
278 // out_data[3] = 1 (00000001)
279 // out_data[4] = 7 (00000111)
280 // out_data[5] = 2 (00000010)
281 // out_data[6] = 0 (00000000)
282 // out_data[7] = 6 (00000110)
283 //
284 // Basically, what the function did was group the bitstream into groups of three and then store all of the
285 // values into out_data.  It had to zero pad all the values (on the MSB side) to get them into out_data.  That's
286 // why out_data is bigger.
287 //
288 // This function works with other unsigned types of data too.  For example, let's say in_data was of type unsigned int
289 // and contained the following bits: 0100110010111000 0111101100000000 1111000011110000 (note that this bitstream is shown
290 // in big endian notation, that will not be the case if you are on a little endian machine -- this is just for illustration)
291 // in other words:
292 // in_data[0] = 19640 (0100110010111000) [shown in big endian for illustrative purposes only]
293 // in_data[1] = 31488 (0111101100000000) [shown in big endian for illustrative purposes only]
294 // in_data[2] = 61680 (1111000011110000) [shown in big endian for illustrative purposes only]
295 // Let's further say, you called this function like this byte_align_data( in_data, 4, 12, out_data ).
296 // Then out_data would be aligned along two byte (sixteen bit) boundaries and would look like this:
297 // out_data[0] = 1227 (0000010011001011) [shown in big endian for illustrative purposes only]
298 // out_data[1] = 2171 (0000100001111011) [shown in big endian for illustrative purposes only]
299 // out_data[2] = 15   (0000000000001111) [shown in big endian for illustrative purposes only]
300 // out_data[3] = 240  (0000000011110000) [shown in big endian for illustrative purposes only]
301 //
302 // Because of the fact that this function uses bit shifting operators, and the behavior of the std::right
303 // shift operator is implementation specific when applied to a negative number, you should probably
304 // only use this function on unsigned data.
305 //
306 // \param in_data: The input data.  It must be at least (num_samples*in_bits_per_sample\8) bytes long.
307 //                The values should have the endianness of your platform.
308 // \param num_samples: The number of actual samples in in_data.
309 // \param in_bits_per_sample: The bits per sample in in_data
310 // \param out_data: I'll store the output data here.  It must be at least (num_samples*sizeof(T)) bytes long
311 //                 The values will have the endianness of your platform.
312 //
313 // Note that inBitsPerSampe must not be >= sizeof(T).  If they were to be equal, then this function
314 // would have nothing to do (in_data is already byte aligned).  If in_bits_per_sample were less than sizeof(T),
315 // then each element of out_data would be too small to store the corresponding elements in in_data.
316 //
317 // Note that there is a specialization for the bool case which just casts it to an 8 bit quantity then calls
318 // this same function.  This is because the logic in get_bits<> doesn't work for the bool case.
319 template< class T >
byte_align_data(T * in_data,unsigned int num_samples,unsigned int in_bits_per_sample,T * out_data)320 T* byte_align_data( T* in_data, unsigned int num_samples, unsigned int in_bits_per_sample, T* out_data )
321 {
322   assert( in_bits_per_sample < sizeof(T)*8 );
323 
324   //grab each value from the bitstream (in_data) that we need... one at a time
325   unsigned int bit_offset = 0;
326   for ( unsigned int o = 0 ; o < num_samples ; o++ ){
327     out_data[o] = get_bits<T>( in_data, bit_offset, in_bits_per_sample );
328     bit_offset+=in_bits_per_sample;
329   }
330 
331   return out_data;
332 }
333 
334 template<> bool* byte_align_data<bool>( bool* in_data, unsigned int num_samples, unsigned int in_bits_per_sample, bool* out_data );
335 
336 #endif // VIL_NITF2_IMAGE_H
337