528 lines
20 KiB
Python
528 lines
20 KiB
Python
|
|
# This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
|
||
|
|
|
||
|
|
import kaitaistruct
|
||
|
|
from kaitaistruct import KaitaiStruct, KaitaiStream, BytesIO
|
||
|
|
from enum import Enum
|
||
|
|
import zlib
|
||
|
|
|
||
|
|
|
||
|
|
if getattr(kaitaistruct, 'API_VERSION', (0, 9)) < (0, 9):
|
||
|
|
raise Exception("Incompatible Kaitai Struct Python API: 0.9 or later is required, but you have %s" % (kaitaistruct.__version__))
|
||
|
|
|
||
|
|
class Png(KaitaiStruct):
|
||
|
|
"""Test files for APNG can be found at the following locations:
|
||
|
|
|
||
|
|
* <https://philip.html5.org/tests/apng/tests.html>
|
||
|
|
* <http://littlesvr.ca/apng/>
|
||
|
|
"""
|
||
|
|
|
||
|
|
class PhysUnit(Enum):
|
||
|
|
unknown = 0
|
||
|
|
meter = 1
|
||
|
|
|
||
|
|
class BlendOpValues(Enum):
|
||
|
|
source = 0
|
||
|
|
over = 1
|
||
|
|
|
||
|
|
class CompressionMethods(Enum):
|
||
|
|
zlib = 0
|
||
|
|
|
||
|
|
class DisposeOpValues(Enum):
|
||
|
|
none = 0
|
||
|
|
background = 1
|
||
|
|
previous = 2
|
||
|
|
|
||
|
|
class ColorType(Enum):
|
||
|
|
greyscale = 0
|
||
|
|
truecolor = 2
|
||
|
|
indexed = 3
|
||
|
|
greyscale_alpha = 4
|
||
|
|
truecolor_alpha = 6
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.magic = self._io.read_bytes(8)
|
||
|
|
if not self.magic == b"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A":
|
||
|
|
raise kaitaistruct.ValidationNotEqualError(b"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", self.magic, self._io, u"/seq/0")
|
||
|
|
self.ihdr_len = self._io.read_u4be()
|
||
|
|
if not self.ihdr_len == 13:
|
||
|
|
raise kaitaistruct.ValidationNotEqualError(13, self.ihdr_len, self._io, u"/seq/1")
|
||
|
|
self.ihdr_type = self._io.read_bytes(4)
|
||
|
|
if not self.ihdr_type == b"\x49\x48\x44\x52":
|
||
|
|
raise kaitaistruct.ValidationNotEqualError(b"\x49\x48\x44\x52", self.ihdr_type, self._io, u"/seq/2")
|
||
|
|
self.ihdr = Png.IhdrChunk(self._io, self, self._root)
|
||
|
|
self.ihdr_crc = self._io.read_bytes(4)
|
||
|
|
self.chunks = []
|
||
|
|
i = 0
|
||
|
|
while True:
|
||
|
|
_ = Png.Chunk(self._io, self, self._root)
|
||
|
|
self.chunks.append(_)
|
||
|
|
if ((_.type == u"IEND") or (self._io.is_eof())) :
|
||
|
|
break
|
||
|
|
i += 1
|
||
|
|
|
||
|
|
class Rgb(KaitaiStruct):
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.r = self._io.read_u1()
|
||
|
|
self.g = self._io.read_u1()
|
||
|
|
self.b = self._io.read_u1()
|
||
|
|
|
||
|
|
|
||
|
|
class Chunk(KaitaiStruct):
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.len = self._io.read_u4be()
|
||
|
|
self.type = (self._io.read_bytes(4)).decode(u"UTF-8")
|
||
|
|
_on = self.type
|
||
|
|
if _on == u"iTXt":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.InternationalTextChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"gAMA":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.GamaChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"tIME":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.TimeChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"PLTE":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.PlteChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"bKGD":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.BkgdChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"pHYs":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.PhysChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"fdAT":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.FrameDataChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"tEXt":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.TextChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"cHRM":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.ChrmChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"acTL":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.AnimationControlChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"sRGB":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.SrgbChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"zTXt":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.CompressedTextChunk(_io__raw_body, self, self._root)
|
||
|
|
elif _on == u"fcTL":
|
||
|
|
self._raw_body = self._io.read_bytes(self.len)
|
||
|
|
_io__raw_body = KaitaiStream(BytesIO(self._raw_body))
|
||
|
|
self.body = Png.FrameControlChunk(_io__raw_body, self, self._root)
|
||
|
|
else:
|
||
|
|
self.body = self._io.read_bytes(self.len)
|
||
|
|
self.crc = self._io.read_bytes(4)
|
||
|
|
|
||
|
|
|
||
|
|
class BkgdIndexed(KaitaiStruct):
|
||
|
|
"""Background chunk for images with indexed palette."""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.palette_index = self._io.read_u1()
|
||
|
|
|
||
|
|
|
||
|
|
class Point(KaitaiStruct):
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.x_int = self._io.read_u4be()
|
||
|
|
self.y_int = self._io.read_u4be()
|
||
|
|
|
||
|
|
@property
|
||
|
|
def x(self):
|
||
|
|
if hasattr(self, '_m_x'):
|
||
|
|
return self._m_x
|
||
|
|
|
||
|
|
self._m_x = (self.x_int / 100000.0)
|
||
|
|
return getattr(self, '_m_x', None)
|
||
|
|
|
||
|
|
@property
|
||
|
|
def y(self):
|
||
|
|
if hasattr(self, '_m_y'):
|
||
|
|
return self._m_y
|
||
|
|
|
||
|
|
self._m_y = (self.y_int / 100000.0)
|
||
|
|
return getattr(self, '_m_y', None)
|
||
|
|
|
||
|
|
|
||
|
|
class BkgdGreyscale(KaitaiStruct):
|
||
|
|
"""Background chunk for greyscale images."""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.value = self._io.read_u2be()
|
||
|
|
|
||
|
|
|
||
|
|
class ChrmChunk(KaitaiStruct):
|
||
|
|
"""
|
||
|
|
.. seealso::
|
||
|
|
Source - https://www.w3.org/TR/PNG/#11cHRM
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.white_point = Png.Point(self._io, self, self._root)
|
||
|
|
self.red = Png.Point(self._io, self, self._root)
|
||
|
|
self.green = Png.Point(self._io, self, self._root)
|
||
|
|
self.blue = Png.Point(self._io, self, self._root)
|
||
|
|
|
||
|
|
|
||
|
|
class IhdrChunk(KaitaiStruct):
|
||
|
|
"""
|
||
|
|
.. seealso::
|
||
|
|
Source - https://www.w3.org/TR/PNG/#11IHDR
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.width = self._io.read_u4be()
|
||
|
|
self.height = self._io.read_u4be()
|
||
|
|
self.bit_depth = self._io.read_u1()
|
||
|
|
self.color_type = KaitaiStream.resolve_enum(Png.ColorType, self._io.read_u1())
|
||
|
|
self.compression_method = self._io.read_u1()
|
||
|
|
self.filter_method = self._io.read_u1()
|
||
|
|
self.interlace_method = self._io.read_u1()
|
||
|
|
|
||
|
|
|
||
|
|
class PlteChunk(KaitaiStruct):
|
||
|
|
"""
|
||
|
|
.. seealso::
|
||
|
|
Source - https://www.w3.org/TR/PNG/#11PLTE
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.entries = []
|
||
|
|
i = 0
|
||
|
|
while not self._io.is_eof():
|
||
|
|
self.entries.append(Png.Rgb(self._io, self, self._root))
|
||
|
|
i += 1
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
class SrgbChunk(KaitaiStruct):
|
||
|
|
"""
|
||
|
|
.. seealso::
|
||
|
|
Source - https://www.w3.org/TR/PNG/#11sRGB
|
||
|
|
"""
|
||
|
|
|
||
|
|
class Intent(Enum):
|
||
|
|
perceptual = 0
|
||
|
|
relative_colorimetric = 1
|
||
|
|
saturation = 2
|
||
|
|
absolute_colorimetric = 3
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.render_intent = KaitaiStream.resolve_enum(Png.SrgbChunk.Intent, self._io.read_u1())
|
||
|
|
|
||
|
|
|
||
|
|
class CompressedTextChunk(KaitaiStruct):
|
||
|
|
"""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.
|
||
|
|
|
||
|
|
.. seealso::
|
||
|
|
Source - https://www.w3.org/TR/PNG/#11zTXt
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.keyword = (self._io.read_bytes_term(0, False, True, True)).decode(u"UTF-8")
|
||
|
|
self.compression_method = KaitaiStream.resolve_enum(Png.CompressionMethods, self._io.read_u1())
|
||
|
|
self._raw_text_datastream = self._io.read_bytes_full()
|
||
|
|
self.text_datastream = zlib.decompress(self._raw_text_datastream)
|
||
|
|
|
||
|
|
|
||
|
|
class FrameDataChunk(KaitaiStruct):
|
||
|
|
"""
|
||
|
|
.. seealso::
|
||
|
|
Source - https://wiki.mozilla.org/APNG_Specification#.60fdAT.60:_The_Frame_Data_Chunk
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.sequence_number = self._io.read_u4be()
|
||
|
|
self.frame_data = self._io.read_bytes_full()
|
||
|
|
|
||
|
|
|
||
|
|
class BkgdTruecolor(KaitaiStruct):
|
||
|
|
"""Background chunk for truecolor images."""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.red = self._io.read_u2be()
|
||
|
|
self.green = self._io.read_u2be()
|
||
|
|
self.blue = self._io.read_u2be()
|
||
|
|
|
||
|
|
|
||
|
|
class GamaChunk(KaitaiStruct):
|
||
|
|
"""
|
||
|
|
.. seealso::
|
||
|
|
Source - https://www.w3.org/TR/PNG/#11gAMA
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.gamma_int = self._io.read_u4be()
|
||
|
|
|
||
|
|
@property
|
||
|
|
def gamma_ratio(self):
|
||
|
|
if hasattr(self, '_m_gamma_ratio'):
|
||
|
|
return self._m_gamma_ratio
|
||
|
|
|
||
|
|
self._m_gamma_ratio = (100000.0 / self.gamma_int)
|
||
|
|
return getattr(self, '_m_gamma_ratio', None)
|
||
|
|
|
||
|
|
|
||
|
|
class BkgdChunk(KaitaiStruct):
|
||
|
|
"""Background chunk stores default background color to display this
|
||
|
|
image against. Contents depend on `color_type` of the image.
|
||
|
|
|
||
|
|
.. seealso::
|
||
|
|
Source - https://www.w3.org/TR/PNG/#11bKGD
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
_on = self._root.ihdr.color_type
|
||
|
|
if _on == Png.ColorType.indexed:
|
||
|
|
self.bkgd = Png.BkgdIndexed(self._io, self, self._root)
|
||
|
|
elif _on == Png.ColorType.truecolor_alpha:
|
||
|
|
self.bkgd = Png.BkgdTruecolor(self._io, self, self._root)
|
||
|
|
elif _on == Png.ColorType.greyscale_alpha:
|
||
|
|
self.bkgd = Png.BkgdGreyscale(self._io, self, self._root)
|
||
|
|
elif _on == Png.ColorType.truecolor:
|
||
|
|
self.bkgd = Png.BkgdTruecolor(self._io, self, self._root)
|
||
|
|
elif _on == Png.ColorType.greyscale:
|
||
|
|
self.bkgd = Png.BkgdGreyscale(self._io, self, self._root)
|
||
|
|
|
||
|
|
|
||
|
|
class PhysChunk(KaitaiStruct):
|
||
|
|
""""Physical size" chunk stores data that allows to translate
|
||
|
|
logical pixels into physical units (meters, etc) and vice-versa.
|
||
|
|
|
||
|
|
.. seealso::
|
||
|
|
Source - https://www.w3.org/TR/PNG/#11pHYs
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.pixels_per_unit_x = self._io.read_u4be()
|
||
|
|
self.pixels_per_unit_y = self._io.read_u4be()
|
||
|
|
self.unit = KaitaiStream.resolve_enum(Png.PhysUnit, self._io.read_u1())
|
||
|
|
|
||
|
|
|
||
|
|
class FrameControlChunk(KaitaiStruct):
|
||
|
|
"""
|
||
|
|
.. seealso::
|
||
|
|
Source - https://wiki.mozilla.org/APNG_Specification#.60fcTL.60:_The_Frame_Control_Chunk
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.sequence_number = self._io.read_u4be()
|
||
|
|
self.width = self._io.read_u4be()
|
||
|
|
if not self.width >= 1:
|
||
|
|
raise kaitaistruct.ValidationLessThanError(1, self.width, self._io, u"/types/frame_control_chunk/seq/1")
|
||
|
|
if not self.width <= self._root.ihdr.width:
|
||
|
|
raise kaitaistruct.ValidationGreaterThanError(self._root.ihdr.width, self.width, self._io, u"/types/frame_control_chunk/seq/1")
|
||
|
|
self.height = self._io.read_u4be()
|
||
|
|
if not self.height >= 1:
|
||
|
|
raise kaitaistruct.ValidationLessThanError(1, self.height, self._io, u"/types/frame_control_chunk/seq/2")
|
||
|
|
if not self.height <= self._root.ihdr.height:
|
||
|
|
raise kaitaistruct.ValidationGreaterThanError(self._root.ihdr.height, self.height, self._io, u"/types/frame_control_chunk/seq/2")
|
||
|
|
self.x_offset = self._io.read_u4be()
|
||
|
|
if not self.x_offset <= (self._root.ihdr.width - self.width):
|
||
|
|
raise kaitaistruct.ValidationGreaterThanError((self._root.ihdr.width - self.width), self.x_offset, self._io, u"/types/frame_control_chunk/seq/3")
|
||
|
|
self.y_offset = self._io.read_u4be()
|
||
|
|
if not self.y_offset <= (self._root.ihdr.height - self.height):
|
||
|
|
raise kaitaistruct.ValidationGreaterThanError((self._root.ihdr.height - self.height), self.y_offset, self._io, u"/types/frame_control_chunk/seq/4")
|
||
|
|
self.delay_num = self._io.read_u2be()
|
||
|
|
self.delay_den = self._io.read_u2be()
|
||
|
|
self.dispose_op = KaitaiStream.resolve_enum(Png.DisposeOpValues, self._io.read_u1())
|
||
|
|
self.blend_op = KaitaiStream.resolve_enum(Png.BlendOpValues, self._io.read_u1())
|
||
|
|
|
||
|
|
@property
|
||
|
|
def delay(self):
|
||
|
|
"""Time to display this frame, in seconds."""
|
||
|
|
if hasattr(self, '_m_delay'):
|
||
|
|
return self._m_delay
|
||
|
|
|
||
|
|
self._m_delay = (self.delay_num / (100.0 if self.delay_den == 0 else self.delay_den))
|
||
|
|
return getattr(self, '_m_delay', None)
|
||
|
|
|
||
|
|
|
||
|
|
class InternationalTextChunk(KaitaiStruct):
|
||
|
|
"""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.
|
||
|
|
|
||
|
|
.. seealso::
|
||
|
|
Source - https://www.w3.org/TR/PNG/#11iTXt
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.keyword = (self._io.read_bytes_term(0, False, True, True)).decode(u"UTF-8")
|
||
|
|
self.compression_flag = self._io.read_u1()
|
||
|
|
self.compression_method = KaitaiStream.resolve_enum(Png.CompressionMethods, self._io.read_u1())
|
||
|
|
self.language_tag = (self._io.read_bytes_term(0, False, True, True)).decode(u"ASCII")
|
||
|
|
self.translated_keyword = (self._io.read_bytes_term(0, False, True, True)).decode(u"UTF-8")
|
||
|
|
self.text = (self._io.read_bytes_full()).decode(u"UTF-8")
|
||
|
|
|
||
|
|
|
||
|
|
class TextChunk(KaitaiStruct):
|
||
|
|
"""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.
|
||
|
|
|
||
|
|
.. seealso::
|
||
|
|
Source - https://www.w3.org/TR/PNG/#11tEXt
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.keyword = (self._io.read_bytes_term(0, False, True, True)).decode(u"iso8859-1")
|
||
|
|
self.text = (self._io.read_bytes_full()).decode(u"iso8859-1")
|
||
|
|
|
||
|
|
|
||
|
|
class AnimationControlChunk(KaitaiStruct):
|
||
|
|
"""
|
||
|
|
.. seealso::
|
||
|
|
Source - https://wiki.mozilla.org/APNG_Specification#.60acTL.60:_The_Animation_Control_Chunk
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.num_frames = self._io.read_u4be()
|
||
|
|
self.num_plays = self._io.read_u4be()
|
||
|
|
|
||
|
|
|
||
|
|
class TimeChunk(KaitaiStruct):
|
||
|
|
"""Time chunk stores time stamp of last modification of this image,
|
||
|
|
up to 1 second precision in UTC timezone.
|
||
|
|
|
||
|
|
.. seealso::
|
||
|
|
Source - https://www.w3.org/TR/PNG/#11tIME
|
||
|
|
"""
|
||
|
|
def __init__(self, _io, _parent=None, _root=None):
|
||
|
|
self._io = _io
|
||
|
|
self._parent = _parent
|
||
|
|
self._root = _root if _root else self
|
||
|
|
self._read()
|
||
|
|
|
||
|
|
def _read(self):
|
||
|
|
self.year = self._io.read_u2be()
|
||
|
|
self.month = self._io.read_u1()
|
||
|
|
self.day = self._io.read_u1()
|
||
|
|
self.hour = self._io.read_u1()
|
||
|
|
self.minute = self._io.read_u1()
|
||
|
|
self.second = self._io.read_u1()
|
||
|
|
|
||
|
|
|
||
|
|
|