mirror of
https://github.com/infrost/RaptorQR.git
synced 2026-09-02 16:07:48 +08:00
Fix robustness, white border, GIF size estimate
- Fix Robust profile: V20-Q (97 modules, 315px) instead of broken V31-Q — fewer modules = bigger squares = camera-friendly — K=16, R=16 (100% overhead for max robustness) — Actual max payload: 450 bytes (verified against QR library) - Fix Balanced: V25-Q, K=20, R=12 - Fix Fast: V35-M, K=24, R=8 - Remove ugly white border: global CSS reset (margin:0, padding:0) - Remove broken estimated GIF size (was off by orders of magnitude) - Show actual GIF size after generation instead - Add 8MB file size limit - Remove warning banners
This commit is contained in:
@@ -3,6 +3,10 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { background: #0d1117; }
|
||||
</style>
|
||||
<title>QR-over-GIF Transfer</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -204,6 +204,7 @@ export function SenderPage() {
|
||||
mime = 'text/plain';
|
||||
} else {
|
||||
if (!file) { setError('Please select a file.'); return; }
|
||||
if (file.size > 8 * 1024 * 1024) { setError('File too large. Maximum size is 8 MB.'); return; }
|
||||
data = await file.arrayBuffer();
|
||||
filename = file.name;
|
||||
mime = file.type || 'application/octet-stream';
|
||||
@@ -307,7 +308,7 @@ export function SenderPage() {
|
||||
}, [gifResult, profileId, stats]);
|
||||
|
||||
// ─── Compute warnings ──────────────────────────────────────────────────────
|
||||
const showWarning = stats && stats.estimatedGifBytes > 5 * 1024 * 1024;
|
||||
const showWarning = false;
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -407,18 +408,9 @@ export function SenderPage() {
|
||||
<span style={S.infoValue}>{stats.frameCount}</span>
|
||||
<span style={S.infoLabel}>Generations</span>
|
||||
<span style={S.infoValue}>{stats.totalGenerations}</span>
|
||||
<span style={S.infoLabel}>Estimated GIF size</span>
|
||||
<span style={S.infoValue}>{formatBytes(stats.estimatedGifBytes)}</span>
|
||||
<span style={S.infoLabel}>Estimated throughput</span>
|
||||
<span style={S.infoValue}>
|
||||
{estimateThroughput(stats.originalSize, stats.frameCount, profileId)}
|
||||
</span>
|
||||
<span style={S.infoLabel}>GIF size</span>
|
||||
<span style={S.infoValue}>{gifResult ? formatBytes(gifResult.gifData.byteLength) : '…'}</span>
|
||||
</div>
|
||||
{showWarning && (
|
||||
<div style={S.warn}>
|
||||
⚠ Large GIF ({formatBytes(stats.estimatedGifBytes)}) — transfer may take several minutes.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -54,11 +54,11 @@ export enum Flags {
|
||||
|
||||
/** QR profile identifiers. */
|
||||
export enum ProfileId {
|
||||
/** Robust profile: QR V31, ECC Q, K=24, R=12. */
|
||||
/** Robust profile: QR V20, ECC Q, K=16, R=16 (100% overhead, big modules). */
|
||||
ROBUST = 0,
|
||||
/** Balanced profile: QR V35, ECC M, K=24, R=8. */
|
||||
/** Balanced profile: QR V25, ECC Q, K=20, R=12 (60% overhead). */
|
||||
BALANCED = 1,
|
||||
/** Fast profile: QR V40, ECC M, K=32, R=8. */
|
||||
/** Fast profile: QR V35, ECC M, K=24, R=8 (33% overhead). */
|
||||
FAST = 2,
|
||||
}
|
||||
|
||||
@@ -86,28 +86,28 @@ export interface ProfileConfig {
|
||||
/** Lookup of all defined profiles by their ProfileId. */
|
||||
export const PROFILES: Record<ProfileId, ProfileConfig> = {
|
||||
[ProfileId.ROBUST]: {
|
||||
qrVersion: 31,
|
||||
qrVersion: 20,
|
||||
eccLevel: 'Q',
|
||||
k: 24,
|
||||
r: 12,
|
||||
k: 16,
|
||||
r: 16,
|
||||
frameDelay: 30,
|
||||
maxPacketPayload: 1230,
|
||||
maxPacketPayload: 450,
|
||||
},
|
||||
[ProfileId.BALANCED]: {
|
||||
qrVersion: 25,
|
||||
eccLevel: 'Q',
|
||||
k: 20,
|
||||
r: 12,
|
||||
frameDelay: 20,
|
||||
maxPacketPayload: 683,
|
||||
},
|
||||
[ProfileId.FAST]: {
|
||||
qrVersion: 35,
|
||||
eccLevel: 'M',
|
||||
k: 24,
|
||||
r: 8,
|
||||
frameDelay: 20,
|
||||
maxPacketPayload: 1770,
|
||||
},
|
||||
[ProfileId.FAST]: {
|
||||
qrVersion: 40,
|
||||
eccLevel: 'M',
|
||||
k: 32,
|
||||
r: 8,
|
||||
frameDelay: 15,
|
||||
maxPacketPayload: 2290,
|
||||
maxPacketPayload: 1777,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ describe('Constants', () => {
|
||||
expect(p.maxPacketPayload).toBeGreaterThan(100);
|
||||
}
|
||||
});
|
||||
it('Robust has highest overhead (K=24, R=12)', () => {
|
||||
expect(PROFILES[ProfileId.ROBUST].k).toBe(24);
|
||||
expect(PROFILES[ProfileId.ROBUST].r).toBe(12);
|
||||
it('Robust has highest overhead (K=16, R=16)', () => {
|
||||
expect(PROFILES[ProfileId.ROBUST].k).toBe(16);
|
||||
expect(PROFILES[ProfileId.ROBUST].r).toBe(16);
|
||||
});
|
||||
it('createSessionId returns a bigint', () => {
|
||||
const id = createSessionId();
|
||||
|
||||
Reference in New Issue
Block a user