Ejemplo n.º 1
0
        /// <summary>
        /// Verification helpers
        /// </summary>
        private void VerifyState(
            bool isFinished,
            bool hasResult,
            CloseableReference <object> resultRef,
            bool hasFailed,
            Exception failureCause)
        {
            IDataSource <CloseableReference <object> > dataSource = _dataSource;

            Assert.IsTrue(isFinished == dataSource.IsFinished(), "isFinished");
            Assert.IsTrue(hasResult == dataSource.HasResult(), "hasResult");
            CloseableReference <object> dataSourceRef = dataSource.GetResult();

            AssertReferencesSame("getResult", resultRef, dataSourceRef);
            CloseableReference <object> .CloseSafely(dataSourceRef);

            Assert.IsTrue(hasFailed == dataSource.HasFailed(), "hasFailed");
            if (failureCause == NPE)
            {
                Assert.IsNotNull(dataSource.GetFailureCause(), "failure");
                Assert.IsTrue(dataSource.GetFailureCause().GetType() == typeof(NullReferenceException), "failure");
            }
            else
            {
                Assert.AreSame(failureCause, dataSource.GetFailureCause(), "failure");
            }
        }
        /// <summary>
        /// Called whenever a new value is ready to be retrieved from
        /// the IDataSource.
        /// </summary>
        public override async Task OnNewResultImpl(
            IDataSource <CloseableReference <CloseableImage> > dataSource)
        {
            if (!dataSource.IsFinished())
            {
                return;
            }

            CloseableReference <CloseableImage> closeableImageRef = dataSource.GetResult();
            SoftwareBitmap bitmap = null;

            if (closeableImageRef != null &&
                (closeableImageRef.Get().GetType() == typeof(CloseableBitmap) ||
                 closeableImageRef.Get().GetType() == typeof(CloseableStaticBitmap)))
            {
                bitmap = ((CloseableBitmap)closeableImageRef.Get()).UnderlyingBitmap;
            }

            try
            {
                await OnNewResultImpl(bitmap).ConfigureAwait(false);
            }
            finally
            {
                CloseableReference <CloseableImage> .CloseSafely(closeableImageRef);
            }
        }
        /// <summary>
        /// Creates a memory-backed encoded image from the stream.
        /// The stream is closed.
        /// </summary>
        protected EncodedImage GetByteBufferBackedEncodedImage(Stream inputStream, int length)
        {
            var reference = default(CloseableReference <IPooledByteBuffer>);

            try
            {
                if (length <= 0)
                {
                    reference = CloseableReference <IPooledByteBuffer> .of(
                        _pooledByteBufferFactory.NewByteBuffer(inputStream));
                }
                else
                {
                    reference = CloseableReference <IPooledByteBuffer> .of(
                        _pooledByteBufferFactory.NewByteBuffer(inputStream, length));
                }

                return(new EncodedImage(reference));
            }
            finally
            {
                Closeables.CloseQuietly(inputStream);
                CloseableReference <IPooledByteBuffer> .CloseSafely(reference);
            }
        }
Ejemplo n.º 4
0
            private void SubmitPostprocessing()
            {
                _parent._executor.Execute(() =>
                {
                    CloseableReference <CloseableImage> closeableImageRef;
                    bool isLast;
                    lock (_gate)
                    {
                        // instead of cloning and closing the reference, we do a more
                        // efficient move.
                        closeableImageRef = _sourceImageRef;
                        isLast            = _isLast;
                        _sourceImageRef   = null;
                        _isDirty          = false;
                    }

                    if (CloseableReference <CloseableImage> .IsValid(closeableImageRef))
                    {
                        try
                        {
                            DoPostprocessing(closeableImageRef, isLast);
                        }
                        finally
                        {
                            CloseableReference <CloseableImage> .CloseSafely(closeableImageRef);
                        }
                    }

                    ClearRunningAndStartIfDirty();
                });
            }
Ejemplo n.º 5
0
        /// <summary>
        /// Returns a new CloseableReference to the same underlying
        /// SharedReference or null if invalid. The SharedReference
        /// ref-count is incremented.
        /// </summary>
        public EncodedImage CloneOrNull()
        {
            EncodedImage encodedImage;

            if (_inputStreamSupplier != null)
            {
                encodedImage = new EncodedImage(_inputStreamSupplier, StreamSize);
            }
            else
            {
                CloseableReference <IPooledByteBuffer> pooledByteBufferRef =
                    CloseableReference <IPooledByteBuffer> .CloneOrNull(_pooledByteBufferRef);

                try
                {
                    encodedImage = (pooledByteBufferRef == null) ?
                                   null :
                                   new EncodedImage(pooledByteBufferRef);
                }
                finally
                {
                    // Close the recently created reference since it will be
                    // cloned again in the constructor.
                    CloseableReference <IPooledByteBuffer> .CloseSafely(pooledByteBufferRef);
                }
            }

            if (encodedImage != null)
            {
                encodedImage.CopyMetaDataFrom(this);
            }

            return(encodedImage);
        }
Ejemplo n.º 6
0
            private void UpdateSourceImageRef(
                CloseableReference <CloseableImage> sourceImageRef,
                bool isLast)
            {
                CloseableReference <CloseableImage> oldSourceImageRef;
                bool shouldSubmit;

                lock (_gate)
                {
                    if (_isClosed)
                    {
                        return;
                    }

                    oldSourceImageRef = _sourceImageRef;
                    _sourceImageRef   = CloseableReference <CloseableImage> .CloneOrNull(sourceImageRef);

                    _isLast      = isLast;
                    _isDirty     = true;
                    shouldSubmit = SetRunningIfDirtyAndNotRunning();
                }

                CloseableReference <CloseableImage> .CloseSafely(oldSourceImageRef);

                if (shouldSubmit)
                {
                    SubmitPostprocessing();
                }
            }
Ejemplo n.º 7
0
        /// <summary>
        /// Closes the stream. Owned resources are released back to the pool.
        /// It is not allowed to call ToByteBuffer after call to this method.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            CloseableReference <NativeMemoryChunk> .CloseSafely(_bufRef);

            _bufRef = null;
            _count  = -1;
        }
        /// <summary>
        /// Cleanup resources.
        /// </summary>
        private void Dispose(bool disposing)
        {
            lock (_poolGate)
            {
                CloseableReference <NativeMemoryChunk> .CloseSafely(_bufRef);

                _bufRef = null;
            }
        }
 /// <summary>
 /// Notifies the client that the cache no longer tracks the given items.
 ///
 /// <para />This method invokes the external
 /// <see cref="CloseableReference{V}.Dispose"/> method, so it must not
 /// be called while holding the <code>_cacheGate</code> lock.
 /// </summary>
 private void MaybeClose(IList <Entry> oldEntries)
 {
     if (oldEntries != null)
     {
         foreach (Entry oldEntry in oldEntries)
         {
             CloseableReference <V> .CloseSafely(ReferenceToClose(oldEntry));
         }
     }
 }
        public void getSize(string uriString, IPromise promise)
        {
            if (string.IsNullOrEmpty(uriString))
            {
                promise.Reject(ErrorInvalidUri, "Cannot get the size of an image for an empty URI.");
                return;
            }

            var uri            = new Uri(uriString);
            var imagePipeline  = ImagePipelineFactory.Instance.GetImagePipeline();
            var request        = ImageRequestBuilder.NewBuilderWithSource(uri).Build();
            var dataSource     = imagePipeline.FetchDecodedImage(request, null);
            var dataSubscriber = new BaseDataSubscriberImpl <CloseableReference <CloseableImage> >(
                response =>
            {
                if (!response.IsFinished())
                {
                    return(Task.CompletedTask);
                }

                CloseableReference <CloseableImage> reference = response.GetResult();
                if (reference != null)
                {
                    try
                    {
                        CloseableImage image = reference.Get();
                        promise.Resolve(new JObject
                        {
                            { "width", image.Width },
                            { "height", image.Height },
                        });
                    }
                    catch (Exception ex)
                    {
                        promise.Reject(ErrorGetSizeFailure, ex.Message);
                    }
                    finally
                    {
                        CloseableReference <CloseableImage> .CloseSafely(reference);
                    }
                }
                else
                {
                    promise.Reject(ErrorGetSizeFailure, Invariant($"Invalid URI '{uri}' provided."));
                }

                return(Task.CompletedTask);
            },
                response =>
            {
                promise.Reject(ErrorGetSizeFailure, response.GetFailureCause());
            });

            dataSource.Subscribe(dataSubscriber, FBCore.Concurrency.CallerThreadExecutor.Instance);
        }
        private Task <EncodedImage> GetAsync(ICacheKey key, AtomicBoolean isCancelled)
        {
            try
            {
                if (isCancelled.Value)
                {
                    throw new OperationCanceledException();
                }

                EncodedImage result = _stagingArea.Get(key);
                if (result != null)
                {
                    Debug.WriteLine($"Found image for { key.ToString() } in staging area");
                    _imageCacheStatsTracker.OnStagingAreaHit();
                }
                else
                {
                    Debug.WriteLine($"Did not find image for { key.ToString() } in staging area");
                    _imageCacheStatsTracker.OnStagingAreaMiss();
                    try
                    {
                        IPooledByteBuffer buffer = ReadFromDiskCache(key);
                        if (buffer == null)
                        {
                            return(Task.FromResult(default(EncodedImage)));
                        }

                        CloseableReference <IPooledByteBuffer> reference =
                            CloseableReference <IPooledByteBuffer> .of(buffer);

                        try
                        {
                            result = new EncodedImage(reference);
                        }
                        finally
                        {
                            CloseableReference <IPooledByteBuffer> .CloseSafely(reference);
                        }
                    }
                    catch (Exception)
                    {
                        return(Task.FromResult(default(EncodedImage)));
                    }
                }

                return(Task.FromResult(result));
            }
            catch (Exception)
            {
                // Log failure
                // TODO: 3697790
                Debug.WriteLine($"Failed to schedule disk-cache read for { key.ToString() }");
                throw;
            }
        }
            protected override void OnNewResultImpl(EncodedImage newResult, bool isLast)
            {
                // Intermediate or null results are not cached, so we just forward them
                if (!isLast || newResult == null)
                {
                    Consumer.OnNewResult(newResult, isLast);
                    return;
                }

                // Cache and forward the last result
                CloseableReference <IPooledByteBuffer> reference = newResult.GetByteBufferRef();

                if (reference != null)
                {
                    CloseableReference <IPooledByteBuffer> cachedResult;

                    try
                    {
                        cachedResult = _memoryCache.Cache(_cacheKey, reference);
                    }
                    finally
                    {
                        CloseableReference <IPooledByteBuffer> .CloseSafely(reference);
                    }

                    if (cachedResult != null)
                    {
                        EncodedImage cachedEncodedImage;
                        try
                        {
                            cachedEncodedImage = new EncodedImage(cachedResult);
                            cachedEncodedImage.CopyMetaDataFrom(newResult);
                        }
                        finally
                        {
                            CloseableReference <IPooledByteBuffer> .CloseSafely(cachedResult);
                        }

                        try
                        {
                            Consumer.OnProgressUpdate(1f);
                            Consumer.OnNewResult(cachedEncodedImage, true);
                            return;
                        }
                        finally
                        {
                            EncodedImage.CloseSafely(cachedEncodedImage);
                        }
                    }
                }

                Consumer.OnNewResult(newResult, true);
            }
Ejemplo n.º 13
0
            /// <summary>
            /// Notifies consumer of new result and finishes if the result
            /// is final.
            /// </summary>
            private void HandleResult(CloseableImage decodedImage, bool isFinal)
            {
                var decodedImageRef = CloseableReference <CloseableImage> .of(decodedImage);

                try
                {
                    MaybeFinish(isFinal);
                    Consumer.OnNewResult(decodedImageRef, isFinal);
                }
                finally
                {
                    CloseableReference <CloseableImage> .CloseSafely(decodedImageRef);
                }
            }
Ejemplo n.º 14
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);
                    }
                }
        }
Ejemplo n.º 15
0
            private void SetSourceImageRef(CloseableReference <CloseableImage> sourceImageRef)
            {
                CloseableReference <CloseableImage> oldSourceImageRef;

                lock (_gate)
                {
                    if (_isClosed)
                    {
                        return;
                    }

                    oldSourceImageRef = _sourceImageRef;
                    _sourceImageRef   = CloseableReference <CloseableImage> .CloneOrNull(sourceImageRef);
                }

                CloseableReference <CloseableImage> .CloseSafely(oldSourceImageRef);
            }
Ejemplo n.º 16
0
            protected override void OnNewResultImpl(EncodedImage newResult, bool isLast)
            {
                CloseableReference <IPooledByteBuffer> ret = null;

                try
                {
                    if (EncodedImage.IsValid(newResult))
                    {
                        ret = newResult.GetByteBufferRef();
                    }

                    Consumer.OnNewResult(ret, isLast);
                }
                finally
                {
                    CloseableReference <IPooledByteBuffer> .CloseSafely(ret);
                }
            }
Ejemplo n.º 17
0
        public void TestFetchDecodedImageSuccess()
        {
            var completion     = new ManualResetEvent(false);
            var dataSource     = _imagePipeline.FetchDecodedImage(ImageRequest.FromUri(IMAGE_URL), null);
            var dataSubscriber = new BaseDataSubscriberImpl <CloseableReference <CloseableImage> >(
                async response =>
            {
                CloseableReference <CloseableImage> reference = response.GetResult();
                if (reference != null)
                {
                    SoftwareBitmap bitmap = ((CloseableBitmap)reference.Get()).UnderlyingBitmap;

                    try
                    {
                        Assert.IsTrue(bitmap.PixelWidth != 0);
                        Assert.IsTrue(bitmap.PixelHeight != 0);
                        Assert.IsTrue(_imagePipeline.IsInBitmapMemoryCache(ImageRequest.FromUri(IMAGE_URL)));
                        Assert.IsTrue(await _imagePipeline.IsInDiskCacheAsync(IMAGE_URL).ConfigureAwait(false));
                    }
                    catch (Exception)
                    {
                        Assert.Fail();
                    }
                    finally
                    {
                        CloseableReference <CloseableImage> .CloseSafely(reference);
                        completion.Set();
                    }
                }
                else
                {
                    Assert.Fail();
                    completion.Set();
                }
            },
                response =>
            {
                Assert.Fail();
                completion.Set();
            });

            dataSource.Subscribe(dataSubscriber, CallerThreadExecutor.Instance);
            completion.WaitOne();
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Called whenever a new value is ready to be retrieved from
        /// the IDataSource.
        /// </summary>
        public override async Task OnNewResultImpl(
            IDataSource <IList <CloseableReference <CloseableImage> > > dataSource)
        {
            if (!dataSource.IsFinished())
            {
                return;
            }

            IList <CloseableReference <CloseableImage> > imageRefList = dataSource.GetResult();

            if (imageRefList == null)
            {
                await OnNewResultListImpl(null).ConfigureAwait(false);

                return;
            }

            try
            {
                IList <SoftwareBitmap> bitmapList = new List <SoftwareBitmap>(imageRefList.Count);
                foreach (var closeableImageRef in imageRefList)
                {
                    if (closeableImageRef != null &&
                        closeableImageRef.Get().GetType() == typeof(CloseableBitmap))
                    {
                        bitmapList.Add(((CloseableBitmap)closeableImageRef.Get()).UnderlyingBitmap);
                    }
                    else
                    {
                        //This is so that client gets list with same length
                        bitmapList.Add(null);
                    }
                }

                await OnNewResultListImpl(bitmapList).ConfigureAwait(false);
            }
            finally
            {
                foreach (var closeableImageRef in imageRefList)
                {
                    CloseableReference <CloseableImage> .CloseSafely(closeableImageRef);
                }
            }
        }
        /// <summary>
        /// Returns whether the image is stored in the bitmap memory cache.
        /// </summary>
        /// <param name="imageRequest">
        /// The imageRequest for the image to be looked up.
        /// </param>
        /// <returns>
        /// true if the image was found in the bitmap memory cache,
        /// false otherwise.
        /// </returns>
        public bool IsInBitmapMemoryCache(ImageRequest imageRequest)
        {
            if (imageRequest == null)
            {
                return(false);
            }

            ICacheKey cacheKey = _cacheKeyFactory.GetBitmapCacheKey(imageRequest, null);
            CloseableReference <CloseableImage> reference = _bitmapMemoryCache.Get(cacheKey);

            try
            {
                return(CloseableReference <CloseableImage> .IsValid(reference));
            }
            finally
            {
                CloseableReference <CloseableImage> .CloseSafely(reference);
            }
        }
        /// <summary>
        /// Called when the client closes its reference.
        /// </summary>
        private void ReleaseClientReference(Entry entry)
        {
            Preconditions.CheckNotNull(entry);
            bool isExclusiveAdded;
            CloseableReference <V> oldRefToClose;

            lock (_cacheGate)
            {
                DecreaseClientCount(entry);
                isExclusiveAdded = MaybeAddToExclusives(entry);
                oldRefToClose    = ReferenceToClose(entry);
            }

            CloseableReference <V> .CloseSafely(oldRefToClose);

            MaybeNotifyExclusiveEntryInsertion(isExclusiveAdded ? entry : null);
            MaybeUpdateCacheParams();
            MaybeEvictEntries();
        }
Ejemplo n.º 21
0
        public void TestFetchEncodedImageSuccess()
        {
            var completion     = new ManualResetEvent(false);
            var dataSource     = _imagePipeline.FetchEncodedImage(ImageRequest.FromUri(IMAGE_URL), null);
            var dataSubscriber = new BaseDataSubscriberImpl <CloseableReference <IPooledByteBuffer> >(
                async response =>
            {
                CloseableReference <IPooledByteBuffer> reference = response.GetResult();
                if (reference != null)
                {
                    IPooledByteBuffer inputStream = reference.Get();

                    try
                    {
                        Assert.IsTrue(inputStream.Size != 0);
                        Assert.IsTrue(await _imagePipeline.IsInDiskCacheAsync(IMAGE_URL).ConfigureAwait(false));
                    }
                    catch (Exception)
                    {
                        Assert.Fail();
                    }
                    finally
                    {
                        CloseableReference <IPooledByteBuffer> .CloseSafely(reference);
                        completion.Set();
                    }
                }
                else
                {
                    Assert.Fail();
                    completion.Set();
                }
            },
                response =>
            {
                Assert.Fail();
                completion.Set();
            });

            dataSource.Subscribe(dataSubscriber, CallerThreadExecutor.Instance);
            completion.WaitOne();
        }
Ejemplo n.º 22
0
            private bool Close()
            {
                CloseableReference <CloseableImage> oldSourceImageRef;

                lock (_gate)
                {
                    if (_isClosed)
                    {
                        return(false);
                    }

                    oldSourceImageRef = _sourceImageRef;
                    _sourceImageRef   = null;
                    _isClosed         = true;
                }

                CloseableReference <CloseableImage> .CloseSafely(oldSourceImageRef);

                return(true);
            }
        private async Task <EncodedImage> BuildEncodedImage(
            IPooledByteBuffer imageBytes,
            IRandomAccessStream imageStream)
        {
            using (var stream = imageStream.AsStream())
            {
                Tuple <int, int> dimensions = await BitmapUtil
                                              .DecodeDimensionsAsync(stream)
                                              .ConfigureAwait(false);

                int rotationAngle = GetRotationAngle(stream);
                int width         = dimensions != default(Tuple <int, int>) ?
                                    dimensions.Item1 :
                                    EncodedImage.UNKNOWN_WIDTH;

                int height = dimensions != default(Tuple <int, int>) ?
                             dimensions.Item2 :
                             EncodedImage.UNKNOWN_HEIGHT;

                EncodedImage encodedImage;
                CloseableReference <IPooledByteBuffer> closeableByteBuffer =
                    CloseableReference <IPooledByteBuffer> .of(imageBytes);

                try
                {
                    encodedImage = new EncodedImage(closeableByteBuffer);
                }
                finally
                {
                    CloseableReference <IPooledByteBuffer> .CloseSafely(
                        closeableByteBuffer);
                }

                encodedImage.Format        = ImageFormat.JPEG;
                encodedImage.RotationAngle = rotationAngle;
                encodedImage.Width         = width;
                encodedImage.Height        = height;

                return(encodedImage);
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Removes key-value from the StagingArea. Both key and value must match.
        /// </summary>
        /// <param name="key">The cache key.</param>
        /// <param name="encodedImage">Value corresponding to key.</param>
        /// <returns>true if item was removed.</returns>
        public bool Remove(ICacheKey key, EncodedImage encodedImage)
        {
            lock (_mapGate)
            {
                Preconditions.CheckNotNull(key);
                Preconditions.CheckNotNull(encodedImage);
                Preconditions.CheckArgument(EncodedImage.IsValid(encodedImage));

                EncodedImage oldValue = default(EncodedImage);
                if (!_map.TryGetValue(key, out oldValue))
                {
                    return(false);
                }

                CloseableReference <IPooledByteBuffer> oldReference = oldValue.GetByteBufferRef();
                CloseableReference <IPooledByteBuffer> reference    = encodedImage.GetByteBufferRef();

                try
                {
                    if (oldReference == null || reference == null || oldReference.Get() != reference.Get())
                    {
                        return(false);
                    }

                    _map.Remove(key);
                }
                finally
                {
                    CloseableReference <IPooledByteBuffer> .CloseSafely(reference);

                    CloseableReference <IPooledByteBuffer> .CloseSafely(oldReference);

                    EncodedImage.CloseSafely(oldValue);
                }

#if DEBUG_STAGING_AREA
                LogStats();
#endif // DEBUG_STAGING_AREA
                return(true);
            }
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Clients should override this method only if the post-processed
        /// bitmap has to be of a different size than the source bitmap.
        /// If the post-processed bitmap is of the same size, clients should
        /// override one of the other two methods.
        ///
        /// <para />The source bitmap must not be modified as it may be shared
        /// by the other clients. The implementation must create a new bitmap
        /// that is safe to be modified and return a reference to it.
        /// Clients should use <code>bitmapFactory</code> to create a new bitmap.
        /// </summary>
        /// <param name="sourceBitmap">The source bitmap.</param>
        /// <param name="bitmapFactory">
        /// The factory to create a destination bitmap.
        /// </param>
        /// <param name="flexByteArrayPool">
        /// The memory pool used for post process.
        /// </param>
        /// <returns>
        /// A reference to the newly created bitmap.
        /// </returns>
        public CloseableReference <SoftwareBitmap> Process(
            SoftwareBitmap sourceBitmap,
            PlatformBitmapFactory bitmapFactory,
            FlexByteArrayPool flexByteArrayPool)
        {
            CloseableReference <SoftwareBitmap> destBitmapRef =
                bitmapFactory.CreateBitmapInternal(
                    sourceBitmap.PixelWidth,
                    sourceBitmap.PixelHeight,
                    sourceBitmap.BitmapPixelFormat);

            try
            {
                Process(destBitmapRef.Get(), sourceBitmap, flexByteArrayPool);
                return(CloseableReference <SoftwareBitmap> .CloneOrNull(destBitmapRef));
            }
            finally
            {
                CloseableReference <SoftwareBitmap> .CloseSafely(destBitmapRef);
            }
        }
        /// <summary>
        /// Caches the given key-value pair.
        ///
        /// <para />Important: the client should use the returned reference
        /// instead of the original one. It is the caller's responsibility
        /// to close the returned reference once not needed anymore.
        /// </summary>
        /// <returns>
        /// The new reference to be used, null if the value cannot be cached.
        /// </returns>
        public CloseableReference <V> Cache(
            K key,
            CloseableReference <V> valueRef,
            IEntryStateObserver <K> observer)
        {
            Preconditions.CheckNotNull(key);
            Preconditions.CheckNotNull(valueRef);

            MaybeUpdateCacheParams();

            Entry oldExclusive;
            CloseableReference <V> oldRefToClose = null;
            CloseableReference <V> clientRef     = null;

            lock (_cacheGate)
            {
                // Remove the old item (if any) as it is stale now
                oldExclusive = _exclusiveEntries.Remove(key);
                Entry oldEntry = _cachedEntries.Remove(key);
                if (oldEntry != null)
                {
                    MakeOrphan(oldEntry);
                    oldRefToClose = ReferenceToClose(oldEntry);
                }

                if (CanCacheNewValue(valueRef.Get()))
                {
                    Entry newEntry = Entry.of(key, valueRef, observer);
                    _cachedEntries.Put(key, newEntry);
                    clientRef = NewClientReference(newEntry);
                }
            }

            CloseableReference <V> .CloseSafely(oldRefToClose);

            MaybeNotifyExclusiveEntryRemoval(oldExclusive);

            MaybeEvictEntries();
            return(clientRef);
        }
Ejemplo n.º 27
0
            private void DoPostprocessing(
                CloseableReference <CloseableImage> sourceImageRef,
                bool isLast)
            {
                Preconditions.CheckArgument(CloseableReference <CloseableImage> .IsValid(sourceImageRef));
                if (!ShouldPostprocess(sourceImageRef.Get()))
                {
                    MaybeNotifyOnNewResult(sourceImageRef, isLast);
                    return;
                }

                _listener.OnProducerStart(_requestId, NAME);
                CloseableReference <CloseableImage> destImageRef = null;

                try
                {
                    try
                    {
                        destImageRef = PostprocessInternal(sourceImageRef.Get());
                    }
                    catch (Exception e)
                    {
                        _listener.OnProducerFinishWithFailure(
                            _requestId, NAME, e, GetExtraMap(_listener, _requestId, _postprocessor));

                        MaybeNotifyOnFailure(e);
                        return;
                    }

                    _listener.OnProducerFinishWithSuccess(
                        _requestId, NAME, GetExtraMap(_listener, _requestId, _postprocessor));

                    MaybeNotifyOnNewResult(destImageRef, isLast);
                }
                finally
                {
                    CloseableReference <CloseableImage> .CloseSafely(destImageRef);
                }
            }
Ejemplo n.º 28
0
            private CloseableReference <CloseableImage> PostprocessInternal(CloseableImage sourceImage)
            {
                CloseableStaticBitmap staticBitmap            = (CloseableStaticBitmap)sourceImage;
                SoftwareBitmap        sourceBitmap            = staticBitmap.UnderlyingBitmap;
                CloseableReference <SoftwareBitmap> bitmapRef =
                    _postprocessor.Process(
                        sourceBitmap,
                        _parent._bitmapFactory,
                        _parent._flexByteArrayPool);

                int rotationAngle = staticBitmap.RotationAngle;

                try
                {
                    return(CloseableReference <CloseableImage> .of(
                               new CloseableStaticBitmap(bitmapRef, sourceImage.QualityInfo, rotationAngle)));
                }
                finally
                {
                    CloseableReference <SoftwareBitmap> .CloseSafely(bitmapRef);
                }
            }
        private void NotifyConsumer(
            PooledByteBufferOutputStream pooledOutputStream,
            bool isFinal,
            IConsumer <EncodedImage> consumer)
        {
            CloseableReference <IPooledByteBuffer> result =
                CloseableReference <IPooledByteBuffer> .of(pooledOutputStream.ToByteBuffer());

            EncodedImage encodedImage = null;

            try
            {
                encodedImage = new EncodedImage(result);
                encodedImage.ParseMetaDataAsync().Wait();
                consumer.OnNewResult(encodedImage, isFinal);
            }
            finally
            {
                EncodedImage.CloseSafely(encodedImage);
                CloseableReference <IPooledByteBuffer> .CloseSafely(result);
            }
        }
Ejemplo n.º 30
0
            private void UpdateInternal()
            {
                CloseableReference <CloseableImage> sourceImageRef;

                lock (_gate)
                {
                    if (_isClosed)
                    {
                        return;
                    }

                    sourceImageRef = CloseableReference <CloseableImage> .CloneOrNull(_sourceImageRef);
                }

                try
                {
                    Consumer.OnNewResult(sourceImageRef, false /* isLast */);
                }
                finally
                {
                    CloseableReference <CloseableImage> .CloseSafely(sourceImageRef);
                }
            }