feat: phase 9 — encoding 9 (IIP) with tile-versioned delta cache
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>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use std::io::{BufReader, BufWriter};
|
||||
use std::net::TcpStream;
|
||||
|
||||
use crate::codec::{hextile, raw_tile, tight};
|
||||
use crate::codec::{hextile, iip, raw_tile, tight};
|
||||
use crate::framebuffer::Framebuffer;
|
||||
use crate::handshake::{self, Config, ServerInit};
|
||||
use crate::msg::{self, ServerMsg};
|
||||
@@ -46,19 +46,23 @@ pub struct ActiveSession {
|
||||
pub writer: BufWriter<TcpStream>,
|
||||
pub server_init: ServerInit,
|
||||
zlib: tight::ZlibStreams,
|
||||
tile_cache: iip::TileCache,
|
||||
}
|
||||
|
||||
impl ActiveSession {
|
||||
/// Connect, handshake, send SetEncodings + initial FBUpdateRequest.
|
||||
pub fn connect(cfg: &Config, encodings: &[i32]) -> Result<Self, SessionError> {
|
||||
let raw = handshake::connect(cfg)?;
|
||||
let w = raw.server_init.width;
|
||||
let h = raw.server_init.height;
|
||||
let mut session = Self {
|
||||
framebuffer: Framebuffer::new(raw.server_init.width, raw.server_init.height),
|
||||
framebuffer: Framebuffer::new(w, h),
|
||||
server_name: raw.server_name,
|
||||
reader: raw.reader,
|
||||
writer: raw.writer,
|
||||
server_init: raw.server_init,
|
||||
zlib: tight::ZlibStreams::new(),
|
||||
tile_cache: iip::TileCache::new(w, h),
|
||||
};
|
||||
|
||||
// Tell server to send 8bpp RGB332 pixels
|
||||
@@ -157,6 +161,8 @@ impl ActiveSession {
|
||||
if self.server_init.width != old_w || self.server_init.height != old_h {
|
||||
self.framebuffer
|
||||
.resize(self.server_init.width, self.server_init.height);
|
||||
self.tile_cache
|
||||
.resize(self.server_init.width, self.server_init.height);
|
||||
return Ok(Some(Event::Resize {
|
||||
width: self.server_init.width,
|
||||
height: self.server_init.height,
|
||||
@@ -221,6 +227,18 @@ impl ActiveSession {
|
||||
hdr.h,
|
||||
)?;
|
||||
}
|
||||
9 => {
|
||||
iip::decode_iip(
|
||||
&mut self.reader,
|
||||
&mut self.framebuffer,
|
||||
&mut self.tile_cache,
|
||||
&mut self.zlib,
|
||||
hdr.x,
|
||||
hdr.y,
|
||||
hdr.w,
|
||||
hdr.h,
|
||||
)?;
|
||||
}
|
||||
10 => {
|
||||
raw_tile::decode_raw_tile(
|
||||
&mut self.reader,
|
||||
|
||||
Reference in New Issue
Block a user