Commit Graph

4 Commits

Author SHA1 Message Date
acf99f849b feat: phase 9 — encoding 9 (IIP) with tile-versioned delta cache
All checks were successful
CI / check (push) Successful in 1m22s
Publish / frontend (push) Successful in 43s
CI / fmt (push) Successful in 54s
CI / clippy (push) Successful in 1m40s
Publish / backend (push) Successful in 2m27s
codec/iip.rs:
- TileCache: (fb_width/16 × fb_height/16) tiles, 8 versions × 256 bytes
  each, matching t.java's (8, 16*16) allocation
- TileEntry: versioned read/write at byte offsets within tile data
- decode_iip() handles all 4 modes from the control byte:
  - Mode 0/12 (cache-read): tile control bytes select which cached
    version of each 16x16 tile to display, no new pixel data on wire
  - Mode 4 (write-only): Tight-decoded pixel data written to cache
  - Mode 8 (update+read): conditionally writes new data to cache
    (bit 7 of control byte = 0 means update), then reads from cache
- Tile control bytes compressed via zlib (varint length) when >= 12
- Sub-types 1-4/8 map to bit-depths 1/2/4/4/8 bpp
- Cache resized on framebuffer resize (ModeChange msg 128)

Wired into session dispatch for encoding 9. Not advertised in default
encoding list — only active if explicitly requested.

codec/tight.rs: made get_or_init() pub for IIP's zlib access.

39 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 09:39:49 +03:00
c31508f138 feat: phase 10 — reconnection, encoding 10, disconnect button
All checks were successful
Publish / frontend (push) Successful in 42s
CI / fmt (push) Successful in 44s
CI / check (push) Successful in 1m43s
CI / clippy (push) Successful in 1m43s
Publish / backend (push) Successful in 2m47s
Frontend reconnection:
- WebSocket auto-reconnects with exponential backoff (1s → 30s)
- Re-authenticates with OmniView to get fresh APPLET_ID on reconnect
- Credentials stored in sessionStorage for automatic re-login
- Status bar shows connection state and reconnect countdown
- Disconnect button returns to login screen

Encoding 10 (Raw with tile interleave):
- codec/raw_tile.rs: decodes encoding 10 per ByteColorRFBRenderer.for()
- Flag byte bit 0 selects plain raw vs 16x16 tile-interleaved data
- Deinterleave handles edge tiles smaller than 16x16
- Wired into session dispatch
- 2 unit tests

39 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 09:21:21 +03:00
c8f981f045 feat: phase 5 — Tight decoder with zlib streams and sub-palettes
All checks were successful
CI / fmt (push) Successful in 36s
CI / check (push) Successful in 1m1s
CI / clippy (push) Successful in 1m4s
codec/tight.rs:
- Full Tight (encoding 7) decoder per ByteColorRFBRenderer.a() line 324
- Control byte: bottom 4 bits = zlib stream reset flags,
  top 4 bits = subencoding (0-15)
- Subencoding 8: solid fill (1-byte color)
- Subencoding 15: palette-indexed fill (selector + index)
- Subencodings 4-7: filtered data with optional 2-color palette
- Subencodings 10-13: reduced bit-depth packed (1/2/4 bpp)
- Subencodings 0-3: raw 8bpp data
- Data >= 12 bytes uses zlib compression with varint length
- 4 persistent zlib streams with reset-on-flag logic
- All 4 hardcoded sub-palettes ported as RGB332 indices:
  PALETTE_BW (2), PALETTE_GRAY4 (4), PALETTE_GRAY16 (16),
  PALETTE_COLOR16 (16 EGA-like colors)
- Bit-depth unpackers: 1bpp, 2bpp, 4bpp (MSB-first)
- 5 unit tests

Updated examples to request [7, 5, 1, 0, -250] (Tight preferred).
Tested against real OmniView: correct rendering with Tight encoding.
32 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 14:44:06 +03:00
21ed797302 feat: phase 4 — Hextile decoder and recording example
All checks were successful
CI / fmt (push) Successful in 28s
CI / check (push) Successful in 1m12s
CI / clippy (push) Successful in 1m12s
codec/hextile.rs:
- Full Hextile (encoding 5) decoder per ByteColorRFBRenderer.int()
- Handles: Raw tiles, BackgroundSpecified, ForegroundSpecified,
  AnySubrects, SubrectsColoured flags
- Background/foreground colors persist across tiles
- 4 unit tests covering all subencoding paths

framebuffer.rs:
- Added fill_rect() for Hextile background/subrect fills

session.rs:
- Wired Hextile encoding 5 into the rect dispatch

examples/record.rs:
- 30-second (configurable) recording session
- Saves 1 PNG per second to out/ directory
- Requests encodings [5, 1, 0] (Hextile, CopyRect, Raw)
- Tested against real OmniView: 10 frames in 10s, no errors

27 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 14:35:20 +03:00