예제 #1
0
        protected unsafe WriteableBitmap DecodeData(byte *codecBuffer, uint length, Dispatcher dispatcher, IEnumerable <IWriteableBitmapModifierTask> modifierTasks)
        {
            if (length < 20)
            {
                return(_decodedBitmap);
            }

            var modifyingTasks = modifierTasks?.ToArray();

            if (modifyingTasks?.Length == 0)
            {
                modifyingTasks = null;
            }

            ImageMetadata metadata;
            PixelFormat   pixelFormat;
            int           width;
            int           height;

            var    position         = RemoteDesktopDataInfo.ReadHeader(codecBuffer, out metadata, out pixelFormat, out width, out height);
            var    pixelSize        = GetPixelSize(pixelFormat);
            IntPtr backBuffer       = IntPtr.Zero;
            int    backBufferStride = 0;

            if (_decodedBitmap == null)
            {
                dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() =>
                {
                    _decodedBitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr32, null);
                    _decodedBitmap.Lock();
                    backBuffer       = _decodedBitmap.BackBuffer;
                    backBufferStride = _decodedBitmap.BackBufferStride;
                })).Wait();
            }
            else
                dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() =>
                {
                    _decodedBitmap.Lock();
                    backBuffer       = _decodedBitmap.BackBuffer;
                    backBufferStride = _decodedBitmap.BackBufferStride;
                })).Wait(); }
예제 #2
0
        protected virtual unsafe RemoteDesktopDataInfo WriteChanges(Rectangle[] changedAreas, MovedRegion[] movedRegions,
                                                                    int pixelSize, byte *imageBuffer, PixelFormat pixelFormat, Size imageSize, int imageStride)
        {
            MemoryStream memoryStream = null;

            byte[][] dataArrays         = null;
            var      changedAreasLength = changedAreas?.Length ?? 0;
            var      movedRegionsLength = movedRegions?.Length ?? 0;

            FrameInfo[] frames = null;

            if ((ImageCompression.CompressionMode & CompressionMode.Stream) == CompressionMode.Stream)
            {
                memoryStream = new MemoryStream(_encodeBuffer.Length / 200);
                RemoteDesktopDataInfo.WriteHeader(pixelFormat, ImageMetadata.Frames, imageSize.Width, imageSize.Height, memoryStream);
            }
            else if ((ImageCompression.CompressionMode & CompressionMode.ByteArray) == CompressionMode.ByteArray)
            {
                dataArrays = new byte[changedAreasLength + movedRegionsLength][];
                frames     = new FrameInfo[changedAreasLength + movedRegionsLength];
            }
            else
            {
                throw new NotSupportedException(ImageCompression.CompressionMode.ToString());
            }

            if (movedRegions != null)
            {
                for (int i = 0; i < movedRegions.Length; i++)
                {
                    var movedRegion = movedRegions[i];

                    if (memoryStream != null)
                    {
                        RemoteDesktopDataInfo.WriteFrameInfo(movedRegion.Destination, 8, FrameFlags.MovedRegion, memoryStream);

                        memoryStream.Write(BitConverter.GetBytes(movedRegion.Source.X), 0, 4);
                        memoryStream.Write(BitConverter.GetBytes(movedRegion.Source.Y), 0, 4);
                    }
                    else
                    {
                        var data = new byte[8];
                        Buffer.BlockCopy(BitConverter.GetBytes(movedRegion.Source.X), 0, data, 0, 4);
                        Buffer.BlockCopy(BitConverter.GetBytes(movedRegion.Source.Y), 0, data, 4, 4);

                        dataArrays[i] = data;
                        frames[i]     = new FrameInfo(movedRegion.Destination, FrameFlags.MovedRegion);
                    }
                }
            }

            if (changedAreas != null)
            {
                for (int i = 0; i < changedAreas.Length; i++)
                {
                    var blockArea    = changedAreas[i];
                    var blockStride  = blockArea.Width * pixelSize;
                    var blockPointer = Marshal.AllocHGlobal(blockStride * blockArea.Height);

                    try
                    {
                        //build bitmap in memory
                        for (int j = 0, offset = 0; j < blockArea.Height; j++)
                        {
                            int blockOffset = imageStride * (blockArea.Y + j) + pixelSize * blockArea.X;
                            CoreMemoryApi.memcpy(blockPointer.Add(offset), (IntPtr)(imageBuffer + blockOffset),
                                                 (UIntPtr)blockStride);
                            offset += blockStride;
                        }

                        if (memoryStream != null)
                        {
                            RemoteDesktopDataInfo.WriteFrameInfo(blockArea, 0, FrameFlags.UpdatedRegion, memoryStream);
                            var framePos = memoryStream.Position;
                            ImageCompression.Compress(blockPointer, blockStride, blockArea.Size, pixelFormat,
                                                      memoryStream);

                            var currentPos = memoryStream.Position;
                            memoryStream.Position = framePos - 4;
                            memoryStream.Write(BitConverter.GetBytes(currentPos - framePos), 0, 4);
                            memoryStream.Position = currentPos;
                        }
                        else
                        {
                            dataArrays[i + movedRegionsLength] = ImageCompression.Compress(blockPointer, blockStride,
                                                                                           blockArea.Size, pixelFormat);
                            frames[i + movedRegionsLength] = new FrameInfo(blockArea, FrameFlags.UpdatedRegion);
                        }
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(blockPointer);
                    }
                }
            }

            if (memoryStream != null)
            {
                using (memoryStream)
                    return(new RemoteDesktopDataInfo(memoryStream.ToArray()));
            }

            return(new RemoteDesktopDataInfo(dataArrays, frames,
                                             new HeaderInfo(ImageMetadata.Frames, pixelFormat, imageSize.Width, imageSize.Height)));
        }