National Imagery Transmission Format: C++98/STL parsing library

The NITF (National Image Transition Format) format is a file format developed by the U.S. Government for storing imagery, e.g. from satellites.

According to the foreword of the specification:

The National Imagery Transmission Format Standard (NITFS) is the suite of standards for formatting digital imagery and imagery-related products and exchanging them among members of the Intelligence Community (IC) as defined by the Executive Order 12333, and other United States Government departments and agencies."

This implementation is set to version format (file_version) of 02.10 and standard_type of BF01. It was implemented by River Loop Security.

File extension

["ntf", "nitf", "ntf.r0", "ntf.r1", "ntf.r2", "ntf.r3", "ntf.r4", "ntf.r5"]

KS implementation details

License: MIT
Minimal Kaitai Struct required: 0.8

References

This page hosts a formal specification of National Imagery Transmission Format using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Usage

Runtime library

All parsing code for C++98/STL generated by Kaitai Struct depends on the C++/STL runtime library. You have to install it before you can parse data.

For C++, the easiest way is to clone the runtime library sources and build them along with your project.

Code

Using Kaitai Struct in C++/STL usually consists of 3 steps.

  1. We need to create an STL input stream (std::istream). One can open local file for that, or use existing std::string or char* buffer.
    #include <fstream>
    
    std::ifstream is("path/to/local/file.["ntf", "nitf", "ntf.r0", "ntf.r1", "ntf.r2", "ntf.r3", "ntf.r4", "ntf.r5"]", std::ifstream::binary);
    
    #include <sstream>
    
    std::istringstream is(str);
    
    #include <sstream>
    
    const char buf[] = { ... };
    std::string str(buf, sizeof buf);
    std::istringstream is(str);
    
  2. We need to wrap our input stream into Kaitai stream:
    #include "kaitai/kaitaistream.h"
    
    kaitai::kstream ks(&is);
    
  3. And finally, we can invoke the parsing:
    nitf_t data(&ks);
    

After that, one can get various attributes from the structure by invoking getter methods like:

data.header() // => get header

C++98/STL source code to parse National Imagery Transmission Format

nitf.h

#ifndef NITF_H_
#define NITF_H_

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

#include "kaitai/kaitaistruct.h"
#include <stdint.h>
#include <vector>

#if KAITAI_STRUCT_VERSION < 9000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required"
#endif

/**
 * The NITF (National Image Transition Format) format is a file format developed by the U.S. Government for
 * storing imagery, e.g. from satellites.
 * 
 * According to the [foreword of the specification](https://gwg.nga.mil/ntb/baseline/docs/2500c/2500C.pdf):
 * > The National Imagery Transmission Format Standard (NITFS) is the suite of standards for formatting digital
 * > imagery and imagery-related products and exchanging them among members of the Intelligence Community (IC) as
 * > defined by the Executive Order 12333, and other United States Government departments and agencies."
 * 
 * This implementation is set to version format (`file_version`) of 02.10 and `standard_type` of `BF01`.
 * It was implemented by [River Loop Security](https://riverloopsecurity.com).
 * \sa https://gwg.nga.mil/ntb/baseline/docs/2500c/2500C.pdf Source
 */

class nitf_t : public kaitai::kstruct {

public:
    class reserved_extension_segment_t;
    class image_comment_t;
    class length_reserved_info_t;
    class tre_t;
    class band_info_t;
    class image_segment_t;
    class text_segment_t;
    class graphic_sub_header_t;
    class clasnfo_t;
    class length_graphic_info_t;
    class encrypt_t;
    class image_data_mask_t;
    class graphics_segment_t;
    class data_sub_header_t;
    class data_extension_segment_t;
    class data_sub_header_tre_t;
    class image_sub_header_t;
    class reserved_sub_header_t;
    class data_sub_header_base_t;
    class text_sub_header_t;
    class date_time_t;
    class header_t;
    class data_sub_header_streaming_t;
    class tre_header_t;
    class length_image_info_t;
    class length_data_info_t;
    class length_text_info_t;

    nitf_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, nitf_t* p__root = 0);

private:
    void _read();
    void _clean_up();

public:
    ~nitf_t();

    class reserved_extension_segment_t : public kaitai::kstruct {

    public:

        reserved_extension_segment_t(uint16_t p_idx, kaitai::kstream* p__io, nitf_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~reserved_extension_segment_t();

    private:
        reserved_sub_header_t* m_reserved_sub_header;
        std::string m_reserved_data_field;
        uint16_t m_idx;
        nitf_t* m__root;
        nitf_t* m__parent;
        std::string m__raw_reserved_sub_header;
        kaitai::kstream* m__io__raw_reserved_sub_header;

    public:
        reserved_sub_header_t* reserved_sub_header() const { return m_reserved_sub_header; }
        std::string reserved_data_field() const { return m_reserved_data_field; }
        uint16_t idx() const { return m_idx; }
        nitf_t* _root() const { return m__root; }
        nitf_t* _parent() const { return m__parent; }
        std::string _raw_reserved_sub_header() const { return m__raw_reserved_sub_header; }
        kaitai::kstream* _io__raw_reserved_sub_header() const { return m__io__raw_reserved_sub_header; }
    };

    class image_comment_t : public kaitai::kstruct {

    public:

        image_comment_t(kaitai::kstream* p__io, nitf_t::image_sub_header_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~image_comment_t();

    private:
        std::string m__unnamed0;
        nitf_t* m__root;
        nitf_t::image_sub_header_t* m__parent;

    public:
        std::string _unnamed0() const { return m__unnamed0; }
        nitf_t* _root() const { return m__root; }
        nitf_t::image_sub_header_t* _parent() const { return m__parent; }
    };

    class length_reserved_info_t : public kaitai::kstruct {

    public:

        length_reserved_info_t(kaitai::kstream* p__io, nitf_t::header_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~length_reserved_info_t();

    private:
        std::string m_length_reserved_extension_subheader;
        std::string m_length_reserved_extension_segment;
        nitf_t* m__root;
        nitf_t::header_t* m__parent;

    public:
        std::string length_reserved_extension_subheader() const { return m_length_reserved_extension_subheader; }
        std::string length_reserved_extension_segment() const { return m_length_reserved_extension_segment; }
        nitf_t* _root() const { return m__root; }
        nitf_t::header_t* _parent() const { return m__parent; }
    };

    class tre_t : public kaitai::kstruct {

    public:

        tre_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~tre_t();

    private:
        std::string m_extension_type_id;
        std::string m_edata_length;
        std::string m_edata;
        nitf_t* m__root;
        kaitai::kstruct* m__parent;

    public:

        /**
         * RETAG or CETAG
         */
        std::string extension_type_id() const { return m_extension_type_id; }

        /**
         * REL or CEL
         */
        std::string edata_length() const { return m_edata_length; }

        /**
         * REDATA or CEDATA
         */
        std::string edata() const { return m_edata; }
        nitf_t* _root() const { return m__root; }
        kaitai::kstruct* _parent() const { return m__parent; }
    };

    class band_info_t : public kaitai::kstruct {

    public:

        band_info_t(kaitai::kstream* p__io, nitf_t::image_sub_header_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~band_info_t();

    private:
        std::string m_representation;
        std::string m_subcategory;
        std::string m_img_filter_condition;
        std::string m_img_filter_code;
        std::string m_num_luts;
        std::string m_num_lut_entries;
        bool n_num_lut_entries;

    public:
        bool _is_null_num_lut_entries() { num_lut_entries(); return n_num_lut_entries; };

    private:
        std::vector<std::string>* m_luts;
        nitf_t* m__root;
        nitf_t::image_sub_header_t* m__parent;

    public:

        /**
         * Indicates processing required to display the nth band of image w.r.t. the general image type recorded by IREP field
         */
        std::string representation() const { return m_representation; }
        std::string subcategory() const { return m_subcategory; }
        std::string img_filter_condition() const { return m_img_filter_condition; }

        /**
         * Reserved
         */
        std::string img_filter_code() const { return m_img_filter_code; }
        std::string num_luts() const { return m_num_luts; }

        /**
         * Number of entries in each of the LUTs for the nth image band
         */
        std::string num_lut_entries() const { return m_num_lut_entries; }
        std::vector<std::string>* luts() const { return m_luts; }
        nitf_t* _root() const { return m__root; }
        nitf_t::image_sub_header_t* _parent() const { return m__parent; }
    };

    class image_segment_t : public kaitai::kstruct {

    public:

        image_segment_t(uint16_t p_idx, kaitai::kstream* p__io, nitf_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~image_segment_t();

    private:
        bool f_has_mask;
        bool m_has_mask;

    public:
        bool has_mask();

    private:
        image_sub_header_t* m_image_sub_header;
        image_data_mask_t* m_image_data_mask;
        bool n_image_data_mask;

    public:
        bool _is_null_image_data_mask() { image_data_mask(); return n_image_data_mask; };

    private:
        std::string m_image_data_field;
        bool n_image_data_field;

    public:
        bool _is_null_image_data_field() { image_data_field(); return n_image_data_field; };

    private:
        uint16_t m_idx;
        nitf_t* m__root;
        nitf_t* m__parent;

    public:
        image_sub_header_t* image_sub_header() const { return m_image_sub_header; }
        image_data_mask_t* image_data_mask() const { return m_image_data_mask; }
        std::string image_data_field() const { return m_image_data_field; }
        uint16_t idx() const { return m_idx; }
        nitf_t* _root() const { return m__root; }
        nitf_t* _parent() const { return m__parent; }
    };

    class text_segment_t : public kaitai::kstruct {

    public:

        text_segment_t(uint16_t p_idx, kaitai::kstream* p__io, nitf_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~text_segment_t();

    private:
        std::string m_text_sub_header;
        std::string m_text_data_field;
        uint16_t m_idx;
        nitf_t* m__root;
        nitf_t* m__parent;

    public:
        std::string text_sub_header() const { return m_text_sub_header; }
        std::string text_data_field() const { return m_text_data_field; }
        uint16_t idx() const { return m_idx; }
        nitf_t* _root() const { return m__root; }
        nitf_t* _parent() const { return m__parent; }
    };

    class graphic_sub_header_t : public kaitai::kstruct {

    public:

        graphic_sub_header_t(kaitai::kstream* p__io, nitf_t::graphics_segment_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~graphic_sub_header_t();

    private:
        std::string m_file_part_type_sy;
        std::string m_graphic_id;
        std::string m_graphic_name;
        clasnfo_t* m_graphic_classification;
        encrypt_t* m_encryption;
        std::string m_graphic_type;
        std::string m_reserved1;
        std::string m_graphic_display_level;
        std::string m_graphic_attachment_level;
        std::string m_graphic_location;
        std::string m_first_graphic_bound_loc;
        std::string m_graphic_color;
        std::string m_second_graphic_bound_loc;
        std::string m_reserved2;
        tre_header_t* m_graphics_extended_sub_header;
        nitf_t* m__root;
        nitf_t::graphics_segment_t* m__parent;

    public:
        std::string file_part_type_sy() const { return m_file_part_type_sy; }
        std::string graphic_id() const { return m_graphic_id; }
        std::string graphic_name() const { return m_graphic_name; }
        clasnfo_t* graphic_classification() const { return m_graphic_classification; }
        encrypt_t* encryption() const { return m_encryption; }
        std::string graphic_type() const { return m_graphic_type; }

        /**
         * Reserved
         */
        std::string reserved1() const { return m_reserved1; }
        std::string graphic_display_level() const { return m_graphic_display_level; }
        std::string graphic_attachment_level() const { return m_graphic_attachment_level; }
        std::string graphic_location() const { return m_graphic_location; }
        std::string first_graphic_bound_loc() const { return m_first_graphic_bound_loc; }
        std::string graphic_color() const { return m_graphic_color; }
        std::string second_graphic_bound_loc() const { return m_second_graphic_bound_loc; }

        /**
         * Reserved
         */
        std::string reserved2() const { return m_reserved2; }
        tre_header_t* graphics_extended_sub_header() const { return m_graphics_extended_sub_header; }
        nitf_t* _root() const { return m__root; }
        nitf_t::graphics_segment_t* _parent() const { return m__parent; }
    };

    class clasnfo_t : public kaitai::kstruct {

    public:

        clasnfo_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~clasnfo_t();

    private:
        std::string m_security_class;
        std::string m_security_system;
        std::string m_codewords;
        std::string m_control_and_handling;
        std::string m_releaseability;
        std::string m_declass_type;
        std::string m_declass_date;
        std::string m_declass_exemption;
        std::string m_downgrade;
        std::string m_downgrade_date;
        std::string m_class_text;
        std::string m_class_authority_type;
        std::string m_class_authority;
        std::string m_class_reason;
        std::string m_source_date;
        std::string m_control_number;
        nitf_t* m__root;
        kaitai::kstruct* m__parent;

    public:
        std::string security_class() const { return m_security_class; }
        std::string security_system() const { return m_security_system; }
        std::string codewords() const { return m_codewords; }
        std::string control_and_handling() const { return m_control_and_handling; }
        std::string releaseability() const { return m_releaseability; }
        std::string declass_type() const { return m_declass_type; }
        std::string declass_date() const { return m_declass_date; }
        std::string declass_exemption() const { return m_declass_exemption; }
        std::string downgrade() const { return m_downgrade; }
        std::string downgrade_date() const { return m_downgrade_date; }
        std::string class_text() const { return m_class_text; }
        std::string class_authority_type() const { return m_class_authority_type; }
        std::string class_authority() const { return m_class_authority; }
        std::string class_reason() const { return m_class_reason; }
        std::string source_date() const { return m_source_date; }
        std::string control_number() const { return m_control_number; }
        nitf_t* _root() const { return m__root; }
        kaitai::kstruct* _parent() const { return m__parent; }
    };

    class length_graphic_info_t : public kaitai::kstruct {

    public:

        length_graphic_info_t(kaitai::kstream* p__io, nitf_t::header_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~length_graphic_info_t();

    private:
        std::string m_length_graphic_subheader;
        std::string m_length_graphic_segment;
        nitf_t* m__root;
        nitf_t::header_t* m__parent;

    public:
        std::string length_graphic_subheader() const { return m_length_graphic_subheader; }
        std::string length_graphic_segment() const { return m_length_graphic_segment; }
        nitf_t* _root() const { return m__root; }
        nitf_t::header_t* _parent() const { return m__parent; }
    };

    class encrypt_t : public kaitai::kstruct {

    public:

        encrypt_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~encrypt_t();

    private:
        std::string m__unnamed0;
        nitf_t* m__root;
        kaitai::kstruct* m__parent;

    public:
        std::string _unnamed0() const { return m__unnamed0; }
        nitf_t* _root() const { return m__root; }
        kaitai::kstruct* _parent() const { return m__parent; }
    };

    class image_data_mask_t : public kaitai::kstruct {

    public:

        image_data_mask_t(kaitai::kstream* p__io, nitf_t::image_segment_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~image_data_mask_t();

    private:
        bool f_has_bmr;
        bool m_has_bmr;

    public:
        bool has_bmr();

    private:
        bool f_has_tmr;
        bool m_has_tmr;

    public:
        bool has_tmr();

    private:
        bool f_tmrbnd_size;
        int32_t m_tmrbnd_size;

    public:
        int32_t tmrbnd_size();

    private:
        bool f_tpxcd_size;
        int32_t m_tpxcd_size;

    public:
        int32_t tpxcd_size();

    private:
        bool f_total_size;
        int32_t m_total_size;

    public:
        int32_t total_size();

    private:
        bool f_bmrbnd_size;
        int32_t m_bmrbnd_size;

    public:
        int32_t bmrbnd_size();

    private:
        bool f_bmrtmr_count;
        int32_t m_bmrtmr_count;

    public:
        int32_t bmrtmr_count();

    private:
        uint32_t m_blocked_img_data_offset;
        uint16_t m_bmrlnth;
        uint16_t m_tmrlnth;
        uint16_t m_tpxcdlnth;
        std::string m_tpxcd;
        std::vector<uint32_t>* m_bmrbnd;
        bool n_bmrbnd;

    public:
        bool _is_null_bmrbnd() { bmrbnd(); return n_bmrbnd; };

    private:
        std::vector<uint32_t>* m_tmrbnd;
        bool n_tmrbnd;

    public:
        bool _is_null_tmrbnd() { tmrbnd(); return n_tmrbnd; };

    private:
        nitf_t* m__root;
        nitf_t::image_segment_t* m__parent;

    public:
        uint32_t blocked_img_data_offset() const { return m_blocked_img_data_offset; }

        /**
         * Block Mask Record Length
         */
        uint16_t bmrlnth() const { return m_bmrlnth; }

        /**
         * Pad Pixel Mask Record Length
         */
        uint16_t tmrlnth() const { return m_tmrlnth; }

        /**
         * Pad Output Pixel Code Length
         */
        uint16_t tpxcdlnth() const { return m_tpxcdlnth; }

        /**
         * Pad Output Pixel Code
         */
        std::string tpxcd() const { return m_tpxcd; }

        /**
         * Block n, Band m Offset
         */
        std::vector<uint32_t>* bmrbnd() const { return m_bmrbnd; }

        /**
         * Pad Pixel n, Band m
         */
        std::vector<uint32_t>* tmrbnd() const { return m_tmrbnd; }
        nitf_t* _root() const { return m__root; }
        nitf_t::image_segment_t* _parent() const { return m__parent; }
    };

    class graphics_segment_t : public kaitai::kstruct {

    public:

        graphics_segment_t(uint16_t p_idx, kaitai::kstream* p__io, nitf_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~graphics_segment_t();

    private:
        graphic_sub_header_t* m_graphic_sub_header;
        std::string m_graphic_data_field;
        uint16_t m_idx;
        nitf_t* m__root;
        nitf_t* m__parent;

    public:
        graphic_sub_header_t* graphic_sub_header() const { return m_graphic_sub_header; }
        std::string graphic_data_field() const { return m_graphic_data_field; }
        uint16_t idx() const { return m_idx; }
        nitf_t* _root() const { return m__root; }
        nitf_t* _parent() const { return m__parent; }
    };

    class data_sub_header_t : public kaitai::kstruct {

    public:

        data_sub_header_t(kaitai::kstream* p__io, nitf_t::data_extension_segment_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~data_sub_header_t();

    private:
        bool f_tre_ofl;
        bool m_tre_ofl;

    public:
        bool tre_ofl();

    private:
        data_sub_header_base_t* m_des_base;
        std::string m_overflowed_header_type;
        bool n_overflowed_header_type;

    public:
        bool _is_null_overflowed_header_type() { overflowed_header_type(); return n_overflowed_header_type; };

    private:
        std::string m_data_item_overflowed;
        bool n_data_item_overflowed;

    public:
        bool _is_null_data_item_overflowed() { data_item_overflowed(); return n_data_item_overflowed; };

    private:
        std::string m_des_defined_subheader_fields_len;
        std::string m_desshf;
        std::string m_des_defined_data_field;
        nitf_t* m__root;
        nitf_t::data_extension_segment_t* m__parent;

    public:
        data_sub_header_base_t* des_base() const { return m_des_base; }
        std::string overflowed_header_type() const { return m_overflowed_header_type; }
        std::string data_item_overflowed() const { return m_data_item_overflowed; }
        std::string des_defined_subheader_fields_len() const { return m_des_defined_subheader_fields_len; }
        std::string desshf() const { return m_desshf; }
        std::string des_defined_data_field() const { return m_des_defined_data_field; }
        nitf_t* _root() const { return m__root; }
        nitf_t::data_extension_segment_t* _parent() const { return m__parent; }
    };

    class data_extension_segment_t : public kaitai::kstruct {

    public:

        data_extension_segment_t(uint16_t p_idx, kaitai::kstream* p__io, nitf_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~data_extension_segment_t();

    private:
        data_sub_header_t* m_data_sub_header;
        std::string m_data_data_field;
        uint16_t m_idx;
        nitf_t* m__root;
        nitf_t* m__parent;
        std::string m__raw_data_sub_header;
        kaitai::kstream* m__io__raw_data_sub_header;

    public:
        data_sub_header_t* data_sub_header() const { return m_data_sub_header; }
        std::string data_data_field() const { return m_data_data_field; }
        uint16_t idx() const { return m_idx; }
        nitf_t* _root() const { return m__root; }
        nitf_t* _parent() const { return m__parent; }
        std::string _raw_data_sub_header() const { return m__raw_data_sub_header; }
        kaitai::kstream* _io__raw_data_sub_header() const { return m__io__raw_data_sub_header; }
    };

    class data_sub_header_tre_t : public kaitai::kstruct {

    public:

        data_sub_header_tre_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~data_sub_header_tre_t();

    private:
        data_sub_header_base_t* m_des_base;
        std::string m_overflowed_header_type;
        bool n_overflowed_header_type;

    public:
        bool _is_null_overflowed_header_type() { overflowed_header_type(); return n_overflowed_header_type; };

    private:
        std::string m_data_item_overflowed;
        bool n_data_item_overflowed;

    public:
        bool _is_null_data_item_overflowed() { data_item_overflowed(); return n_data_item_overflowed; };

    private:
        std::string m_des_defined_subheader_fields_len;
        std::string m_des_defined_data_field;
        nitf_t* m__root;
        kaitai::kstruct* m__parent;

    public:
        data_sub_header_base_t* des_base() const { return m_des_base; }
        std::string overflowed_header_type() const { return m_overflowed_header_type; }
        std::string data_item_overflowed() const { return m_data_item_overflowed; }
        std::string des_defined_subheader_fields_len() const { return m_des_defined_subheader_fields_len; }
        std::string des_defined_data_field() const { return m_des_defined_data_field; }
        nitf_t* _root() const { return m__root; }
        kaitai::kstruct* _parent() const { return m__parent; }
    };

    class image_sub_header_t : public kaitai::kstruct {

    public:

        image_sub_header_t(kaitai::kstream* p__io, nitf_t::image_segment_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~image_sub_header_t();

    private:
        std::string m_file_part_type;
        std::string m_image_id_1;
        date_time_t* m_image_date_time;
        std::string m_target_id;
        std::string m_image_id_2;
        clasnfo_t* m_image_security_classification;
        encrypt_t* m_encryption;
        std::string m_image_source;
        std::string m_num_sig_rows;
        std::string m_num_sig_cols;
        std::string m_pixel_value_type;
        std::string m_image_representation;
        std::string m_image_category;
        std::string m_actual_bits_per_pixel_per_band;
        std::string m_pixel_justification;
        std::string m_image_coordinate_rep;
        std::string m_image_geo_loc;
        std::string m_num_img_comments;
        std::vector<image_comment_t*>* m_img_comments;
        std::string m_img_compression;
        std::string m_compression_rate_code;
        std::string m_num_bands;
        std::string m_num_multispectral_bands;
        bool n_num_multispectral_bands;

    public:
        bool _is_null_num_multispectral_bands() { num_multispectral_bands(); return n_num_multispectral_bands; };

    private:
        std::vector<band_info_t*>* m_bands;
        std::string m_img_sync_code;
        std::string m_img_mode;
        std::string m_num_blocks_per_row;
        std::string m_num_blocks_per_col;
        std::string m_num_pixels_per_block_horz;
        std::string m_num_pixels_per_block_vert;
        std::string m_num_pixels_per_band;
        std::string m_img_display_level;
        std::string m_attachment_level;
        std::string m_img_location;
        std::string m_img_magnification;
        std::string m_user_def_img_data_len;
        std::string m_user_def_overflow;
        bool n_user_def_overflow;

    public:
        bool _is_null_user_def_overflow() { user_def_overflow(); return n_user_def_overflow; };

    private:
        std::vector<uint8_t>* m_user_def_img_data;
        bool n_user_def_img_data;

    public:
        bool _is_null_user_def_img_data() { user_def_img_data(); return n_user_def_img_data; };

    private:
        tre_header_t* m_image_extended_sub_header;
        nitf_t* m__root;
        nitf_t::image_segment_t* m__parent;

    public:
        std::string file_part_type() const { return m_file_part_type; }
        std::string image_id_1() const { return m_image_id_1; }
        date_time_t* image_date_time() const { return m_image_date_time; }
        std::string target_id() const { return m_target_id; }
        std::string image_id_2() const { return m_image_id_2; }
        clasnfo_t* image_security_classification() const { return m_image_security_classification; }
        encrypt_t* encryption() const { return m_encryption; }
        std::string image_source() const { return m_image_source; }

        /**
         * Total number of rows of significant pixels in the image; only rows indexed 0 to (NROWS - 1) of the image contain significant data.
         */
        std::string num_sig_rows() const { return m_num_sig_rows; }
        std::string num_sig_cols() const { return m_num_sig_cols; }
        std::string pixel_value_type() const { return m_pixel_value_type; }

        /**
         * MONO, RGB, RGB/LUT, MULTI, NODISPLY, NVECTOR, POLAR, VPH, YCbCr601
         */
        std::string image_representation() const { return m_image_representation; }

        /**
         * VIS, SL, TI, FL, RD, EO, OP, HR, HS,CP, BP, SAR, SARIQ, IR, MAP, MS, FP, MRI, XRAY, CAT, VD, PAT, LEG, DTEM, MATR, LOCG, BARO, CURRENT, DEPTH, WIND
         */
        std::string image_category() const { return m_image_category; }
        std::string actual_bits_per_pixel_per_band() const { return m_actual_bits_per_pixel_per_band; }
        std::string pixel_justification() const { return m_pixel_justification; }
        std::string image_coordinate_rep() const { return m_image_coordinate_rep; }
        std::string image_geo_loc() const { return m_image_geo_loc; }
        std::string num_img_comments() const { return m_num_img_comments; }
        std::vector<image_comment_t*>* img_comments() const { return m_img_comments; }
        std::string img_compression() const { return m_img_compression; }
        std::string compression_rate_code() const { return m_compression_rate_code; }
        std::string num_bands() const { return m_num_bands; }
        std::string num_multispectral_bands() const { return m_num_multispectral_bands; }
        std::vector<band_info_t*>* bands() const { return m_bands; }

        /**
         * Reserved for future use.
         */
        std::string img_sync_code() const { return m_img_sync_code; }

        /**
         * B = Band Interleaved by Block, P = Band Interleaved by Pixel, R = Band Interleaved by Row, S = Band Sequential
         */
        std::string img_mode() const { return m_img_mode; }
        std::string num_blocks_per_row() const { return m_num_blocks_per_row; }
        std::string num_blocks_per_col() const { return m_num_blocks_per_col; }
        std::string num_pixels_per_block_horz() const { return m_num_pixels_per_block_horz; }
        std::string num_pixels_per_block_vert() const { return m_num_pixels_per_block_vert; }
        std::string num_pixels_per_band() const { return m_num_pixels_per_band; }
        std::string img_display_level() const { return m_img_display_level; }
        std::string attachment_level() const { return m_attachment_level; }
        std::string img_location() const { return m_img_location; }
        std::string img_magnification() const { return m_img_magnification; }
        std::string user_def_img_data_len() const { return m_user_def_img_data_len; }
        std::string user_def_overflow() const { return m_user_def_overflow; }
        std::vector<uint8_t>* user_def_img_data() const { return m_user_def_img_data; }
        tre_header_t* image_extended_sub_header() const { return m_image_extended_sub_header; }
        nitf_t* _root() const { return m__root; }
        nitf_t::image_segment_t* _parent() const { return m__parent; }
    };

    class reserved_sub_header_t : public kaitai::kstruct {

    public:

        reserved_sub_header_t(kaitai::kstream* p__io, nitf_t::reserved_extension_segment_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~reserved_sub_header_t();

    private:
        std::string m_file_part_type_re;
        std::string m_res_type_id;
        std::string m_res_version;
        clasnfo_t* m_reclasnfo;
        std::string m_res_user_defined_subheader_length;
        std::string m_res_user_defined_subheader_fields;
        std::string m_res_user_defined_data;
        nitf_t* m__root;
        nitf_t::reserved_extension_segment_t* m__parent;

    public:
        std::string file_part_type_re() const { return m_file_part_type_re; }
        std::string res_type_id() const { return m_res_type_id; }
        std::string res_version() const { return m_res_version; }
        clasnfo_t* reclasnfo() const { return m_reclasnfo; }
        std::string res_user_defined_subheader_length() const { return m_res_user_defined_subheader_length; }
        std::string res_user_defined_subheader_fields() const { return m_res_user_defined_subheader_fields; }
        std::string res_user_defined_data() const { return m_res_user_defined_data; }
        nitf_t* _root() const { return m__root; }
        nitf_t::reserved_extension_segment_t* _parent() const { return m__parent; }
    };

    class data_sub_header_base_t : public kaitai::kstruct {

    public:

        data_sub_header_base_t(kaitai::kstream* p__io, nitf_t::data_sub_header_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~data_sub_header_base_t();

    private:
        std::string m_file_part_type_de;
        std::string m_desid;
        std::string m_data_definition_version;
        clasnfo_t* m_declasnfo;
        nitf_t* m__root;
        nitf_t::data_sub_header_t* m__parent;

    public:

        /**
         * File Part Type desigantor for Data Extension
         */
        std::string file_part_type_de() const { return m_file_part_type_de; }
        std::string desid() const { return m_desid; }
        std::string data_definition_version() const { return m_data_definition_version; }
        clasnfo_t* declasnfo() const { return m_declasnfo; }
        nitf_t* _root() const { return m__root; }
        nitf_t::data_sub_header_t* _parent() const { return m__parent; }
    };

    class text_sub_header_t : public kaitai::kstruct {

    public:

        text_sub_header_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~text_sub_header_t();

    private:
        std::string m_text_date_time;
        std::string m_text_title;
        clasnfo_t* m_text_security_class;
        encrypt_t* m_encryp;
        std::string m_text_format;
        tre_header_t* m_text_extended_sub_header;
        nitf_t* m__root;
        kaitai::kstruct* m__parent;

    public:
        std::string text_date_time() const { return m_text_date_time; }
        std::string text_title() const { return m_text_title; }
        clasnfo_t* text_security_class() const { return m_text_security_class; }
        encrypt_t* encryp() const { return m_encryp; }

        /**
         * MTF (USMTF see MIL-STD-6040), STA (indicates BCS), UT1 (indicates ECS), U8S
         */
        std::string text_format() const { return m_text_format; }
        tre_header_t* text_extended_sub_header() const { return m_text_extended_sub_header; }
        nitf_t* _root() const { return m__root; }
        kaitai::kstruct* _parent() const { return m__parent; }
    };

    class date_time_t : public kaitai::kstruct {

    public:

        date_time_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~date_time_t();

    private:
        std::string m__unnamed0;
        nitf_t* m__root;
        kaitai::kstruct* m__parent;

    public:

        /**
         * UTC time of image acquisition in the format CCYYMMDDhhmmss: CC century, YY last two digits of the year, MM month, DD day, hh hour, mm minute, ss second
         */
        std::string _unnamed0() const { return m__unnamed0; }
        nitf_t* _root() const { return m__root; }
        kaitai::kstruct* _parent() const { return m__parent; }
    };

    class header_t : public kaitai::kstruct {

    public:

        header_t(kaitai::kstream* p__io, nitf_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~header_t();

    private:
        std::string m_file_profile_name;
        std::string m_file_version;
        std::string m_complexity_level;
        std::string m_standard_type;
        std::string m_originating_station_id;
        date_time_t* m_file_date_time;
        std::string m_file_title;
        clasnfo_t* m_file_security;
        std::string m_file_copy_number;
        std::string m_file_num_of_copys;
        encrypt_t* m_encryption;
        std::string m_file_bg_color;
        std::string m_originator_name;
        std::string m_originator_phone;
        std::string m_file_length;
        std::string m_file_header_length;
        std::string m_num_image_segments;
        std::vector<length_image_info_t*>* m_linfo;
        std::string m_num_graphics_segments;
        std::vector<length_graphic_info_t*>* m_lnnfo;
        std::string m_reserved_numx;
        std::string m_num_text_files;
        std::vector<length_text_info_t*>* m_ltnfo;
        std::string m_num_data_extension;
        std::vector<length_data_info_t*>* m_ldnfo;
        std::string m_num_reserved_extension;
        std::vector<length_reserved_info_t*>* m_lrnfo;
        tre_header_t* m_user_defined_header;
        tre_header_t* m_extended_header;
        nitf_t* m__root;
        nitf_t* m__parent;

    public:
        std::string file_profile_name() const { return m_file_profile_name; }
        std::string file_version() const { return m_file_version; }
        std::string complexity_level() const { return m_complexity_level; }

        /**
         * Value of BF01 indicates the file is formatted using ISO/IEC IS 12087-5.
         */
        std::string standard_type() const { return m_standard_type; }
        std::string originating_station_id() const { return m_originating_station_id; }
        date_time_t* file_date_time() const { return m_file_date_time; }
        std::string file_title() const { return m_file_title; }
        clasnfo_t* file_security() const { return m_file_security; }
        std::string file_copy_number() const { return m_file_copy_number; }
        std::string file_num_of_copys() const { return m_file_num_of_copys; }
        encrypt_t* encryption() const { return m_encryption; }
        std::string file_bg_color() const { return m_file_bg_color; }
        std::string originator_name() const { return m_originator_name; }
        std::string originator_phone() const { return m_originator_phone; }
        std::string file_length() const { return m_file_length; }
        std::string file_header_length() const { return m_file_header_length; }
        std::string num_image_segments() const { return m_num_image_segments; }
        std::vector<length_image_info_t*>* linfo() const { return m_linfo; }
        std::string num_graphics_segments() const { return m_num_graphics_segments; }
        std::vector<length_graphic_info_t*>* lnnfo() const { return m_lnnfo; }
        std::string reserved_numx() const { return m_reserved_numx; }
        std::string num_text_files() const { return m_num_text_files; }
        std::vector<length_text_info_t*>* ltnfo() const { return m_ltnfo; }
        std::string num_data_extension() const { return m_num_data_extension; }
        std::vector<length_data_info_t*>* ldnfo() const { return m_ldnfo; }
        std::string num_reserved_extension() const { return m_num_reserved_extension; }
        std::vector<length_reserved_info_t*>* lrnfo() const { return m_lrnfo; }
        tre_header_t* user_defined_header() const { return m_user_defined_header; }
        tre_header_t* extended_header() const { return m_extended_header; }
        nitf_t* _root() const { return m__root; }
        nitf_t* _parent() const { return m__parent; }
    };

    /**
     * Streaming file Header Data Extension Segment Subheader
     */

    class data_sub_header_streaming_t : public kaitai::kstruct {

    public:

        data_sub_header_streaming_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~data_sub_header_streaming_t();

    private:
        data_sub_header_base_t* m_des_base;
        std::string m_des_defined_subheader_fields_len;
        std::string m_sfh_l1;
        uint32_t m_sfh_delim1;
        std::vector<uint8_t>* m_sfh_dr;
        uint32_t m_sfh_delim2;
        std::string m_sfh_l2;
        nitf_t* m__root;
        kaitai::kstruct* m__parent;

    public:
        data_sub_header_base_t* des_base() const { return m_des_base; }
        std::string des_defined_subheader_fields_len() const { return m_des_defined_subheader_fields_len; }

        /**
         * SFH Length 1: number of bytes in sfh_dr field
         */
        std::string sfh_l1() const { return m_sfh_l1; }

        /**
         * Shall contain the value 0x0A6E1D97.
         */
        uint32_t sfh_delim1() const { return m_sfh_delim1; }
        std::vector<uint8_t>* sfh_dr() const { return m_sfh_dr; }

        /**
         * Shall contain the value 0x0ECA14BF.
         */
        uint32_t sfh_delim2() const { return m_sfh_delim2; }

        /**
         * A repeat of sfh_l1.
         */
        std::string sfh_l2() const { return m_sfh_l2; }
        nitf_t* _root() const { return m__root; }
        kaitai::kstruct* _parent() const { return m__parent; }
    };

    class tre_header_t : public kaitai::kstruct {

    public:

        tre_header_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~tre_header_t();

    private:
        std::string m_header_data_length;
        std::string m_header_overflow;
        bool n_header_overflow;

    public:
        bool _is_null_header_overflow() { header_overflow(); return n_header_overflow; };

    private:
        std::vector<uint8_t>* m_header_data;
        bool n_header_data;

    public:
        bool _is_null_header_data() { header_data(); return n_header_data; };

    private:
        nitf_t* m__root;
        kaitai::kstruct* m__parent;

    public:
        std::string header_data_length() const { return m_header_data_length; }
        std::string header_overflow() const { return m_header_overflow; }
        std::vector<uint8_t>* header_data() const { return m_header_data; }
        nitf_t* _root() const { return m__root; }
        kaitai::kstruct* _parent() const { return m__parent; }
    };

    class length_image_info_t : public kaitai::kstruct {

    public:

        length_image_info_t(kaitai::kstream* p__io, nitf_t::header_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~length_image_info_t();

    private:
        std::string m_length_image_subheader;
        std::string m_length_image_segment;
        nitf_t* m__root;
        nitf_t::header_t* m__parent;

    public:
        std::string length_image_subheader() const { return m_length_image_subheader; }
        std::string length_image_segment() const { return m_length_image_segment; }
        nitf_t* _root() const { return m__root; }
        nitf_t::header_t* _parent() const { return m__parent; }
    };

    class length_data_info_t : public kaitai::kstruct {

    public:

        length_data_info_t(kaitai::kstream* p__io, nitf_t::header_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~length_data_info_t();

    private:
        std::string m_length_data_extension_subheader;
        std::string m_length_data_extension_segment;
        nitf_t* m__root;
        nitf_t::header_t* m__parent;

    public:
        std::string length_data_extension_subheader() const { return m_length_data_extension_subheader; }
        std::string length_data_extension_segment() const { return m_length_data_extension_segment; }
        nitf_t* _root() const { return m__root; }
        nitf_t::header_t* _parent() const { return m__parent; }
    };

    class length_text_info_t : public kaitai::kstruct {

    public:

        length_text_info_t(kaitai::kstream* p__io, nitf_t::header_t* p__parent = 0, nitf_t* p__root = 0);

    private:
        void _read();
        void _clean_up();

    public:
        ~length_text_info_t();

    private:
        std::string m_length_text_subheader;
        std::string m_length_text_segment;
        nitf_t* m__root;
        nitf_t::header_t* m__parent;

    public:
        std::string length_text_subheader() const { return m_length_text_subheader; }
        std::string length_text_segment() const { return m_length_text_segment; }
        nitf_t* _root() const { return m__root; }
        nitf_t::header_t* _parent() const { return m__parent; }
    };

private:
    header_t* m_header;
    std::vector<image_segment_t*>* m_image_segments;
    std::vector<graphics_segment_t*>* m_graphics_segments;
    std::vector<text_segment_t*>* m_text_segments;
    std::vector<data_extension_segment_t*>* m_data_extension_segments;
    std::vector<reserved_extension_segment_t*>* m_reserved_extension_segments;
    nitf_t* m__root;
    kaitai::kstruct* m__parent;

public:
    header_t* header() const { return m_header; }
    std::vector<image_segment_t*>* image_segments() const { return m_image_segments; }
    std::vector<graphics_segment_t*>* graphics_segments() const { return m_graphics_segments; }
    std::vector<text_segment_t*>* text_segments() const { return m_text_segments; }
    std::vector<data_extension_segment_t*>* data_extension_segments() const { return m_data_extension_segments; }
    std::vector<reserved_extension_segment_t*>* reserved_extension_segments() const { return m_reserved_extension_segments; }
    nitf_t* _root() const { return m__root; }
    kaitai::kstruct* _parent() const { return m__parent; }
};

#endif  // NITF_H_

nitf.cpp

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

#include "nitf.h"
#include "kaitai/exceptions.h"

nitf_t::nitf_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = this;
    m_header = 0;
    m_image_segments = 0;
    m_graphics_segments = 0;
    m_text_segments = 0;
    m_data_extension_segments = 0;
    m_reserved_extension_segments = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::_read() {
    m_header = new header_t(m__io, this, m__root);
    int l_image_segments = std::stoi(header()->num_image_segments());
    m_image_segments = new std::vector<image_segment_t*>();
    m_image_segments->reserve(l_image_segments);
    for (int i = 0; i < l_image_segments; i++) {
        m_image_segments->push_back(new image_segment_t(i, m__io, this, m__root));
    }
    int l_graphics_segments = std::stoi(header()->num_graphics_segments());
    m_graphics_segments = new std::vector<graphics_segment_t*>();
    m_graphics_segments->reserve(l_graphics_segments);
    for (int i = 0; i < l_graphics_segments; i++) {
        m_graphics_segments->push_back(new graphics_segment_t(i, m__io, this, m__root));
    }
    int l_text_segments = std::stoi(header()->num_text_files());
    m_text_segments = new std::vector<text_segment_t*>();
    m_text_segments->reserve(l_text_segments);
    for (int i = 0; i < l_text_segments; i++) {
        m_text_segments->push_back(new text_segment_t(i, m__io, this, m__root));
    }
    int l_data_extension_segments = std::stoi(header()->num_data_extension());
    m_data_extension_segments = new std::vector<data_extension_segment_t*>();
    m_data_extension_segments->reserve(l_data_extension_segments);
    for (int i = 0; i < l_data_extension_segments; i++) {
        m_data_extension_segments->push_back(new data_extension_segment_t(i, m__io, this, m__root));
    }
    int l_reserved_extension_segments = std::stoi(header()->num_reserved_extension());
    m_reserved_extension_segments = new std::vector<reserved_extension_segment_t*>();
    m_reserved_extension_segments->reserve(l_reserved_extension_segments);
    for (int i = 0; i < l_reserved_extension_segments; i++) {
        m_reserved_extension_segments->push_back(new reserved_extension_segment_t(i, m__io, this, m__root));
    }
}

nitf_t::~nitf_t() {
    _clean_up();
}

void nitf_t::_clean_up() {
    if (m_header) {
        delete m_header; m_header = 0;
    }
    if (m_image_segments) {
        for (std::vector<image_segment_t*>::iterator it = m_image_segments->begin(); it != m_image_segments->end(); ++it) {
            delete *it;
        }
        delete m_image_segments; m_image_segments = 0;
    }
    if (m_graphics_segments) {
        for (std::vector<graphics_segment_t*>::iterator it = m_graphics_segments->begin(); it != m_graphics_segments->end(); ++it) {
            delete *it;
        }
        delete m_graphics_segments; m_graphics_segments = 0;
    }
    if (m_text_segments) {
        for (std::vector<text_segment_t*>::iterator it = m_text_segments->begin(); it != m_text_segments->end(); ++it) {
            delete *it;
        }
        delete m_text_segments; m_text_segments = 0;
    }
    if (m_data_extension_segments) {
        for (std::vector<data_extension_segment_t*>::iterator it = m_data_extension_segments->begin(); it != m_data_extension_segments->end(); ++it) {
            delete *it;
        }
        delete m_data_extension_segments; m_data_extension_segments = 0;
    }
    if (m_reserved_extension_segments) {
        for (std::vector<reserved_extension_segment_t*>::iterator it = m_reserved_extension_segments->begin(); it != m_reserved_extension_segments->end(); ++it) {
            delete *it;
        }
        delete m_reserved_extension_segments; m_reserved_extension_segments = 0;
    }
}

nitf_t::reserved_extension_segment_t::reserved_extension_segment_t(uint16_t p_idx, kaitai::kstream* p__io, nitf_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_idx = p_idx;
    m_reserved_sub_header = 0;
    m__io__raw_reserved_sub_header = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::reserved_extension_segment_t::_read() {
    m__raw_reserved_sub_header = m__io->read_bytes(std::stoi(_parent()->header()->lrnfo()->at(idx())->length_reserved_extension_subheader()));
    m__io__raw_reserved_sub_header = new kaitai::kstream(m__raw_reserved_sub_header);
    m_reserved_sub_header = new reserved_sub_header_t(m__io__raw_reserved_sub_header, this, m__root);
    m_reserved_data_field = m__io->read_bytes(std::stoi(_parent()->header()->lrnfo()->at(idx())->length_reserved_extension_segment()));
}

nitf_t::reserved_extension_segment_t::~reserved_extension_segment_t() {
    _clean_up();
}

void nitf_t::reserved_extension_segment_t::_clean_up() {
    if (m__io__raw_reserved_sub_header) {
        delete m__io__raw_reserved_sub_header; m__io__raw_reserved_sub_header = 0;
    }
    if (m_reserved_sub_header) {
        delete m_reserved_sub_header; m_reserved_sub_header = 0;
    }
}

nitf_t::image_comment_t::image_comment_t(kaitai::kstream* p__io, nitf_t::image_sub_header_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::image_comment_t::_read() {
    m__unnamed0 = kaitai::kstream::bytes_to_str(m__io->read_bytes(80), std::string("UTF-8"));
}

nitf_t::image_comment_t::~image_comment_t() {
    _clean_up();
}

void nitf_t::image_comment_t::_clean_up() {
}

nitf_t::length_reserved_info_t::length_reserved_info_t(kaitai::kstream* p__io, nitf_t::header_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::length_reserved_info_t::_read() {
    m_length_reserved_extension_subheader = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_length_reserved_extension_segment = kaitai::kstream::bytes_to_str(m__io->read_bytes(7), std::string("UTF-8"));
}

nitf_t::length_reserved_info_t::~length_reserved_info_t() {
    _clean_up();
}

void nitf_t::length_reserved_info_t::_clean_up() {
}

nitf_t::tre_t::tre_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::tre_t::_read() {
    m_extension_type_id = kaitai::kstream::bytes_to_str(m__io->read_bytes(6), std::string("UTF-8"));
    m_edata_length = kaitai::kstream::bytes_to_str(m__io->read_bytes(5), std::string("UTF-8"));
    m_edata = kaitai::kstream::bytes_to_str(m__io->read_bytes(std::stoi(edata_length())), std::string("UTF-8"));
}

nitf_t::tre_t::~tre_t() {
    _clean_up();
}

void nitf_t::tre_t::_clean_up() {
}

nitf_t::band_info_t::band_info_t(kaitai::kstream* p__io, nitf_t::image_sub_header_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_luts = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::band_info_t::_read() {
    m_representation = kaitai::kstream::bytes_to_str(m__io->read_bytes(2), std::string("UTF-8"));
    m_subcategory = kaitai::kstream::bytes_to_str(m__io->read_bytes(6), std::string("UTF-8"));
    m_img_filter_condition = m__io->read_bytes(1);
    if (!(img_filter_condition() == std::string("\x4E", 1))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x4E", 1), img_filter_condition(), _io(), std::string("/types/band_info/seq/2"));
    }
    m_img_filter_code = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    m_num_luts = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    n_num_lut_entries = true;
    if (std::stoi(num_luts()) != 0) {
        n_num_lut_entries = false;
        m_num_lut_entries = kaitai::kstream::bytes_to_str(m__io->read_bytes(5), std::string("UTF-8"));
    }
    int l_luts = std::stoi(num_luts());
    m_luts = new std::vector<std::string>();
    m_luts->reserve(l_luts);
    for (int i = 0; i < l_luts; i++) {
        m_luts->push_back(m__io->read_bytes(std::stoi(num_lut_entries())));
    }
}

nitf_t::band_info_t::~band_info_t() {
    _clean_up();
}

void nitf_t::band_info_t::_clean_up() {
    if (!n_num_lut_entries) {
    }
    if (m_luts) {
        delete m_luts; m_luts = 0;
    }
}

nitf_t::image_segment_t::image_segment_t(uint16_t p_idx, kaitai::kstream* p__io, nitf_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_idx = p_idx;
    m_image_sub_header = 0;
    m_image_data_mask = 0;
    f_has_mask = false;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::image_segment_t::_read() {
    m_image_sub_header = new image_sub_header_t(m__io, this, m__root);
    n_image_data_mask = true;
    if (has_mask()) {
        n_image_data_mask = false;
        m_image_data_mask = new image_data_mask_t(m__io, this, m__root);
    }
    n_image_data_field = true;
    if (has_mask()) {
        n_image_data_field = false;
        m_image_data_field = m__io->read_bytes((std::stoi(_parent()->header()->linfo()->at(idx())->length_image_segment()) - image_data_mask()->total_size()));
    }
}

nitf_t::image_segment_t::~image_segment_t() {
    _clean_up();
}

void nitf_t::image_segment_t::_clean_up() {
    if (m_image_sub_header) {
        delete m_image_sub_header; m_image_sub_header = 0;
    }
    if (!n_image_data_mask) {
        if (m_image_data_mask) {
            delete m_image_data_mask; m_image_data_mask = 0;
        }
    }
    if (!n_image_data_field) {
    }
}

bool nitf_t::image_segment_t::has_mask() {
    if (f_has_mask)
        return m_has_mask;
    m_has_mask = image_sub_header()->img_compression().substr(0, (2) - (0)) == (std::string("MM"));
    f_has_mask = true;
    return m_has_mask;
}

nitf_t::text_segment_t::text_segment_t(uint16_t p_idx, kaitai::kstream* p__io, nitf_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_idx = p_idx;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::text_segment_t::_read() {
    m_text_sub_header = m__io->read_bytes(1);
    m_text_data_field = m__io->read_bytes(std::stoi(_parent()->header()->ltnfo()->at(idx())->length_text_segment()));
}

nitf_t::text_segment_t::~text_segment_t() {
    _clean_up();
}

void nitf_t::text_segment_t::_clean_up() {
}

nitf_t::graphic_sub_header_t::graphic_sub_header_t(kaitai::kstream* p__io, nitf_t::graphics_segment_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_graphic_classification = 0;
    m_encryption = 0;
    m_graphics_extended_sub_header = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::graphic_sub_header_t::_read() {
    m_file_part_type_sy = m__io->read_bytes(2);
    if (!(file_part_type_sy() == std::string("\x53\x59", 2))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x53\x59", 2), file_part_type_sy(), _io(), std::string("/types/graphic_sub_header/seq/0"));
    }
    m_graphic_id = kaitai::kstream::bytes_to_str(m__io->read_bytes(10), std::string("UTF-8"));
    m_graphic_name = kaitai::kstream::bytes_to_str(m__io->read_bytes(20), std::string("UTF-8"));
    m_graphic_classification = new clasnfo_t(m__io, this, m__root);
    m_encryption = new encrypt_t(m__io, this, m__root);
    m_graphic_type = m__io->read_bytes(1);
    if (!(graphic_type() == std::string("\x43", 1))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x43", 1), graphic_type(), _io(), std::string("/types/graphic_sub_header/seq/5"));
    }
    m_reserved1 = kaitai::kstream::bytes_to_str(m__io->read_bytes(13), std::string("UTF-8"));
    m_graphic_display_level = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    m_graphic_attachment_level = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    m_graphic_location = kaitai::kstream::bytes_to_str(m__io->read_bytes(10), std::string("UTF-8"));
    m_first_graphic_bound_loc = kaitai::kstream::bytes_to_str(m__io->read_bytes(10), std::string("UTF-8"));
    m_graphic_color = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    m_second_graphic_bound_loc = kaitai::kstream::bytes_to_str(m__io->read_bytes(10), std::string("UTF-8"));
    m_reserved2 = kaitai::kstream::bytes_to_str(m__io->read_bytes(2), std::string("UTF-8"));
    m_graphics_extended_sub_header = new tre_header_t(m__io, this, m__root);
}

nitf_t::graphic_sub_header_t::~graphic_sub_header_t() {
    _clean_up();
}

void nitf_t::graphic_sub_header_t::_clean_up() {
    if (m_graphic_classification) {
        delete m_graphic_classification; m_graphic_classification = 0;
    }
    if (m_encryption) {
        delete m_encryption; m_encryption = 0;
    }
    if (m_graphics_extended_sub_header) {
        delete m_graphics_extended_sub_header; m_graphics_extended_sub_header = 0;
    }
}

nitf_t::clasnfo_t::clasnfo_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::clasnfo_t::_read() {
    m_security_class = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    m_security_system = kaitai::kstream::bytes_to_str(m__io->read_bytes(2), std::string("UTF-8"));
    m_codewords = kaitai::kstream::bytes_to_str(m__io->read_bytes(11), std::string("UTF-8"));
    m_control_and_handling = kaitai::kstream::bytes_to_str(m__io->read_bytes(2), std::string("UTF-8"));
    m_releaseability = kaitai::kstream::bytes_to_str(m__io->read_bytes(20), std::string("UTF-8"));
    m_declass_type = kaitai::kstream::bytes_to_str(m__io->read_bytes(2), std::string("UTF-8"));
    m_declass_date = kaitai::kstream::bytes_to_str(m__io->read_bytes(8), std::string("UTF-8"));
    m_declass_exemption = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_downgrade = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    m_downgrade_date = kaitai::kstream::bytes_to_str(m__io->read_bytes(8), std::string("UTF-8"));
    m_class_text = kaitai::kstream::bytes_to_str(m__io->read_bytes(43), std::string("UTF-8"));
    m_class_authority_type = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    m_class_authority = kaitai::kstream::bytes_to_str(m__io->read_bytes(40), std::string("UTF-8"));
    m_class_reason = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    m_source_date = kaitai::kstream::bytes_to_str(m__io->read_bytes(8), std::string("UTF-8"));
    m_control_number = kaitai::kstream::bytes_to_str(m__io->read_bytes(15), std::string("UTF-8"));
}

nitf_t::clasnfo_t::~clasnfo_t() {
    _clean_up();
}

void nitf_t::clasnfo_t::_clean_up() {
}

nitf_t::length_graphic_info_t::length_graphic_info_t(kaitai::kstream* p__io, nitf_t::header_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::length_graphic_info_t::_read() {
    m_length_graphic_subheader = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_length_graphic_segment = kaitai::kstream::bytes_to_str(m__io->read_bytes(6), std::string("UTF-8"));
}

nitf_t::length_graphic_info_t::~length_graphic_info_t() {
    _clean_up();
}

void nitf_t::length_graphic_info_t::_clean_up() {
}

nitf_t::encrypt_t::encrypt_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::encrypt_t::_read() {
    m__unnamed0 = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
}

nitf_t::encrypt_t::~encrypt_t() {
    _clean_up();
}

void nitf_t::encrypt_t::_clean_up() {
}

nitf_t::image_data_mask_t::image_data_mask_t(kaitai::kstream* p__io, nitf_t::image_segment_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_bmrbnd = 0;
    m_tmrbnd = 0;
    f_has_bmr = false;
    f_has_tmr = false;
    f_tmrbnd_size = false;
    f_tpxcd_size = false;
    f_total_size = false;
    f_bmrbnd_size = false;
    f_bmrtmr_count = false;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::image_data_mask_t::_read() {
    m_blocked_img_data_offset = m__io->read_u4be();
    m_bmrlnth = m__io->read_u2be();
    m_tmrlnth = m__io->read_u2be();
    m_tpxcdlnth = m__io->read_u2be();
    m_tpxcd = m__io->read_bytes(tpxcd_size());
    n_bmrbnd = true;
    if (has_bmr()) {
        n_bmrbnd = false;
        int l_bmrbnd = bmrtmr_count();
        m_bmrbnd = new std::vector<uint32_t>();
        m_bmrbnd->reserve(l_bmrbnd);
        for (int i = 0; i < l_bmrbnd; i++) {
            m_bmrbnd->push_back(m__io->read_u4be());
        }
    }
    n_tmrbnd = true;
    if (has_tmr()) {
        n_tmrbnd = false;
        int l_tmrbnd = bmrtmr_count();
        m_tmrbnd = new std::vector<uint32_t>();
        m_tmrbnd->reserve(l_tmrbnd);
        for (int i = 0; i < l_tmrbnd; i++) {
            m_tmrbnd->push_back(m__io->read_u4be());
        }
    }
}

nitf_t::image_data_mask_t::~image_data_mask_t() {
    _clean_up();
}

void nitf_t::image_data_mask_t::_clean_up() {
    if (!n_bmrbnd) {
        if (m_bmrbnd) {
            delete m_bmrbnd; m_bmrbnd = 0;
        }
    }
    if (!n_tmrbnd) {
        if (m_tmrbnd) {
            delete m_tmrbnd; m_tmrbnd = 0;
        }
    }
}

bool nitf_t::image_data_mask_t::has_bmr() {
    if (f_has_bmr)
        return m_has_bmr;
    m_has_bmr = bmrlnth() != 0;
    f_has_bmr = true;
    return m_has_bmr;
}

bool nitf_t::image_data_mask_t::has_tmr() {
    if (f_has_tmr)
        return m_has_tmr;
    m_has_tmr = tmrlnth() != 0;
    f_has_tmr = true;
    return m_has_tmr;
}

int32_t nitf_t::image_data_mask_t::tmrbnd_size() {
    if (f_tmrbnd_size)
        return m_tmrbnd_size;
    m_tmrbnd_size = ((has_tmr()) ? ((bmrtmr_count() * 4)) : (0));
    f_tmrbnd_size = true;
    return m_tmrbnd_size;
}

int32_t nitf_t::image_data_mask_t::tpxcd_size() {
    if (f_tpxcd_size)
        return m_tpxcd_size;
    m_tpxcd_size = (((kaitai::kstream::mod(tpxcdlnth(), 8) == 0) ? (tpxcdlnth()) : ((tpxcdlnth() + (8 - kaitai::kstream::mod(tpxcdlnth(), 8))))) / 8);
    f_tpxcd_size = true;
    return m_tpxcd_size;
}

int32_t nitf_t::image_data_mask_t::total_size() {
    if (f_total_size)
        return m_total_size;
    m_total_size = ((((((4 + 2) + 2) + 2) + tpxcd_size()) + bmrbnd_size()) + tmrbnd_size());
    f_total_size = true;
    return m_total_size;
}

int32_t nitf_t::image_data_mask_t::bmrbnd_size() {
    if (f_bmrbnd_size)
        return m_bmrbnd_size;
    m_bmrbnd_size = ((has_bmr()) ? ((bmrtmr_count() * 4)) : (0));
    f_bmrbnd_size = true;
    return m_bmrbnd_size;
}

int32_t nitf_t::image_data_mask_t::bmrtmr_count() {
    if (f_bmrtmr_count)
        return m_bmrtmr_count;
    m_bmrtmr_count = ((std::stoi(_parent()->image_sub_header()->num_blocks_per_row()) * std::stoi(_parent()->image_sub_header()->num_blocks_per_col())) * ((_parent()->image_sub_header()->img_mode() != std::string("S")) ? (1) : (((std::stoi(_parent()->image_sub_header()->num_bands()) != 0) ? (std::stoi(_parent()->image_sub_header()->num_bands())) : (std::stoi(_parent()->image_sub_header()->num_multispectral_bands()))))));
    f_bmrtmr_count = true;
    return m_bmrtmr_count;
}

nitf_t::graphics_segment_t::graphics_segment_t(uint16_t p_idx, kaitai::kstream* p__io, nitf_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_idx = p_idx;
    m_graphic_sub_header = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::graphics_segment_t::_read() {
    m_graphic_sub_header = new graphic_sub_header_t(m__io, this, m__root);
    m_graphic_data_field = m__io->read_bytes(std::stoi(_parent()->header()->lnnfo()->at(idx())->length_graphic_segment()));
}

nitf_t::graphics_segment_t::~graphics_segment_t() {
    _clean_up();
}

void nitf_t::graphics_segment_t::_clean_up() {
    if (m_graphic_sub_header) {
        delete m_graphic_sub_header; m_graphic_sub_header = 0;
    }
}

nitf_t::data_sub_header_t::data_sub_header_t(kaitai::kstream* p__io, nitf_t::data_extension_segment_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_des_base = 0;
    f_tre_ofl = false;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::data_sub_header_t::_read() {
    m_des_base = new data_sub_header_base_t(m__io, this, m__root);
    n_overflowed_header_type = true;
    if (tre_ofl()) {
        n_overflowed_header_type = false;
        m_overflowed_header_type = kaitai::kstream::bytes_to_str(m__io->read_bytes(6), std::string("UTF-8"));
    }
    n_data_item_overflowed = true;
    if (tre_ofl()) {
        n_data_item_overflowed = false;
        m_data_item_overflowed = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    }
    m_des_defined_subheader_fields_len = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_desshf = kaitai::kstream::bytes_to_str(m__io->read_bytes(std::stoi(des_defined_subheader_fields_len())), std::string("UTF-8"));
    m_des_defined_data_field = kaitai::kstream::bytes_to_str(m__io->read_bytes_full(), std::string("UTF-8"));
}

nitf_t::data_sub_header_t::~data_sub_header_t() {
    _clean_up();
}

void nitf_t::data_sub_header_t::_clean_up() {
    if (m_des_base) {
        delete m_des_base; m_des_base = 0;
    }
    if (!n_overflowed_header_type) {
    }
    if (!n_data_item_overflowed) {
    }
}

bool nitf_t::data_sub_header_t::tre_ofl() {
    if (f_tre_ofl)
        return m_tre_ofl;
    m_tre_ofl = des_base()->desid() == (std::string("TRE_OVERFLOW"));
    f_tre_ofl = true;
    return m_tre_ofl;
}

nitf_t::data_extension_segment_t::data_extension_segment_t(uint16_t p_idx, kaitai::kstream* p__io, nitf_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_idx = p_idx;
    m_data_sub_header = 0;
    m__io__raw_data_sub_header = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::data_extension_segment_t::_read() {
    m__raw_data_sub_header = m__io->read_bytes(std::stoi(_parent()->header()->ldnfo()->at(idx())->length_data_extension_subheader()));
    m__io__raw_data_sub_header = new kaitai::kstream(m__raw_data_sub_header);
    m_data_sub_header = new data_sub_header_t(m__io__raw_data_sub_header, this, m__root);
    m_data_data_field = m__io->read_bytes(std::stoi(_parent()->header()->ldnfo()->at(idx())->length_data_extension_segment()));
}

nitf_t::data_extension_segment_t::~data_extension_segment_t() {
    _clean_up();
}

void nitf_t::data_extension_segment_t::_clean_up() {
    if (m__io__raw_data_sub_header) {
        delete m__io__raw_data_sub_header; m__io__raw_data_sub_header = 0;
    }
    if (m_data_sub_header) {
        delete m_data_sub_header; m_data_sub_header = 0;
    }
}

nitf_t::data_sub_header_tre_t::data_sub_header_tre_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_des_base = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::data_sub_header_tre_t::_read() {
    m_des_base = new data_sub_header_base_t(m__io, this, m__root);
    n_overflowed_header_type = true;
    if (des_base()->desid() == (std::string("TRE_OVERFLOW"))) {
        n_overflowed_header_type = false;
        m_overflowed_header_type = kaitai::kstream::bytes_to_str(m__io->read_bytes(6), std::string("UTF-8"));
    }
    n_data_item_overflowed = true;
    if (des_base()->desid() == (std::string("TRE_OVERFLOW"))) {
        n_data_item_overflowed = false;
        m_data_item_overflowed = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    }
    m_des_defined_subheader_fields_len = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_des_defined_data_field = kaitai::kstream::bytes_to_str(m__io->read_bytes(std::stoi(des_defined_subheader_fields_len())), std::string("UTF-8"));
}

nitf_t::data_sub_header_tre_t::~data_sub_header_tre_t() {
    _clean_up();
}

void nitf_t::data_sub_header_tre_t::_clean_up() {
    if (m_des_base) {
        delete m_des_base; m_des_base = 0;
    }
    if (!n_overflowed_header_type) {
    }
    if (!n_data_item_overflowed) {
    }
}

nitf_t::image_sub_header_t::image_sub_header_t(kaitai::kstream* p__io, nitf_t::image_segment_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_image_date_time = 0;
    m_image_security_classification = 0;
    m_encryption = 0;
    m_img_comments = 0;
    m_bands = 0;
    m_user_def_img_data = 0;
    m_image_extended_sub_header = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::image_sub_header_t::_read() {
    m_file_part_type = m__io->read_bytes(2);
    if (!(file_part_type() == std::string("\x49\x4D", 2))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x49\x4D", 2), file_part_type(), _io(), std::string("/types/image_sub_header/seq/0"));
    }
    m_image_id_1 = kaitai::kstream::bytes_to_str(m__io->read_bytes(10), std::string("UTF-8"));
    m_image_date_time = new date_time_t(m__io, this, m__root);
    m_target_id = kaitai::kstream::bytes_to_str(m__io->read_bytes(17), std::string("UTF-8"));
    m_image_id_2 = kaitai::kstream::bytes_to_str(m__io->read_bytes(80), std::string("UTF-8"));
    m_image_security_classification = new clasnfo_t(m__io, this, m__root);
    m_encryption = new encrypt_t(m__io, this, m__root);
    m_image_source = kaitai::kstream::bytes_to_str(m__io->read_bytes(42), std::string("UTF-8"));
    m_num_sig_rows = kaitai::kstream::bytes_to_str(m__io->read_bytes(8), std::string("UTF-8"));
    m_num_sig_cols = kaitai::kstream::bytes_to_str(m__io->read_bytes(8), std::string("UTF-8"));
    m_pixel_value_type = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    m_image_representation = kaitai::kstream::bytes_to_str(m__io->read_bytes(8), std::string("UTF-8"));
    m_image_category = kaitai::kstream::bytes_to_str(m__io->read_bytes(8), std::string("UTF-8"));
    m_actual_bits_per_pixel_per_band = kaitai::kstream::bytes_to_str(m__io->read_bytes(2), std::string("UTF-8"));
    m_pixel_justification = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    m_image_coordinate_rep = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    m_image_geo_loc = kaitai::kstream::bytes_to_str(m__io->read_bytes(60), std::string("UTF-8"));
    m_num_img_comments = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    int l_img_comments = std::stoi(num_img_comments());
    m_img_comments = new std::vector<image_comment_t*>();
    m_img_comments->reserve(l_img_comments);
    for (int i = 0; i < l_img_comments; i++) {
        m_img_comments->push_back(new image_comment_t(m__io, this, m__root));
    }
    m_img_compression = kaitai::kstream::bytes_to_str(m__io->read_bytes(2), std::string("UTF-8"));
    m_compression_rate_code = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_num_bands = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    n_num_multispectral_bands = true;
    if (std::stoi(num_bands()) == 0) {
        n_num_multispectral_bands = false;
        m_num_multispectral_bands = kaitai::kstream::bytes_to_str(m__io->read_bytes(5), std::string("UTF-8"));
    }
    int l_bands = ((std::stoi(num_bands()) != 0) ? (std::stoi(num_bands())) : (std::stoi(num_multispectral_bands())));
    m_bands = new std::vector<band_info_t*>();
    m_bands->reserve(l_bands);
    for (int i = 0; i < l_bands; i++) {
        m_bands->push_back(new band_info_t(m__io, this, m__root));
    }
    m_img_sync_code = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    m_img_mode = kaitai::kstream::bytes_to_str(m__io->read_bytes(1), std::string("UTF-8"));
    m_num_blocks_per_row = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_num_blocks_per_col = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_num_pixels_per_block_horz = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_num_pixels_per_block_vert = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_num_pixels_per_band = kaitai::kstream::bytes_to_str(m__io->read_bytes(2), std::string("UTF-8"));
    m_img_display_level = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    m_attachment_level = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    m_img_location = kaitai::kstream::bytes_to_str(m__io->read_bytes(10), std::string("UTF-8"));
    m_img_magnification = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_user_def_img_data_len = kaitai::kstream::bytes_to_str(m__io->read_bytes(5), std::string("UTF-8"));
    n_user_def_overflow = true;
    if (std::stoi(user_def_img_data_len()) != 0) {
        n_user_def_overflow = false;
        m_user_def_overflow = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    }
    n_user_def_img_data = true;
    if (std::stoi(user_def_img_data_len()) > 2) {
        n_user_def_img_data = false;
        int l_user_def_img_data = (std::stoi(user_def_img_data_len()) - 3);
        m_user_def_img_data = new std::vector<uint8_t>();
        m_user_def_img_data->reserve(l_user_def_img_data);
        for (int i = 0; i < l_user_def_img_data; i++) {
            m_user_def_img_data->push_back(m__io->read_u1());
        }
    }
    m_image_extended_sub_header = new tre_header_t(m__io, this, m__root);
}

nitf_t::image_sub_header_t::~image_sub_header_t() {
    _clean_up();
}

void nitf_t::image_sub_header_t::_clean_up() {
    if (m_image_date_time) {
        delete m_image_date_time; m_image_date_time = 0;
    }
    if (m_image_security_classification) {
        delete m_image_security_classification; m_image_security_classification = 0;
    }
    if (m_encryption) {
        delete m_encryption; m_encryption = 0;
    }
    if (m_img_comments) {
        for (std::vector<image_comment_t*>::iterator it = m_img_comments->begin(); it != m_img_comments->end(); ++it) {
            delete *it;
        }
        delete m_img_comments; m_img_comments = 0;
    }
    if (!n_num_multispectral_bands) {
    }
    if (m_bands) {
        for (std::vector<band_info_t*>::iterator it = m_bands->begin(); it != m_bands->end(); ++it) {
            delete *it;
        }
        delete m_bands; m_bands = 0;
    }
    if (!n_user_def_overflow) {
    }
    if (!n_user_def_img_data) {
        if (m_user_def_img_data) {
            delete m_user_def_img_data; m_user_def_img_data = 0;
        }
    }
    if (m_image_extended_sub_header) {
        delete m_image_extended_sub_header; m_image_extended_sub_header = 0;
    }
}

nitf_t::reserved_sub_header_t::reserved_sub_header_t(kaitai::kstream* p__io, nitf_t::reserved_extension_segment_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_reclasnfo = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::reserved_sub_header_t::_read() {
    m_file_part_type_re = m__io->read_bytes(2);
    if (!(file_part_type_re() == std::string("\x52\x45", 2))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x52\x45", 2), file_part_type_re(), _io(), std::string("/types/reserved_sub_header/seq/0"));
    }
    m_res_type_id = kaitai::kstream::bytes_to_str(m__io->read_bytes(25), std::string("UTF-8"));
    m_res_version = kaitai::kstream::bytes_to_str(m__io->read_bytes(2), std::string("UTF-8"));
    m_reclasnfo = new clasnfo_t(m__io, this, m__root);
    m_res_user_defined_subheader_length = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_res_user_defined_subheader_fields = kaitai::kstream::bytes_to_str(m__io->read_bytes(std::stoi(res_user_defined_subheader_length())), std::string("UTF-8"));
    m_res_user_defined_data = kaitai::kstream::bytes_to_str(m__io->read_bytes_full(), std::string("UTF-8"));
}

nitf_t::reserved_sub_header_t::~reserved_sub_header_t() {
    _clean_up();
}

void nitf_t::reserved_sub_header_t::_clean_up() {
    if (m_reclasnfo) {
        delete m_reclasnfo; m_reclasnfo = 0;
    }
}

nitf_t::data_sub_header_base_t::data_sub_header_base_t(kaitai::kstream* p__io, nitf_t::data_sub_header_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_declasnfo = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::data_sub_header_base_t::_read() {
    m_file_part_type_de = m__io->read_bytes(2);
    if (!(file_part_type_de() == std::string("\x44\x45", 2))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x44\x45", 2), file_part_type_de(), _io(), std::string("/types/data_sub_header_base/seq/0"));
    }
    m_desid = kaitai::kstream::bytes_to_str(m__io->read_bytes(25), std::string("UTF-8"));
    m_data_definition_version = kaitai::kstream::bytes_to_str(m__io->read_bytes(2), std::string("UTF-8"));
    m_declasnfo = new clasnfo_t(m__io, this, m__root);
}

nitf_t::data_sub_header_base_t::~data_sub_header_base_t() {
    _clean_up();
}

void nitf_t::data_sub_header_base_t::_clean_up() {
    if (m_declasnfo) {
        delete m_declasnfo; m_declasnfo = 0;
    }
}

nitf_t::text_sub_header_t::text_sub_header_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_text_security_class = 0;
    m_encryp = 0;
    m_text_extended_sub_header = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::text_sub_header_t::_read() {
    m_text_date_time = kaitai::kstream::bytes_to_str(m__io->read_bytes(14), std::string("UTF-8"));
    m_text_title = kaitai::kstream::bytes_to_str(m__io->read_bytes(80), std::string("UTF-8"));
    m_text_security_class = new clasnfo_t(m__io, this, m__root);
    m_encryp = new encrypt_t(m__io, this, m__root);
    m_text_format = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    m_text_extended_sub_header = new tre_header_t(m__io, this, m__root);
}

nitf_t::text_sub_header_t::~text_sub_header_t() {
    _clean_up();
}

void nitf_t::text_sub_header_t::_clean_up() {
    if (m_text_security_class) {
        delete m_text_security_class; m_text_security_class = 0;
    }
    if (m_encryp) {
        delete m_encryp; m_encryp = 0;
    }
    if (m_text_extended_sub_header) {
        delete m_text_extended_sub_header; m_text_extended_sub_header = 0;
    }
}

nitf_t::date_time_t::date_time_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::date_time_t::_read() {
    m__unnamed0 = kaitai::kstream::bytes_to_str(m__io->read_bytes(14), std::string("UTF-8"));
}

nitf_t::date_time_t::~date_time_t() {
    _clean_up();
}

void nitf_t::date_time_t::_clean_up() {
}

nitf_t::header_t::header_t(kaitai::kstream* p__io, nitf_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_file_date_time = 0;
    m_file_security = 0;
    m_encryption = 0;
    m_linfo = 0;
    m_lnnfo = 0;
    m_ltnfo = 0;
    m_ldnfo = 0;
    m_lrnfo = 0;
    m_user_defined_header = 0;
    m_extended_header = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::header_t::_read() {
    m_file_profile_name = m__io->read_bytes(4);
    if (!(file_profile_name() == std::string("\x4E\x49\x54\x46", 4))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x4E\x49\x54\x46", 4), file_profile_name(), _io(), std::string("/types/header/seq/0"));
    }
    m_file_version = m__io->read_bytes(5);
    if (!(file_version() == std::string("\x30\x32\x2E\x31\x30", 5))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x30\x32\x2E\x31\x30", 5), file_version(), _io(), std::string("/types/header/seq/1"));
    }
    m_complexity_level = m__io->read_bytes(2);
    m_standard_type = m__io->read_bytes(4);
    if (!(standard_type() == std::string("\x42\x46\x30\x31", 4))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x42\x46\x30\x31", 4), standard_type(), _io(), std::string("/types/header/seq/3"));
    }
    m_originating_station_id = kaitai::kstream::bytes_to_str(m__io->read_bytes(10), std::string("UTF-8"));
    m_file_date_time = new date_time_t(m__io, this, m__root);
    m_file_title = kaitai::kstream::bytes_to_str(m__io->read_bytes(80), std::string("UTF-8"));
    m_file_security = new clasnfo_t(m__io, this, m__root);
    m_file_copy_number = kaitai::kstream::bytes_to_str(m__io->read_bytes(5), std::string("UTF-8"));
    m_file_num_of_copys = kaitai::kstream::bytes_to_str(m__io->read_bytes(5), std::string("UTF-8"));
    m_encryption = new encrypt_t(m__io, this, m__root);
    m_file_bg_color = m__io->read_bytes(3);
    m_originator_name = kaitai::kstream::bytes_to_str(m__io->read_bytes(24), std::string("UTF-8"));
    m_originator_phone = kaitai::kstream::bytes_to_str(m__io->read_bytes(18), std::string("UTF-8"));
    m_file_length = kaitai::kstream::bytes_to_str(m__io->read_bytes(12), std::string("UTF-8"));
    m_file_header_length = kaitai::kstream::bytes_to_str(m__io->read_bytes(6), std::string("UTF-8"));
    m_num_image_segments = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    int l_linfo = std::stoi(num_image_segments());
    m_linfo = new std::vector<length_image_info_t*>();
    m_linfo->reserve(l_linfo);
    for (int i = 0; i < l_linfo; i++) {
        m_linfo->push_back(new length_image_info_t(m__io, this, m__root));
    }
    m_num_graphics_segments = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    int l_lnnfo = std::stoi(num_graphics_segments());
    m_lnnfo = new std::vector<length_graphic_info_t*>();
    m_lnnfo->reserve(l_lnnfo);
    for (int i = 0; i < l_lnnfo; i++) {
        m_lnnfo->push_back(new length_graphic_info_t(m__io, this, m__root));
    }
    m_reserved_numx = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    m_num_text_files = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    int l_ltnfo = std::stoi(num_text_files());
    m_ltnfo = new std::vector<length_text_info_t*>();
    m_ltnfo->reserve(l_ltnfo);
    for (int i = 0; i < l_ltnfo; i++) {
        m_ltnfo->push_back(new length_text_info_t(m__io, this, m__root));
    }
    m_num_data_extension = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    int l_ldnfo = std::stoi(num_data_extension());
    m_ldnfo = new std::vector<length_data_info_t*>();
    m_ldnfo->reserve(l_ldnfo);
    for (int i = 0; i < l_ldnfo; i++) {
        m_ldnfo->push_back(new length_data_info_t(m__io, this, m__root));
    }
    m_num_reserved_extension = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    int l_lrnfo = std::stoi(num_reserved_extension());
    m_lrnfo = new std::vector<length_reserved_info_t*>();
    m_lrnfo->reserve(l_lrnfo);
    for (int i = 0; i < l_lrnfo; i++) {
        m_lrnfo->push_back(new length_reserved_info_t(m__io, this, m__root));
    }
    m_user_defined_header = new tre_header_t(m__io, this, m__root);
    m_extended_header = new tre_header_t(m__io, this, m__root);
}

nitf_t::header_t::~header_t() {
    _clean_up();
}

void nitf_t::header_t::_clean_up() {
    if (m_file_date_time) {
        delete m_file_date_time; m_file_date_time = 0;
    }
    if (m_file_security) {
        delete m_file_security; m_file_security = 0;
    }
    if (m_encryption) {
        delete m_encryption; m_encryption = 0;
    }
    if (m_linfo) {
        for (std::vector<length_image_info_t*>::iterator it = m_linfo->begin(); it != m_linfo->end(); ++it) {
            delete *it;
        }
        delete m_linfo; m_linfo = 0;
    }
    if (m_lnnfo) {
        for (std::vector<length_graphic_info_t*>::iterator it = m_lnnfo->begin(); it != m_lnnfo->end(); ++it) {
            delete *it;
        }
        delete m_lnnfo; m_lnnfo = 0;
    }
    if (m_ltnfo) {
        for (std::vector<length_text_info_t*>::iterator it = m_ltnfo->begin(); it != m_ltnfo->end(); ++it) {
            delete *it;
        }
        delete m_ltnfo; m_ltnfo = 0;
    }
    if (m_ldnfo) {
        for (std::vector<length_data_info_t*>::iterator it = m_ldnfo->begin(); it != m_ldnfo->end(); ++it) {
            delete *it;
        }
        delete m_ldnfo; m_ldnfo = 0;
    }
    if (m_lrnfo) {
        for (std::vector<length_reserved_info_t*>::iterator it = m_lrnfo->begin(); it != m_lrnfo->end(); ++it) {
            delete *it;
        }
        delete m_lrnfo; m_lrnfo = 0;
    }
    if (m_user_defined_header) {
        delete m_user_defined_header; m_user_defined_header = 0;
    }
    if (m_extended_header) {
        delete m_extended_header; m_extended_header = 0;
    }
}

nitf_t::data_sub_header_streaming_t::data_sub_header_streaming_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_des_base = 0;
    m_sfh_dr = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::data_sub_header_streaming_t::_read() {
    m_des_base = new data_sub_header_base_t(m__io, this, m__root);
    m_des_defined_subheader_fields_len = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_sfh_l1 = kaitai::kstream::bytes_to_str(m__io->read_bytes(7), std::string("UTF-8"));
    m_sfh_delim1 = m__io->read_u4be();
    int l_sfh_dr = std::stoi(sfh_l1());
    m_sfh_dr = new std::vector<uint8_t>();
    m_sfh_dr->reserve(l_sfh_dr);
    for (int i = 0; i < l_sfh_dr; i++) {
        m_sfh_dr->push_back(m__io->read_u1());
    }
    m_sfh_delim2 = m__io->read_u4be();
    m_sfh_l2 = kaitai::kstream::bytes_to_str(m__io->read_bytes(7), std::string("UTF-8"));
}

nitf_t::data_sub_header_streaming_t::~data_sub_header_streaming_t() {
    _clean_up();
}

void nitf_t::data_sub_header_streaming_t::_clean_up() {
    if (m_des_base) {
        delete m_des_base; m_des_base = 0;
    }
    if (m_sfh_dr) {
        delete m_sfh_dr; m_sfh_dr = 0;
    }
}

nitf_t::tre_header_t::tre_header_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_header_data = 0;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::tre_header_t::_read() {
    m_header_data_length = kaitai::kstream::bytes_to_str(m__io->read_bytes(5), std::string("UTF-8"));
    n_header_overflow = true;
    if (std::stoi(header_data_length()) != 0) {
        n_header_overflow = false;
        m_header_overflow = kaitai::kstream::bytes_to_str(m__io->read_bytes(3), std::string("UTF-8"));
    }
    n_header_data = true;
    if (std::stoi(header_data_length()) > 2) {
        n_header_data = false;
        int l_header_data = (std::stoi(header_data_length()) - 3);
        m_header_data = new std::vector<uint8_t>();
        m_header_data->reserve(l_header_data);
        for (int i = 0; i < l_header_data; i++) {
            m_header_data->push_back(m__io->read_u1());
        }
    }
}

nitf_t::tre_header_t::~tre_header_t() {
    _clean_up();
}

void nitf_t::tre_header_t::_clean_up() {
    if (!n_header_overflow) {
    }
    if (!n_header_data) {
        if (m_header_data) {
            delete m_header_data; m_header_data = 0;
        }
    }
}

nitf_t::length_image_info_t::length_image_info_t(kaitai::kstream* p__io, nitf_t::header_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::length_image_info_t::_read() {
    m_length_image_subheader = kaitai::kstream::bytes_to_str(m__io->read_bytes(6), std::string("UTF-8"));
    m_length_image_segment = kaitai::kstream::bytes_to_str(m__io->read_bytes(10), std::string("UTF-8"));
}

nitf_t::length_image_info_t::~length_image_info_t() {
    _clean_up();
}

void nitf_t::length_image_info_t::_clean_up() {
}

nitf_t::length_data_info_t::length_data_info_t(kaitai::kstream* p__io, nitf_t::header_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::length_data_info_t::_read() {
    m_length_data_extension_subheader = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_length_data_extension_segment = kaitai::kstream::bytes_to_str(m__io->read_bytes(9), std::string("UTF-8"));
}

nitf_t::length_data_info_t::~length_data_info_t() {
    _clean_up();
}

void nitf_t::length_data_info_t::_clean_up() {
}

nitf_t::length_text_info_t::length_text_info_t(kaitai::kstream* p__io, nitf_t::header_t* p__parent, nitf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;

    try {
        _read();
    } catch(...) {
        _clean_up();
        throw;
    }
}

void nitf_t::length_text_info_t::_read() {
    m_length_text_subheader = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("UTF-8"));
    m_length_text_segment = kaitai::kstream::bytes_to_str(m__io->read_bytes(5), std::string("UTF-8"));
}

nitf_t::length_text_info_t::~length_text_info_t() {
    _clean_up();
}

void nitf_t::length_text_info_t::_clean_up() {
}