15 # include <vcl_msvc_warnings.h> 20 #include <vil/vil_config.h> 33 static char const nitf2_string[] =
"nitf";
43 if ( !im->parse_headers() ) {
66 unsigned int index )
const 104 bool going_past_end =
false;
108 index = num_segments;
109 going_past_end =
true;
114 for (i = 0 ; i < index ; i++) {
115 int current_header_size;
117 offset += current_header_size;
121 offset += current_data_size;
124 int current_data_size;
126 offset += current_data_size;
134 if ( going_past_end ) { assert(!
"skipped past all segments");
return 0L; }
135 int current_header_size;
137 offset += current_header_size;
143 (
vil_stream* vs,
unsigned i0,
unsigned ni,
unsigned j0,
unsigned nj,
double i_factor,
double j_factor ) =
nullptr;
147 m_current_image_index(0)
153 : m_current_image_index(0)
155 #ifdef VIL_USE_FSTREAM64 156 m_stream =
new vil_stream_fstream64(filePath.c_str(), mode);
157 #else //VIL_USE_FSTREAM64 159 #endif //VIL_USE_FSTREAM64 166 delete m_image_header;
173 for (
auto & m_de :
m_des) {
206 unsigned int image_index,
unsigned int block_index_x,
unsigned int block_index_y,
int bandIndex)
const 220 int bits_per_pixel_per_band;
223 #if 0 //Not valid if blocks are partially filled (JLM 11/03/07) 224 unsigned int bytes_per_band =
ni() *
nj() * bits_per_pixel_per_band / 8;
229 unsigned int bytes_per_band = nbi*nbj*sbi*sbj*bits_per_pixel_per_band/8;
243 if (data_mask_table) {
248 int bI = i_mode ==
"S" ? bandIndex : -1;
257 unsigned int bits_per_band = pixels_per_block * bits_per_pixel_per_band;
258 unsigned int bytes_per_block_per_band = bits_per_band / 8;
261 if (bits_per_band % 8 != 0) bytes_per_block_per_band++;
264 unsigned int offset_to_desired_band = bandIndex * bytes_per_band;
265 unsigned int offset_to_desired_block = bytes_per_block_per_band * (block_index_y *
n_block_i() + block_index_x);
266 offset += offset_to_desired_band + offset_to_desired_block;
270 unsigned int block_size_bytes = bytes_per_block_per_band *
nplanes();
271 unsigned int offset_to_desired_block = block_size_bytes * (block_index_y *
n_block_i() + block_index_x);
272 offset += offset_to_desired_block;
279 unsigned int offset_to_desired_band = bandIndex * bytes_per_band;
280 offset += offset_to_desired_band;
296 for (
unsigned int i = 0 ; i <
nimages() ; i++) {
307 m_des.resize( num_des );
308 for (
int j = 0 ; j < num_des ; j++ ){
359 int num_significant_cols;
362 return num_significant_cols;
373 int num_significant_rows;
376 return num_significant_rows;
383 std::string pixel_type;
389 int bytesPerPixel = bits_per_pixel / 8;
390 if (bits_per_pixel % 8 != 0) bytesPerPixel++;
391 bits_per_pixel = bytesPerPixel * 8;
392 if (pixel_type ==
"INT") {
393 if (bits_per_pixel == 8) {
396 else if (bits_per_pixel == 16) {
399 else if (bits_per_pixel == 32) {
403 else if (bits_per_pixel == 64) {
404 return VIL_PIXEL_FORMAT_UINT_64;
406 #endif //VXL_HAS_INT_64 408 else if (pixel_type ==
"B") {
411 else if (pixel_type ==
"SI") {
412 if (bits_per_pixel == 8) {
415 else if (bits_per_pixel == 16) {
418 else if (bits_per_pixel == 32) {
422 else if (bits_per_pixel == 64) {
423 return VIL_PIXEL_FORMAT_INT_64;
425 #endif //VXL_HAS_INT_64 427 else if (pixel_type ==
"R") {
428 if (bits_per_pixel == 32) {
431 else if (bits_per_pixel == 64) {
435 else if (pixel_type ==
"C") {
437 if (bits_per_pixel == 64) {
468 unsigned int& block,
unsigned int& offset)
474 block = (j0 / block_size);
475 if (j0 > 0 && j0 % block_size != 0) {
476 offset = j0 - (block * block_size);
483 std::string compression_type;
488 ( compression_type ==
"C8" || compression_type ==
"M8" );
492 unsigned start_i,
unsigned num_i,
unsigned start_j,
unsigned num_j,
double i_factor,
double j_factor )
const 495 if ((start_i + num_i >
ni()) || (start_j + num_j >
nj())) {
503 std::cerr <<
"Cannot decode JPEG 2000 image. The J2K library was not built." << std::endl;
516 unsigned start_j,
unsigned num_j)
const 519 if ((start_i + num_i >
ni()) || (start_j + num_j >
nj())) {
523 std::string compression_type;
529 if (compression_type ==
"NC" || compression_type ==
"NM") {
541 unsigned start_j,
unsigned num_j)
const 548 unsigned int in_bits_per_sample, T )
550 if (in_bits_per_sample !=
sizeof(T)*8) {
552 byte_align_data((T*)in_data->data(), num_samples, in_bits_per_sample, (T*)new_memory->data());
579 void right_justify(T* data,
unsigned int num_samples,
unsigned int bitsToMove)
581 for (
unsigned int i = 0 ; i < num_samples ; i++) {
582 data[i] = data[i] >> bitsToMove;
590 template<>
void right_justify< std::complex< float > >(std::complex< float >* ,
unsigned int ,
595 {
return (T)in_val; }
598 {
return in_val ? 1 : 0; }
602 unsigned int pixels_per_block_x,
unsigned int pixels_per_block_y,
603 unsigned int nplanes,
604 unsigned int i_step,
unsigned int j_step,
unsigned int plane_step,
605 bool need_to_right_justify,
606 unsigned int extra_bits,
unsigned int bits_per_pixel_per_band,
610 unsigned int num_samples = pixels_per_block_x * pixels_per_block_y * nplanes;
612 if (data_is_all_blank) {
614 T* data_ptr = reinterpret_cast<T*>(image_memory->data());
615 for (
unsigned int i = 0 ;
616 i < pixels_per_block_x * pixels_per_block_y * nplanes ;
625 if (need_to_right_justify)
626 right_justify<T>(static_cast<T*>(image_memory->data()), (
unsigned int)(image_memory->size()/
sizeof(T)), extra_bits);
636 pixels_per_block_x, pixels_per_block_y, nplanes, i_step, j_step, plane_step);
644 if ( blockIndexX >=
n_block_i() )
return nullptr;
645 if ( blockIndexY >=
n_block_j() )
return nullptr;
651 unsigned int i0 = (std::min)( blockIndexX *
size_block_i(),
ni() );
653 unsigned int j0 = (std::min)( blockIndexY *
size_block_j(),
nj() );
666 std::string image_mode_type;
670 int bits_per_pixel_per_band, actualBitsPerPixelPerBand;
671 std::string bitJustification;
677 int extra_bits = bits_per_pixel_per_band - actualBitsPerPixelPerBand;
678 bool need_to_right_justify = bitJustification ==
"L" && (extra_bits > 0);
685 unsigned int bits_per_band = pixels_per_block * bits_per_pixel_per_band;
686 unsigned int bytes_per_block_per_band = bits_per_band / 8;
687 if (bits_per_band % 8 != 0) bytes_per_block_per_band++;
688 unsigned int block_size_bytes = bytes_per_block_per_band *
nplanes();
693 unsigned int i_step(0), j_step(0), plane_step(0);
694 bool data_is_all_blank =
false;
695 if (image_mode_type ==
"S") {
697 unsigned int bytes_per_band =
ni() *
nj() * bits_per_pixel_per_band / 8;
698 unsigned int offset_to_desired_block = bytes_per_block_per_band * (block_index_y *
n_block_i() + block_index_x);
701 for (
unsigned int i = 0 ; i <
nplanes() ; i++) {
703 if (current_offset == 0) {
705 data_is_all_blank =
true;
709 char* position_to_read_to = static_cast<char*>(image_memory->data());
710 position_to_read_to += i*bytes_per_block_per_band;
711 if (
m_stream->
read((
void*)position_to_read_to, bytes_per_block_per_band) != static_cast<int>(bytes_per_block_per_band)) {
723 if (current_offset == 0) {
725 data_is_all_blank =
true;
731 if (
m_stream->
read(image_memory->data(), block_size_bytes) != static_cast<int>(block_size_bytes)) {
737 if (image_mode_type ==
"B") {
743 else if (image_mode_type ==
"P") {
749 else if (image_mode_type ==
"R") {
761 #define GET_BLOCK_CASE(FORMAT, T)\ 764 return get_block_vcl_internal(\ 765 FORMAT, image_memory, size_block_i(),size_block_j(), nplanes(),\ 766 i_step, j_step, plane_step, need_to_right_justify, extra_bits, bits_per_pixel_per_band,\ 767 data_is_all_blank, current_image_header(), t);\ 785 #undef GET_BLOCK_CASE 788 assert(!
"Unknown vil data type.");
794 template<>
bool*
byte_align_data<bool>(
bool* in_data,
unsigned int num_samples,
unsigned int in_bits_per_sample,
bool* out_data)
796 switch (
sizeof(
bool))
799 byte_align_data((vxl_byte*)in_data, num_samples, in_bits_per_sample, (vxl_byte*)out_data);
802 byte_align_data((vxl_uint_16*)in_data, num_samples, in_bits_per_sample, (vxl_uint_16*)out_data);
805 byte_align_data((vxl_uint_32*)in_data, num_samples, in_bits_per_sample, (vxl_uint_32*)out_data);
809 byte_align_data((vxl_uint_64*)in_data, num_samples, in_bits_per_sample, (vxl_uint_64*)out_data);
811 #endif //VXL_HAS_INT_64 813 assert(!
"Unsupported size of bool.");
818 std::cout <<
"\nBools: ";
819 for (
unsigned int i = 0 ; i < num_samples ; i++) {
820 std::cout << (out_data[i] ?
'1' :
'0');
822 std::cout << std::endl;
832 *static_cast<unsigned*>(property_value) = this->
size_block_i();
839 *static_cast<unsigned*>(property_value) = this->
size_block_j();
846 property_value = std::malloc(result.size());
847 std::memcpy(property_value, result.c_str(), result.size());
856 t->
columns.emplace_back(
"NITF File" );
862 for ( i = 0 ; i <
m_des.size() ; i++ ){
vil_memory_chunk_sptr maybe_byte_align_data(vil_memory_chunk_sptr in_data, unsigned int num_samples, unsigned int in_bits_per_sample, T)
char const * file_format() const override
returns "nitf vM.N".
virtual vil_image_view_base_sptr get_copy_view_decimated_j2k(unsigned i0, unsigned ni, unsigned j0, unsigned nj, double i_factor, double j_factor) const
vil_smart_ptr< vil_image_view_base > vil_image_view_base_sptr
vxl_int_32 vil_nitf2_long
bool has_offset_table() const
If this function returns true, then you may call.
~vil_nitf2_image() override
unsigned int get_index< bool >(bool in_val)
enum vil_pixel_format pixel_format() const override
Pixel Format.
This class is responsible for parsing a NITF 2.1 data mask table.
unsigned n_block_i() const override
Number of blocks in image width.
unsigned size_block_i() const override
Block size in columns.
std::vector< std::string > columns
bool get_property(char const *tag, void *property_value=nullptr) const override
Extra property information.
virtual vil_image_view_base_sptr get_copy_view_uncompressed(unsigned i0, unsigned ni, unsigned j0, unsigned nj) const
Concrete view of image data of type T held in memory.
void clear_image_headers()
vil_nitf2_image(vil_stream *is)
Instantiate an image resource, but doesn't read anything.
vil_nitf2_classification::file_version file_version() const
vil_j2k: Written by Rob Radtke (rob@) and Harry Voorhees (hlv@) of Stellar Science Ltd.
#define GET_BLOCK_CASE(FORMAT, T)
vxl_uint_32 blocked_image_data_offset() const
std::vector< vil_nitf2_des * > m_des
virtual void seek(vil_streampos position)=0
Goto file pointer.
const vil_nitf2_header & get_header() const
static vil_image_view_base_sptr(* s_decode_jpeg_2000)(vil_stream *vs, unsigned i0, unsigned ni, unsigned j0, unsigned nj, double i_factor, double j_factor)
All instances of vil_nitf2_image will use s_decode_jpeg_2000() to decode JPEG 2000 streams if you set...
vil_streampos size_to(vil_nitf2_header::section_type sec, vil_nitf2_header::portion_type por, int index) const
virtual vil_streampos read(void *buf, vil_streampos n)=0
Read n bytes into buf. Returns number of bytes read.
A vil_stream implementation using std::fstream.
vil_image_view_base_sptr get_block(unsigned int blockIndexX, unsigned int blockIndexY) const override
virtual void set_current_image(unsigned int index)
Since the VIL API (eg.
unsigned ni() const override
Dimensions: Planes x ni x nj.
static void maybe_endian_swap(char *a, unsigned sizeOfAInBytes, vil_pixel_format pixFormat)
void right_justify< bool >(bool *, unsigned int, unsigned int)
unsigned int get_index(T in_val)
vil_memory_chunk_sptr maybe_byte_align_data< float >(vil_memory_chunk_sptr in_data, unsigned int, unsigned int, float)
vil_streampos get_offset_to(vil_nitf2_header::section_type sec, vil_nitf2_header::portion_type por, unsigned int index=0) const
Stream interface for VIL image loaders.
vil_nitf2: Written by Rob Radtke (rob@) and Harry Voorhees (hlv@) of Stellar Science Ltd.
A vil_stream implementation using std::fstream.
virtual vil_nitf2_field::field_tree * get_tree() const
Class for reading NITF 2.1 imagery files.
vil_memory_chunk_sptr maybe_byte_align_data< double >(vil_memory_chunk_sptr in_data, unsigned int, unsigned int, double)
virtual unsigned int current_image() const
unsigned int m_current_image_index
#define vil_property_size_block_i
For unblocked images, the following properties are not implemented.
vil_streampos get_offset_to_image_data_block_band(unsigned int imageIndex, unsigned int blockIndexX, unsigned int blockIndexY, int bandIndex) const
void right_justify< float >(float *, unsigned int, unsigned int)
unsigned n_block_j() const override
Number of blocks in image height.
void right_justify< double >(double *, unsigned int, unsigned int)
void compute_block_and_offset(unsigned j0, unsigned long block_size, unsigned int &block, unsigned int &offset)
bool is_jpeg_2000_compressed() const
bool * byte_align_data< bool >(bool *in_data, unsigned int num_samples, unsigned int in_bits_per_sample, bool *out_data)
void right_justify(T *data, unsigned int num_samples, unsigned int bitsToMove)
This function handles the case where the actual bits per pixel per band is less then the actual bpppb...
void ref()
up/down the reference count.
vil_image_view_base_sptr get_copy_view() const
Create a read/write view of a copy of all the data.
A base class reference-counting view of some image data.
unsigned nplanes() const override
return the image info of the current image.
std::vector< vil_nitf2_image_subheader * > m_image_headers
There is no class or function called vil_property.
Ref. counted block of data on the heap.
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 !...
vil_nitf2_header m_file_header
virtual bool ok() const =0
Return false if the stream is broken.
#define vil_property_size_block_j
Block size in rows.
T * byte_align_data(T *in_data, unsigned int num_samples, unsigned int in_bits_per_sample, T *out_data)
This function will byte align the data in in_data and store the result in out_data.
virtual vil_image_view_base_sptr get_block_j2k(unsigned int blockIndexX, unsigned int blockIndexY) const
const vil_nitf2_image_subheader * current_image_header() const
vil_image_view_base_sptr get_block_vcl_internal(vil_pixel_format pix_format, vil_memory_chunk_sptr image_memory, unsigned int pixels_per_block_x, unsigned int pixels_per_block_y, unsigned int nplanes, unsigned int i_step, unsigned int j_step, unsigned int plane_step, bool need_to_right_justify, unsigned int extra_bits, unsigned int bits_per_pixel_per_band, bool data_is_all_blank, const vil_nitf2_image_subheader *, T dummy)
virtual vil_image_view_base_sptr get_copy_view() const
static vil_image_view_base_sptr s_decode_jpeg_2000(vil_stream *vs, unsigned i0, unsigned ni, unsigned j0, unsigned nj, double i_factor, double j_factor)
Static function that can be used to decode a JPEG2000 codestream or file (jp2 file).
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.
virtual unsigned int nimages() const
unsigned size_block_j() const override
Block size in rows.
unsigned nj() const override
Dimensions: Planes x ni x nj.