vil_nitf2_data_mask_table.cxx
Go to the documentation of this file.
1 // vil_nitf2: Written by Rob Radtke (rob@) and Harry Voorhees (hlv@) of
2 // Stellar Science Ltd. Co. (stellarscience.com) for
3 // Air Force Research Laboratory, 2005.
4 
5 #include <string>
6 #include <cstdlib>
8 
9 #include <vil/vil_stream.h>
10 #include <cassert>
11 #ifdef _MSC_VER
12 # include <vcl_msvc_warnings.h>
13 #endif
14 
16  unsigned int num_blocks_x, unsigned int num_blocks_y,
17  unsigned int num_bands, const std::string& i_mode )
18  : num_blocks_x( num_blocks_x ),
19  num_blocks_y( num_blocks_y ),
20  num_bands( num_bands ),
21  i_mode( i_mode )
22 { }
23 
25 {
26  //get the std::fixed width stuff first
27  if ( stream->read( (void*)(&IMDATOFF), 4 ) != 4 ||
28  stream->read( (void*)(&BMRLNTH), 2 ) != 2 ||
29  stream->read( (void*)(&TMRLNTH), 2 ) != 2 ||
30  stream->read( (void*)(&TPXCDLNTH), 2 ) != 2 )
31  {
32  return false;
33  } else {
34  maybe_endian_swap( (char*)&IMDATOFF, 4, 4 );
35  maybe_endian_swap( (char*)&BMRLNTH, 2, 2 );
36  maybe_endian_swap( (char*)&TMRLNTH, 2, 2 );
37  maybe_endian_swap( (char*)&TPXCDLNTH, 2, 2 );
38  }
39 
40  //reading in TPXCD is quite an ordeal because
41  //the width of the field varies based on the value of
42  //TPXCDLNTH
43  unsigned short width = TPXCDLNTH / 8;
44  if ( TPXCDLNTH % 8 != 0 ) width++;
45  void* val = std::malloc( width );
46 // if ( stream->read( &val, width ) != width ) return false;
47  if ( stream->read( val, width ) != width ) return false;
48  maybe_endian_swap( (char*)val, width, width );
49  if ( width == 1 ){
50  TPXCD = *((vxl_byte*)val);
51  } else if ( width == 2 ){
52  TPXCD = *((vxl_uint_16*)val);
53  } else if ( width == 4 ){
54  TPXCD = *((vxl_uint_32*)val);
55  }
56 #if VXL_HAS_INT_64
57  else if ( width == 8 ){
58  TPXCD = *((vxl_uint_64*)val);
59  }
60 #endif //VXL_HAS_INT64
61 
62  //properly size and then read in our vectors
63  ////do BMR_n_BND_m first
64  unsigned int i, j, b;
65  if ( BMRLNTH != 0 ){
66  BMR_n_BND_m.resize( num_blocks_x );
67  for ( i = 0 ; i < num_blocks_y ; i++ ){
68  BMR_n_BND_m[i].resize( num_blocks_y );
69  for ( j = 0 ; j < num_blocks_x ; j++ ){
70  BMR_n_BND_m[i][j].resize( i_mode == "S" ? num_bands : 1 );
71  }
72  }
73  for ( i = 0 ; i < num_blocks_x ; i++ ){
74  for ( j = 0 ; j < num_blocks_y ; j++ ){
75  for ( b = 0 ; b < BMR_n_BND_m[i][j].size() ; b++ ){
76  if ( stream->read( (void*)(&BMR_n_BND_m[i][j][b]), 4 ) != 4 ) return false;
77  maybe_endian_swap( (char*)(&BMR_n_BND_m[i][j][b]), 4, 4 );
78  }
79  }
80  }
81  }
82 
83 
84  //now do the pad pixel std::vector
85  if ( TMRLNTH != 0 ){
86  TMR_n_BND_m.resize( num_blocks_x );
87  for ( i = 0 ; i < num_blocks_y ; i++ ){
88  TMR_n_BND_m[i].resize( num_blocks_y );
89  for ( j = 0 ; j < num_blocks_x ; j++ ){
90  TMR_n_BND_m[i][j].resize( i_mode == "S" ? num_bands : 1 );
91  }
92  }
93  for ( i = 0 ; i < num_blocks_x ; i++ ){
94  for ( j = 0 ; j < num_blocks_y ; j++ ){
95  for ( b = 0 ; b < TMR_n_BND_m[i][j].size() ; b++ ){
96  if ( stream->read( (void*)(&TMR_n_BND_m[i][j][b]), 4 ) != 4 ) return false;
97  maybe_endian_swap( (char*)(&TMR_n_BND_m[i][j][b]), 4, 4 );
98  }
99  }
100  }
101  }
102 
103  return true;
104 }
105 
107 {
108  return IMDATOFF;
109 }
110 
111 vxl_uint_32 vil_nitf2_data_mask_table::block_band_offset( unsigned int block_x,
112  unsigned int block_y,
113  int band ) const
114 {
115  int band_to_use = i_mode == "S" ? band : 0;
116  assert( block_x < BMR_n_BND_m.size() &&
117  block_y < BMR_n_BND_m[block_x].size() &&
118  band_to_use < static_cast<int>(BMR_n_BND_m[block_x][band_to_use].size()) );
119  assert( ( band < 0 && i_mode != "S" ) ||
120  ( band >= 0 && i_mode == "S" ) );
121  return BMR_n_BND_m[block_x][block_y][band_to_use];
122 }
123 
124 vxl_uint_32 vil_nitf2_data_mask_table::pad_pixel( unsigned int block_x,
125  unsigned int block_y,
126  int band ) const
127 {
128  int band_to_use = i_mode == "S" ? band : 0;
129  assert( block_x < TMR_n_BND_m.size() &&
130  block_y < TMR_n_BND_m[block_x].size() &&
131  band_to_use < static_cast<int>(TMR_n_BND_m[block_x][band_to_use].size()) );
132  assert( ( band < 0 && i_mode != "S" ) ||
133  ( band >= 0 && i_mode == "S" ) );
134  return TMR_n_BND_m[block_x][block_y][band_to_use];
135 }
136 
137 #if VXL_LITTLE_ENDIAN
138 
139 #undef swap16
140 void swap16(char *a, unsigned n)
141 {
142  for (unsigned i = 0; i < n * 2; i += 2)
143  {
144  std::swap( a[i+0], a[i+1] );
145  }
146 }
147 
148 #undef swap32
149 void swap32(char *a, unsigned n)
150 {
151  for (unsigned i = 0; i < n * 4; i += 4)
152  {
153  std::swap( a[i+0], a[i+3] );
154  std::swap( a[i+1], a[i+2] );
155  }
156 }
157 
158 #undef swap64
159 void swap64(char *a, unsigned n)
160 {
161  for (unsigned i = 0; i < n * 8; i += 8)
162  {
163  std::swap( a[i+0], a[i+7] );
164  std::swap( a[i+1], a[i+6] );
165  std::swap( a[i+2], a[i+5] );
166  std::swap( a[i+3], a[i+4] );
167  }
168 }
169 
170 #endif
171 
172 void vil_nitf2_data_mask_table::maybe_endian_swap( char* a, unsigned size_of_a_in_bytes,
173  vil_pixel_format pix_format )
174 {
175 #if VXL_LITTLE_ENDIAN
176  maybe_endian_swap( a, size_of_a_in_bytes, vil_pixel_format_sizeof_components( pix_format ) );
177 #else
178  (void)a;
179  (void)size_of_a_in_bytes; // silence unused parameter compiler warning
180  (void)pix_format;
181 #endif //VXL_LITTLE_ENDIAN
182 }
183 
184 void vil_nitf2_data_mask_table::maybe_endian_swap( char* a, unsigned size_of_a_in_bytes,
185  unsigned int bytesPerSample )
186 {
187 #if VXL_LITTLE_ENDIAN
188  switch ( bytesPerSample )
189  {
190  case 8: swap64( a, size_of_a_in_bytes / 8 ); break; //64 bit
191  case 4: swap32( a, size_of_a_in_bytes / 4 ); break; //32 bit
192  case 2: swap16( a, size_of_a_in_bytes / 2 ); break; //16 bit
193  default: break; // do nothing
194  }
195 #else
196  (void)a;
197  (void)size_of_a_in_bytes; // silence unused parameter compiler warning
198  (void)bytesPerSample;
199 #endif //VXL_LITTLE_ENDIAN
200 }
201 
202 vxl_uint_32 vil_nitf2_data_mask_table::block_band_present( unsigned int block_x, unsigned int block_y, int band ) const
203 {
204  int band_to_use = i_mode == "S" ? band : 0;
205  assert( block_x < BMR_n_BND_m.size() &&
206  block_y < BMR_n_BND_m[block_x].size() &&
207  band_to_use < static_cast<int>(BMR_n_BND_m[block_x][band_to_use].size()) );
208  if (band_to_use >= static_cast<int>(BMR_n_BND_m[block_x][band_to_use].size()) )
209  return false;
210  return block_band_offset( block_x, block_y, band ) != 0xFFFFFFFF;
211 }
212 
213 vxl_uint_32 vil_nitf2_data_mask_table::block_band_has_pad( unsigned int block_x, unsigned int block_y, int band ) const
214 {
215  int band_to_use = i_mode == "S" ? band : 0;
216  assert( block_x < TMR_n_BND_m.size() &&
217  block_y < TMR_n_BND_m[block_x].size() &&
218  band_to_use < static_cast<int>(TMR_n_BND_m[block_x][band_to_use].size()) );
219  if (band_to_use >= static_cast<int>(TMR_n_BND_m[block_x][band_to_use].size()) )
220  return false;
221  return pad_pixel( block_x, block_y, band ) != 0xFFFFFFFF;
222 }
Stream interface for VIL image loaders.
void swap64(void *ptr)
vil_pixel_format
Describes the type of the concrete data.
vxl_uint_32 blocked_image_data_offset() const
std::vector< std::vector< std::vector< vxl_uint_32 > > > BMR_n_BND_m
virtual vil_streampos read(void *buf, vil_streampos n)=0
Read n bytes into buf. Returns number of bytes read.
unsigned vil_pixel_format_sizeof_components(enum vil_pixel_format f)
Return the number of bytes used by each component of pixel format f.
void swap32(void *ptr)
static void maybe_endian_swap(char *a, unsigned sizeOfAInBytes, vil_pixel_format pixFormat)
vil_nitf2_data_mask_table(unsigned int numBlocksX, unsigned int numBlocksY, unsigned int numBands, const std::string &imode)
Stream interface for VIL image loaders.
Definition: vil_stream.h:21
vxl_uint_32 block_band_has_pad(unsigned int block_x, unsigned int block_y, int band=-1) const
vxl_uint_32 block_band_offset(unsigned int block_x, unsigned int block_y, int band=-1) const
if imode == "S", then the band argument is used and I will return the offset to 'band' if imode !...
std::vector< std::vector< std::vector< vxl_uint_32 > > > TMR_n_BND_m
vxl_uint_32 pad_pixel(unsigned int block_x, unsigned int block_y, int band) const
band argument is ignored if imode != "S"...
vxl_uint_32 block_band_present(unsigned int block_x, unsigned int block_y, int band=-1) const
Returns true iff this block is present in the data. False otherwise.