/// <summary>
        /// return an index page according to the inputs
        /// </summary>
        /// <returns></returns>
        public ActionResult IndexWithInputs()
        {
            dynamic obj = GetJsonObject(Request.InputStream);

            // retrieve the quant
            QuantizationFactorsArray quantArray = JsonHelper.RetrieveQuantsArray(obj.Params.QuantizationFactorsArray);
            EntropyAlgorithm         algorithm  = JsonHelper.CastTo <EntropyAlgorithm>(obj.Params.EntropyAlgorithm);


            _viewModel = new RFXDecodeViewModel();
            // Updates parameters
            ((RFXDecodeViewModel)_viewModel).ProvideParam(quantArray, algorithm);
            Triplet <string> triplet = JsonHelper.RetrieveTriplet(obj.Inputs);

            ((RFXDecodeViewModel)_viewModel).ProvidePanelInputs(triplet.ToArray());

            var envValues = new Dictionary <string, object>()
            {
                { ModelKey, _viewModel },
                { isModelValid, true }
            };

            SaveToSession(envValues);

            return(new HttpStatusCodeResult(HttpStatusCode.OK));
        }
        /// <summary>
        /// Using RDPRFX to send image whose resolution is Width x Height
        /// </summary>
        /// <param name="imagefile">Image to send</param>
        /// <param name="width">Width of image to send</param>
        /// <param name="height">Height of image to send</param>
        public bool RdprfxSendImage(Image image, ushort width, ushort height)
        {
            uint             frameId     = 0; //The index of the sending frame.
            OperationalMode  opMode      = OperationalMode.ImageMode;
            EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR1;
            ushort           destLeft    = 0; //the left bound of the frame.
            ushort           destTop     = 0; //the top bound of the frame.

            // Crop Image
            Bitmap    bitmap   = new Bitmap(width, height);
            Graphics  graphics = Graphics.FromImage(bitmap);
            Rectangle section  = new Rectangle(0, 0, width, height);

            graphics.DrawImage(image, 0, 0, section, GraphicsUnit.Pixel);

            //Check if the above setting is supported by the client.
            if (!this.rdprfxAdapter.CheckIfClientSupports(opMode, enAlgorithm))
            {
                return(false);
            }
            rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_BEGIN, frameId);

            rdprfxAdapter.SendImageToClient(bitmap, opMode, enAlgorithm, destLeft, destTop);
            rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_END, frameId);
            rdprfxAdapter.ExpectTsFrameAcknowledgePdu(frameId, waitTime);
            return(true);
        }
        private bool rdprfxNegativeTest(RdprfxNegativeType negType)
        {
            StartRDPConnection();

            this.rdprfxAdapter.SetTestType(negType);

            #region Fill parameters
            TS_RFX_ICAP[] clientSupportedCaps;
            rdprfxAdapter.ReceiveAndCheckClientCapabilities(maxRequestSize, out clientSupportedCaps);

            OperationalMode  opMode      = OperationalMode.ImageMode;
            EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR3;
            ushort           destLeft    = 0; //the left bound of the frame.
            ushort           destTop     = 0; //the top bound of the frame.

            //Set OperationalMode/EntropyAlgorithm to valid pair.
            if (clientSupportedCaps != null)
            {
                opMode      = (OperationalMode)clientSupportedCaps[0].flags;
                enAlgorithm = (EntropyAlgorithm)clientSupportedCaps[0].entropyBits;
            }
            #endregion

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending one frame of encoded bitmap data to client. Operational Mode = {0}, Entropy Algorithm = {1}, destLeft = {2}, destTop = {3}.",
                                  opMode, enAlgorithm, destLeft, destTop);
            this.rdprfxAdapter.SendImageToClient(image_64X64, opMode, enAlgorithm, destLeft, destTop);

            bool fDisconnected = this.rdpbcgrAdapter.WaitForDisconnection(waitTime);

            StopRDPConnection();

            return(fDisconnected);
        }
        /// <summary>
        /// Method to create TS_RFX_CONTEXT.
        /// </summary>
        /// <param name="isImageMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        public TS_RFX_CONTEXT CreateTsRfxContext(OperationalMode opMode, EntropyAlgorithm entropy)
        {
            TS_RFX_CONTEXT rfxContext = new TS_RFX_CONTEXT();
            rfxContext.CodecChannelT = new TS_RFX_CODEC_CHANNELT();
            rfxContext.CodecChannelT.blockType = blockType_Value.WBT_CONTEXT;
            rfxContext.CodecChannelT.blockLen = 13;
            rfxContext.CodecChannelT.codecId = 0x01;
            rfxContext.CodecChannelT.channelId = 0x00;
            rfxContext.ctxId = 0x00;
            rfxContext.tileSize = 0x0040;

            ushort flags = 0x0002;
            if (opMode == OperationalMode.VideoMode) flags = 0x0000;
            ushort cct = 0x0001;
            ushort xft = 0x0001;
            ushort et = 0x0001;
            if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3) et = 0x0004;
            ushort qt = 0x0001;
            ushort r = 0x0000;

            rfxContext.properties = 0x0000;
            rfxContext.properties |= flags;
            rfxContext.properties |= (ushort)(cct << 3);
            rfxContext.properties |= (ushort)(xft << 5);
            rfxContext.properties |= (ushort)(et << 9);
            rfxContext.properties |= (ushort)(qt << 13);
            rfxContext.properties |= (ushort)(r << 15);

            return rfxContext;
        }
        public async Task <IActionResult> IndexWithInputs()
        {
            try
            {
                using (var bodyStream = new StreamReader(Request.Body))
                {
                    var bodyText = await bodyStream.ReadToEndAsync();

                    dynamic obj = JsonConvert.DeserializeObject(bodyText);

                    // retrieve the quant
                    QuantizationFactorsArray quantArray = JsonHelper.RetrieveQuantsArray(obj.Params.QuantizationFactorsArray);
                    EntropyAlgorithm         algorithm  = JsonHelper.CastTo <EntropyAlgorithm>(obj.Params.EntropyAlgorithm);

                    _viewModel = new RFXDecodeViewModel();
                    // Updates parameters
                    ((RFXDecodeViewModel)_viewModel).ProvideParam(quantArray, algorithm);
                    Triplet <string> triplet = JsonHelper.RetrieveTriplet(obj.Inputs);
                    ((RFXDecodeViewModel)_viewModel).ProvidePanelInputs(triplet.ToArray());

                    var envValues = new Dictionary <string, object>()
                    {
                        { ModelKey, _viewModel },
                        { isModelValid, true }
                    };

                    SaveToSession(envValues);
                }
                return(Json(ReturnResult <string> .Success("Success")));
            }
            catch (Exception ex)
            {
                return(Json(ReturnResult <string> .Fail(ex.Message)));
            }
        }
        /// <summary>
        /// Method to send TS_RFX_CONTEXT to client.
        /// </summary>
        /// <param name="isImageMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        public void SendTsRfxContext(OperationalMode opMode, EntropyAlgorithm entropy)
        {
            this.admEntropyAlgorithm = entropy;
            this.admOperationMode    = opMode;

            TS_RFX_CONTEXT rfxContext = rdprfxServer.CreateTsRfxContext(opMode, entropy);

            if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidCtxId)
            {
                rfxContext.ctxId = 0x01; //set to an invalid value other than 0x00.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidTileSize)
            {
                rfxContext.tileSize = 0x0080; //set to an invalid value other than 0x0040.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidCct)
            {
                rfxContext.properties &= 0xFFF7; //set "cct" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidXft)
            {
                rfxContext.properties &= 0xFE1F; //set "xft" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidQt)
            {
                rfxContext.properties &= 0x9FFF; //set "qt" to an invalid value: 0x0.
            }

            AddToPendingList(rfxContext);
        }
Example #7
0
        public static void RLGREncode(short[] input, EntropyAlgorithm mode, out byte[] output)
        {
            var rfxMode     = (Microsoft.Protocols.TestTools.StackSdk.RemoteDesktop.Rdprfx.EntropyAlgorithm)mode.Algorithm;
            var RLGREncoder = new RLGREncoder();

            output = RLGREncoder.Encode(input, rfxMode);
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="tsRfxCodecQuant"></param>
 /// <param name="mode"></param>
 public RemoteFXCodecContext(TS_RFX_CODEC_QUANT tsRfxCodecQuant, EntropyAlgorithm mode)
 {
     this.CodecQuantVals = new TS_RFX_CODEC_QUANT[] { tsRfxCodecQuant };
     this.QuantIdxY      = 0;
     this.QuantIdxCb     = 0;
     this.QuantIdxCr     = 0;
     this.Mode           = mode;
 }
        public static void RLGRDecode(byte[] input, EntropyAlgorithm mode, out short[] output)
        {
            var rfxMode     = (Microsoft.Protocols.TestTools.StackSdk.RemoteDesktop.Rdprfx.EntropyAlgorithm)mode.Algorithm;
            var RLGRDecoder = new RLGRDecoder();
            int comLength   = RdpegfxTileUtils.TileSize * RdpegfxTileUtils.TileSize;

            output = RLGRDecoder.Decode(input, rfxMode, comLength);
        }
Example #10
0
 /// <summary>
 /// ALGR decode the input data.
 /// </summary>
 /// <param name="encodedData">The input data to be decoded.</param>
 /// <param name="rlgrMode">The RLGR mode.</param>
 /// <param name="lengthToDecode">The expected decoding size.</param>
 /// <returns></returns>
 public short[] Decode(byte[] encodedData, EntropyAlgorithm rlgrMode, int lengthToDecode)
 {
     encodedBytes = encodedData;
     //bitsToDecode = new BitArray(encodedData);
     dataOffset  = 0;
     decodedList = new List <short>();
     this.RLGR_Decode(rlgrMode, lengthToDecode);
     return(decodedList.ToArray());
 }
 /// <summary>
 /// ALGR decode the input data.
 /// </summary>
 /// <param name="encodedData">The input data to be decoded.</param>
 /// <param name="rlgrMode">The RLGR mode.</param>
 /// <param name="lengthToDecode">The expected decoding size.</param>
 /// <returns></returns>
 public short[] Decode(byte[] encodedData, EntropyAlgorithm rlgrMode, int lengthToDecode)
 {
     encodedBytes = encodedData;
     //bitsToDecode = new BitArray(encodedData);
     dataOffset = 0;
     decodedList = new List<short>();
     this.RLGR_Decode(rlgrMode, lengthToDecode);
     return decodedList.ToArray();
 }
        public static void RLGRDecode(Triplet <byte[]> input, EntropyAlgorithm mode, bool useReduceExtrapolate, out Triplet <short[]> output)
        {
            var outlist = new List <short[]>();

            foreach (var component in input)
            {
                short[] decodedComponent;
                RFXDecoderWrapper.RLGRDecode(component, mode, out decodedComponent);
                ComputeOriginalLL3FromDeltas(decodedComponent, useReduceExtrapolate);
                outlist.Add(decodedComponent);
            }
            output = new Triplet <short[]>(outlist[0], outlist[1], outlist[2]);
        }
        /// <summary>
        /// Method to send an image to the client.
        /// </summary>
        /// <param name="image">The image to be sent.</param>
        /// <param name="destLeft">The left bound of the frame.</param>
        /// <param name="destTop">The top bound of the frame.</param>
        /// <param name="frameId">The index of the sending frame.</param>
        public static void SendImageToClient(Image image, ushort destLeft, ushort destTop, uint frameId)
        {
            OperationalMode  opMode      = OperationalMode.ImageMode;
            EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR1;

            Site.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (Begin) with frameID: {0}.", frameId);
            rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_BEGIN, frameId);

            Site.Log.Add(LogEntryKind.Comment, "Sending encoded bitmap data to client. Operational Mode = {0}, Entropy Algorithm = {1}, destLeft = {2}, destTop = {3}.",
                         opMode, enAlgorithm, destLeft, destTop);
            rdprfxAdapter.SendImageToClient(image, opMode, enAlgorithm, destLeft, destTop);

            Site.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (End) with frameID: {0}.", frameId);
            rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_END, frameId);
        }
        /// <summary>
        /// Do ALGR encode to the input data.
        /// </summary>
        /// <param name="inputArr">Input data to be encoded.</param>
        /// <param name="mode">The ALGR mode, can be RLGR1 or RLGR3.</param>
        /// <returns>The encoded data.</returns>
        public byte[] Encode(short[] inputArr, EntropyAlgorithm mode)
        {
            inputData = inputArr;
            nextInputIdx = 0;
            bufferOffset = 0; //offset&0xFFFFFFF8 = byte offset, offset&0x7 = bit offset
            pBuffer = new byte[inputArr.Length];

            RLGR_Encode(mode);
            int numbytes = bufferOffset >> 3;
            int bitOffset = bufferOffset & 7;
            if (bitOffset != 0) numbytes++;

            byte[] encodedBytes = new byte[numbytes];
            Array.Copy(pBuffer, encodedBytes, encodedBytes.Length);
            return encodedBytes;
        }
        public ActionResult IndexWithInputs()
        {
            dynamic obj = GetJsonObject(Request.InputStream);

            foreach (var input in obj)
            {
                // TODO: refine this
                if (input != null && input.Inputs != null)
                {
                    int layer = JsonHelper.CastTo <int>(input.Layer);
                    if (layer == 0)
                    {
                        // TODO: refine this
                        // retrieve the quant
                        var quantArray = JsonHelper.RetrieveQuantsArray(input.Params.QuantizationFactorsArray);
                        // retrive the progressive quants
                        var progQuantList = new List <QuantizationFactorsArray>();
                        foreach (var layerQuant in input.Params.ProgQuantizationArray)
                        {
                            var layerQuants = JsonHelper.RetrieveQuantsArray(layerQuant);
                            progQuantList.Add(layerQuants);
                        }
                        var progQuantarray = new ProgressiveQuantizationFactors
                        {
                            ProgQuants = progQuantList
                        };

                        EntropyAlgorithm     algorithm            = JsonHelper.CastTo <EntropyAlgorithm>(input.Params.EntropyAlgorithm);
                        UseDifferenceTile    useDifferenceTile    = JsonHelper.CastTo <UseDifferenceTile>(input.Params.UseDifferenceTile);
                        UseReduceExtrapolate useReduceExtrapolate = JsonHelper.CastTo <UseReduceExtrapolate>(input.Params.UseReduceExtrapolate);

                        _viewModel = new RFXPDecodeViewModel(0);
                        ((RFXPDecodeViewModel)_viewModel).ProvideParam(quantArray, progQuantarray, algorithm, useDifferenceTile, useReduceExtrapolate);
                        ((RFXPDecodeViewModel)_viewModel).ProvidePanelInputs(layer, input.Inputs[0], input.Inputs[1], input.Inputs[2]);

                        Session[ModelKey]        = _viewModel;
                        Session[isPreFrameValid] = true;
                    }
                    Decode(input);
                    // Updates Decode Status
                    UpdateDecodeStatus(layer);
                }
            }
            Session[IsValid] = true;
            return(new HttpStatusCodeResult(HttpStatusCode.OK));
        }
        /// <summary>
        /// Method to send TS_RFX_TILESET to client.
        /// </summary>
        /// <param name="opMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        /// <param name="tileImages">The image array for tiles to be sent. The width and height must be less than or equals with 64.</param>
        /// <param name="positions">A TILE_POSITION array indicating the positions of each tile images</param>
        /// <param name="codecQuantVals">Quant values array</param>
        /// <param name="quantIdxYs">Index array of Y component in Quant value array</param>
        /// <param name="quantIdxCbs">Index array of Cb component in Quant value array</param>
        /// <param name="quantIdxCrs">Index array of Cr component in Quant value array</param>
        public void SendTsRfxTileSet(OperationalMode opMode, EntropyAlgorithm entropy, Image[] tileImages, TILE_POSITION[] positions,
                                     TS_RFX_CODEC_QUANT[] codecQuantVals = null, byte[] quantIdxYs = null, byte[] quantIdxCbs = null, byte[] quantIdxCrs = null)
        {
            this.admEntropyAlgorithm = entropy;
            this.admOperationMode    = opMode;
            TS_RFX_TILESET rfxTileSet = rdprfxServer.CreateTsRfxTileSet(opMode, entropy, tileImages, positions, codecQuantVals, quantIdxYs, quantIdxCbs, quantIdxCrs);

            if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidIdx)
            {
                rfxTileSet.idx = 0x0001; //set to an invalid value other than 0x0000.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidLt)
            {
                rfxTileSet.properties &= 0xFFFE; //set "lt" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidCct)
            {
                rfxTileSet.properties &= 0xFFCF; //set "cct" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidXft)
            {
                rfxTileSet.properties &= 0xFC3F; //set "xft" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidQt)
            {
                rfxTileSet.properties &= 0x3FFF; //set "xft" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidTileSize)
            {
                rfxTileSet.tileSize = 0x80; //set to an invalid value other than 0x40.
            }

            if (this.rdpbcgrAdapter.SimulatedScreen != null)
            {
                this.rdpbcgrAdapter.SimulatedScreen.SetRemoteFXTileSet(rfxTileSet, entropy);
            }

            AddToPendingList(rfxTileSet);
            if (!CheckIfClientSupports(opMode, entropy))
            {
                Site.Log.Add(LogEntryKind.Debug, "The client Cap is not supported: OperationalMode = {0}, EntropyAlgorithm = {1}",
                             opMode.ToString(),
                             entropy.ToString());
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="tsRfxCodecQuantVals"></param>
        /// <param name="quantIdxY"></param>
        /// <param name="quantIdxCb"></param>
        /// <param name="quantIdxCr"></param>
        /// <param name="mode"></param>
        public RemoteFXCodecContext(TS_RFX_CODEC_QUANT[] tsRfxCodecQuantVals, byte quantIdxY, byte quantIdxCb, byte quantIdxCr, EntropyAlgorithm mode)
        {
            if (tsRfxCodecQuantVals == null || tsRfxCodecQuantVals.Length == 0)
            {
                throw new ArgumentException("Parameter tsRfxCodecQuantVals cannot be null and its length must larger than 0.");
            }
            int maxIndex = tsRfxCodecQuantVals.Length - 1;

            if (quantIdxY > maxIndex || quantIdxCb > maxIndex || quantIdxCr > maxIndex)
            {
                throw new ArgumentException("Quant index for Y , Cb or Cr is/are larger than the size of tsRfxCodecQuantVals.");
            }
            this.CodecQuantVals = tsRfxCodecQuantVals;
            this.QuantIdxY      = quantIdxY;
            this.QuantIdxCb     = quantIdxCb;
            this.QuantIdxCr     = quantIdxCr;
            this.Mode           = mode;
        }
Example #18
0
        /// <summary>
        /// Copy from RDPRFX test suite code
        /// </summary>
        private void receiveAndLogClientRfxCapabilites()
        {
            uint maxRequestSize = 38055; // MS-RDPBCGR section 2.2.7.2.7

            TS_RFX_ICAP[] clientRfxCaps;

            this.TestSite.Log.Add(LogEntryKind.Comment, "Receive and check client capabilities...");
            rdprfxAdapter.ReceiveAndCheckClientCapabilities(maxRequestSize, out clientRfxCaps);

            if (clientRfxCaps != null)
            {
                foreach (TS_RFX_ICAP iCap in clientRfxCaps)
                {
                    OperationalMode  opMode = (OperationalMode)iCap.flags;
                    EntropyAlgorithm enAlg  = (EntropyAlgorithm)iCap.entropyBits;
                    this.TestSite.Log.Add(LogEntryKind.Comment, "Client supports ({0}, {1}).", opMode, enAlg);
                }
            }
        }
        /// <summary>
        /// Do ALGR encode to the input data.
        /// </summary>
        /// <param name="inputArr">Input data to be encoded.</param>
        /// <param name="mode">The ALGR mode, can be RLGR1 or RLGR3.</param>
        /// <returns>The encoded data.</returns>
        public byte[] Encode(short[] inputArr, EntropyAlgorithm mode)
        {
            inputData    = inputArr;
            nextInputIdx = 0;
            bufferOffset = 0; //offset&0xFFFFFFF8 = byte offset, offset&0x7 = bit offset
            pBuffer      = new byte[inputArr.Length];

            RLGR_Encode(mode);
            int numbytes  = bufferOffset >> 3;
            int bitOffset = bufferOffset & 7;

            if (bitOffset != 0)
            {
                numbytes++;
            }

            byte[] encodedBytes = new byte[numbytes];
            Array.Copy(pBuffer, encodedBytes, encodedBytes.Length);
            return(encodedBytes);
        }
 /// <summary>
 /// Method to check if the input pair of the operation mode and entropy algorithm is supported by the client.
 /// </summary>
 /// <param name="opMode">The operation mode.</param>
 /// <param name="entropy">The entropy algorithm.</param>
 /// <returns></returns>
 public bool CheckIfClientSupports(OperationalMode opMode, EntropyAlgorithm entropy)
 {
     TS_RFX_ICAP[] iCaps = this.client_RFX_Caps_Container.capsData.capsetsData[0].icapsData;
     foreach (TS_RFX_ICAP icap in iCaps)
     {
         if ((icap.flags & (byte)OperationalMode.ImageMode) == (byte)0 &&
             ((byte)icap.entropyBits == (byte)entropy))
         {
             //OperationalMode.ImageMode is not set, both the image mode and the video mode of the codec are supported
             return(true);
         }
         else if ((byte)icap.entropyBits == (byte)entropy)
         {
             //OperationalMode.ImageMode is set, only image mode is supported
             if (opMode == OperationalMode.ImageMode)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Example #21
0
        /// <summary>
        /// Method to create TS_RFX_CONTEXT.
        /// </summary>
        /// <param name="isImageMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        public TS_RFX_CONTEXT CreateTsRfxContext(OperationalMode opMode, EntropyAlgorithm entropy)
        {
            TS_RFX_CONTEXT rfxContext = new TS_RFX_CONTEXT();

            rfxContext.CodecChannelT           = new TS_RFX_CODEC_CHANNELT();
            rfxContext.CodecChannelT.blockType = blockType_Value.WBT_CONTEXT;
            rfxContext.CodecChannelT.blockLen  = 13;
            rfxContext.CodecChannelT.codecId   = 0x01;
            rfxContext.CodecChannelT.channelId = 0xFF;
            rfxContext.ctxId    = 0x00;
            rfxContext.tileSize = 0x0040;

            ushort flags = 0x0002;

            if (opMode == OperationalMode.VideoMode)
            {
                flags = 0x0000;
            }
            ushort cct = 0x0001;
            ushort xft = 0x0001;
            ushort et  = 0x0001;

            if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3)
            {
                et = 0x0004;
            }
            ushort qt = 0x0001;
            ushort r  = 0x0000;

            rfxContext.properties  = 0x0000;
            rfxContext.properties |= flags;
            rfxContext.properties |= (ushort)(cct << 3);
            rfxContext.properties |= (ushort)(xft << 5);
            rfxContext.properties |= (ushort)(et << 9);
            rfxContext.properties |= (ushort)(qt << 13);
            rfxContext.properties |= (ushort)(r << 15);

            return(rfxContext);
        }
        public void Rdprfx_HeaderMessage_PositiveTest_OrderTest_VersionsContextChannels()
        {
            #region Test Description
            /*
            Step 1: [RDPBCGR] establishing the connection.
            Step 2: [RDPBCGR] send Frame Maker Command (Begin) to SUT.
            Step 3: [RDPRFX] Send Encode Header Messages to SUT in order of TS_RFX_SYNC -> TS_RFX_VERSIONS -> TS_RFX_CONTEXT -> TS_RFX_CHANNELS.
            Step 4: [RDPRFX] Send one frame of Encode Data Messages to SUT.
            Step 5: [RDPBCGR] send Frame Maker Command (End) to SUT.
            Step 6: [RDPRFX] Expect SUT sends a TS_FRAME_ACKNOWLEDGE_PDU.
            */
            #endregion

            #region Test Sequence

            //Start RDP listening.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening.");
            this.rdpbcgrAdapter.StartRDPListening(transportProtocol);

            #region Trigger client to connect
            //Trigger client to connect. 
            this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server.");
            triggerClientRDPConnect(transportProtocol);
            #endregion

            #region RDPBCGR Connection

            //Waiting for the transport level connection request.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request.");
            this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal);

            
            //Set Server Capability with RomoteFX codec supported.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability.");
            setServerCapabilitiesWithRemoteFxSupported();

            //Waiting for the RDP connection sequence.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Establishing RDP connection.");
            this.rdpbcgrAdapter.EstablishRDPConnection(selectedProtocol, enMethod, enLevel, true, false, rdpServerVersion);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server Save Session Info PDU to SUT to notify user has logged on.");
            this.rdpbcgrAdapter.ServerSaveSessionInfo(LogonNotificationType.UserLoggedOn, ErrorNotificationType_Values.LOGON_FAILED_OTHER);

            #endregion

            //Initial the RDPRFX adapter context.
            rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext);

            TS_RFX_ICAP[] clientSupportedCaps;
            rdprfxAdapter.ReceiveAndCheckClientCapabilities(maxRequestSize, out clientSupportedCaps);

            uint frameId = 0; //The index of the sending frame.
            OperationalMode opMode = OperationalMode.ImageMode;
            EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR3;
            ushort destLeft = 0; //the left bound of the frame.
            ushort destTop = 0; //the top bound of the frame.

            //Set OperationalMode/EntropyAlgorithm to valid pair.
            if (clientSupportedCaps != null)
            {
                opMode = (OperationalMode)clientSupportedCaps[0].flags;
                enAlgorithm = (EntropyAlgorithm)clientSupportedCaps[0].entropyBits;
            }

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (Begin) with frameID: {0}.", frameId);
            rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_BEGIN, frameId);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending one frame of encoded bitmap data to client. Operational Mode = {0}, Entropy Algorithm = {1}, destLeft = {2}, destTop = {3}.",
                opMode, enAlgorithm, destLeft, destTop);

            this.TestSite.Log.Add(LogEntryKind.Comment,
                "Sending the encode header messages in the order of TS_RFX_SYNC -> TS_RFX_VERSIONS -> TS_RFX_CONTEXT -> TS_RFX_CHANNELS.");
            rdprfxAdapter.SendTsRfxSync();
            rdprfxAdapter.SendTsRfxCodecVersions();
            rdprfxAdapter.SendTsRfxContext(opMode, enAlgorithm);
            rdprfxAdapter.SendTsRfxChannels();

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending the encode data messages to client.");
            rdprfxAdapter.SendTsRfxFrameBegin(0);
            rdprfxAdapter.SendTsRfxRegion();
            rdprfxAdapter.SendTsRfxTileSet(opMode, enAlgorithm, image_64X64);
            rdprfxAdapter.SendTsRfxFrameEnd();
            rdprfxAdapter.FlushEncodedData(destLeft, destTop);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (End) with frameID: {0}.", frameId);
            rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_END, frameId);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting TS_FRAME_ACKNOWLEDGE_PDU.");
            rdprfxAdapter.ExpectTsFrameAcknowledgePdu(frameId, waitTime);
            #endregion
        } 
        public void Rdprfx_HeaderMessage_NegativeTest_UnspecifiedMessage()
        {
            #region Test Description
            /*
            Step 1: [RDPBCGR] establish the RDP connection.
            Step 2: [RDPRFX] send one unspecified message to client.
            Step 3: [RDPRFX] expect SUT terminate the RDP connectioin.
            */
            #endregion

            #region Test Sequence

            //Start RDP listening.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening.");
            this.rdpbcgrAdapter.StartRDPListening(transportProtocol);

            #region Trigger client to connect
            //Trigger client to connect. 
            this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server.");
            triggerClientRDPConnect(transportProtocol);
            #endregion

            #region RDPBCGR Connection

            //Waiting for the transport level connection request.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request.");
            this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal);


            //Set Server Capability with RomoteFX codec supported.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability.");
            setServerCapabilitiesWithRemoteFxSupported();

            //Waiting for the RDP connection sequence.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Establishing RDP connection.");
            this.rdpbcgrAdapter.EstablishRDPConnection(selectedProtocol, enMethod, enLevel, true, false, rdpServerVersion);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server Save Session Info PDU to SUT to notify user has logged on.");
            this.rdpbcgrAdapter.ServerSaveSessionInfo(LogonNotificationType.UserLoggedOn, ErrorNotificationType_Values.LOGON_FAILED_OTHER);

            #endregion

            //Initial the RDPRFX adapter context.
            rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext);

            #region Fill parameters
            TS_RFX_ICAP[] clientSupportedCaps;
            rdprfxAdapter.ReceiveAndCheckClientCapabilities(maxRequestSize, out clientSupportedCaps);

            OperationalMode opMode = OperationalMode.ImageMode;
            EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR3;
            ushort destLeft = 0; //the left bound of the frame.
            ushort destTop = 0; //the top bound of the frame.

            //Set OperationalMode/EntropyAlgorithm to valid pair.
            if (clientSupportedCaps != null)
            {
                opMode = (OperationalMode)clientSupportedCaps[0].flags;
                enAlgorithm = (EntropyAlgorithm)clientSupportedCaps[0].entropyBits;
            }
            #endregion

            this.TestSite.Log.Add(LogEntryKind.Comment, "Set the test type to {0}.", RdprfxNegativeType.UnspecifiedBlockType);
            rdprfxAdapter.SetTestType(RdprfxNegativeType.UnspecifiedBlockType);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Encode Header/Data Messages to client.");
            rdprfxAdapter.SendImageToClient(image_64X64, opMode, enAlgorithm, destLeft, destTop);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the client terminates the RDP connection.");
            bool bDisconnected = rdpbcgrAdapter.WaitForDisconnection(waitTime);

            this.TestSite.Assert.IsTrue(bDisconnected, "Client is expected to drop the connection when received an invalid message.");

            #endregion
        }
        public void Rdprfx_VerifyClientCapabilities()
        {
            #region Test Description

            /*
             * Step 1: trigger SUT initial a connection request.
             * Step 2: continue the connection until Capabilities Exchange phase.
             * Step 3: server sends Demand Active PDU to SUT.
             * Step 4: Expect SUT responds a Confirm Active PDU and verify this PDU.
             */
            #endregion

            #region Test Sequence

            //Start RDP listening.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening.");
            this.rdpbcgrAdapter.StartRDPListening(transportProtocol);

            #region Trigger client to connect
            //Trigger client to connect.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server.");
            triggerClientRDPConnect(transportProtocol);
            #endregion

            #region Connection initialization phase

            //Waiting for the transport level connection request.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request.");
            this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal);

            #region Connection Initiation phase
            //Expect SUT send a Client X.224 Connection Request PDU.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Client X.224 Connection Request PDU");
            this.rdpbcgrAdapter.ExpectPacket <Client_X_224_Connection_Request_Pdu>(waitTime);

            //Respond a Server X.224 Connection Confirm PDU and set the EXTENDED_CLIENT_DATA_SUPPORTED flag.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server X.224 Connection Confirm PDU to SUT. Selected protocol: {0}; Extended Client Data supported: true", selectedProtocol.ToString());
            this.rdpbcgrAdapter.Server_X_224_Connection_Confirm(selectedProtocol, true, true, NegativeType.None);
            #endregion

            #region Basic Setting Exchange phase
            //Expect SUT send Client MCS Connect Initial PDU.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Client MCS Connect Initial PDU.");
            this.rdpbcgrAdapter.ExpectPacket <Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request>(waitTime);

            //Respond a Server MCS Connect Response PDU with GCC Conference Create Response.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server MCS Connect Response PDU to SUT. Encryption Method {0}; Encryption Level: {1}; RDP Version Code: {2}.", enMethod.ToString(), enLevel.ToString(), TS_UD_SC_CORE_version_Values.V2.ToString());
            this.rdpbcgrAdapter.Server_MCS_Connect_Response(enMethod, enLevel, TS_UD_SC_CORE_version_Values.V2, NegativeType.None);
            #endregion

            #region Channel Connection phase
            //Expect a Client MCS Erect Domain Request PDU.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Client MCS Erect Domain Request PDU.");
            this.rdpbcgrAdapter.ExpectPacket <Client_MCS_Erect_Domain_Request>(waitTime);

            //Expect a Client MCS Attach User Request PDU
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Client MCS Attach User Request PDU.");
            this.rdpbcgrAdapter.ExpectPacket <Client_MCS_Attach_User_Request>(waitTime);

            //Respond a Server MCS Channel Join Confirm PDU.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server MCS Channel Join Confirm PDU to SUT.");
            this.rdpbcgrAdapter.MCSAttachUserConfirm(NegativeType.None);

            //Expect SUT start a channel join sequence
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expect SUT to start the  channel join sequence.");
            this.rdpbcgrAdapter.ChannelJoinRequestAndConfirm(NegativeType.None);
            #endregion

            #region RDP Security Commencement phase
            //Expects SUT continue the connection by sending a Client Security Exchange PDU
            //(if Standard RDP Security mechanisms are being employed) or a Client Info PDU.
            if (transportProtocol == EncryptedProtocol.Rdp)
            {
                this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send Client a Security Exchange PDU.");
                this.rdpbcgrAdapter.ExpectPacket <Client_Security_Exchange_Pdu>(waitTime);
            }
            #endregion

            #region Secure Setting Exchange phase
            //Expect a Client Info PDU.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send Client a Client Info PDU.");
            this.rdpbcgrAdapter.ExpectPacket <Client_Info_Pdu>(waitTime);
            #endregion

            #region Licensing phase
            //Send SUT a Server License Error Pdu - Valid Client.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending a Server License Error Pdu - Valid Client to SUT.");
            this.rdpbcgrAdapter.Server_License_Error_Pdu_Valid_Client(NegativeType.None);
            #endregion

            #region Capabilities Exchange phase
            //Set Server Capability with RomoteFX codec supported.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability. Server advertises the support for MS-RDPRFX.");
            setServerCapabilitiesWithRemoteFxSupported();

            //Send a Server Demand Active PDU to SUT.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending a Server Demand Active PDU to SUT.");
            this.rdpbcgrAdapter.Server_Demand_Active(NegativeType.None);

            //Expect SUT respond a Client Confirm Active PDU.
            //Once the Confirm Active PDU has been sent, the client can start sending input PDUs (see section 2.2.8) to the server.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Client Confirm Active PDU.");
            this.rdpbcgrAdapter.ExpectPacket <Client_Confirm_Active_Pdu>(waitTime);
            #endregion

            //Initial the RDPRFX adapter context.
            this.rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext);

            //Verify the Client capabilites.
            TS_RFX_ICAP[] supportedRfxCaps;
            this.rdprfxAdapter.ReceiveAndCheckClientCapabilities(maxRequestSize, out supportedRfxCaps);

            if (supportedRfxCaps != null)
            {
                foreach (TS_RFX_ICAP iCap in supportedRfxCaps)
                {
                    OperationalMode  opMode = (OperationalMode)iCap.flags;
                    EntropyAlgorithm enAlg  = (EntropyAlgorithm)iCap.entropyBits;
                    this.TestSite.Log.Add(LogEntryKind.Comment, "Client supports ({0}, {1}).", opMode, enAlg);
                }
            }

            #endregion

            #endregion
        }
        // The output format is
        // firstPass [X, Y, Z]
        // ProgressivePass1 [encodedX, encodedY, encodedZ]
        // ProgressivePass1 [rawX, rawY, rawZ]
        // ...
        public static void RLGR_SRLEncode(List <Triplet <short[]> > input, ProgressiveQuantizationFactors proQuants, EntropyAlgorithm mode, bool UseReduceExtrapolate, out List <Triplet <byte[]> > output)
        {
            output = new List <Triplet <byte[]> >();
            byte[] x, y, z;

            // fisrt pass
            Triplet <short[]> firstPass = input[0];

            ComputeLL3Deltas(firstPass, UseReduceExtrapolate);
            RFXEncode.RFXEncoderWrapper.RLGREncode(firstPass.X, mode, out x);
            RFXEncode.RFXEncoderWrapper.RLGREncode(firstPass.Y, mode, out y);
            RFXEncode.RFXEncoderWrapper.RLGREncode(firstPass.Z, mode, out z);
            output.Add(new Triplet <byte[]>(x, y, z));

            // fake encodingContext used for SRL encode
            var encodingContext = new RfxProgressiveCodecContext(new [] { RdpegfxTileUtils.GetCodecQuant(ImageQuality_Values.Midium) }, 0, 0, 0, UseReduceExtrapolate);

            encodingContext.DAS = new DwtTile(firstPass.X, firstPass.Y, firstPass.Z);

            var progQuantList = new List <RFX_PROGRESSIVE_CODEC_QUANT>();

            foreach (var quant in proQuants.ProgQuants)
            {
                progQuantList.Add(Utility.ConvertProgQuant(quant));
            }

            // progressive pass
            for (int i = 1; i < input.Count; i++)
            {
                Triplet <short[]> progressivePass = input[i];
                encodingContext.ProgQ         = new DwtTile(progressivePass.X, progressivePass.Y, progressivePass.Z);
                encodingContext.prevProgQuant = progQuantList[i - 1];
                EncodedTile encodedTile = SRLEncode(encodingContext, progQuantList[i]);
                output.Add(new Triplet <byte[]>(encodedTile.YEncodedData, encodedTile.CbEncodedData, encodedTile.CrEncodedData));
                output.Add(new Triplet <byte[]>(encodedTile.YRawData, encodedTile.CbRawData, encodedTile.CrRawData));
                encodingContext.DAS.Add(new DwtTile(progressivePass.X, progressivePass.Y, progressivePass.Z));
                encodingContext.prevProgQuant = progQuantList[i];
            }
        }
        /// <summary>
        /// Method to create TS_RFX_TILESET.
        /// </summary>
        /// <param name="opMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        /// <param name="tileImages">An array of bitmaps in Image type for a tile. The width and heigth must be less than or equals with 64.</param>
        /// <param name="positions">A TILE_POSITION array indicating the positions of each tile images</param>
        /// <param name="codecQuantVals">Quant values array</param>
        /// <param name="quantIdxYs">Index array of Y component in Quant value array</param>
        /// <param name="quantIdxCbs">Index array of Cb component in Quant value array</param>
        /// <param name="quantIdxCrs">Index array of Cr component in Quant value array</param>
        /// <returns></returns>
        public TS_RFX_TILESET CreateTsRfxTileSet(
            OperationalMode opMode,
            EntropyAlgorithm entropy,
            Image[] tileImages,
            TILE_POSITION[] positions,
            TS_RFX_CODEC_QUANT[] codecQuantVals = null,
            byte[] quantIdxYs = null,
            byte[] quantIdxCbs = null,
            byte[] quantIdxCrs = null
            )
        {
            if (codecQuantVals == null)
            {
                codecQuantVals = new TS_RFX_CODEC_QUANT[1];
                codecQuantVals[0] = codecQuant;
            }

            TS_RFX_TILESET rfxTileSet = new TS_RFX_TILESET();
            rfxTileSet.CodecChannelT = new TS_RFX_CODEC_CHANNELT();
            rfxTileSet.CodecChannelT.blockType = blockType_Value.WBT_EXTENSION;
            rfxTileSet.CodecChannelT.blockLen = 22 + 5;
            rfxTileSet.CodecChannelT.codecId = 0x01;
            rfxTileSet.CodecChannelT.channelId = 0x00;
            rfxTileSet.subtype = 0xCAC2;
            rfxTileSet.idx = 0x0000;

            ushort lt = 0x0001;
            ushort flags = 0x0002;
            if (opMode == OperationalMode.VideoMode) flags = 0x0000;
            ushort cct = 0x0001;
            ushort xft = 0x0001;
            ushort et = 0x0001;
            if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3) et = 0x0004;
            ushort qt = 0x0001;
            rfxTileSet.properties = lt;
            rfxTileSet.properties |= (ushort)(flags << 1);
            rfxTileSet.properties |= (ushort)(cct << 4);
            rfxTileSet.properties |= (ushort)(xft << 6);
            rfxTileSet.properties |= (ushort)(et << 10);
            rfxTileSet.properties |= (ushort)(qt << 14);

            rfxTileSet.numQuant = (byte)codecQuantVals.Length;
            rfxTileSet.tileSize = RdprfxServer.TileSize;
            rfxTileSet.numTiles = 1;

            rfxTileSet.quantVals = codecQuantVals;

            byte[] yData, cbData, crData;

            rfxTileSet.tiles = new TS_RFX_TILE[tileImages.Length];
            rfxTileSet.numTiles = (ushort) rfxTileSet.tiles.Length;

            for (int i = 0; i < tileImages.Length; i++)
            {
                byte quantIdxY = quantIdxYs == null ? (byte)0 : (quantIdxYs.Length > i ? quantIdxYs[i] : (byte)0);
                byte quantIdxCb = quantIdxCbs == null ? (byte)0 : (quantIdxCbs.Length > i ? quantIdxCbs[i] : (byte)0);
                byte quantIdxCr = quantIdxCrs == null ? (byte)0 : (quantIdxCrs.Length > i ? quantIdxCrs[i] : (byte)0);

                RemoteFXCodecContext encodingContext = new RemoteFXCodecContext(codecQuantVals, quantIdxY, quantIdxCb, quantIdxCr, entropy);
                RemoteFXEncoder.EncodeTile(tileImages[i], 0, 0, encodingContext);
                yData = encodingContext.YData;
                cbData = encodingContext.CbData;
                crData = encodingContext.CrData;

                rfxTileSet.tiles[i].BlockT.blockType = blockType_Value.CBT_TILE;
                rfxTileSet.tiles[i].BlockT.blockLen = (uint)(19 + yData.Length + cbData.Length + crData.Length);
                rfxTileSet.tiles[i].quantIdxY = quantIdxY;
                rfxTileSet.tiles[i].quantIdxCb = quantIdxCb;
                rfxTileSet.tiles[i].quantIdxCr = quantIdxCr;
                rfxTileSet.tiles[i].xIdx = positions[i].xIdx;
                rfxTileSet.tiles[i].yIdx = positions[i].yIdx;
                rfxTileSet.tiles[i].YLen = (ushort)yData.Length;
                rfxTileSet.tiles[i].CbLen = (ushort)cbData.Length;
                rfxTileSet.tiles[i].CrLen = (ushort)crData.Length;
                rfxTileSet.tiles[i].YData = yData;
                rfxTileSet.tiles[i].CbData = cbData;
                rfxTileSet.tiles[i].CrData = crData;

                rfxTileSet.tilesDataSize += rfxTileSet.tiles[i].BlockT.blockLen;
                rfxTileSet.CodecChannelT.blockLen = (uint)(22 + 5 * rfxTileSet.numQuant + rfxTileSet.tilesDataSize);
            }

            return rfxTileSet;
        }
        /// <summary>
        /// Pack a Rdprfx message for a tile image.
        /// </summary>
        /// <param name="index"> Frame index in frame begin block.</param>
        /// <param name="opMode"> Indicate Operational Mode.</param>
        /// <param name="entropy"> Indicate Entropy Algorithm.</param>
        /// <param name="tileImage"> The image to be encoded as RFX codec.</param>
        /// <return> A byte array of image encoded as RFX codec.</return>
        private byte[] PackRfxTileImage(uint index, OperationalMode opMode, EntropyAlgorithm entropy, System.Drawing.Image tileImage)
        {
            lock (syncLocker)
            {
                pendingRfxBuffer.Clear();
            }

            if (index == 0 || opMode == OperationalMode.ImageMode)
            {
                TS_RFX_SYNC rfxSync = rdprfxServer.CreateTsRfxSync();
                AddToPendingList(rfxSync);

                TS_RFX_CODEC_VERSIONS rfxVersions = rdprfxServer.CreateTsRfxCodecVersions();
                AddToPendingList(rfxVersions);

                TS_RFX_CHANNELS rfxChannels = rdprfxServer.CreateTsRfxChannels();
                AddToPendingList(rfxChannels);

                TS_RFX_CONTEXT rfxContext = rdprfxServer.CreateTsRfxContext(opMode, entropy);
                AddToPendingList(rfxContext);
            }

            TS_RFX_FRAME_BEGIN rfxBegin = rdprfxServer.CreateTsRfxFrameBegin(index);
            AddToPendingList(rfxBegin);

            TS_RFX_REGION rfxRegion = rdprfxServer.CreateTsRfxRegion();
            AddToPendingList(rfxRegion);

            TS_RFX_TILESET rfxTileSet = rdprfxServer.CreateTsRfxTileSet(opMode, entropy, tileImage);
            AddToPendingList(rfxTileSet);

            TS_RFX_FRAME_END rfxEnd = rdprfxServer.CreateTsRfxFrameEnd();
            AddToPendingList(rfxEnd);

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                this.bcgrAdapter.SimulatedScreen.SetRemoteFXRegion(rfxRegion);
                this.bcgrAdapter.SimulatedScreen.SetRemoteFXTileSet(rfxTileSet, entropy);
            }

            lock (syncLocker)
            {
                return pendingRfxBuffer.ToArray();
            }
        }
        //
        // Routine that outputs a stream of RLGR1/RLGR3-encoded bits
        //
        void RLGR_Encode(
            EntropyAlgorithm rlgrMode    // RLGR1 || RLGR3
            )
        {
            // initialize the parameters
            int k = 1;
            int kp = 1 << LSGR;
            //int kr = 1;
            int krp = 1 << LSGR;

            // process all the input coefficients
            while (hasMoreData())
            {
                int input;

                if (k != 0)
                {
                    // RUN-LENGTH MODE

                    // collect the run of zeros in the input stream
                    int numZeros = 0;
                    while ((input = GetNextInput()) == 0)
                    {
                        ++numZeros;
                        if (!hasMoreData()) break;
                    }

                    // emit output zebros
                    int runmax = 1 << k;
                    while (numZeros >= runmax)
                    {
                        OutputBit(1, 0);             // output a zero bit
                        numZeros -= runmax;
                        k = UpdateParam(ref kp, UP_GR);  // update kp, k
                        runmax = 1 << k;
                    }

                    // output a 1 to terminate runs
                    OutputBit(1, 1);

                    // output the remaining run length using k bits
                    OutputBits(k, numZeros);

                    if (input != 0)
                    {
                        // encode the nonzero value using GR coding

                        int mag = Math.Abs(input);            // absolute value of input coefficient
                        int sign = (input < 0 ? 1 : 0);  // sign of input coefficient

                        OutputBit(1, sign);      // output the sign bit
                        CodeGR(ref krp, (uint)(mag - 1));   // output GR code for (mag - 1)

                        k = UpdateParam(ref kp, -DN_GR);
                    }
                }
                else
                {
                    // GOLOMB-RICE MODE

                    if (rlgrMode == EntropyAlgorithm.CLW_ENTROPY_RLGR1)
                    {
                        // RLGR1 variant

                        // convert input to (2*magnitude - sign), encode using GR code
                        uint twoMs = Get2MagSign(GetNextInput());
                        CodeGR(ref krp, twoMs);

                        // update k, kp
                        if (twoMs == 0)
                        {
                            k = UpdateParam(ref kp, UQ_GR);
                        }
                        else
                        {
                            k = UpdateParam(ref kp, -DQ_GR);
                        }
                    }
                    else // rlgrMode == RLGR3
                    {
                        // RLGR3 variant

                        // convert the next two input values to (2*magnitude - sign) and
                        // encode their sum using GR code

                        uint twoMs1 = Get2MagSign(GetNextInput());
                        uint twoMs2 = 0;
                        if (hasMoreData())
                        {
                            twoMs2 = Get2MagSign(GetNextInput());
                        }

                        uint sum2Ms = twoMs1 + twoMs2;

                        CodeGR(ref krp, sum2Ms);

                        // encode binary representation of the first input (twoMs1).
                        OutputBits((int)GetMinBits((int)sum2Ms), (int)twoMs1);

                        // update k,kp for the two input values
                        if (twoMs1 != 0 && twoMs2 != 0)
                        {
                            k = UpdateParam(ref kp, -2 * DQ_GR);
                        }
                        else if (twoMs1 == 0 && twoMs2 == 0)
                        {
                            k = UpdateParam(ref kp, 2 * UQ_GR);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Method to send one frame of encoded data message to client.
        /// </summary>
        /// <param name="image">The image to be sent.</param>
        /// <param name="opMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        /// <param name="destLeft">Left bound of the frame.</param>
        /// <param name="destTop">Left bound of the frame.</param>
        public void SendImageToClient(System.Drawing.Image image, OperationalMode opMode, EntropyAlgorithm entropy, ushort destLeft, ushort destTop)
        {
            if (image == null)
            {
                Site.Log.Add(LogEntryKind.Debug, "[In iRdprfxAdapter.SendImageToClient Method] The image to be send is null.");
                return;
            }

            TileImage[] tileImageArr = RdprfxTileUtils.SplitToTileImage(image, RdprfxServer.TileSize, RdprfxServer.TileSize);

            for (int idx = 0; idx < tileImageArr.Length; idx++)
            {
                if (idx == 0 || opMode == OperationalMode.ImageMode)
                {
                    SendTsRfxSync();
                    SendTsRfxCodecVersions();
                    SendTsRfxChannels();
                    SendTsRfxContext(opMode, entropy);
                }
                SendTsRfxFrameBegin((uint)idx);
                SendTsRfxRegion();
                SendTsRfxTileSet(opMode, entropy, tileImageArr[idx].image);
                SendTsRfxFrameEnd();
                FlushEncodedData((ushort)(destLeft + tileImageArr[idx].x), (ushort)(destTop + tileImageArr[idx].y));
                if (currentTestType != RdprfxNegativeType.None)
                {
                    // Only send one message if it is in a negative test case.
                    break;
                }
            }
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="tsRfxCodecQuantVals"></param>
 /// <param name="quantIdxY"></param>
 /// <param name="quantIdxCb"></param>
 /// <param name="quantIdxCr"></param>
 /// <param name="mode"></param>
 public RemoteFXCodecContext(TS_RFX_CODEC_QUANT[] tsRfxCodecQuantVals, byte quantIdxY, byte quantIdxCb, byte quantIdxCr, EntropyAlgorithm mode)
 {
     if(tsRfxCodecQuantVals == null || tsRfxCodecQuantVals.Length == 0)
     {
         throw new ArgumentException("Parameter tsRfxCodecQuantVals cannot be null and its length must larger than 0.");
     }
     int maxIndex = tsRfxCodecQuantVals.Length -1;
     if (quantIdxY > maxIndex || quantIdxCb > maxIndex || quantIdxCr > maxIndex)
     {
         throw new ArgumentException("Quant index for Y , Cb or Cr is/are larger than the size of tsRfxCodecQuantVals.");
     }
     this.CodecQuantVals = tsRfxCodecQuantVals;
     this.QuantIdxY = quantIdxY;
     this.QuantIdxCb = quantIdxCb;
     this.QuantIdxCr = quantIdxCr;
     this.Mode = mode;
 }
        public void Rdprfx_ImageMode_PositiveTest_RLGR3()
        {
            #region Test Description

            /*
             * Step 1: [RDPBCGR] establishing the connection.
             * Step 2: [RDPBCGR] send Frame Maker Command (Begin) to SUT.
             * Step 3: [RDPRFX] Send Encode Header Messages to SUT.
             * Step 4: [RDPRFX] Send one frame of Encode Data Messages (encoded with RLGR3) to SUT.
             * Step 5: [RDPBCGR] send Frame Maker Command (End) to SUT.
             * Step 6: [RDPRFX] Expect SUT sends a TS_FRAME_ACKNOWLEDGE_PDU.
             */
            #endregion

            #region Test Sequence

            //Start RDP listening.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening.");
            this.rdpbcgrAdapter.StartRDPListening(transportProtocol);

            #region Trigger client to connect
            //Trigger client to connect.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server.");
            triggerClientRDPConnect(transportProtocol, true);
            #endregion

            #region RDPBCGR Connection

            //Waiting for the transport level connection request.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request.");
            this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal);

            //Set Server Capability with RomoteFX codec supported.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability.");
            setServerCapabilitiesWithRemoteFxSupported();

            //Waiting for the RDP connection sequence.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Establishing RDP connection.");
            this.rdpbcgrAdapter.EstablishRDPConnection(selectedProtocol, enMethod, enLevel, true, false, rdpServerVersion);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server Save Session Info PDU to SUT to notify user has logged on.");
            this.rdpbcgrAdapter.ServerSaveSessionInfo(LogonNotificationType.UserLoggedOn, ErrorNotificationType_Values.LOGON_FAILED_OTHER);

            #endregion

            //Initial the RDPRFX adapter context.
            rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext);

            receiveAndLogClientRfxCapabilites();

            uint             frameId     = 0; //The index of the sending frame.
            OperationalMode  opMode      = OperationalMode.ImageMode;
            EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR3;
            ushort           destLeft    = 64; //the left bound of the frame.
            ushort           destTop     = 64; //the top bound of the frame.

            //Check if the above setting is supported by the client.
            if (!this.rdprfxAdapter.CheckIfClientSupports(opMode, enAlgorithm))
            {
                this.TestSite.Log.Add(LogEntryKind.Comment, "the input pair of Operational Mode ({0}) / Entropy Algorithm ({1}) is not supported by the client, so stop running this test case.", opMode, enAlgorithm);
                return;
            }

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (Begin) with frameID: {0}.", frameId);
            rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_BEGIN, frameId);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending one frame of encoded bitmap data to client. Operational Mode = {0}, Entropy Algorithm = {1}, destLeft = {2}, destTop = {3}.",
                                  opMode, enAlgorithm, destLeft, destTop);
            rdprfxAdapter.SendImageToClient(image_64X64, opMode, enAlgorithm, destLeft, destTop);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (End) with frameID: {0}.", frameId);
            rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_END, frameId);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting TS_FRAME_ACKNOWLEDGE_PDU.");
            rdprfxAdapter.ExpectTsFrameAcknowledgePdu(frameId, waitTime);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            Rectangle compareRect = new Rectangle(destLeft, destTop, image_64X64.Width, image_64X64.Height);
            this.VerifySUTDisplay(true, compareRect);

            #endregion
        }
        //
        // Routine that outputs a stream of RLGR1/RLGR3-encoded bits
        //
        void RLGR_Encode(
            EntropyAlgorithm rlgrMode    // RLGR1 || RLGR3
            )
        {
            // initialize the parameters
            int k  = 1;
            int kp = 1 << LSGR;
            //int kr = 1;
            int krp = 1 << LSGR;

            // process all the input coefficients
            while (hasMoreData())
            {
                int input;

                if (k != 0)
                {
                    // RUN-LENGTH MODE

                    // collect the run of zeros in the input stream
                    int numZeros = 0;
                    while ((input = GetNextInput()) == 0)
                    {
                        ++numZeros;
                        if (!hasMoreData())
                        {
                            break;
                        }
                    }

                    // emit output zebros
                    int runmax = 1 << k;
                    while (numZeros >= runmax)
                    {
                        OutputBit(1, 0);                        // output a zero bit
                        numZeros -= runmax;
                        k         = UpdateParam(ref kp, UP_GR); // update kp, k
                        runmax    = 1 << k;
                    }

                    // output a 1 to terminate runs
                    OutputBit(1, 1);

                    // output the remaining run length using k bits
                    OutputBits(k, numZeros);

                    if (input != 0)
                    {
                        // encode the nonzero value using GR coding

                        int mag  = Math.Abs(input);       // absolute value of input coefficient
                        int sign = (input < 0 ? 1 : 0);   // sign of input coefficient

                        OutputBit(1, sign);               // output the sign bit
                        CodeGR(ref krp, (uint)(mag - 1)); // output GR code for (mag - 1)

                        k = UpdateParam(ref kp, -DN_GR);
                    }
                }
                else
                {
                    // GOLOMB-RICE MODE

                    if (rlgrMode == EntropyAlgorithm.CLW_ENTROPY_RLGR1)
                    {
                        // RLGR1 variant

                        // convert input to (2*magnitude - sign), encode using GR code
                        uint twoMs = Get2MagSign(GetNextInput());
                        CodeGR(ref krp, twoMs);

                        // update k, kp
                        if (twoMs == 0)
                        {
                            k = UpdateParam(ref kp, UQ_GR);
                        }
                        else
                        {
                            k = UpdateParam(ref kp, -DQ_GR);
                        }
                    }
                    else // rlgrMode == RLGR3
                    {
                        // RLGR3 variant

                        // convert the next two input values to (2*magnitude - sign) and
                        // encode their sum using GR code

                        uint twoMs1 = Get2MagSign(GetNextInput());
                        uint twoMs2 = 0;
                        if (hasMoreData())
                        {
                            twoMs2 = Get2MagSign(GetNextInput());
                        }

                        uint sum2Ms = twoMs1 + twoMs2;

                        CodeGR(ref krp, sum2Ms);

                        // encode binary representation of the first input (twoMs1).
                        OutputBits((int)GetMinBits((int)sum2Ms), (int)twoMs1);

                        // update k,kp for the two input values
                        if (twoMs1 != 0 && twoMs2 != 0)
                        {
                            k = UpdateParam(ref kp, -2 * DQ_GR);
                        }
                        else if (twoMs1 == 0 && twoMs2 == 0)
                        {
                            k = UpdateParam(ref kp, 2 * UQ_GR);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Method to send TS_RFX_TILESET to client.
        /// </summary>
        /// <param name="opMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        /// <param name="tileImages">The image array for tiles to be sent. The width and height must be less than or equals with 64.</param>
        /// <param name="positions">A TILE_POSITION array indicating the positions of each tile images</param>
        /// <param name="codecQuantVals">Quant values array</param>
        /// <param name="quantIdxYs">Index array of Y component in Quant value array</param>
        /// <param name="quantIdxCbs">Index array of Cb component in Quant value array</param>
        /// <param name="quantIdxCrs">Index array of Cr component in Quant value array</param>
        public void SendTsRfxTileSet(OperationalMode opMode, EntropyAlgorithm entropy, Image[] tileImages, TILE_POSITION[] positions,
            TS_RFX_CODEC_QUANT[] codecQuantVals = null, byte[] quantIdxYs = null, byte[] quantIdxCbs = null, byte[] quantIdxCrs = null)
        {
            this.admEntropyAlgorithm = entropy;
            this.admOperationMode = opMode;
            TS_RFX_TILESET rfxTileSet = rdprfxServer.CreateTsRfxTileSet(opMode, entropy, tileImages, positions, codecQuantVals, quantIdxYs, quantIdxCbs, quantIdxCrs);
            if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidIdx)
            {
                rfxTileSet.idx = 0x0001; //set to an invalid value other than 0x0000.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidLt)
            {
                rfxTileSet.properties &= 0xFFFE; //set "lt" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidCct)
            {
                rfxTileSet.properties &= 0xFFCF; //set "cct" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidXft)
            {
                rfxTileSet.properties &= 0xFC3F; //set "xft" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidQt)
            {
                rfxTileSet.properties &= 0x3FFF; //set "xft" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidTileSize)
            {
                rfxTileSet.tileSize = 0x80; //set to an invalid value other than 0x40.
            }

            if (this.rdpbcgrAdapter.SimulatedScreen != null)
            {
                this.rdpbcgrAdapter.SimulatedScreen.SetRemoteFXTileSet(rfxTileSet, entropy);
            }

            AddToPendingList(rfxTileSet);
            if (!CheckIfClientSupports(opMode, entropy))
            {
                Site.Log.Add(LogEntryKind.Debug, "The client Cap is not supported: OperationalMode = {0}, EntropyAlgorithm = {1}",
                    opMode.ToString(),
                    entropy.ToString());
            }
        }
        //
        // Routine that reads and decodes stream of RLGR data
        //
        void RLGR_Decode(
            EntropyAlgorithm rlgrMode,    // RLGR1 || RLGR3
            int lenToDecode
            )
        {
            int termsToDecode = lenToDecode;
            // initialize the parameters
            int k = 1;
            int kp = k << LSGR;
            int kr = 1;
            int krp = kr << LSGR;

            while (termsToDecode > 0)
            {
                int run;

                if (k != 0)
                {
                    // RL MODE
                    while (GetBits(1) == 0)
                    {
                        if (termsToDecode > 0)
                        {
                            // we have an RL escape "0", which translates to a run (1<<k) of zeros
                            WriteZeroes((uint)(1 << k), ref termsToDecode);
                            k = UpdateParam(ref kp, UP_GR);  // raise k and kp up because of zero run
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (termsToDecode > 0)
                    {
                        // next k bits will contain remaining run of zeros
                        run = (int)GetBits((uint)k);
                        WriteZeroes((uint)run, ref termsToDecode);
                    }

                    if (termsToDecode > 0)
                    {
                        // get nonzero value, starting with sign bit and
                        // then GRCode for magnitude - 1
                        uint sign = GetBits(1);

                        // magnitude - 1 was coded (because it was nonzero)
                        int mag = (int)GetGRCode(ref krp, ref kr) + 1;

                        WriteValue(sign != 0 ? -mag : mag, ref termsToDecode);
                        k = UpdateParam(ref kp, -DN_GR); // lower k and kp because of nonzero term
                    }
                }
                else
                {
                    // GR (GOLOMB-RICE) MODE
                    uint mag = GetGRCode(ref krp, ref kr); // values coded are 2*magnitude - sign

                    if (rlgrMode == EntropyAlgorithm.CLW_ENTROPY_RLGR1)
                    {
                        if (mag == 0)
                        {
                            WriteValue(0, ref termsToDecode);
                            k = UpdateParam(ref kp, UQ_GR); // raise k and kp due to zero
                        }
                        else
                        {
                            WriteValue(GetIntFrom2MagSign(mag), ref termsToDecode);
                            k = UpdateParam(ref kp, -DQ_GR);  // lower k and kp due to nonzero
                        }

                    }
                    else // rlgrMode == RLGR3
                    {
                        // In GR mode FOR RLGR3, we have encoded the
                        // sum of two (2*mag - sign) values

                        // maximum possible bits for first term
                        uint nIdx = GetMinBits(mag);

                        // decode val1 is first term's (2*mag - sign) value
                        uint val1 = GetBits(nIdx);

                        // val2 is second term's (2*mag - sign) value
                        uint val2 = mag - val1;

                        if (val1 != 0 && val2 != 0)
                        {
                            // raise k and kp if both terms nonzero
                            k = UpdateParam(ref kp, -2 * DQ_GR);
                        }
                        else if (val1 == 0 && val2 == 0)
                        {
                            // lower k and kp if both terms zero
                            k = UpdateParam(ref kp, 2 * UQ_GR);
                        }

                        WriteValue(GetIntFrom2MagSign(val1), ref termsToDecode);
                        if (termsToDecode > 0)
                        {
                            WriteValue(GetIntFrom2MagSign(val2), ref termsToDecode);
                        }
                    }
                }
            }
        }
Example #35
0
        //
        // Routine that reads and decodes stream of RLGR data
        //
        void RLGR_Decode(
            EntropyAlgorithm rlgrMode,    // RLGR1 || RLGR3
            int lenToDecode
            )
        {
            int termsToDecode = lenToDecode;
            // initialize the parameters
            int k   = 1;
            int kp  = k << LSGR;
            int kr  = 1;
            int krp = kr << LSGR;

            while (termsToDecode > 0)
            {
                int run;

                if (k != 0)
                {
                    // RL MODE
                    while (GetBits(1) == 0)
                    {
                        if (termsToDecode > 0)
                        {
                            // we have an RL escape "0", which translates to a run (1<<k) of zeros
                            WriteZeroes((uint)(1 << k), ref termsToDecode);
                            k = UpdateParam(ref kp, UP_GR);  // raise k and kp up because of zero run
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (termsToDecode > 0)
                    {
                        // next k bits will contain remaining run of zeros
                        run = (int)GetBits((uint)k);
                        WriteZeroes((uint)run, ref termsToDecode);
                    }

                    if (termsToDecode > 0)
                    {
                        // get nonzero value, starting with sign bit and
                        // then GRCode for magnitude - 1
                        uint sign = GetBits(1);

                        // magnitude - 1 was coded (because it was nonzero)
                        int mag = (int)GetGRCode(ref krp, ref kr) + 1;

                        WriteValue(sign != 0 ? -mag : mag, ref termsToDecode);
                        k = UpdateParam(ref kp, -DN_GR); // lower k and kp because of nonzero term
                    }
                }
                else
                {
                    // GR (GOLOMB-RICE) MODE
                    uint mag = GetGRCode(ref krp, ref kr); // values coded are 2*magnitude - sign

                    if (rlgrMode == EntropyAlgorithm.CLW_ENTROPY_RLGR1)
                    {
                        if (mag == 0)
                        {
                            WriteValue(0, ref termsToDecode);
                            k = UpdateParam(ref kp, UQ_GR); // raise k and kp due to zero
                        }
                        else
                        {
                            WriteValue(GetIntFrom2MagSign(mag), ref termsToDecode);
                            k = UpdateParam(ref kp, -DQ_GR);  // lower k and kp due to nonzero
                        }
                    }
                    else // rlgrMode == RLGR3
                    {
                        // In GR mode FOR RLGR3, we have encoded the
                        // sum of two (2*mag - sign) values

                        // maximum possible bits for first term
                        uint nIdx = GetMinBits(mag);

                        // decode val1 is first term's (2*mag - sign) value
                        uint val1 = GetBits(nIdx);

                        // val2 is second term's (2*mag - sign) value
                        uint val2 = mag - val1;

                        if (val1 != 0 && val2 != 0)
                        {
                            // raise k and kp if both terms nonzero
                            k = UpdateParam(ref kp, -2 * DQ_GR);
                        }
                        else if (val1 == 0 && val2 == 0)
                        {
                            // lower k and kp if both terms zero
                            k = UpdateParam(ref kp, 2 * UQ_GR);
                        }


                        WriteValue(GetIntFrom2MagSign(val1), ref termsToDecode);
                        if (termsToDecode > 0)
                        {
                            WriteValue(GetIntFrom2MagSign(val2), ref termsToDecode);
                        }
                    }
                }
            }
        }
Example #36
0
        /// <summary>
        /// Method to create TS_RFX_TILESET.
        /// </summary>
        /// <param name="isImageMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        /// <param name="tileImage">A RgbTile. The width and heigth must be less than or equals with 64.</param>
        public TS_RFX_TILESET CreateTsRfxTileSet(OperationalMode opMode, EntropyAlgorithm entropy, RgbTile tileImage)
        {
            TS_RFX_TILESET rfxTileSet = new TS_RFX_TILESET();

            rfxTileSet.CodecChannelT           = new TS_RFX_CODEC_CHANNELT();
            rfxTileSet.CodecChannelT.blockType = blockType_Value.WBT_EXTENSION;
            rfxTileSet.CodecChannelT.blockLen  = 22 + 5;
            rfxTileSet.CodecChannelT.codecId   = 0x01;
            rfxTileSet.CodecChannelT.channelId = 0x00;
            rfxTileSet.subtype = 0xCAC2;
            rfxTileSet.idx     = 0x0000;

            ushort lt    = 0x0001;
            ushort flags = 0x0002;

            if (opMode == OperationalMode.VideoMode)
            {
                flags = 0x0000;
            }
            ushort cct = 0x0001;
            ushort xft = 0x0001;
            ushort et  = 0x0001;

            if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3)
            {
                et = 0x0004;
            }
            ushort qt = 0x0001;

            rfxTileSet.properties  = lt;
            rfxTileSet.properties |= (ushort)(flags << 1);
            rfxTileSet.properties |= (ushort)(cct << 4);
            rfxTileSet.properties |= (ushort)(xft << 6);
            rfxTileSet.properties |= (ushort)(et << 10);
            rfxTileSet.properties |= (ushort)(qt << 14);

            rfxTileSet.numQuant = 1;
            rfxTileSet.tileSize = RdprfxServer.TileSize;
            rfxTileSet.numTiles = 1;

            rfxTileSet.quantVals    = new TS_RFX_CODEC_QUANT[1];
            rfxTileSet.quantVals[0] = codecQuant;

            byte[] yData, cbData, crData;

            RemoteFXCodecContext encodingContext = new RemoteFXCodecContext(codecQuant, entropy);

            RemoteFXEncoder.EncodeTile(tileImage, 0, 0, encodingContext);
            yData  = encodingContext.YData;
            cbData = encodingContext.CbData;
            crData = encodingContext.CrData;

            rfxTileSet.tiles = new TS_RFX_TILE[1];
            rfxTileSet.tiles[0].BlockT.blockType = blockType_Value.CBT_TILE;
            rfxTileSet.tiles[0].BlockT.blockLen  = (uint)(19 + yData.Length + cbData.Length + crData.Length);
            rfxTileSet.tiles[0].quantIdxY        = 0;
            rfxTileSet.tiles[0].quantIdxCb       = 0;
            rfxTileSet.tiles[0].quantIdxCr       = 0;
            rfxTileSet.tiles[0].xIdx             = 0;
            rfxTileSet.tiles[0].yIdx             = 0;
            rfxTileSet.tiles[0].YLen             = (ushort)yData.Length;
            rfxTileSet.tiles[0].CbLen            = (ushort)cbData.Length;
            rfxTileSet.tiles[0].CrLen            = (ushort)crData.Length;
            rfxTileSet.tiles[0].YData            = yData;
            rfxTileSet.tiles[0].CbData           = cbData;
            rfxTileSet.tiles[0].CrData           = crData;

            rfxTileSet.tilesDataSize          = rfxTileSet.tiles[0].BlockT.blockLen;
            rfxTileSet.CodecChannelT.blockLen = 22 + 5 + rfxTileSet.tilesDataSize;

            return(rfxTileSet);
        }
Example #37
0
        /// <summary>
        /// Method to create TS_RFX_TILESET.
        /// </summary>
        /// <param name="opMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        /// <param name="tileImages">An array of bitmaps in Image type for a tile. The width and heigth must be less than or equals with 64.</param>
        /// <param name="positions">A TILE_POSITION array indicating the positions of each tile images</param>
        /// <param name="codecQuantVals">Quant values array</param>
        /// <param name="quantIdxYs">Index array of Y component in Quant value array</param>
        /// <param name="quantIdxCbs">Index array of Cb component in Quant value array</param>
        /// <param name="quantIdxCrs">Index array of Cr component in Quant value array</param>
        /// <returns></returns>
        public TS_RFX_TILESET CreateTsRfxTileSet(
            OperationalMode opMode,
            EntropyAlgorithm entropy,
            Image[] tileImages,
            TILE_POSITION[] positions,
            TS_RFX_CODEC_QUANT[] codecQuantVals = null,
            byte[] quantIdxYs  = null,
            byte[] quantIdxCbs = null,
            byte[] quantIdxCrs = null
            )
        {
            if (codecQuantVals == null)
            {
                codecQuantVals    = new TS_RFX_CODEC_QUANT[1];
                codecQuantVals[0] = codecQuant;
            }

            TS_RFX_TILESET rfxTileSet = new TS_RFX_TILESET();

            rfxTileSet.CodecChannelT           = new TS_RFX_CODEC_CHANNELT();
            rfxTileSet.CodecChannelT.blockType = blockType_Value.WBT_EXTENSION;
            rfxTileSet.CodecChannelT.blockLen  = 22 + 5;
            rfxTileSet.CodecChannelT.codecId   = 0x01;
            rfxTileSet.CodecChannelT.channelId = 0x00;
            rfxTileSet.subtype = 0xCAC2;
            rfxTileSet.idx     = 0x0000;

            ushort lt    = 0x0001;
            ushort flags = 0x0002;

            if (opMode == OperationalMode.VideoMode)
            {
                flags = 0x0000;
            }
            ushort cct = 0x0001;
            ushort xft = 0x0001;
            ushort et  = 0x0001;

            if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3)
            {
                et = 0x0004;
            }
            ushort qt = 0x0001;

            rfxTileSet.properties  = lt;
            rfxTileSet.properties |= (ushort)(flags << 1);
            rfxTileSet.properties |= (ushort)(cct << 4);
            rfxTileSet.properties |= (ushort)(xft << 6);
            rfxTileSet.properties |= (ushort)(et << 10);
            rfxTileSet.properties |= (ushort)(qt << 14);

            rfxTileSet.numQuant = (byte)codecQuantVals.Length;
            rfxTileSet.tileSize = RdprfxServer.TileSize;
            rfxTileSet.numTiles = 1;

            rfxTileSet.quantVals = codecQuantVals;

            byte[] yData, cbData, crData;

            rfxTileSet.tiles    = new TS_RFX_TILE[tileImages.Length];
            rfxTileSet.numTiles = (ushort)rfxTileSet.tiles.Length;

            for (int i = 0; i < tileImages.Length; i++)
            {
                byte quantIdxY  = quantIdxYs == null ? (byte)0 : (quantIdxYs.Length > i ? quantIdxYs[i] : (byte)0);
                byte quantIdxCb = quantIdxCbs == null ? (byte)0 : (quantIdxCbs.Length > i ? quantIdxCbs[i] : (byte)0);
                byte quantIdxCr = quantIdxCrs == null ? (byte)0 : (quantIdxCrs.Length > i ? quantIdxCrs[i] : (byte)0);

                RemoteFXCodecContext encodingContext = new RemoteFXCodecContext(codecQuantVals, quantIdxY, quantIdxCb, quantIdxCr, entropy);
                RemoteFXEncoder.EncodeTile(tileImages[i], 0, 0, encodingContext);
                yData  = encodingContext.YData;
                cbData = encodingContext.CbData;
                crData = encodingContext.CrData;

                rfxTileSet.tiles[i].BlockT.blockType = blockType_Value.CBT_TILE;
                rfxTileSet.tiles[i].BlockT.blockLen  = (uint)(19 + yData.Length + cbData.Length + crData.Length);
                rfxTileSet.tiles[i].quantIdxY        = quantIdxY;
                rfxTileSet.tiles[i].quantIdxCb       = quantIdxCb;
                rfxTileSet.tiles[i].quantIdxCr       = quantIdxCr;
                rfxTileSet.tiles[i].xIdx             = positions[i].xIdx;
                rfxTileSet.tiles[i].yIdx             = positions[i].yIdx;
                rfxTileSet.tiles[i].YLen             = (ushort)yData.Length;
                rfxTileSet.tiles[i].CbLen            = (ushort)cbData.Length;
                rfxTileSet.tiles[i].CrLen            = (ushort)crData.Length;
                rfxTileSet.tiles[i].YData            = yData;
                rfxTileSet.tiles[i].CbData           = cbData;
                rfxTileSet.tiles[i].CrData           = crData;

                rfxTileSet.tilesDataSize         += rfxTileSet.tiles[i].BlockT.blockLen;
                rfxTileSet.CodecChannelT.blockLen = (uint)(22 + 5 * rfxTileSet.numQuant + rfxTileSet.tilesDataSize);
            }

            return(rfxTileSet);
        }
 /// <summary>
 /// Set TS_RFX_TILESET for RemoteFX codec image
 /// </summary>
 /// <param name="rfxTileSet"></param>
 /// <param name="entropy"></param>
 public void SetRemoteFXTileSet(TS_RFX_TILESET rfxTileSet, EntropyAlgorithm entropy)
 {
     remoteFXContext.TileSet = rfxTileSet;
     remoteFXContext.Entropy = entropy;
 }
        /// <summary>
        /// Method to create TS_RFX_TILESET.
        /// </summary>
        /// <param name="isImageMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        /// <param name="tileImage">A RgbTile. The width and heigth must be less than or equals with 64.</param>
        public TS_RFX_TILESET CreateTsRfxTileSet(OperationalMode opMode, EntropyAlgorithm entropy, RgbTile tileImage)
        {
            TS_RFX_TILESET rfxTileSet = new TS_RFX_TILESET();
            rfxTileSet.CodecChannelT = new TS_RFX_CODEC_CHANNELT();
            rfxTileSet.CodecChannelT.blockType = blockType_Value.WBT_EXTENSION;
            rfxTileSet.CodecChannelT.blockLen = 22 + 5;
            rfxTileSet.CodecChannelT.codecId = 0x01;
            rfxTileSet.CodecChannelT.channelId = 0x00;
            rfxTileSet.subtype = 0xCAC2;
            rfxTileSet.idx = 0x0000;

            ushort lt = 0x0001;
            ushort flags = 0x0002;
            if (opMode == OperationalMode.VideoMode) flags = 0x0000;
            ushort cct = 0x0001;
            ushort xft = 0x0001;
            ushort et = 0x0001;
            if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3) et = 0x0004;
            ushort qt = 0x0001;
            rfxTileSet.properties = lt;
            rfxTileSet.properties |= (ushort)(flags << 1);
            rfxTileSet.properties |= (ushort)(cct << 4);
            rfxTileSet.properties |= (ushort)(xft << 6);
            rfxTileSet.properties |= (ushort)(et << 10);
            rfxTileSet.properties |= (ushort)(qt << 14);

            rfxTileSet.numQuant = 1;
            rfxTileSet.tileSize = RdprfxServer.TileSize;
            rfxTileSet.numTiles = 1;

            rfxTileSet.quantVals = new TS_RFX_CODEC_QUANT[1];
            rfxTileSet.quantVals[0] = codecQuant;

            byte[] yData, cbData, crData;

            RemoteFXCodecContext encodingContext = new RemoteFXCodecContext(codecQuant, entropy);
            RemoteFXEncoder.EncodeTile(tileImage, 0, 0, encodingContext);
            yData = encodingContext.YData;
            cbData = encodingContext.CbData;
            crData = encodingContext.CrData;

            rfxTileSet.tiles = new TS_RFX_TILE[1];
            rfxTileSet.tiles[0].BlockT.blockType = blockType_Value.CBT_TILE;
            rfxTileSet.tiles[0].BlockT.blockLen = (uint)(19 + yData.Length + cbData.Length + crData.Length);
            rfxTileSet.tiles[0].quantIdxY = 0;
            rfxTileSet.tiles[0].quantIdxCb = 0;
            rfxTileSet.tiles[0].quantIdxCr = 0;
            rfxTileSet.tiles[0].xIdx = 0;
            rfxTileSet.tiles[0].yIdx = 0;
            rfxTileSet.tiles[0].YLen = (ushort)yData.Length;
            rfxTileSet.tiles[0].CbLen = (ushort)cbData.Length;
            rfxTileSet.tiles[0].CrLen = (ushort)crData.Length;
            rfxTileSet.tiles[0].YData = yData;
            rfxTileSet.tiles[0].CbData = cbData;
            rfxTileSet.tiles[0].CrData = crData;

            rfxTileSet.tilesDataSize = rfxTileSet.tiles[0].BlockT.blockLen;
            rfxTileSet.CodecChannelT.blockLen = 22 + 5 + rfxTileSet.tilesDataSize;

            return rfxTileSet;
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="tsRfxCodecQuant"></param>
 /// <param name="mode"></param>
 public RemoteFXCodecContext(TS_RFX_CODEC_QUANT tsRfxCodecQuant, EntropyAlgorithm mode)
 {
     this.CodecQuantVals = new TS_RFX_CODEC_QUANT[] { tsRfxCodecQuant };
     this.QuantIdxY = 0;
     this.QuantIdxCb = 0;
     this.QuantIdxCr = 0;
     this.Mode = mode;
 }
        public void Rdprfx_ImageMode_PositiveTest_MultiQuantVals()
        {
            #region Test Description

            /*
             * Step 1: [RDPBCGR] establishing the connection.
             * Step 2: [RDPBCGR] send Frame Maker Command (Begin) to SUT.
             * Step 3: [RDPRFX] Send Encode Header Messages to SUT.
             * Step 4: [RDPRFX] Send one frame of Encode Data Messages (encoded with RLGR1) to SUT, each component use different quantization value.
             * Step 5: [RDPBCGR] send Frame Maker Command (End) to SUT.
             * Step 6: [RDPRFX] Expect SUT sends a TS_FRAME_ACKNOWLEDGE_PDU.
             */
            #endregion

            #region Test Sequence

            //Start RDP listening.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening.");
            this.rdpbcgrAdapter.StartRDPListening(transportProtocol);

            #region Trigger client to connect
            //Trigger client to connect.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server.");
            triggerClientRDPConnect(transportProtocol, true);
            #endregion

            #region RDPBCGR Connection

            //Waiting for the transport level connection request.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request.");
            this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal);

            //Set Server Capability with RomoteFX codec supported.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability.");
            setServerCapabilitiesWithRemoteFxSupported();

            //Waiting for the RDP connection sequence.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Establishing RDP connection.");
            this.rdpbcgrAdapter.EstablishRDPConnection(selectedProtocol, enMethod, enLevel, true, false, rdpServerVersion);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server Save Session Info PDU to SUT to notify user has logged on.");
            this.rdpbcgrAdapter.ServerSaveSessionInfo(LogonNotificationType.UserLoggedOn, ErrorNotificationType_Values.LOGON_FAILED_OTHER);

            #endregion

            //Initial the RDPRFX adapter context.
            rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext);

            receiveAndLogClientRfxCapabilites();

            uint             frameId     = 0; //The index of the sending frame.
            OperationalMode  opMode      = OperationalMode.ImageMode;
            EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR1;
            ushort           destLeft    = 64; //the left bound of the frame.
            ushort           destTop     = 64; //the top bound of the frame.

            //Check if the above setting is supported by the client.
            if (!this.rdprfxAdapter.CheckIfClientSupports(opMode, enAlgorithm))
            {
                this.TestSite.Log.Add(LogEntryKind.Comment, "the input pair of Operational Mode ({0}) / Entropy Algorithm ({1}) is not supported by the client, so stop running this test case.", opMode, enAlgorithm);
                return;
            }

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (Begin) with frameID: {0}.", frameId);
            rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_BEGIN, frameId);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Start to send encoded bitmap data to client. Operational Mode = {0}, Entropy Algorithm = {1}, destLeft = {2}, destTop = {3}.",
                                  opMode, enAlgorithm, destLeft, destTop);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Generate Quantization value, each component has different quant index.");
            TS_RFX_CODEC_QUANT[] quantVals = this.GenerateCodecQuantVals();
            byte quantIdxY  = 0;
            byte quantIdxCb = 1;
            byte quantIdxCr = 2;

            TileImage[] tileImageArr = RdprfxTileUtils.SplitToTileImage(image_64X64, RdprfxServer.TileSize, RdprfxServer.TileSize);
            for (int idx = 0; idx < tileImageArr.Length; idx++)
            {
                if (idx == 0)
                {
                    rdprfxAdapter.SendTsRfxSync();
                    rdprfxAdapter.SendTsRfxCodecVersions();
                    rdprfxAdapter.SendTsRfxChannels();
                    rdprfxAdapter.SendTsRfxContext(opMode, enAlgorithm);
                }
                rdprfxAdapter.SendTsRfxFrameBegin((uint)idx);
                rdprfxAdapter.SendTsRfxRegion();
                rdprfxAdapter.SendTsRfxTileSet(opMode, enAlgorithm, tileImageArr[idx].image, quantVals, quantIdxY, quantIdxCb, quantIdxCr);
                rdprfxAdapter.SendTsRfxFrameEnd();
                rdprfxAdapter.FlushEncodedData((ushort)(destLeft + tileImageArr[idx].x), (ushort)(destTop + tileImageArr[idx].y));
            }

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (End) with frameID: {0}.", frameId);
            rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_END, frameId);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting TS_FRAME_ACKNOWLEDGE_PDU.");
            rdprfxAdapter.ExpectTsFrameAcknowledgePdu(frameId, waitTime);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            Rectangle compareRect = new Rectangle(destLeft, destTop, image_64X64.Width, image_64X64.Height);
            this.VerifySUTDisplay(true, compareRect);

            #endregion
        }
        /// <summary>
        /// Method to check if the input pair of the operation mode and entropy algorithm is supported by the client.
        /// </summary>
        /// <param name="opMode">The operation mode.</param>
        /// <param name="entropy">The entropy algorithm.</param>
        /// <returns></returns>
        public bool CheckIfClientSupports(OperationalMode opMode, EntropyAlgorithm entropy)
        {
            TS_RFX_ICAP[] iCaps = this.client_RFX_Caps_Container.capsData.capsetsData[0].icapsData;
            foreach (TS_RFX_ICAP icap in iCaps)
            {
                if ((icap.flags & (byte)OperationalMode.ImageMode) == (byte)0 &&
                    ((byte)icap.entropyBits == (byte)entropy))
                {
                    //OperationalMode.ImageMode is not set, both the image mode and the video mode of the codec are supported
                    return true;
                }
                else if ((byte)icap.entropyBits == (byte)entropy)
                {
                    //OperationalMode.ImageMode is set, only image mode is supported
                    if (opMode == OperationalMode.ImageMode)
                        return true;
                }

            }
            return false;
        }
        /// <summary>
        /// Method to send one frame of encoded data message to client.
        /// </summary>
        /// <param name="image">The image to be sent.</param>
        /// <param name="opMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        /// <param name="destLeft">Left bound of the frame.</param>
        /// <param name="destTop">Left bound of the frame.</param>
        public void SendImageToClient(System.Drawing.Image image, OperationalMode opMode, EntropyAlgorithm entropy, ushort destLeft, ushort destTop)
        {
            if (image == null)
            {
                Site.Log.Add(LogEntryKind.Debug, "[In iRdprfxAdapter.SendImageToClient Method] The image to be send is null.");
                return;
            }

            TileImage[] tileImageArr = RdprfxTileUtils.SplitToTileImage(image, RdprfxServer.TileSize, RdprfxServer.TileSize);

            for (int idx = 0; idx < tileImageArr.Length; idx++)
            {
                if (idx == 0 || opMode == OperationalMode.ImageMode)
                {
                    SendTsRfxSync();
                    SendTsRfxCodecVersions();
                    SendTsRfxChannels();
                    SendTsRfxContext(opMode, entropy);
                }
                SendTsRfxFrameBegin((uint)idx);
                SendTsRfxRegion();
                SendTsRfxTileSet(opMode, entropy, tileImageArr[idx].image);
                SendTsRfxFrameEnd();
                FlushEncodedData((ushort)(destLeft + tileImageArr[idx].x), (ushort)(destTop + tileImageArr[idx].y));
                if (currentTestType != RdprfxNegativeType.None)
                {
                    // Only send one message if it is in a negative test case.
                    break;
                }
            }
        }
        public void Rdprfx_ImageMode_NegativeTest_TsRfxFrameBegin_InvalidBlockLen()
        {
            #region Test Description

            /*
             * Step 1: [RDPBCGR] establishing the connection.
             * Step 2: [RDPRFX] send one frame of Encode Header and Data Messages to client, set the blockLen field of TS_RFX_FRAME_BEGIN to an invalid value (less than the actual).
             * Step 3: [RDPRFX] expect the client terminates the RDP connection.
             */
            #endregion

            #region Test Sequence

            //Start RDP listening.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening.");
            this.rdpbcgrAdapter.StartRDPListening(transportProtocol);

            #region Trigger client to connect
            //Trigger client to connect.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server.");
            triggerClientRDPConnect(transportProtocol);
            #endregion

            #region RDPBCGR Connection

            //Waiting for the transport level connection request.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request.");
            this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal);

            //Set Server Capability with RomoteFX codec supported.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability.");
            setServerCapabilitiesWithRemoteFxSupported();

            //Waiting for the RDP connection sequence.
            this.TestSite.Log.Add(LogEntryKind.Comment, "Establishing RDP connection.");
            this.rdpbcgrAdapter.EstablishRDPConnection(selectedProtocol, enMethod, enLevel, true, false, rdpServerVersion);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server Save Session Info PDU to SUT to notify user has logged on.");
            this.rdpbcgrAdapter.ServerSaveSessionInfo(LogonNotificationType.UserLoggedOn, ErrorNotificationType_Values.LOGON_FAILED_OTHER);

            #endregion

            //Initial the RDPRFX adapter context.
            rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext);

            receiveAndLogClientRfxCapabilites();

            OperationalMode  opMode      = OperationalMode.ImageMode;
            EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR3;
            ushort           destLeft    = 0; //the left bound of the frame.
            ushort           destTop     = 0; //the top bound of the frame.

            //Check if the above setting is supported by the client.
            if (!this.rdprfxAdapter.CheckIfClientSupports(opMode, enAlgorithm))
            {
                enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR1;
                if (!this.rdprfxAdapter.CheckIfClientSupports(opMode, enAlgorithm))
                {
                    this.TestSite.Log.Add(LogEntryKind.Comment, "Client does not support Image Mode, so stop running this test case.");
                    return;
                }
            }

            this.TestSite.Log.Add(LogEntryKind.Comment, "Set the test type to {0}.", RdprfxNegativeType.TsRfxFrameBegin_InvalidBlockLen);
            rdprfxAdapter.SetTestType(RdprfxNegativeType.TsRfxFrameBegin_InvalidBlockLen);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Encode Header/Data Messages to client.");
            rdprfxAdapter.SendImageToClient(image_64X64, opMode, enAlgorithm, destLeft, destTop);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the client terminates the RDP connection.");
            bool bDisconnected = rdpbcgrAdapter.WaitForDisconnection(waitTime);

            this.TestSite.Assert.IsTrue(bDisconnected, "Client is expected to drop the connection if received encode data in Video Mode when Image Mode is in effect.");

            #endregion
        }
        /// <summary>
        /// Encode a bitmap data by RemoteFX codec.
        /// </summary>
        /// <param name="image"> The bitmap image to be sent </param>
        /// <param name="opMode"> Indicate Operational Mode.</param>
        /// <param name="entropy"> Indicate Entropy Algorithm.</param>
        /// <param name="imgPos"> The top-left position of bitmap image relative to surface</param>
        /// <param name="sId"> The surface Id that bitmap image is sent to </param>
        /// <returns> A dictionary with frameId and byte stream frame pair </returns>
        public Dictionary<uint, byte[]> RemoteFXCodecEncode(System.Drawing.Image image, OperationalMode opMode, EntropyAlgorithm entropy,
            RDPGFX_POINT16 imgPos, ushort sId, PixelFormat pixFormat)
        {
            if (image == null) return null;

            Dictionary<uint, byte[]> frDict = new Dictionary<uint, byte[]>();   // Save encoded frames for one tile

            TileImage[] tileImageArr = RdprfxTileUtils.SplitToTileImage(image, RdprfxServer.TileSize, RdprfxServer.TileSize);

            for (uint index = 0; index < tileImageArr.Length; index++)
            {
                byte[] tileBitmap = this.PackRfxTileImage(index, opMode, entropy, tileImageArr[index].image);
                ushort tileLeft = (ushort)(imgPos.x + tileImageArr[index].x);
                ushort tileTop = (ushort)(imgPos.y + tileImageArr[index].y);
                RDPGFX_RECT16 tileRect = new RDPGFX_RECT16(tileLeft, tileTop,
                                                            (ushort)(tileLeft + tileImageArr[index].image.Width),
                                                            (ushort)(tileTop + tileImageArr[index].image.Height));

                uint fid = MakeStartFramePdu();
                MakeWireToSurfacePdu1(sId, CodecType.RDPGFX_CODECID_CAVIDEO, pixFormat, tileRect, tileBitmap);
                MakeEndFramePdu(fid);

                if (this.bcgrAdapter.SimulatedScreen != null)
                {
                    this.bcgrAdapter.SimulatedScreen.RenderRemoteFXTile(sId, tileRect);
                }

                frDict.Add(fid, EncodePdusToSent());
            }

            return frDict;
        }
        /// <summary>
        /// Method to send TS_RFX_CONTEXT to client.
        /// </summary>
        /// <param name="isImageMode">Indicates the operational mode.</param>
        /// <param name="entropy">Indicates the entropy algorithm.</param>
        public void SendTsRfxContext(OperationalMode opMode, EntropyAlgorithm entropy)
        {
            this.admEntropyAlgorithm = entropy;
            this.admOperationMode = opMode;

            TS_RFX_CONTEXT rfxContext = rdprfxServer.CreateTsRfxContext(opMode, entropy);
            if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidCtxId)
            {
                rfxContext.ctxId = 0x01; //set to an invalid value other than 0x00.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidTileSize)
            {
                rfxContext.tileSize = 0x0080; //set to an invalid value other than 0x0040.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidCct)
            {
                rfxContext.properties &= 0xFFF7; //set "cct" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidXft)
            {
                rfxContext.properties &= 0xFE1F; //set "xft" to an invalid value: 0x0.
            }
            else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidQt)
            {
                rfxContext.properties &= 0x9FFF; //set "qt" to an invalid value: 0x0.
            }

            AddToPendingList(rfxContext);
        }