PNG (Portable Network Graphics) file: Go parsing library

This page hosts a formal specification of PNG (Portable Network Graphics) file 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 PNG (Portable Network Graphics) file

png.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"
	"bytes"
	"unicode/utf8"
	"golang.org/x/text/encoding/charmap"
)


/**
 * Test files for APNG can be found at the following locations:
 * 
 *   * <https://philip.html5.org/tests/apng/tests.html>
 *   * <http://littlesvr.ca/apng/>
 */

type Png_BlendOpValues int
const (
	Png_BlendOpValues__Source Png_BlendOpValues = 0
	Png_BlendOpValues__Over Png_BlendOpValues = 1
)
var values_Png_BlendOpValues = map[Png_BlendOpValues]struct{}{0: {}, 1: {}}
func (v Png_BlendOpValues) isDefined() bool {
	_, ok := values_Png_BlendOpValues[v]
	return ok
}

type Png_ColorType int
const (
	Png_ColorType__Greyscale Png_ColorType = 0
	Png_ColorType__Truecolor Png_ColorType = 2
	Png_ColorType__Indexed Png_ColorType = 3
	Png_ColorType__GreyscaleAlpha Png_ColorType = 4
	Png_ColorType__TruecolorAlpha Png_ColorType = 6
)
var values_Png_ColorType = map[Png_ColorType]struct{}{0: {}, 2: {}, 3: {}, 4: {}, 6: {}}
func (v Png_ColorType) isDefined() bool {
	_, ok := values_Png_ColorType[v]
	return ok
}

type Png_CompressionMethods int
const (
	Png_CompressionMethods__Zlib Png_CompressionMethods = 0
)
var values_Png_CompressionMethods = map[Png_CompressionMethods]struct{}{0: {}}
func (v Png_CompressionMethods) isDefined() bool {
	_, ok := values_Png_CompressionMethods[v]
	return ok
}

type Png_DisposeOpValues int
const (
	Png_DisposeOpValues__None Png_DisposeOpValues = 0
	Png_DisposeOpValues__Background Png_DisposeOpValues = 1
	Png_DisposeOpValues__Previous Png_DisposeOpValues = 2
)
var values_Png_DisposeOpValues = map[Png_DisposeOpValues]struct{}{0: {}, 1: {}, 2: {}}
func (v Png_DisposeOpValues) isDefined() bool {
	_, ok := values_Png_DisposeOpValues[v]
	return ok
}

type Png_PhysUnit int
const (
	Png_PhysUnit__Unknown Png_PhysUnit = 0
	Png_PhysUnit__Meter Png_PhysUnit = 1
)
var values_Png_PhysUnit = map[Png_PhysUnit]struct{}{0: {}, 1: {}}
func (v Png_PhysUnit) isDefined() bool {
	_, ok := values_Png_PhysUnit[v]
	return ok
}
type Png struct {
	Magic []byte
	IhdrLen uint32
	IhdrType []byte
	Ihdr *Png_IhdrChunk
	IhdrCrc []byte
	Chunks []*Png_Chunk
	_io *kaitai.Stream
	_root *Png
	_parent kaitai.Struct
}
func NewPng() *Png {
	return &Png{
	}
}

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

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

	tmp1, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp1 = tmp1
	this.Magic = tmp1
	if !(bytes.Equal(this.Magic, []uint8{137, 80, 78, 71, 13, 10, 26, 10})) {
		return kaitai.NewValidationNotEqualError([]uint8{137, 80, 78, 71, 13, 10, 26, 10}, this.Magic, this._io, "/seq/0")
	}
	tmp2, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.IhdrLen = uint32(tmp2)
	if !(this.IhdrLen == 13) {
		return kaitai.NewValidationNotEqualError(13, this.IhdrLen, this._io, "/seq/1")
	}
	tmp3, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp3 = tmp3
	this.IhdrType = tmp3
	if !(bytes.Equal(this.IhdrType, []uint8{73, 72, 68, 82})) {
		return kaitai.NewValidationNotEqualError([]uint8{73, 72, 68, 82}, this.IhdrType, this._io, "/seq/2")
	}
	tmp4 := NewPng_IhdrChunk()
	err = tmp4.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Ihdr = tmp4
	tmp5, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp5 = tmp5
	this.IhdrCrc = tmp5
	for i := 1;; i++ {
		tmp6 := NewPng_Chunk()
		err = tmp6.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		_it := tmp6
		this.Chunks = append(this.Chunks, _it)
		tmp7, err := this._io.EOF()
		if err != nil {
			return err
		}
		if  ((_it.Type == "IEND") || (tmp7))  {
			break
		}
	}
	return err
}

/**
 * @see <a href="https://stackoverflow.com/questions/4242402/the-fireworks-png-format-any-insight-any-libs/51683285#51683285">Source</a>
 */
type Png_AdobeFireworksChunk struct {
	PreviewData []byte
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
	_raw_PreviewData []byte
}
func NewPng_AdobeFireworksChunk() *Png_AdobeFireworksChunk {
	return &Png_AdobeFireworksChunk{
	}
}

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

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

	tmp8, err := this._io.ReadBytesFull()
	if err != nil {
		return err
	}
	tmp8 = tmp8
	this._raw_PreviewData = tmp8
	tmp9, err := kaitai.ProcessZlib(this._raw_PreviewData)
	if err != nil {
		return err
	}
	this.PreviewData = tmp9
	return err
}

/**
 * @see <a href="https://wiki.mozilla.org/APNG_Specification#.60acTL.60:_The_Animation_Control_Chunk">Source</a>
 */
type Png_AnimationControlChunk struct {
	NumFrames uint32
	NumPlays uint32
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_AnimationControlChunk() *Png_AnimationControlChunk {
	return &Png_AnimationControlChunk{
	}
}

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

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

	tmp10, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.NumFrames = uint32(tmp10)
	tmp11, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.NumPlays = uint32(tmp11)
	return err
}

/**
 * Number of frames, must be equal to the number of `frame_control_chunk`s
 */

/**
 * Number of times to loop, 0 indicates infinite looping.
 */

/**
 * @see <a href="https://github.com/skeeto/scratch/tree/58470254f4a95cdf7a53888e405c851c21eb2cae/pngattach">Source</a>
 * @see <a href="https://nullprogram.com/blog/2021/12/31/">A new protocol and tool for PNG file attachments</a>
 */

type Png_AtchChunk_CompressionAttachMethods int
const (
	Png_AtchChunk_CompressionAttachMethods__None Png_AtchChunk_CompressionAttachMethods = 0
	Png_AtchChunk_CompressionAttachMethods__Zlib Png_AtchChunk_CompressionAttachMethods = 1
)
var values_Png_AtchChunk_CompressionAttachMethods = map[Png_AtchChunk_CompressionAttachMethods]struct{}{0: {}, 1: {}}
func (v Png_AtchChunk_CompressionAttachMethods) isDefined() bool {
	_, ok := values_Png_AtchChunk_CompressionAttachMethods[v]
	return ok
}
type Png_AtchChunk struct {
	FileName string
	Compression Png_AtchChunk_CompressionAttachMethods
	DataPlain []byte
	DataZlib []byte
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
	_raw_DataZlib []byte
	_f_data bool
	data []byte
}
func NewPng_AtchChunk() *Png_AtchChunk {
	return &Png_AtchChunk{
	}
}

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

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

	tmp12, err := this._io.ReadBytesTerm(0, false, true, true)
	if err != nil {
		return err
	}
	this.FileName = string(tmp12)
	{
		_it := this.FileName
		if !( ((utf8.RuneCountInString(_it) != 0) && (_it[0:1] != ".")) ) {
			return kaitai.NewValidationExprError(this.FileName, this._io, "/types/atch_chunk/seq/0")
		}
	}
	tmp13, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Compression = Png_AtchChunk_CompressionAttachMethods(tmp13)
	if !( ((this.Compression == Png_AtchChunk_CompressionAttachMethods__None) || (this.Compression == Png_AtchChunk_CompressionAttachMethods__Zlib)) ) {
		return kaitai.NewValidationNotAnyOfError(this.Compression, this._io, "/types/atch_chunk/seq/1")
	}
	if (this.Compression == Png_AtchChunk_CompressionAttachMethods__None) {
		tmp14, err := this._io.ReadBytesFull()
		if err != nil {
			return err
		}
		tmp14 = tmp14
		this.DataPlain = tmp14
	}
	if (this.Compression == Png_AtchChunk_CompressionAttachMethods__Zlib) {
		tmp15, err := this._io.ReadBytesFull()
		if err != nil {
			return err
		}
		tmp15 = tmp15
		this._raw_DataZlib = tmp15
		tmp16, err := kaitai.ProcessZlib(this._raw_DataZlib)
		if err != nil {
			return err
		}
		this.DataZlib = tmp16
	}
	return err
}
func (this *Png_AtchChunk) Data() (v []byte, err error) {
	if (this._f_data) {
		return this.data, nil
	}
	this._f_data = true
	var tmp17 []byte;
	if (this.Compression == Png_AtchChunk_CompressionAttachMethods__None) {
		tmp17 = this.DataPlain
	} else {
		tmp17 = this.DataZlib
	}
	this.data = []byte(tmp17)
	return this.data, nil
}

/**
 * From the [official
 * specification](https://github.com/skeeto/scratch/tree/58470254f4a95cdf7a53888e405c851c21eb2cae/pngattach#atch-chunk-specification):
 * 
 * > The name can be any length that fits in the chunk, and should be
 * > encoded with UTF-8. It's up to each implementation to determine how
 * > to appropriately interpret the bytestring for the local system.
 * 
 * > The name must be at least one byte long, not counting the null
 * > terminator. It cannot begin with a period (`0x2e`), nor contain
 * > control bytes (anything less than `0x20`), nor slash (`0x2f`), nor
 * > backslash (`0x5c`), i.e. no directory hierarchies.
 * 
 * As of Kaitai Struct 0.11, we cannot easily check whether a string
 * contains certain characters, so we only enforce that the file name is
 * not empty and that it doesn't start with a period.
 */

/**
 * Background chunk stores default background color to display this
 * image against. Contents depend on `color_type` of the image.
 * @see <a href="https://www.w3.org/TR/png/#11bKGD">Source</a>
 */
type Png_BkgdChunk struct {
	Bkgd kaitai.Struct
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_BkgdChunk() *Png_BkgdChunk {
	return &Png_BkgdChunk{
	}
}

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

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

	switch (this._root.Ihdr.ColorType) {
	case Png_ColorType__Greyscale:
		tmp18 := NewPng_BkgdGreyscale()
		err = tmp18.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Bkgd = tmp18
	case Png_ColorType__GreyscaleAlpha:
		tmp19 := NewPng_BkgdGreyscale()
		err = tmp19.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Bkgd = tmp19
	case Png_ColorType__Indexed:
		tmp20 := NewPng_BkgdIndexed()
		err = tmp20.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Bkgd = tmp20
	case Png_ColorType__Truecolor:
		tmp21 := NewPng_BkgdTruecolor()
		err = tmp21.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Bkgd = tmp21
	case Png_ColorType__TruecolorAlpha:
		tmp22 := NewPng_BkgdTruecolor()
		err = tmp22.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Bkgd = tmp22
	}
	return err
}

/**
 * Background chunk for greyscale images.
 */
type Png_BkgdGreyscale struct {
	Value uint16
	_io *kaitai.Stream
	_root *Png
	_parent *Png_BkgdChunk
}
func NewPng_BkgdGreyscale() *Png_BkgdGreyscale {
	return &Png_BkgdGreyscale{
	}
}

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

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

	tmp23, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Value = uint16(tmp23)
	return err
}

/**
 * Background chunk for images with indexed palette.
 */
type Png_BkgdIndexed struct {
	PaletteIndex uint8
	_io *kaitai.Stream
	_root *Png
	_parent *Png_BkgdChunk
}
func NewPng_BkgdIndexed() *Png_BkgdIndexed {
	return &Png_BkgdIndexed{
	}
}

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

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

	tmp24, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.PaletteIndex = tmp24
	return err
}

/**
 * Background chunk for truecolor images.
 */
type Png_BkgdTruecolor struct {
	Red uint16
	Green uint16
	Blue uint16
	_io *kaitai.Stream
	_root *Png
	_parent *Png_BkgdChunk
}
func NewPng_BkgdTruecolor() *Png_BkgdTruecolor {
	return &Png_BkgdTruecolor{
	}
}

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

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

	tmp25, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Red = uint16(tmp25)
	tmp26, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Green = uint16(tmp26)
	tmp27, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Blue = uint16(tmp27)
	return err
}

/**
 * @see <a href="https://www.w3.org/TR/png/#11cHRM">Source</a>
 */
type Png_ChrmChunk struct {
	WhitePoint *Png_Point
	Red *Png_Point
	Green *Png_Point
	Blue *Png_Point
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_ChrmChunk() *Png_ChrmChunk {
	return &Png_ChrmChunk{
	}
}

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

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

	tmp28 := NewPng_Point()
	err = tmp28.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.WhitePoint = tmp28
	tmp29 := NewPng_Point()
	err = tmp29.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Red = tmp29
	tmp30 := NewPng_Point()
	err = tmp30.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Green = tmp30
	tmp31 := NewPng_Point()
	err = tmp31.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Blue = tmp31
	return err
}
type Png_Chunk struct {
	Len uint32
	Type string
	Body interface{}
	Crc []byte
	_io *kaitai.Stream
	_root *Png
	_parent *Png
	_raw_Body []byte
}
func NewPng_Chunk() *Png_Chunk {
	return &Png_Chunk{
	}
}

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

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

	tmp32, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Len = uint32(tmp32)
	tmp33, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp33 = tmp33
	this.Type = string(tmp33)
	{
		_it := this.Type
		if !(this.Type != "\000\000\000\000") {
			return kaitai.NewValidationExprError(this.Type, this._io, "/types/chunk/seq/1")
		}
	}
	switch (this.Type) {
	case "PLTE":
		tmp34, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp34 = tmp34
		this._raw_Body = tmp34
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp35 := NewPng_PlteChunk()
		err = tmp35.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp35
	case "acTL":
		tmp36, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp36 = tmp36
		this._raw_Body = tmp36
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp37 := NewPng_AnimationControlChunk()
		err = tmp37.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp37
	case "atCh":
		tmp38, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp38 = tmp38
		this._raw_Body = tmp38
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp39 := NewPng_AtchChunk()
		err = tmp39.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp39
	case "bKGD":
		tmp40, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp40 = tmp40
		this._raw_Body = tmp40
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp41 := NewPng_BkgdChunk()
		err = tmp41.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp41
	case "cHRM":
		tmp42, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp42 = tmp42
		this._raw_Body = tmp42
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp43 := NewPng_ChrmChunk()
		err = tmp43.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp43
	case "fcTL":
		tmp44, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp44 = tmp44
		this._raw_Body = tmp44
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp45 := NewPng_FrameControlChunk()
		err = tmp45.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp45
	case "fdAT":
		tmp46, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp46 = tmp46
		this._raw_Body = tmp46
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp47 := NewPng_FrameDataChunk()
		err = tmp47.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp47
	case "gAMA":
		tmp48, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp48 = tmp48
		this._raw_Body = tmp48
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp49 := NewPng_GamaChunk()
		err = tmp49.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp49
	case "iTXt":
		tmp50, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp50 = tmp50
		this._raw_Body = tmp50
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp51 := NewPng_InternationalTextChunk()
		err = tmp51.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp51
	case "mkBS":
		tmp52, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp52 = tmp52
		this._raw_Body = tmp52
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp53 := NewPng_AdobeFireworksChunk()
		err = tmp53.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp53
	case "mkTS":
		tmp54, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp54 = tmp54
		this._raw_Body = tmp54
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp55 := NewPng_AdobeFireworksChunk()
		err = tmp55.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp55
	case "pHYs":
		tmp56, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp56 = tmp56
		this._raw_Body = tmp56
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp57 := NewPng_PhysChunk()
		err = tmp57.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp57
	case "prVW":
		tmp58, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp58 = tmp58
		this._raw_Body = tmp58
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp59 := NewPng_AdobeFireworksChunk()
		err = tmp59.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp59
	case "sRGB":
		tmp60, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp60 = tmp60
		this._raw_Body = tmp60
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp61 := NewPng_SrgbChunk()
		err = tmp61.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp61
	case "skMf":
		tmp62, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp62 = tmp62
		this._raw_Body = tmp62
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp63 := NewPng_EvernoteSkmfChunk()
		err = tmp63.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp63
	case "skRf":
		tmp64, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp64 = tmp64
		this._raw_Body = tmp64
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp65 := NewPng_EvernoteSkrfChunk()
		err = tmp65.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp65
	case "tEXt":
		tmp66, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp66 = tmp66
		this._raw_Body = tmp66
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp67 := NewPng_TextChunk()
		err = tmp67.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp67
	case "tIME":
		tmp68, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp68 = tmp68
		this._raw_Body = tmp68
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp69 := NewPng_TimeChunk()
		err = tmp69.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp69
	case "zTXt":
		tmp70, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp70 = tmp70
		this._raw_Body = tmp70
		_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
		tmp71 := NewPng_CompressedTextChunk()
		err = tmp71.Read(_io__raw_Body, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp71
	default:
		tmp72, err := this._io.ReadBytes(int(this.Len))
		if err != nil {
			return err
		}
		tmp72 = tmp72
		this._raw_Body = tmp72
	}
	tmp73, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp73 = tmp73
	this.Crc = tmp73
	return err
}

/**
 * Compressed text chunk effectively allows to store key-value
 * string pairs in PNG container, compressing "value" part (which
 * can be quite lengthy) with zlib compression.
 * @see <a href="https://www.w3.org/TR/png/#11zTXt">Source</a>
 */
type Png_CompressedTextChunk struct {
	Keyword string
	CompressionMethod Png_CompressionMethods
	TextDatastream []byte
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
	_raw_TextDatastream []byte
}
func NewPng_CompressedTextChunk() *Png_CompressedTextChunk {
	return &Png_CompressedTextChunk{
	}
}

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

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

	tmp74, err := this._io.ReadBytesTerm(0, false, true, true)
	if err != nil {
		return err
	}
	this.Keyword = string(tmp74)
	tmp75, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.CompressionMethod = Png_CompressionMethods(tmp75)
	tmp76, err := this._io.ReadBytesFull()
	if err != nil {
		return err
	}
	tmp76 = tmp76
	this._raw_TextDatastream = tmp76
	tmp77, err := kaitai.ProcessZlib(this._raw_TextDatastream)
	if err != nil {
		return err
	}
	this.TextDatastream = tmp77
	return err
}

/**
 * Indicates purpose of the following text data.
 */

/**
 * @see <a href="https://web.archive.org/web/20210302212148/https://discussion.evernote.com/forums/topic/88532-how-to-extract-annotation-information-from-annotated-evernoteskitch-images/#comment-451501">Source</a>
 */
type Png_EvernoteSkmfChunk struct {
	Json string
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_EvernoteSkmfChunk() *Png_EvernoteSkmfChunk {
	return &Png_EvernoteSkmfChunk{
	}
}

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

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

	tmp78, err := this._io.ReadBytesFull()
	if err != nil {
		return err
	}
	tmp78 = tmp78
	this.Json = string(tmp78)
	return err
}

/**
 * JSON document with information about editable annotations (text,
 * lines, paths, etc.) in Evernote/Skitch.
 * 
 * It refers to the original image stored in the `skRf` chunk (which
 * usually follows immediately after `skMf`) via the
 * `.children[0].children[0].uri` JSON property. This has the format
 * `"skitch+uuid:///$UUID"`, where `$UUID` is a random UUIDv4 value that
 * matches the `uuid` field in `evernote_skrf_chunk` (i.e. in the first
 * 16 bytes of the `skRf` chunk).
 */

/**
 * @see <a href="https://web.archive.org/web/20210302212148/https://discussion.evernote.com/forums/topic/88532-how-to-extract-annotation-information-from-annotated-evernoteskitch-images/#comment-451501">Source</a>
 */
type Png_EvernoteSkrfChunk struct {
	Uuid []byte
	OrigImg []byte
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_EvernoteSkrfChunk() *Png_EvernoteSkrfChunk {
	return &Png_EvernoteSkrfChunk{
	}
}

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

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

	tmp79, err := this._io.ReadBytes(int(16))
	if err != nil {
		return err
	}
	tmp79 = tmp79
	this.Uuid = tmp79
	tmp80, err := this._io.ReadBytesFull()
	if err != nil {
		return err
	}
	tmp80 = tmp80
	this.OrigImg = tmp80
	return err
}

/**
 * Random UUIDv4 value used to identify the image. It is referenced by
 * the `skMf` chunk - see the documentation for the `json` field in
 * `evernote_skmf_chunk`.
 */

/**
 * The original source image without annotations. It's usually a PNG
 * image as well, but it can also be a JPEG or possibly other formats.
 */

/**
 * @see <a href="https://wiki.mozilla.org/APNG_Specification#.60fcTL.60:_The_Frame_Control_Chunk">Source</a>
 */
type Png_FrameControlChunk struct {
	SequenceNumber uint32
	Width uint32
	Height uint32
	XOffset uint32
	YOffset uint32
	DelayNum uint16
	DelayDen uint16
	DisposeOp Png_DisposeOpValues
	BlendOp Png_BlendOpValues
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
	_f_delay bool
	delay float64
}
func NewPng_FrameControlChunk() *Png_FrameControlChunk {
	return &Png_FrameControlChunk{
	}
}

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

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

	tmp81, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.SequenceNumber = uint32(tmp81)
	tmp82, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Width = uint32(tmp82)
	if !(this.Width >= 1) {
		return kaitai.NewValidationLessThanError(1, this.Width, this._io, "/types/frame_control_chunk/seq/1")
	}
	if !(this.Width <= this._root.Ihdr.Width) {
		return kaitai.NewValidationGreaterThanError(this._root.Ihdr.Width, this.Width, this._io, "/types/frame_control_chunk/seq/1")
	}
	tmp83, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Height = uint32(tmp83)
	if !(this.Height >= 1) {
		return kaitai.NewValidationLessThanError(1, this.Height, this._io, "/types/frame_control_chunk/seq/2")
	}
	if !(this.Height <= this._root.Ihdr.Height) {
		return kaitai.NewValidationGreaterThanError(this._root.Ihdr.Height, this.Height, this._io, "/types/frame_control_chunk/seq/2")
	}
	tmp84, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.XOffset = uint32(tmp84)
	if !(this.XOffset <= this._root.Ihdr.Width - this.Width) {
		return kaitai.NewValidationGreaterThanError(this._root.Ihdr.Width - this.Width, this.XOffset, this._io, "/types/frame_control_chunk/seq/3")
	}
	tmp85, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.YOffset = uint32(tmp85)
	if !(this.YOffset <= this._root.Ihdr.Height - this.Height) {
		return kaitai.NewValidationGreaterThanError(this._root.Ihdr.Height - this.Height, this.YOffset, this._io, "/types/frame_control_chunk/seq/4")
	}
	tmp86, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.DelayNum = uint16(tmp86)
	tmp87, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.DelayDen = uint16(tmp87)
	tmp88, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.DisposeOp = Png_DisposeOpValues(tmp88)
	tmp89, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.BlendOp = Png_BlendOpValues(tmp89)
	return err
}

/**
 * Time to display this frame, in seconds
 */
func (this *Png_FrameControlChunk) Delay() (v float64, err error) {
	if (this._f_delay) {
		return this.delay, nil
	}
	this._f_delay = true
	var tmp90 float64;
	if (this.DelayDen == 0) {
		tmp90 = 100.0
	} else {
		tmp90 = this.DelayDen
	}
	this.delay = float64(this.DelayNum / tmp90)
	return this.delay, nil
}

/**
 * Sequence number of the animation chunk
 */

/**
 * Width of the following frame
 */

/**
 * Height of the following frame
 */

/**
 * X position at which to render the following frame
 */

/**
 * Y position at which to render the following frame
 */

/**
 * Frame delay fraction numerator
 */

/**
 * Frame delay fraction denominator
 */

/**
 * Type of frame area disposal to be done after rendering this frame
 */

/**
 * Type of frame area rendering for this frame
 */

/**
 * @see <a href="https://wiki.mozilla.org/APNG_Specification#.60fdAT.60:_The_Frame_Data_Chunk">Source</a>
 */
type Png_FrameDataChunk struct {
	SequenceNumber uint32
	FrameData []byte
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_FrameDataChunk() *Png_FrameDataChunk {
	return &Png_FrameDataChunk{
	}
}

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

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

	tmp91, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.SequenceNumber = uint32(tmp91)
	tmp92, err := this._io.ReadBytesFull()
	if err != nil {
		return err
	}
	tmp92 = tmp92
	this.FrameData = tmp92
	return err
}

/**
 * Sequence number of the animation chunk. The fcTL and fdAT chunks
 * have a 4 byte sequence number. Both chunk types share the sequence.
 * The first fcTL chunk must contain sequence number 0, and the sequence
 * numbers in the remaining fcTL and fdAT chunks must be in order, with
 * no gaps or duplicates.
 */

/**
 * Frame data for the frame. At least one fdAT chunk is required for
 * each frame. The compressed datastream is the concatenation of the
 * contents of the data fields of all the fdAT chunks within a frame.
 */

/**
 * @see <a href="https://www.w3.org/TR/png/#11gAMA">Source</a>
 */
type Png_GamaChunk struct {
	GammaInt uint32
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
	_f_gammaRatio bool
	gammaRatio float64
}
func NewPng_GamaChunk() *Png_GamaChunk {
	return &Png_GamaChunk{
	}
}

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

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

	tmp93, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.GammaInt = uint32(tmp93)
	return err
}
func (this *Png_GamaChunk) GammaRatio() (v float64, err error) {
	if (this._f_gammaRatio) {
		return this.gammaRatio, nil
	}
	this._f_gammaRatio = true
	this.gammaRatio = float64(100000.0 / this.GammaInt)
	return this.gammaRatio, nil
}

/**
 * @see <a href="https://www.w3.org/TR/png/#11IHDR">Source</a>
 */
type Png_IhdrChunk struct {
	Width uint32
	Height uint32
	BitDepth uint8
	ColorType Png_ColorType
	CompressionMethod uint8
	FilterMethod uint8
	InterlaceMethod uint8
	_io *kaitai.Stream
	_root *Png
	_parent *Png
}
func NewPng_IhdrChunk() *Png_IhdrChunk {
	return &Png_IhdrChunk{
	}
}

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

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

	tmp94, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Width = uint32(tmp94)
	if !(this.Width >= 1) {
		return kaitai.NewValidationLessThanError(1, this.Width, this._io, "/types/ihdr_chunk/seq/0")
	}
	tmp95, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Height = uint32(tmp95)
	if !(this.Height >= 1) {
		return kaitai.NewValidationLessThanError(1, this.Height, this._io, "/types/ihdr_chunk/seq/1")
	}
	tmp96, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.BitDepth = tmp96
	tmp97, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.ColorType = Png_ColorType(tmp97)
	tmp98, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.CompressionMethod = tmp98
	tmp99, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.FilterMethod = tmp99
	tmp100, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.InterlaceMethod = tmp100
	return err
}

/**
 * International text chunk effectively allows to store key-value string pairs in
 * PNG container. Both "key" (keyword) and "value" (text) parts are
 * given in pre-defined subset of iso8859-1 without control
 * characters.
 * @see <a href="https://www.w3.org/TR/png/#11iTXt">Source</a>
 */
type Png_InternationalTextChunk struct {
	Keyword string
	CompressionFlag uint8
	CompressionMethod Png_CompressionMethods
	LanguageTag string
	TranslatedKeyword string
	Text string
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_InternationalTextChunk() *Png_InternationalTextChunk {
	return &Png_InternationalTextChunk{
	}
}

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

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

	tmp101, err := this._io.ReadBytesTerm(0, false, true, true)
	if err != nil {
		return err
	}
	this.Keyword = string(tmp101)
	tmp102, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.CompressionFlag = tmp102
	tmp103, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.CompressionMethod = Png_CompressionMethods(tmp103)
	tmp104, err := this._io.ReadBytesTerm(0, false, true, true)
	if err != nil {
		return err
	}
	this.LanguageTag = string(tmp104)
	tmp105, err := this._io.ReadBytesTerm(0, false, true, true)
	if err != nil {
		return err
	}
	this.TranslatedKeyword = string(tmp105)
	tmp106, err := this._io.ReadBytesFull()
	if err != nil {
		return err
	}
	tmp106 = tmp106
	this.Text = string(tmp106)
	return err
}

/**
 * Indicates purpose of the following text data.
 */

/**
 * 0 = text is uncompressed, 1 = text is compressed with a
 * method specified in `compression_method`.
 */

/**
 * Human language used in `translated_keyword` and `text`
 * attributes - should be a language code conforming to ISO
 * 646.IRV:1991.
 */

/**
 * Keyword translated into language specified in
 * `language_tag`. Line breaks are not allowed.
 */

/**
 * Text contents ("value" of this key-value pair), written in
 * language specified in `language_tag`. Line breaks are
 * allowed.
 */

/**
 * "Physical size" chunk stores data that allows to translate
 * logical pixels into physical units (meters, etc) and vice-versa.
 * @see <a href="https://www.w3.org/TR/png/#11pHYs">Source</a>
 */
type Png_PhysChunk struct {
	PixelsPerUnitX uint32
	PixelsPerUnitY uint32
	Unit Png_PhysUnit
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_PhysChunk() *Png_PhysChunk {
	return &Png_PhysChunk{
	}
}

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

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

	tmp107, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.PixelsPerUnitX = uint32(tmp107)
	tmp108, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.PixelsPerUnitY = uint32(tmp108)
	tmp109, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Unit = Png_PhysUnit(tmp109)
	return err
}

/**
 * Number of pixels per physical unit (typically, 1 meter) by X
 * axis.
 */

/**
 * Number of pixels per physical unit (typically, 1 meter) by Y
 * axis.
 */

/**
 * @see <a href="https://www.w3.org/TR/png/#11PLTE">Source</a>
 */
type Png_PlteChunk struct {
	Entries []*Png_Rgb
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_PlteChunk() *Png_PlteChunk {
	return &Png_PlteChunk{
	}
}

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

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

	for i := 0;; i++ {
		tmp110, err := this._io.EOF()
		if err != nil {
			return err
		}
		if tmp110 {
			break
		}
		tmp111 := NewPng_Rgb()
		err = tmp111.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Entries = append(this.Entries, tmp111)
	}
	return err
}
type Png_Point struct {
	XInt uint32
	YInt uint32
	_io *kaitai.Stream
	_root *Png
	_parent *Png_ChrmChunk
	_f_x bool
	x float64
	_f_y bool
	y float64
}
func NewPng_Point() *Png_Point {
	return &Png_Point{
	}
}

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

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

	tmp112, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.XInt = uint32(tmp112)
	tmp113, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.YInt = uint32(tmp113)
	return err
}
func (this *Png_Point) X() (v float64, err error) {
	if (this._f_x) {
		return this.x, nil
	}
	this._f_x = true
	this.x = float64(this.XInt / 100000.0)
	return this.x, nil
}
func (this *Png_Point) Y() (v float64, err error) {
	if (this._f_y) {
		return this.y, nil
	}
	this._f_y = true
	this.y = float64(this.YInt / 100000.0)
	return this.y, nil
}
type Png_Rgb struct {
	R uint8
	G uint8
	B uint8
	_io *kaitai.Stream
	_root *Png
	_parent *Png_PlteChunk
}
func NewPng_Rgb() *Png_Rgb {
	return &Png_Rgb{
	}
}

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

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

	tmp114, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.R = tmp114
	tmp115, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.G = tmp115
	tmp116, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.B = tmp116
	return err
}

/**
 * @see <a href="https://www.w3.org/TR/png/#11sRGB">Source</a>
 */

type Png_SrgbChunk_Intent int
const (
	Png_SrgbChunk_Intent__Perceptual Png_SrgbChunk_Intent = 0
	Png_SrgbChunk_Intent__RelativeColorimetric Png_SrgbChunk_Intent = 1
	Png_SrgbChunk_Intent__Saturation Png_SrgbChunk_Intent = 2
	Png_SrgbChunk_Intent__AbsoluteColorimetric Png_SrgbChunk_Intent = 3
)
var values_Png_SrgbChunk_Intent = map[Png_SrgbChunk_Intent]struct{}{0: {}, 1: {}, 2: {}, 3: {}}
func (v Png_SrgbChunk_Intent) isDefined() bool {
	_, ok := values_Png_SrgbChunk_Intent[v]
	return ok
}
type Png_SrgbChunk struct {
	RenderIntent Png_SrgbChunk_Intent
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_SrgbChunk() *Png_SrgbChunk {
	return &Png_SrgbChunk{
	}
}

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

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

	tmp117, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.RenderIntent = Png_SrgbChunk_Intent(tmp117)
	return err
}

/**
 * Text chunk effectively allows to store key-value string pairs in
 * PNG container. Both "key" (keyword) and "value" (text) parts are
 * given in pre-defined subset of iso8859-1 without control
 * characters.
 * @see <a href="https://www.w3.org/TR/png/#11tEXt">Source</a>
 */
type Png_TextChunk struct {
	Keyword string
	Text string
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_TextChunk() *Png_TextChunk {
	return &Png_TextChunk{
	}
}

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

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

	tmp118, err := this._io.ReadBytesTerm(0, false, true, true)
	if err != nil {
		return err
	}
	tmp119, err := kaitai.BytesToStr(tmp118, charmap.ISO8859_1.NewDecoder())
	if err != nil {
		return err
	}
	this.Keyword = tmp119
	tmp120, err := this._io.ReadBytesFull()
	if err != nil {
		return err
	}
	tmp120 = tmp120
	tmp121, err := kaitai.BytesToStr(tmp120, charmap.ISO8859_1.NewDecoder())
	if err != nil {
		return err
	}
	this.Text = tmp121
	return err
}

/**
 * Indicates purpose of the following text data.
 */

/**
 * Time chunk stores time stamp of last modification of this image,
 * up to 1 second precision in UTC timezone.
 * @see <a href="https://www.w3.org/TR/png/#11tIME">Source</a>
 */
type Png_TimeChunk struct {
	Year uint16
	Month uint8
	Day uint8
	Hour uint8
	Minute uint8
	Second uint8
	_io *kaitai.Stream
	_root *Png
	_parent *Png_Chunk
}
func NewPng_TimeChunk() *Png_TimeChunk {
	return &Png_TimeChunk{
	}
}

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

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

	tmp122, err := this._io.ReadU2be()
	if err != nil {
		return err
	}
	this.Year = uint16(tmp122)
	tmp123, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Month = tmp123
	tmp124, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Day = tmp124
	tmp125, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Hour = tmp125
	tmp126, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Minute = tmp126
	tmp127, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Second = tmp127
	return err
}