/// <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>
 /// 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="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;
        }