def __load_textures__(self, reader: FileStream): while True: if reader.finished_reading(): break offset = reader.tell() im_data = io.BytesIO(reader.read_remaining_bytes()) try: # Load image, flip it, and store it im: Image.Image = Image.open(im_data) im = im.transpose(Image.FLIP_TOP_BOTTOM) self.textures.append(im) # For some reason the TGA header flag is not being set correctly for some files so let's save it from the raw TGA header bytes self.flags.append(im_data.getbuffer()[17]) # Figure out where exactly the next image begins if im.mode == "RGBA": bytes_per_pixel = RGBA_BYTES_PER_PIXEL im_header_size = RGBA_HEADER_SIZE elif im.mode == "P": bytes_per_pixel = P_BYTES_PER_PIXEL im_header_size = P_HEADER_SIZE size = (im.width * im.height * bytes_per_pixel) + im_header_size reader.seek(offset + size) # print(f"[Reading] IDX: {len(self.flags)-1}, Offset: {offset}, Size: {size}, Mode: {im.mode}") except IOError: print("Couldn't read image") break # print("READ ", [im.mode for idx, im in enumerate(self.textures)]) if not reader.finished_reading(): self.unparsed_bytes = reader.read_remaining_bytes() print( "Could not parse all the bytes of the WPG. Unparsed byte count: ", len(self.unparsed_bytes))
def save(self, spath: Path = None): # print("SAVE ", [im.mode for idx, im in enumerate(self.textures)]) if spath is None: spath = self.path with open(spath, 'wb') as file: writer = FileStream(file) writer.write_byte_array(self.header) for idx, im_texture in enumerate(self.textures): offset = writer.tell() orig_im = im_texture.transpose(Image.FLIP_TOP_BOTTOM) with io.BytesIO() as io_bytes: orig_im.save(io_bytes, format="TGA") # For some reason the TGA header flag is not being set correctly, so load our local copy of it io_bytes.getbuffer()[17] = self.flags[idx] im_bytes = io_bytes.getvalue()[:-26] writer.write(im_bytes) # print(f"[Writing] IDX: {idx}, Offset: {offset}, Size: {len(im_bytes)}, Mode: {orig_im.mode}") writer.write(self.unparsed_bytes) print("Saved to", spath)