/// <summary> /// Gets the number of the overlay frame that is applicable to a given image frame, if any. /// </summary> /// <remarks> /// <para> /// The DICOM Standard 2008, Part 3, Section C.9.3.1.1 states: /// "The frames within a Multi-frame Overlay shall be conveyed as a logical sequence. If Multi-frame /// Overlays are related to a Multi-frame Image, the order of the Overlay Frames are one to one with /// the order of the Image frames. Otherwise, no attribute is used to indicate the sequencing of the /// Overlay Frames. If Image Frame Origin (60xx,0051) is present, the Overlay frames are applied /// one to one to the Image frames, beginning at the indicated frame number. Otherwise, no attribute /// is used to indicated the sequencing of the Overlay Frames." /// </para> /// <para> /// This is taken to mean that each image frame may have at most ONE overlay frame from any given /// overlay plane group. The algorithm used here evaluates a number of conditions and computes an /// appropriate overlay frame number, if any. The cases are, in order of precedence: /// </para> /// <list> /// <item>If the overlay is embedded in the pixel data, this function always returns the same frame number /// as this was required under the 2004 version of the standard (the last version to allow this usage).</item> /// <item>If the overlay is not multi-frame, all image frames will match with the sole overlay frame.</item> /// <item>If the image frame number is less than <see cref="ImageFrameOrigin"/> or greater than /// <see cref="ImageFrameOrigin"/>+<see cref="NumberOfFramesInOverlay"/>-1, it will have no overlay frame.</item> /// <item>Otherwise, this function returns the matching overlay frame number as determined by the /// <see cref="ImageFrameOrigin"/>.</item> /// </list> /// <para> /// N.B.: This function does NOT access attributes outside this module (i.e. Number of Frames (0028,0008)) /// so as to prevent unintended side effects in the dataset. Therefore, this information must be provided /// by the calling code via <paramref cref="totalImageFrames"/>. /// </para> /// </remarks> /// <param name="imageFrameNumber">The one-based image frame number.</param> /// <param name="totalImageFrames">The total number of frames in the image.</param> /// <returns>The one-based overlay frame number if an overlay frame exists for the given image frame; NULL otherwise.</returns> /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="imageFrameNumber"/> does not specify a valid frame number according to <paramref name="totalImageFrames"/>.</exception> public int?GetRelevantOverlayFrame(int imageFrameNumber, int totalImageFrames) { // if image frame identification is invalid, fail if (imageFrameNumber < 1 || imageFrameNumber > totalImageFrames) { throw new ArgumentOutOfRangeException("imageFrameNumber", "imageFrameNumber must be a positive, non-zero value and less than or equal to totalImageFrames."); } // if the overlay plane is embedded in the pixel data, the overlay frames are required to be 1-to-1 with each image frame if (!HasOverlayData) { return(imageFrameNumber); } // if the overlay is not a multi-frame, then the only overlay frame is applicable to all image frames if (!IsMultiFrame) { return(1); } var origin = ImageFrameOrigin.GetValueOrDefault(1); var count = NumberOfFramesInOverlay.GetValueOrDefault(1); // otherwise the origin and count specify the range of image frames for which a 1-to-1 relation exists to the overlay frames if (imageFrameNumber >= origin && imageFrameNumber < origin + count) { return(imageFrameNumber - (origin - 1)); } return(null); }
/// <summary> /// Gets a value indicating whether or not this multi-frame overlay plane is valid given the total number of frames in the image. /// </summary> /// <remarks> /// DICOM 2009 PS 3.3 Section C.9.3.1.1 states that "The Number of Frames in Overlay (60xx,0015) plus the Image Frame Origin (60xx,0051) minus 1 /// shall be less than or equal to the total number of frames in the Multi-frame Image." /// </remarks> /// <param name="totalImageFrames">The total number of frames in the image.</param> /// <returns>True if this multi-frame overlay plane is valid or the overlay plane is not a multi-frame; False otherwise.</returns> public bool IsValidMultiFrameOverlay(int totalImageFrames) { if (totalImageFrames < 1) { throw new ArgumentOutOfRangeException("totalImageFrames", "Total number of frames in the image must be 1 or greater."); } return(NumberOfFramesInOverlay.GetValueOrDefault(1) + ImageFrameOrigin.GetValueOrDefault(1) - 1 <= totalImageFrames); }