/// <summary>
        /// Encode bitmap data by RFX Progressive codec (one tile in one rfx_progressive_datablock frame).
        /// </summary>
        /// <param name="image"> The bitmap image to be sent </param>
        /// <param name="surf"> The surface that bitmap image is sent to </param>
        /// <param name="pixFormat">The pixel format to draw surface.</param>
        /// <param name="hasSync">Indicates if sync block exists in FRX Progressive bitmap stream.</param>
        /// <param name="hasContext">Indicates if context block exists in FRX Progressive bitmap stream.</param>
        /// <param name="quality">The target encoded quality.</param>
        /// <param name="bProg">Indicates if encode progressively</param>
        /// <param name="bSubDiff">Indicates if sub-diffing with last frame of this surface</param>
        /// <param name="bReduceExtrapolate">Indicates if use Reduce Extrapolate method in DWT step.</param>
        /// <returns> A list of layer byte stream, each layer is built by a dictionary with frameId and byte stream frame pair </returns>
        public List<Dictionary<uint, byte[]>> RfxProgressiveCodecEncode(Surface surf, Image image, PixelFormat pixFormat, bool hasSync, bool hasContext,                                                  
            ImageQuality_Values quality, bool bProg, bool bSubDiff, bool bReduceExtrapolate)
        {
            bool multipleTileInRegion = true;
            List<Dictionary<TileIndex, EncodedTile>> layerTileList = new List<Dictionary<TileIndex,EncodedTile>>();

            if (image == null)  return null;

            uint fid = 0;
            List<Dictionary<uint, byte[]>> layerDataList = new List<Dictionary<uint, byte[]>>();  // To save different layer data encoded by RFX Prog Codec.
            RdpegfxRfxProgCodecBlockManagerDecorator blockMngr = new RdpegfxRfxProgCodecBlockManagerDecorator(currentTestType);

            surf.UpdateFromBitmap((System.Drawing.Bitmap)image);
            Dictionary<TileIndex, EncodedTile[]> tileDict = surf.ProgressiveEncode(quality, bProg, bSubDiff, bReduceExtrapolate, false);
            if(multipleTileInRegion)
            {
                layerTileList = ConvertTileDictToLayer(tileDict);
            }

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                this.bcgrAdapter.SimulatedScreen.RenderProgressiveCodec(surf.Id, tileDict, (ushort)image.Width, (ushort)image.Height);
            }

            if (bProg)  // Progressive codec is enabled
            {

                for (int i = 0; i < layerTileList.Count; i++)
                {
                    Dictionary<uint, byte[]> tileFrameDict = new Dictionary<uint, byte[]>();

                    fid = MakeStartFramePdu();
                    RFXProgCodecBlockType blockType = i == 0 ? RFXProgCodecBlockType.WBT_TILE_PROGRESSIVE_FIRST : RFXProgCodecBlockType.WBT_TILE_PROGRESSIVE_UPGRADE;
                    byte[] tileUpgradeData = blockMngr.PackRfxProgCodecDataBlock(hasSync, hasContext, bSubDiff, bReduceExtrapolate, layerTileList[i], blockType);
                    MakeWireToSurfacePdu2(surf.Id, pixFormat, tileUpgradeData);

                    MakeEndFramePdu(fid);

                    // Save frame into encoded tile first frame Dictionary
                    tileFrameDict.Add(fid, EncodePdusToSent());

                    // Add tile first frames into layer data list
                    layerDataList.Add(tileFrameDict);
                }
            }
            else  // Non-progressive encoding(i.e. tile_simple)
            {

                Dictionary<uint, byte[]> tileSimpleFrameDict = new Dictionary<uint, byte[]>();
                fid = MakeStartFramePdu();

                foreach (Dictionary<TileIndex, EncodedTile> layerTileDict in layerTileList)
                {
                    byte[] tileUpgradeData = blockMngr.PackRfxProgCodecDataBlock(hasSync, hasContext, bSubDiff, bReduceExtrapolate, layerTileDict, RFXProgCodecBlockType.WBT_TILE_SIMPLE);
                    MakeWireToSurfacePdu2(surf.Id, pixFormat, tileUpgradeData);
                }

                MakeEndFramePdu(fid);

                // Save frame into encoded tile simple frame Dictionary
                tileSimpleFrameDict.Add(fid, EncodePdusToSent());

                // Add tile first frames into layer data list
                layerDataList.Add(tileSimpleFrameDict);
            }
            return layerDataList;
        }
        /// <summary>
        /// Send RFX Progressive codec Pdu without image data to client.
        /// </summary>
        /// <param name="sId"> The surface Id that bitmap image is sent to </param>
        /// <param name="pixFormat">The pixel format to draw surface.</param>
        /// <param name="hasSync">Indicates if sync block exists in FRX Progressive bitmap stream.</param>
        /// <param name="hasContext">Indicates if context block exists in FRX Progressive bitmap stream.</param>
        /// <param name="bSubDiff">Indicates if sub-diffing with last frame of this surface</param>
        /// <returns> Frame Id </returns>
        public uint SendRfxProgressiveCodecPduWithoutImage(ushort sId, PixelFormat pixFormat, bool hasSync, bool hasContext, bool bSubDiff)
        {
            uint fid = MakeStartFramePdu();
            RdpegfxRfxProgCodecBlockManagerDecorator blockMngr = new RdpegfxRfxProgCodecBlockManagerDecorator(currentTestType);

            // No image in w2s_2 pdu, encoding rfx progressive data block without region and tile blocks
            byte[] blockdata = blockMngr.PackRfxProgCodecDataBlock(hasSync, hasContext, bSubDiff);
            MakeWireToSurfacePdu2(sId, pixFormat, blockdata);
            MakeEndFramePdu(fid);
            PackAndSendServerPdu();
            return fid;
        }