protected override void PerformSerialization(IList <IPresentationImage> images)
        {
            DicomPresentationImageCollection <T> imageCollection = new DicomPresentationImageCollection <T>(images.OfType <T>());

            if (imageCollection.Count == 0)
            {
                return;
            }

            PerformTypeSpecificSerialization(imageCollection);
        }
        protected override sealed void PerformDeserialization(IList <IPresentationImage> images)
        {
            foreach (PresentationStateRelationshipModuleIod psRelationship in this.RelationshipSets)
            {
                SeriesReferenceDictionary dictionary = new SeriesReferenceDictionary(psRelationship.ReferencedSeriesSequence);

                DicomPresentationImageCollection <T> imageCollection = new DicomPresentationImageCollection <T>(images.OfType <T>().Where(img => dictionary.ReferencesFrame(img.ImageSop.SeriesInstanceUid, img.ImageSop.SopInstanceUid, img.Frame.FrameNumber)));

                this.PerformTypeSpecificDeserialization(imageCollection);
            }
        }
Beispiel #3
0
        protected override void PerformTypeSpecificDeserialization(DicomPresentationImageCollection <DicomColorPresentationImage> images)
        {
            ColorSoftcopyPresentationStateIod iod = new ColorSoftcopyPresentationStateIod(base.DataSet);

            foreach (DicomColorPresentationImage image in images)
            {
                RectangleF displayedArea;
                this.DeserializeSpatialTransform(iod.SpatialTransform, image);
                this.DeserializeDisplayedArea(iod.DisplayedArea, out displayedArea, image);
                this.DeserializeGraphicLayer(iod.GraphicLayer, image);
                this.DeserializeGraphicAnnotation(iod.GraphicAnnotation, displayedArea, image);
                this.DeserializeOverlayPlane(iod.OverlayPlane, image);
                this.DeserializeOverlayActivation(iod.OverlayActivation, image);
                this.DeserializeBitmapDisplayShutter(iod.BitmapDisplayShutter, image);
                this.DeserializeDisplayShutter(iod.DisplayShutter, image);
            }
        }
Beispiel #4
0
        protected override void PerformTypeSpecificSerialization(DicomPresentationImageCollection <DicomColorPresentationImage> images)
        {
            IOverlayMapping overlayMapping;
            ColorSoftcopyPresentationStateIod iod = new ColorSoftcopyPresentationStateIod(base.DataSet);

            this.SerializePresentationStateRelationship(iod.PresentationStateRelationship, images);
            this.SerializePresentationStateShutter(iod.PresentationStateShutter);
            this.SerializeDisplayShutter(iod.DisplayShutter, images);
            this.SerializeOverlayPlane(iod.OverlayPlane, out overlayMapping, images);
            this.SerializeOverlayActivation(iod.OverlayActivation, overlayMapping, images);
            this.SerializeBitmapDisplayShutter(iod.BitmapDisplayShutter, overlayMapping, images);
            this.SerializeDisplayedArea(iod.DisplayedArea, images);
            this.SerializeGraphicAnnotation(iod.GraphicAnnotation, images);
            this.SerializeSpatialTransform(iod.SpatialTransform, images);
            this.SerializeGraphicLayer(iod.GraphicLayer, images);
            this.SerializeIccProfile(iod.IccProfile);
        }
        protected override sealed void PerformDeserialization(IList <IPresentationImage> images)
        {
            DicomPresentationImageCollection <T> imageCollection;

            if (!DeserializeIgnoreImageRelationship)
            {
                imageCollection = new DicomPresentationImageCollection <T>(
                    RelationshipSets.Select(s => new SeriesReferenceDictionary(s.ReferencedSeriesSequence))
                    .Aggregate(Enumerable.Empty <T>(),
                               (set, rel) => set.Union(images.OfType <T>()
                                                       .Where(img => rel.ReferencesFrame(img.ImageSop.SeriesInstanceUid, img.ImageSop.SopInstanceUid, img.Frame.FrameNumber)))));
            }
            else
            {
                imageCollection = new DicomPresentationImageCollection <T>(images.OfType <T>());
            }

            PerformTypeSpecificDeserialization(imageCollection);
        }
        protected void SerializeSoftcopyVoiLut(SoftcopyVoiLutModuleIod module, DicomPresentationImageCollection <T> images)
        {
            List <SoftcopyVoiLutModuleIod.SoftcopyVoiLutSequenceItem> voiLutSequenceItems = new List <SoftcopyVoiLutModuleIod.SoftcopyVoiLutSequenceItem>();

            foreach (T image in images)
            {
                if (!image.VoiLutManager.Enabled)
                {
                    continue;
                }

                SoftcopyVoiLutModuleIod.SoftcopyVoiLutSequenceItem sequenceItem = new SoftcopyVoiLutModuleIod.SoftcopyVoiLutSequenceItem();
                sequenceItem.InitializeAttributes();
                sequenceItem.ReferencedImageSequence = new ImageSopInstanceReferenceMacro[] { CreateImageSopInstanceReference(image.Frame) };

                IVoiLut lut = image.VoiLutManager.VoiLut;
                if (lut is IDataLut)
                {
                    IDataLut voiLut = (IDataLut)lut;
                    sequenceItem.VoiLutSequence = new VoiLutSequenceItem[] { SerializeDataLut(voiLut) };
                }
                else if (lut is IVoiLutLinear)
                {
                    IVoiLutLinear voiLut = (IVoiLutLinear)lut;
                    sequenceItem.WindowWidth  = new double[] { voiLut.WindowWidth };
                    sequenceItem.WindowCenter = new double[] { voiLut.WindowCenter };
                    sequenceItem.WindowCenterWidthExplanation = new string[] { SR.LabelPresentationVoiLinearLut };
                    sequenceItem.VoiLutFunction = VoiLutFunction.Linear;                     // we don't support sigmoid
                }
                else
                {
                    // should never happen - all VOI LUT object should implement either interface
                    continue;
                }

                voiLutSequenceItems.Add(sequenceItem);
            }

            if (voiLutSequenceItems.Count > 0)
            {
                module.SoftcopyVoiLutSequence = voiLutSequenceItems.ToArray();
            }
        }
Beispiel #7
0
        protected override void PerformTypeSpecificSerialization(DicomPresentationImageCollection <DicomGrayscalePresentationImage> images)
        {
            IOverlayMapping overlayMapping;
            GrayscaleSoftcopyPresentationStateIod iod = new GrayscaleSoftcopyPresentationStateIod(base.DataSet);

            this.SerializePresentationStateRelationship(iod.PresentationStateRelationship, images);
            this.SerializePresentationStateShutter(iod.PresentationStateShutter);
            this.SerializePresentationStateMask(iod.PresentationStateMask, images);
            this.SerializeMask(iod.Mask, images);
            this.SerializeDisplayShutter(iod.DisplayShutter, images);
            this.SerializeOverlayPlane(iod.OverlayPlane, out overlayMapping, images);
            this.SerializeOverlayActivation(iod.OverlayActivation, overlayMapping, images);
            this.SerializeBitmapDisplayShutter(iod.BitmapDisplayShutter, overlayMapping, images);
            this.SerializeDisplayedArea(iod.DisplayedArea, images);
            this.SerializeGraphicAnnotation(iod.GraphicAnnotation, images);
            this.SerializeSpatialTransform(iod.SpatialTransform, images);
            this.SerializeGraphicLayer(iod.GraphicLayer, images);
            this.SerializeModalityLut(iod.ModalityLut, images);
            this.SerializeSoftcopyVoiLut(iod.SoftcopyVoiLut, images);
            this.SerializeSoftcopyPresentationLut(iod.SoftcopyPresentationLut, images);
        }
        protected void SerializeDisplayedArea(DisplayedAreaModuleIod displayedAreaModule, DicomPresentationImageCollection <T> images)
        {
            displayedAreaModule.InitializeAttributes();
            List <DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem> displayedAreas = new List <DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem>();

            foreach (T image in images)
            {
                DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem displayedArea = new DisplayedAreaModuleIod.DisplayedAreaSelectionSequenceItem();
                displayedArea.InitializeAttributes();
                displayedArea.ReferencedImageSequence = new[] { CreateImageSopInstanceReference(image.Frame) };

                ImageGraphic imageGraphic = ((IImageGraphicProvider)image).ImageGraphic;
                Size         imageSize    = new Size(imageGraphic.Columns, imageGraphic.Rows);

                // compute the visible area of the image as a rectangle oriented positively in screen space
                RectangleF visibleImageArea = imageGraphic.SpatialTransform.ConvertToSource(image.ClientRectangle);
                visibleImageArea = RectangleUtilities.ConvertToPositiveRectangle(visibleImageArea);
                visibleImageArea = RectangleUtilities.RoundInflate(visibleImageArea);
                visibleImageArea = RectangleUtilities.Intersect(visibleImageArea, new Rectangle(new Point(0, 0), imageSize));

                // compute the pixel addresses of the visible area by intersecting area with actual pixel addresses available
                Rectangle visiblePixels = ConvertToPixelAddressRectangle(Rectangle.Truncate(visibleImageArea));
                displayedArea.DisplayedAreaTopLeftHandCorner     = visiblePixels.Location;
                displayedArea.DisplayedAreaBottomRightHandCorner = visiblePixels.Location + visiblePixels.Size;

                ISpatialTransform spatialTransform = image.SpatialTransform;
                switch (_displayAreaSerializationOption)
                {
                case DisplayAreaSerializationOption.SerializeAsMagnification:
                    displayedArea.PresentationSizeMode = DisplayedAreaModuleIod.PresentationSizeMode.Magnify;
                    displayedArea.PresentationPixelMagnificationRatio = spatialTransform.Scale;
                    break;

                case DisplayAreaSerializationOption.SerializeAsTrueSize:
                    displayedArea.PresentationSizeMode     = DisplayedAreaModuleIod.PresentationSizeMode.TrueSize;
                    displayedArea.PresentationPixelSpacing = image.Frame.NormalizedPixelSpacing;
                    break;

                case DisplayAreaSerializationOption.SerializeAsDisplayedArea:
                default:
                    displayedArea.PresentationSizeMode = DisplayedAreaModuleIod.PresentationSizeMode.ScaleToFit;
                    break;
                }

                displayedArea.PresentationPixelAspectRatio = PixelAspectRatio.FromString(image.Frame.NormalizedPixelSpacing.GetPixelAspectRatioString());

                displayedAreas.Add(displayedArea);
            }
            displayedAreaModule.DisplayedAreaSelectionSequence = displayedAreas.ToArray();
        }
 protected void SerializeOverlayActivation(OverlayActivationModuleIod overlayActivationModule, IOverlayMapping overlayMapping, DicomPresentationImageCollection <T> images)
 {
     // Doesn't support multiframe or whatever case it is when we get more than one image serialized to one state
     for (int n = 0; n < 16; n++)
     {
         OverlayPlaneGraphic overlay = overlayMapping[n];
         if (overlay != null)
         {
             if (overlay.ParentGraphic is ILayer)
             {
                 overlayActivationModule[n].OverlayActivationLayer = ((ILayer)overlay.ParentGraphic).Id;
             }
             else
             {
                 overlayActivationModule.Delete(n);
             }
         }
     }
 }
        protected void SerializeOverlayPlane(OverlayPlaneModuleIod overlayPlaneModule, out IOverlayMapping overlayMapping, DicomPresentationImageCollection <T> images)
        {
            // Doesn't support multiframe or whatever case it is when we get more than one image serialized to one state
            List <OverlayPlaneGraphic> visibleOverlays = new List <OverlayPlaneGraphic>();

            foreach (T image in images)
            {
                DicomGraphicsPlane dicomGraphics = DicomGraphicsPlane.GetDicomGraphicsPlane(image, false);
                if (dicomGraphics != null)
                {
                    // identify visible bitmap shutter if exists
                    OverlayPlaneGraphic bitmapShutter = dicomGraphics.Shutters.ActiveShutter as OverlayPlaneGraphic;
                    if (bitmapShutter != null)
                    {
                        visibleOverlays.Add(bitmapShutter);
                    }

                    // identify any visible overlays
                    visibleOverlays.AddRange(((IEnumerable <ILayer>)dicomGraphics.Layers).Where(l => l.Visible).SelectMany(l => l.Graphics).OfType <OverlayPlaneGraphic>().Where(g => g.Visible));
                }
            }

            OverlayMapping overlayMap = new OverlayMapping();
            Queue <OverlayPlaneGraphic> overlaysToRemap = new Queue <OverlayPlaneGraphic>();

            // user and presentation state overlays are high priority items to remap
            foreach (OverlayPlaneGraphic overlay in CollectionUtils.Select(visibleOverlays, delegate(OverlayPlaneGraphic t) { return(t.Source != OverlayPlaneSource.Image); }))
            {
                overlaysToRemap.Enqueue(overlay);
            }
            foreach (OverlayPlaneGraphic overlay in CollectionUtils.Select(visibleOverlays, delegate(OverlayPlaneGraphic t) { return(t.Source == OverlayPlaneSource.Image); }))
            {
                if (overlayMap[overlay.Index] == null)
                {
                    overlayMap[overlay.Index] = overlay;
                }
                else
                {
                    overlaysToRemap.Enqueue(overlay);                     // image overlays are lower priority items to remap, since they will be included in the header anyway
                }
            }

            // seed the overlays to remap into the remaining available overlay groups
            for (int n = 0; n < 16 && overlaysToRemap.Count > 0; n++)
            {
                if (overlayMap[n] == null)
                {
                    overlayMap[n] = overlaysToRemap.Dequeue();
                }
            }

            // serialize the overlays
            for (int n = 0; n < 16; n++)
            {
                OverlayPlaneGraphic overlay = overlayMap[n];
                if (overlay != null)
                {
                    if (overlay.Source != OverlayPlaneSource.Image || overlay.Index != n)
                    {
                        // only record this overlay in the presentation state if it is being remapped to another group or is not already in the image.
                        OverlayPlane overlayIod = overlayPlaneModule[n];
                        overlayIod.OverlayData          = overlay.CreateOverlayData(overlayIod.IsBigEndianOW).Raw;
                        overlayIod.OverlayBitPosition   = 0;
                        overlayIod.OverlayBitsAllocated = 1;
                        overlayIod.OverlayColumns       = overlay.Columns;
                        overlayIod.OverlayDescription   = overlay.Description;
                        overlayIod.OverlayLabel         = overlay.Label;
                        overlayIod.OverlayOrigin        = Point.Round(overlay.Origin);
                        overlayIod.OverlayRows          = overlay.Rows;
                        overlayIod.OverlaySubtype       = overlay.Subtype;
                        overlayIod.OverlayType          = overlay.Type;
                        overlayIod.RoiArea = null;
                        overlayIod.RoiMean = null;
                        overlayIod.RoiStandardDeviation = null;
                    }
                    else
                    {
                        overlayPlaneModule.Delete(n);
                    }
                }
            }

            if (overlaysToRemap.Count > 0)
            {
                Platform.Log(LogLevel.Warn, "Attempt to serialize presentation state with more than 16 visible overlays - some information may be lost.");
            }

            overlayMapping = overlayMap;
        }
 protected void SerializeBitmapDisplayShutter(BitmapDisplayShutterModuleIod bitmapDisplayShutterModule, IOverlayMapping overlayMapping, DicomPresentationImageCollection <T> images)
 {
     // Doesn't support multiframe or whatever case it is when we get more than one image serialized to one state
     for (int n = 0; n < 16; n++)
     {
         OverlayPlaneGraphic overlay = overlayMapping[n];
         if (overlay != null)
         {
             if (overlay.ParentGraphic is IDicomGraphicsPlaneShutters)
             {
                 bitmapDisplayShutterModule.ShutterShape                        = ShutterShape.Bitmap;
                 bitmapDisplayShutterModule.ShutterOverlayGroupIndex            = n;
                 bitmapDisplayShutterModule.ShutterPresentationValue            = overlay.GrayPresentationValue;
                 bitmapDisplayShutterModule.ShutterPresentationColorCielabValue = null;
                 break;                         // there can only be one
             }
         }
     }
 }
        protected void SerializeDisplayShutter(DisplayShutterModuleIod displayShutterModule, DicomPresentationImageCollection <T> images)
        {
            // Doesn't support multiframe or whatever case it is when we get more than one image serialized to one state
            CircularShutter    circular    = null;
            RectangularShutter rectangular = null;
            PolygonalShutter   polygonal   = null;
            int unserializedCount          = 0;

            foreach (T image in images)
            {
                DicomGraphicsPlane dicomGraphics = DicomGraphicsPlane.GetDicomGraphicsPlane(image, false);
                if (dicomGraphics != null)
                {
                    // identify visible geometric shutter if exists
                    GeometricShuttersGraphic geometricShutters = dicomGraphics.Shutters.ActiveShutter as GeometricShuttersGraphic;
                    if (geometricShutters != null)
                    {
                        // we can only save the first of each
                        foreach (GeometricShutter shutter in geometricShutters.CustomShutters)
                        {
                            if (shutter is CircularShutter && circular == null)
                            {
                                circular = (CircularShutter)shutter;
                            }
                            else if (shutter is RectangularShutter && rectangular == null)
                            {
                                rectangular = (RectangularShutter)shutter;
                            }
                            else if (shutter is PolygonalShutter && polygonal == null)
                            {
                                polygonal = (PolygonalShutter)shutter;
                            }
                            else
                            {
                                unserializedCount++;
                            }
                        }
                        foreach (GeometricShutter shutter in geometricShutters.DicomShutters)
                        {
                            if (shutter is CircularShutter && circular == null)
                            {
                                circular = (CircularShutter)shutter;
                            }
                            else if (shutter is RectangularShutter && rectangular == null)
                            {
                                rectangular = (RectangularShutter)shutter;
                            }
                            else if (shutter is PolygonalShutter && polygonal == null)
                            {
                                polygonal = (PolygonalShutter)shutter;
                            }
                            else
                            {
                                unserializedCount++;
                            }
                        }
                    }
                }
            }

            ShutterShape shape = ShutterShape.None;

            if (circular != null)
            {
                shape |= ShutterShape.Circular;

                displayShutterModule.CenterOfCircularShutter = circular.Center;
                displayShutterModule.RadiusOfCircularShutter = circular.Radius;
            }
            if (rectangular != null)
            {
                shape |= ShutterShape.Rectangular;

                Rectangle r = rectangular.Rectangle;
                displayShutterModule.ShutterLeftVerticalEdge    = r.Left;
                displayShutterModule.ShutterRightVerticalEdge   = r.Right;
                displayShutterModule.ShutterUpperHorizontalEdge = r.Top;
                displayShutterModule.ShutterLowerHorizontalEdge = r.Bottom;
            }
            if (polygonal != null)
            {
                shape |= ShutterShape.Polygonal;

                List <Point> vertices = new List <Point>();
                vertices.AddRange(polygonal.Vertices);
                displayShutterModule.VerticesOfThePolygonalShutter = vertices.ToArray();
            }

            if (shape != ShutterShape.None)
            {
                displayShutterModule.ShutterShape             = shape;
                displayShutterModule.ShutterPresentationValue = 0;
            }
            else
            {
                foreach (uint tag in DisplayShutterMacroIod.DefinedTags)
                {
                    displayShutterModule.DicomAttributeProvider[tag] = null;
                }
            }

            if (unserializedCount > 0)
            {
                Platform.Log(LogLevel.Warn, "Attempt to serialize presentation state with an unsupported combination of shutters - some information may be lost.");
            }
        }
        protected void SerializeGraphicAnnotation(GraphicAnnotationModuleIod graphicAnnotationModule, DicomPresentationImageCollection <T> images)
        {
            List <GraphicAnnotationSequenceItem> annotations = new List <GraphicAnnotationSequenceItem>();

            foreach (T image in images)
            {
                DicomGraphicsPlane psGraphic = DicomGraphicsPlane.GetDicomGraphicsPlane(image, false);
                if (psGraphic != null)
                {
                    foreach (ILayer layerGraphic in (IEnumerable <ILayer>)psGraphic.Layers)
                    {
                        foreach (IGraphic graphic in layerGraphic.Graphics)
                        {
                            GraphicAnnotationSequenceItem annotation = new GraphicAnnotationSequenceItem();
                            if (GraphicAnnotationSerializer.SerializeGraphic(graphic, annotation) && AnyContent(annotation))
                            {
                                SetAllSpecificCharacterSets(annotation, DataSet.SpecificCharacterSet);
                                annotation.GraphicLayer            = layerGraphic.Id.ToUpperInvariant();
                                annotation.ReferencedImageSequence = new[] { CreateImageSopInstanceReference(image.Frame) };
                                annotations.Add(annotation);
                            }
                        }
                    }
                }

                foreach (IGraphic graphic in image.OverlayGraphics)
                {
                    GraphicAnnotationSequenceItem annotation = new GraphicAnnotationSequenceItem();
                    if (GraphicAnnotationSerializer.SerializeGraphic(graphic, annotation) && AnyContent(annotation))
                    {
                        SetAllSpecificCharacterSets(annotation, DataSet.SpecificCharacterSet);
                        annotation.GraphicLayer            = _annotationsLayerId;
                        annotation.ReferencedImageSequence = new[] { CreateImageSopInstanceReference(image.Frame) };
                        annotations.Add(annotation);
                    }
                }
            }

            if (annotations.Count > 0)
            {
                graphicAnnotationModule.GraphicAnnotationSequence = annotations.ToArray();
            }
        }
 protected void SerializePresentationStateMask(PresentationStateMaskModuleIod module, DicomPresentationImageCollection <T> images)
 {
     // NOTE: Not supported
     module.InitializeAttributes();
 }
        protected void SerializePresentationStateRelationship(PresentationStateRelationshipModuleIod presentationStateRelationshipModule, DicomPresentationImageCollection <T> images)
        {
            presentationStateRelationshipModule.InitializeAttributes();
            List <IReferencedSeriesSequence> seriesReferences = new List <IReferencedSeriesSequence>();

            foreach (string seriesUid in images.EnumerateSeries())
            {
                IReferencedSeriesSequence seriesReference = presentationStateRelationshipModule.CreateReferencedSeriesSequence();
                seriesReference.SeriesInstanceUid = seriesUid;
                List <ImageSopInstanceReferenceMacro> imageReferences = new List <ImageSopInstanceReferenceMacro>();
                foreach (T image in images.EnumerateImages(seriesUid))
                {
                    imageReferences.Add(CreateImageSopInstanceReference(image.Frame));
                }
                seriesReference.ReferencedImageSequence = imageReferences.ToArray();
                seriesReferences.Add(seriesReference);
            }
            presentationStateRelationshipModule.ReferencedSeriesSequence = seriesReferences.ToArray();
        }
 protected void SerializeModalityLut(ModalityLutModuleIod module, DicomPresentationImageCollection <T> images)
 {
 }
 protected void SerializeMask(MaskModuleIod module, DicomPresentationImageCollection <T> images)
 {
     // NOTE: Not supported
 }
 protected abstract void PerformTypeSpecificDeserialization(DicomPresentationImageCollection <T> images);
 protected void SerializeSpatialTransform(SpatialTransformModuleIod spatialTransformModule, DicomPresentationImageCollection <T> images)
 {
     foreach (T image in images)
     {
         // spatial transform defines rotation in cartesian space - dicom module defines rotation as clockwise in image space
         // spatial transform defines both horizontal and vertical flip - dicom module defines horizontal flip only (vertical flip is 180 rotation plus horizontal flip)
         ISpatialTransform spatialTransform = image.SpatialTransform;
         int rotationBy90 = (((spatialTransform.RotationXY % 360) + 360) % 360) / 90;
         int flipState    = (spatialTransform.FlipX ? 2 : 0) + (spatialTransform.FlipY ? 1 : 0);
         spatialTransformModule.ImageRotation       = _spatialTransformRotationTranslation[rotationBy90 + 4 * flipState];
         spatialTransformModule.ImageHorizontalFlip = spatialTransform.FlipY ^ spatialTransform.FlipX ? ImageHorizontalFlip.Y : ImageHorizontalFlip.N;
         break;
     }
 }
Beispiel #20
0
        /// <summary>
        /// Serializes the Softcopy Presentation LUT IOD module (DICOM PS 3.3, C.11.6)
        /// </summary>
        /// <param name="module">The IOD module.</param>
        /// <param name="images">The images to be serialized.</param>
        private void SerializeSoftcopyPresentationLut(SoftcopyPresentationLutModuleIod module, DicomPresentationImageCollection <DicomGrayscalePresentationImage> images)
        {
            var inverted = false;

            if (images.Count > 0)
            {
                inverted = images.FirstImage.VoiLutManager.Invert;

                // if more than one image is being serialized in the same presentation state, and they have different inversion states, then just don't invert any of them
                foreach (var image in images)
                {
                    if (inverted != image.VoiLutManager.Invert)
                    {
                        inverted = false;
                        break;
                    }
                }
            }

            module.InitializeAttributes();
            module.PresentationLutShape = !inverted ? PresentationLutShape.Identity : PresentationLutShape.Inverse;
        }
        protected void SerializeGraphicLayer(GraphicLayerModuleIod graphicLayerModule, DicomPresentationImageCollection <T> images)
        {
            Dictionary <string, string>     layerIndex     = new Dictionary <string, string>();
            List <GraphicLayerSequenceItem> layerSequences = new List <GraphicLayerSequenceItem>();

            int order = 1;

            foreach (T image in images)
            {
                DicomGraphicsPlane psGraphic = DicomGraphicsPlane.GetDicomGraphicsPlane(image, false);
                if (psGraphic != null)
                {
                    foreach (ILayer layerGraphic in (IEnumerable <ILayer>)psGraphic.Layers)
                    {
                        // do not serialize the inactive layer, and do not serialize layers more than once
                        if (!string.IsNullOrEmpty(layerGraphic.Id) && !layerIndex.ContainsKey(layerGraphic.Id))
                        {
                            GraphicLayerSequenceItem layerSequence = new GraphicLayerSequenceItem();
                            layerSequence.GraphicLayer            = layerGraphic.Id.ToUpperInvariant();
                            layerSequence.GraphicLayerDescription = layerGraphic.Description;
                            layerSequence.GraphicLayerOrder       = order++;
                            layerSequence.GraphicLayerRecommendedDisplayCielabValue    = null;
                            layerSequence.GraphicLayerRecommendedDisplayGrayscaleValue = null;
                            layerSequences.Add(layerSequence);
                            layerIndex.Add(layerGraphic.Id, null);
                        }
                    }
                }

                if (image.OverlayGraphics.Count > 0)
                {
                    if (!layerIndex.ContainsKey(_annotationsLayerId))
                    {
                        layerIndex.Add(_annotationsLayerId, null);
                        GraphicLayerSequenceItem layerSequence = new GraphicLayerSequenceItem();
                        layerSequence.GraphicLayer      = _annotationsLayerId;
                        layerSequence.GraphicLayerOrder = order++;
                        layerSequences.Add(layerSequence);
                        break;
                    }
                }
            }

            if (layerSequences.Count > 0)
            {
                graphicLayerModule.GraphicLayerSequence = layerSequences.ToArray();
            }
        }