National Imagery Transmission Format: Go 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.

Go source code to parse National Imagery Transmission Format

nitf.go

// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT.

import (
	"github.com/kaitai-io/kaitai_struct_go_runtime/kaitai"
	"strconv"
	"bytes"
)


/**
 * 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://web.archive.org/web/20181105050336/https://www.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://www.riverloopsecurity.com/).
 * @see <a href="https://web.archive.org/web/20181105050336/https://www.gwg.nga.mil/ntb/baseline/docs/2500c/2500C.pdf">Source</a>
 */
type Nitf struct {
	Header *Nitf_Header
	ImageSegments []*Nitf_ImageSegment
	GraphicsSegments []*Nitf_GraphicsSegment
	TextSegments []*Nitf_TextSegment
	DataExtensionSegments []*Nitf_DataExtensionSegment
	ReservedExtensionSegments []*Nitf_ReservedExtensionSegment
	_io *kaitai.Stream
	_root *Nitf
	_parent kaitai.Struct
}
func NewNitf() *Nitf {
	return &Nitf{
	}
}

func (this Nitf) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf) Read(io *kaitai.Stream, parent kaitai.Struct, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp1 := NewNitf_Header()
	err = tmp1.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Header = tmp1
	tmp2, err := strconv.ParseInt(this.Header.NumImageSegments, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp2); i++ {
		_ = i
		tmp3 := NewNitf_ImageSegment(i)
		err = tmp3.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.ImageSegments = append(this.ImageSegments, tmp3)
	}
	tmp4, err := strconv.ParseInt(this.Header.NumGraphicsSegments, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp4); i++ {
		_ = i
		tmp5 := NewNitf_GraphicsSegment(i)
		err = tmp5.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.GraphicsSegments = append(this.GraphicsSegments, tmp5)
	}
	tmp6, err := strconv.ParseInt(this.Header.NumTextFiles, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp6); i++ {
		_ = i
		tmp7 := NewNitf_TextSegment(i)
		err = tmp7.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.TextSegments = append(this.TextSegments, tmp7)
	}
	tmp8, err := strconv.ParseInt(this.Header.NumDataExtension, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp8); i++ {
		_ = i
		tmp9 := NewNitf_DataExtensionSegment(i)
		err = tmp9.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.DataExtensionSegments = append(this.DataExtensionSegments, tmp9)
	}
	tmp10, err := strconv.ParseInt(this.Header.NumReservedExtension, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp10); i++ {
		_ = i
		tmp11 := NewNitf_ReservedExtensionSegment(i)
		err = tmp11.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.ReservedExtensionSegments = append(this.ReservedExtensionSegments, tmp11)
	}
	return err
}
type Nitf_BandInfo struct {
	Representation string
	Subcategory string
	ImgFilterCondition []byte
	ImgFilterCode string
	NumLuts string
	NumLutEntries string
	Luts [][]byte
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_ImageSubHeader
}
func NewNitf_BandInfo() *Nitf_BandInfo {
	return &Nitf_BandInfo{
	}
}

func (this Nitf_BandInfo) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_BandInfo) Read(io *kaitai.Stream, parent *Nitf_ImageSubHeader, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp12, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp12 = tmp12
	this.Representation = string(tmp12)
	tmp13, err := this._io.ReadBytes(int(6))
	if err != nil {
		return err
	}
	tmp13 = tmp13
	this.Subcategory = string(tmp13)
	tmp14, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp14 = tmp14
	this.ImgFilterCondition = tmp14
	if !(bytes.Equal(this.ImgFilterCondition, []uint8{78})) {
		return kaitai.NewValidationNotEqualError([]uint8{78}, this.ImgFilterCondition, this._io, "/types/band_info/seq/2")
	}
	tmp15, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp15 = tmp15
	this.ImgFilterCode = string(tmp15)
	tmp16, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp16 = tmp16
	this.NumLuts = string(tmp16)
	tmp17, err := strconv.ParseInt(this.NumLuts, 10, 0)
	if err != nil {
		return err
	}
	if (tmp17 != 0) {
		tmp18, err := this._io.ReadBytes(int(5))
		if err != nil {
			return err
		}
		tmp18 = tmp18
		this.NumLutEntries = string(tmp18)
	}
	tmp19, err := strconv.ParseInt(this.NumLuts, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp19); i++ {
		_ = i
		tmp20, err := strconv.ParseInt(this.NumLutEntries, 10, 0)
		if err != nil {
			return err
		}
		tmp21, err := this._io.ReadBytes(int(tmp20))
		if err != nil {
			return err
		}
		tmp21 = tmp21
		this.Luts = append(this.Luts, tmp21)
	}
	return err
}

/**
 * Indicates processing required to display the nth band of image w.r.t. the general image type recorded by IREP field
 */

/**
 * Reserved
 */

/**
 * Number of entries in each of the LUTs for the nth image band
 */
type Nitf_Clasnfo struct {
	SecurityClass string
	SecuritySystem string
	Codewords string
	ControlAndHandling string
	Releaseability string
	DeclassType string
	DeclassDate string
	DeclassExemption string
	Downgrade string
	DowngradeDate string
	ClassText string
	ClassAuthorityType string
	ClassAuthority string
	ClassReason string
	SourceDate string
	ControlNumber string
	_io *kaitai.Stream
	_root *Nitf
	_parent kaitai.Struct
}
func NewNitf_Clasnfo() *Nitf_Clasnfo {
	return &Nitf_Clasnfo{
	}
}

func (this Nitf_Clasnfo) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_Clasnfo) Read(io *kaitai.Stream, parent kaitai.Struct, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp22, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp22 = tmp22
	this.SecurityClass = string(tmp22)
	tmp23, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp23 = tmp23
	this.SecuritySystem = string(tmp23)
	tmp24, err := this._io.ReadBytes(int(11))
	if err != nil {
		return err
	}
	tmp24 = tmp24
	this.Codewords = string(tmp24)
	tmp25, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp25 = tmp25
	this.ControlAndHandling = string(tmp25)
	tmp26, err := this._io.ReadBytes(int(20))
	if err != nil {
		return err
	}
	tmp26 = tmp26
	this.Releaseability = string(tmp26)
	tmp27, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp27 = tmp27
	this.DeclassType = string(tmp27)
	tmp28, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp28 = tmp28
	this.DeclassDate = string(tmp28)
	tmp29, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp29 = tmp29
	this.DeclassExemption = string(tmp29)
	tmp30, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp30 = tmp30
	this.Downgrade = string(tmp30)
	tmp31, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp31 = tmp31
	this.DowngradeDate = string(tmp31)
	tmp32, err := this._io.ReadBytes(int(43))
	if err != nil {
		return err
	}
	tmp32 = tmp32
	this.ClassText = string(tmp32)
	tmp33, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp33 = tmp33
	this.ClassAuthorityType = string(tmp33)
	tmp34, err := this._io.ReadBytes(int(40))
	if err != nil {
		return err
	}
	tmp34 = tmp34
	this.ClassAuthority = string(tmp34)
	tmp35, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp35 = tmp35
	this.ClassReason = string(tmp35)
	tmp36, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp36 = tmp36
	this.SourceDate = string(tmp36)
	tmp37, err := this._io.ReadBytes(int(15))
	if err != nil {
		return err
	}
	tmp37 = tmp37
	this.ControlNumber = string(tmp37)
	return err
}
type Nitf_DataExtensionSegment struct {
	DataSubHeader *Nitf_DataSubHeader
	DataDataField []byte
	Idx uint16
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf
	_raw_DataSubHeader []byte
}
func NewNitf_DataExtensionSegment(idx uint16) *Nitf_DataExtensionSegment {
	return &Nitf_DataExtensionSegment{
		Idx: idx,
	}
}

func (this Nitf_DataExtensionSegment) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_DataExtensionSegment) Read(io *kaitai.Stream, parent *Nitf, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp38, err := strconv.ParseInt(this._parent.Header.Ldnfo[this.Idx].LengthDataExtensionSubheader, 10, 0)
	if err != nil {
		return err
	}
	tmp39, err := this._io.ReadBytes(int(tmp38))
	if err != nil {
		return err
	}
	tmp39 = tmp39
	this._raw_DataSubHeader = tmp39
	_io__raw_DataSubHeader := kaitai.NewStream(bytes.NewReader(this._raw_DataSubHeader))
	tmp40 := NewNitf_DataSubHeader()
	err = tmp40.Read(_io__raw_DataSubHeader, this, this._root)
	if err != nil {
		return err
	}
	this.DataSubHeader = tmp40
	tmp41, err := strconv.ParseInt(this._parent.Header.Ldnfo[this.Idx].LengthDataExtensionSegment, 10, 0)
	if err != nil {
		return err
	}
	tmp42, err := this._io.ReadBytes(int(tmp41))
	if err != nil {
		return err
	}
	tmp42 = tmp42
	this.DataDataField = tmp42
	return err
}
type Nitf_DataSubHeader struct {
	DesBase *Nitf_DataSubHeaderBase
	OverflowedHeaderType string
	DataItemOverflowed string
	DesDefinedSubheaderFieldsLen string
	Desshf string
	DesDefinedDataField string
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_DataExtensionSegment
	_f_treOfl bool
	treOfl bool
}
func NewNitf_DataSubHeader() *Nitf_DataSubHeader {
	return &Nitf_DataSubHeader{
	}
}

func (this Nitf_DataSubHeader) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_DataSubHeader) Read(io *kaitai.Stream, parent *Nitf_DataExtensionSegment, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp43 := NewNitf_DataSubHeaderBase()
	err = tmp43.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.DesBase = tmp43
	tmp44, err := this.TreOfl()
	if err != nil {
		return err
	}
	if (tmp44) {
		tmp45, err := this._io.ReadBytes(int(6))
		if err != nil {
			return err
		}
		tmp45 = tmp45
		this.OverflowedHeaderType = string(tmp45)
	}
	tmp46, err := this.TreOfl()
	if err != nil {
		return err
	}
	if (tmp46) {
		tmp47, err := this._io.ReadBytes(int(3))
		if err != nil {
			return err
		}
		tmp47 = tmp47
		this.DataItemOverflowed = string(tmp47)
	}
	tmp48, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp48 = tmp48
	this.DesDefinedSubheaderFieldsLen = string(tmp48)
	tmp49, err := strconv.ParseInt(this.DesDefinedSubheaderFieldsLen, 10, 0)
	if err != nil {
		return err
	}
	tmp50, err := this._io.ReadBytes(int(tmp49))
	if err != nil {
		return err
	}
	tmp50 = tmp50
	this.Desshf = string(tmp50)
	tmp51, err := this._io.ReadBytesFull()
	if err != nil {
		return err
	}
	tmp51 = tmp51
	this.DesDefinedDataField = string(tmp51)
	return err
}
func (this *Nitf_DataSubHeader) TreOfl() (v bool, err error) {
	if (this._f_treOfl) {
		return this.treOfl, nil
	}
	this._f_treOfl = true
	this.treOfl = bool(this.DesBase.Desid == "TRE_OVERFLOW")
	return this.treOfl, nil
}
type Nitf_DataSubHeaderBase struct {
	FilePartTypeDe []byte
	Desid string
	DataDefinitionVersion string
	Declasnfo *Nitf_Clasnfo
	_io *kaitai.Stream
	_root *Nitf
	_parent kaitai.Struct
}
func NewNitf_DataSubHeaderBase() *Nitf_DataSubHeaderBase {
	return &Nitf_DataSubHeaderBase{
	}
}

func (this Nitf_DataSubHeaderBase) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_DataSubHeaderBase) Read(io *kaitai.Stream, parent kaitai.Struct, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp52, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp52 = tmp52
	this.FilePartTypeDe = tmp52
	if !(bytes.Equal(this.FilePartTypeDe, []uint8{68, 69})) {
		return kaitai.NewValidationNotEqualError([]uint8{68, 69}, this.FilePartTypeDe, this._io, "/types/data_sub_header_base/seq/0")
	}
	tmp53, err := this._io.ReadBytes(int(25))
	if err != nil {
		return err
	}
	tmp53 = tmp53
	this.Desid = string(tmp53)
	tmp54, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp54 = tmp54
	this.DataDefinitionVersion = string(tmp54)
	tmp55 := NewNitf_Clasnfo()
	err = tmp55.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Declasnfo = tmp55
	return err
}

/**
 * File Part Type desigantor for Data Extension
 */

/**
 * Streaming file Header Data Extension Segment Subheader
 */
type Nitf_DataSubHeaderStreaming struct {
	DesBase *Nitf_DataSubHeaderBase
	DesDefinedSubheaderFieldsLen string
	SfhL1 string
	SfhDelim1 uint32
	SfhDr []uint8
	SfhDelim2 uint32
	SfhL2 string
	_io *kaitai.Stream
	_root *Nitf
	_parent kaitai.Struct
}
func NewNitf_DataSubHeaderStreaming() *Nitf_DataSubHeaderStreaming {
	return &Nitf_DataSubHeaderStreaming{
	}
}

func (this Nitf_DataSubHeaderStreaming) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_DataSubHeaderStreaming) Read(io *kaitai.Stream, parent kaitai.Struct, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp56 := NewNitf_DataSubHeaderBase()
	err = tmp56.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.DesBase = tmp56
	tmp57, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp57 = tmp57
	this.DesDefinedSubheaderFieldsLen = string(tmp57)
	tmp58, err := this._io.ReadBytes(int(7))
	if err != nil {
		return err
	}
	tmp58 = tmp58
	this.SfhL1 = string(tmp58)
	tmp59, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.SfhDelim1 = uint32(tmp59)
	tmp60, err := strconv.ParseInt(this.SfhL1, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp60); i++ {
		_ = i
		tmp61, err := this._io.ReadU1()
		if err != nil {
			return err
		}
		this.SfhDr = append(this.SfhDr, tmp61)
	}
	tmp62, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.SfhDelim2 = uint32(tmp62)
	tmp63, err := this._io.ReadBytes(int(7))
	if err != nil {
		return err
	}
	tmp63 = tmp63
	this.SfhL2 = string(tmp63)
	return err
}

/**
 * SFH Length 1: number of bytes in sfh_dr field
 */

/**
 * Shall contain the value 0x0A6E1D97.
 */

/**
 * Shall contain the value 0x0ECA14BF.
 */

/**
 * A repeat of sfh_l1.
 */
type Nitf_DataSubHeaderTre struct {
	DesBase *Nitf_DataSubHeaderBase
	OverflowedHeaderType string
	DataItemOverflowed string
	DesDefinedSubheaderFieldsLen string
	DesDefinedDataField string
	_io *kaitai.Stream
	_root *Nitf
	_parent kaitai.Struct
}
func NewNitf_DataSubHeaderTre() *Nitf_DataSubHeaderTre {
	return &Nitf_DataSubHeaderTre{
	}
}

func (this Nitf_DataSubHeaderTre) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_DataSubHeaderTre) Read(io *kaitai.Stream, parent kaitai.Struct, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp64 := NewNitf_DataSubHeaderBase()
	err = tmp64.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.DesBase = tmp64
	if (this.DesBase.Desid == "TRE_OVERFLOW") {
		tmp65, err := this._io.ReadBytes(int(6))
		if err != nil {
			return err
		}
		tmp65 = tmp65
		this.OverflowedHeaderType = string(tmp65)
	}
	if (this.DesBase.Desid == "TRE_OVERFLOW") {
		tmp66, err := this._io.ReadBytes(int(3))
		if err != nil {
			return err
		}
		tmp66 = tmp66
		this.DataItemOverflowed = string(tmp66)
	}
	tmp67, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp67 = tmp67
	this.DesDefinedSubheaderFieldsLen = string(tmp67)
	tmp68, err := strconv.ParseInt(this.DesDefinedSubheaderFieldsLen, 10, 0)
	if err != nil {
		return err
	}
	tmp69, err := this._io.ReadBytes(int(tmp68))
	if err != nil {
		return err
	}
	tmp69 = tmp69
	this.DesDefinedDataField = string(tmp69)
	return err
}
type Nitf_DateTime struct {
	_unnamed0 string
	_io *kaitai.Stream
	_root *Nitf
	_parent kaitai.Struct
}
func NewNitf_DateTime() *Nitf_DateTime {
	return &Nitf_DateTime{
	}
}

func (this Nitf_DateTime) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_DateTime) Read(io *kaitai.Stream, parent kaitai.Struct, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp70, err := this._io.ReadBytes(int(14))
	if err != nil {
		return err
	}
	tmp70 = tmp70
	this._unnamed0 = string(tmp70)
	return err
}

/**
 * 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
 */
type Nitf_Encrypt struct {
	_unnamed0 string
	_io *kaitai.Stream
	_root *Nitf
	_parent kaitai.Struct
}
func NewNitf_Encrypt() *Nitf_Encrypt {
	return &Nitf_Encrypt{
	}
}

func (this Nitf_Encrypt) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_Encrypt) Read(io *kaitai.Stream, parent kaitai.Struct, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp71, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp71 = tmp71
	this._unnamed0 = string(tmp71)
	return err
}
type Nitf_GraphicSubHeader struct {
	FilePartTypeSy []byte
	GraphicId string
	GraphicName string
	GraphicClassification *Nitf_Clasnfo
	Encryption *Nitf_Encrypt
	GraphicType []byte
	Reserved1 string
	GraphicDisplayLevel string
	GraphicAttachmentLevel string
	GraphicLocation string
	FirstGraphicBoundLoc string
	GraphicColor string
	SecondGraphicBoundLoc string
	Reserved2 string
	GraphicsExtendedSubHeader *Nitf_TreHeader
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_GraphicsSegment
}
func NewNitf_GraphicSubHeader() *Nitf_GraphicSubHeader {
	return &Nitf_GraphicSubHeader{
	}
}

func (this Nitf_GraphicSubHeader) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_GraphicSubHeader) Read(io *kaitai.Stream, parent *Nitf_GraphicsSegment, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp72, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp72 = tmp72
	this.FilePartTypeSy = tmp72
	if !(bytes.Equal(this.FilePartTypeSy, []uint8{83, 89})) {
		return kaitai.NewValidationNotEqualError([]uint8{83, 89}, this.FilePartTypeSy, this._io, "/types/graphic_sub_header/seq/0")
	}
	tmp73, err := this._io.ReadBytes(int(10))
	if err != nil {
		return err
	}
	tmp73 = tmp73
	this.GraphicId = string(tmp73)
	tmp74, err := this._io.ReadBytes(int(20))
	if err != nil {
		return err
	}
	tmp74 = tmp74
	this.GraphicName = string(tmp74)
	tmp75 := NewNitf_Clasnfo()
	err = tmp75.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.GraphicClassification = tmp75
	tmp76 := NewNitf_Encrypt()
	err = tmp76.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Encryption = tmp76
	tmp77, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp77 = tmp77
	this.GraphicType = tmp77
	if !(bytes.Equal(this.GraphicType, []uint8{67})) {
		return kaitai.NewValidationNotEqualError([]uint8{67}, this.GraphicType, this._io, "/types/graphic_sub_header/seq/5")
	}
	tmp78, err := this._io.ReadBytes(int(13))
	if err != nil {
		return err
	}
	tmp78 = tmp78
	this.Reserved1 = string(tmp78)
	tmp79, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp79 = tmp79
	this.GraphicDisplayLevel = string(tmp79)
	tmp80, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp80 = tmp80
	this.GraphicAttachmentLevel = string(tmp80)
	tmp81, err := this._io.ReadBytes(int(10))
	if err != nil {
		return err
	}
	tmp81 = tmp81
	this.GraphicLocation = string(tmp81)
	tmp82, err := this._io.ReadBytes(int(10))
	if err != nil {
		return err
	}
	tmp82 = tmp82
	this.FirstGraphicBoundLoc = string(tmp82)
	tmp83, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp83 = tmp83
	this.GraphicColor = string(tmp83)
	tmp84, err := this._io.ReadBytes(int(10))
	if err != nil {
		return err
	}
	tmp84 = tmp84
	this.SecondGraphicBoundLoc = string(tmp84)
	tmp85, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp85 = tmp85
	this.Reserved2 = string(tmp85)
	tmp86 := NewNitf_TreHeader()
	err = tmp86.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.GraphicsExtendedSubHeader = tmp86
	return err
}

/**
 * Reserved
 */

/**
 * Reserved
 */
type Nitf_GraphicsSegment struct {
	GraphicSubHeader *Nitf_GraphicSubHeader
	GraphicDataField []byte
	Idx uint16
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf
}
func NewNitf_GraphicsSegment(idx uint16) *Nitf_GraphicsSegment {
	return &Nitf_GraphicsSegment{
		Idx: idx,
	}
}

func (this Nitf_GraphicsSegment) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_GraphicsSegment) Read(io *kaitai.Stream, parent *Nitf, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp87 := NewNitf_GraphicSubHeader()
	err = tmp87.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.GraphicSubHeader = tmp87
	tmp88, err := strconv.ParseInt(this._parent.Header.Lnnfo[this.Idx].LengthGraphicSegment, 10, 0)
	if err != nil {
		return err
	}
	tmp89, err := this._io.ReadBytes(int(tmp88))
	if err != nil {
		return err
	}
	tmp89 = tmp89
	this.GraphicDataField = tmp89
	return err
}
type Nitf_Header struct {
	FileProfileName []byte
	FileVersion []byte
	ComplexityLevel []byte
	StandardType []byte
	OriginatingStationId string
	FileDateTime *Nitf_DateTime
	FileTitle string
	FileSecurity *Nitf_Clasnfo
	FileCopyNumber string
	FileNumOfCopys string
	Encryption *Nitf_Encrypt
	FileBgColor []byte
	OriginatorName string
	OriginatorPhone string
	FileLength string
	FileHeaderLength string
	NumImageSegments string
	Linfo []*Nitf_LengthImageInfo
	NumGraphicsSegments string
	Lnnfo []*Nitf_LengthGraphicInfo
	ReservedNumx string
	NumTextFiles string
	Ltnfo []*Nitf_LengthTextInfo
	NumDataExtension string
	Ldnfo []*Nitf_LengthDataInfo
	NumReservedExtension string
	Lrnfo []*Nitf_LengthReservedInfo
	UserDefinedHeader *Nitf_TreHeader
	ExtendedHeader *Nitf_TreHeader
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf
}
func NewNitf_Header() *Nitf_Header {
	return &Nitf_Header{
	}
}

func (this Nitf_Header) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_Header) Read(io *kaitai.Stream, parent *Nitf, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp90, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp90 = tmp90
	this.FileProfileName = tmp90
	if !(bytes.Equal(this.FileProfileName, []uint8{78, 73, 84, 70})) {
		return kaitai.NewValidationNotEqualError([]uint8{78, 73, 84, 70}, this.FileProfileName, this._io, "/types/header/seq/0")
	}
	tmp91, err := this._io.ReadBytes(int(5))
	if err != nil {
		return err
	}
	tmp91 = tmp91
	this.FileVersion = tmp91
	if !(bytes.Equal(this.FileVersion, []uint8{48, 50, 46, 49, 48})) {
		return kaitai.NewValidationNotEqualError([]uint8{48, 50, 46, 49, 48}, this.FileVersion, this._io, "/types/header/seq/1")
	}
	tmp92, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp92 = tmp92
	this.ComplexityLevel = tmp92
	tmp93, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp93 = tmp93
	this.StandardType = tmp93
	if !(bytes.Equal(this.StandardType, []uint8{66, 70, 48, 49})) {
		return kaitai.NewValidationNotEqualError([]uint8{66, 70, 48, 49}, this.StandardType, this._io, "/types/header/seq/3")
	}
	tmp94, err := this._io.ReadBytes(int(10))
	if err != nil {
		return err
	}
	tmp94 = tmp94
	this.OriginatingStationId = string(tmp94)
	tmp95 := NewNitf_DateTime()
	err = tmp95.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.FileDateTime = tmp95
	tmp96, err := this._io.ReadBytes(int(80))
	if err != nil {
		return err
	}
	tmp96 = tmp96
	this.FileTitle = string(tmp96)
	tmp97 := NewNitf_Clasnfo()
	err = tmp97.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.FileSecurity = tmp97
	tmp98, err := this._io.ReadBytes(int(5))
	if err != nil {
		return err
	}
	tmp98 = tmp98
	this.FileCopyNumber = string(tmp98)
	tmp99, err := this._io.ReadBytes(int(5))
	if err != nil {
		return err
	}
	tmp99 = tmp99
	this.FileNumOfCopys = string(tmp99)
	tmp100 := NewNitf_Encrypt()
	err = tmp100.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Encryption = tmp100
	tmp101, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp101 = tmp101
	this.FileBgColor = tmp101
	tmp102, err := this._io.ReadBytes(int(24))
	if err != nil {
		return err
	}
	tmp102 = tmp102
	this.OriginatorName = string(tmp102)
	tmp103, err := this._io.ReadBytes(int(18))
	if err != nil {
		return err
	}
	tmp103 = tmp103
	this.OriginatorPhone = string(tmp103)
	tmp104, err := this._io.ReadBytes(int(12))
	if err != nil {
		return err
	}
	tmp104 = tmp104
	this.FileLength = string(tmp104)
	tmp105, err := this._io.ReadBytes(int(6))
	if err != nil {
		return err
	}
	tmp105 = tmp105
	this.FileHeaderLength = string(tmp105)
	tmp106, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp106 = tmp106
	this.NumImageSegments = string(tmp106)
	tmp107, err := strconv.ParseInt(this.NumImageSegments, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp107); i++ {
		_ = i
		tmp108 := NewNitf_LengthImageInfo()
		err = tmp108.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Linfo = append(this.Linfo, tmp108)
	}
	tmp109, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp109 = tmp109
	this.NumGraphicsSegments = string(tmp109)
	tmp110, err := strconv.ParseInt(this.NumGraphicsSegments, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp110); i++ {
		_ = i
		tmp111 := NewNitf_LengthGraphicInfo()
		err = tmp111.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Lnnfo = append(this.Lnnfo, tmp111)
	}
	tmp112, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp112 = tmp112
	this.ReservedNumx = string(tmp112)
	tmp113, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp113 = tmp113
	this.NumTextFiles = string(tmp113)
	tmp114, err := strconv.ParseInt(this.NumTextFiles, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp114); i++ {
		_ = i
		tmp115 := NewNitf_LengthTextInfo()
		err = tmp115.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Ltnfo = append(this.Ltnfo, tmp115)
	}
	tmp116, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp116 = tmp116
	this.NumDataExtension = string(tmp116)
	tmp117, err := strconv.ParseInt(this.NumDataExtension, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp117); i++ {
		_ = i
		tmp118 := NewNitf_LengthDataInfo()
		err = tmp118.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Ldnfo = append(this.Ldnfo, tmp118)
	}
	tmp119, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp119 = tmp119
	this.NumReservedExtension = string(tmp119)
	tmp120, err := strconv.ParseInt(this.NumReservedExtension, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp120); i++ {
		_ = i
		tmp121 := NewNitf_LengthReservedInfo()
		err = tmp121.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Lrnfo = append(this.Lrnfo, tmp121)
	}
	tmp122 := NewNitf_TreHeader()
	err = tmp122.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.UserDefinedHeader = tmp122
	tmp123 := NewNitf_TreHeader()
	err = tmp123.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.ExtendedHeader = tmp123
	return err
}

/**
 * Value of BF01 indicates the file is formatted using ISO/IEC IS 12087-5.
 */
type Nitf_ImageComment struct {
	_unnamed0 string
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_ImageSubHeader
}
func NewNitf_ImageComment() *Nitf_ImageComment {
	return &Nitf_ImageComment{
	}
}

func (this Nitf_ImageComment) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_ImageComment) Read(io *kaitai.Stream, parent *Nitf_ImageSubHeader, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp124, err := this._io.ReadBytes(int(80))
	if err != nil {
		return err
	}
	tmp124 = tmp124
	this._unnamed0 = string(tmp124)
	return err
}
type Nitf_ImageDataMask struct {
	BlockedImgDataOffset uint32
	Bmrlnth uint16
	Tmrlnth uint16
	Tpxcdlnth uint16
	Tpxcd []byte
	Bmrbnd []uint32
	Tmrbnd []uint32
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_ImageSegment
	_f_bmrbndSize bool
	bmrbndSize int
	_f_bmrtmrCount bool
	bmrtmrCount int
	_f_hasBmr bool
	hasBmr bool
	_f_hasTmr bool
	hasTmr bool
	_f_tmrbndSize bool
	tmrbndSize int
	_f_totalSize bool
	totalSize int
	_f_tpxcdSize bool
	tpxcdSize int
}
func NewNitf_ImageDataMask() *Nitf_ImageDataMask {
	return &Nitf_ImageDataMask{
	}
}

func (this Nitf_ImageDataMask) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_ImageDataMask) Read(io *kaitai.Stream, parent *Nitf_ImageSegment, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp125, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.BlockedImgDataOffset = uint32(tmp125)
	tmp126, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Bmrlnth = uint16(tmp126)
	tmp127, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Tmrlnth = uint16(tmp127)
	tmp128, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Tpxcdlnth = uint16(tmp128)
	tmp129, err := this.TpxcdSize()
	if err != nil {
		return err
	}
	tmp130, err := this._io.ReadBytes(int(tmp129))
	if err != nil {
		return err
	}
	tmp130 = tmp130
	this.Tpxcd = tmp130
	tmp131, err := this.HasBmr()
	if err != nil {
		return err
	}
	if (tmp131) {
		tmp132, err := this.BmrtmrCount()
		if err != nil {
			return err
		}
		for i := 0; i < int(tmp132); i++ {
			_ = i
			tmp133, err := this._io.ReadU4be()
			if err != nil {
				return err
			}
			this.Bmrbnd = append(this.Bmrbnd, tmp133)
		}
	}
	tmp134, err := this.HasTmr()
	if err != nil {
		return err
	}
	if (tmp134) {
		tmp135, err := this.BmrtmrCount()
		if err != nil {
			return err
		}
		for i := 0; i < int(tmp135); i++ {
			_ = i
			tmp136, err := this._io.ReadU4be()
			if err != nil {
				return err
			}
			this.Tmrbnd = append(this.Tmrbnd, tmp136)
		}
	}
	return err
}
func (this *Nitf_ImageDataMask) BmrbndSize() (v int, err error) {
	if (this._f_bmrbndSize) {
		return this.bmrbndSize, nil
	}
	this._f_bmrbndSize = true
	var tmp137 int;
	tmp138, err := this.HasBmr()
	if err != nil {
		return 0, err
	}
	if (tmp138) {
		tmp139, err := this.BmrtmrCount()
		if err != nil {
			return 0, err
		}
		tmp137 = tmp139 * 4
	} else {
		tmp137 = 0
	}
	this.bmrbndSize = int(tmp137)
	return this.bmrbndSize, nil
}
func (this *Nitf_ImageDataMask) BmrtmrCount() (v int, err error) {
	if (this._f_bmrtmrCount) {
		return this.bmrtmrCount, nil
	}
	this._f_bmrtmrCount = true
	tmp140, err := strconv.ParseInt(this._parent.ImageSubHeader.NumBlocksPerRow, 10, 0)
	if err != nil {
		return 0, err
	}
	tmp141, err := strconv.ParseInt(this._parent.ImageSubHeader.NumBlocksPerCol, 10, 0)
	if err != nil {
		return 0, err
	}
	var tmp142 int8;
	if (this._parent.ImageSubHeader.ImgMode != "S") {
		tmp142 = 1
	} else {
		var tmp143 int;
		tmp144, err := strconv.ParseInt(this._parent.ImageSubHeader.NumBands, 10, 0)
		if err != nil {
			return 0, err
		}
		if (tmp144 != 0) {
			tmp145, err := strconv.ParseInt(this._parent.ImageSubHeader.NumBands, 10, 0)
			if err != nil {
				return 0, err
			}
			tmp143 = tmp145
		} else {
			tmp146, err := strconv.ParseInt(this._parent.ImageSubHeader.NumMultispectralBands, 10, 0)
			if err != nil {
				return 0, err
			}
			tmp143 = tmp146
		}
		tmp142 = tmp143
	}
	this.bmrtmrCount = int((tmp140 * tmp141) * tmp142)
	return this.bmrtmrCount, nil
}
func (this *Nitf_ImageDataMask) HasBmr() (v bool, err error) {
	if (this._f_hasBmr) {
		return this.hasBmr, nil
	}
	this._f_hasBmr = true
	this.hasBmr = bool(this.Bmrlnth != 0)
	return this.hasBmr, nil
}
func (this *Nitf_ImageDataMask) HasTmr() (v bool, err error) {
	if (this._f_hasTmr) {
		return this.hasTmr, nil
	}
	this._f_hasTmr = true
	this.hasTmr = bool(this.Tmrlnth != 0)
	return this.hasTmr, nil
}
func (this *Nitf_ImageDataMask) TmrbndSize() (v int, err error) {
	if (this._f_tmrbndSize) {
		return this.tmrbndSize, nil
	}
	this._f_tmrbndSize = true
	var tmp147 int;
	tmp148, err := this.HasTmr()
	if err != nil {
		return 0, err
	}
	if (tmp148) {
		tmp149, err := this.BmrtmrCount()
		if err != nil {
			return 0, err
		}
		tmp147 = tmp149 * 4
	} else {
		tmp147 = 0
	}
	this.tmrbndSize = int(tmp147)
	return this.tmrbndSize, nil
}
func (this *Nitf_ImageDataMask) TotalSize() (v int, err error) {
	if (this._f_totalSize) {
		return this.totalSize, nil
	}
	this._f_totalSize = true
	tmp150, err := this.TpxcdSize()
	if err != nil {
		return 0, err
	}
	tmp151, err := this.BmrbndSize()
	if err != nil {
		return 0, err
	}
	tmp152, err := this.TmrbndSize()
	if err != nil {
		return 0, err
	}
	this.totalSize = int((((((4 + 2) + 2) + 2) + tmp150) + tmp151) + tmp152)
	return this.totalSize, nil
}
func (this *Nitf_ImageDataMask) TpxcdSize() (v int, err error) {
	if (this._f_tpxcdSize) {
		return this.tpxcdSize, nil
	}
	this._f_tpxcdSize = true
	var tmp153 uint16;
	tmp154 := this.Tpxcdlnth % 8
	if tmp154 < 0 {
		tmp154 += 8
	}
	if (tmp154 == 0) {
		tmp153 = this.Tpxcdlnth
	} else {
		tmp155 := this.Tpxcdlnth % 8
		if tmp155 < 0 {
			tmp155 += 8
		}
		tmp153 = this.Tpxcdlnth + (8 - tmp155)
	}
	this.tpxcdSize = int(tmp153 / 8)
	return this.tpxcdSize, nil
}

/**
 * Block Mask Record Length
 */

/**
 * Pad Pixel Mask Record Length
 */

/**
 * Pad Output Pixel Code Length
 */

/**
 * Pad Output Pixel Code
 */

/**
 * Block n, Band m Offset
 */

/**
 * Pad Pixel n, Band m
 */
type Nitf_ImageSegment struct {
	ImageSubHeader *Nitf_ImageSubHeader
	ImageDataMask *Nitf_ImageDataMask
	ImageDataField []byte
	Idx uint16
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf
	_f_hasMask bool
	hasMask bool
}
func NewNitf_ImageSegment(idx uint16) *Nitf_ImageSegment {
	return &Nitf_ImageSegment{
		Idx: idx,
	}
}

func (this Nitf_ImageSegment) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_ImageSegment) Read(io *kaitai.Stream, parent *Nitf, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp156 := NewNitf_ImageSubHeader()
	err = tmp156.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.ImageSubHeader = tmp156
	tmp157, err := this.HasMask()
	if err != nil {
		return err
	}
	if (tmp157) {
		tmp158 := NewNitf_ImageDataMask()
		err = tmp158.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.ImageDataMask = tmp158
	}
	tmp159, err := this.HasMask()
	if err != nil {
		return err
	}
	if (tmp159) {
		tmp160, err := strconv.ParseInt(this._parent.Header.Linfo[this.Idx].LengthImageSegment, 10, 0)
		if err != nil {
			return err
		}
		tmp161, err := this.ImageDataMask.TotalSize()
		if err != nil {
			return err
		}
		tmp162, err := this._io.ReadBytes(int(tmp160 - tmp161))
		if err != nil {
			return err
		}
		tmp162 = tmp162
		this.ImageDataField = tmp162
	}
	return err
}
func (this *Nitf_ImageSegment) HasMask() (v bool, err error) {
	if (this._f_hasMask) {
		return this.hasMask, nil
	}
	this._f_hasMask = true
	this.hasMask = bool(this.ImageSubHeader.ImgCompression[0:2] == "MM")
	return this.hasMask, nil
}
type Nitf_ImageSubHeader struct {
	FilePartType []byte
	ImageId1 string
	ImageDateTime *Nitf_DateTime
	TargetId string
	ImageId2 string
	ImageSecurityClassification *Nitf_Clasnfo
	Encryption *Nitf_Encrypt
	ImageSource string
	NumSigRows string
	NumSigCols string
	PixelValueType string
	ImageRepresentation string
	ImageCategory string
	ActualBitsPerPixelPerBand string
	PixelJustification string
	ImageCoordinateRep string
	ImageGeoLoc string
	NumImgComments string
	ImgComments []*Nitf_ImageComment
	ImgCompression string
	CompressionRateCode string
	NumBands string
	NumMultispectralBands string
	Bands []*Nitf_BandInfo
	ImgSyncCode string
	ImgMode string
	NumBlocksPerRow string
	NumBlocksPerCol string
	NumPixelsPerBlockHorz string
	NumPixelsPerBlockVert string
	NumPixelsPerBand string
	ImgDisplayLevel string
	AttachmentLevel string
	ImgLocation string
	ImgMagnification string
	UserDefImgDataLen string
	UserDefOverflow string
	UserDefImgData []uint8
	ImageExtendedSubHeader *Nitf_TreHeader
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_ImageSegment
}
func NewNitf_ImageSubHeader() *Nitf_ImageSubHeader {
	return &Nitf_ImageSubHeader{
	}
}

func (this Nitf_ImageSubHeader) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_ImageSubHeader) Read(io *kaitai.Stream, parent *Nitf_ImageSegment, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp163, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp163 = tmp163
	this.FilePartType = tmp163
	if !(bytes.Equal(this.FilePartType, []uint8{73, 77})) {
		return kaitai.NewValidationNotEqualError([]uint8{73, 77}, this.FilePartType, this._io, "/types/image_sub_header/seq/0")
	}
	tmp164, err := this._io.ReadBytes(int(10))
	if err != nil {
		return err
	}
	tmp164 = tmp164
	this.ImageId1 = string(tmp164)
	tmp165 := NewNitf_DateTime()
	err = tmp165.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.ImageDateTime = tmp165
	tmp166, err := this._io.ReadBytes(int(17))
	if err != nil {
		return err
	}
	tmp166 = tmp166
	this.TargetId = string(tmp166)
	tmp167, err := this._io.ReadBytes(int(80))
	if err != nil {
		return err
	}
	tmp167 = tmp167
	this.ImageId2 = string(tmp167)
	tmp168 := NewNitf_Clasnfo()
	err = tmp168.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.ImageSecurityClassification = tmp168
	tmp169 := NewNitf_Encrypt()
	err = tmp169.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Encryption = tmp169
	tmp170, err := this._io.ReadBytes(int(42))
	if err != nil {
		return err
	}
	tmp170 = tmp170
	this.ImageSource = string(tmp170)
	tmp171, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp171 = tmp171
	this.NumSigRows = string(tmp171)
	tmp172, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp172 = tmp172
	this.NumSigCols = string(tmp172)
	tmp173, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp173 = tmp173
	this.PixelValueType = string(tmp173)
	tmp174, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp174 = tmp174
	this.ImageRepresentation = string(tmp174)
	tmp175, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp175 = tmp175
	this.ImageCategory = string(tmp175)
	tmp176, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp176 = tmp176
	this.ActualBitsPerPixelPerBand = string(tmp176)
	tmp177, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp177 = tmp177
	this.PixelJustification = string(tmp177)
	tmp178, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp178 = tmp178
	this.ImageCoordinateRep = string(tmp178)
	tmp179, err := this._io.ReadBytes(int(60))
	if err != nil {
		return err
	}
	tmp179 = tmp179
	this.ImageGeoLoc = string(tmp179)
	tmp180, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp180 = tmp180
	this.NumImgComments = string(tmp180)
	tmp181, err := strconv.ParseInt(this.NumImgComments, 10, 0)
	if err != nil {
		return err
	}
	for i := 0; i < int(tmp181); i++ {
		_ = i
		tmp182 := NewNitf_ImageComment()
		err = tmp182.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.ImgComments = append(this.ImgComments, tmp182)
	}
	tmp183, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp183 = tmp183
	this.ImgCompression = string(tmp183)
	tmp184, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp184 = tmp184
	this.CompressionRateCode = string(tmp184)
	tmp185, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp185 = tmp185
	this.NumBands = string(tmp185)
	tmp186, err := strconv.ParseInt(this.NumBands, 10, 0)
	if err != nil {
		return err
	}
	if (tmp186 == 0) {
		tmp187, err := this._io.ReadBytes(int(5))
		if err != nil {
			return err
		}
		tmp187 = tmp187
		this.NumMultispectralBands = string(tmp187)
	}
	var tmp188 int;
	tmp189, err := strconv.ParseInt(this.NumBands, 10, 0)
	if err != nil {
		return err
	}
	if (tmp189 != 0) {
		tmp190, err := strconv.ParseInt(this.NumBands, 10, 0)
		if err != nil {
			return err
		}
		tmp188 = tmp190
	} else {
		tmp191, err := strconv.ParseInt(this.NumMultispectralBands, 10, 0)
		if err != nil {
			return err
		}
		tmp188 = tmp191
	}
	for i := 0; i < int(tmp188); i++ {
		_ = i
		tmp192 := NewNitf_BandInfo()
		err = tmp192.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Bands = append(this.Bands, tmp192)
	}
	tmp193, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp193 = tmp193
	this.ImgSyncCode = string(tmp193)
	tmp194, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp194 = tmp194
	this.ImgMode = string(tmp194)
	tmp195, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp195 = tmp195
	this.NumBlocksPerRow = string(tmp195)
	tmp196, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp196 = tmp196
	this.NumBlocksPerCol = string(tmp196)
	tmp197, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp197 = tmp197
	this.NumPixelsPerBlockHorz = string(tmp197)
	tmp198, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp198 = tmp198
	this.NumPixelsPerBlockVert = string(tmp198)
	tmp199, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp199 = tmp199
	this.NumPixelsPerBand = string(tmp199)
	tmp200, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp200 = tmp200
	this.ImgDisplayLevel = string(tmp200)
	tmp201, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp201 = tmp201
	this.AttachmentLevel = string(tmp201)
	tmp202, err := this._io.ReadBytes(int(10))
	if err != nil {
		return err
	}
	tmp202 = tmp202
	this.ImgLocation = string(tmp202)
	tmp203, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp203 = tmp203
	this.ImgMagnification = string(tmp203)
	tmp204, err := this._io.ReadBytes(int(5))
	if err != nil {
		return err
	}
	tmp204 = tmp204
	this.UserDefImgDataLen = string(tmp204)
	tmp205, err := strconv.ParseInt(this.UserDefImgDataLen, 10, 0)
	if err != nil {
		return err
	}
	if (tmp205 != 0) {
		tmp206, err := this._io.ReadBytes(int(3))
		if err != nil {
			return err
		}
		tmp206 = tmp206
		this.UserDefOverflow = string(tmp206)
	}
	tmp207, err := strconv.ParseInt(this.UserDefImgDataLen, 10, 0)
	if err != nil {
		return err
	}
	if (tmp207 > 2) {
		tmp208, err := strconv.ParseInt(this.UserDefImgDataLen, 10, 0)
		if err != nil {
			return err
		}
		for i := 0; i < int(tmp208 - 3); i++ {
			_ = i
			tmp209, err := this._io.ReadU1()
			if err != nil {
				return err
			}
			this.UserDefImgData = append(this.UserDefImgData, tmp209)
		}
	}
	tmp210 := NewNitf_TreHeader()
	err = tmp210.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.ImageExtendedSubHeader = tmp210
	return err
}

/**
 * Total number of rows of significant pixels in the image; only rows indexed 0 to (NROWS - 1) of the image contain significant data.
 */

/**
 * MONO, RGB, RGB/LUT, MULTI, NODISPLY, NVECTOR, POLAR, VPH, YCbCr601
 */

/**
 * 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
 */

/**
 * Reserved for future use.
 */

/**
 * B = Band Interleaved by Block, P = Band Interleaved by Pixel, R = Band Interleaved by Row, S = Band Sequential
 */
type Nitf_LengthDataInfo struct {
	LengthDataExtensionSubheader string
	LengthDataExtensionSegment string
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_Header
}
func NewNitf_LengthDataInfo() *Nitf_LengthDataInfo {
	return &Nitf_LengthDataInfo{
	}
}

func (this Nitf_LengthDataInfo) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_LengthDataInfo) Read(io *kaitai.Stream, parent *Nitf_Header, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp211, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp211 = tmp211
	this.LengthDataExtensionSubheader = string(tmp211)
	tmp212, err := this._io.ReadBytes(int(9))
	if err != nil {
		return err
	}
	tmp212 = tmp212
	this.LengthDataExtensionSegment = string(tmp212)
	return err
}
type Nitf_LengthGraphicInfo struct {
	LengthGraphicSubheader string
	LengthGraphicSegment string
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_Header
}
func NewNitf_LengthGraphicInfo() *Nitf_LengthGraphicInfo {
	return &Nitf_LengthGraphicInfo{
	}
}

func (this Nitf_LengthGraphicInfo) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_LengthGraphicInfo) Read(io *kaitai.Stream, parent *Nitf_Header, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp213, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp213 = tmp213
	this.LengthGraphicSubheader = string(tmp213)
	tmp214, err := this._io.ReadBytes(int(6))
	if err != nil {
		return err
	}
	tmp214 = tmp214
	this.LengthGraphicSegment = string(tmp214)
	return err
}
type Nitf_LengthImageInfo struct {
	LengthImageSubheader string
	LengthImageSegment string
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_Header
}
func NewNitf_LengthImageInfo() *Nitf_LengthImageInfo {
	return &Nitf_LengthImageInfo{
	}
}

func (this Nitf_LengthImageInfo) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_LengthImageInfo) Read(io *kaitai.Stream, parent *Nitf_Header, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp215, err := this._io.ReadBytes(int(6))
	if err != nil {
		return err
	}
	tmp215 = tmp215
	this.LengthImageSubheader = string(tmp215)
	tmp216, err := this._io.ReadBytes(int(10))
	if err != nil {
		return err
	}
	tmp216 = tmp216
	this.LengthImageSegment = string(tmp216)
	return err
}
type Nitf_LengthReservedInfo struct {
	LengthReservedExtensionSubheader string
	LengthReservedExtensionSegment string
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_Header
}
func NewNitf_LengthReservedInfo() *Nitf_LengthReservedInfo {
	return &Nitf_LengthReservedInfo{
	}
}

func (this Nitf_LengthReservedInfo) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_LengthReservedInfo) Read(io *kaitai.Stream, parent *Nitf_Header, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp217, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp217 = tmp217
	this.LengthReservedExtensionSubheader = string(tmp217)
	tmp218, err := this._io.ReadBytes(int(7))
	if err != nil {
		return err
	}
	tmp218 = tmp218
	this.LengthReservedExtensionSegment = string(tmp218)
	return err
}
type Nitf_LengthTextInfo struct {
	LengthTextSubheader string
	LengthTextSegment string
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_Header
}
func NewNitf_LengthTextInfo() *Nitf_LengthTextInfo {
	return &Nitf_LengthTextInfo{
	}
}

func (this Nitf_LengthTextInfo) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_LengthTextInfo) Read(io *kaitai.Stream, parent *Nitf_Header, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp219, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp219 = tmp219
	this.LengthTextSubheader = string(tmp219)
	tmp220, err := this._io.ReadBytes(int(5))
	if err != nil {
		return err
	}
	tmp220 = tmp220
	this.LengthTextSegment = string(tmp220)
	return err
}
type Nitf_ReservedExtensionSegment struct {
	ReservedSubHeader *Nitf_ReservedSubHeader
	ReservedDataField []byte
	Idx uint16
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf
	_raw_ReservedSubHeader []byte
}
func NewNitf_ReservedExtensionSegment(idx uint16) *Nitf_ReservedExtensionSegment {
	return &Nitf_ReservedExtensionSegment{
		Idx: idx,
	}
}

func (this Nitf_ReservedExtensionSegment) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_ReservedExtensionSegment) Read(io *kaitai.Stream, parent *Nitf, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp221, err := strconv.ParseInt(this._parent.Header.Lrnfo[this.Idx].LengthReservedExtensionSubheader, 10, 0)
	if err != nil {
		return err
	}
	tmp222, err := this._io.ReadBytes(int(tmp221))
	if err != nil {
		return err
	}
	tmp222 = tmp222
	this._raw_ReservedSubHeader = tmp222
	_io__raw_ReservedSubHeader := kaitai.NewStream(bytes.NewReader(this._raw_ReservedSubHeader))
	tmp223 := NewNitf_ReservedSubHeader()
	err = tmp223.Read(_io__raw_ReservedSubHeader, this, this._root)
	if err != nil {
		return err
	}
	this.ReservedSubHeader = tmp223
	tmp224, err := strconv.ParseInt(this._parent.Header.Lrnfo[this.Idx].LengthReservedExtensionSegment, 10, 0)
	if err != nil {
		return err
	}
	tmp225, err := this._io.ReadBytes(int(tmp224))
	if err != nil {
		return err
	}
	tmp225 = tmp225
	this.ReservedDataField = tmp225
	return err
}
type Nitf_ReservedSubHeader struct {
	FilePartTypeRe []byte
	ResTypeId string
	ResVersion string
	Reclasnfo *Nitf_Clasnfo
	ResUserDefinedSubheaderLength string
	ResUserDefinedSubheaderFields string
	ResUserDefinedData string
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf_ReservedExtensionSegment
}
func NewNitf_ReservedSubHeader() *Nitf_ReservedSubHeader {
	return &Nitf_ReservedSubHeader{
	}
}

func (this Nitf_ReservedSubHeader) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_ReservedSubHeader) Read(io *kaitai.Stream, parent *Nitf_ReservedExtensionSegment, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp226, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp226 = tmp226
	this.FilePartTypeRe = tmp226
	if !(bytes.Equal(this.FilePartTypeRe, []uint8{82, 69})) {
		return kaitai.NewValidationNotEqualError([]uint8{82, 69}, this.FilePartTypeRe, this._io, "/types/reserved_sub_header/seq/0")
	}
	tmp227, err := this._io.ReadBytes(int(25))
	if err != nil {
		return err
	}
	tmp227 = tmp227
	this.ResTypeId = string(tmp227)
	tmp228, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp228 = tmp228
	this.ResVersion = string(tmp228)
	tmp229 := NewNitf_Clasnfo()
	err = tmp229.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Reclasnfo = tmp229
	tmp230, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp230 = tmp230
	this.ResUserDefinedSubheaderLength = string(tmp230)
	tmp231, err := strconv.ParseInt(this.ResUserDefinedSubheaderLength, 10, 0)
	if err != nil {
		return err
	}
	tmp232, err := this._io.ReadBytes(int(tmp231))
	if err != nil {
		return err
	}
	tmp232 = tmp232
	this.ResUserDefinedSubheaderFields = string(tmp232)
	tmp233, err := this._io.ReadBytesFull()
	if err != nil {
		return err
	}
	tmp233 = tmp233
	this.ResUserDefinedData = string(tmp233)
	return err
}
type Nitf_TextSegment struct {
	TextSubHeader []byte
	TextDataField []byte
	Idx uint16
	_io *kaitai.Stream
	_root *Nitf
	_parent *Nitf
}
func NewNitf_TextSegment(idx uint16) *Nitf_TextSegment {
	return &Nitf_TextSegment{
		Idx: idx,
	}
}

func (this Nitf_TextSegment) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_TextSegment) Read(io *kaitai.Stream, parent *Nitf, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp234, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp234 = tmp234
	this.TextSubHeader = tmp234
	tmp235, err := strconv.ParseInt(this._parent.Header.Ltnfo[this.Idx].LengthTextSegment, 10, 0)
	if err != nil {
		return err
	}
	tmp236, err := this._io.ReadBytes(int(tmp235))
	if err != nil {
		return err
	}
	tmp236 = tmp236
	this.TextDataField = tmp236
	return err
}
type Nitf_TextSubHeader struct {
	TextDateTime string
	TextTitle string
	TextSecurityClass *Nitf_Clasnfo
	Encryp *Nitf_Encrypt
	TextFormat string
	TextExtendedSubHeader *Nitf_TreHeader
	_io *kaitai.Stream
	_root *Nitf
	_parent kaitai.Struct
}
func NewNitf_TextSubHeader() *Nitf_TextSubHeader {
	return &Nitf_TextSubHeader{
	}
}

func (this Nitf_TextSubHeader) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_TextSubHeader) Read(io *kaitai.Stream, parent kaitai.Struct, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp237, err := this._io.ReadBytes(int(14))
	if err != nil {
		return err
	}
	tmp237 = tmp237
	this.TextDateTime = string(tmp237)
	tmp238, err := this._io.ReadBytes(int(80))
	if err != nil {
		return err
	}
	tmp238 = tmp238
	this.TextTitle = string(tmp238)
	tmp239 := NewNitf_Clasnfo()
	err = tmp239.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.TextSecurityClass = tmp239
	tmp240 := NewNitf_Encrypt()
	err = tmp240.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Encryp = tmp240
	tmp241, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp241 = tmp241
	this.TextFormat = string(tmp241)
	tmp242 := NewNitf_TreHeader()
	err = tmp242.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.TextExtendedSubHeader = tmp242
	return err
}

/**
 * MTF (USMTF see MIL-STD-6040), STA (indicates BCS), UT1 (indicates ECS), U8S
 */
type Nitf_Tre struct {
	ExtensionTypeId string
	EdataLength string
	Edata string
	_io *kaitai.Stream
	_root *Nitf
	_parent kaitai.Struct
}
func NewNitf_Tre() *Nitf_Tre {
	return &Nitf_Tre{
	}
}

func (this Nitf_Tre) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_Tre) Read(io *kaitai.Stream, parent kaitai.Struct, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp243, err := this._io.ReadBytes(int(6))
	if err != nil {
		return err
	}
	tmp243 = tmp243
	this.ExtensionTypeId = string(tmp243)
	tmp244, err := this._io.ReadBytes(int(5))
	if err != nil {
		return err
	}
	tmp244 = tmp244
	this.EdataLength = string(tmp244)
	tmp245, err := strconv.ParseInt(this.EdataLength, 10, 0)
	if err != nil {
		return err
	}
	tmp246, err := this._io.ReadBytes(int(tmp245))
	if err != nil {
		return err
	}
	tmp246 = tmp246
	this.Edata = string(tmp246)
	return err
}

/**
 * RETAG or CETAG
 */

/**
 * REL or CEL
 */

/**
 * REDATA or CEDATA
 */
type Nitf_TreHeader struct {
	HeaderDataLength string
	HeaderOverflow string
	HeaderData []uint8
	_io *kaitai.Stream
	_root *Nitf
	_parent kaitai.Struct
}
func NewNitf_TreHeader() *Nitf_TreHeader {
	return &Nitf_TreHeader{
	}
}

func (this Nitf_TreHeader) IO_() *kaitai.Stream {
	return this._io
}

func (this *Nitf_TreHeader) Read(io *kaitai.Stream, parent kaitai.Struct, root *Nitf) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp247, err := this._io.ReadBytes(int(5))
	if err != nil {
		return err
	}
	tmp247 = tmp247
	this.HeaderDataLength = string(tmp247)
	tmp248, err := strconv.ParseInt(this.HeaderDataLength, 10, 0)
	if err != nil {
		return err
	}
	if (tmp248 != 0) {
		tmp249, err := this._io.ReadBytes(int(3))
		if err != nil {
			return err
		}
		tmp249 = tmp249
		this.HeaderOverflow = string(tmp249)
	}
	tmp250, err := strconv.ParseInt(this.HeaderDataLength, 10, 0)
	if err != nil {
		return err
	}
	if (tmp250 > 2) {
		tmp251, err := strconv.ParseInt(this.HeaderDataLength, 10, 0)
		if err != nil {
			return err
		}
		for i := 0; i < int(tmp251 - 3); i++ {
			_ = i
			tmp252, err := this._io.ReadU1()
			if err != nil {
				return err
			}
			this.HeaderData = append(this.HeaderData, tmp252)
		}
	}
	return err
}