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 #ifndef VIL_NITF2_DATA_MASK_TABLE_H
6 #define VIL_NITF2_DATA_MASK_TABLE_H
7 //:
8 // \file
9 
10 #include <vector>
11 #include <string>
12 #include <vxl_config.h>
13 #ifdef _MSC_VER
14 #  include <vcl_msvc_warnings.h>
15 #endif
16 #include <vil/vil_pixel_format.h>
17 
18 class vil_stream;
19 
20 //: This class is responsible for parsing a NITF 2.1 data mask table.
21 //  When present, a vil_nitf2_image_subheader() will use this class
22 //  to extract the table from the file.  It reads a vil_stream, via
23 //  the parse() method and will return false if it failed.
24 class vil_nitf2_data_mask_table
25 {
26  public:
27    vil_nitf2_data_mask_table(unsigned int numBlocksX, unsigned int numBlocksY,
28                              unsigned int numBands, std::string imode);
29    bool parse(vil_stream *stream);
30 
31    //: If this function returns true, then you may call \sa block_band_offset()
has_offset_table()32    bool has_offset_table() const { return !BMR_n_BND_m.empty(); }
33 
34    //: If this function returns true, then you may call \sa pad_pixel()
has_pad_pixel_table()35    bool has_pad_pixel_table() const { return !TMR_n_BND_m.empty(); }
36 
37    vxl_uint_32 blocked_image_data_offset() const;
38 
39    //: Returns true iff this block is present in the data.  False otherwise.
40    //  If this returns false, then there is not sense calling block_band_offset
41    //  for this band/block combination. It will return 0xFFFFFFFF.
42    //  If this returns false, then this entire block/band is considered to be
43    //  blank.
44    vxl_uint_32 block_band_present(unsigned int block_x, unsigned int block_y,
45                                   int band = -1) const;
46 
47    //:
48    //  if imode == "S", then the band argument is used and I will return the
49    //  offset to 'band' if imode != "S", then the band argument is ignored, and
50    //  I will return the offset to the beginning of the requested block
51    vxl_uint_32 block_band_offset(unsigned int block_x, unsigned int block_y,
52                                  int band = -1) const;
53 
54    //:
55    // band argument is ignored if imode != "S"... i.e. all bands have the same
56    // pad pixel in that case
57    vxl_uint_32 pad_pixel(unsigned int block_x, unsigned int block_y,
58                          int band) const;
59 
60    vxl_uint_32 block_band_has_pad(unsigned int block_x, unsigned int block_y,
61                                   int band = -1) const;
62 
63    static void maybe_endian_swap(char *a, unsigned sizeOfAInBytes,
64                                  vil_pixel_format pixFormat);
65    static void maybe_endian_swap(char *a, unsigned sizeOfAInBytes,
66                                  unsigned int bytesPerSample);
67  protected:
68   //Blocked Image Data Offset (in bytes)
69   vxl_uint_32 IMDATOFF;
70   //Block Mask Record Length (in bytes)
71   vxl_uint_16 BMRLNTH;
72   //Pad Pixel Mask Record Length (in bytes)
73   vxl_uint_16 TMRLNTH;
74   //Pad Output Pixel Code Length (in bits)
75   vxl_uint_16 TPXCDLNTH;
76   //Pad Output Pixel Code
77   // (it's an integer, but its length is TPXCDLNTH rounded up to the nearest byte)
78 #if VXL_HAS_INT_64
79   vxl_uint_64 TPXCD;
80 #else
81   vxl_uint_32 TPXCD;
82 #endif //VXL_HAS_INT_64
83 
84   //Block n, Band m Offset
85   //indexed BMR_n_BND_m[row][col][band] for i_mode = "S" else
86   //indexed BMR_n_BND_m[row][col]
87   std::vector< std::vector< std::vector< vxl_uint_32 > > > BMR_n_BND_m;
88   //Pad Pixel n, Band m
89   //indexed TMR_n_BND_m[row][col][band] for i_mode = "S" else
90   //indexed TMR_n_BND_m[row][col]
91   std::vector< std::vector< std::vector< vxl_uint_32 > > > TMR_n_BND_m;
92 
93   unsigned int num_blocks_x;
94   unsigned int num_blocks_y;
95   unsigned int num_bands;
96   std::string i_mode;
97 };
98 
99 #endif // VIL_NITF2_DATA_MASK_TABLE_H
100