/// <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_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
        }