TuringsSolutions commited on
Commit
a9aa180
·
verified ·
1 Parent(s): 93b1058

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +132 -0
app.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os, struct, math, tempfile
3
+ import numpy as np
4
+ from PIL import Image
5
+
6
+ # --- FLC v1.3 Logic Engine ---
7
+ PHI = (1.0 + 5.0**0.5) / 2.0
8
+
9
+ def fibonacci_sequence(n):
10
+ fibs = [1, 2]
11
+ while len(fibs) < n: fibs.append(fibs[-1] + fibs[-2])
12
+ return np.array(fibs[:n], dtype=np.int64)
13
+
14
+ def fibonacci_frequency_boundaries(n_coeffs, n_bands):
15
+ if n_bands < 2: return [0, n_coeffs]
16
+ fibs = fibonacci_sequence(n_bands).astype(np.float64)
17
+ w = fibs / (fibs.sum() + 1e-12)
18
+ cum = np.cumsum(w)
19
+ b = [0]
20
+ for i in range(n_bands - 1): b.append(int(round(n_coeffs * cum[i])))
21
+ b.append(n_coeffs)
22
+ for i in range(1, len(b)):
23
+ if b[i] <= b[i-1]: b[i] = b[i-1] + 1
24
+ return b
25
+
26
+ def dct_ortho_1d(x):
27
+ N = x.shape[0]
28
+ v = np.concatenate([x, x[::-1]])
29
+ V = np.fft.fft(v)
30
+ k = np.arange(N)
31
+ X = np.real(V[:N] * np.exp(-1j * np.pi * k / (2 * N)))
32
+ X *= 2.0
33
+ X[0] *= (1.0 / math.sqrt(4 * N))
34
+ X[1:] *= (1.0 / math.sqrt(2 * N))
35
+ return X
36
+
37
+ def idct_ortho_1d(X):
38
+ N = X.shape[0]
39
+ x0, xr = X[0] * math.sqrt(4 * N), X[1:] * math.sqrt(2 * N)
40
+ c = np.empty(N, dtype=np.complex128)
41
+ c[0], c[1:] = x0 / 2.0, xr / 2.0
42
+ k = np.arange(N)
43
+ c = c * np.exp(1j * np.pi * k / (2 * N))
44
+ V = np.zeros(2 * N, dtype=np.complex128)
45
+ V[:N] = c
46
+ V[N+1:] = np.conj(c[1:][::-1])
47
+ return np.fft.ifft(V).real[:N]
48
+
49
+ def hologram_spectrum_image(zints):
50
+ z = zints[:262144]; v = np.tanh(z / 32.0)
51
+ theta = (2 * math.pi / (PHI**2)) * np.arange(v.size) + 2.0 * math.pi * (v * 0.25)
52
+ r = 1.0 + 0.35 * np.abs(v)
53
+ syms = r * np.cos(theta) + 1j * r * np.sin(theta)
54
+ N = int(2**math.ceil(math.log2(math.sqrt(syms.size or 1))))
55
+ U = np.pad(syms, (0, N*N - syms.size)).reshape(N, N)
56
+ mag = np.log1p(np.abs(np.fft.fftshift(np.fft.fft2(U))))
57
+ mag = (mag - mag.min()) / (mag.max() - mag.min() + 1e-12)
58
+ return (mag * 255).astype(np.uint8)
59
+
60
+ def bytes_to_fib_spiral_image(data):
61
+ arr = np.frombuffer(data, dtype=np.uint8)[:262144]
62
+ fibs = [1, 1]
63
+ while sum(s*s for s in fibs) < arr.size: fibs.append(fibs[-1] + fibs[-2])
64
+ tiles, minx, miny, maxx, maxy, curr_x, curr_y = [], 0, 0, 0, 0, 0, 0
65
+ for i, s in enumerate(fibs):
66
+ d = (i-1)%4
67
+ if i>0:
68
+ if d==0: curr_x = maxx; curr_y = miny
69
+ elif d==1: curr_x = maxx-s; curr_y = maxy
70
+ elif d==2: curr_x = minx-s; curr_y = maxy-s
71
+ else: curr_x = minx; curr_y = miny-s
72
+ tiles.append((curr_x, curr_y, s))
73
+ minx, miny, maxx, maxy = min(minx, curr_x), min(miny, curr_y), max(maxx, curr_x+s), max(maxy, curr_y+s)
74
+ img, idx = np.zeros((maxy-miny, maxx-minx), dtype=np.uint8), 0
75
+ for x, y, s in tiles:
76
+ take = min(s*s, arr.size - idx)
77
+ if take <= 0: break
78
+ block = np.pad(arr[idx:idx+take], (0, s*s-take)).reshape(s, s)
79
+ img[img.shape[0]-(y-miny+s):img.shape[0]-(y-miny), x-minx:x-minx+s] = block
80
+ idx += take
81
+ return img
82
+
83
+ def process_flc(input_file, fidelity):
84
+ with open(input_file, "rb") as f: raw_data = f.read()
85
+
86
+ q_map = {"High Compression": 6, "Balanced": 12, "Near-Lossless": 24}
87
+ n_bands = q_map[fidelity]
88
+ step = 0.08 if fidelity == "High Compression" else (0.005 if fidelity == "Balanced" else 0.0001)
89
+
90
+ x = (np.frombuffer(raw_data, dtype=np.uint8).astype(float) - 127.5) / 127.5
91
+ block_len = 1024
92
+ X = np.pad(x, (0, (-x.size) % block_len)).reshape(-1, block_len)
93
+
94
+ C = np.array([dct_ortho_1d(b) for b in X])
95
+ bnds = fibonacci_frequency_boundaries(block_len, n_bands)
96
+ Q = np.zeros_like(C, dtype=np.int32)
97
+ for bi in range(len(bnds)-1):
98
+ Q[:, bnds[bi]:bnds[bi+1]] = np.round(C[:, bnds[bi]:bnds[bi+1]] / (step * (PHI**bi)))
99
+
100
+ frames = []
101
+ for t in range(1, n_bands + 1):
102
+ Q_p = np.zeros_like(Q)
103
+ for bi in range(t): Q_p[:, bnds[bi]:bnds[bi+1]] = Q[:, bnds[bi]:bnds[bi+1]]
104
+ C_p = np.zeros_like(Q_p, dtype=float)
105
+ for bi in range(len(bnds)-1): C_p[:, bnds[bi]:bnds[bi+1]] = Q_p[:, bnds[bi]:bnds[bi+1]] * (step * (PHI**bi))
106
+
107
+ recon = np.clip((np.array([idct_ortho_1d(B) for B in C_p]).flatten()[:len(raw_data)] * 127.5) + 127.5, 0, 255).astype(np.uint8)
108
+
109
+ h_img = Image.fromarray(hologram_spectrum_image(Q_p.flatten())).resize((256, 256))
110
+ s_img = Image.fromarray(bytes_to_fib_spiral_image(recon.tobytes())).resize((256, 256))
111
+ frame = Image.new("RGB", (512, 280), (15, 15, 25))
112
+ frame.paste(h_img, (0, 12)); frame.paste(s_img, (256, 12))
113
+ frames.append(frame)
114
+
115
+ gif_path = tempfile.mktemp(suffix=".gif")
116
+ frames[0].save(gif_path, save_all=True, append_images=frames[1:], duration=150, loop=0)
117
+ return gif_path
118
+
119
+ # --- Gradio UI ---
120
+ demo = gr.Interface(
121
+ fn=process_flc,
122
+ inputs=[
123
+ gr.File(label="Upload File"),
124
+ gr.Radio(["High Compression", "Balanced", "Near-Lossless"], value="Balanced", label="Fidelity Tier")
125
+ ],
126
+ outputs=gr.Image(label="Holographic Unzip Sequence"),
127
+ title="🌀 Fibonacci Lattice Compression (FLC)",
128
+ description="Bio-inspired spectral compression using the Golden Ratio."
129
+ )
130
+
131
+ if __name__ == "__main__":
132
+ demo.launch()