"""LCM type definitions
This file automatically generated by lcm.
DO NOT MODIFY BY HAND!!!!
"""


from io import BytesIO
import struct

import drake

class lcmt_image(object):
    """ A representation of an image. """

    __slots__ = ["header", "width", "height", "row_stride", "size", "data", "bigendian", "pixel_format", "channel_type", "compression_method"]

    __typenames__ = ["drake.lcmt_header", "int32_t", "int32_t", "int32_t", "int32_t", "byte", "boolean", "int8_t", "int8_t", "int8_t"]

    __dimensions__ = [None, None, None, None, None, ["size"], None, None, None, None]

    PIXEL_FORMAT_GRAY = 0
    """ enum for pixel_format. """
    PIXEL_FORMAT_RGB = 1
    PIXEL_FORMAT_BGR = 2
    PIXEL_FORMAT_RGBA = 3
    PIXEL_FORMAT_BGRA = 4
    PIXEL_FORMAT_DEPTH = 5
    PIXEL_FORMAT_LABEL = 6
    PIXEL_FORMAT_MASK = 7
    PIXEL_FORMAT_DISPARITY = 8
    PIXEL_FORMAT_BAYER_BGGR = 9
    PIXEL_FORMAT_BAYER_RGGB = 10
    PIXEL_FORMAT_BAYER_GBRG = 11
    PIXEL_FORMAT_BAYER_GRBG = 12
    PIXEL_FORMAT_INVALID = -1
    CHANNEL_TYPE_INT8 = 0
    """ enum for channel_type. """
    CHANNEL_TYPE_UINT8 = 1
    CHANNEL_TYPE_INT16 = 2
    CHANNEL_TYPE_UINT16 = 3
    CHANNEL_TYPE_INT32 = 4
    CHANNEL_TYPE_UINT32 = 5
    CHANNEL_TYPE_FLOAT32 = 6
    CHANNEL_TYPE_FLOAT64 = 7
    CHANNEL_TYPE_INVALID = -1
    COMPRESSION_METHOD_NOT_COMPRESSED = 0
    """ enum for compression_method. """
    COMPRESSION_METHOD_ZLIB = 1
    COMPRESSION_METHOD_JPEG = 2
    COMPRESSION_METHOD_PNG = 3
    COMPRESSION_METHOD_INVALID = -1

    def __init__(self):
        self.header = drake.lcmt_header()
        """
        The timestamp and the frame name where this image is obtained.
        LCM Type: drake.lcmt_header
        """

        self.width = 0
        """
        The image width in pixels.
        LCM Type: int32_t
        """

        self.height = 0
        """
        The image height in pixels.
        LCM Type: int32_t
        """

        self.row_stride = 0
        """
        The physical memory size per a single row in bytes.
        LCM Type: int32_t
        """

        self.size = 0
        """
        The size of `data` in bytes.
        LCM Type: int32_t
        """

        self.data = b""
        """
        The data that contains actual image.
        LCM Type: byte[size]
        """

        self.bigendian = False
        """
        The boolean to denote if the data is stored in the bigendian order.
        LCM Type: boolean
        """

        self.pixel_format = 0
        """
        The semantic meaning of pixels.
        LCM Type: int8_t
        """

        self.channel_type = 0
        """
        The data type for a channel.
        LCM Type: int8_t
        """

        self.compression_method = 0
        """
        The compression method.
        LCM Type: int8_t
        """


    def encode(self):
        buf = BytesIO()
        buf.write(lcmt_image._get_packed_fingerprint())
        self._encode_one(buf)
        return buf.getvalue()

    def _encode_one(self, buf):
        assert self.header._get_packed_fingerprint() == drake.lcmt_header._get_packed_fingerprint()
        self.header._encode_one(buf)
        buf.write(struct.pack(">iiii", self.width, self.height, self.row_stride, self.size))
        buf.write(bytearray(self.data[:self.size]))
        buf.write(struct.pack(">bbbb", self.bigendian, self.pixel_format, self.channel_type, self.compression_method))

    @staticmethod
    def decode(data: bytes):
        if hasattr(data, 'read'):
            buf = data
        else:
            buf = BytesIO(data)
        if buf.read(8) != lcmt_image._get_packed_fingerprint():
            raise ValueError("Decode error")
        return lcmt_image._decode_one(buf)

    @staticmethod
    def _decode_one(buf):
        self = lcmt_image()
        self.header = drake.lcmt_header._decode_one(buf)
        self.width, self.height, self.row_stride, self.size = struct.unpack(">iiii", buf.read(16))
        self.data = buf.read(self.size)
        self.bigendian = bool(struct.unpack('b', buf.read(1))[0])
        self.pixel_format, self.channel_type, self.compression_method = struct.unpack(">bbb", buf.read(3))
        return self

    @staticmethod
    def _get_hash_recursive(parents):
        if lcmt_image in parents: return 0
        newparents = parents + [lcmt_image]
        tmphash = (0xcc69e8044fc49594+ drake.lcmt_header._get_hash_recursive(newparents)) & 0xffffffffffffffff
        tmphash  = (((tmphash<<1)&0xffffffffffffffff) + (tmphash>>63)) & 0xffffffffffffffff
        return tmphash
    _packed_fingerprint = None

    @staticmethod
    def _get_packed_fingerprint():
        if lcmt_image._packed_fingerprint is None:
            lcmt_image._packed_fingerprint = struct.pack(">Q", lcmt_image._get_hash_recursive([]))
        return lcmt_image._packed_fingerprint

    def get_hash(self):
        """Get the LCM hash of the struct"""
        return struct.unpack(">Q", lcmt_image._get_packed_fingerprint())[0]

