import numpy as np
from PIL import Image
from scipy.fftpack import dct

img = Image.open('/Users/user/puz/README.jpg')
Y = np.asarray(img.convert('YCbCr'))[:, :, 0].astype(float) - 128.0
h, w = Y.shape
bh, bw = h // 8, w // 8

zz = []
for s in range(15):
    for i in range(8):
        j = s - i
        if 0 <= j < 8:
            zz.append((i, j) if s % 2 else (j, i))
idxs = zz[1:9]

bits = []
for by in range(bh):
    for bx in range(bw):
        b = Y[by*8:by*8+8, bx*8:bx*8+8]
        c = dct(dct(b.T, norm='ortho').T, norm='ortho')
        bits.append([1 if c[i, j] > 0 else 0 for (i, j) in idxs])
bits = np.array(bits)                      # (nblocks, 8)
n = len(bits) // 9
print('blocks', len(bits), '-> chars', n)

grp = bits[:n*9].reshape(n, 9, 8)
maj = (grp.sum(axis=1) >= 5).astype(int)   # majority vote per bit
data = bytes(int(''.join(map(str, row)), 2) for row in maj)

open('/private/tmp/claude-501/-Users-user-puz/23b7dffc-7a02-481f-ab9c-8220e076a9d4/scratchpad/msg.bin', 'wb').write(data)
print('printable ratio:', sum(1 for c in data if 32 <= c < 127 or c in (9,10,13)) / len(data))
print('=' * 70)
print(data.decode('utf-8', 'replace'))
