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