Example #1
0
        public void TestGet()
        {
            CloseableReference <byte[]> arrayRef = _pool.Get(1);

            Assert.AreEqual(0, _delegatePool._freeCounter.NumBytes);
            Assert.AreEqual(MIN_BUFFER_SIZE, arrayRef.Get().Length);
        }
Example #2
0
        /// <summary>
        /// Clients should override this method if the post-processing cannot be
        /// done in place. If the post-processing can be done in place, clients
        /// should override the
        /// Process(byte[], int, int, BitmapPixelFormat, BitmapAlphaMode) method.
        ///
        /// <para />The provided destination bitmap is of the same size as the
        /// source bitmap. There are no guarantees on the initial content of the
        /// destination bitmap, so the implementation has to make sure that it
        /// properly populates it.
        ///
        /// <para />The source bitmap must not be modified as it may be shared
        /// by the other clients. The implementation must use the provided
        /// destination bitmap as its output.
        /// </summary>
        /// <param name="destBitmap">
        /// The destination bitmap to be used as output.
        /// </param>
        /// <param name="sourceBitmap">
        /// The source bitmap to be used as input.
        /// </param>
        /// <param name="flexByteArrayPool">
        /// The memory pool used for post process.
        /// </param>
        public unsafe virtual void Process(
            SoftwareBitmap destBitmap,
            SoftwareBitmap sourceBitmap,
            FlexByteArrayPool flexByteArrayPool)
        {
            Preconditions.CheckArgument(sourceBitmap.BitmapPixelFormat == destBitmap.BitmapPixelFormat);
            Preconditions.CheckArgument(!destBitmap.IsReadOnly);
            Preconditions.CheckArgument(destBitmap.PixelWidth == sourceBitmap.PixelWidth);
            Preconditions.CheckArgument(destBitmap.PixelHeight == sourceBitmap.PixelHeight);
            sourceBitmap.CopyTo(destBitmap);

            using (var buffer = destBitmap.LockBuffer(BitmapBufferAccessMode.Write))
                using (var reference = buffer.CreateReference())
                {
                    // Get input data
                    byte *srcData;
                    uint  capacity;
                    ((IMemoryBufferByteAccess)reference).GetBuffer(out srcData, out capacity);

                    // Allocate temp buffer for processing
                    byte[] desData = default(byte[]);
                    CloseableReference <byte[]> bytesArrayRef = default(CloseableReference <byte[]>);

                    try
                    {
                        bytesArrayRef = flexByteArrayPool.Get((int)capacity);
                        desData       = bytesArrayRef.Get();
                    }
                    catch (Exception)
                    {
                        // Allocates the byte array since the pool couldn't provide one
                        desData = new byte[capacity];
                    }

                    try
                    {
                        // Process output data
                        Marshal.Copy((IntPtr)srcData, desData, 0, (int)capacity);
                        Process(desData, destBitmap.PixelWidth, destBitmap.PixelHeight,
                                destBitmap.BitmapPixelFormat, destBitmap.BitmapAlphaMode);

                        Marshal.Copy(desData, 0, (IntPtr)srcData, (int)capacity);
                    }
                    finally
                    {
                        CloseableReference <byte[]> .CloseSafely(bytesArrayRef);
                    }
                }
        }
        /// <summary>
        /// Fetches the encoded BitmapImage.
        /// </summary>
        /// <param name="uri">The image uri.</param>
        /// <param name="token">The cancellation token.</param>
        /// <param name="dispatcher">
        /// The current view's dispatcher, used to create BitmapImage.
        /// </param>
        /// <returns>The encoded BitmapImage.</returns>
        /// <exception cref="IOException">
        /// If the image uri can't be found.
        /// </exception>
        public Task <BitmapImage> FetchEncodedBitmapImageAsync(
            Uri uri,
            CancellationToken token   = default(CancellationToken),
            CoreDispatcher dispatcher = null)
        {
            var taskCompletionSource = new TaskCompletionSource <BitmapImage>();
            var dataSource           = FetchEncodedImage(ImageRequest.FromUri(uri), null);
            var dataSubscriber       = new BaseDataSubscriberImpl <CloseableReference <IPooledByteBuffer> >(
                async response =>
            {
                CloseableReference <IPooledByteBuffer> reference = response.GetResult();
                if (reference != null)
                {
                    //----------------------------------------------------------------------
                    // Phong Cao: InMemoryRandomAccessStream can't write anything < 16KB.
                    // http://stackoverflow.com/questions/25928408/inmemoryrandomaccessstream-incorrect-behavior
                    //----------------------------------------------------------------------
                    IPooledByteBuffer inputStream = reference.Get();
                    int supportedSize             = Math.Max(16 * ByteConstants.KB, inputStream.Size);

                    // Allocate temp buffer for stream convert
                    byte[] bytesArray = default(byte[]);
                    CloseableReference <byte[]> bytesArrayRef = default(CloseableReference <byte[]>);

                    try
                    {
                        bytesArrayRef = _flexByteArrayPool.Get(supportedSize);
                        bytesArray    = bytesArrayRef.Get();
                    }
                    catch (Exception)
                    {
                        // Allocates the byte array since the pool couldn't provide one
                        bytesArray = new byte[supportedSize];
                    }

                    try
                    {
                        inputStream.Read(0, bytesArray, 0, inputStream.Size);
                        await DispatcherHelpers.CallOnDispatcherAsync(async() =>
                        {
                            using (var outStream = new InMemoryRandomAccessStream())
                                using (var writeStream = outStream.AsStreamForWrite())
                                {
                                    await writeStream.WriteAsync(bytesArray, 0, supportedSize);
                                    outStream.Seek(0);
                                    BitmapImage bitmapImage = new BitmapImage();
                                    await bitmapImage.SetSourceAsync(outStream).AsTask().ConfigureAwait(false);
                                    taskCompletionSource.SetResult(bitmapImage);
                                }
                        },
                                                                      dispatcher).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        taskCompletionSource.SetException(e);
                    }
                    finally
                    {
                        CloseableReference <IPooledByteBuffer> .CloseSafely(reference);
                        CloseableReference <byte[]> .CloseSafely(bytesArrayRef);
                    }
                }
                else
                {
                    taskCompletionSource.SetResult(null);
                }
            },
                response =>
            {
                taskCompletionSource.SetException(response.GetFailureCause());
            });

            dataSource.Subscribe(dataSubscriber, _handleResultExecutor);
            token.Register(() =>
            {
                dataSource.Close();
                taskCompletionSource.TrySetCanceled();
            });

            return(taskCompletionSource.Task);
        }