示例#1
0
        /// <summary>
        /// Draws an <see cref="ImageGraphic"/>.
        /// </summary>
        protected override void DrawImageGraphic(ImageGraphic imageGraphic)
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            const int bytesPerPixel = 4;

            Surface.ImageBuffer.Graphics.Clear(Color.FromArgb(0x0, 0xFF, 0xFF, 0xFF));

            BitmapData bitmapData = Surface.ImageBuffer.Bitmap.LockBits(
                new Rectangle(0, 0, Surface.ImageBuffer.Bitmap.Width, Surface.ImageBuffer.Bitmap.Height),
                ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

            try
            {
                ImageRenderer.Render(imageGraphic, bitmapData.Scan0, bitmapData.Width, bytesPerPixel, Surface.ClientRectangle);
            }
            finally
            {
                Surface.ImageBuffer.Bitmap.UnlockBits(bitmapData);
            }

            Surface.FinalBuffer.RenderImage(Surface.ImageBuffer);

            clock.Stop();
            PerformanceReportBroker.PublishReport("GDIRenderer", "DrawImageGraphic", clock.Seconds);
        }
示例#2
0
        /// <summary>
        /// Draws the Text Overlay.
        /// </summary>
        protected virtual void DrawTextOverlay(TPresentationImage presentationImage)
        {
#if DEBUG
            var clock = new CodeClock();
            clock.Start();
#endif
            var annotationLayoutProvider = presentationImage as IAnnotationLayoutProvider;
            if (annotationLayoutProvider == null)
            {
                return;
            }

            var layout = annotationLayoutProvider.AnnotationLayout;
            if (layout == null || !layout.Visible)
            {
                return;
            }

            foreach (var annotationBox in layout.AnnotationBoxes)
            {
                if (annotationBox.Visible)
                {
                    var annotationText = annotationBox.GetAnnotationText(presentationImage);
                    if (!string.IsNullOrEmpty(annotationText))
                    {
                        DrawAnnotationBox(annotationText, annotationBox);
                    }
                }
            }
#if DEBUG
            clock.Stop();
            PerformanceReportBroker.PublishReport(_rendererTypeId, "DrawTextOverlay", clock.Seconds);
#endif
        }
示例#3
0
        /// <summary>
        /// Draws the Text Overlay.
        /// </summary>
        protected void DrawTextOverlay(IPresentationImage presentationImage)
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            if (presentationImage == null || !(presentationImage is IAnnotationLayoutProvider))
            {
                return;
            }

            IAnnotationLayout layout = ((IAnnotationLayoutProvider)presentationImage).AnnotationLayout;

            if (layout == null || !layout.Visible)
            {
                return;
            }

            foreach (AnnotationBox annotationBox in layout.AnnotationBoxes)
            {
                if (annotationBox.Visible)
                {
                    string annotationText = annotationBox.GetAnnotationText(presentationImage);
                    if (!String.IsNullOrEmpty(annotationText))
                    {
                        DrawAnnotationBox(annotationText, annotationBox);
                    }
                }
            }

            clock.Stop();
            PerformanceReportBroker.PublishReport("RendererBase", "DrawTextOverlay", clock.Seconds);
        }
            public void Refresh()
            {
                var clock = new CodeClock();

                clock.Start();

                var currentProcess = Process.GetCurrentProcess();

                currentProcess.Refresh();

                ProcessVirtualMemoryBytes = currentProcess.VirtualMemorySize64;
                ProcessPrivateBytes       = currentProcess.PrivateMemorySize64;
                ProcessWorkingSetBytes    = currentProcess.WorkingSet64;
                GCTotalBytesAllocated     = GC.GetTotalMemory(false);
                SystemFreeMemoryBytes     = SystemResources.GetAvailableMemory(SizeUnits.Bytes);

                HighWaterMarkBytes         = MemoryManagementSettings.Default.HighWatermarkMegaBytes * OneMegabyte;
                LowWaterMarkBytes          = MemoryManagementSettings.Default.LowWatermarkMegaBytes * OneMegabyte;
                HeldMemoryToCollectPercent = MemoryManagementSettings.Default.HeldMemoryToCollectPercent / 100.0;

                x64MinimumFreeSystemMemoryBytes = MemoryManagementSettings.Default.x64MinimumFreeSystemMemoryMegabytes * OneMegabyte;
                x64MaxMemoryUsagePercent        = MemoryManagementSettings.Default.x64MaxMemoryUsagePercent / 100.0;
                x64MaxMemoryToCollectBytes      = MemoryManagementSettings.Default.x64MaxMemoryToCollectMegabytes * OneMegabyte;

                MemoryManagerLargeObjectBytesCount = MemoryManager.LargeObjectBytesCount;

                clock.Stop();

                PerformanceReportBroker.PublishReport("Memory", "UpdateMemoryInfo", clock.Seconds);
            }
            /// <summary>
            /// Called by <see cref="StandardSopFrameData.GetNormalizedOverlayData"/> to create a new byte buffer containing normalized
            /// overlay pixel data for a particular overlay plane.
            /// </summary>
            /// <remarks>
            /// See <see cref="StandardSopFrameData.GetNormalizedOverlayData"/> for details on the expected format of the byte buffer.
            /// </remarks>
            /// <param name="overlayNumber">The 1-based overlay plane number.</param>
            /// <returns>A new byte buffer containing the normalized overlay pixel data.</returns>
            protected override byte[] CreateNormalizedOverlayData(int overlayNumber)
            {
                //TODO (CR December 2010): make this a helper method somewhere, since it's now identical to the one in StreamingSopFrameData?

                var overlayIndex = overlayNumber - 1;

                byte[] overlayData = null;

                var clock = new CodeClock();

                clock.Start();

                // check whether or not the overlay plane exists before attempting to ascertain
                // whether or not the overlay is embedded in the pixel data
                var overlayPlaneModuleIod = new OverlayPlaneModuleIod(Parent);

                if (overlayPlaneModuleIod.HasOverlayPlane(overlayIndex))
                {
                    if (_overlayCache[overlayIndex] == null)
                    {
                        var overlayPlane = overlayPlaneModuleIod[overlayIndex];
                        if (!overlayPlane.HasOverlayData)
                        {
                            // if the overlay is embedded, trigger retrieval of pixel data which will populate the cache for us
                            GetNormalizedPixelData();
                        }
                        else
                        {
                            // try to compute the offset in the OverlayData bit stream where we can find the overlay frame that applies to this image frame
                            int overlayFrame;
                            int bitOffset;
                            if (overlayPlane.TryGetRelevantOverlayFrame(FrameNumber, Parent.NumberOfFrames, out overlayFrame) &&
                                overlayPlane.TryComputeOverlayDataBitOffset(overlayFrame, out bitOffset))
                            {
                                // offset found - unpack only that overlay frame
                                var od = new OverlayData(bitOffset,
                                                         overlayPlane.OverlayRows,
                                                         overlayPlane.OverlayColumns,
                                                         overlayPlane.IsBigEndianOW,
                                                         overlayPlane.OverlayData);
                                _overlayCache[overlayIndex] = od.Unpack();
                            }
                            else
                            {
                                // no relevant overlay frame found - i.e. the overlay for this image frame is blank
                                _overlayCache[overlayIndex] = new byte[0];
                            }
                        }
                    }

                    overlayData = _overlayCache[overlayIndex];
                }

                clock.Stop();
                PerformanceReportBroker.PublishReport("DicomMessageSopDataSource", "CreateNormalizedOverlayData", clock.Seconds);

                return(overlayData);
            }
示例#6
0
        public static void Render(
            ImageGraphic imageGraphic,
            IntPtr pDstPixelData,
            int dstWidth,
            int dstBytesPerPixel,
            Rectangle clientRectangle)
        {
            if (clientRectangle.Width <= 0 || clientRectangle.Height <= 0)
            {
                return;
            }

            if (imageGraphic.SizeInBytes != imageGraphic.PixelData.Raw.Length)
            {
                throw new InvalidOperationException(String.Format(SR.ExceptionIncorrectPixelDataSize, imageGraphic.SizeInBytes, imageGraphic.PixelData.Raw.Length));
            }

#if DEBUG
            CodeClock clock = new CodeClock();
            clock.Start();
#endif
            RectangleF srcViewableRectangle;
            Rectangle  dstViewableRectangle;

            CalculateVisibleRectangles(imageGraphic, clientRectangle, out dstViewableRectangle, out srcViewableRectangle);

            var grayGraphic = imageGraphic as GrayscaleImageGraphic;
            ColorImageGraphic colorGraphic;
            if (grayGraphic != null)
            {
                RenderGrayscale(
                    grayGraphic,
                    srcViewableRectangle,
                    dstViewableRectangle,
                    pDstPixelData,
                    dstWidth,
                    dstBytesPerPixel);
            }
            else if (null != (colorGraphic = imageGraphic as ColorImageGraphic))
            {
                RenderColor(
                    colorGraphic,
                    srcViewableRectangle,
                    dstViewableRectangle,
                    pDstPixelData,
                    dstWidth,
                    dstBytesPerPixel);
            }
            else
            {
                throw new Exception("Unknown ImageGraphic.");
            }
#if DEBUG
            clock.Stop();
            PerformanceReportBroker.PublishReport("ImageRenderer", "Render", clock.Seconds);
#endif
        }
示例#7
0
        /// <summary>
        /// Traverses and renders the scene graph.
        /// </summary>
        protected override void Render()
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            Surface.FinalBuffer.Graphics.Clear(Color.Black);
            base.Render();

            clock.Stop();
            PerformanceReportBroker.PublishReport("GDIRenderer", "Render", clock.Seconds);
        }
        private void CollectGarbage()
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            Platform.Log(LogLevel.Debug, "Performing garbage collection.");
            GC.Collect();

            clock.Stop();
            PerformanceReportBroker.PublishReport("Memory", "GarbageCollection", clock.Seconds);
        }
示例#9
0
        private static int[] ConstructFinalLut(IComposedLut outputLut, IColorMap colorMap, bool invert)
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            colorMap.MinInputValue = outputLut.MinOutputValue;
            colorMap.MaxInputValue = outputLut.MaxOutputValue;

            int[] outputLutData = outputLut.Data;
            int[] colorMapData  = colorMap.Data;

            if (_finalLutBuffer == null || _finalLutBuffer.Length != outputLutData.Length)
            {
                _finalLutBuffer = new int[outputLutData.Length];
            }

            int numberOfEntries = _finalLutBuffer.Length;

            fixed(int *pOutputLutData = outputLutData)
            {
                fixed(int *pColorMapData = colorMapData)
                {
                    fixed(int *pFinalLutData = _finalLutBuffer)
                    {
                        int *pFinalLut = pFinalLutData;

                        if (!invert)
                        {
                            int firstColorMappedPixelValue = colorMap.FirstMappedPixelValue;
                            for (int i = 0; i < numberOfEntries; ++i)
                            {
                                *(pFinalLut++) = pColorMapData[*(pOutputLutData + i) - firstColorMappedPixelValue];
                            }
                        }
                        else
                        {
                            int lastColorMappedPixelValue = colorMap.FirstMappedPixelValue + colorMap.Data.Length - 1;
                            for (int i = 0; i < numberOfEntries; ++i)
                            {
                                *(pFinalLut++) = pColorMapData[lastColorMappedPixelValue - *(pOutputLutData + i)];
                            }
                        }
                    }
                }
            }

            clock.Stop();
            PerformanceReportBroker.PublishReport("ImageRenderer", "ConstructFinalLut", clock.Seconds);

            return(_finalLutBuffer);
        }
示例#10
0
        public static PaletteColorMap Create(IDicomAttributeProvider dataSource)
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            PaletteColorLut paletteColorLut = PaletteColorLut.Create(dataSource);

            clock.Stop();
            PerformanceReportBroker.PublishReport("PaletteColorMap", "Create(IDicomAttributeProvider)", clock.Seconds);

            return(new PaletteColorMap(paletteColorLut));
        }
示例#11
0
        /// <summary>
        /// Called when <see cref="DrawArgs.DrawMode"/> is equal to <b>DrawMode.Refresh</b>.
        /// </summary>
        protected override void Refresh()
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            if (Surface.FinalBuffer != null)
            {
                Surface.FinalBuffer.RenderToScreen();
            }

            clock.Stop();
            PerformanceReportBroker.PublishReport("GDIRenderer", "Refresh", clock.Seconds);
        }
示例#12
0
            /// <summary>
            /// Called by the base class to create a new byte buffer containing normalized pixel data
            /// for this frame (8 or 16-bit grayscale, or 32-bit ARGB).
            /// </summary>
            /// <returns>A new byte buffer containing the normalized pixel data.</returns>
            protected override byte[] CreateNormalizedPixelData()
            {
                DicomMessageBase message = this.Parent.SourceMessage;

                CodeClock clock = new CodeClock();

                clock.Start();

                PhotometricInterpretation photometricInterpretation;

                byte[] rawPixelData = null;

                if (!message.TransferSyntax.Encapsulated)
                {
                    DicomUncompressedPixelData pixelData = new DicomUncompressedPixelData(message);
                    // DICOM library uses zero-based frame numbers
                    MemoryManager.Execute(delegate { rawPixelData = pixelData.GetFrame(_frameIndex); });

                    ExtractOverlayFrames(rawPixelData, pixelData.BitsAllocated);

                    photometricInterpretation = PhotometricInterpretation.FromCodeString(message.DataSet[DicomTags.PhotometricInterpretation]);
                }
                else if (DicomCodecRegistry.GetCodec(message.TransferSyntax) != null)
                {
                    DicomCompressedPixelData pixelData = new DicomCompressedPixelData(message);
                    string pi = null;

                    MemoryManager.Execute(delegate { rawPixelData = pixelData.GetFrame(_frameIndex, out pi); });

                    photometricInterpretation = PhotometricInterpretation.FromCodeString(pi);
                }
                else
                {
                    throw new DicomCodecException("Unsupported transfer syntax");
                }

                if (photometricInterpretation.IsColor)
                {
                    rawPixelData = ToArgb(message.DataSet, rawPixelData, photometricInterpretation);
                }
                else
                {
                    NormalizeGrayscalePixels(message.DataSet, rawPixelData);
                }

                clock.Stop();
                PerformanceReportBroker.PublishReport("DicomMessageSopDataSource", "CreateFrameNormalizedPixelData", clock.Seconds);

                return(rawPixelData);
            }
        private static byte[] CreateShutter(IList <GeometricShutter> shutters, Rectangle imageRectangle, Color fillColor)
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            int stride = imageRectangle.Width * 4;
            int size   = imageRectangle.Height * stride;

            byte[] buffer = MemoryManager.Allocate <byte>(size);

            GCHandle bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);

            try
            {
                using (Bitmap bitmap = new Bitmap(imageRectangle.Width, imageRectangle.Height, stride, PixelFormat.Format32bppPArgb, bufferHandle.AddrOfPinnedObject()))
                {
                    using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap))
                    {
                        graphics.Clear(Color.FromArgb(0, Color.Black));
                        using (Brush brush = new SolidBrush(fillColor))
                        {
                            foreach (GeometricShutter shutter in shutters)
                            {
                                using (GraphicsPath path = new GraphicsPath())
                                {
                                    path.FillMode = FillMode.Alternate;
                                    path.AddRectangle(imageRectangle);
                                    shutter.AddToGraphicsPath(path);
                                    path.CloseFigure();
                                    graphics.FillPath(brush, path);
                                }
                            }
                        }
                    }

                    //NOTE: we are not doing this properly according to Dicom.  We should be rendering
                    //to a 16-bit image so we can set the 16-bit p-value.
                    return(buffer);
                }
            }
            finally
            {
                bufferHandle.Free();

                clock.Stop();
                PerformanceReportBroker.PublishReport("Shutters", "Render", clock.Seconds);
            }
        }
示例#14
0
        /// <summary>
        /// Draws an <see cref="ImageGraphic"/>.
        /// </summary>
        protected override void DrawImageGraphic(ImageGraphic imageGraphic)
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            Surface.ImageBuffer.Graphics.Clear(Color.FromArgb(0x0, 0xFF, 0xFF, 0xFF));

            DrawImageGraphic(Surface.ImageBuffer, imageGraphic);

            Surface.FinalBuffer.RenderImage(Surface.ImageBuffer);

            clock.Stop();
            PerformanceReportBroker.PublishReport("GDIRenderer", "DrawImageGraphic", clock.Seconds);
        }
示例#15
0
        private static int[] ConstructFinalLut(IComposedLut outputLut, bool invert)
        {
#if DEBUG
            CodeClock clock = new CodeClock();
            clock.Start();
#endif
            int[] outputLutData = outputLut.Data;

            if (_finalLutBuffer == null || _finalLutBuffer.Length != outputLutData.Length)
            {
                _finalLutBuffer = new int[outputLutData.Length];
            }

            int numberOfEntries = _finalLutBuffer.Length;

            fixed(int *pOutputLutData = outputLutData)
            fixed(int *pFinalLutData = _finalLutBuffer)
            {
                int *pOutputLut = pOutputLutData;
                int *pFinalLut  = pFinalLutData;

                if (!invert)
                {
                    int firstColorMappedPixelValue = outputLut.MinOutputValue;
                    for (int i = 0; i < numberOfEntries; ++i)
                    {
                        *pFinalLut++ = *pOutputLut++ - firstColorMappedPixelValue;
                    }
                }
                else
                {
                    int lastColorMappedPixelValue = outputLut.MaxOutputValue;
                    for (int i = 0; i < numberOfEntries; ++i)
                    {
                        *pFinalLut++ = lastColorMappedPixelValue - *pOutputLut++;
                    }
                }
            }

#if DEBUG
            clock.Stop();
            PerformanceReportBroker.PublishReport("ImageRenderer", "ConstructFinalLut", clock.Seconds);
#endif
            return(_finalLutBuffer);
        }
示例#16
0
        /// <summary>
        /// Converts colour pixel data to ARGB.
        /// </summary>
        protected static byte[] ToArgb(IDicomAttributeProvider dicomAttributeProvider, byte[] pixelData, PhotometricInterpretation photometricInterpretation)
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            int rows        = dicomAttributeProvider[DicomTags.Rows].GetInt32(0, 0);
            int columns     = dicomAttributeProvider[DicomTags.Columns].GetInt32(0, 0);
            int sizeInBytes = rows * columns * 4;

            byte[] argbPixelData = MemoryManager.Allocate <byte>(sizeInBytes);

            // Convert palette colour images to ARGB so we don't get interpolation artifacts
            // when rendering.
            if (photometricInterpretation == PhotometricInterpretation.PaletteColor)
            {
                int bitsAllocated       = dicomAttributeProvider[DicomTags.BitsAllocated].GetInt32(0, 0);
                int pixelRepresentation = dicomAttributeProvider[DicomTags.PixelRepresentation].GetInt32(0, 0);

                ColorSpaceConverter.ToArgb(
                    bitsAllocated,
                    pixelRepresentation != 0 ? true : false,
                    pixelData,
                    argbPixelData,
                    PaletteColorMap.Create(dicomAttributeProvider));
            }
            // Convert RGB and YBR variants to ARGB
            else
            {
                int planarConfiguration = dicomAttributeProvider[DicomTags.PlanarConfiguration].GetInt32(0, 0);

                ColorSpaceConverter.ToArgb(
                    photometricInterpretation,
                    planarConfiguration,
                    pixelData,
                    argbPixelData);
            }

            clock.Stop();
            PerformanceReportBroker.PublishReport("DicomMessageSopDataSource", "ToArgb", clock.Seconds);

            return(argbPixelData);
        }
        private void UpdateProcessMemoryData()
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            Process currentProcess = Process.GetCurrentProcess();

            currentProcess.Refresh();

            _processVirtualMemoryBytes = currentProcess.VirtualMemorySize64;
            _processPrivateBytes       = currentProcess.PrivateMemorySize64;
            _processWorkingSetBytes    = currentProcess.WorkingSet64;
            _gcTotalBytesAllocated     = GC.GetTotalMemory(false);

            clock.Stop();

            PerformanceReportBroker.PublishReport("Memory", "UpdateProcessMemoryData", clock.Seconds);
        }
        public static XmlDocument GetStudyMetadata(StudyKey key)
        {
            CodeClock clock = new CodeClock();

            clock.Start();

            HttpWebResponse rep = CallService(key.MetadataUri);

            XmlDocument doc = new XmlDocument();

            using (var reader = XmlReader.Create(rep.GetResponseStream()))
            {
                doc.Load(reader);
            }

            clock.Stop();
            PerformanceReportBroker.PublishReport("MINT", "Metadata Load/Parse", clock.Seconds);

            return(doc);
        }
        public static IEnumerable <StudyKey> GetStudies(string serviceUri)
        {
            try
            {
                CodeClock clock = new CodeClock();
                clock.Start();

                HttpWebResponse rep = CallService(AllStudiesUri(serviceUri));

                var keys = ParseStudiesResponse(serviceUri, rep.GetResponseStream());

                clock.Stop();
                PerformanceReportBroker.PublishReport("MINT", "Get study list", clock.Seconds);

                return(keys);
            }
            catch (Exception ex)
            {
                Platform.Log(LogLevel.Error, ex, "Problem calling MINT service at {0}", serviceUri);
            }
            return(new List <StudyKey>());
        }
示例#20
0
        /// <summary>
        /// Recomputes the LUT data, if necessary.
        /// </summary>
        public unsafe void Recalculate()
        {
            if (!_recalculationRequired)
            {
                return;
            }

            var outputLut = GetOutputLut();
            var colorMap  = ColorMap;

            colorMap.MinInputValue = outputLut.MinOutputValue;
            colorMap.MaxInputValue = outputLut.MaxOutputValue;

            var outputLutData   = outputLut.Data;
            var colorMapData    = colorMap.Data;
            var numberOfEntries = outputLutData.Length;

            if (_vtkData == null || _vtkData.Length != 3 * numberOfEntries)
            {
                _vtkData = new double[3 * numberOfEntries];
            }

            var clock = new CodeClock();

            clock.Start();

            fixed(int *pOutputLutData = outputLutData)
            fixed(int *pColorMapData    = colorMapData)
            fixed(double *pFinalLutData = _vtkData)
            fixed(double *pLookup       = _singleChannelByteToDouble)
            {
                var pFinalLut  = pFinalLutData;
                var pOutputLut = pOutputLutData;

                if (!Invert)
                {
                    var firstColorMappedPixelValue = colorMap.FirstMappedPixelValue;
                    for (var i = 0; i < numberOfEntries; ++i)
                    {
                        var value = pColorMapData[*(pOutputLut++) - firstColorMappedPixelValue];
                        *(pFinalLut++) = pLookup[(value >> 16) & 0x0FF];
                        *(pFinalLut++) = pLookup[(value >> 8) & 0x0FF];
                        *(pFinalLut++) = pLookup[(value) & 0x0FF];
                    }
                }
                else
                {
                    var lastColorMappedPixelValue = colorMap.FirstMappedPixelValue + colorMap.Data.Length - 1;
                    for (var i = 0; i < numberOfEntries; ++i)
                    {
                        var value = pColorMapData[lastColorMappedPixelValue - *(pOutputLut++)];
                        *(pFinalLut++) = pLookup[(value >> 16) & 0x0FF];
                        *(pFinalLut++) = pLookup[(value >> 8) & 0x0FF];
                        *(pFinalLut++) = pLookup[(value) & 0x0FF];
                    }
                }
            }

            clock.Stop();
            PerformanceReportBroker.PublishReport("VtkColorTransferFunctionComposer", "Recalculate", clock.Seconds);

            _recalculationRequired = false;
            _modifiedTime          = Environment.TickCount;
        }
        public override void Collect(MemoryCollectionArgs collectionArgs)
        {
            _largeObjectEnumerator = collectionArgs.LargeObjectContainers.GetEnumerator();

            _regenerationCost = RegenerationCost.Low;

            //TODO (Time Review): Use Environment.TickCount?
            _collectionStartTime     = DateTime.Now;
            _timeSinceLastCollection = _collectionStartTime - _lastCollectionTime;
            TimeSpan thirtySeconds = TimeSpan.FromSeconds(30);

            if (_timeSinceLastCollection < thirtySeconds)
            {
                Platform.Log(LogLevel.Debug, "Time since last collection is less than 30 seconds; adjusting to 30 seconds.");
                _timeSinceLastCollection = thirtySeconds;
            }

            _maxTimeSinceLastAccess          = _timeSinceLastCollection;
            _maxTimeSinceLastAccessDecrement = TimeSpan.FromSeconds(_timeSinceLastCollection.TotalSeconds / 3);

            _totalNumberOfCollections   = 0;
            _totalBytesCollected        = 0;
            _totalLargeObjectsCollected = 0;
            _totalContainersUnloaded    = 0;

            try
            {
                CodeClock clock = new CodeClock();
                clock.Start();

                Collect();

                clock.Stop();
                PerformanceReportBroker.PublishReport("Memory", "Collect", clock.Seconds);
            }
            catch (Exception e)
            {
                Platform.Log(LogLevel.Warn, e, "Default memory management strategy failed to collect.");
            }
            finally
            {
                DateTime collectionEndTime = DateTime.Now;
                if (_totalContainersUnloaded > 0)
                {
                    _lastCollectionTime = collectionEndTime;
                }

                _largeObjectEnumerator = null;

                TimeSpan totalElapsed = collectionEndTime - _collectionStartTime;

                MemoryCollectedEventArgs finalArgs = new MemoryCollectedEventArgs(
                    _totalContainersUnloaded, _totalLargeObjectsCollected, _totalBytesCollected, totalElapsed, true);

                if (_totalNumberOfCollections != 0 ||
                    _totalBytesCollected != 0 ||
                    _totalLargeObjectsCollected != 0 ||
                    _totalContainersUnloaded != 0)
                {
                    Platform.Log(LogLevel.Info,
                                 "Large object collection summary: freed {0} MB in {1} seconds and {2} iterations, Total Containers: {3}, Total Large Objects: {4}",
                                 _totalBytesCollected / (float)OneMegabyte,
                                 totalElapsed.TotalSeconds,
                                 _totalNumberOfCollections,
                                 _totalContainersUnloaded,
                                 _totalLargeObjectsCollected);
                }

                OnMemoryCollected(finalArgs);
            }
        }
        private void Collect(long bytesToCollect)
        {
            bool continueCollecting      = false;
            bool needMoreMemorySignalled = false;

            if (bytesToCollect <= 0)
            {
                Platform.Log(LogLevel.Debug,
                             "Memory is not above high watermark; firing collected event to check if more memory is required.");

                MemoryCollectedEventArgs args = new MemoryCollectedEventArgs(0, 0, 0, TimeSpan.Zero, false);
                OnMemoryCollected(args);
                continueCollecting = needMoreMemorySignalled = args.NeedMoreMemory;
            }
            else
            {
                continueCollecting = true;
                Platform.Log(LogLevel.Debug, "Memory *is* above high watermark; collecting ...");
            }

            if (!continueCollecting)
            {
                return;
            }

            int batchSize        = 10;
            int collectionNumber = 0;

            while (continueCollecting)
            {
                CodeClock clock = new CodeClock();
                clock.Start();

                long bytesCollected        = 0;
                int  largeObjectsCollected = 0;
                int  containersUnloaded    = 0;
                int  i = 0;

                foreach (ILargeObjectContainer container in GetNextBatchOfContainersToCollect(batchSize))
                {
                    ++i;

                    try
                    {
                        long bytesHeldBefore        = container.BytesHeldCount;
                        int  largeObjectsHeldBefore = container.LargeObjectCount;

                        container.Unload();

                        long bytesHeldAfter        = container.BytesHeldCount;
                        int  largeObjectsHeldAfter = container.LargeObjectCount;

                        int largeObjectsHeldDifference = largeObjectsHeldBefore - largeObjectsHeldAfter;
                        largeObjectsCollected += largeObjectsHeldDifference;
                        if (largeObjectsHeldDifference > 0)
                        {
                            ++containersUnloaded;
                        }

                        long bytesDifference = (bytesHeldBefore - bytesHeldAfter);
                        bytesCollected       += bytesDifference;
                        _totalBytesCollected += bytesDifference;
                    }
                    catch (Exception e)
                    {
                        Platform.Log(LogLevel.Warn, e, "An unexpected error occurred while attempting to collect large object memory.");
                    }

                    //when needMoreMemorySignalled is true, we need to be more aggressive and keep collecting.
                    if (!needMoreMemorySignalled && _totalBytesCollected >= bytesToCollect)
                    {
                        break;
                    }
                }

                batchSize *= 2;

                _totalContainersUnloaded    += containersUnloaded;
                _totalLargeObjectsCollected += largeObjectsCollected;
                ++_totalNumberOfCollections;

                clock.Stop();

                continueCollecting = i > 0;
                if (!continueCollecting)
                {
                    continue;
                }

                PerformanceReportBroker.PublishReport("Memory", "CollectionIteration", clock.Seconds);

                MemoryCollectedEventArgs args = new MemoryCollectedEventArgs(
                    containersUnloaded, largeObjectsCollected, bytesCollected, TimeSpan.FromSeconds(clock.Seconds), false);

                OnMemoryCollected(args);

                needMoreMemorySignalled = args.NeedMoreMemory;
                continueCollecting      = needMoreMemorySignalled || _totalBytesCollected < bytesToCollect;

                if (Platform.IsLogLevelEnabled(LogLevel.Debug))
                {
                    Platform.Log(LogLevel.Debug,
                                 "Large object collection #{0}: freed {1} MB in {2}, Containers Unloaded: {3}, Large Objects Collected: {4}, Need More Memory: {5}, Last Batch: {6}",
                                 ++collectionNumber, args.BytesCollectedCount / (float)OneMegabyte, clock,
                                 containersUnloaded, largeObjectsCollected, needMoreMemorySignalled, i);
                }
            }

            CollectGarbage();
        }
示例#23
0
        public RetrievePixelDataResult RetrievePixelData(string serverAE, string studyInstanceUID, string seriesInstanceUID, string sopInstanceUid, int frame)
        {
            try
            {
                CodeClock clock = new CodeClock();
                clock.Start();

                FrameStreamingResultMetaData result = new FrameStreamingResultMetaData();
                StringBuilder url = new StringBuilder();

                if (_baseUri.ToString().EndsWith("/"))
                {
                    url.AppendFormat("{0}{1}", _baseUri, serverAE);
                }
                else
                {
                    url.AppendFormat("{0}/{1}", _baseUri, serverAE);
                }

                url.AppendFormat("?requesttype=WADO&studyUID={0}&seriesUID={1}&objectUID={2}", studyInstanceUID, seriesInstanceUID, sopInstanceUid);
                url.AppendFormat("&frameNumber={0}", frame);
                url.AppendFormat("&contentType={0}", HttpUtility.HtmlEncode("application/clearcanvas"));

                result.Speed.Start();

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url.ToString());
                request.Accept    = "application/dicom,application/clearcanvas,image/jpeg";
                request.Timeout   = (int)TimeSpan.FromSeconds(StreamingSettings.Default.ClientTimeoutSeconds).TotalMilliseconds;
                request.KeepAlive = false;

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    throw new StreamingClientException(response.StatusCode, HttpUtility.HtmlDecode(response.StatusDescription));
                }

                Stream       responseStream = response.GetResponseStream();
                BinaryReader reader         = new BinaryReader(responseStream);
                byte[]       buffer         = reader.ReadBytes((int)response.ContentLength);
                reader.Close();
                responseStream.Close();
                response.Close();

                result.Speed.SetData(buffer.Length);
                result.Speed.End();

                result.ResponseMimeType  = response.ContentType;
                result.Status            = response.StatusCode;
                result.StatusDescription = response.StatusDescription;
                result.Uri           = response.ResponseUri;
                result.ContentLength = buffer.Length;
                result.IsLast        = (response.Headers["IsLast"] != null && bool.Parse(response.Headers["IsLast"]));

                clock.Stop();
                PerformanceReportBroker.PublishReport("Streaming", "RetrievePixelData", clock.Seconds);

                RetrievePixelDataResult pixelDataResult;
                if (response.Headers["Compressed"] != null && bool.Parse(response.Headers["Compressed"]))
                {
                    pixelDataResult = new RetrievePixelDataResult(CreateCompressedPixelData(response, buffer), result);
                }
                else
                {
                    pixelDataResult = new RetrievePixelDataResult(buffer, result);
                }

                return(pixelDataResult);
            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response is HttpWebResponse)
                {
                    HttpWebResponse response = (HttpWebResponse)ex.Response;
                    throw new StreamingClientException(response.StatusCode, HttpUtility.HtmlDecode(response.StatusDescription));
                }
                throw new StreamingClientException(StreamingClientExceptionType.Network, ex);
            }
        }
示例#24
0
        private static void RunCollectionThread()
        {
            const int waitTimeMilliseconds = 10000;

            while (true)
            {
                try
                {
                    lock (_syncLock)
                    {
                        if (_waitingClients == 0)
                        {
                            Monitor.Wait(_syncLock, waitTimeMilliseconds);
                        }

                        if (Platform.IsLogLevelEnabled(LogLevel.Debug))
                        {
                            Platform.Log(LogLevel.Debug, "Adding {0} containers and removing {1} from large object container cache.",
                                         _containersToAdd.Count, _containersToRemove.Count);
                        }

                        foreach (ILargeObjectContainer container in _containersToRemove)
                        {
                            _containerCache.Remove(container);
                        }
                        foreach (ILargeObjectContainer container in _containersToAdd)
                        {
                            _containerCache.Add(container);
                        }

                        _containersToRemove.Clear();
                        _containersToAdd.Clear();

                        if (_waitingClients == 0 && _containerCache.IsEmpty)
                        {
                            Platform.Log(LogLevel.Debug, "Exiting collection thread, container cache is empty.");
                            _containerCache.CleanupDeadItems(true);                             //updates the estimates
                            _collectionThread = null;
                            break;
                        }
                    }

                    CodeClock clock = new CodeClock();
                    clock.Start();

                    _containerCache.CleanupDeadItems(true);

                    clock.Stop();
                    PerformanceReportBroker.PublishReport("Memory", "CleanupDeadItems", clock.Seconds);

                    _strategy.Collect(new MemoryCollectionArgs(_containerCache));
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error occurred while collecting large objects.");
                }
                finally
                {
                    if (_collecting)
                    {
                        Platform.Log(LogLevel.Debug, "Memory management strategy failed to fire 'complete' event; firing to avoid deadlocks.");
                        OnMemoryCollected(null, new MemoryCollectedEventArgs(0, 0, 0, TimeSpan.Zero, true));
                    }
                }
            }
        }
        public RetrievePixelDataResult RetrievePixelData()
        {
            try
            {
                if (_useBulkLoading)
                {
                    //FrameStreamingResultMetaData result = new FrameStreamingResultMetaData();

                    string[] uriSplit = Regex.Split(_baseUri.ToString(), "/");
                    //Console.WriteLine("URI: " + _baseUri);
                    //Console.WriteLine("binary item no: " + uriSplit[uriSplit.Length - 1]);

                    //byte[] binaryData = new byte[1000000];
                    //_binaryItems.TryGetValue(1, out binaryData);
                    int binaryItemNumber = Int32.Parse(uriSplit[uriSplit.Length - 1]);
                    //byte[] binaryData = _binaryStream.GetBinaryData(binaryItemNumber);
                    //result = _binaryStream.GetMetadata(binaryItemNumber);

                    RetrievePixelDataResult pixelDataResult = new RetrievePixelDataResult(_binaryStream.GetBinaryData(binaryItemNumber), _binaryStream.GetMetadata(binaryItemNumber));
                    return(pixelDataResult);
                }
                else
                {
                    CodeClock clock = new CodeClock();
                    clock.Start();

                    FrameStreamingResultMetaData result = new FrameStreamingResultMetaData();

                    result.Speed.Start();

                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_baseUri);
                    request.Timeout   = 30000;
                    request.KeepAlive = false;

                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        throw new StreamingClientException(response.StatusCode, HttpUtility.HtmlDecode(response.StatusDescription));
                    }

                    Stream       responseStream = response.GetResponseStream();
                    BinaryReader reader         = new BinaryReader(responseStream);
                    byte[]       buffer         = reader.ReadBytes((int)response.ContentLength);
                    reader.Close();
                    responseStream.Close();
                    response.Close();

                    result.Speed.SetData(buffer.Length);
                    result.Speed.End();

                    result.ResponseMimeType  = response.ContentType;
                    result.Status            = response.StatusCode;
                    result.StatusDescription = response.StatusDescription;
                    result.Uri           = response.ResponseUri;
                    result.ContentLength = buffer.Length;
                    result.IsLast        = (response.Headers["IsLast"] != null && bool.Parse(response.Headers["IsLast"]));

                    clock.Stop();
                    PerformanceReportBroker.PublishReport("MINT", "RetrievePixelData", clock.Seconds);

                    RetrievePixelDataResult pixelDataResult;
                    if (response.Headers["Compressed"] != null && bool.Parse(response.Headers["Compressed"]))
                    {
                        pixelDataResult = new RetrievePixelDataResult(CreateCompressedPixelData(response, buffer), result);
                    }
                    else
                    {
                        pixelDataResult = new RetrievePixelDataResult(buffer, result);
                    }

                    return(pixelDataResult);
                }
            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response is HttpWebResponse)
                {
                    HttpWebResponse response = (HttpWebResponse)ex.Response;
                    throw new StreamingClientException(response.StatusCode, HttpUtility.HtmlDecode(response.StatusDescription));
                }
                throw new StreamingClientException(StreamingClientExceptionType.Network, ex);
            }
        }