コード例 #1
0
ファイル: rle.py プロジェクト: C3RV1/LaytonEditor
def decompress(data: bytes):
    rdr = BinaryReader(data)
    wtr = BinaryWriter()
    type_ = rdr.read_uint8()
    if type_ != 0x30:
        raise Exception("Tried to decompress commands that isn't RLE")
    ds = rdr.read_uint24()
    if ds == 0:
        rdr.read_uint32()

    while True:
        flag = rdr.read_uint8()
        if flag is None:
            break  # we've hit the end
        compressed = (flag & 0x80) > 0
        length = flag & 0x7f
        length += 3 if compressed else 1
        if compressed:
            next_ = rdr.read_uint8()
            for i in range(length):
                wtr.write_uint8(next_)
        else:
            wtr.write(rdr.read(length))

    return wtr.data
コード例 #2
0
    def read(self, rdr: BinaryReader):
        self.chunk_id = rdr.read(4)[::-1]
        if self.chunk_id != b"CGLP":
            raise ValueError("CGLPChunk does not start with magic value")
        self.chunk_size = rdr.read_uint32()
        self.tile_width = rdr.read_uint8()
        self.tile_height = rdr.read_uint8()
        self.tile_bytes = rdr.read_uint16()
        bitmap_items = self.tile_width * self.tile_height
        self.underline_location = rdr.read_uint8()
        self.max_proportional_width = rdr.read_uint8()
        self.tile_depth = rdr.read_uint8()
        self.tile_rotation = rdr.read_uint8()

        self.tile_bitmaps = []

        tile_bytes = self.tile_bytes
        tile_width = self.tile_width
        tile_height = self.tile_height
        tile_depth = self.tile_depth
        # To avoid byte boundaries efficiently
        # If bit depth is 2, we can read in blocks of 2
        # If bit depth is 1, we can only read in blocks of 1
        bit_steps = get_bit_steps(self.tile_depth)
        bit_mask = ((1 << bit_steps) - 1)

        for _ in range((self.chunk_size - 0x10) // tile_bytes):
            buffer = rdr.read(tile_bytes)
            bitmap = np.zeros(bitmap_items, dtype=np.uint8)

            current_bit = 0
            for i in range(bitmap_items):
                # Get value from bytes to bit depth
                v = 0
                for _ in range(tile_depth // bit_steps):
                    # Shift the value bit steps
                    v <<= bit_steps

                    # Get the bit index and the byte index
                    bit_i = current_bit % 8
                    byte_i = (current_bit - bit_i) // 8

                    # Read <bit steps> bits from byte (bit 7 is the MSB)
                    byte = buffer[byte_i]
                    bit = (byte >> (7 - bit_i)) & bit_mask

                    # Add the value and change the current bit
                    v += bit
                    current_bit += bit_steps

                bitmap[i] = v

            bitmap.shape = tile_height, tile_width
            self.tile_bitmaps.append(bitmap)
コード例 #3
0
def decompress(data: bytes) -> bytes:
    rdr = BinaryReader(data)
    wtr = BinaryWriter()
    compression_type = rdr.read_uint8()
    if compression_type == 0x24:
        blocksize = 4
    elif compression_type == 0x28:
        blocksize = 8
    else:
        raise Exception(
            "Tried to decompress something as huffman that isn't huffman")
    ds = rdr.read_uint24()
    if ds == 0:
        rdr.read_uint32()

    # Read the tree
    treesize = (rdr.read_uint8() + 1) * 2
    tree_end = (rdr.c - 1) + treesize
    rootNode = HuffTreeNode.from_rdr(rdr, False, 5, tree_end)
    rdr.c = tree_end

    # Decompress with the tree
    bitsleft = 0  # amount of bits left to read from {commands}
    current_size = 0
    currentNode = rootNode

    cashedbyte = -1

    while current_size < ds:
        # Find next refrence to commands node
        while not currentNode.is_data:
            if bitsleft == 0:
                data = rdr.read_uint32()
                bitsleft = 32

            bitsleft -= 1
            nextIsOne = (data & (1 << bitsleft)) != 0
            if nextIsOne:
                currentNode = currentNode.child1
            else:
                currentNode = currentNode.child0

        if blocksize == 8:
            current_size += 1
            wtr.write_uint8(currentNode.data)

        elif blocksize == 4:
            if cashedbyte < 0:
                cashedbyte = currentNode.data
            else:
                cashedbyte |= currentNode.data << 4
                wtr.write_uint8(cashedbyte)
                current_size += 1
                cashedbyte = -1
        currentNode = rootNode

    return wtr.data
コード例 #4
0
    def read(self, rdr: BinaryReader, fmt_chunk: FmtChunk):
        self.chunk_id = rdr.read(4)
        self.chunk_size = rdr.read_uint32()

        if fmt_chunk.bits_per_sample == 0x10:
            data = np.frombuffer(rdr.read(self.chunk_size), dtype="<h")
        elif fmt_chunk.bits_per_sample == 0x08:
            data = np.frombuffer(rdr.read(self.chunk_size), dtype="<b")
        else:
            raise NotImplementedError()
        data = data.reshape(
            (data.shape[0] // fmt_chunk.num_channels, fmt_chunk.num_channels))
        self.data = data.swapaxes(0, 1)
コード例 #5
0
    def read_stream(self, stream: any):
        if isinstance(stream, BinaryReader):
            rdr: BinaryReader = stream
        else:
            rdr: BinaryReader = BinaryReader(stream)
        self.header = NFTRHeader()
        self.font_info = FINFChunk()
        self.char_glyph = CGLPChunk()
        self.char_width = CWDHChunk()
        self.char_maps = []

        self.header.read(rdr)

        rdr.seek(self.header.offset_to_fnif)
        self.font_info.read(rdr)

        rdr.seek(self.font_info.offset_to_cglp_chunk)
        self.char_glyph.read(rdr)

        rdr.seek(self.font_info.offset_to_cwdh_chunk)
        self.char_width.read(rdr, len(self.char_glyph.tile_bitmaps))

        next_offset = self.font_info.offset_to_cmap_chunk
        for i in range(self.header.following_chunk_count - 3):
            rdr.seek(next_offset)
            cmap = CMAPChunk()
            cmap.read(rdr)
            self.char_maps.append(cmap)
            next_offset = cmap.offset_to_next_cmap
コード例 #6
0
ファイル: swd.py プロジェクト: C3RV1/LaytonEditor
def swd_read_samplebank(stream) -> SampleBank:
    rdr = stream if isinstance(stream, BinaryReader) else BinaryReader(stream)
    rdr.seek(0x0c)
    assert rdr.read_uint16() == 0x0415  # Correct version
    assert rdr.read_bool()  # This is a SampleBank
    group = rdr.read_uint8()
    rdr.seek(0x20)
    label = rdr.read_string(16, pad=b"\xaa")
    samples = swd_read_samples(stream)
    return SampleBank(label, group, samples)
コード例 #7
0
 def read(self, rdr: BinaryReader):
     self.chunk_id = rdr.read(4)
     self.chunk_size = rdr.read_uint32()
     self.audio_format = rdr.read_uint16()
     self.num_channels = rdr.read_uint16()
     self.sample_rate = rdr.read_uint32()
     self.byte_rate = rdr.read_uint32()
     self.block_align = rdr.read_uint16()
     self.bits_per_sample = rdr.read_uint16()
コード例 #8
0
ファイル: swd.py プロジェクト: C3RV1/LaytonEditor
def swd_read_presetbank(stream) -> PresetBank:
    rdr = stream if isinstance(stream, BinaryReader) else BinaryReader(stream)
    rdr.seek(0x0c)
    assert rdr.read_uint16() == 0x0415  # Correct version
    assert not rdr.read_bool()  # This is not a SampleBank
    group = rdr.read_ubyte()

    rdr.seek(0x20)
    label = rdr.read_string(16, pad=b"\xaa")

    samples_info = swd_read_samples_info(stream)
    presets = swd_read_presets(stream, samples_info)
    return PresetBank(label, group, presets, samples_info)
コード例 #9
0
    def from_rdr(cls,
                 rdr: BinaryReader,
                 is_data: bool,
                 relative_offset,
                 max_stream_pos,
                 parent=None):
        self = cls(is_data, parent=parent)
        if rdr.c >= max_stream_pos:
            return
        self.data = rdr.read_uint8()
        if not is_data:
            offset = self.data & 0x3F
            zeroIsData = (self.data & 0x80) > 0
            oneIsData = (self.data & 0x40) > 0

            # off AND NOT == off XOR (off AND 1)
            zeroRelOffset = (relative_offset ^
                             (relative_offset & 1)) + offset * 2 + 2

            currStreamPos = rdr.c

            rdr.c += (zeroRelOffset - relative_offset) - 1

            # Node after 0
            self.child0 = HuffTreeNode.from_rdr(rdr,
                                                zeroIsData,
                                                zeroRelOffset,
                                                max_stream_pos,
                                                parent=self)
            # Node after 1 directly located after the node after 0
            self.child1 = HuffTreeNode.from_rdr(rdr,
                                                oneIsData,
                                                zeroRelOffset + 1,
                                                max_stream_pos,
                                                parent=self)

            # reset stream
            rdr.c = currStreamPos
        return self
コード例 #10
0
    def read_stream(self, stream: BinaryIO):
        if isinstance(stream, BinaryReader):
            rdr = stream
        else:
            rdr = BinaryReader(stream)

        n_entries = rdr.read_uint16()
        header_length = rdr.read_uint16()
        entry_length = rdr.read_uint16()
        rdr.seek(header_length)

        self._entries = []

        for i in range(n_entries):
            self._entries.append(rdr.read(entry_length))
コード例 #11
0
 def read(self, rdr: BinaryReader):
     self.magic_value = rdr.read(4)[::-1]
     if self.magic_value != b"NFTR":
         raise ValueError("NFTRHeader does not start with magic value")
     self.byte_order = rdr.read_uint16()
     self.version = rdr.read_uint16()
     self.decompressed_resource_size = rdr.read_uint32()
     self.offset_to_fnif = rdr.read_uint16()
     self.following_chunk_count = rdr.read_uint16()
コード例 #12
0
    def read(self, rdr: BinaryReader, tile_count: int):
        self.chunk_id = rdr.read(4)[::-1]
        if self.chunk_id != b"CWDH":
            raise ValueError("CWDHChunk does not start with magic value")
        self.chunk_size = rdr.read_uint32()
        self.first_tile_no = rdr.read_uint16()
        self.last_tile_no = rdr.read_uint16()
        rdr.read(4)

        self.left_spacing = []
        self.width = []
        self.total_width = []
        for i in range(tile_count):
            left_spacing = rdr.read_uint8()
            width = rdr.read_uint8()
            total_width = rdr.read_uint8()

            self.left_spacing.append(left_spacing)
            self.width.append(width)
            self.total_width.append(total_width)
コード例 #13
0
ファイル: swd.py プロジェクト: C3RV1/LaytonEditor
def swd_read_sections(stream) -> Dict[str, Tuple[int, int]]:
    rdr = stream if isinstance(stream, BinaryReader) else BinaryReader(stream)
    rdr.seek(0x50)  # goto the start of the sections
    sections: Dict[str, Tuple[int, int]] = {
    }  # dict of the name of the section and then the start and length.
    while rdr.tell() < len(rdr):
        header_start = rdr.tell()
        name = rdr.read_string(4)
        rdr.seek(4, SEEK_CUR)
        header_length = rdr.read_uint32()
        start = header_start + header_length
        length = rdr.read_uint32()
        sections[name] = (start, length)
        rdr.seek(start + length)
        rdr.align(0x10)
    return sections
コード例 #14
0
ファイル: swd.py プロジェクト: C3RV1/LaytonEditor
def swd_read_presets(stream, samples_info) -> Dict[int, Preset]:
    rdr = stream if isinstance(stream, BinaryReader) else BinaryReader(stream)
    rdr.seek(0x48)
    n_prgi_slots = rdr.read_uint16()
    sections = swd_read_sections(stream)
    prgi_offset, prgi_len = sections["prgi"]
    presets: Dict[int, Preset] = {}
    rdr.seek(prgi_offset)
    for preset_index, preset_section_offset in enumerate(
            rdr.read_uint16_array(n_prgi_slots)):
        if not preset_section_offset:
            continue
        preset_offset = prgi_offset + preset_section_offset
        rdr.seek(preset_offset)
        assert rdr.read_uint16() == preset_index
        n_splits = rdr.read_uint16()
        rdr.seek(preset_offset + 0xb)
        n_lfos = rdr.read_uint8()
        rdr.seek(preset_offset + 0x10)
        lfos = []
        for lfo_index in range(n_lfos):
            lfo_offset = rdr.tell()
            rdr.seek(lfo_offset + 2)
            destination = LFODestination(rdr.read_int8())
            wave_shape = LFOWaveShape(rdr.read_int8())
            rate = rdr.read_uint16()
            depth = rdr.read_uint16()
            delay = rdr.read_uint16()
            lfos.append(LFO(destination, wave_shape, rate, depth, delay))
        rdr.seek(preset_offset + 0x10 + 0x10 * n_lfos + 0x10)
        splits = []
        for split_index in range(n_splits):
            split_offset = rdr.tell()
            rdr.seek(split_offset + 0x04)
            lowkey = rdr.read_int8()
            highkey = rdr.read_int8()
            rdr.seek(split_offset + 0x12)
            sample_index = rdr.read_uint16()
            tuning = rdr.read_int8()
            rdr.seek(split_offset + 0x16)
            rootkey = rdr.read_int8()
            rdr.seek(split_offset + 0x30)
            splits.append(
                SplitEntry(highkey, lowkey, samples_info[sample_index], tuning,
                           rootkey))
        presets[preset_index] = Preset(splits, lfos)
    return presets
コード例 #15
0
ファイル: smdl.py プロジェクト: C3RV1/LaytonEditor
    def read_stream(self, stream: BinaryIO):
        if isinstance(stream, BinaryReader):
            rdr = stream
        else:
            rdr = BinaryReader(stream)
        self.smdl_header = SMDLHeader()
        self.song_chunk = SongChunk()
        self.tracks = []
        self.eoc_chunk = EOCChunk()

        self.smdl_header.read(rdr)
        self.song_chunk.read(rdr)
        for i in range(self.song_chunk.num_tracks):
            new_track = Track()
            new_track.read(rdr)
            self.tracks.append(new_track)
        self.eoc_chunk.read(rdr)
コード例 #16
0
ファイル: swd.py プロジェクト: C3RV1/LaytonEditor
def swd_read_samples_info(stream) -> Dict[int, SampleInfo]:
    rdr = stream if isinstance(stream, BinaryReader) else BinaryReader(stream)
    rdr.seek(0x46)
    n_wavi_slots = rdr.read_uint16()
    sections = swd_read_sections(stream)
    wavi_offset, wavi_len = sections["wavi"]
    samples_info: Dict[int, SampleInfo] = {}
    rdr.seek(wavi_offset)
    for sample_index, sample_info_section_offset in enumerate(
            rdr.read_uint16_array(n_wavi_slots)):
        if not sample_info_section_offset:
            continue
        sample_info_offset = wavi_offset + sample_info_section_offset
        rdr.seek(sample_info_offset + 0x04)
        tuning = rdr.read_int8()
        rdr.seek(sample_info_offset + 0x15)
        loop_enabled = rdr.read_bool()
        rdr.seek(sample_info_offset + 0x28)
        loop = rdr.read_uint32() * 8 - 9
        samples_info[sample_index] = SampleInfo(sample_index, loop_enabled,
                                                loop, tuning)
    return samples_info
コード例 #17
0
ファイル: swd.py プロジェクト: C3RV1/LaytonEditor
def swd_read_samples(stream) -> Dict[int, Sample]:
    rdr = stream if isinstance(stream, BinaryReader) else BinaryReader(stream)
    rdr.seek(0x46)
    n_wavi_slots = rdr.read_uint16()
    sections = swd_read_sections(stream)
    wavi_offset, wavi_len = sections["wavi"]
    pcmd_offset, pcmd_len = sections["pcmd"]
    samples: Dict[int, Sample] = {}
    rdr.seek(wavi_offset)
    for sample_index, sample_info_offset in enumerate(
            rdr.read_uint16_array(n_wavi_slots)):
        if not sample_info_offset:
            continue
        rdr.seek(wavi_offset + sample_info_offset + 0x20)
        samplerate = rdr.read_uint32()
        adpcm_pos = rdr.read_uint32()
        adpcm_loop_position = rdr.read_uint32() * 4
        adpcm_loop_lenght = rdr.read_uint32() * 4
        adpcm_lenght = (adpcm_loop_position + adpcm_loop_lenght)

        rdr.seek(pcmd_offset + adpcm_pos)
        samples[sample_index] = Sample(samplerate, rdr.read(adpcm_lenght))

    return samples
コード例 #18
0
ファイル: gds.py プロジェクト: C3RV1/LaytonEditor
    def read_stream(self, stream: BinaryIO):
        if isinstance(stream, BinaryReader):
            rdr = stream
        else:
            rdr = BinaryReader(stream)

        self.commands = []
        self.params = []
        file_length = rdr.read_uint32()

        while rdr.c < file_length:
            datatype = rdr.read_uint16()
            if datatype == 0:
                break
            elif datatype == 1:
                self.params.append(rdr.read_uint32())
            elif datatype == 2:
                self.params.append(rdr.read_float())
            elif datatype == 3:
                self.params.append(rdr.read_string(rdr.read_uint16()))
            elif datatype == 0xc:
                return
        while rdr.c < file_length:
            self.commands.append(command := GDSCommand(rdr.read_uint16()))
            while rdr.c < file_length:
                datatype = rdr.read_uint16()
                if datatype == 0:
                    break
                if datatype == 1:
                    command.params.append(rdr.read_uint32())
                elif datatype == 2:
                    command.params.append(rdr.read_float())
                elif datatype == 3:
                    command.params.append(rdr.read_string(rdr.read_uint16()))
                elif datatype == 0xc:
                    return
コード例 #19
0
def compress(data: bytes):
    rdr = BinaryReader(data)
    wtr = BinaryWriter()

    wtr.write_uint8(0x30)  # rle identifier

    wtr.write_uint24(len(data) if len(data) < 0xffffff else 0)
    if len(data) > 0xffffff:
        wtr.write_uint32(len(data))

    repCount = 1
    currentBlockLenght = 0
    dataBlock = [0 for _ in range(130)]
    while rdr.c < len(rdr.data):
        foundRepetition = False
        while (currentBlockLenght < 130 and rdr.c < len(rdr.data)):
            nextByte = rdr.read_uint8()
            dataBlock[currentBlockLenght] = nextByte
            currentBlockLenght += 1
            if (currentBlockLenght > 1):
                if nextByte == dataBlock[currentBlockLenght - 2]:
                    repCount += 1
                else:
                    repCount = 1
            foundRepetition = repCount > 2
            if foundRepetition:
                break
        if foundRepetition:
            numUncompToCopy = currentBlockLenght - 3
        else:
            numUncompToCopy = min(currentBlockLenght, 130 - 2)

        if numUncompToCopy > 0:
            flag = numUncompToCopy - 1
            wtr.write_uint8(flag)
            for i in range(numUncompToCopy):
                wtr.write_uint8(dataBlock[i])
            for i in range(numUncompToCopy, currentBlockLenght):
                dataBlock[i - numUncompToCopy] = dataBlock[i]
            currentBlockLenght -= numUncompToCopy
        if foundRepetition:
            while currentBlockLenght < 130 and rdr.c < len(rdr.data):
                nextByte = rdr.read_uint8()
                dataBlock[currentBlockLenght] = nextByte
                currentBlockLenght += 1
                if nextByte != dataBlock[0]:
                    break
                else:
                    repCount += 1
            flag = 0x80 | (repCount - 3)
            wtr.write_uint8(flag)
            wtr.write_uint8(dataBlock[0])
            if (repCount != currentBlockLenght):
                dataBlock[0] = dataBlock[currentBlockLenght - 1]
            currentBlockLenght -= repCount

    if currentBlockLenght > 0:
        flag = currentBlockLenght - 1
        wtr.write_uint8(flag)
        for i in range(currentBlockLenght):
            wtr.write_uint8(dataBlock[i])
        currentBlockLenght = 0

    return wtr.data
コード例 #20
0
ファイル: puzzle.py プロジェクト: C3RV1/LaytonEditor
    def load(self, rdr):
        if not isinstance(rdr, BinaryReader):
            rdr = BinaryReader(rdr)
        rdr: BinaryReader

        self.original = rdr.read()
        rdr.seek(0)

        self.number = rdr.read_uint16()
        rdr.read_uint16()  # 112
        self.title = rdr.read_string(encoding=self.encoding)
        rdr.seek(0x34)
        self.tutorial_id = rdr.read_uint8()
        for i in range(3):
            self.picarat_decay[i] = rdr.read_uint8()
        self._flags = rdr.read_uint8()
        self.location_id = rdr.read_uint8()
        self.type = rdr.read_uint8()
        self.bg_btm_id = rdr.read_uint8()
        rdr.read_uint16()
        self.bg_top_id = rdr.read_uint8()
        self.reward_id = rdr.read_uint8()

        puzzle_text_offset = 0x70 + rdr.read_uint32()
        puzzle_correct_answer_offset = 0x70 + rdr.read_uint32()
        puzzle_incorrect_answer_offset = 0x70 + rdr.read_uint32()
        puzzle_hint1_offset = 0x70 + rdr.read_uint32()
        puzzle_hint2_offset = 0x70 + rdr.read_uint32()
        puzzle_hint3_offset = 0x70 + rdr.read_uint32()
        rdr.seek(puzzle_text_offset)
        self.text = subs.replace_substitutions(rdr.read_string(encoding=self.encoding), True)
        rdr.seek(puzzle_correct_answer_offset)
        self.correct_answer = subs.replace_substitutions(rdr.read_string(encoding=self.encoding), True)
        rdr.seek(puzzle_incorrect_answer_offset)
        self.incorrect_answer = subs.replace_substitutions(rdr.read_string(encoding=self.encoding), True)
        rdr.seek(puzzle_hint1_offset)
        self.hint1 = subs.replace_substitutions(rdr.read_string(encoding=self.encoding), True)
        rdr.seek(puzzle_hint2_offset)
        self.hint2 = subs.replace_substitutions(rdr.read_string(encoding=self.encoding), True)
        rdr.seek(puzzle_hint3_offset)
        self.hint3 = subs.replace_substitutions(rdr.read_string(encoding=self.encoding), True)
コード例 #21
0
    def read_stream(self, stream):
        if not isinstance(stream, BinaryReader):
            rdr = BinaryReader(stream)
        else:
            rdr = stream

        self.chunk_id = rdr.read(4)
        self.chunk_size = rdr.read_uint32()
        self.format = rdr.read(4)
        if self.chunk_id != b"RIFF" or self.format != b"WAVE":
            raise NotImplementedError()

        self.fmt.read(rdr)

        if self.fmt.audio_format != WaveFormat.WAVE_FORMAT_PCM or self.fmt.bits_per_sample == 0x08:
            raise NotImplementedError()

        rdr.seek(0x14 + self.fmt.chunk_size)

        data_id = rdr.read(4)
        while data_id != b"data":
            offset = rdr.read_uint32()
            rdr.seek(rdr.tell() + offset)
            data_id = rdr.read(4)
        rdr.seek(-4, os.SEEK_CUR)

        self.data.read(rdr, self.fmt)
コード例 #22
0
ファイル: rle.py プロジェクト: C3RV1/LaytonEditor
def compress(data: bytes):
    rdr = BinaryReader(data)
    wtr = BinaryWriter()

    wtr.write_uint8(0x30)  # rle identifier

    wtr.write_uint24(len(data) if len(data) < 0xffffff else 0)
    if len(data) > 0xffffff:
        wtr.write_uint32(len(data))

    rep_count = 1
    current_block_length = 0
    data_block = [0 for _ in range(130)]
    while rdr.c < len(rdr.data):
        found_repetition = False
        while current_block_length < 130 and rdr.c < len(rdr.data):
            next_byte = rdr.read_uint8()
            data_block[current_block_length] = next_byte
            current_block_length += 1
            if current_block_length > 1:
                if next_byte == data_block[current_block_length - 2]:
                    rep_count += 1
                else:
                    rep_count = 1
            found_repetition = rep_count > 2
            if found_repetition:
                break
        if found_repetition:
            num_uncomp_to_copy = current_block_length - 3
        else:
            num_uncomp_to_copy = min(current_block_length, 130 - 2)

        if num_uncomp_to_copy > 0:
            flag = num_uncomp_to_copy - 1
            wtr.write_uint8(flag)
            for i in range(num_uncomp_to_copy):
                wtr.write_uint8(data_block[i])
            for i in range(num_uncomp_to_copy, current_block_length):
                data_block[i - num_uncomp_to_copy] = data_block[i]
            current_block_length -= num_uncomp_to_copy
        if found_repetition:
            while current_block_length < 130 and rdr.c < len(rdr.data):
                next_byte = rdr.read_uint8()
                data_block[current_block_length] = next_byte
                current_block_length += 1
                if next_byte != data_block[0]:
                    break
                else:
                    rep_count += 1
            flag = 0x80 | (rep_count - 3)
            wtr.write_uint8(flag)
            wtr.write_uint8(data_block[0])
            if rep_count != current_block_length:
                data_block[0] = data_block[current_block_length - 1]
            current_block_length -= rep_count

    if current_block_length > 0:
        flag = current_block_length - 1
        wtr.write_uint8(flag)
        for i in range(current_block_length):
            wtr.write_uint8(data_block[i])

    return wtr.data
コード例 #23
0
ファイル: smdl.py プロジェクト: C3RV1/LaytonEditor
 def read(self, br: BinaryReader):
     br.seek(0x40, io.SEEK_SET)
     self.label = br.read(4)
     if self.label != b"song":
         raise ValueError("SongChunk does not start with magic value")
     self.unk1 = br.read_uint32()
     br.read_uint32()  # 0xFF10
     br.read_uint32()  # 0xFFFFFFB0
     br.read_uint16()  # 0x1
     self.tpqn = br.read_uint16()
     br.read_uint16()  # 0xFF10
     self.num_tracks = br.read_uint8()
     self.num_channels = br.read_uint8()
     br.read_uint32()  # 0x0F000000
     br.read_uint32()  # 0xFFFFFFFF
     br.read_uint32()  # 0x40000000
     br.read_uint32()  # 0x00404000
     br.read_uint16()  # 0x0200
     br.read_uint16()  # 0x0800
     br.read_uint32()  # 0xFFFFFF00
     br.read(16)  # 16 0xFF Padding
コード例 #24
0
ファイル: smdl.py プロジェクト: C3RV1/LaytonEditor
 def read(self, br: BinaryReader):
     br.seek(0, io.SEEK_SET)
     self.magic = br.read(4)
     if self.magic != b"smdl":
         raise ValueError("SMDHeader does not start with magic value")
     br.read_uint32()  # 0
     self.file_length = br.read_uint32()
     self.version = br.read_uint16()
     self.unk1 = br.read_uint8()
     self.unk2 = br.read_uint8()
     # 8 bytes of 0
     br.read_uint32()
     br.read_uint32()
     self.year = br.read_uint16()
     self.month = br.read_uint8()
     self.day = br.read_uint8()
     self.hour = br.read_uint8()
     self.minute = br.read_uint8()
     self.second = br.read_uint8()
     self.centisecond = br.read_uint8()
     self.file_name = br.read_string(16, encoding=None, pad=b"\xFF")
     br.read_uint32()  # 0x1
     br.read_uint32()  # 0x1
     br.read_uint32()  # 0xFFFFFFFF
     br.read_uint32()  # 0xFFFFFFFF
コード例 #25
0
ファイル: smdl.py プロジェクト: C3RV1/LaytonEditor
 def read(self, br: BinaryReader, track_header: TrackChunkHeader):
     eb = br.read_char_array(track_header.chunk_length - 4)
     self.event_bytes = b"".join(eb)
コード例 #26
0
ファイル: smdl.py プロジェクト: C3RV1/LaytonEditor
 def read(self, br: BinaryReader):
     self.track_id = br.read_uint8()
     self.channel_id = br.read_uint8()
     self.unk1 = br.read_uint8()
     self.unk2 = br.read_uint8()
コード例 #27
0
    def read_stream(self, stream: BinaryIO):
        if isinstance(stream, BinaryReader):
            rdr = stream
        else:
            rdr = BinaryReader(stream)
        with open("test.bin", "wb+") as f:
            f.write(rdr.read())
        rdr.seek(0)

        palette_lenght = rdr.read_uint32()
        for color_i in range(palette_lenght):
            self.palette[color_i] = ndspy.color.unpack255(rdr.read_uint16())
            if color_i:
                self.palette[color_i, 3] = 255

        n_tiles = rdr.read_uint32()
        tiles = np.frombuffer(rdr.read(n_tiles * 0x40), np.uint8).reshape((n_tiles, 8, 8))

        map_w = rdr.read_uint16()
        map_h = rdr.read_uint16()

        img_w = map_w * 8
        img_h = map_h * 8

        self.image = np.zeros((img_h, img_w), np.uint8)

        for map_y in range(map_h):
            for map_x in range(map_w):
                img_y = map_y * 8
                img_x = map_x * 8

                self.image[img_y:img_y + 8, img_x:img_x + 8] = tiles[rdr.read_uint16()]
コード例 #28
0
ファイル: ani.py プロジェクト: C3RV1/LaytonEditor
    def read_stream(self, stream: BinaryIO):
        if isinstance(stream, BinaryReader):
            rdr = stream
        else:
            rdr = BinaryReader(stream)

        n_images = rdr.read_uint16()
        self.colordepth = 4 if rdr.read_uint16() == 3 else 8

        # import the images
        self.images = []
        for img_i in range(n_images):
            img_w = rdr.read_uint16()
            img_h = rdr.read_uint16()
            n_parts = rdr.read_uint16()

            img = np.zeros((img_h, img_w), np.uint8)

            rdr.seek(2, SEEK_CUR)
            for part_i in range(n_parts):
                part_x = rdr.read_uint16()
                part_y = rdr.read_uint16()
                part_w = 2**(3 + rdr.read_uint16())
                part_h = 2**(3 + rdr.read_uint16())

                part: np.ndarray
                if self.colordepth == 8:
                    part = np.frombuffer(rdr.read(part_h * part_w), np.uint8)
                    part = part.reshape((part_h, part_w))
                else:
                    bufpart = np.frombuffer(rdr.read(part_h * part_w // 2),
                                            np.uint8)
                    part = np.zeros((part_w * part_h), np.uint8)
                    part[0::2] = bufpart & 0xf
                    part[1::2] = bufpart >> 4
                    part = part.reshape((part_h, part_w))

                if (part_x + part_w) > img_w:
                    part_w = img_w - part_x
                if (part_y + part_h) > img_h:
                    part_h = img_h - part_y
                img[part_y:part_y + part_h,
                    part_x:part_x + part_w] = part[:part_h, :part_w]

            self.images.append(img)

        self.palette = np.zeros((256, 4), np.uint8)
        palette_length = rdr.read_uint32()
        for color_i in range(palette_length):
            self.palette[color_i] = ndspy.color.unpack255(rdr.read_uint16())
            if color_i:
                self.palette[color_i, 3] = 255

        rdr.seek(0x1E, SEEK_CUR)
        n_animations = rdr.read_uint32()
        animation_names = rdr.read_string_array(n_animations, 0x1e)
        animation_frame_sets = []
        for i in range(n_animations):
            n_frames = rdr.read_uint32()
            frame_indexes = rdr.read_uint32_array(n_frames)
            frame_durations = rdr.read_uint32_array(n_frames)
            image_indexes = rdr.read_uint32_array(n_frames)
            animation_frame_sets.append([
                AnimationFrame(index=frame_indexes[i],
                               duration=frame_durations[i],
                               image_index=image_indexes[i])
                for i in range(n_frames)
            ])
        self.animations = [
            Animation(name=animation_names[i], frames=animation_frame_sets[i])
            for i in range(n_animations)
        ]

        if rdr.read_uint16() != 0x1234:
            return  # We hit end of stream

        variable_labels = rdr.read_string_array(16, 16)
        variable_data = [[] for _ in range(16)]
        for _ in range(8):
            for var_i in range(16):
                variable_data[var_i].append(rdr.read_int16())

        self.variables = {
            variable_labels[i]: variable_data[i]
            for i in range(16)
        }

        for anim in self.animations:
            anim.child_image_x = rdr.read_uint16()
        for anim in self.animations:
            anim.child_image_y = rdr.read_uint16()
        for anim in self.animations:
            anim.child_image_animation_index = rdr.read_uint8()

        self.child_image = rdr.read_string(128)
コード例 #29
0
    def read_stream(self, stream):
        if not isinstance(stream, BinaryReader):
            rdr = BinaryReader(stream)
        else:
            rdr = stream
        self.original_header = rdr.read(0x100)
        rdr.seek(0)

        self.chunk_id = rdr.read(4)
        if self.chunk_id != b"sadl":
            raise ValueError("SADL does not start with magic value")
        rdr.seek(0x31)
        self.loop_flag = rdr.read_uint8()
        self.channels = rdr.read_uint8()

        coding = rdr.read_uint8()
        if coding & 0x06 == 4:
            self.sample_rate = 32728
        elif coding & 0x06 == 2:
            self.sample_rate = 16364
        self.coding = coding & 0xf0

        rdr.seek(0x40)
        self.file_size = rdr.read_uint32()

        if self.coding == Coding.INT_IMA:
            self.num_samples = int((self.file_size - 0x100) / self.channels * 2)
        elif self.coding == Coding.NDS_PROCYON:
            self.num_samples = int((self.file_size - 0x100) / self.channels / 16 * 30)
        else:
            raise NotImplementedError()

        rdr.seek(0x54)
        if self.loop_flag != 0:
            if self.coding == Coding.INT_IMA:
                self.loop_offset = int((rdr.read_uint32() - 0x100) / self.channels * 2)
            elif self.coding == Coding.NDS_PROCYON:
                self.loop_offset = int((rdr.read_uint32() - 0x100) / self.channels / 16 * 30)

        rdr.seek(0x100)
        buffer = rdr.read(self.file_size - 0x100)
        buffer = np.frombuffer(buffer, dtype=np.uint8)
        buffer = buffer.reshape(((self.file_size - 0x100) // 0x10 // self.channels, self.channels, 0x10))
        buffer = buffer.swapaxes(0, 1)
        self.buffer = buffer.reshape((buffer.shape[0], buffer.shape[1] * buffer.shape[2]))
        self.offset = [0] * self.channels
        self.ima_decoders = []
        self.procyon_decoders = []
        for i in range(self.channels):
            self.ima_decoders.append(ima_adpcm.ImaAdpcm())
            self.procyon_decoders.append(procyon.Procyon())
        self.blocks_done = 0
コード例 #30
0
    def read_stream(self, stream: BinaryIO):
        rdr = stream if isinstance(stream, BinaryReader) else BinaryReader(stream)

        n_images = rdr.read_uint16()
        self.colordepth = 4 if rdr.read_uint16() == 3 else 8
        palette_length = rdr.read_uint32()

        # import the images
        self.images = []
        for img_i in range(n_images):
            img_w = rdr.read_uint16()
            img_h = rdr.read_uint16()
            n_parts = rdr.read_uint16()

            img = np.zeros((img_h, img_w), np.uint8)

            rdr.seek(2, SEEK_CUR)
            for part_i in range(n_parts):
                _part_glb_x = rdr.read_uint16()
                _part_glb_y = rdr.read_uint16()
                part_x = rdr.read_uint16()
                part_y = rdr.read_uint16()
                part_w = 2 ** (3 + rdr.read_uint16())
                part_h = 2 ** (3 + rdr.read_uint16())
                part: np.ndarray
                if self.colordepth == 8:
                    part = np.frombuffer(rdr.read(part_h * part_w), np.uint8)
                else:
                    bufpart = np.frombuffer(rdr.read(part_h * part_w // 2), np.uint8)
                    part = np.zeros((part_w * part_h), np.uint8)
                    part[0::2] = bufpart & 0xf
                    part[1::2] = bufpart >> 4
                    part = part.reshape((part_h, part_w))
                part.resize((part_h // 8, part_w // 8, 8, 8))
                part_w = min(img_w - part_x, part_w)
                part_h = min(img_h - part_y, part_h)
                for yt, yslice in enumerate(part):
                    for xt, xslice in enumerate(yslice):
                        offset_y = part_y + yt * 8
                        offset_x = part_x + xt * 8
                        end_y = min(part_y + yt * 8 + 8, part_y + part_h)
                        end_x = min(part_x + xt * 8 + 8, part_x + part_w)
                        copy_h = max(end_y - offset_y, 0)
                        copy_w = max(end_x - offset_x, 0)
                        img[offset_y:end_y,
                            offset_x:end_x] = \
                            xslice[:copy_h, :copy_w]

            self.images.append(img)

        self.palette = np.zeros((256, 4), np.uint8)
        for color_i in range(palette_length):
            self.palette[color_i] = ndspy.color.unpack255(rdr.read_uint16())
            if color_i:
                self.palette[color_i, 3] = 255

        rdr.seek(0x1E, SEEK_CUR)
        n_animations = rdr.read_uint32()
        animation_names = rdr.read_string_array(n_animations, 0x1e)
        animation_frame_sets = []
        for i in range(n_animations):
            n_frames = rdr.read_uint32()
            frame_indexes = rdr.read_uint32_array(n_frames)
            frame_durations = rdr.read_uint32_array(n_frames)
            image_indexes = rdr.read_uint32_array(n_frames)
            animation_frame_sets.append([
                AnimationFrame(index=frame_indexes[i], duration=frame_durations[i],
                               image_index=image_indexes[i])
                for i in range(n_frames)])
        self.animations = [Animation(name=animation_names[i], frames=animation_frame_sets[i])
                           for i in range(n_animations)]

        if rdr.read_uint16() != 0x1234:
            return  # We hit end of stream

        variable_labels = rdr.read_string_array(16, 16)
        variable_data = [[] for _ in range(16)]
        for _ in range(8):
            for var_i in range(16):
                variable_data[var_i].append(rdr.read_int16())

        self.variables = {variable_labels[i]: variable_data[i] for i in range(16)}

        for anim in self.animations:
            anim.child_image_x = rdr.read_int16()
        for anim in self.animations:
            anim.child_image_y = rdr.read_int16()
        for anim in self.animations:
            anim.child_spr_index = rdr.read_uint8()

        self.child_image = rdr.read_string(128)