Exemplo n.º 1
0
    def load_file(self, index):
        file = self._files[index]

        if file['data'] is None:
            if file['size'] != 0:
                file['data'] = IOHelper.read_range(self._io, file['offset'],
                                                   file['size'])
            else:
                print('size is zero, read all data.')
                file['data'] = IOHelper.read_range(self._io, file['offset'],
                                                   -1)

        return file['data']
Exemplo n.º 2
0
    def _png_to_nximg(data, image_format):
        data_nximg = bytes()

        with BytesIO(data) as io_png:
            with BytesIO() as io_nximg:
                png = PngImageFile(io_png)
                w, h = png.width, png.height

                if image_format == IMAGE_FORMAT_1555:
                    for y in range(h):
                        for x in range(w):
                            [r, g, b, a] = png.getpixel((x, y))
                            IOHelper.write_struct(io_nximg, "<2B",
                                                  *NXColor.to_1555(r, g, b, a))
                elif image_format == IMAGE_FORMAT_4444:
                    for y in range(h):
                        for x in range(w):
                            [r, g, b, a] = png.getpixel((x, y))
                            IOHelper.write_struct(io_nximg, "<2B",
                                                  *NXColor.to_4444(r, g, b, a))
                elif image_format == IMAGE_FORMAT_8888:
                    for y in range(h):
                        for x in range(w):
                            [r, g, b, a] = png.getpixel((x, y))
                            IOHelper.write_struct(io_nximg, "<4B", b, g, r, a)
                else:
                    raise Exception('Unsupport image format: %s' %
                                    image_format)

                data_nximg = IOHelper.read_range(io_nximg)

        return data_nximg, w, h
Exemplo n.º 3
0
    def load_file(self, index):
        file = self._files[index]

        if file['data'] is None:
            file['data'] = IOHelper.read_range(self._io, file['offset'],
                                               file['size'])

        return file['data']
Exemplo n.º 4
0
def raw_to_png(data, w, h, rotate=0):
    raw_image = Image.frombytes('RGBA', (w, h), data)

    if rotate == 1:
        raw_image = raw_image.transpose(Image.ROTATE_90)

    with BytesIO() as io_png:
        raw_image.save(io_png, 'png')
        data_png = IOHelper.read_range(io_png)

    return data_png
Exemplo n.º 5
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
Exemplo n.º 6
0
    def load_image_map(self, index):
        io = self._io
        map_image = self._map_images[index]

        if map_image['data'] is not None:
            return map_image['data']

        data = IOHelper.read_range(io, map_image['offset'],
                                   map_image['data_size'])
        data = zlib.decompress(data)
        map_image['data'] = data

        return data
Exemplo n.º 7
0
    def save(self, io=None):
        # load all file data.
        self.load_all()
        files = self._files

        if io is None:
            io = self._io

        # clean file.
        io.seek(0)
        io.truncate()

        head_data = b''

        # build head in memory.
        with BytesIO() as io_head:
            IOHelper.write_ascii_string(io_head, FILE_MAGIC)
            count = len(files)
            IOHelper.write_struct(io_head, 'i', count)

            # count file offset.
            # magic(16) + count(4) + info(264 * n) + hash(32)
            offset = 52 + count * 264

            for file in files:
                file['offset'] = offset
                file['size'] = len(file['data'])
                IOHelper.write_struct(io_head, '<2i', file['offset'],
                                      file['size'])
                if isinstance(file['name'], str):
                    name_data = file['name'].encode(encoding='euc_kr')
                elif isinstance(file['name'], bytes):
                    name_data = file['name']
                else:
                    raise Exception('Filename type Error: %s(%s)' %
                                    (file['name'], type(file['name'])))
                name = NPK._decrypt_name(name_data)
                io_head.write(name)

                offset += file['size']

            head_data = IOHelper.read_range(io_head)

        io.write(head_data)
        # write hash.
        io.write(
            hashlib.sha256(head_data[:len(head_data) // 17 * 17]).digest())

        for file in files:
            io.seek(file['offset'])
            io.write(file['data'])
Exemplo n.º 8
0
    def data(self, index):
        if index < len(self._files):
            file = self._files[index]  # type: dict
            if file['data'] is None:
                if not file['is_zip']:
                    data = IOHelper.read_range(self._io, file['offset'],
                                               file['data_size'])
                    file['data'] = data
                else:
                    raise Exception('Unsupport File.')
            else:
                data = file['data']

            return data
Exemplo n.º 9
0
def dds_to_png(data, box=None, rotate=0):
    with BytesIO(data) as io_dds:
        map_image = DdsImageFile(io_dds)
        if box is not None:
            map_image = map_image.crop(box)

        if rotate == 1:
            map_image = map_image.transpose(Image.ROTATE_90)

        with BytesIO() as io_png:
            map_image.save(io_png, 'png')
            data_png = IOHelper.read_range(io_png)

    return data_png
Exemplo n.º 10
0
    def load_image(self, index):
        io = self._io
        image = self._images[index]

        if image['format'] == IMAGE_FORMAT_LINK:
            return None

        if image['data'] is not None:
            return image['data']

        data = IOHelper.read_range(io, image['offset'], image['size'])

        if image['extra'] == IMAGE_EXTRA_ZLIB:
            data = zlib.decompress(data)
        elif image['extra'] != IMAGE_EXTRA_NONE:
            raise Exception('Unknown Extra Type.', image['extra'])

        image['data'] = data

        return data
Exemplo n.º 11
0
    def save(self, io=None):
        # load all file data.
        self.load_all()
        files = self._files

        if io is None:
            io = self._io

        # clean file.
        io.seek(0)
        io.truncate()

        # build head in memory.
        with BytesIO() as io_head:
            IOHelper.write_ascii_string(io_head, FILE_MAGIC)
            count = len(files)
            IOHelper.write_struct(io_head, 'i', count)

            # count file offset.
            # magic(16) + count(4) + info(264 * n) + hash(32)
            offset = 52 + count * 264

            for file in files:
                IOHelper.write_struct(io_head, '<2i', file['offset'],
                                      file['size'])
                name = NPK._decrypt_name(file['name'].encode(encoding='ascii'))
                io_head.write(name)

                offset += file['size']

            head_data = IOHelper.read_range(io_head)

        io.write(head_data)
        # write hash.
        io.write(
            hashlib.sha256(head_data[:len(head_data) // 17 * 17]).digest())

        for file in files:
            io.seek(file['offset'])
            io.write(file['data'])
Exemplo n.º 12
0
 def print_exception(type, value, tb):
     with StringIO() as io:
         traceback.print_exception(type, value, tb, file=io)
         err_str = IOHelper.read_range(io)
     print(err_str)
     QMessageBox.warning(None, '错误:', err_str)
Exemplo n.º 13
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
Exemplo n.º 14
0
    def save(self, io=None):
        self.load_all()
        images = self._images
        color_board = self._color_board
        color_boards = self._color_boards
        map_images = self._map_images
        version = self._version

        images_data = []

        # compress data, get size, add to data_list.
        if version == FILE_VERSION_5:
            for map_image in sorted(map_images):
                data = map_image['data']
                map_image['raw_size'] = len(data)
                data = zlib.compress(data)
                map_image['data_size'] = len(data)

                images_data.append(data)
        else:
            for image in images:
                if image['format'] != IMAGE_FORMAT_LINK:
                    data = image['data']
                    if image['extra'] == IMAGE_EXTRA_ZLIB or image[
                            'extra'] == IMAGE_EXTRA_MAP_ZLIB:
                        data = zlib.compress(data)
                    image['size'] = len(data)

                    images_data.append(data)

        images_size = self._save_count_images_size()
        file_size = self._save_count_file_size(images_size, images_data)

        if io is None:
            io = self._io

        io.seek(0)
        io.truncate()

        with BytesIO() as io_head:
            if version == FILE_VERSION_1:
                IOHelper.write_ascii_string(io_head, FILE_MAGIC_OLD)
                # TODO: unknown, now be zero.
                IOHelper.write_struct(io_head, 'h', 0)
            else:
                # images_size
                IOHelper.write_ascii_string(io_head, FILE_MAGIC)
                IOHelper.write_struct(io_head, 'i', images_size)

            # keep, version, img_count
            IOHelper.write_struct(io_head, '<3i', 0, version, len(images))

            is_ver5 = version == FILE_VERSION_5

            if is_ver5:
                # map_count, file_size
                IOHelper.write_struct(io_head, '<2i', len(map_images),
                                      file_size)

            if version == FILE_VERSION_4 or is_ver5:
                # color_count
                IOHelper.write_struct(io_head, 'i', len(color_board))
                for color in color_board:
                    # color
                    IOHelper.write_struct(io_head, '<4B', *color)

            if is_ver5:
                for map_image in map_images:
                    IOHelper.write_struct(io_head, '<7i', map_image['keep'],
                                          map_image['format'],
                                          map_image['index'],
                                          map_image['data_size'],
                                          map_image['raw_size'],
                                          map_image['w'], map_image['h'])

            if version == FILE_VERSION_6:
                # color_board count.
                IOHelper.write_struct(io_head, 'i', len(color_boards))
                for color_board_v6 in color_boards:
                    # color_count
                    IOHelper.write_struct(io_head, 'i', len(color_board_v6))
                    for color in color_board_v6:
                        # color
                        IOHelper.write_struct(io_head, '<4B', *color)

            for image in images:
                # format
                IOHelper.write_struct(io_head, 'i', image['format'])
                if image['format'] == IMAGE_FORMAT_LINK:
                    # link
                    IOHelper.write_struct(io_head, 'i', image['link'])
                else:
                    # extra, w, h, size, x, y, mw, mh
                    IOHelper.write_struct(io_head, '<8i', image['extra'],
                                          image['w'], image['h'],
                                          image['size'], image['x'],
                                          image['y'], image['mw'], image['mh'])
                    if image['extra'] == IMAGE_EXTRA_MAP_ZLIB:
                        # keep_1, map_index, left, top, right, bottom, rotate
                        IOHelper.write_struct(io_head, '<7i', image['keep_1'],
                                              image['map_index'],
                                              image['left'], image['top'],
                                              image['right'], image['bottom'],
                                              image['rotate'])

            head_data = IOHelper.read_range(io_head)

        io.write(head_data)

        for data in images_data:
            io.write(data)