Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c21332d
feat: Add sender and receiver HTML pages for QRL web application
minimike86 May 8, 2026
1cb011b
feat: Update README to include web version details and local serving …
minimike86 May 8, 2026
4f5496f
feat: Add replay functionality for missing chunks in sender and enhan…
minimike86 May 8, 2026
be6299a
feat: Adjust chunk indexing in receiver and sender for 1-based numbering
minimike86 May 8, 2026
5072260
Add minified QR code library to vendor directory
minimike86 May 8, 2026
3d76a7c
Refactor sender and receiver logic; enhance chunk replay functionality
minimike86 May 8, 2026
52507f2
feat: Add frames per chunk setting in sender and initialize repeat co…
minimike86 May 8, 2026
d57703d
feat: Enhance ETA calculation in sender to account for chunk repeat s…
minimike86 May 8, 2026
8957ca3
feat: Implement fountain coding for enhanced data transfer efficiency
minimike86 May 8, 2026
3383749
Refactor sender and receiver UI: hide/show camera placeholder and QR …
minimike86 May 8, 2026
9614c27
feat: Enhance QR code scanning logic and improve error handling in re…
minimike86 May 9, 2026
bb587f9
feat: Adjust tooltip positioning for right-column settings to enhance…
minimike86 May 9, 2026
ee7e35b
feat: Simplify QR code data handling in scan loop for improved perfor…
minimike86 May 9, 2026
c624627
feat: Update transfer display to differentiate between fountain and m…
minimike86 May 9, 2026
e267693
Remove obsolete test files and add a new UI theme module for the QRL …
minimike86 May 9, 2026
b3267dc
feat: Enhance decoder and GUI to support fountain mode; update status…
minimike86 May 9, 2026
2a86d12
feat: Add Multi-QR Sender page and functionality for simultaneous QR …
minimike86 May 9, 2026
135dd4a
feat: Update multi-QR sender options for improved layout; adjust hint…
minimike86 May 9, 2026
80653f5
feat: Implement source selection for camera and screen capture; add c…
minimike86 May 9, 2026
e9cc337
Update README.md to add txqr
minimike86 May 9, 2026
217f20e
Add qrterminal to similar projects list
minimike86 May 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .claude/scheduled_tasks.lock

This file was deleted.

5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,7 @@ Tempqrl_boxsize_test/
Tempqrl_test_folder/
Tempqrl_test_grid/
Tempqrl_test_out/
Tempqrl_test_single/
Tempqrl_test_single/

# claude
.claude/
124 changes: 88 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,76 +1,126 @@
# QRL — QR Link

QRL transfers files across a screen boundary by encoding them as a flashing sequence of QR codes. The **server** chunks, compresses, and displays the codes; the **client** screen-captures and reassembles them into the original file.
QRL transfers files across a screen boundary by encoding them as a sequence of QR codes. The **web sender** encodes, chunks, and displays the codes in the browser; the **receiver** scans and reassembles — either via the web receiver (camera) or the Python client (screen capture).

No network connection, no clipboard, and no agent is needed on the receiving end — only a screen you can see. Typical scenarios: pulling a file out of a remote desktop session, VNC, Citrix, or any environment where the only shared channel is a rendered screen.

---

## Quick start
## Web version (recommended — no install)

**Combined GUI — send and receive in one window:**
`qrl_web/` is a browser-only implementation. Both sender and receiver run entirely in the browser — no Python, no build step.

**Live on GitHub Pages:**

| Page | URL |
|------|-----|
| Home | https://minimike86.github.io/QRL/qrl_web |
| Sender | https://minimike86.github.io/QRL/qrl_web/sender.html |
| Receiver | https://minimike86.github.io/QRL/qrl_web/receiver.html |

**Or serve locally:**
```bash
python qrl_gui.py
cd qrl_web
python -m http.server 8765
# open http://localhost:8765
```

**Standalone GUIs:**
The receiver requires HTTPS or `localhost` for camera access — GitHub Pages and the local server both satisfy this.

### Workflow

1. Open **Sender** on the source device and select a file or folder.
2. Configure settings (chunk size, FPS, error correction, QR size, fountain mode).
3. Press **Start Transfer** — a manifest QR appears first. Press **Resume** once the receiver is ready.
4. Open **Receiver** on the destination device and press **Start Camera**.
5. Point the camera at the sender's screen. The file downloads automatically when all chunks arrive.

### Sender settings

| Setting | Default | Description |
|---------|---------|-------------|
| Chunk size (B) | 600 | Payload bytes per QR frame. Smaller = more reliable; larger = fewer total frames. |
| FPS | 3 | Target frames per second. Increase in good lighting conditions. |
| Error correction | L | Reed-Solomon redundancy baked into each QR (L / M / Q / H). |
| QR size (px) | 420 | Rendered canvas size. Larger aids scanning from a distance. |
| Frames per chunk | 1 | Hold each chunk for N consecutive frames before advancing (sequential mode only). |
| Fountain mode | off | XOR-coded infinite packet stream — no replay needed (see below). |

### Fountain mode

When **Fountain mode** is on the sender generates an infinite stream of XOR-coded packets using LT codes. The receiver reconstructs the full file from any sufficient subset of packets via belief propagation — scanning can be intermittent without requiring a manual replay step.

The sender display shows `fountain pkt N` (packet counter), **CYCLES** (completed equivalent-sets), and a cycling progress bar showing position within the current cycle.

In sequential mode, the **Replay missing chunks** field lets you send only specific chunk numbers again by entering numbers, ranges, or comparisons (e.g. `3,7,5-10,>=50`).

---

## Python client (receive only)

The Python client captures the screen with `mss` and decodes QR codes with `pyzbar`. It is fully compatible with the web sender — same wire format, same manifest, same fountain protocol.

**GUI:**
```bash
python -m qrl_server --gui # encode and display
python -m qrl_client --gui # capture and decode
python qrl_gui.py
# or
python -m qrl_client --gui
```

**CLI:**
```bash
qrl-server myfile.bin # display with defaults
qrl-server myfile.bin --chunk-size 1490 --duration 0.1 --error-correction Q
qrl-client --output /tmp/received/ # capture to folder
qrl-client --output ~/received/
```

---

## How it works

1. The server reads the source file (or tar-packs a folder), optionally gzips it, and splits it into fixed-size chunks.
2. Each chunk gets a 9-byte binary header and is rendered as a QR code.
3. A **manifest QR** is shown at the start of every display cycle carrying the filename, size, and stream metadata so a late-joining client can catch up.
4. The client captures the screen on a configurable interval, decodes every visible QR per frame, and writes the file when the last chunk arrives.
1. The sender reads the source file (or zip-packs a folder), optionally gzips it, and splits it into fixed-size chunks.
2. Each chunk gets a 9-byte binary wire header and is encoded as a QR code in byte mode.
3. A **manifest QR** (stream_id = 255) is shown first, carrying the filename, size, chunk count, and transfer mode so a late-joining receiver can catch up.
4. **Sequential mode**: chunks cycle continuously until stopped. The receiver collects until the full set arrives, then auto-downloads.
5. **Fountain mode**: an infinite stream of XOR-coded packets (stream_id = 2) is generated. The receiver runs iterative belief-propagation decoding and finalises as soon as all source chunks are recovered.
6. The receiver decompresses and saves the file on completion.

See [docs/architecture.md](docs/architecture.md) for the full wire format and data flow.
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full wire format, fountain coding details, and data flow.

---

## Features at a glance
## Features

| Area | Feature |
|------|---------|
| Encoding | Auto gzip compression (skipped if it doesn't help) |
| Encoding | Folder support — tar-packed, auto-extracted on arrival |
| Display | Configurable FPS (2 / 10 / 20 / 30) and QR quality presets |
| Display | Parallel grid mode — 4, 9, 16, or auto-fit streams for multiplied throughput |
| Display | Background prefetch with a bounded LRU cache |
| Display | Export QR sequence as PDF or MP4 for offline replay |
| GUI | Drag-and-drop file loading (server tab) |
| Capture | Whole screen, specific monitor, or hand-drawn region |
| Capture | Live preview at 5 fps while decoding runs |
| Capture | Partial-progress save — resume an interrupted session |
| Config | YAML / JSON config files with auto-discovery search paths |
| **Web sender** | Browser-only — no install, no Python |
| **Web sender** | Fountain mode: LT-code XOR packets, infinite stream, no replay needed |
| **Web sender** | Sequential mode with targeted missing-chunk replay |
| **Web sender** | Auto gzip compression (skipped when not beneficial) |
| **Web sender** | Folder support — packed as .zip, extracted on arrival |
| **Web sender** | Responsive two-column desktop layout and mobile-optimised UI |
| **Web sender** | Contextual setting hints and QR flash animation |
| **Web receiver** | Webcam-based scanning, chunk map, ETA, duplicate detection |
| **Web receiver** | Auto-download on completion |
| **Python client** | Screen capture via `mss` — no GUI required on remote end |
| **Python client** | Whole screen, specific monitor, or hand-drawn capture region |
| **Python client** | Live preview, partial-progress resume |
| Config | YAML / JSON config files for the Python client |

---

## Documentation

| File | Contents |
|------|---------|
| [docs/architecture.md](docs/architecture.md) | Wire format, data flow, compression, LRU cache, manifest |
| [docs/server.md](docs/server.md) | All server settings, speed/quality/density/mode presets, export |
| [docs/client.md](docs/client.md) | All client settings, region picker, monitor selection, progress |
| [docs/parallel-streams.md](docs/parallel-streams.md) | How parallel grid mode works, throughput estimates |
| [docs/configuration.md](docs/configuration.md) | Full config file reference and search path order |
| [docs/cli.md](docs/cli.md) | All CLI flags for `qrl-server` and `qrl-client` |
| [qrl_web/](qrl_web/) | Browser sender + receiver source |
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Wire format, fountain coding, data flow, compression |
| [docs/server.md](docs/server.md) | Web sender settings, workflow, and display panel |
| [docs/client.md](docs/client.md) | Python client settings, region picker, progress panel |
| [docs/configuration.md](docs/configuration.md) | Python client config file reference and search paths |
| [docs/cli.md](docs/cli.md) | `qrl-client` CLI flags |

---

## Installation
## Installation (Python client)

```bash
git clone https://github.com/minimike86/QRL.git
Expand All @@ -92,5 +142,7 @@ pytest tests/

## Similar projects

- [QRxfil](https://github.com/OverkillGuy/qrxfil) — QR-code-based file transfer, outputs a static PDF.
- [QRExfil](https://github.com/Shell-Company/QRExfil) — QR code transfer with animated GIF output.
- [txqr](https://github.com/divan/txqr)
- [QRxfil](https://github.com/OverkillGuy/qrxfil)
- [QRExfil](https://github.com/Shell-Company/QRExfil)
- [qrterminal](https://github.com/mdp/qrterminal)
28 changes: 0 additions & 28 deletions config/server_example.yaml

This file was deleted.

7 changes: 0 additions & 7 deletions config/server_minimal.json

This file was deleted.

Loading
Loading