/// <summary>
        /// Decode one PDU
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static RdpegfxPdu DecodeSinglePdu(byte[] data)
        {
            RdpegfxPdu pdu     = new RdpegfxPdu();
            bool       fResult = PduMarshaler.Unmarshal(data, pdu);

            if (fResult)
            {
                RdpegfxServerPdu receivedPdu = null;
                if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_WIRETOSURFACE_1)
                {
                    receivedPdu = new RDPGFX_WIRE_TO_SURFACE_PDU_1();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_WIRETOSURFACE_2)
                {
                    receivedPdu = new RDPGFX_WIRE_TO_SURFACE_PDU_2();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_DELETEENCODINGCONTEXT)
                {
                    receivedPdu = new RDPGFX_DELETE_ENCODING_CONTEXT();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_SOLIDFILL)
                {
                    receivedPdu = new RDPGFX_SOLIDFILL();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_SURFACETOSURFACE)
                {
                    receivedPdu = new RDPGFX_SURFACE_TO_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_SURFACETOCACHE)
                {
                    receivedPdu = new RDPGFX_SURFACE_TO_CACHE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CACHETOSURFACE)
                {
                    receivedPdu = new RDPGFX_CACHE_TO_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_EVICTCACHEENTRY)
                {
                    receivedPdu = new RDPGFX_EVICT_CACHE_ENTRY();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CREATESURFACE)
                {
                    receivedPdu = new RDPGFX_CREATE_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_DELETESURFACE)
                {
                    receivedPdu = new RDPGFX_DELETE_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_STARTFRAME)
                {
                    receivedPdu = new RDPGFX_START_FRAME();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_ENDFRAME)
                {
                    receivedPdu = new RDPGFX_END_FRAME();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_RESETGRAPHICS)
                {
                    receivedPdu = new RDPGFX_RESET_GRAPHICS();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOOUTPUT)
                {
                    receivedPdu = new RDPGFX_MAPSURFACE_TO_OUTPUT();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CACHEIMPORTREPLY)
                {
                    receivedPdu = new RDPGFX_CACHE_IMPORT_REPLY();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CAPSCONFIRM)
                {
                    receivedPdu = new RDPGFX_CAPS_CONFIRM();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOWINDOW)
                {
                    receivedPdu = new RDPGFX_MAP_SURFACE_TO_WINDOW();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE)
                {
                    receivedPdu = new RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOSCALEDOUTPUT)
                {
                    receivedPdu = new RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOSCALEDWINDOW)
                {
                    receivedPdu = new RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU();
                }

                if (receivedPdu != null && PduMarshaler.Unmarshal(data, receivedPdu))
                {
                    return(receivedPdu);
                }
            }
            RdpegfxUnkownPdu unkown = new RdpegfxUnkownPdu();

            PduMarshaler.Unmarshal(data, unkown);
            return(unkown);
        }
        /// <summary>
        /// Create a wire to surface Pdu1.
        /// </summary>
        /// <param name="sId">This is used to indicate the target surface id.</param>
        /// <param name="cId">This is used to indicate the codecId.</param>
        /// <param name="pixFormat">This is used to indicate the pixel format to fill target surface.</param>
        /// <param name="bmRect">This is used to indicate border of bitmap on target surface.</param>
        /// <param name="bmLen">This is used to indicate the length of bitmap data.</param>
        /// <param name="bmData">This is used to indicate the bitmap data encoded by cId codec.</param>
        public RDPGFX_WIRE_TO_SURFACE_PDU_1 CreateWireToSurfacePdu1(ushort sId, CodecType cId, PixelFormat pixFormat, RDPGFX_RECT16 bmRect, byte[] bmData)
        {
            RDPGFX_WIRE_TO_SURFACE_PDU_1 wireToSurf1 = new RDPGFX_WIRE_TO_SURFACE_PDU_1(sId, cId, pixFormat, bmRect, bmData);

            return(wireToSurf1);
        }