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
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
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
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
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
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
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
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.')