Exemple #1
0
    def _open(self):
        io = self._io
        io.seek(0)

        magic = IOHelper.read_ascii_string(io, 16)
        if magic != FILE_MAGIC:
            raise Exception('Not NPK File.')

        [count] = IOHelper.read_struct(io, 'i')

        files = []
        for i in range(count):
            offset, size = IOHelper.read_struct(io, '<2i')
            name_data = NPK._decrypt_name(io.read(256))
            try:
                name = name_data.decode('euc_kr')
                name = name[:name.find('\x00')]
            except:
                name = name_data[:name_data.find(b'\x00')].decode(
                    'euc_kr', errors='ignore')
                print('Bad Filename: ', name_data)

            file = {
                'name': name,
                'offset': offset,
                'size': size,
                'data': None,
            }
            files.append(file)

        self._files = files
Exemple #2
0
    def _indexes_to_raw(data, color_board):
        with BytesIO(data) as io_indexes:
            with BytesIO() as io_raw:
                temp = IOHelper.read_struct(io_indexes, '<B', False)
                while temp is not None:
                    [index] = temp
                    IOHelper.write_struct(io_raw, '<4B', *color_board[index])
                    temp = IOHelper.read_struct(io_indexes, '<B', False)
                data_raw = IOHelper.read_range(io_raw)

        return data_raw
Exemple #3
0
    def _open_color_board(self):
        io = self._io

        [count] = IOHelper.read_struct(io, 'i')

        colors = []
        for i in range(count):
            color = IOHelper.read_struct(io, '<4B')
            colors.append(color)

        return colors
Exemple #4
0
    def _open_images(self, count):
        io = self._io
        version = self._version
        images = []

        for i in range(count):
            image = {}

            [fmt] = IOHelper.read_struct(io, '<i')
            image['format'] = fmt

            if fmt == IMAGE_FORMAT_LINK:
                [link] = IOHelper.read_struct(io, '<i')
                image['link'] = link
            else:
                extra, w, h, size, x, y, mw, mh = IOHelper.read_struct(
                    io, '<8i')

                # fix size to real size.
                if (version == FILE_VERSION_1 or version
                        == FILE_VERSION_2) and extra == IMAGE_EXTRA_NONE:
                    size = w * h * PIX_SIZE[fmt]

                image['extra'] = extra
                image['w'] = w
                image['h'] = h
                image['size'] = size
                image['x'] = x
                image['y'] = y
                image['mw'] = mw
                image['mh'] = mh
                # temp
                image['data'] = None

                if extra == IMAGE_EXTRA_MAP_ZLIB:
                    keep_1, map_index, lx, ly, rx, ry, rotate = IOHelper.read_struct(
                        io, '<7i')
                    image['keep_1'] = keep_1
                    image['map_index'] = map_index
                    image['left'] = lx
                    image['top'] = ly
                    image['right'] = rx
                    image['bottom'] = ry
                    # horizontal, vertical
                    image['rotate'] = rotate

                if self._version == FILE_VERSION_1:
                    image['offset'] = io.tell()
                    io.seek(size, SEEK_CUR)

            images.append(image)

        return images
Exemple #5
0
    def load(io: FileIO):
        instance = MPK(io)
        magic = IOHelper.read_ascii_string(io, 4)
        if magic == MPK_MAGIC:
            version, count = IOHelper.read_struct(io, '<2i')
            io.seek(52, SEEK_CUR)
            instance.set_version(version)
            for i in range(count):
                is_zip, index, offset, data_size, zip_size = IOHelper.read_struct(
                    io, '<2i3q')
                name_data = io.read(224)
                name = name_data[:name_data.find(b'\x00')].decode(
                    encoding='ascii')
                instance.insert_file({
                    'is_zip': is_zip != 0,
                    'index': index,
                    'offset': offset,
                    'data_size': data_size,
                    'zip_size': zip_size,
                    'name': name,
                    'data': None,
                })

        return instance
Exemple #6
0
    def _open_map_images(self, map_count):
        io = self._io

        map_images = []
        for i in range(map_count):
            keep, fmt, index, data_size, raw_size, w, h = IOHelper.read_struct(
                io, '<7i')
            map_image = {
                'keep': keep,
                'format': fmt,
                'index': index,
                'data_size': data_size,
                'raw_size': raw_size,
                'w': w,
                'h': h,
                'data': None,
            }
            map_images.append(map_image)

        return map_images
Exemple #7
0
    def _nximg_to_raw(data, image_format, w=None, box=None):
        data_raw = bytes()
        ps = PIX_SIZE[image_format]

        with BytesIO(data) as io_nximg:
            with BytesIO() as io_raw:
                if image_format == IMAGE_FORMAT_1555:
                    if box is not None and w is not None:
                        [left, top, right, bottom] = box
                        for y in range(top, bottom):
                            o = y * w * ps
                            for x in range(left, right):
                                io_nximg.seek(o + x * ps)
                                temp = IOHelper.read_struct(
                                    io_nximg, '<2B', False)
                                if temp is not None:
                                    [v1, v2] = temp
                                    IOHelper.write_struct(
                                        io_raw, '<4B',
                                        *NXColor.from_1555(v1, v2))
                    else:
                        temp = IOHelper.read_struct(io_nximg, '<2B', False)
                        while temp is not None:
                            [v1, v2] = temp
                            IOHelper.write_struct(io_raw, '<4B',
                                                  *NXColor.from_1555(v1, v2))

                            temp = IOHelper.read_struct(io_nximg, '<2B', False)
                elif image_format == IMAGE_FORMAT_4444:
                    if box is not None and w is not None:
                        [left, top, right, bottom] = box
                        for y in range(top, bottom):
                            o = y * w * ps
                            for x in range(left, right):
                                io_nximg.seek(o + x * ps)
                                temp = IOHelper.read_struct(
                                    io_nximg, '<2B', False)
                                if temp is not None:
                                    [v1, v2] = temp
                                    IOHelper.write_struct(
                                        io_raw, '<4B',
                                        *NXColor.from_4444(v1, v2))
                    else:
                        temp = IOHelper.read_struct(io_nximg, '<2B', False)
                        while temp is not None:
                            [v1, v2] = temp
                            IOHelper.write_struct(io_raw, '<4B',
                                                  *NXColor.from_4444(v1, v2))

                            temp = IOHelper.read_struct(io_nximg, '<2B', False)
                elif image_format == IMAGE_FORMAT_8888:
                    if box is not None and w is not None:
                        [left, top, right, bottom] = box
                        for y in range(top, bottom):
                            o = y * w * ps
                            for x in range(left, right):
                                io_nximg.seek(o + x * ps)
                                temp = IOHelper.read_struct(
                                    io_nximg, '<4B', False)
                                if temp is not None:
                                    [b, g, r, a] = temp
                                    IOHelper.write_struct(
                                        io_raw, '<4B', r, g, b, a)
                    else:
                        temp = IOHelper.read_struct(io_nximg, '<4B', False)
                        while temp is not None:
                            [b, g, r, a] = temp
                            IOHelper.write_struct(io_raw, '<4B', r, g, b, a)

                            temp = IOHelper.read_struct(io_nximg, '<4B', False)
                else:
                    raise Exception('Unsupport Image Format.', image_format)

                data_raw = IOHelper.read_range(io_raw)

        return data_raw
Exemple #8
0
    def _open(self):
        io = self._io
        io.seek(0)

        magic = IOHelper.read_ascii_string(io, 18)
        if magic == FILE_MAGIC or magic == FILE_MAGIC_OLD:
            if magic == FILE_MAGIC:
                # images_size without version,count,extra(color_board,map_images)...
                [images_size] = IOHelper.read_struct(io, 'i')
            else:
                # unknown.
                [unknown] = IOHelper.read_struct(io, 'h')
                images_size = 0

            # keep: 0
            [keep, version, img_count] = IOHelper.read_struct(io, '<3i')
            self._version = version

            if version == FILE_VERSION_4:
                # single color board.
                self._color_board = self._open_color_board()
            elif version == FILE_VERSION_5:
                # map image.
                map_count, file_size = IOHelper.read_struct(io, '<2i')
                self._color_board = self._open_color_board()
                self._map_images = self._open_map_images(map_count)
            elif version == FILE_VERSION_6:
                # multiple color board.
                color_boards = []

                [color_board_count] = IOHelper.read_struct(io, 'i')
                for i in range(color_board_count):
                    color_board = self._open_color_board()
                    color_boards.append(color_board)

                self._color_boards = color_boards

            images = self._open_images(img_count)
            self._images = images

            # count image offset.
            if version != FILE_VERSION_1:
                # behind header.
                if images_size != 0:
                    offset = images_size + 32
                else:
                    offset = io.tell()

                if version == FILE_VERSION_5:
                    map_images = self._map_images
                    for i in range(len(map_images)):
                        map_image = map_images[i]
                        map_image['offset'] = offset
                        offset += map_image['data_size']
                for i in range(len(images)):
                    image = images[i]
                    if image['format'] != IMAGE_FORMAT_LINK and image[
                            'extra'] != IMAGE_EXTRA_MAP_ZLIB:
                        image['offset'] = offset
                        offset += image['size']
        else:
            raise Exception('Not IMG File.')