Exemplo n.º 1
0
            private void SwapCacheAndClear()
            {
                ImageCache temp;

                temp                 = _verticalCache;
                _verticalCache       = _backupVerticalCache;
                _backupVerticalCache = temp;
                temp.Clear();

                temp                   = _horizontalCache;
                _horizontalCache       = _backupHorizontalCache;
                _backupHorizontalCache = temp;
                temp.Clear();
            }
Exemplo n.º 2
0
            public async Task FillRegionAsync(int x, int y, Image <Rgb24> region, CancellationToken cancellationToken)
            {
                int layer = _ripper._layers.Length - 1;

                int tileYIndex  = y / _deepZoomTileSize;
                int tileYOffset = tileYIndex * _deepZoomTileSize;
                int tileYCount  = (y - tileYOffset + region.Height + _deepZoomTileSize - 1) / _deepZoomTileSize;

                tileYCount = Math.Min(tileYCount, _deepZoomTileRowCount - tileYIndex);

                int tileXIndex  = x / _deepZoomTileSize;
                int tileXOffset = tileXIndex * _deepZoomTileSize;
                int tileXCount  = (x - tileXOffset + region.Width + _deepZoomTileSize - 1) / _deepZoomTileSize;

                tileXCount = Math.Min(tileXCount, _deepZoomTileColCount - tileXIndex);

                ImageCache nextVerticalCache   = _backupVerticalCache;
                ImageCache nextHorizontalCache = _backupHorizontalCache;

                for (int i = 0; i < tileXCount; i++)
                {
                    int tileCol = tileXIndex + i;

                    for (int j = 0; j < tileYCount; j++)
                    {
                        int tileRow = tileYIndex + j;

                        int tilePointX = tileXOffset + i * _deepZoomTileSize;
                        int tilePointY = tileYOffset + j * _deepZoomTileSize;

                        int drawPointX = tilePointX - x - _deepZoomTileOverlap;
                        int drawPointY = tilePointY - y - _deepZoomTileOverlap;

                        cancellationToken.ThrowIfCancellationRequested();

                        Image <Rgb24> tile       = null;
                        bool          cachedOnce = false;
                        try
                        {
                            // First column
                            if (i == 0)
                            {
                                if (_verticalCache.TryFind(tilePointX, tilePointY, out Image <Rgb24> cachedImage))
                                {
                                    _verticalCache.RemoveEntry(tilePointX, tilePointY);
                                    tile = cachedImage;
                                }
                            }
                            // First row
                            if (tile == null && j == 0)
                            {
                                if (_horizontalCache.TryFind(tilePointX, tilePointY, out Image <Rgb24> cachedImage))
                                {
                                    _horizontalCache.RemoveEntry(tilePointX, tilePointY);
                                    tile = cachedImage;
                                }
                            }

                            // Not found in the cache
                            if (tile == null)
                            {
                                tile = await _ripper.ReadTileImageAsync(layer, tileCol, tileRow, cancellationToken).ConfigureAwait(false);
                            }

                            // Draw on the canvas
                            region.Mutate(ctx =>
                            {
                                ctx.DrawImage(tile, new Point(drawPointX, drawPointY), GraphicsOptions.Default);
                            });

                            // Last column
                            if (tilePointX + _deepZoomTileSize > x + region.Width)
                            {
                                nextVerticalCache.SetEntry(tilePointX, tilePointY, tile);
                                cachedOnce = true;
                            }
                            // Lat row
                            if (tilePointY + _deepZoomTileSize > y + region.Height)
                            {
                                nextHorizontalCache.SetEntry(tilePointX, tilePointY, cachedOnce ? tile.Clone() : tile);
                                cachedOnce = true;
                            }

                            if (cachedOnce)
                            {
                                tile = null;
                            }
                        }
                        finally
                        {
                            tile?.Dispose();
                        }
                    }
                }

                SwapCacheAndClear();
            }