import numpy as np
from PIL import Image

def main():
    # Load matrix P from output2g.png
    # output2g is 16384 rows by 2048 columns
    img = Image.open("output2g.png").convert("L")
    P = (np.array(img) < 128).astype(np.uint8)
    
    # Blocks are 256x256. 64x8 blocks.
    # We need the first row of each block.
    # Total 512 polynomials.
    polys = []
    for by in range(64):
        for bx in range(8):
            row = P[by*256, bx*256 : (bx+1)*256]
            # Convert bits to hex
            hex_str = ""
            for i in range(0, 256, 4):
                bits = row[i:i+4]
                val = 0
                for b in bits:
                    val = (val << 1) | b # Wait, MSB first or LSB first?
                    # Conventional: bit 0 of poly is index 0. 
                    # Let's use standard hex mapping.
                # Actually, bits[0] is index 0. Let's make it easy to shift in Verilog.
                # If we use val = sum(bits[j]*2^j), then bit 0 is LSB.
                val = 0
                for j in range(4):
                    if i+j < len(row):
                        val |= (row[i+j] << j)
                hex_str += f"{val:x}"
            # Reverse order of nibbles to make bit 0 at the low end?
            # Or just keep it as is and use [31:0] in Verilog correctly.
            # Verilog [255:0] will have bit 0 as LSB.
            # So val above (bit i+0 as bit 0) is correct for LSB-first.
            # But hex strings in readmemh are usually [N-1:0].
            # So the last byte in the string is bits [7:0].
            
            # Correction: readmemh expects the first character to be the MSB.
            # Let's re-calculate:
            full_hex = ""
            for byte_idx in range(31, -1, -1): # 32 bytes, from highest to lowest
                byte_val = 0
                for bit_in_byte in range(8):
                    bit_idx = byte_idx * 8 + bit_in_byte
                    byte_val |= (row[bit_idx] << bit_in_byte)
                full_hex += f"{byte_val:02x}"
            polys.append(full_hex)
            
    with open("polys.mem", "w") as f:
        for p in polys:
            f.write(p + "\n")
            
    print(f"Created polys.mem with {len(polys)} polynomials.")

    # Process codeword.bin
    with open("codeword.bin", "rb") as f:
        data = f.read()
    # Write as 32-bit words for easy reading? 
    # Or just one big word. Let's do 18432 bits as one hex per line (too large).
    # Let's do 8-bit hex per line.
    with open("codeword.mem", "w") as f:
        for b in data:
            f.write(f"{b:02x}\n")
    print(f"Created codeword.mem with {len(data)} bytes.")

if __name__ == "__main__":
    main()
