Beispiel #1
0
 def from_stream(cls, stream, planes_count=3):
     planes_count = int(planes_count)
     assert planes_count > 0
     plane_offsets = tuple(stream_unpack_array('<L', stream, planes_count))
     plane_sizes = tuple(stream_unpack_array('<H', stream, planes_count))
     size = stream_unpack('<HH', stream)
     name = stream_unpack('<16s', stream)[0].decode('ascii')
     null_char_index = name.find('\0')
     if null_char_index >= 0:
         name = name[:null_char_index]
     name = name.rstrip(' \t\r\n\v\0')
     return cls(plane_offsets, plane_sizes, size, name)
Beispiel #2
0
 def from_stream(cls, stream, planes_count=3):
     planes_count = int(planes_count)
     assert planes_count > 0
     plane_offsets = tuple(stream_unpack_array('<L', stream, planes_count))
     plane_sizes = tuple(stream_unpack_array('<H', stream, planes_count))
     dimensions = stream_unpack('<HH', stream)
     name = stream_unpack('<16s', stream)[0].decode('ascii')
     null_char_index = name.find('\0')
     if null_char_index >= 0:
         name = name[:null_char_index]
     name = name.rstrip(' \t\r\n\v\0')
     return cls(plane_offsets, plane_sizes, dimensions, name)
Beispiel #3
0
    def load(self,
             data_stream,
             header_stream,
             data_base=None,
             data_size=None,
             header_base=None,
             header_size=None):

        super().load(data_stream, data_base, data_size)
        data_size = self._data_size
        header_base, header_size = stream_fit(header_stream, header_base,
                                              header_size)
        assert header_size % 4 == 0

        chunk_count = header_size // 4
        chunk_offsets = list(
            stream_unpack_array('<L', header_stream, chunk_count))
        chunk_offsets.append(data_size)
        assert all(0 <= chunk_offsets[i] <= data_size
                   for i in range(chunk_count))
        assert all(chunk_offsets[i] <= chunk_offsets[i + 1]
                   for i in range(chunk_count))

        self._chunk_count = chunk_count
        self._chunk_offsets = chunk_offsets
        self._header_stream = header_stream
        self._header_base = header_base
        self._header_size = header_size
        return self
Beispiel #4
0
    def _read_sounds_infos(self):
        data_stream = self._data_stream
        chunk_count = self._chunk_count
        sounds_start = self.sounds_start

        assert self.sizeof(chunk_count - 1) % 4 == 0
        count = self.sizeof(chunk_count - 1) // 4
        self._seek(chunk_count - 1)
        bounds = list(
            stream_unpack_array('<HH', data_stream, count, scalar=False))
        bounds.append([(chunk_count - sounds_start), bounds[-1][1]])
        infos = [None] * count

        for i in range(count):
            start, length = bounds[i]
            if start >= chunk_count - 1:
                return infos[:i]
            last = bounds[i + 1][0]

            if not last or last + sounds_start > chunk_count - 1:
                last = chunk_count - 1
            else:
                last += sounds_start

            actual_length = sum(
                self.sizeof(j) for j in range(sounds_start + start, last))
            if actual_length & 0xFFFF0000 and (
                    actual_length & 0xFFFF) < length:  # TBV: really needed?
                actual_length -= 0x10000
            actual_length = (actual_length & 0xFFFF0000) | length

            infos[i] = (start, actual_length)

        return infos
Beispiel #5
0
 def from_stream(cls, stream):
     length = stream_unpack('<H', stream)[0]
     assert length % 4 == 0
     length //= 4
     events = list(stream_unpack_array('<BBH', stream, length,
                                       scalar=False))
     return cls(events)
Beispiel #6
0
    def _read_sounds_infos(self):
        data_stream = self._data_stream
        chunk_count = self._chunk_count
        sounds_start = self.sounds_start

        assert self.sizeof(chunk_count - 1) % struct.calcsize('<HH') == 0
        count = self.sizeof(chunk_count - 1) // struct.calcsize('<HH')
        self._seek(chunk_count - 1)
        bounds = list(stream_unpack_array('<HH', data_stream, count, scalar=False))
        bounds.append([(chunk_count - sounds_start), bounds[-1][1]])
        infos = [None] * count

        for i in range(count):
            start, length = bounds[i]
            if start >= chunk_count - 1:
                return infos[:i]
            last = bounds[i + 1][0]

            if not last or last + sounds_start > chunk_count - 1:
                last = chunk_count - 1
            else:
                last += sounds_start

            actual_length = sum(self.sizeof(j) for j in range(sounds_start + start, last))
            if actual_length & 0xFFFF0000 and (actual_length & 0xFFFF) < length:  # FIXME: really needed?
                actual_length -= 0x10000
            actual_length = (actual_length & 0xFFFF0000) | length

            infos[i] = (start, actual_length)

        return infos
Beispiel #7
0
    def load(self, data_stream, data_base=None, data_size=None, dimensions=(64, 64), alpha_index=0xFF,
             data_size_guard=None):
        super().load(data_stream, data_base, data_size)
        data_stream = self._data_stream
        data_base = self._data_base
        data_size = self._data_size
        assert data_size % struct.calcsize('<LH') == 0
        alpha_index = int(alpha_index)
        assert 0x00 <= alpha_index <= 0xFF

        chunk_count, sprites_start, sounds_start = stream_unpack('<HHH', data_stream)
        chunk_offsets = list(stream_unpack_array('<L', data_stream, chunk_count))
        chunk_offsets.append(data_size)

        pages_offset = chunk_offsets[0]
        pages_size = data_size - pages_offset
        assert data_size_guard is None or data_size < data_size_guard  # 100 MiB
        for i in reversed(range(chunk_count)):
            if not chunk_offsets[i]:
                chunk_offsets[i] = chunk_offsets[i + 1]
        assert all(pages_offset <= chunk_offsets[i] <= data_size for i in range(chunk_count))
        assert all(chunk_offsets[i] <= chunk_offsets[i + 1] for i in range(chunk_count))

        self._chunk_count = chunk_count
        self._chunk_offsets = chunk_offsets
        self._pages_offset = pages_offset
        self._pages_size = pages_size
        self._dimensions = dimensions
        self._alpha_index = alpha_index
        self.sprites_start = sprites_start
        self.sounds_start = sounds_start
        self.sounds_infos = self._read_sounds_infos()
        return self
Beispiel #8
0
    def _build_pics_dimensions(self):
        partition_map = self._partition_map
        pics_dimensions_index = self._pics_dimensions_index

        count = partition_map['pics'][1]
        chunk = self.extract_chunk(pics_dimensions_index)
        pics_dimensions = list(stream_unpack_array('<HH', io.BytesIO(chunk), count, scalar=False))
        return pics_dimensions
Beispiel #9
0
    def load(self,
             data_stream,
             header_stream,
             huffman_stream,
             partition_map,
             pics_size_index=0,
             data_base=None,
             data_size=None,
             header_base=None,
             header_size=None,
             huffman_offset=None,
             huffman_size=None):

        super().load(data_stream, data_base, data_size)
        data_size = self._data_size
        pics_size_index = int(pics_size_index)
        assert pics_size_index >= 0
        header_base, header_size = stream_fit(header_stream, header_base,
                                              header_size)
        huffman_offset, huffman_size = stream_fit(huffman_stream,
                                                  huffman_offset, huffman_size)
        assert header_size % 3 == 0
        assert huffman_size >= 4 * HUFFMAN_NODE_COUNT

        chunk_count = header_size // 3
        chunk_offsets = [None] * chunk_count
        for i in range(chunk_count):
            byte0, byte1, byte2 = stream_unpack('<BBB', header_stream)
            offset = byte0 | (byte1 << 8) | (byte2 << 16)
            if offset < 0xFFFFFF:
                chunk_offsets[i] = offset
        chunk_offsets.append(data_size)
        for i in reversed(range(chunk_count)):
            if chunk_offsets[i] is None:
                chunk_offsets[i] = chunk_offsets[i + 1]
        assert all(0 <= chunk_offsets[i] <= data_size
                   for i in range(chunk_count))
        assert all(chunk_offsets[i] <= chunk_offsets[i + 1]
                   for i in range(chunk_count))

        huffman_nodes = list(
            stream_unpack_array('<HH',
                                huffman_stream,
                                HUFFMAN_NODE_COUNT,
                                scalar=False))
        self._chunk_count = chunk_count
        self._chunk_offsets = chunk_offsets
        self._header_stream = header_stream
        self._header_base = header_base
        self._header_size = header_size
        self._huffman_stream = huffman_stream
        self._huffman_offset = huffman_offset
        self._huffman_size = huffman_size
        self._partition_map = partition_map
        self._pics_size_index = pics_size_index
        self._huffman_nodes = huffman_nodes
        self.pics_size = self._build_pics_size()
        return self
Beispiel #10
0
    def _build_pics_size(self):
        partition_map = self._partition_map
        pics_size_index = self._pics_size_index

        count = partition_map['pics'][1]
        chunk = self.extract_chunk(pics_size_index)
        pics_size = list(
            stream_unpack_array('<HH', io.BytesIO(chunk), count, scalar=False))
        return pics_size
Beispiel #11
0
    def load(self, data_stream, header_stream, huffman_stream,
             partition_map, pics_dimensions_index=0,
             data_base=None, data_size=None,
             header_base=None, header_size=None,
             huffman_offset=None, huffman_size=None):

        super().load(data_stream, data_base, data_size)
        data_size = self._data_size
        pics_dimensions_index = int(pics_dimensions_index)
        assert pics_dimensions_index >= 0
        header_base, header_size = stream_fit(header_stream, header_base, header_size)
        huffman_offset, huffman_size = stream_fit(huffman_stream, huffman_offset, huffman_size)
        assert header_size % struct.calcsize('<BBB') == 0
        assert huffman_size >= struct.calcsize('<HH') * HUFFMAN_NODES_COUNT

        chunk_count = header_size // struct.calcsize('<BBB')
        chunk_offsets = [None] * chunk_count
        for i in range(chunk_count):
            byte0, byte1, byte2 = stream_unpack('<BBB', header_stream)
            offset = byte0 | (byte1 << 8) | (byte2 << 16)
            if offset < 0xFFFFFF:
                chunk_offsets[i] = offset
        chunk_offsets.append(data_size)
        for i in reversed(range(chunk_count)):
            if chunk_offsets[i] is None:
                chunk_offsets[i] = chunk_offsets[i + 1]
        assert all(0 <= chunk_offsets[i] <= data_size for i in range(chunk_count))
        assert all(chunk_offsets[i] <= chunk_offsets[i + 1] for i in range(chunk_count))

        huffman_nodes = list(stream_unpack_array('<HH', huffman_stream, HUFFMAN_NODES_COUNT, scalar=False))
        self._chunk_count = chunk_count
        self._chunk_offsets = chunk_offsets
        self._header_stream = header_stream
        self._header_base = header_base
        self._header_size = header_size
        self._huffman_stream = huffman_stream
        self._huffman_offset = huffman_offset
        self._huffman_size = huffman_size
        self._partition_map = partition_map
        self._pics_dimensions_index = pics_dimensions_index
        self._huffman_nodes = huffman_nodes
        self.pics_dimensions = self._build_pics_dimensions()
        return self
Beispiel #12
0
    def load(self,
             data_stream,
             data_base=None,
             data_size=None,
             image_size=(64, 64),
             alpha_index=0xFF,
             data_size_guard=None):
        super().load(data_stream, data_base, data_size)
        data_stream = self._data_stream
        data_base = self._data_base
        data_size = self._data_size
        assert data_size % 6 == 0
        alpha_index = int(alpha_index)
        assert 0x00 <= alpha_index <= 0xFF

        chunk_count, sprites_start, sounds_start = stream_unpack(
            '<HHH', data_stream)
        chunk_offsets = list(
            stream_unpack_array('<L', data_stream, chunk_count))
        chunk_offsets.append(data_size)

        pages_offset = chunk_offsets[0]
        pages_size = data_size - pages_offset
        assert data_size_guard is None or data_size < data_size_guard
        for i in reversed(range(chunk_count)):
            if not chunk_offsets[i]:
                chunk_offsets[i] = chunk_offsets[i + 1]
        assert all(pages_offset <= chunk_offsets[i] <= data_size
                   for i in range(chunk_count))
        assert all(chunk_offsets[i] <= chunk_offsets[i + 1]
                   for i in range(chunk_count))

        self._chunk_count = chunk_count
        self._chunk_offsets = chunk_offsets
        self._pages_offset = pages_offset
        self._pages_size = pages_size
        self._image_size = image_size
        self._alpha_index = alpha_index
        self.sprites_start = sprites_start
        self.sounds_start = sounds_start
        self.sounds_infos = self._read_sounds_infos()
        return self
Beispiel #13
0
    def load(self, data_stream, header_stream,
             data_base=None, data_size=None,
             header_base=None, header_size=None):

        super().load(data_stream, data_base, data_size)
        data_size = self._data_size
        header_base, header_size = stream_fit(header_stream, header_base, header_size)
        assert header_size % struct.calcsize('<L') == 0

        chunk_count = header_size // struct.calcsize('<L')
        chunk_offsets = list(stream_unpack_array('<L', header_stream, chunk_count))
        chunk_offsets.append(data_size)
        assert all(0 <= chunk_offsets[i] <= data_size for i in range(chunk_count))
        assert all(chunk_offsets[i] <= chunk_offsets[i + 1] for i in range(chunk_count))

        self._chunk_count = chunk_count
        self._chunk_offsets = chunk_offsets
        self._header_stream = header_stream
        self._header_base = header_base
        self._header_size = header_size
        return self
Beispiel #14
0
 def from_stream(cls, chunk_stream):
     height = stream_unpack('<H', chunk_stream)[0]
     offsets = list(stream_unpack_array('<H', chunk_stream, cls.CHARACTER_COUNT))
     widths = list(stream_unpack_array('<B', chunk_stream, cls.CHARACTER_COUNT))
     return cls(height, offsets, widths)
Beispiel #15
0
 def from_stream(cls, chunk_stream):
     left, right = stream_unpack('<HH', chunk_stream)
     width = right - left + 1
     offsets = list(stream_unpack_array('<H', chunk_stream, width))
     return cls(left, right, offsets)
Beispiel #16
0
 def from_stream(cls, chunk_stream):
     height = stream_unpack('<H', chunk_stream)[0]
     offsets = list(stream_unpack_array('<H', chunk_stream, cls.CHARACTER_COUNT))
     widths = list(stream_unpack_array('<B', chunk_stream, cls.CHARACTER_COUNT))
     return cls(height, offsets, widths)
Beispiel #17
0
 def from_stream(cls, chunk_stream):
     left, right = stream_unpack('<HH', chunk_stream)
     width = right - left + 1
     offsets = list(stream_unpack_array('<H', chunk_stream, width))
     return cls(left, right, offsets)