The TS_BITMAPCODEC structure is used to describe the encoding parameters of a bitmap codec.
 private static TS_BITMAPCODEC CreateTS_BITMAPCODEC_RemoteFX()
 {
     TS_BITMAPCODEC bitmapCodec = new TS_BITMAPCODEC();
     bitmapCodec.codecGUID.codecGUID1 = 0x76772F12;
     bitmapCodec.codecGUID.codecGUID2 = 0xBD72;
     bitmapCodec.codecGUID.codecGUID3 = 0x4463;
     bitmapCodec.codecGUID.codecGUID4 = 0xAF;
     bitmapCodec.codecGUID.codecGUID5 = 0xB3;
     bitmapCodec.codecGUID.codecGUID6 = 0xB7;
     bitmapCodec.codecGUID.codecGUID7 = 0x3C;
     bitmapCodec.codecGUID.codecGUID8 = 0x9C;
     bitmapCodec.codecGUID.codecGUID9 = 0x6F;
     bitmapCodec.codecGUID.codecGUID10 = 0x78;
     bitmapCodec.codecGUID.codecGUID11 = 0x86;
     bitmapCodec.codecID = 0;
     bitmapCodec.codecPropertiesLength = 4;
     bitmapCodec.codecProperties = new byte[4];//TS_RFX_SRVR_CAPS_CONTAINER, reserved, 4 bytes, all zero.
     return bitmapCodec;
 }
 private static TS_BITMAPCODEC CreateTS_BITMAPCODEC_NSCodec()
 {
     TS_BITMAPCODEC bitmapCodec = new TS_BITMAPCODEC();
     bitmapCodec.codecGUID.codecGUID1 = 0xCA8D1BB9;
     bitmapCodec.codecGUID.codecGUID2 = 0x000F;
     bitmapCodec.codecGUID.codecGUID3 = 0x154F;
     bitmapCodec.codecGUID.codecGUID4 = 0x58;
     bitmapCodec.codecGUID.codecGUID5 = 0x9F;
     bitmapCodec.codecGUID.codecGUID6 = 0xAE;
     bitmapCodec.codecGUID.codecGUID7 = 0x2D;
     bitmapCodec.codecGUID.codecGUID8 = 0x1A;
     bitmapCodec.codecGUID.codecGUID9 = 0x87;
     bitmapCodec.codecGUID.codecGUID10 = 0xE2;
     bitmapCodec.codecGUID.codecGUID11 = 0xD6;
     bitmapCodec.codecID = 0;
     bitmapCodec.codecPropertiesLength = 3;
     bitmapCodec.codecProperties = new byte[3];
     bitmapCodec.codecProperties[0] = 0x01; //fAllowDynamicFidelity
     bitmapCodec.codecProperties[1] = 0x01; //fAllowSubsampling
     bitmapCodec.codecProperties[2] = 0x03; //colorLossLevel
     return bitmapCodec;
 }
 /// <summary>
 /// Generate a random bitmap codec structure used for test
 /// </summary>
 /// <returns></returns>
 private TS_BITMAPCODEC GenerateBitmapCodedcForTest()
 {
     TS_BITMAPCODEC bitmapCodec = new TS_BITMAPCODEC();
     byte[] guidData = new byte[16];
     random.NextBytes(guidData);
     bitmapCodec.codecGUID.codecGUID1 = BitConverter.ToUInt32(guidData, 0);
     bitmapCodec.codecGUID.codecGUID2 = BitConverter.ToUInt16(guidData, 4);
     bitmapCodec.codecGUID.codecGUID3 = BitConverter.ToUInt16(guidData, 6);
     bitmapCodec.codecGUID.codecGUID4 = guidData[8];
     bitmapCodec.codecGUID.codecGUID5 = guidData[9];
     bitmapCodec.codecGUID.codecGUID6 = guidData[10];
     bitmapCodec.codecGUID.codecGUID7 = guidData[11];
     bitmapCodec.codecGUID.codecGUID8 = guidData[12];
     bitmapCodec.codecGUID.codecGUID9 = guidData[13];
     bitmapCodec.codecGUID.codecGUID10 = 0xFF; // Specify this field to a constant value, prevent the random GUID coincidentally same as a real codec GUID.
     bitmapCodec.codecGUID.codecGUID11 = guidData[15];
     bitmapCodec.codecPropertiesLength = (ushort)random.Next(2, 10);
     if (bitmapCodec.codecPropertiesLength != 0)
     {
         bitmapCodec.codecProperties = new byte[bitmapCodec.codecPropertiesLength];
         random.NextBytes(bitmapCodec.codecProperties);
     }
     return bitmapCodec;
 }
        /// <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>
        /// Parse TS_BITMAPCODEC
        /// (parser index is updated according to parsed length)
        /// </summary>
        /// <param name="data">data to be parsed</param>
        /// <param name="currentIndex">current parser index</param>
        /// <returns>TS_BITMAPCODEC</returns>
        private TS_BITMAPCODEC ParseTsBitmapCodec(byte[] data, ref int currentIndex)
        {
            TS_BITMAPCODEC codec = new TS_BITMAPCODEC();

            // TS_BITMAPCODEC: codecGUID
            codec.codecGUID = ParseTsBitmapCodecGuid(data, ref currentIndex);

            // TS_BITMAPCODEC: codecID
            codec.codecID = ParseByte(data, ref currentIndex);

            // TS_BITMAPCODEC: codecPropertiesLength
            codec.codecPropertiesLength = ParseUInt16(data, ref currentIndex, false);

            // TS_BITMAPCODEC: codecProperties
            codec.codecProperties = GetBytes(data, ref currentIndex, (int)codec.codecPropertiesLength);

            return codec;
        }