// 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"
)
/**
* GIF (Graphics Interchange Format) is an image file format, developed
* in 1987. It became popular in 1990s as one of the main image formats
* used in World Wide Web.
*
* GIF format allows encoding of palette-based images up to 256 colors
* (each of the colors can be chosen from a 24-bit RGB
* colorspace). Image data stream uses LZW (Lempel-Ziv-Welch) lossless
* compression.
*
* Over the years, several version of the format were published and
* several extensions to it were made, namely, a popular Netscape
* extension that allows to store several images in one file, switching
* between them, which produces crude form of animation.
*
* Structurally, format consists of several mandatory headers and then
* a stream of blocks follows. Blocks can carry additional
* metainformation or image data.
*/
type Gif_BlockType int
const (
Gif_BlockType__Extension Gif_BlockType = 33
Gif_BlockType__LocalImageDescriptor Gif_BlockType = 44
Gif_BlockType__EndOfFile Gif_BlockType = 59
)
type Gif_ExtensionLabel int
const (
Gif_ExtensionLabel__GraphicControl Gif_ExtensionLabel = 249
Gif_ExtensionLabel__Comment Gif_ExtensionLabel = 254
Gif_ExtensionLabel__Application Gif_ExtensionLabel = 255
)
type Gif struct {
Hdr *Gif_Header
LogicalScreenDescriptor *Gif_LogicalScreenDescriptorStruct
GlobalColorTable *Gif_ColorTable
Blocks []*Gif_Block
_io *kaitai.Stream
_root *Gif
_parent interface{}
_raw_GlobalColorTable []byte
}
func NewGif() *Gif {
return &Gif{
}
}
func (this *Gif) Read(io *kaitai.Stream, parent interface{}, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp1 := NewGif_Header()
err = tmp1.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Hdr = tmp1
tmp2 := NewGif_LogicalScreenDescriptorStruct()
err = tmp2.Read(this._io, this, this._root)
if err != nil {
return err
}
this.LogicalScreenDescriptor = tmp2
tmp3, err := this.LogicalScreenDescriptor.HasColorTable()
if err != nil {
return err
}
if (tmp3) {
tmp4, err := this.LogicalScreenDescriptor.ColorTableSize()
if err != nil {
return err
}
tmp5, err := this._io.ReadBytes(int((tmp4 * 3)))
if err != nil {
return err
}
tmp5 = tmp5
this._raw_GlobalColorTable = tmp5
_io__raw_GlobalColorTable := kaitai.NewStream(bytes.NewReader(this._raw_GlobalColorTable))
tmp6 := NewGif_ColorTable()
err = tmp6.Read(_io__raw_GlobalColorTable, this, this._root)
if err != nil {
return err
}
this.GlobalColorTable = tmp6
}
for i := 1;; i++ {
tmp7 := NewGif_Block()
err = tmp7.Read(this._io, this, this._root)
if err != nil {
return err
}
_it := tmp7
this.Blocks = append(this.Blocks, _it)
tmp8, err := this._io.EOF()
if err != nil {
return err
}
if ((tmp8) || (_it.BlockType == Gif_BlockType__EndOfFile)) {
break
}
}
return err
}
/**
* @see - section 18
*/
/**
* @see - section 22
*/
type Gif_ImageData struct {
LzwMinCodeSize uint8
Subblocks *Gif_Subblocks
_io *kaitai.Stream
_root *Gif
_parent *Gif_LocalImageDescriptor
}
func NewGif_ImageData() *Gif_ImageData {
return &Gif_ImageData{
}
}
func (this *Gif_ImageData) Read(io *kaitai.Stream, parent *Gif_LocalImageDescriptor, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp9, err := this._io.ReadU1()
if err != nil {
return err
}
this.LzwMinCodeSize = tmp9
tmp10 := NewGif_Subblocks()
err = tmp10.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Subblocks = tmp10
return err
}
type Gif_ColorTableEntry struct {
Red uint8
Green uint8
Blue uint8
_io *kaitai.Stream
_root *Gif
_parent *Gif_ColorTable
}
func NewGif_ColorTableEntry() *Gif_ColorTableEntry {
return &Gif_ColorTableEntry{
}
}
func (this *Gif_ColorTableEntry) Read(io *kaitai.Stream, parent *Gif_ColorTable, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp11, err := this._io.ReadU1()
if err != nil {
return err
}
this.Red = tmp11
tmp12, err := this._io.ReadU1()
if err != nil {
return err
}
this.Green = tmp12
tmp13, err := this._io.ReadU1()
if err != nil {
return err
}
this.Blue = tmp13
return err
}
/**
* @see - section 18
*/
type Gif_LogicalScreenDescriptorStruct struct {
ScreenWidth uint16
ScreenHeight uint16
Flags uint8
BgColorIndex uint8
PixelAspectRatio uint8
_io *kaitai.Stream
_root *Gif
_parent *Gif
_f_hasColorTable bool
hasColorTable bool
_f_colorTableSize bool
colorTableSize int
}
func NewGif_LogicalScreenDescriptorStruct() *Gif_LogicalScreenDescriptorStruct {
return &Gif_LogicalScreenDescriptorStruct{
}
}
func (this *Gif_LogicalScreenDescriptorStruct) Read(io *kaitai.Stream, parent *Gif, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp14, err := this._io.ReadU2le()
if err != nil {
return err
}
this.ScreenWidth = uint16(tmp14)
tmp15, err := this._io.ReadU2le()
if err != nil {
return err
}
this.ScreenHeight = uint16(tmp15)
tmp16, err := this._io.ReadU1()
if err != nil {
return err
}
this.Flags = tmp16
tmp17, err := this._io.ReadU1()
if err != nil {
return err
}
this.BgColorIndex = tmp17
tmp18, err := this._io.ReadU1()
if err != nil {
return err
}
this.PixelAspectRatio = tmp18
return err
}
func (this *Gif_LogicalScreenDescriptorStruct) HasColorTable() (v bool, err error) {
if (this._f_hasColorTable) {
return this.hasColorTable, nil
}
this.hasColorTable = bool((this.Flags & 128) != 0)
this._f_hasColorTable = true
return this.hasColorTable, nil
}
func (this *Gif_LogicalScreenDescriptorStruct) ColorTableSize() (v int, err error) {
if (this._f_colorTableSize) {
return this.colorTableSize, nil
}
this.colorTableSize = int((2 << (this.Flags & 7)))
this._f_colorTableSize = true
return this.colorTableSize, nil
}
type Gif_LocalImageDescriptor struct {
Left uint16
Top uint16
Width uint16
Height uint16
Flags uint8
LocalColorTable *Gif_ColorTable
ImageData *Gif_ImageData
_io *kaitai.Stream
_root *Gif
_parent *Gif_Block
_raw_LocalColorTable []byte
_f_hasColorTable bool
hasColorTable bool
_f_hasInterlace bool
hasInterlace bool
_f_hasSortedColorTable bool
hasSortedColorTable bool
_f_colorTableSize bool
colorTableSize int
}
func NewGif_LocalImageDescriptor() *Gif_LocalImageDescriptor {
return &Gif_LocalImageDescriptor{
}
}
func (this *Gif_LocalImageDescriptor) Read(io *kaitai.Stream, parent *Gif_Block, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp19, err := this._io.ReadU2le()
if err != nil {
return err
}
this.Left = uint16(tmp19)
tmp20, err := this._io.ReadU2le()
if err != nil {
return err
}
this.Top = uint16(tmp20)
tmp21, err := this._io.ReadU2le()
if err != nil {
return err
}
this.Width = uint16(tmp21)
tmp22, err := this._io.ReadU2le()
if err != nil {
return err
}
this.Height = uint16(tmp22)
tmp23, err := this._io.ReadU1()
if err != nil {
return err
}
this.Flags = tmp23
tmp24, err := this.HasColorTable()
if err != nil {
return err
}
if (tmp24) {
tmp25, err := this.ColorTableSize()
if err != nil {
return err
}
tmp26, err := this._io.ReadBytes(int((tmp25 * 3)))
if err != nil {
return err
}
tmp26 = tmp26
this._raw_LocalColorTable = tmp26
_io__raw_LocalColorTable := kaitai.NewStream(bytes.NewReader(this._raw_LocalColorTable))
tmp27 := NewGif_ColorTable()
err = tmp27.Read(_io__raw_LocalColorTable, this, this._root)
if err != nil {
return err
}
this.LocalColorTable = tmp27
}
tmp28 := NewGif_ImageData()
err = tmp28.Read(this._io, this, this._root)
if err != nil {
return err
}
this.ImageData = tmp28
return err
}
func (this *Gif_LocalImageDescriptor) HasColorTable() (v bool, err error) {
if (this._f_hasColorTable) {
return this.hasColorTable, nil
}
this.hasColorTable = bool((this.Flags & 128) != 0)
this._f_hasColorTable = true
return this.hasColorTable, nil
}
func (this *Gif_LocalImageDescriptor) HasInterlace() (v bool, err error) {
if (this._f_hasInterlace) {
return this.hasInterlace, nil
}
this.hasInterlace = bool((this.Flags & 64) != 0)
this._f_hasInterlace = true
return this.hasInterlace, nil
}
func (this *Gif_LocalImageDescriptor) HasSortedColorTable() (v bool, err error) {
if (this._f_hasSortedColorTable) {
return this.hasSortedColorTable, nil
}
this.hasSortedColorTable = bool((this.Flags & 32) != 0)
this._f_hasSortedColorTable = true
return this.hasSortedColorTable, nil
}
func (this *Gif_LocalImageDescriptor) ColorTableSize() (v int, err error) {
if (this._f_colorTableSize) {
return this.colorTableSize, nil
}
this.colorTableSize = int((2 << (this.Flags & 7)))
this._f_colorTableSize = true
return this.colorTableSize, nil
}
type Gif_Block struct {
BlockType Gif_BlockType
Body interface{}
_io *kaitai.Stream
_root *Gif
_parent *Gif
}
func NewGif_Block() *Gif_Block {
return &Gif_Block{
}
}
func (this *Gif_Block) Read(io *kaitai.Stream, parent *Gif, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp29, err := this._io.ReadU1()
if err != nil {
return err
}
this.BlockType = Gif_BlockType(tmp29)
switch (this.BlockType) {
case Gif_BlockType__Extension:
tmp30 := NewGif_Extension()
err = tmp30.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Body = tmp30
case Gif_BlockType__LocalImageDescriptor:
tmp31 := NewGif_LocalImageDescriptor()
err = tmp31.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Body = tmp31
}
return err
}
/**
* @see - section 19
*/
type Gif_ColorTable struct {
Entries []*Gif_ColorTableEntry
_io *kaitai.Stream
_root *Gif
_parent interface{}
}
func NewGif_ColorTable() *Gif_ColorTable {
return &Gif_ColorTable{
}
}
func (this *Gif_ColorTable) Read(io *kaitai.Stream, parent interface{}, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
for i := 1;; i++ {
tmp32, err := this._io.EOF()
if err != nil {
return err
}
if tmp32 {
break
}
tmp33 := NewGif_ColorTableEntry()
err = tmp33.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Entries = append(this.Entries, tmp33)
}
return err
}
/**
* @see - section 17
*/
type Gif_Header struct {
Magic []byte
Version string
_io *kaitai.Stream
_root *Gif
_parent *Gif
}
func NewGif_Header() *Gif_Header {
return &Gif_Header{
}
}
func (this *Gif_Header) Read(io *kaitai.Stream, parent *Gif, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp34, err := this._io.ReadBytes(int(3))
if err != nil {
return err
}
tmp34 = tmp34
this.Magic = tmp34
if !(bytes.Equal(this.Magic, []uint8{71, 73, 70})) {
return kaitai.NewValidationNotEqualError([]uint8{71, 73, 70}, this.Magic, this._io, "/types/header/seq/0")
}
tmp35, err := this._io.ReadBytes(int(3))
if err != nil {
return err
}
tmp35 = tmp35
this.Version = string(tmp35)
return err
}
/**
* @see - section 23
*/
type Gif_ExtGraphicControl struct {
BlockSize []byte
Flags uint8
DelayTime uint16
TransparentIdx uint8
Terminator []byte
_io *kaitai.Stream
_root *Gif
_parent *Gif_Extension
_f_transparentColorFlag bool
transparentColorFlag bool
_f_userInputFlag bool
userInputFlag bool
}
func NewGif_ExtGraphicControl() *Gif_ExtGraphicControl {
return &Gif_ExtGraphicControl{
}
}
func (this *Gif_ExtGraphicControl) Read(io *kaitai.Stream, parent *Gif_Extension, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp36, err := this._io.ReadBytes(int(1))
if err != nil {
return err
}
tmp36 = tmp36
this.BlockSize = tmp36
if !(bytes.Equal(this.BlockSize, []uint8{4})) {
return kaitai.NewValidationNotEqualError([]uint8{4}, this.BlockSize, this._io, "/types/ext_graphic_control/seq/0")
}
tmp37, err := this._io.ReadU1()
if err != nil {
return err
}
this.Flags = tmp37
tmp38, err := this._io.ReadU2le()
if err != nil {
return err
}
this.DelayTime = uint16(tmp38)
tmp39, err := this._io.ReadU1()
if err != nil {
return err
}
this.TransparentIdx = tmp39
tmp40, err := this._io.ReadBytes(int(1))
if err != nil {
return err
}
tmp40 = tmp40
this.Terminator = tmp40
if !(bytes.Equal(this.Terminator, []uint8{0})) {
return kaitai.NewValidationNotEqualError([]uint8{0}, this.Terminator, this._io, "/types/ext_graphic_control/seq/4")
}
return err
}
func (this *Gif_ExtGraphicControl) TransparentColorFlag() (v bool, err error) {
if (this._f_transparentColorFlag) {
return this.transparentColorFlag, nil
}
this.transparentColorFlag = bool((this.Flags & 1) != 0)
this._f_transparentColorFlag = true
return this.transparentColorFlag, nil
}
func (this *Gif_ExtGraphicControl) UserInputFlag() (v bool, err error) {
if (this._f_userInputFlag) {
return this.userInputFlag, nil
}
this.userInputFlag = bool((this.Flags & 2) != 0)
this._f_userInputFlag = true
return this.userInputFlag, nil
}
type Gif_Subblock struct {
LenBytes uint8
Bytes []byte
_io *kaitai.Stream
_root *Gif
_parent interface{}
}
func NewGif_Subblock() *Gif_Subblock {
return &Gif_Subblock{
}
}
func (this *Gif_Subblock) Read(io *kaitai.Stream, parent interface{}, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp41, err := this._io.ReadU1()
if err != nil {
return err
}
this.LenBytes = tmp41
tmp42, err := this._io.ReadBytes(int(this.LenBytes))
if err != nil {
return err
}
tmp42 = tmp42
this.Bytes = tmp42
return err
}
type Gif_ApplicationId struct {
LenBytes uint8
ApplicationIdentifier string
ApplicationAuthCode []byte
_io *kaitai.Stream
_root *Gif
_parent *Gif_ExtApplication
}
func NewGif_ApplicationId() *Gif_ApplicationId {
return &Gif_ApplicationId{
}
}
func (this *Gif_ApplicationId) Read(io *kaitai.Stream, parent *Gif_ExtApplication, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp43, err := this._io.ReadU1()
if err != nil {
return err
}
this.LenBytes = tmp43
if !(this.LenBytes == 11) {
return kaitai.NewValidationNotEqualError(11, this.LenBytes, this._io, "/types/application_id/seq/0")
}
tmp44, err := this._io.ReadBytes(int(8))
if err != nil {
return err
}
tmp44 = tmp44
this.ApplicationIdentifier = string(tmp44)
tmp45, err := this._io.ReadBytes(int(3))
if err != nil {
return err
}
tmp45 = tmp45
this.ApplicationAuthCode = tmp45
return err
}
type Gif_ExtApplication struct {
ApplicationId *Gif_ApplicationId
Subblocks []*Gif_Subblock
_io *kaitai.Stream
_root *Gif
_parent *Gif_Extension
}
func NewGif_ExtApplication() *Gif_ExtApplication {
return &Gif_ExtApplication{
}
}
func (this *Gif_ExtApplication) Read(io *kaitai.Stream, parent *Gif_Extension, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp46 := NewGif_ApplicationId()
err = tmp46.Read(this._io, this, this._root)
if err != nil {
return err
}
this.ApplicationId = tmp46
for i := 1;; i++ {
tmp47 := NewGif_Subblock()
err = tmp47.Read(this._io, this, this._root)
if err != nil {
return err
}
_it := tmp47
this.Subblocks = append(this.Subblocks, _it)
if _it.LenBytes == 0 {
break
}
}
return err
}
type Gif_Subblocks struct {
Entries []*Gif_Subblock
_io *kaitai.Stream
_root *Gif
_parent interface{}
}
func NewGif_Subblocks() *Gif_Subblocks {
return &Gif_Subblocks{
}
}
func (this *Gif_Subblocks) Read(io *kaitai.Stream, parent interface{}, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
for i := 1;; i++ {
tmp48 := NewGif_Subblock()
err = tmp48.Read(this._io, this, this._root)
if err != nil {
return err
}
_it := tmp48
this.Entries = append(this.Entries, _it)
if _it.LenBytes == 0 {
break
}
}
return err
}
type Gif_Extension struct {
Label Gif_ExtensionLabel
Body interface{}
_io *kaitai.Stream
_root *Gif
_parent *Gif_Block
}
func NewGif_Extension() *Gif_Extension {
return &Gif_Extension{
}
}
func (this *Gif_Extension) Read(io *kaitai.Stream, parent *Gif_Block, root *Gif) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp49, err := this._io.ReadU1()
if err != nil {
return err
}
this.Label = Gif_ExtensionLabel(tmp49)
switch (this.Label) {
case Gif_ExtensionLabel__Application:
tmp50 := NewGif_ExtApplication()
err = tmp50.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Body = tmp50
case Gif_ExtensionLabel__Comment:
tmp51 := NewGif_Subblocks()
err = tmp51.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Body = tmp51
case Gif_ExtensionLabel__GraphicControl:
tmp52 := NewGif_ExtGraphicControl()
err = tmp52.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Body = tmp52
default:
tmp53 := NewGif_Subblocks()
err = tmp53.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Body = tmp53
}
return err
}