00001
00002
00003
00004
00005 #include "vil_nitf2_data_mask_table.h"
00006
00007 #include <vil/vil_stream.h>
00008 #include <vcl_string.h>
00009 #include <vcl_cassert.h>
00010 #include <vcl_cstdlib.h>
00011
00012 vil_nitf2_data_mask_table::vil_nitf2_data_mask_table(
00013 unsigned int num_blocks_x, unsigned int num_blocks_y,
00014 unsigned int num_bands, const vcl_string i_mode )
00015 : num_blocks_x( num_blocks_x ),
00016 num_blocks_y( num_blocks_y ),
00017 num_bands( num_bands ),
00018 i_mode( i_mode )
00019 { }
00020
00021 bool vil_nitf2_data_mask_table::parse( vil_stream* stream )
00022 {
00023
00024 if ( stream->read( (void*)(&IMDATOFF), 4 ) != 4 ||
00025 stream->read( (void*)(&BMRLNTH), 2 ) != 2 ||
00026 stream->read( (void*)(&TMRLNTH), 2 ) != 2 ||
00027 stream->read( (void*)(&TPXCDLNTH), 2 ) != 2 )
00028 {
00029 return false;
00030 } else {
00031 maybe_endian_swap( (char*)&IMDATOFF, 4, 4 );
00032 maybe_endian_swap( (char*)&BMRLNTH, 2, 2 );
00033 maybe_endian_swap( (char*)&TMRLNTH, 2, 2 );
00034 maybe_endian_swap( (char*)&TPXCDLNTH, 2, 2 );
00035 }
00036
00037
00038
00039
00040 unsigned short width = TPXCDLNTH / 8;
00041 if ( TPXCDLNTH % 8 != 0 ) width++;
00042 void* val = vcl_malloc( width );
00043
00044 if ( stream->read( val, width ) != width ) return false;
00045 maybe_endian_swap( (char*)val, width, width );
00046 if ( width == 1 ){
00047 TPXCD = *((vxl_byte*)val);
00048 } else if ( width == 2 ){
00049 TPXCD = *((vxl_uint_16*)val);
00050 } else if ( width == 4 ){
00051 TPXCD = *((vxl_uint_32*)val);
00052 }
00053 #if VXL_HAS_INT_64
00054 else if ( width == 8 ){
00055 TPXCD = *((vxl_uint_64*)val);
00056 }
00057 #endif //VXL_HAS_INT64
00058
00059
00060
00061 unsigned int i, j, b;
00062 if ( BMRLNTH != 0 ){
00063 BMR_n_BND_m.resize( num_blocks_x );
00064 for ( i = 0 ; i < num_blocks_y ; i++ ){
00065 BMR_n_BND_m[i].resize( num_blocks_y );
00066 for ( j = 0 ; j < num_blocks_x ; j++ ){
00067 BMR_n_BND_m[i][j].resize( i_mode == "S" ? num_bands : 1 );
00068 }
00069 }
00070 for ( i = 0 ; i < num_blocks_x ; i++ ){
00071 for ( j = 0 ; j < num_blocks_y ; j++ ){
00072 for ( b = 0 ; b < BMR_n_BND_m[i][j].size() ; b++ ){
00073 if ( stream->read( (void*)(&BMR_n_BND_m[i][j][b]), 4 ) != 4 ) return false;
00074 maybe_endian_swap( (char*)(&BMR_n_BND_m[i][j][b]), 4, 4 );
00075 }
00076 }
00077 }
00078 }
00079
00080
00081
00082 if ( TMRLNTH != 0 ){
00083 TMR_n_BND_m.resize( num_blocks_x );
00084 for ( i = 0 ; i < num_blocks_y ; i++ ){
00085 TMR_n_BND_m[i].resize( num_blocks_y );
00086 for ( j = 0 ; j < num_blocks_x ; j++ ){
00087 TMR_n_BND_m[i][j].resize( i_mode == "S" ? num_bands : 1 );
00088 }
00089 }
00090 for ( i = 0 ; i < num_blocks_x ; i++ ){
00091 for ( j = 0 ; j < num_blocks_y ; j++ ){
00092 for ( b = 0 ; b < TMR_n_BND_m[i][j].size() ; b++ ){
00093 if ( stream->read( (void*)(&TMR_n_BND_m[i][j][b]), 4 ) != 4 ) return false;
00094 maybe_endian_swap( (char*)(&TMR_n_BND_m[i][j][b]), 4, 4 );
00095 }
00096 }
00097 }
00098 }
00099
00100 return true;
00101 }
00102
00103 vxl_uint_32 vil_nitf2_data_mask_table::blocked_image_data_offset() const
00104 {
00105 return IMDATOFF;
00106 }
00107
00108 vxl_uint_32 vil_nitf2_data_mask_table::block_band_offset( unsigned int block_x,
00109 unsigned int block_y,
00110 int band ) const
00111 {
00112 int band_to_use = i_mode == "S" ? band : 0;
00113 assert( block_x < BMR_n_BND_m.size() &&
00114 block_y < BMR_n_BND_m[block_x].size() &&
00115 band_to_use < static_cast<int>(BMR_n_BND_m[block_x][band_to_use].size()) );
00116 assert( ( band < 0 && i_mode != "S" ) ||
00117 ( band >= 0 && i_mode == "S" ) );
00118 return BMR_n_BND_m[block_x][block_y][band_to_use];
00119 }
00120
00121 vxl_uint_32 vil_nitf2_data_mask_table::pad_pixel( unsigned int block_x,
00122 unsigned int block_y,
00123 int band ) const
00124 {
00125 int band_to_use = i_mode == "S" ? band : 0;
00126 assert( block_x < TMR_n_BND_m.size() &&
00127 block_y < TMR_n_BND_m[block_x].size() &&
00128 band_to_use < static_cast<int>(TMR_n_BND_m[block_x][band_to_use].size()) );
00129 assert( ( band < 0 && i_mode != "S" ) ||
00130 ( band >= 0 && i_mode == "S" ) );
00131 return TMR_n_BND_m[block_x][block_y][band_to_use];
00132 }
00133
00134 #if VXL_LITTLE_ENDIAN
00135
00136 #undef swap16
00137 void swap16(char *a, unsigned n)
00138 {
00139 for (unsigned i = 0; i < n * 2; i += 2)
00140 {
00141 vcl_swap( a[i+0], a[i+1] );
00142 }
00143 }
00144
00145 #undef swap32
00146 void swap32(char *a, unsigned n)
00147 {
00148 for (unsigned i = 0; i < n * 4; i += 4)
00149 {
00150 vcl_swap( a[i+0], a[i+3] );
00151 vcl_swap( a[i+1], a[i+2] );
00152 }
00153 }
00154
00155 #undef swap64
00156 void swap64(char *a, unsigned n)
00157 {
00158 for (unsigned i = 0; i < n * 8; i += 8)
00159 {
00160 vcl_swap( a[i+0], a[i+7] );
00161 vcl_swap( a[i+1], a[i+6] );
00162 vcl_swap( a[i+2], a[i+5] );
00163 vcl_swap( a[i+3], a[i+4] );
00164 }
00165 }
00166
00167 #endif
00168
00169 void vil_nitf2_data_mask_table::maybe_endian_swap( char* a, unsigned size_of_a_in_bytes,
00170 vil_pixel_format pix_format )
00171 {
00172 #if VXL_LITTLE_ENDIAN
00173 maybe_endian_swap( a, size_of_a_in_bytes, vil_pixel_format_sizeof_components( pix_format ) );
00174 #else
00175 (void)a;
00176 (void)size_of_a_in_bytes;
00177 (void)pix_format;
00178 #endif //VXL_LITTLE_ENDIAN
00179 }
00180
00181 void vil_nitf2_data_mask_table::maybe_endian_swap( char* a, unsigned size_of_a_in_bytes,
00182 unsigned int bytesPerSample )
00183 {
00184 #if VXL_LITTLE_ENDIAN
00185 switch ( bytesPerSample )
00186 {
00187 case 8: swap64( a, size_of_a_in_bytes / 8 ); break;
00188 case 4: swap32( a, size_of_a_in_bytes / 4 ); break;
00189 case 2: swap16( a, size_of_a_in_bytes / 2 ); break;
00190 default: break;
00191 }
00192 #else
00193 (void)a;
00194 (void)size_of_a_in_bytes;
00195 (void)bytesPerSample;
00196 #endif //VXL_LITTLE_ENDIAN
00197 }
00198
00199 vxl_uint_32 vil_nitf2_data_mask_table::block_band_present( unsigned int block_x, unsigned int block_y, int band ) const
00200 {
00201 int band_to_use = i_mode == "S" ? band : 0;
00202 assert( block_x < BMR_n_BND_m.size() &&
00203 block_y < BMR_n_BND_m[block_x].size() &&
00204 band_to_use < static_cast<int>(BMR_n_BND_m[block_x][band_to_use].size()) );
00205 if (band_to_use >= static_cast<int>(BMR_n_BND_m[block_x][band_to_use].size()) )
00206 return false;
00207 return block_band_offset( block_x, block_y, band ) != 0xFFFFFFFF;
00208 }
00209
00210 vxl_uint_32 vil_nitf2_data_mask_table::block_band_has_pad( unsigned int block_x, unsigned int block_y, int band ) const
00211 {
00212 int band_to_use = i_mode == "S" ? band : 0;
00213 assert( block_x < TMR_n_BND_m.size() &&
00214 block_y < TMR_n_BND_m[block_x].size() &&
00215 band_to_use < static_cast<int>(TMR_n_BND_m[block_x][band_to_use].size()) );
00216 if (band_to_use >= static_cast<int>(TMR_n_BND_m[block_x][band_to_use].size()) )
00217 return false;
00218 return pad_pixel( block_x, block_y, band ) != 0xFFFFFFFF;
00219 }