# Design Specification: LT Code (Luby Transform) Fountain Streaming Engine

* **Date**: 2026-08-07
* **Status**: Approved
* **Target Repository**: `qrcode_transceiver`

---

## 1. Executive Summary

This design replaces the fixed sequential chunking mechanism in `qrcode_transceiver` with a **rateless Fountain Code streaming engine** based on **Luby Transform (LT) Codes** with **Belief Propagation decoding** and **raw binary QR code 8-bit byte mode**.

This architectural upgrade eliminates transmission stalls caused by dropped frames, enables out-of-order frame capture with zero frame repetition dependency, and increases overall throughput by ~33%+ by replacing JSON+Base64 encoding with a compact binary packet schema.

---

## 2. Architecture & Data Flow

```mermaid
flowchart TD
    subgraph Transmitter ["Transmitter (transmitter.html)"]
        A[Input File / Text] --> B[Raw Byte Array Slicing into K Source Blocks]
        B --> C["LT Encoder Loop (Seed s = 1..∞)"]
        C --> D["Sample Degree d ~ Robust Soliton μ(d) via Mulberry32(s)"]
        D --> E["Select d Blocks via PRNG(s) & XOR Byte Arrays"]
        E --> F[Construct Binary Packet Header & Payload Uint8Array]
        F --> G[Convert to Binary String via Latin1 Mapping]
        G --> H[Render Raw Byte Mode QR Code via easy.qrcode.min.js]
    end

    subgraph Receiver ["Receiver (receiver.html)"]
        I[Camera Frame Scan] --> J[Extract Raw Uint8Array Data]
        J --> K[Parse Binary Packet: Seed s, K blocks, XOR payload]
        K --> L["Recreate Block List via Mulberry32(s)"]
        L --> M[Insert Drop into Belief Propagation Graph]
        M --> N{Degree 1 Drop or Reduced to Degree 1?}
        N -- Yes --> O[Solve Source Block & Cascade XOR-Reduce Neighbors]
        N -- No --> P[Store Reduced Drop in Graph]
        O --> Q{All K Source Blocks Solved?}
        Q -- Yes --> R[Reconstruct File Bytes & Trigger Download/Display]
        Q -- No --> I
    end
```

---

## 3. Protocol & Binary Frame Specification

Each QR code frame contains a raw binary byte array (8-bit Byte Mode) avoiding Base64 and JSON formatting overhead.

### Compact Binary Packet Layout

```
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Frame Seed (4 bytes)                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       Total Blocks K (2 bytes)       | Block Length L (2 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Flags (1 byte)|  Name Len N   | Filename (N bytes, optional)...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                  Raw XOR Payload Data (L bytes)               |
+---------------------------------------------------------------+
```

#### Field Specifications:
1. **Frame Seed `s`** (4 bytes, Uint32 Big Endian): Unique seed initializing the Mulberry32 PRNG for generating degree $d$ and block indices.
2. **Total Blocks `K`** (2 bytes, Uint16 Big Endian): Total number of source blocks in the dataset.
3. **Block Length `L`** (2 bytes, Uint16 Big Endian): Length of each individual source block in bytes.
4. **Flags** (1 byte):
   - `Bit 0`: File flag (`1` = Binary File download, `0` = UTF-8 Text display).
   - `Bit 1`: Filename present flag (`1` = Filename bytes follow header, `0` = No filename).
5. **Name Len `N`** (1 byte, Uint8): Length of original filename in bytes (present only if Bit 1 of Flags is `1`).
6. **Filename** (`N` bytes): Original UTF-8 encoded filename string (present only if Bit 1 of Flags is `1`).
7. **Raw XOR Payload Data** (`L` bytes): The byte-wise XOR combination of the $d$ selected source blocks.

---

## 4. LT Algorithm Engine Specification

### 4.1 Pseudo-Random Number Generator (Mulberry32)
A fast 32-bit deterministic PRNG used on both transmitter and receiver:
```javascript
function mulberry32(seed) {
    return function() {
        let t = seed += 0x6D2B79F5;
        t = Math.imul(t ^ (t >>> 15), t | 1);
        t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
        return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
    };
}
```

### 4.2 Robust Soliton Distribution ($\mu(d)$)
For $K$ source blocks, parameters $c = 0.1$ and $\delta = 0.5$:
1. **Ideal Soliton $\rho(d)$**:
   $$\rho(1) = \frac{1}{K}, \quad \rho(d) = \frac{1}{d(d-1)} \text{ for } d = 2 \dots K$$
2. **Spike Vector $\tau(d)$**:
   $$R = c \cdot \ln(K/\delta) \sqrt{K}$$
   $$\tau(d) = \begin{cases} \frac{R}{d \cdot K} & \text{for } 1 \le d < \lfloor K/R \rfloor \\ \frac{R \ln(R/\delta)}{K} & \text{for } d = \lfloor K/R \rfloor \\ 0 & \text{for } d > \lfloor K/R \rfloor \end{cases}$$
3. **Normalized Distribution $\mu(d)$**:
   $$\mu(d) = \frac{\rho(d) + \tau(d)}{\sum_{k=1}^K (\rho(k) + \tau(k))}$$

### 4.3 Belief Propagation (BP) Graph Decoder
* Maintains an array `blocks[0..K-1]` initialized to `null`.
* Maintains a bipartite graph of unsolved drop nodes containing:
  - `payload`: Uint8Array of XOR data bytes.
  - `neighbors`: Set of unresolved block indices.
* **Algorithm**:
  1. On receiving a packet frame with seed `s`, recreate degree $d$ and block set $B = \{b_1, \dots, b_d\}$ using `mulberry32(s)`.
  2. For every block $b \in B$ already resolved (`blocks[b] !== null`), XOR `blocks[b]` into `payload` and remove $b$ from $B$.
  3. If $|B| == 1$:
     - Resolve new block $b^* = B[0]$: `blocks[b*] = payload`.
     - **Cascade Resolution**: Iterate through all stored graph nodes containing $b^*$:
       - XOR `blocks[b*]` into the node's `payload`.
       - Remove $b^*$ from the node's `neighbors`.
       - If node's `neighbors.size == 1`, recursively solve that block.
  4. If $|B| > 1$: Add node $(B, \text{payload})$ to graph.

---

## 5. Binary-Safe QR Code Generation & Compatibility

### 5.1 Library Binary Configuration (`easy.qrcode.min.js`)
Inspection of [`easy.qrcode.min.js`](file:///Users/aidan/dev/qrcode_transceiver/easy.qrcode.min.js) confirms native support for raw 8-bit byte mode via the `binary: true` option:

```javascript
function uint8ArrayToBinaryString(uint8Array) {
    let str = '';
    for (let i = 0; i < uint8Array.length; i++) {
        str += String.fromCharCode(uint8Array[i]);
    }
    return str;
}

const binaryString = uint8ArrayToBinaryString(packetUint8Array);
const options = {
    text: binaryString,
    width: qrSize,
    height: qrSize,
    correctLevel: QRCode.CorrectLevel.L,
    binary: true // Instructs easy.qrcode.min.js to bypass UTF-8 re-encoding and encode raw bytes 0..255 directly
};
```

### 5.2 Receiver Binary Scanning (`receiver.html`)
`QrScanner` extracts the binary data:
```javascript
function resultToUint8Array(result) {
    if (result.bytes) return new Uint8Array(result.bytes);
    const str = result.data;
    const bytes = new Uint8Array(str.length);
    for (let i = 0; i < str.length; i++) {
        bytes[i] = str.charCodeAt(i) & 0xFF;
    }
    return bytes;
}
```

### 5.3 Browser Compatibility
* **Transmitter (`easy.qrcode.min.js`)**: Uses HTML5 Canvas API (`<canvas>`), supported across 100% of modern browsers (Chrome, Safari, Firefox, Edge, iOS Safari, Android Chrome).
* **Receiver (`QrScanner`)**: Uses WebRTC MediaDevices (`navigator.mediaDevices.getUserMedia`) over HTTPS, supported across all modern mobile and desktop browsers.

---

## 6. UI & User Experience

### 6.1 Transmitter UI (`transmitter.html`)
* Rateless frame animation counter displaying: `Frames Generated: 1,420 | Current Seed: 1420 | Total Blocks K: 32`.
* Real-time FPS control (1–15 FPS).
* Dynamic QR Code size & Version selection.
* Gemini AI text summarization retained.

### 6.2 Receiver UI (`receiver.html`)
* **Soliton Block Progress Bar**: Displays percentage of solved blocks ($\frac{\text{solvedCount}}{K} \times 100\%$).
* **Interactive $K$-Cell Grid**:
  - `Gray`: Unsolved block.
  - `Indigo`: Solved block.
* **Transmission Stats**:
  - `Scanned Frames`: Total QR codes scanned.
  - `Solved Blocks`: $M / K$.
  - `Overhead`: $\frac{\text{Scanned Frames}}{K}$ (typical completion ratio $\sim 1.05 - 1.15$).

---

## 7. Verification & Test Plan

1. **Unit Test LT Engine**: Test Mulberry32 PRNG determinism, Soliton distribution sampling, and Belief Propagation decoding with simulated random frame drops.
2. **End-to-End File Transfer Test**:
   - Transmit plain text payloads (e.g. 5 KB text string).
   - Transmit binary files (e.g. 50 KB image file).
3. **Frame Drop Resilience Test**: Simulate 50% random frame loss on receiver camera to verify clean decoding completion without stalls.
