feat(pdu,graphics,egfx): add ClearCodec bitmap compression codec#1174
Open
Greg Lamberson (glamberson) wants to merge 6 commits intoDevolutions:masterfrom
Open
feat(pdu,graphics,egfx): add ClearCodec bitmap compression codec#1174Greg Lamberson (glamberson) wants to merge 6 commits intoDevolutions:masterfrom
Greg Lamberson (glamberson) wants to merge 6 commits intoDevolutions:masterfrom
Conversation
Implement MS-RDPEGFX 2.2.4.1 ClearCodec (codecId=0x0008), a mandatory lossless codec for all EGFX versions. PDU layer (ironrdp-pdu): - Top-level bitmap stream with glyph index/hit/cache reset flags - Three-layer composite payload (residual, bands, subcodec) - Residual: BGR run-length encoding with variable-length factors - Bands: V-bar dispatch (full cache hit, short cache hit, cache miss) - RLEX: palette-indexed RLE with gradient suite encoding - Subcodec: container for Raw, NSCodec (stub), and RLEX regions Graphics layer (ironrdp-graphics): - ClearCodecDecoder with persistent V-bar and glyph cache state - V-bar cache: 32K full + 16K short entries in ring buffers - Glyph cache: 4,000 entries for small bitmap deduplication - Full three-layer compositing (residual -> bands -> subcodec) 35 tests covering all codec layers and round-trip encoding. NSCodec subcodec deferred (servers can use Raw or RLEX instead).
Add ClearCodecEncoder for server-side ClearCodec bitmap compression: - Residual-only encoding strategy (BGR RLE) for reliable compression - Glyph cache with automatic hit detection for small repeated bitmaps - Sequence number tracking matching the decoder protocol - Cache reset message encoding - BGRA-to-BGR run segment conversion with run-length coalescing 7 new encoder tests including encode-decode round trips that verify interoperability between the encoder and decoder.
Add send_clearcodec_frame() to GraphicsPipelineServer, following the same pattern as send_avc420_frame(). Takes pre-encoded ClearCodec bitmap data and queues it as a WireToSurface1 PDU with the standard three-PDU frame sequence (StartFrame, WireToSurface1, EndFrame). ClearCodec is mandatory for all EGFX versions and provides lossless compression optimized for text and UI elements.
…tion Security hardening informed by FreeRDP ClearCodec CVEs (GHSA-3frr, GHSA-32q9, CVE-2026-26955, CVE-2026-23531) and three rounds of targeted code review. Fixes: - Correct shortVBarYOff interpretation: 6-bit field is an absolute end-row offset, not a pixel count. Pixel count = yOff - yOn per MS-RDPEGFX 2.2.4.1.1.2.1.1.3. (Round 2) - Validate shortVBarYOff >= shortVBarYOn and <= band_height (Round 2) - Cap residual run_length iterations to output buffer size (Round 1) - Cap decoder allocation to 8192x8192 pixels max (Round 3) - Validate glyph index range 0-3999 per spec 2.2.4.1 (Round 2) - Cap encoder input to available pixel data (Round 1) Add integration tests in ironrdp-testsuite-core (35 tests) covering codec round-trip, adversarial input (DoS, OOM, malformed streams), bands layer compositing, cache state, compression quality, and multi-frame session simulation. Inline unit tests (42 tests) in the PDU and graphics crates cover wire format decode/encode.
Greg Lamberson (glamberson)
added a commit
to lamco-admin/IronRDP
that referenced
this pull request
Mar 18, 2026
Wire ClearCodec into the EGFX client's WireToSurface1 codec dispatch, following the same pattern as AVC420 and Uncompressed decode. - Add ClearCodecDecoder field (always enabled, no external codec needed) - Decode ClearCodec bitmap data and convert BGRA output to RGBA - Reset decoder caches on ResetGraphics (V-bar + glyph state) - Add 3 integration tests: basic decode, RGBA output, reset survival - Add unit test for BGRA-to-RGBA channel reordering Depends on the ClearCodec codec PR (Devolutions#1174).
There was a problem hiding this comment.
Pull request overview
Adds ClearCodec (MS-RDPEGFX 2.2.4.1) support across the wire-format layer (ironrdp-pdu), codec logic (ironrdp-graphics), and EGFX server API (ironrdp-egfx), with extensive new tests in ironrdp-testsuite-core.
Changes:
- Introduces
ironrdp-pdu::codecs::clearcodecwith residual/bands/subcodec parsing and helpers. - Adds
ironrdp-graphics::clearcodecencoder/decoder plus persistent V-bar and glyph caching. - Extends
GraphicsPipelineServerwithsend_clearcodec_frame()and adds ClearCodec integration tests.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/ironrdp-testsuite-core/tests/graphics/mod.rs | Registers the new ClearCodec integration test module. |
| crates/ironrdp-testsuite-core/tests/graphics/clearcodec.rs | Adds ClearCodec end-to-end and adversarial integration tests. |
| crates/ironrdp-pdu/src/codecs/mod.rs | Exposes the new ClearCodec codec module. |
| crates/ironrdp-pdu/src/codecs/clearcodec/mod.rs | Defines ClearCodec bitmap stream + composite payload parsing and exports layer decoders. |
| crates/ironrdp-pdu/src/codecs/clearcodec/residual.rs | Implements residual (BGR RLE) encode/decode. |
| crates/ironrdp-pdu/src/codecs/clearcodec/bands.rs | Implements bands layer decoding (V-bar references + inline data). |
| crates/ironrdp-pdu/src/codecs/clearcodec/subcodec.rs | Implements subcodec layer parsing (raw/NSCodec/RLEX region headers). |
| crates/ironrdp-pdu/src/codecs/clearcodec/rlex.rs | Implements RLEX subcodec parsing. |
| crates/ironrdp-graphics/src/lib.rs | Exposes the new clearcodec module. |
| crates/ironrdp-graphics/src/clearcodec/mod.rs | Implements ClearCodec decoder/encoder and compositing across layers. |
| crates/ironrdp-graphics/src/clearcodec/glyph_cache.rs | Adds glyph cache backing storage used by encoder/decoder. |
| crates/ironrdp-graphics/src/clearcodec/vbar_cache.rs | Adds V-bar/short V-bar cache backing storage used by decoder. |
| crates/ironrdp-egfx/src/server.rs | Adds send_clearcodec_frame() EGFX server API entry point. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
…items Address review feedback on Devolutions#1174: - Validate subcodec region bounds against surface dimensions - Validate RLEX palette indices and enforce region pixel budget - Remove silent pixel skipping that caused coordinate desync - Add glyph cache dimension mismatch check on hit - Use checked arithmetic for raw subcodec data length - Remove unused expected_seq field from ClearCodecDecoder - Use saturating_mul in encoder for pixel count - Add missing QoE backpressure recording for ClearCodec frames - Document vbar_cache wrap constant derivation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the multi-codec EGFX implementation described in #1158 (Section 3).
Summary
Add ClearCodec (MS-RDPEGFX 2.2.4.1), the mandatory lossless bitmap codec
for all EGFX versions (V8-V10.7). ClearCodec uses three-layer compositing
(residual BGR RLE, bands with V-bar caching, subcodec regions) to encode
text, UI elements, and icons with pixel-perfect fidelity.
This is the first ClearCodec encoder in any open-source RDP implementation.
FreeRDP has client-side decode only.
What it adds
ironrdp-pdu (wire format):
RLE decode/encode, bands with V-bar cache references (full hit, short
hit, short miss), RLEX subcodec, raw/NSCodec dispatch
ironrdp-graphics (codec logic):
ClearCodecEncoder with residual-only encoding and glyph deduplication
ironrdp-egfx (server integration):
ironrdp-testsuite-core:
adversarial input handling (max run_length, OOM dimensions, malformed
streams, uncached glyph hits), bands layer compositing through the full
decode pipeline, cache state management across multi-frame sessions,
compression quality assertions
Security hardening
Three rounds of code review against FreeRDP ClearCodec CVEs:
(MS-RDPEGFX 2.2.4.1.1.2.1.1.3)
NSCodec
The NSCodec subcodec (Layer 3 option) is not implemented in this PR.
The encoder avoids generating NSCodec tiles, and the decoder stub leaves
NSCodec regions at their residual-layer values. This can be added later
without API changes.
Test plan