Index: ImageViewer/ColorPresentationImage.cs
===================================================================
--- ImageViewer/ColorPresentationImage.cs (revision 9089)
+++ ImageViewer/ColorPresentationImage.cs (working copy)
@@ -39,7 +39,8 @@
/// A colour .
///
[Cloneable]
- public class ColorPresentationImage : BasicPresentationImage
+ public class ColorPresentationImage : BasicPresentationImage,
+ IVoiLutProvider, IModalityLutProvider
{
#region Private fields
@@ -151,7 +152,37 @@
///
public new ColorImageGraphic ImageGraphic
{
- get { return (ColorImageGraphic)base.ImageGraphic; }
- }
- }
+ get { return (ColorImageGraphic)base.ImageGraphic; }
+ }
+
+ #region IVoiLutProvider and IModalityLutProvider Members
+
+ ///
+ /// Gets this image's .
+ ///
+ public IVoiLutManager VoiLutManager
+ {
+ get
+ {
+ return this.ImageGraphic.VoiLutManager;
+ }
+ }
+
+
+ ///
+ /// Gets this image's modality lut.
+ ///
+ public IComposableLut ModalityLut
+ {
+ get
+ {
+ return this.ImageGraphic.ModalityLut;
+ }
+ }
+
+ #endregion
+
+
+ }
+
}
Index: ImageViewer/DicomColorPresentationImage.cs
===================================================================
--- ImageViewer/DicomColorPresentationImage.cs (revision 9089)
+++ ImageViewer/DicomColorPresentationImage.cs (working copy)
@@ -32,11 +32,17 @@
using System;
using ClearCanvas.Common;
using ClearCanvas.Common.Utilities;
+using ClearCanvas.Dicom;
+using ClearCanvas.Dicom.Iod;
using ClearCanvas.ImageViewer.Annotations;
using ClearCanvas.ImageViewer.Annotations.Dicom;
+using ClearCanvas.ImageViewer.Imaging;
using ClearCanvas.ImageViewer.PresentationStates;
using ClearCanvas.ImageViewer.StudyManagement;
+
+
+
namespace ClearCanvas.ImageViewer
{
///
@@ -44,7 +50,8 @@
///
[Cloneable]
public class DicomColorPresentationImage
- : ColorPresentationImage, IImageSopProvider, IDicomSoftcopyPresentationStateProvider
+ : ColorPresentationImage, IImageSopProvider,
+ IDicomSoftcopyPresentationStateProvider, IDicomVoiLutsProvider
{
[CloneIgnore]
private IFrameReference _frameReference;
@@ -74,6 +81,7 @@
frameReference.Frame.GetNormalizedPixelData)
{
_frameReference = frameReference;
+ _dicomVoiLuts = new DicomVoiLuts(this);
}
///
@@ -84,6 +92,7 @@
{
Frame frame = source.Frame;
_frameReference = frame.CreateTransientReference();
+ _dicomVoiLuts = new DicomVoiLuts(this);
}
///
@@ -141,6 +150,20 @@
#endregion
+
+ #region IDicomVoiLutsProvider Members
+
+ [CloneIgnore]
+ private readonly DicomVoiLuts _dicomVoiLuts;
+
+ public IDicomVoiLuts DicomVoiLuts
+ {
+ get { return _dicomVoiLuts; }
+ }
+
+ #endregion
+
+
///
/// Dispose method. Inheritors should override this method to do any additional cleanup.
///
Index: ImageViewer/Graphics/ColorImageGraphic.cs
===================================================================
--- ImageViewer/Graphics/ColorImageGraphic.cs (revision 9089)
+++ ImageViewer/Graphics/ColorImageGraphic.cs (working copy)
@@ -31,7 +31,10 @@
using ClearCanvas.Common.Utilities;
using ClearCanvas.ImageViewer.Imaging;
+using ClearCanvas.Common;
+using ClearCanvas.Dicom.Validation;
+
namespace ClearCanvas.ImageViewer.Graphics
{
///
@@ -44,8 +47,38 @@
/// opacity (i.e. alpha) of each pixel.
///
[Cloneable]
- public class ColorImageGraphic : ImageGraphic
+ public class ColorImageGraphic : ImageGraphic,
+ IModalityLutProvider,
+ IVoiLutProvider
+
{
+
+ private enum Luts
+ {
+ Modality = 1,
+ Voi = 2,
+ }
+
+
+ #region Private fields
+
+ private int _bitsStored;
+ private int _highBit;
+ private bool _isSigned;
+
+ private double _rescaleSlope;
+ private double _rescaleIntercept;
+ private bool _invert;
+
+ private LutComposer _lutComposer;
+ private LutFactory _lutFactory;
+ private IVoiLutManager _voiLutManager;
+
+ private IDataLut _colorMap;
+
+ #endregion
+
+
///
/// Initializes a new instance of
/// with the specified image parameters.
@@ -60,8 +93,10 @@
public ColorImageGraphic(int rows, int columns)
: base(rows, columns, 32)
{
+ Initialize(8, 7, false, 1, 0, false);
}
+
///
/// Initializes a new instance of
/// with the specified image parameters.
@@ -75,6 +110,7 @@
public ColorImageGraphic(int rows, int columns, byte[] pixelData)
: base(rows, columns, 32, pixelData)
{
+ Initialize(8, 7, false, 1, 0, false);
}
///
@@ -85,7 +121,7 @@
///
///
///
- /// Creates a grayscale image using existing pixel data but does so
+ /// Creates a color image using existing pixel data but does so
/// without ever storing a reference to the pixel data. This is necessary
/// to ensure that pixel data can be properly garbage collected in
/// any future memory management schemes.
@@ -93,6 +129,7 @@
public ColorImageGraphic(int rows, int columns, PixelDataGetter pixelDataGetter)
: base(rows, columns, 32, pixelDataGetter)
{
+ Initialize(8, 7, false, 1, 0, false);
}
///
@@ -125,6 +162,279 @@
return new ColorPixelData(this.Rows, this.Columns, this.PixelDataRaw);
else
return new ColorPixelData(this.Rows, this.Columns, this.PixelDataGetter);
- }
- }
+ }
+
+ #region Public properties
+
+ ///
+ /// Gets the number of bits stored in the image.
+ ///
+ ///
+ /// The number of bits stored does not necessarily equal the number of bits
+ /// allocated. Value 8 is typical for RGB Images
+ ///
+ public int BitsStored
+ {
+ get { return _bitsStored; }
+ }
+
+ ///
+ /// Gets the high bit.
+ ///
+ ///
+ /// Theoretically, the high bit does not necessarily have to equal
+ /// Bits Stored - 1. But in almost all cases this assumption is true;
+ /// we too make this assumption.
+ ///
+ public int HighBit
+ {
+ get { return _highBit; }
+ }
+
+ ///
+ /// Get a value indicating whether the image's pixel data is signed.
+ ///
+ public bool IsSigned
+ {
+ get { return _isSigned; }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the image should be inverted.
+ ///
+
+ public bool Invert
+ {
+ get { return _invert; }
+ set { _invert = value; }
+ }
+
+ #endregion
+
+ #region IVoiLutProvider and Modality Members
+
+ ///
+ /// Retrieves the VoiLutManager .
+ ///
+ public IVoiLutManager VoiLutManager
+ {
+ get
+ {
+ if (_voiLutManager == null)
+ _voiLutManager = new VoiLutManager(this);
+
+ return _voiLutManager;
+ }
+ }
+
+ ///
+ /// Retrieves this image's modality lut.
+ ///
+ public IComposableLut ModalityLut
+ {
+ get
+ {
+ InitializeNecessaryLuts(Luts.Modality);
+ return this.LutComposer.LutCollection[0];
+ }
+ }
+
+ ///
+ /// Retrieves this image's Voi Lut.
+ ///
+ public IComposableLut VoiLut
+ {
+ get
+ {
+ InitializeNecessaryLuts(Luts.Voi);
+ return this.LutComposer.LutCollection[1];
+ }
+ }
+
+
+ ///
+ /// The output lut composed of both the Modality and Voi Luts.
+ ///
+ public IComposedLut OutputLut
+ {
+ get
+ {
+ InitializeNecessaryLuts(Luts.Voi);
+ return this.LutComposer;
+ }
+ }
+
+
+ ///
+ /// Retrieves this image's color map.
+ ///
+ public IDataLut ColorMap
+ {
+ get
+ {
+ if (_colorMap == null)
+ InstallColorMap(this.LutFactory.GetGrayscaleColorMap());
+
+ return _colorMap;
+ }
+ }
+
+ #endregion
+
+
+ #region Private properties
+
+ ///
+ /// Retrieves LutComposer.
+ ///
+ private LutComposer LutComposer
+ {
+ get
+ {
+ if (_lutComposer == null)
+ _lutComposer = new LutComposer();
+
+ return _lutComposer;
+ }
+ }
+
+ ///
+ /// Retrieves LutFactory
+ ///
+ private LutFactory LutFactory
+ {
+ get
+ {
+ if (_lutFactory == null)
+ _lutFactory = LutFactory.NewInstance;
+
+ return _lutFactory;
+ }
+ }
+
+ #endregion
+
+ #region Disposal
+
+ ///
+ /// Implementation of the pattern
+ ///
+ /// True if this object is being disposed, false if it is being finalized
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (_lutFactory != null)
+ _lutFactory.Dispose();
+
+ if (_lutComposer != null)
+ _lutComposer.Dispose();
+ }
+ }
+
+ #endregion
+
+
+ #region Private methods
+
+ ///
+ /// Install IComposableLut
+ ///
+ ///
+
+ internal void InstallVoiLut(IComposableLut voiLut)
+ {
+ Platform.CheckForNullReference(voiLut, "voiLut");
+
+ InitializeNecessaryLuts(Luts.Modality);
+
+ if (this.LutComposer.LutCollection.Count == 1)
+ {
+ this.LutComposer.LutCollection.Add(voiLut);
+ }
+ else
+ {
+ this.LutComposer.LutCollection[1] = voiLut;
+ }
+ }
+
+ ///
+ /// Initialization of private Variables
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void Initialize(
+ int bitsStored,
+ int highBit,
+ bool isSigned,
+ double rescaleSlope,
+ double rescaleIntercept,
+ bool invert)
+ {
+
+ _bitsStored = bitsStored;
+ _highBit = highBit;
+ _isSigned = isSigned;
+ _rescaleSlope = rescaleSlope <= double.Epsilon ? 1 : rescaleSlope;
+ _rescaleIntercept = rescaleIntercept;
+ _invert = invert;
+ }
+
+ ///
+ /// Initialization of Lut if is need.
+ ///
+ ///
+ private void InitializeNecessaryLuts(Luts luts)
+ {
+ if (luts >= Luts.Modality && LutComposer.LutCollection.Count == 0)
+ {
+ IComposableLut modalityLut =
+ this.LutFactory.GetModalityLutLinear(this.BitsStored, this.IsSigned, _rescaleSlope, _rescaleIntercept);
+
+ this.LutComposer.LutCollection.Add(modalityLut);
+ }
+
+ if (luts >= Luts.Voi && LutComposer.LutCollection.Count == 1)
+ {
+ IComposableLut lut = InitialVoiLutProvider.Instance.GetLut(this.ParentPresentationImage);
+
+ if (lut == null)
+ lut = new MinMaxPixelCalculatedLinearLut(this.PixelData, this.ModalityLut);
+
+ InstallVoiLut(lut);
+ }
+ }
+
+ ///
+ /// Install ColorMap by Name
+ ///
+ ///
+ internal void InstallColorMap(string name)
+ {
+ InstallColorMap(this.LutFactory.GetColorMap(name));
+ }
+
+
+ ///
+ /// Install ColorMap by Interface
+ ///
+ ///
+ internal void InstallColorMap(IDataLut colorMap)
+ {
+ if (_colorMap == colorMap)
+ return;
+
+ _colorMap = colorMap;
+ }
+
+ #endregion
+
+
+
+ }
+
}
Index: ImageViewer/Imaging/AlgorithmCalculatedVoiLutLinear.cs
===================================================================
--- ImageViewer/Imaging/AlgorithmCalculatedVoiLutLinear.cs (revision 9089)
+++ ImageViewer/Imaging/AlgorithmCalculatedVoiLutLinear.cs (working copy)
@@ -52,8 +52,11 @@
#region Private Fields
[CloneCopyReference]
- private readonly GrayscalePixelData _pixelData;
-
+
+ private readonly GrayscalePixelData _pixelData = null;
+
+ private readonly ColorPixelData _pixelDatacolor = null;
+
//allow this to be cloned, since it will just clone the LutFactory's proxy object, anyway.
private readonly IComposableLut _modalityLut;
@@ -80,7 +83,7 @@
_windowCenter = double.NaN;
}
- ///
+ ///
/// Constructor.
///
/// The pixel data the algorithm will be run on.
@@ -89,6 +92,32 @@
{
}
+ ///
+ /// Constructor for ColorPixelData
+ ///
+ /// The pixel data the algorithm will be run on.
+ /// The modality lut to use for calculating and , if applicable.
+ protected AlgorithmCalculatedVoiLutLinear(ColorPixelData pixelDatacolor, IComposableLut modalityLut)
+ {
+ Platform.CheckForNullReference(pixelDatacolor, "pixelData");
+
+ _pixelDatacolor = pixelDatacolor;
+ _modalityLut = modalityLut;
+
+ _windowWidth = 256.0;
+ _windowCenter = 128.0;
+ }
+
+ ///
+ /// Additional Constructor for ColorPixelData
+ ///
+ /// The pixel data the algorithm will be run on.
+ protected AlgorithmCalculatedVoiLutLinear(ColorPixelData pixelDatacolor)
+ : this(pixelDatacolor, null)
+ {
+ }
+
+
///
/// Cloning constructor.
///
Index: ImageViewer/Imaging/MinMaxPixelCalculatedLinearLut.cs
===================================================================
--- ImageViewer/Imaging/MinMaxPixelCalculatedLinearLut.cs (revision 9089)
+++ ImageViewer/Imaging/MinMaxPixelCalculatedLinearLut.cs (working copy)
@@ -42,10 +42,10 @@
[Cloneable]
public sealed class MinMaxPixelCalculatedLinearLut : AlgorithmCalculatedVoiLutLinear
{
- #region Public Constructors
+ #region Constructors
///
- /// Constructor.
+ /// Constructor for GrayscalePixelData
///
///
/// The input object can be null.
@@ -59,7 +59,7 @@
}
///
- /// Constructor.
+ /// Constructor for GrayscalePixelData
///
/// The pixel data the algorithm will be run on.
public MinMaxPixelCalculatedLinearLut(GrayscalePixelData pixelData)
@@ -67,13 +67,44 @@
{
}
+ ///
+ /// Constructor for ColorPixelData
+ ///
+ ///
+ /// The input object can be null.
+ ///
+ /// The pixel data the algorithm will be run on.
+ public MinMaxPixelCalculatedLinearLut(ColorPixelData colorpixelData)
+ : base(colorpixelData)
+ {
+ }
+
+ ///
+ /// Constructor for ColorPixelData
+ ///
+ ///
+ /// The input object can be null.
+ ///
+ /// The pixel data the algorithm will be run on.
+ /// The modality lut to use for calculating
+ /// and , if applicable.
+ public MinMaxPixelCalculatedLinearLut(ColorPixelData pixelData, IComposableLut modalityLut)
+ : base(pixelData, modalityLut)
+ {
+ }
+
+ ///
+ /// Cloning constructor.
+ ///
+ ///
+ ///
private MinMaxPixelCalculatedLinearLut(MinMaxPixelCalculatedLinearLut source, ICloningContext context)
: base(source, context)
{
context.CloneFields(source, this);
}
- #endregion
+ #endregion
#region Overrides
Index: ImageViewer/Imaging/VoiLutManager.cs
===================================================================
--- ImageViewer/Imaging/VoiLutManager.cs (revision 9089)
+++ ImageViewer/Imaging/VoiLutManager.cs (working copy)
@@ -37,68 +37,149 @@
internal sealed class VoiLutManager : IVoiLutManager
{
#region Private Fields
-
- private GrayscaleImageGraphic _grayscaleImageGraphic;
-
+
+ private GrayscaleImageGraphic _grayscaleImageGraphic = null;
+
+ // _colorImageGraphic also IVoiLutManager Provider
+ private ColorImageGraphic _colorImageGraphic = null;
+
#endregion
+
+ #region Public Constructors
+
+ ///
+ /// Constructor for GrayscaleImageGraphic
+ ///
+ ///
public VoiLutManager(GrayscaleImageGraphic grayscaleImageGraphic)
{
Platform.CheckForNullReference(grayscaleImageGraphic, "grayscaleImageGraphic");
_grayscaleImageGraphic = grayscaleImageGraphic;
- }
+ }
- #region IVoiLutManager Members
+ ///
+ /// Constructor for ColorImageGraphic
+ ///
+ ///
+ public VoiLutManager(ColorImageGraphic colorImageGraphic)
+ {
+ Platform.CheckForNullReference(colorImageGraphic, "colorImageGraphic");
+ _colorImageGraphic = colorImageGraphic;
+ }
+
+ #endregion
+
- public IComposableLut GetLut()
- {
- return _grayscaleImageGraphic.VoiLut;
- }
+ #region IVoiLutManager Members
- public void InstallLut(IComposableLut lut)
+
+ public IComposableLut GetLut()
{
- IComposableLut existingLut = GetLut();
- if (existingLut is IGeneratedDataLut)
- {
- //Clear the data in the data lut so it's not hanging around using up memory.
- ((IGeneratedDataLut)existingLut).Clear();
- }
-
- _grayscaleImageGraphic.InstallVoiLut(lut);
- }
+ if (_grayscaleImageGraphic != null)
+ return _grayscaleImageGraphic.VoiLut;
+ else // ColorImageGraphic was instantiated
+ return _colorImageGraphic.VoiLut;
+ }
- public bool Invert
- {
- get { return _grayscaleImageGraphic.Invert; }
- set { _grayscaleImageGraphic.Invert = value; }
- }
+ public void InstallLut(IComposableLut lut)
+ {
+ IComposableLut existingLut = GetLut();
+ if (existingLut is IGeneratedDataLut)
+ {
+ //Clear the data in the data lut so it's not hanging around using up memory.
+ ((IGeneratedDataLut)existingLut).Clear();
+ }
- public void ToggleInvert()
- {
- _grayscaleImageGraphic.Invert = !_grayscaleImageGraphic.Invert;
- }
+ if (_grayscaleImageGraphic != null)
+ _grayscaleImageGraphic.InstallVoiLut(lut);
+ else // ColorImageGraphic was instantiated
+ _colorImageGraphic.InstallVoiLut(lut);
+ }
+
+ public bool Invert
+ {
+ get
+ {
+
+ if (_grayscaleImageGraphic != null)
+ return _grayscaleImageGraphic.Invert;
+ else // ColorImageGraphic was instantiated
+ return _colorImageGraphic.Invert;
+
+ }
+ set
+ {
+ if (_grayscaleImageGraphic != null)
+ {
+ _grayscaleImageGraphic.Invert = value;
+ }
+ else // ColorImageGraphic was instantiated
+ {
+ _colorImageGraphic.Invert = value;
+ }
+ }
+ }
+
+ public void ToggleInvert()
+ {
+ if (_grayscaleImageGraphic != null)
+ {
+ _grayscaleImageGraphic.Invert = !_grayscaleImageGraphic.Invert;
+ }
+ else // ColorImageGraphic was instantiated
+ {
+ _colorImageGraphic.Invert = !_colorImageGraphic.Invert;
+
+ }
+ }
+
#endregion
#region IMemorable Members
+
+ public object CreateMemento()
+ {
+ if (_grayscaleImageGraphic != null)
+ {
+ return new VoiLutMemento(_grayscaleImageGraphic.VoiLut, _grayscaleImageGraphic.Invert);
+ }
+ else // ColorImageGraphic was instantiated
+ {
+ return new VoiLutMemento(_colorImageGraphic.VoiLut, _colorImageGraphic.Invert);
+ }
- public object CreateMemento()
- {
- return new VoiLutMemento(_grayscaleImageGraphic.VoiLut, _grayscaleImageGraphic.Invert);
- }
+ }
public void SetMemento(object memento)
{
- VoiLutMemento lutMemento = memento as VoiLutMemento;
- Platform.CheckForInvalidCast(lutMemento, "memento", typeof(VoiLutMemento).Name);
+ VoiLutMemento lutMemento = memento as VoiLutMemento;
+ Platform.CheckForInvalidCast(lutMemento, "memento", typeof(VoiLutMemento).Name);
- if (_grayscaleImageGraphic.VoiLut != lutMemento.ComposableLutMemento.OriginatingLut)
- this.InstallLut(lutMemento.ComposableLutMemento.OriginatingLut);
+ if (_grayscaleImageGraphic != null)
+ {
- if (lutMemento.ComposableLutMemento.InnerMemento != null)
- _grayscaleImageGraphic.VoiLut.SetMemento(lutMemento.ComposableLutMemento.InnerMemento);
+ if (_grayscaleImageGraphic.VoiLut != lutMemento.ComposableLutMemento.OriginatingLut)
+ this.InstallLut(lutMemento.ComposableLutMemento.OriginatingLut);
- _grayscaleImageGraphic.Invert = lutMemento.Invert;
+ if (lutMemento.ComposableLutMemento.InnerMemento != null)
+ _grayscaleImageGraphic.VoiLut.SetMemento(lutMemento.ComposableLutMemento.InnerMemento);
+
+ _grayscaleImageGraphic.Invert = lutMemento.Invert;
+ }
+ else // ColorImageGraphic was instantiated
+ {
+ if (_colorImageGraphic.VoiLut != lutMemento.ComposableLutMemento.OriginatingLut)
+ this.InstallLut(lutMemento.ComposableLutMemento.OriginatingLut);
+
+ if (lutMemento.ComposableLutMemento.InnerMemento != null)
+ _colorImageGraphic.VoiLut.SetMemento(lutMemento.ComposableLutMemento.InnerMemento);
+
+ _colorImageGraphic.Invert = lutMemento.Invert;
+
+
+ }
}
#endregion
Index: ImageViewer/Rendering/BilinearInterpolation/BilinearInterpolation.cpp
===================================================================
--- ImageViewer/Rendering/BilinearInterpolation/BilinearInterpolation.cpp (revision 9089)
+++ ImageViewer/Rendering/BilinearInterpolation/BilinearInterpolation.cpp (working copy)
@@ -606,6 +606,7 @@
}
}
+
void InterpolateBilinearRGB(
BYTE* pDstPixelData,
@@ -627,6 +628,8 @@
float xRatio,
float yRatio,
+ LUTDATA* pLutData,
+
std::auto_ptr& spxSrcPixels,
std::auto_ptr& spdxFixedAtSrcPixelCoordinates)
{
@@ -666,8 +669,10 @@
int yInterpolated2 = (*pSrcPixel01 << FIXEDPRECISION) + ((dyFixed * ((*pSrcPixel11 - *pSrcPixel01) << FIXEDPRECISION)) >> FIXEDPRECISION);
int IFinal = (yInterpolated1 + (((*pdxFixed) * (yInterpolated2 - yInterpolated1)) >> FIXEDPRECISION)) >> FIXEDPRECISION;
- pRowDstPixelData[i] = (BYTE)(IFinal); //R(i=0), G(1), B(2), A(3)
+ // pRowDstPixelData[i] = (BYTE)(IFinal);
+ pRowDstPixelData[i] = (BYTE)(*(pLutData->LutData + (BYTE)(IFinal) - pLutData->FirstMappedPixelValue));
+
pSrcPixel00 += srcNextChannelOffset;
}
@@ -682,6 +687,10 @@
}
+
+
+
+
BOOL InterpolateBilinear
(
BYTE* pSrcPixelData,
@@ -825,8 +834,10 @@
srcNextChannelOffset,
xRatio,
yRatio,
+ pLutData,
spxSrcPixels,
spdxFixedAtSrcPixelCoordinates);
+
}
else
{
Index: ImageViewer/Rendering/ImageRenderer.cs
===================================================================
--- ImageViewer/Rendering/ImageRenderer.cs (revision 9089)
+++ ImageViewer/Rendering/ImageRenderer.cs (working copy)
@@ -135,7 +135,15 @@
}
}
}
-
+ ///
+ /// Render ColorImageGraphic with lutData
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
private static void RenderColor(
ColorImageGraphic image,
RectangleF srcViewableRectangle,
@@ -144,30 +152,49 @@
int dstWidth,
int dstBytesPerPixel)
{
- fixed (byte* pSrcPixelData = image.PixelData.Raw)
- {
- if (image.InterpolationMode == InterpolationMode.Bilinear)
- {
- int srcBytesPerPixel = 4;
+
- ImageInterpolatorBilinear.Interpolate(
- srcViewableRectangle,
- pSrcPixelData,
- image.Columns,
- image.Rows,
- srcBytesPerPixel,
- 32,
- dstViewableRectangle,
- (byte*)pDstPixelData,
- dstWidth,
- dstBytesPerPixel,
- IsRotated(image),
- null,
- true,
- false,
- false);
- }
- }
+ fixed (byte* pSrcPixelData = image.PixelData.Raw)
+ {
+ if (image.InterpolationMode == InterpolationMode.Bilinear)
+ {
+ // int[] finalLutBuffer = ConstructFinalLut(image.OutputLut, image.ColorMap, image.Invert);
+
+ //
+ // Invert of Color Image is disabled
+ //
+ int[] finalLutBuffer = ConstructFinalLut(image.OutputLut, image.ColorMap, false);
+
+ fixed (int* pFinalLutData = finalLutBuffer)
+ {
+ ImageInterpolatorBilinear.LutData lutData;
+ lutData.Data = pFinalLutData;
+ lutData.FirstMappedPixelData = image.OutputLut.MinInputValue;
+ lutData.Length = finalLutBuffer.Length;
+
+ int srcBytesPerPixel = 4;
+
+ ImageInterpolatorBilinear.Interpolate(
+ srcViewableRectangle,
+ pSrcPixelData,
+ image.Columns,
+ image.Rows,
+ srcBytesPerPixel,
+ 8,
+ dstViewableRectangle,
+ (byte*)pDstPixelData,
+ dstWidth,
+ dstBytesPerPixel,
+ IsRotated(image),
+ &lutData, //ok because it's a local variable in an unsafe method, therefore it's already fixed.
+ true,
+ false,
+ false);
+ }
+ }
+ }
+
+
}
private static bool IsRotated(ImageGraphic imageGraphic)
Index: ImageViewer/Tools/Standard/PresetVoiLuts/Luts/AutoVoiLutLinear.cs
===================================================================
--- ImageViewer/Tools/Standard/PresetVoiLuts/Luts/AutoVoiLutLinear.cs (revision 9089)
+++ ImageViewer/Tools/Standard/PresetVoiLuts/Luts/AutoVoiLutLinear.cs (working copy)
@@ -184,9 +184,22 @@
get { return _name; }
}
+
+ ///
+ ///
+ ///
+ ///
+ ///
public static bool CanCreateFrom(IDicomVoiLutsProvider provider)
{
- return provider != null && provider.DicomVoiLuts.ImageVoiLinearLuts.Count > 0;
+ //
+ // In the case when Image doesn't have Width and Center
+ // "DicomVoiLuts.ImageVoiLinearLuts.Count" is zero and function return false
+ // This case is frequently for RGB images
+ // The condition "provider.DicomVoiLuts.ImageVoiLinearLuts.Count >= 0"
+ // is temporary workaround about this problem
+ //
+ return provider != null && provider.DicomVoiLuts.ImageVoiLinearLuts.Count >= 0;
}
public static AutoImageVoiLutLinear CreateFrom(IDicomVoiLutsProvider provider)
Index: ImageViewer/Tools/Standard/PresetVoiLuts/Operations/AutoPresetVoiLutOperationComponent.cs
===================================================================
--- ImageViewer/Tools/Standard/PresetVoiLuts/Operations/AutoPresetVoiLutOperationComponent.cs (revision 9089)
+++ ImageViewer/Tools/Standard/PresetVoiLuts/Operations/AutoPresetVoiLutOperationComponent.cs (working copy)
@@ -64,7 +64,15 @@
{
get { return (GrayscalePixelData) ((IImageGraphicProvider) _image).ImageGraphic.PixelData; }
}
+ ///
+ /// Property PixelDataColor for ColorPixelData
+ ///
+ private ColorPixelData PixelDataColor
+ {
+ get { return (ColorPixelData)((IImageGraphicProvider)_image).ImageGraphic.PixelData; }
+ }
+
private IVoiLutManager VoiLutManager
{
get { return ((IVoiLutProvider) _image).VoiLutManager; }
@@ -77,10 +85,28 @@
private MinMaxPixelCalculatedLinearLut GetDefaultMinMaxLut()
{
- if (IsModalityLutProvider(_image))
- return new MinMaxPixelCalculatedLinearLut(this.PixelData, ((IModalityLutProvider) _image).ModalityLut);
- else
- return new MinMaxPixelCalculatedLinearLut(this.PixelData);
+ //
+ // We have two different cases for DicomGrayscalePresentationImage
+ // and DicomColorPresentationImage
+ //
+ if ((IImageGraphicProvider)_image is DicomGrayscalePresentationImage)
+ {
+
+ if (IsModalityLutProvider(_image))
+ return new MinMaxPixelCalculatedLinearLut(this.PixelData, ((IModalityLutProvider)_image).ModalityLut);
+ else
+ return new MinMaxPixelCalculatedLinearLut(this.PixelData);
+ }
+ else // _image is DicomColorPresentationImage
+ {
+
+ if (IsModalityLutProvider(_image))
+ return new MinMaxPixelCalculatedLinearLut(this.PixelDataColor, ((IModalityLutProvider)_image).ModalityLut);
+ else
+ return new MinMaxPixelCalculatedLinearLut(this.PixelDataColor);
+ }
+
+
}
public IComposableLut GetInitialLut()
@@ -223,7 +249,13 @@
public static bool CanCreateFrom(IPresentationImage presentationImage)
{
- if (IsVoiLutProvider(presentationImage) && IsGrayScaleImage(presentationImage) && IsImageSopProvider(presentationImage))
+ //
+ // RGB Images is also IVoiLutProvider and IDIcomVoiLutProvider.
+ // Because this the check "IsGrayScaleImage(presentationImage)" is canceled
+ //
+
+ if ( IsVoiLutProvider(presentationImage) // && IsGrayScaleImage(presentationImage)
+ && IsImageSopProvider(presentationImage))
{
IDicomVoiLutsProvider voiLutsProvider = presentationImage as IDicomVoiLutsProvider;
return (AutoImageVoiLutLinear.CanCreateFrom(voiLutsProvider)
Index: ImageViewer/Tools/Standard/WindowLevelTool.cs
===================================================================
--- ImageViewer/Tools/Standard/WindowLevelTool.cs (revision 9089)
+++ ImageViewer/Tools/Standard/WindowLevelTool.cs (working copy)
@@ -127,22 +127,22 @@
private void IncrementWindowWidth()
{
- IncrementWindowWithUndo(10, 0);
+ IncrementWindowWithUndo(5, 0);
}
private void DecrementWindowWidth()
{
- IncrementWindowWithUndo(-10, 0);
+ IncrementWindowWithUndo(-5, 0);
}
private void IncrementWindowCenter()
{
- IncrementWindowWithUndo(0, 10);
+ IncrementWindowWithUndo(0, 5);
}
private void DecrementWindowCenter()
{
- IncrementWindowWithUndo(0, -10);
+ IncrementWindowWithUndo(0, -5);
}
private void IncrementWindow(double windowIncrement, double levelIncrement)
@@ -210,7 +210,7 @@
{
base.Track(mouseInformation);
- IncrementWindow(this.DeltaX * 10, this.DeltaY * 10);
+ IncrementWindow(this.DeltaX * 5, this.DeltaY * 5);
return true;
}