Internal
Public Access
Add VNC ZRLE decoding
Implements RFC 6143 SS7.7.6: a ZRLE rectangle is a 4-byte compressed length followed by that many zlib-compressed bytes, decompressing to 64x64 tiles each using one of five subencodings (Raw, Solid, packed palette, Plain RLE, Palette RLE). The zlib stream persists for the whole connection rather than being reset per-rectangle or per-update, so VncSessionBackend now owns a lazily-initialized, persistent z_stream torn down only in resetProtocolState() on a fresh connect/reconnect. Since the entire rectangle's compressed data decompresses into memory in one shot, tile parsing is a plain synchronous loop rather than needing its own RfbState values -- only the compressed-length and compressed-data reads are actual protocol states. Tile decoding (the five subencodings, including the continuation-byte run-length encoding shared by two of them) lives in vnc_pixel_codecs.h/.cpp alongside the Hextile decoder, unit-tested with 6 new tests covering each subencoding plus a persistence test that splits one continuous deflate stream across two separate FramebufferUpdate messages -- it only decodes correctly if the connection's inflate stream is retained between them. Adds a top-level find_package(ZLIB REQUIRED) + ZLIB::ZLIB link (previously only pulled in transitively via vendored FreeRDP's own smartcard-emulation feature, which happened to have it enabled but shouldn't be relied on for that). Live-verified against the TightVNC test server that nothing regressed (connect, cursor, clipboard); that server consistently sends Raw for actual framebuffer content regardless of announced encodings, so Hextile/ZRLE's live decode path isn't independently confirmed against a real server -- the unit tests are the primary evidence here. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include <QRgb>
|
||||
|
||||
class QTcpSocket;
|
||||
struct z_stream_s;
|
||||
|
||||
// Implements RFB (RFC 6143) directly against QTcpSocket -- there is no
|
||||
// permissively licensed VNC client library to vendor the way FreeRDP was
|
||||
@@ -22,11 +23,10 @@ class QTcpSocket;
|
||||
//
|
||||
// Scope (see plan / issue #3 for the full rationale): standard VNC
|
||||
// Authentication (security type 2) and no-auth (type 1) only -- not
|
||||
// Apple's Screen Sharing scheme (type 30). Raw + CopyRect + Hextile
|
||||
// encodings (ZRLE/Tight compression not yet implemented). No dynamic
|
||||
// resize. Clipboard sync (Latin-1 only, per RFB's ServerCutText/
|
||||
// ClientCutText) and remote cursor shape sync (the Cursor pseudo-encoding)
|
||||
// are supported.
|
||||
// Apple's Screen Sharing scheme (type 30). Raw + CopyRect + Hextile + ZRLE
|
||||
// encodings (Tight compression not yet implemented). No dynamic resize.
|
||||
// Clipboard sync (Latin-1 only, per RFB's ServerCutText/ClientCutText) and
|
||||
// remote cursor shape sync (the Cursor pseudo-encoding) are supported.
|
||||
class VncSessionBackend : public SessionBackend
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -90,6 +90,8 @@ private:
|
||||
WaitingHextileTileMeta,
|
||||
WaitingHextileSubrectData,
|
||||
WaitingHextileRawTileData,
|
||||
WaitingZrleCompressedLength,
|
||||
WaitingZrleCompressedData,
|
||||
WaitingSetColourMapHeader,
|
||||
WaitingSetColourMapData,
|
||||
WaitingServerCutTextHeader,
|
||||
@@ -139,6 +141,15 @@ private:
|
||||
int m_hextileSubrectsRemaining;
|
||||
bool m_hextileSubrectsColoured;
|
||||
|
||||
// ZRLE's zlib stream (RFC 6143 SS7.7.6) persists for the whole
|
||||
// connection, not per-rectangle or per-update -- lazily initialized on
|
||||
// the first ZRLE rectangle, torn down and reset on every fresh
|
||||
// connect/reconnect via resetProtocolState(). z_stream_s is only
|
||||
// forward-declared here so <zlib.h> doesn't leak into every includer of
|
||||
// this header; the full type is only needed in the .cpp.
|
||||
z_stream_s* m_zrleInflateStream;
|
||||
bool m_zrleInflateInitialized;
|
||||
|
||||
void setState(SessionState state, const QString& message);
|
||||
void resetProtocolState();
|
||||
void processReceiveBuffer();
|
||||
|
||||
Reference in New Issue
Block a user