The TS_BITMAPCODECS_CAPABILITYSET structure advertises support for bitmap encoding and decoding codecs used in conjunction with the Set Surface Bits Surface Command (section 2.2.9.2.1) and Cache Bitmap (Revision 3) Secondary Drawing Order ([MS-RDPEGDI] section 2.2.2.2.1.2.8). This capability is sent by both the client and server.
        /// <summary>
        /// Parse TS_BITMAPCODECS_CAPABILITYSET
        /// </summary>
        /// <param name="data">data to be parsed</param>
        /// <returns>TS_BITMAPCODECS_CAPABILITYSET</returns>
        private TS_BITMAPCODECS_CAPABILITYSET ParseCapsTypeBitmapCodecs(byte[] data)
        {
            int currentIndex = 0;
            TS_BITMAPCODECS_CAPABILITYSET set = new TS_BITMAPCODECS_CAPABILITYSET();

            // TS_BITMAPCODECS_CAPABILITYSET: capabilitySetType
            set.capabilitySetType = (capabilitySetType_Values)ParseUInt16(data, ref currentIndex, false);

            // TS_BITMAPCODECS_CAPABILITYSET: lengthCapability
            set.lengthCapability = ParseUInt16(data, ref currentIndex, false);

            // TS_BITMAPCODECS_CAPABILITYSET: supportedBitmapCodecs
            set.supportedBitmapCodecs = ParseTsBitmapCodecs(data, ref currentIndex);

            // Check if data length is consistent with the decoded struct length
            VerifyDataLength(data.Length, currentIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_INCONSISTENT);
            return set;
        }
        /// <summary>
        /// Create a TS_BITMAPCODECS_CAPABILITYSET type Capability, 2.2.7.2.10   
        /// Problem: lengthCapability may be wrong, as different from previous value
        /// </summary>
        ///<param name="isNSCodecPresent">Indicates if present NS codec.</param>
        ///<param name="isRemoteFxCodecPresent">Indicates if present RemoteFX codec.</param>
        /// <returns>TS_BITMAPCODECS_CAPABILITYSET type Capability</returns>
        public static TS_BITMAPCODECS_CAPABILITYSET CreateBitmapCodecsCapSet(bool isNSCodecPresent, bool isRemoteFxCodecPresent)
        {
            TS_BITMAPCODEC[] codecArr;
            if (isNSCodecPresent && isRemoteFxCodecPresent)
            {
                codecArr = new TS_BITMAPCODEC[2];
                codecArr[0] = CreateTS_BITMAPCODEC_NSCodec();
                codecArr[1] = CreateTS_BITMAPCODEC_RemoteFX();
            }
            else if (isRemoteFxCodecPresent)
            {
                codecArr = new TS_BITMAPCODEC[1];
                codecArr[0] = CreateTS_BITMAPCODEC_RemoteFX();
            }
            else
            {
                codecArr = new TS_BITMAPCODEC[1];
                codecArr[0] = CreateTS_BITMAPCODEC_NSCodec();
            }

            TS_BITMAPCODECS_CAPABILITYSET codecCapSet = new TS_BITMAPCODECS_CAPABILITYSET();
            codecCapSet.capabilitySetType = capabilitySetType_Values.CAPSETTYPE_BITMAP_CODECS;
            codecCapSet.supportedBitmapCodecs.bitmapCodecCount = (byte)codecArr.Length;
            codecCapSet.supportedBitmapCodecs.bitmapCodecArray = codecArr;

            //<needcheck>
            // capabilitySetType (2 bytes) + lengthCapability (2 bytes) + bitmapCodecCount (1 byte)
            codecCapSet.lengthCapability = (ushort)(2 + 2 + 1);
            for (int index = 0; index < codecCapSet.supportedBitmapCodecs.bitmapCodecCount; ++index)
            {
                //codecGUID (16 bytes) + codecID (1 byte) + codecPropertiesLength (2 bytes) + codecProperties (variable)
                codecCapSet.lengthCapability += (ushort)(16 + 1 + 2 + codecCapSet.supportedBitmapCodecs.bitmapCodecArray[index].codecPropertiesLength);
            }

            return codecCapSet;
        }
        /// <summary>
        /// Method to receive and decode client capabilities.
        /// </summary>
        /// <param name="serverMaxRequestSize">The MaxRequestSize field of the server-to-client Multifragment Update Capability Set. </param>
        /// <param name="supportedRfxCaps">Output the TS_RFX_ICAP array supported by the client.</param>
        public void ReceiveAndCheckClientCapabilities(uint serverMaxRequestSize, out TS_RFX_ICAP[] supportedRfxCaps)
        {
            supportedRfxCaps = null;
            s2cMaxRequestSize = serverMaxRequestSize;
            ConfirmCapabilitySets =  this.rdpbcgrSessionContext.ConfirmCapabilitySets;
            foreach (ITsCapsSet capSet in ConfirmCapabilitySets)
            {
                if (capSet is TS_MULTIFRAGMENTUPDATE_CAPABILITYSET)
                {
                    this.is_Client_Multifragment_Update_CapabilitySet_Received = true;
                    this.client_Multifragment_Update_CapabilitySet = (TS_MULTIFRAGMENTUPDATE_CAPABILITYSET)capSet;
                }
                else if (capSet is TS_LARGE_POINTER_CAPABILITYSET)
                {
                    this.is_Client_Large_Pointer_Capability_Set_Received = true;
                    this.client_Large_Pointer_Capability_Set = (TS_LARGE_POINTER_CAPABILITYSET)capSet;
                }
                else if (capSet is TS_BITMAPCACHE_CAPABILITYSET_REV2)
                {
                    this.is_Client_Revision2_Bitmap_Cache_Capability_Set_Received = true;
                    this.client_Revision2_Bitmap_Cache_Capability_Set = (TS_BITMAPCACHE_CAPABILITYSET_REV2)capSet;
                }
                else if (capSet is TS_FRAME_ACKNOWLEDGE_CAPABILITYSET)
                {
                    this.is_TS_FRAME_ACKNOWLEDGE_CAPABILITYSET_Received = true;
                    this.clientTS_FRAME_ACKNOWLEDGE_CAPABILITYSET = (TS_FRAME_ACKNOWLEDGE_CAPABILITYSET)capSet;
                }
                else if (capSet is TS_SURFCMDS_CAPABILITYSET)
                {
                    this.is_Client_Surface_Commands_Capability_Set_Received = true;
                    this.client_Surface_Commands_Capability_Set = (TS_SURFCMDS_CAPABILITYSET)capSet;
                    if ((this.client_Surface_Commands_Capability_Set.cmdFlags & CmdFlags_Values.SURFCMDS_STREAMSURFACEBITS) == CmdFlags_Values.SURFCMDS_STREAMSURFACEBITS)
                    {
                        this.clientupportStreamSurfaceBits = true;
                    }
                }
                else if (capSet is TS_BITMAPCODECS_CAPABILITYSET)
                {
                    this.is_Client_Bitmap_Codecs_Capability_Set_Received = true;
                    this.client_Bitmap_Codecs_Capability_Set = (TS_BITMAPCODECS_CAPABILITYSET)capSet;
                    foreach (TS_BITMAPCODEC codec in this.client_Bitmap_Codecs_Capability_Set.supportedBitmapCodecs.bitmapCodecArray)
                    {
                        if (is_REMOTEFX_CODEC_GUID(codec.codecGUID))
                        {
                            is_TS_RFX_CLNT_CAPS_CONTAINER_Received = true;
                            remoteFXCodecID = codec.codecID;
                            this.client_RFX_Caps_Container =  rdprfxServerDecoder.Decode_TS_RFX_CLNT_CAPS_CONTAINER(codec.codecProperties);
                            supportedRfxCaps = this.client_RFX_Caps_Container.capsData.capsetsData[0].icapsData;
                            break;
                        }
                    }
                }
            }

            //Verify Client Capabilities
            VerifyClientCapabilities();
        }