decode.py (2247B)
1 import numpy as np 2 import os 3 from PIL import Image 4 5 class Header: 6 def __init__(self, name, chunk, bytes_enc): 7 self.name = name 8 self.chunk = chunk 9 self.bytes_enc = bytes_enc 10 def __str__(self): 11 return f"Name: {self.name} Chunk Number: {self.chunk} Bytes Encoded: {self.bytes_enc}" 12 def __lt__(self, other): 13 if self.name != other.name: 14 return self.name < other.name 15 else: 16 return self.chunk < other.chunk 17 18 def bits_to_byte(bits): 19 return sum(bit << (7 - i) for i, bit in enumerate(bits)) 20 21 def get_header(image_path): 22 img = Image.open(image_path).convert('L') 23 pixels = list(img.getdata()) 24 25 bits = [1 if px > 127 else 0 for px in pixels[:864]] 26 header_bytes = bytearray() 27 for i in range(0, 864, 8): 28 header_bytes.append(bits_to_byte(bits[i:i+8])) 29 30 file_name_bytes = header_bytes[0:100] 31 chunk_number_bytes = header_bytes[100:104] 32 bytes_encoded_bytes = header_bytes[104:108] 33 34 file_name = file_name_bytes.rstrip(b'\x00').decode('utf-8', errors='replace').replace('\x00', '') 35 chunk_number = int(np.frombuffer(chunk_number_bytes, dtype=np.int32)[0]) 36 bytes_encoded = int(np.frombuffer(bytes_encoded_bytes, dtype=np.int32)[0]) 37 38 return Header(file_name, chunk_number, bytes_encoded) 39 40 def extract_data_from_image(image_path, bytes_to_read): 41 img = Image.open(image_path).convert('L') 42 pixels = list(img.getdata()) 43 44 data_pixels = pixels[864:] 45 46 bits = [1 if px > 127 else 0 for px in data_pixels] 47 48 data_bytes = bytearray() 49 total_bits_needed = bytes_to_read * 8 50 51 for i in range(0, total_bits_needed, 8): 52 byte_bits = bits[i:i+8] 53 if len(byte_bits) < 8: 54 byte_bits += [0] * (8 - len(byte_bits)) 55 data_bytes.append(bits_to_byte(byte_bits)) 56 57 return data_bytes 58 59 files = os.listdir() 60 headers = [] 61 62 for file in files: 63 if file.endswith(".png"): 64 header = get_header(file) 65 headers.append((header, file)) 66 67 headers.sort() 68 69 for header, file in headers: 70 print(f"Decoding: {header}") 71 72 data = extract_data_from_image(file, header.bytes_enc) 73 74 mode = 'wb' if header.chunk == 1 else 'ab' 75 with open(header.name, mode) as f: 76 f.write(data)