/// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="collection"></param>
		protected DicomPixelData(DicomAttributeCollection collection)
		{
			collection.LoadDicomFields(this);

			SopClass = SopClass.GetSopClass(collection[DicomTags.SopClassUid].GetString(0, string.Empty));

			if (collection.Contains(DicomTags.NumberOfFrames))
				NumberOfFrames = collection[DicomTags.NumberOfFrames].GetInt32(0, 1);
			if (collection.Contains(DicomTags.PlanarConfiguration))
				PlanarConfiguration = collection[DicomTags.PlanarConfiguration].GetUInt16(0, 1);
			if (collection.Contains(DicomTags.LossyImageCompression))
				LossyImageCompression = collection[DicomTags.LossyImageCompression].GetString(0, string.Empty);
			if (collection.Contains(DicomTags.LossyImageCompressionRatio))
				LossyImageCompressionRatio = collection[DicomTags.LossyImageCompressionRatio].GetFloat32(0, 1.0f);
			if (collection.Contains(DicomTags.LossyImageCompressionMethod))
				LossyImageCompressionMethod = collection[DicomTags.LossyImageCompressionMethod].GetString(0, string.Empty);
			if (collection.Contains(DicomTags.DerivationDescription))
				DerivationDescription = collection[DicomTags.DerivationDescription].GetString(0, string.Empty);
			if (collection.Contains(DicomTags.RescaleSlope))
				RescaleSlope = collection[DicomTags.RescaleSlope].ToString();
			if (collection.Contains(DicomTags.RescaleIntercept))
				RescaleIntercept = collection[DicomTags.RescaleIntercept].ToString();
			if (collection.Contains(DicomTags.ModalityLutSequence))
			{
				DicomAttribute attrib = collection[DicomTags.ModalityLutSequence];
				_hasDataModalityLut = !attrib.IsEmpty && !attrib.IsNull;
			}

			_linearVoiLuts = Window.GetWindowCenterAndWidth(collection);
			if (collection.Contains(DicomTags.VoiLutSequence))
			{
				DicomAttribute attrib = collection[DicomTags.VoiLutSequence];
				_hasDataVoiLuts = !attrib.IsEmpty && !attrib.IsNull;
			}

			if (PhotometricInterpretation.Equals(Iod.PhotometricInterpretation.PaletteColor.Code) && collection.Contains(DicomTags.RedPaletteColorLookupTableDescriptor))
			{
				_paletteColorLut = PaletteColorLut.Create(collection);
				_hasPaletteColorLut = true;
			}
		}
		/// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="attrib"></param>
		internal DicomPixelData(DicomPixelData attrib)
		{
			SopClass = attrib.SopClass;

			NumberOfFrames = attrib.NumberOfFrames;
			ImageWidth = attrib.ImageWidth;
			ImageHeight = attrib.ImageHeight;
			HighBit = attrib.HighBit;
			BitsStored = attrib.BitsStored;
			BitsAllocated = attrib.BitsAllocated;
			SamplesPerPixel = attrib.SamplesPerPixel;
			PixelRepresentation = attrib.PixelRepresentation;
			PlanarConfiguration = attrib.PlanarConfiguration;
			PhotometricInterpretation = attrib.PhotometricInterpretation;
			LossyImageCompression = attrib.LossyImageCompression;
			DerivationDescription = attrib.DerivationDescription;
			LossyImageCompressionRatio = attrib.LossyImageCompressionRatio;
			LossyImageCompressionMethod = attrib.LossyImageCompressionMethod;
			RescaleSlope = attrib.RescaleSlope;
			RescaleIntercept = attrib.RescaleIntercept;

			_hasDataModalityLut = attrib.HasDataModalityLut;
			_hasDataVoiLuts = attrib.HasDataVoiLuts;
			_hasPaletteColorLut = attrib.HasPaletteColorLut;
			_paletteColorLut = attrib.PaletteColorLut;

			foreach (Window window in attrib.LinearVoiLuts)
				_linearVoiLuts.Add(new Window(window));
		}
		/// <summary>
		/// Convert Palette Color pixel data to RGB.
		/// </summary>
		/// <param name="bitsAllocated"></param>
		/// <param name="isSigned"></param>
		/// <param name="srcPixelData"></param>
		/// <param name="rgbPixelData"></param>
		/// <param name="lut"></param>
		public static unsafe void PaletteColorToRgb(
			int bitsAllocated,
			bool isSigned,
			byte[] srcPixelData,
			byte[] rgbPixelData,
			PaletteColorLut lut)
		{
			Platform.CheckTrue(bitsAllocated == 8 || bitsAllocated == 16, "Valid Bits Allocated");
			Platform.CheckForNullReference(srcPixelData, "srcPixelData");
			Platform.CheckForNullReference(rgbPixelData, "rgbPixelData");
			Platform.CheckForNullReference(lut, "lut");

			int sizeInPixels = rgbPixelData.Length/3;

			const string messageInvalidBufferSize = "Invalid destination buffer size";
			if (bitsAllocated == 8 && 3*srcPixelData.Length != rgbPixelData.Length)
				throw new ArgumentException(messageInvalidBufferSize, "rgbPixelData");
			if (bitsAllocated > 8 && srcPixelData.Length/2 != sizeInPixels)
				throw new ArgumentException(messageInvalidBufferSize, "rgbPixelData");

			int firstPixelMapped = lut.FirstMappedPixelValue;

			fixed (byte* pSrcPixelData = srcPixelData)
			{
				fixed (byte* pRgbPixelData = rgbPixelData)
				{
					int dst = 0;

					if (bitsAllocated == 8)
					{
						if (isSigned)
						{
							// 8-bit signed
							for (int i = 0; i < sizeInPixels; i++)
							{
								Color value = lut.Data[((sbyte*) pSrcPixelData)[i] - firstPixelMapped];
								pRgbPixelData[dst] = value.R;
								pRgbPixelData[dst + 1] = value.G;
								pRgbPixelData[dst + 2] = value.B;

								dst += 3;
							}
						}
						else
						{
							// 8-bit unsigned
							for (int i = 0; i < sizeInPixels; i++)
							{
								Color value = lut.Data[pSrcPixelData[i] - firstPixelMapped];
								pRgbPixelData[dst] = value.R;
								pRgbPixelData[dst + 1] = value.G;
								pRgbPixelData[dst + 2] = value.B;

								dst += 3;
							}
						}
					}
					else
					{
						if (isSigned)
						{
							// 16-bit signed
							for (int i = 0; i < sizeInPixels; i++)
							{
								Color value = lut.Data[((short*) pSrcPixelData)[i] - firstPixelMapped];
								pRgbPixelData[dst] = value.R;
								pRgbPixelData[dst + 1] = value.G;
								pRgbPixelData[dst + 2] = value.B;

								dst += 3;
							}
						}
						else
						{
							// 16-bit unsinged
							for (int i = 0; i < sizeInPixels; i++)
							{
								Color value = lut.Data[((ushort*) pSrcPixelData)[i] - firstPixelMapped];
								pRgbPixelData[dst] = value.R;
								pRgbPixelData[dst + 1] = value.G;
								pRgbPixelData[dst + 2] = value.B;

								dst += 3;
							}
						}
					}
				}
			}
		}