public async Task GivenMultipleFrames_WhenRetrieveFrame_ThenServerShouldReturnExpectedContent() { string studyInstanceUid = TestUidGenerator.Generate(); DicomFile dicomFile1 = Samples.CreateRandomDicomFileWithPixelData(studyInstanceUid, frames: 3); DicomPixelData pixelData = DicomPixelData.Create(dicomFile1.Dataset); InstanceIdentifier dicomInstance = dicomFile1.Dataset.ToInstanceIdentifier(); await InternalStoreAsync(new[] { dicomFile1 }); using DicomWebAsyncEnumerableResponse <Stream> response = await _client.RetrieveFramesAsync( dicomInstance.StudyInstanceUid, dicomInstance.SeriesInstanceUid, dicomInstance.SopInstanceUid, frames : new[] { 1, 2 }, dicomTransferSyntax : "*"); Stream[] frames = await response.ToArrayAsync(); Assert.NotNull(frames); Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(2, frames.Length); Assert.Equal(KnownContentTypes.MultipartRelated, response.ContentHeaders.ContentType.MediaType); Assert.Equal(pixelData.GetFrame(0).Data, frames[0].ToByteArray()); Assert.Equal(pixelData.GetFrame(1).Data, frames[1].ToByteArray()); }
/// <summary> /// Create <see cref="IPixelData"/> form <see cref="DicomPixelData"/> /// according to the input <paramref name="pixelData"/> <seealso cref="PhotometricInterpretation"/> /// </summary> /// <param name="pixelData">Input pixel data</param> /// <param name="frame">Frame number (0 based)</param> /// <returns>Implementation of <seealso cref="IPixelData"/> according to <seealso cref="PhotometricInterpretation"/></returns> public static IPixelData Create(DicomPixelData pixelData, int frame) { PhotometricInterpretation pi = pixelData.PhotometricInterpretation; if (pi == null) { // generally ACR-NEMA var samples = pixelData.SamplesPerPixel; if (samples == 0 || samples == 1) { if (pixelData.Dataset.Contains(DicomTag.RedPaletteColorLookupTableData)) pi = PhotometricInterpretation.PaletteColor; else pi = PhotometricInterpretation.Monochrome2; } else { // assume, probably incorrectly, that the image is RGB pi = PhotometricInterpretation.Rgb; } } if (pixelData.BitsStored == 1) { if (pixelData.Dataset.Get<DicomUID>(DicomTag.SOPClassUID) == DicomUID.MultiFrameSingleBitSecondaryCaptureImageStorage) // Multi-frame Single Bit Secondary Capture is stored LSB -> MSB return new SingleBitPixelData(pixelData.Width, pixelData.Height, PixelDataConverter.ReverseBits(pixelData.GetFrame(frame))); else // Need sample images to verify that this is correct return new SingleBitPixelData(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame)); } else if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2 || pi == PhotometricInterpretation.PaletteColor) { if (pixelData.BitsAllocated <= 8) return new GrayscalePixelDataU8(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame)); else if (pixelData.BitsAllocated <= 16) { if (pixelData.PixelRepresentation == PixelRepresentation.Signed) return new GrayscalePixelDataS16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); else return new GrayscalePixelDataU16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); } else if (pixelData.BitsAllocated <= 32) { if (pixelData.PixelRepresentation == PixelRepresentation.Signed) return new GrayscalePixelDataS32(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); else return new GrayscalePixelDataU32(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); } else throw new DicomImagingException("Unsupported pixel data value for bits stored: {0}", pixelData.BitsStored); } else if (pi == PhotometricInterpretation.Rgb || pi == PhotometricInterpretation.YbrFull) { var buffer = pixelData.GetFrame(frame); if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar) buffer = PixelDataConverter.PlanarToInterleaved24(buffer); return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer); } else { throw new DicomImagingException("Unsupported pixel data photometric interpretation: {0}", pi.Value); } }
/// <summary> /// Create <see cref="IPixelData"/> form <see cref="DicomPixelData"/> /// according to the input <paramref name="pixelData"/> <seealso cref="PhotometricInterpretation"/> /// </summary> /// <param name="pixelData">Input pixel data</param> /// <param name="frame">Frame number (0 based)</param> /// <returns>Implementation of <seealso cref="IPixelData"/> according to <seealso cref="PhotometricInterpretation"/></returns> public static IPixelData Create(DicomPixelData pixelData, int frame) { PhotometricInterpretation pi = pixelData.PhotometricInterpretation; if (pi == null) { // generally ACR-NEMA var samples = pixelData.SamplesPerPixel; if (samples == 0 || samples == 1) { if (pixelData.Dataset.Contains(DicomTag.RedPaletteColorLookupTableData)) pi = PhotometricInterpretation.PaletteColor; else pi = PhotometricInterpretation.Monochrome2; } else { // assume, probably incorrectly, that the image is RGB pi = PhotometricInterpretation.Rgb; } } if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2 || pi == PhotometricInterpretation.PaletteColor) { if (pixelData.BitsAllocated <= 8) return new GrayscalePixelDataU8(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame)); else if (pixelData.BitsAllocated <= 16) { if (pixelData.PixelRepresentation == PixelRepresentation.Signed) return new GrayscalePixelDataS16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); else return new GrayscalePixelDataU16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); } else if (pixelData.BitsAllocated <= 32) { if (pixelData.PixelRepresentation == PixelRepresentation.Signed) return new GrayscalePixelDataS32(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); else return new GrayscalePixelDataU32(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); } else throw new DicomImagingException("Unsupported pixel data value for bits stored: {0}", pixelData.BitsStored); } else if (pi == PhotometricInterpretation.Rgb || pi == PhotometricInterpretation.YbrFull) { var buffer = pixelData.GetFrame(frame); if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar) buffer = PixelDataConverter.PlanarToInterleaved24(buffer); return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer); } else if (pi == PhotometricInterpretation.YbrFull422) { var buffer = pixelData.GetFrame(frame); if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar) throw new DicomImagingException("Unsupported planar configuration for YBR_FULL_422"); return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer); } else { throw new DicomImagingException("Unsupported pixel data photometric interpretation: {0}", pi.Value); } }
static private void BreakUp() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); const string sourcePath = "/media/nikolaev_ov/CEFE3C54FE3C36D5/DICOM/ComputerTomography/Covid/favorite/several-frames/sources/1.2.392.200036.9116.2.5.1.37.2418295482.1507184833.33568"; DicomFile dicomFile = DicomFile.Open(sourcePath); DicomPixelData pixelData = DicomPixelData.Create(dicomFile.Dataset, false); MemoryStream[] frameFiles = new MemoryStream[pixelData.NumberOfFrames]; MemoryStream zip = new MemoryStream(); using (ZipArchive archive = new ZipArchive(zip, ZipArchiveMode.Create, true)) { for (int frameIndex = 0; frameIndex != pixelData.NumberOfFrames; frameIndex++) { DicomDataset frameDataset = new DicomDataset(dicomFile.Dataset.InternalTransferSyntax); dicomFile.Dataset.CopyTo(frameDataset); DicomPixelData framePixelData = DicomPixelData.Create(frameDataset, true); IByteBuffer buffer = pixelData.GetFrame(frameIndex); framePixelData.AddFrame(buffer); ZipArchiveEntry readmeEntry = archive.CreateEntry(frameIndex.ToString()); using (Stream stream = readmeEntry.Open()) new DicomFile(frameDataset).Save(stream); } } stopwatch.Stop(); Console.WriteLine(stopwatch.ElapsedMilliseconds); using (FileStream file = new FileStream("/media/nikolaev_ov/CEFE3C54FE3C36D5/test.zip", FileMode.OpenOrCreate, FileAccess.ReadWrite)) { zip.Position = 0; zip.CopyTo(file); } }
internal static void Decode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomJpegLsParams parameters) { for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var jpegData = oldPixelData.GetFrame(frame); var frameSize = newPixelData.UncompressedFrameSize; if ((frameSize & 1) == 1) { ++frameSize; } var frameData = new byte[frameSize]; string errorMessage; var err = JpegLs.Decode(frameData, jpegData.Data, null, out errorMessage); if (err != ApiResult.OK) { throw new InvalidOperationException(GetErrorMessage(err, errorMessage)); } newPixelData.AddFrame(new MemoryByteBuffer(frameData)); } }
public static NativePixelData ToNativePixelData(this DicomPixelData dicomPixelData) { return(new NativePixelData { NumberOfFrames = dicomPixelData.NumberOfFrames, Width = dicomPixelData.Width, Height = dicomPixelData.Height, SamplesPerPixel = dicomPixelData.SamplesPerPixel, HighBit = dicomPixelData.HighBit, BitsStored = dicomPixelData.BitsStored, BitsAllocated = dicomPixelData.BitsAllocated, BytesAllocated = dicomPixelData.BytesAllocated, UncompressedFrameSize = dicomPixelData.UncompressedFrameSize, PlanarConfiguration = (int)dicomPixelData.PlanarConfiguration, PixelRepresentation = (int)dicomPixelData.PixelRepresentation, TransferSyntaxIsLossy = dicomPixelData.Syntax.IsLossy, PhotometricInterpretation = dicomPixelData.PhotometricInterpretation.Value, GetFrameImpl = index => dicomPixelData.GetFrame(index).Data, AddFrameImpl = buffer => dicomPixelData.AddFrame(new MemoryByteBuffer(buffer)), SetPlanarConfigurationImpl = value => dicomPixelData.PlanarConfiguration = (PlanarConfiguration)value, SetPhotometricInterpretationImpl = value => dicomPixelData.PhotometricInterpretation = PhotometricInterpretation.Parse(value) }); }
public async Task GivenSupportedAcceptHeaders_WhenRetrieveFrame_ThenServerShouldReturnExpectedContent(string testDataFolder, string mediaType, string transferSyntax) { TranscoderTestData transcoderTestData = TranscoderTestDataHelper.GetTestData(testDataFolder); DicomFile inputDicomFile = await DicomFile.OpenAsync(transcoderTestData.InputDicomFile); await EnsureFileIsStoredAsync(inputDicomFile); var instanceId = inputDicomFile.Dataset.ToInstanceIdentifier(); _studiesToClean.Add(instanceId.StudyInstanceUid); DicomFile outputDicomFile = DicomFile.Open(transcoderTestData.ExpectedOutputDicomFile); DicomPixelData pixelData = DicomPixelData.Create(outputDicomFile.Dataset); using DicomWebAsyncEnumerableResponse <Stream> response = await _client.RetrieveFramesAsync( instanceId.StudyInstanceUid, instanceId.SeriesInstanceUid, instanceId.SopInstanceUid, mediaType, transferSyntax, frames : new[] { 1 }); int frameIndex = 0; await foreach (Stream item in response) { // TODO: verify media type once https://microsofthealth.visualstudio.com/Health/_workitems/edit/75185 is done Assert.Equal(item.ToByteArray(), pixelData.GetFrame(frameIndex).Data); frameIndex++; } }
private DicomDataset Encode(DicomDataset oldDataset, DicomTransferSyntax inSyntax, IDicomCodec codec, DicomCodecParams parameters) { DicomPixelData oldPixelData = DicomPixelData.Create(oldDataset, false); DicomDataset newDataset = oldDataset.Clone(); newDataset.InternalTransferSyntax = codec.TransferSyntax; DicomPixelData newPixelData = DicomPixelData.Create(newDataset, true); codec.Encode(oldPixelData, newPixelData, parameters); if (codec.TransferSyntax.IsLossy && newPixelData.NumberOfFrames > 0) { newDataset.Add(new DicomCodeString(DicomTag.LossyImageCompression, "01")); List <string> methods = new List <string>(); if (newDataset.Contains(DicomTag.LossyImageCompressionMethod)) { methods.AddRange(newDataset.Get <string[]>(DicomTag.LossyImageCompressionMethod)); } methods.Add(codec.TransferSyntax.LossyCompressionMethod); newDataset.Add(new DicomCodeString(DicomTag.LossyImageCompressionMethod, methods.ToArray())); double oldSize = oldPixelData.GetFrame(0).Size; double newSize = newPixelData.GetFrame(0).Size; string ratio = String.Format("{0:0.000}", oldSize / newSize); newDataset.Add(new DicomDecimalString(DicomTag.LossyImageCompressionRatio, ratio)); } ProcessOverlays(oldDataset, newDataset); newDataset.RecalculateGroupLengths(false); return(newDataset); }
public override void Decode(DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { throw new InvalidOperationException("Unsupported OS Platform"); } for (int frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { IByteBuffer jpegData = oldPixelData.GetFrame(frame); //Converting photmetricinterpretation YbrFull or YbrFull422 to RGB if (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull) { jpegData = PixelDataConverter.YbrFullToRgb(jpegData); oldPixelData.PhotometricInterpretation = PhotometricInterpretation.Rgb; } else if (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull422) { jpegData = PixelDataConverter.YbrFull422ToRgb(jpegData, oldPixelData.Width); oldPixelData.PhotometricInterpretation = PhotometricInterpretation.Rgb; } PinnedByteArray jpegArray = new PinnedByteArray(jpegData.Data); byte[] frameData = new byte[newPixelData.UncompressedFrameSize]; PinnedByteArray frameArray = new PinnedByteArray(frameData); JlsParameters jls = new JlsParameters(); char[] errorMessage = new char[256]; // IMPORT JpegLsDecode unsafe { if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { CharlsApiResultType err = JpegLSDecode_Linux64((void *)frameArray.Pointer, frameData.Length, (void *)jpegArray.Pointer, Convert.ToUInt32(jpegData.Size), ref jls, errorMessage); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { CharlsApiResultType err = JpegLSDecode_Windows64((void *)frameArray.Pointer, frameData.Length, (void *)jpegArray.Pointer, Convert.ToUInt32(jpegData.Size), ref jls, errorMessage); } IByteBuffer buffer; if (frameData.Length >= (1 * 1024 * 1024) || oldPixelData.NumberOfFrames > 1) { buffer = new TempFileBuffer(frameData); } else { buffer = new MemoryByteBuffer(frameData); } buffer = EvenLengthBuffer.Create(buffer); newPixelData.AddFrame(buffer); } } }
public void SavePixels(string filename) { DicomPixelData pd = DicomPixelData.CreateFrom(_dicomFile); if (File.Exists(filename)) { File.Delete(filename); } using (FileStream fs = new FileStream(filename, FileMode.CreateNew)) { byte[] ba; DicomCompressedPixelData compressed = pd as DicomCompressedPixelData; if (compressed != null) { ba = compressed.GetFrameFragmentData(0); } else { ba = pd.GetFrame(0); } fs.Write(ba, 0, ba.Length); fs.Flush(); fs.Close(); } }
private Stream GetFrameAsDicomData(DicomPixelData pixelData, int frame) { EnsureArg.IsNotNull(pixelData, nameof(pixelData)); IByteBuffer resultByteBuffer = pixelData.GetFrame(frame); return(_recyclableMemoryStreamManager.GetStream("FrameHandler.GetFrameAsDicomData", resultByteBuffer.Data, 0, resultByteBuffer.Data.Length)); }
/// <summary> /// Extracts DICOM file data and saves it as a UByteArrayAsImage. /// </summary> /// <param name="f">A DICOM file</param> /// <returns>A UByteArrayAsImage</returns> public static UByteArrayAsImage GetUByteImageInfo(this DicomFile f) { DicomPixelData pixelData = DicomPixelData.Create(f.Dataset); int columns = f.Dataset.GetValue <int>(DicomTag.Columns, 0); int rows = f.Dataset.GetValue <int>(DicomTag.Rows, 0); byte[] byteData = pixelData.GetFrame(0).Data; return(new UByteArrayAsImage(byteData, columns, rows)); }
public override void Encode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { var pixelCount = oldPixelData.Width * oldPixelData.Height; var numberOfSegments = oldPixelData.BytesAllocated * oldPixelData.SamplesPerPixel; for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var frameData = oldPixelData.GetFrame(frame); var frameArray = frameData.Data; using (var encoder = new RLEEncoder()) { for (var s = 0; s < numberOfSegments; s++) { encoder.NextSegment(); var sample = s / oldPixelData.BytesAllocated; var sabyte = s % oldPixelData.BytesAllocated; int pos; int offset; if (newPixelData.PlanarConfiguration == PlanarConfiguration.Interleaved) { pos = sample * oldPixelData.BytesAllocated; offset = numberOfSegments; } else { pos = sample * oldPixelData.BytesAllocated * pixelCount; offset = oldPixelData.BytesAllocated; } pos += oldPixelData.BytesAllocated - sabyte - 1; for (var p = 0; p < pixelCount; p++) { if (pos >= frameArray.Length) { throw new InvalidOperationException("Read position is past end of frame buffer"); } encoder.Encode(frameArray[pos]); pos += offset; } encoder.Flush(); } encoder.MakeEvenLength(); var data = encoder.GetBuffer(); newPixelData.AddFrame(data); } } }
public override void Decode(DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var encodedData = oldPixelData.GetFrame(frame); var decodedData = ReadImage(encodedData); newPixelData.AddFrame(new StreamByteBuffer(decodedData, 0, (uint)decodedData.Length)); } }
protected override void Upload(fo.DicomDataset dicomObject, int frame, IStorageLocation storeLocation) { var frameIndex = frame - 1; DicomPixelData pd = DicomPixelData.Create(dicomObject); byte[] buffer = pd.GetFrame(frameIndex).Data; storeLocation.Upload(buffer); }
private string GetFramesHashCode(DicomFile dicomFile) { DicomPixelData dicomPixelData = DicomPixelData.Create(dicomFile.Dataset); List <byte> frames = new List <byte>(); for (int i = 0; i < dicomPixelData.NumberOfFrames; i++) { frames.AddRange(dicomPixelData.GetFrame(i).Data); } return(GetByteArrayHashCode(frames.ToArray())); }
public override void Decode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var rleData = oldPixelData.GetFrame(frame); // Create new frame data of even length var frameSize = newPixelData.UncompressedFrameSize; if ((frameSize & 1) == 1) { ++frameSize; } var frameData = new MemoryByteBuffer(new byte[frameSize]); var pixelCount = oldPixelData.Width * oldPixelData.Height; var numberOfSegments = oldPixelData.BytesAllocated * oldPixelData.SamplesPerPixel; var decoder = new RLEDecoder(rleData); if (decoder.NumberOfSegments != numberOfSegments) { throw new InvalidOperationException("Unexpected number of RLE segments!"); } for (var s = 0; s < numberOfSegments; s++) { var sample = s / newPixelData.BytesAllocated; var sabyte = s % newPixelData.BytesAllocated; int pos, offset; if (newPixelData.PlanarConfiguration == PlanarConfiguration.Interleaved) { pos = sample * newPixelData.BytesAllocated; offset = newPixelData.SamplesPerPixel * newPixelData.BytesAllocated; } else { pos = sample * newPixelData.BytesAllocated * pixelCount; offset = newPixelData.BytesAllocated; } pos += newPixelData.BytesAllocated - sabyte - 1; decoder.DecodeSegment(s, frameData, pos, offset); } newPixelData.AddFrame(frameData); } }
protected override void Upload(DicomFile dicomObject, int frame, IStorageLocation storeLocation) { DicomPixelData pd = null; byte[] buffer = null; pd = DicomPixelData.CreateFrom(dicomObject); buffer = pd.GetFrame(frame - 1); storeLocation.Upload(buffer); }
private static int[] GetGrayPixelData(DicomDataset dataset) { DicomPixelData pixelData = DicomPixelData.Create(dataset); IByteBuffer buffer = pixelData.GetFrame(0); IPixelData data = PixelDataFactory.Create(pixelData, 0); var renderOptions = GrayscaleRenderOptions.FromDataset(dataset); int[] output = new int[pixelData.Width * pixelData.Height]; data.Render(new ModalityLUT(renderOptions), output); return(output); }
public byte[] ReadFrame(int frame) { DicomPixelData pd = _context.PixelData; if (pd is DicomCompressedPixelData) { byte[] buffer = (pd as DicomCompressedPixelData).GetFrameFragmentData(frame); return(buffer); } else { return(pd.GetFrame(frame)); } }
private void loadPixels() { // code found at https://groups.google.com/forum/#!topic/fo-dicom/EQtF5-7_PAU DicomPixelData pxd = DicomPixelData.Create(dicomFile.Dataset); IByteBuffer buffer = pxd.GetFrame(0); slicePixels = Dicom.IO.ByteConverter.ToArray <ushort>(buffer); //byte[] bSlicePixels = Dicom.IO.ByteConverter.ToArray<byte>(buffer); // alternative: //var header = DicomPixelData.Create(dicomFile.Dataset); //var pixelData = PixelDataFactory.Create(header, 0); //ushort[] pixels = ((GrayscalePixelDataU16)pixelData).Data; }
public Stream Convert(DicomAttributeCollection ds) { DicomAttributeCollection command = new DicomAttributeCollection(); command[DicomTags.TransferSyntaxUid] = ds[DicomTags.TransferSyntaxUid]; DicomMessage message = new DicomMessage(command, ds); DicomPixelData pd = DicomPixelData.CreateFrom(message); string tempFile = System.IO.Path.GetTempFileName( ); System.IO.File.WriteAllBytes(tempFile, pd.GetFrame(0)); return(new DICOMcloud.Core.Storage.TempStream(new TempFile(tempFile))); }
public static IByteBuffer ExtractSingleFrame(DicomDataset dataset, int frame) { DicomPixelData pixelData = DicomPixelData.Create(dataset); int frames = pixelData.NumberOfFrames; if (frame > frames) { return(null); } else { var frameData = pixelData.GetFrame(frame); return(frameData); } }
static public unsafe void GetAverageValue(this DicomDataset original, out double average, out double dispersion, out ushort min, out ushort max) { DicomPixelData pixelDataSource = DicomPixelData.Create(original, false); if (pixelDataSource.BytesAllocated != 2 || pixelDataSource.SamplesPerPixel != 1) { throw new Exception(); } IByteBuffer buffer = pixelDataSource.GetFrame(0); byte[] bytes = buffer.Data; int size = (int)buffer.Size; GetAverageValue(original, bytes, size, out average, out dispersion, out min, out max); }
internal static void Encode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomJpegLsParams parameters) { if (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull422 || oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial422 || oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial420) { throw new InvalidOperationException( "Photometric Interpretation '{oldPixelData.PhotometricInterpretation}' not supported by JPEG-LS encoder"); } var jparameters = new JlsParameters { width = oldPixelData.Width, height = oldPixelData.Height, bitsPerSample = oldPixelData.BitsStored, stride = oldPixelData.BytesAllocated * oldPixelData.Width * oldPixelData.SamplesPerPixel, components = oldPixelData.SamplesPerPixel, interleaveMode = oldPixelData.SamplesPerPixel == 1 ? InterleaveMode.None : oldPixelData.PlanarConfiguration == PlanarConfiguration.Interleaved ? InterleaveMode.Sample : InterleaveMode.Line, colorTransformation = ColorTransformation.None }; for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var frameData = oldPixelData.GetFrame(frame); // assume compressed frame will be smaller than original var jpegData = new byte[frameData.Size]; ulong jpegDataSize; string errorMessage; var err = JpegLs.Encode(jpegData, frameData.Data, jparameters, out jpegDataSize, out errorMessage); if (err != ApiResult.OK) { throw new InvalidOperationException(GetErrorMessage(err, errorMessage)); } Array.Resize(ref jpegData, (int)jpegDataSize + ((jpegDataSize & 1) == 1 ? 1 : 0)); newPixelData.AddFrame(new MemoryByteBuffer(jpegData)); } }
public GridBasedVoxelDataStructure Load(DicomFile[] dicomFiles) { GridBasedVoxelDataStructure grid = new GridBasedVoxelDataStructure(); DicomFile[] files = SortOnZIncreasing(dicomFiles); PixelDataInfo DicomHeader = new PixelDataInfo(files[0]); Point3d size = GetSize(files); grid.ConstantGridSpacing = true; grid.GridSpacing = GetSpacing(files); grid.XCoords = GetCoords(files, (int)size.X, DicomHeader.RowDir.X, DicomHeader.ColDir.X, DicomHeader.ImagePositionPatient.X, 1); grid.YCoords = GetCoords(files, (int)size.Y, DicomHeader.RowDir.Y, DicomHeader.ColDir.Y, DicomHeader.ImagePositionPatient.Y, 1); grid.ZCoords = GetCoords(files, (int)size.Z, DicomHeader.RowDir.Z, DicomHeader.ColDir.Z, DicomHeader.ImagePositionPatient.Z, 1); grid.Data = new float[(int)size.X / 1, (int)size.Y / 1, (int)size.Z / 1]; int currYIndex = 0; int currZIndex = 0; int currXIndex = 0; for (int i = 0; i < files.Length; i++) { DicomPixelData dicomPixelData = DicomPixelData.Create(files[i].Dataset); PixelDataInfo tempHeaderInfo = new PixelDataInfo(files[i]); for (int j = 0; j < tempHeaderInfo.GridFrameOffsetVector.Length; j++) { byte[] framePixelData = dicomPixelData.GetFrame(j).Data; float[] dataArray = GetDataArray(framePixelData, tempHeaderInfo.BitsAllocated, tempHeaderInfo.PixelRepresentation); for (int k = 0; k < dataArray.Length; k++) { int currRow = k % tempHeaderInfo.Columns; int currCol = (int)Math.Floor((double)(k / (tempHeaderInfo.Columns))); currXIndex = (int)Math.Abs(tempHeaderInfo.RowDir.X) * currRow + (int)Math.Abs(tempHeaderInfo.ColDir.X) * currCol + (1 - (int)Math.Abs(tempHeaderInfo.RowDir.X) - (int)Math.Abs(tempHeaderInfo.ColDir.X)) * (i + j);; currYIndex = (int)Math.Abs(tempHeaderInfo.RowDir.Y) * currRow + (int)Math.Abs(tempHeaderInfo.ColDir.Y) * currCol + (1 - (int)Math.Abs(tempHeaderInfo.RowDir.Y) - (int)Math.Abs(tempHeaderInfo.ColDir.Y)) * (i + j);; currZIndex = (int)Math.Abs(tempHeaderInfo.RowDir.Z) * currRow + (int)Math.Abs(tempHeaderInfo.ColDir.Z) * currCol + (1 - (int)Math.Abs(tempHeaderInfo.RowDir.Z) - (int)Math.Abs(tempHeaderInfo.ColDir.Z)) * (i + j); //Rescale back to actual values dataArray[k] = dataArray[k] * tempHeaderInfo.RescaleSlope + tempHeaderInfo.RescaleSlope; grid.Data[currXIndex, currYIndex, currZIndex] = dataArray[k]; } } } return(grid); //setGlobalMax(); }
/// <summary> /// The JPEG-LS decoding function /// </summary> /// <param name="oldPixelData">The old pixel data</param> /// <param name="newPixelData">The new pixel data</param> /// <param name="parameters">The compression parameters</param> public override void Decode(DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var jpegLsData = oldPixelData.GetFrame(frame); var message = String.Empty; var jpegLsParams = new JlsParameters(); var frameData = new byte[newPixelData.UncompressedFrameSize]; var err = JpegLs.Decode(frameData, jpegLsData.Data, jpegLsParams, out message); var buffer = frameData.Length >= 1 * 1024 * 1024 || oldPixelData.NumberOfFrames > 1 ? (IByteBuffer) new TempFileBuffer(frameData) : new MemoryByteBuffer(frameData); newPixelData.AddFrame(EvenLengthBuffer.Create(buffer)); } }
public SliceBasedVoxelDataStructure Load(DicomFile[] files) { SliceBasedVoxelDataStructure grid = new SliceBasedVoxelDataStructure(); files = sort(files); PixelDataInfo[] headerInfos = GetHeaderInfo(files); if (files.Length > 1) { grid.MatrixA = getMatrixA(files.First(), files.Last(), files.Length); } else { grid.MatrixA = getSingleMatrixA(files[0]); } for (int i = 0; i < files.Length; i++) { PixelDataInfo headerInfo = headerInfos[i]; DicomPixelData dicomPixelData = DicomPixelData.Create(files[i].Dataset); for (int j = 0; j < headerInfo.GridFrameOffsetVector.Length; j++) { byte[] framePixelData = dicomPixelData.GetFrame(j).Data; float[] dataArray = GetDataArray(framePixelData, dicomPixelData.BitsAllocated, headerInfo.PixelRepresentation); //rescale to proper values for (int k = 0; k < dataArray.Length; k++) { dataArray[k] = dataArray[k] * headerInfo.RescaleSlope + headerInfo.RescaleIntercept; } grid.AddSlice(dataArray, headerInfo.Rows, headerInfo.Columns, headerInfo.PixelSpacing[0], headerInfo.PixelSpacing[1], headerInfo.ImagePositionPatient.X, headerInfo.ImagePositionPatient.Y, headerInfo.ImagePositionPatient.Z + headerInfo.GridFrameOffsetVector[j], headerInfo.RowDir.X, headerInfo.RowDir.Y, headerInfo.RowDir.Z, headerInfo.ColDir.X, headerInfo.ColDir.Y, headerInfo.ColDir.Z); } files[i] = null; } //grid.Window = (int)grid.GlobalMax.Value ; //grid.Level = (int)(grid.GlobalMax.Value / 2); return(grid); }
public static IPixelData Create(DicomPixelData pixelData, int frame) { PhotometricInterpretation pi = pixelData.PhotometricInterpretation; if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2 || pi == PhotometricInterpretation.PaletteColor) { if (pixelData.BitsStored <= 8) { return(new GrayscalePixelDataU8(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame))); } else if (pixelData.BitsStored <= 16) { if (pixelData.PixelRepresentation == PixelRepresentation.Signed) { return(new GrayscalePixelDataS16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame))); } else { return(new GrayscalePixelDataU16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame))); } } else { throw new DicomImagingException("Unsupported pixel data value for bits stored: {0}", pixelData.BitsStored); } } else if (pi == PhotometricInterpretation.Rgb || pi == PhotometricInterpretation.YbrFull) { var buffer = pixelData.GetFrame(frame); if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar) { buffer = PixelDataConverter.PlanarToInterleaved24(buffer); } return(new ColorPixelData24(pixelData.Width, pixelData.Height, buffer)); } else { throw new DicomImagingException("Unsupported pixel data photometric interpretation: {0}", pi.Value); } }
/// <summary> /// Create <see cref="IPixelData"/> form <see cref="DicomPixelData"/> /// according to the input <paramref name="pixelData"/> <seealso cref="PhotometricInterpretation"/> /// </summary> /// <param name="pixelData">Input pixel data</param> /// <param name="frame">Frame number (0 based)</param> /// <returns>Implementation of <seealso cref="IPixelData"/> according to <seealso cref="PhotometricInterpretation"/></returns> public static IPixelData Create(DicomPixelData pixelData, int frame) { PhotometricInterpretation pi = pixelData.PhotometricInterpretation; if (pi == null) { // generally ACR-NEMA var samples = pixelData.SamplesPerPixel; if (samples == 0 || samples == 1) { pi = pixelData.Dataset.Contains(DicomTag.RedPaletteColorLookupTableData) ? PhotometricInterpretation.PaletteColor : PhotometricInterpretation.Monochrome2; } else { // assume, probably incorrectly, that the image is RGB pi = PhotometricInterpretation.Rgb; } } if (pixelData.BitsStored == 1) { if (pixelData.Dataset.GetSingleValue<DicomUID>(DicomTag.SOPClassUID) == DicomUID.MultiFrameSingleBitSecondaryCaptureImageStorage) // Multi-frame Single Bit Secondary Capture is stored LSB -> MSB return new SingleBitPixelData( pixelData.Width, pixelData.Height, PixelDataConverter.ReverseBits(pixelData.GetFrame(frame))); else // Need sample images to verify that this is correct return new SingleBitPixelData(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame)); } else if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2 || pi == PhotometricInterpretation.PaletteColor) { if (pixelData.BitsAllocated == 8 && pixelData.HighBit == 7 && pixelData.BitsStored == 8) return new GrayscalePixelDataU8(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame)); else if (pixelData.BitsAllocated <= 16) { if (pixelData.PixelRepresentation == PixelRepresentation.Signed) return new GrayscalePixelDataS16( pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); else return new GrayscalePixelDataU16( pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); } else if (pixelData.BitsAllocated <= 32) { if (pixelData.PixelRepresentation == PixelRepresentation.Signed) return new GrayscalePixelDataS32( pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); else return new GrayscalePixelDataU32( pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); } else throw new DicomImagingException( "Unsupported pixel data value for bits stored: {0}", pixelData.BitsStored); } else if (pi == PhotometricInterpretation.Rgb || pi == PhotometricInterpretation.YbrFull || pi == PhotometricInterpretation.YbrFull422 || pi == PhotometricInterpretation.YbrPartial422) { var buffer = pixelData.GetFrame(frame); if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar) buffer = PixelDataConverter.PlanarToInterleaved24(buffer); if (pi == PhotometricInterpretation.YbrFull) buffer = PixelDataConverter.YbrFullToRgb(buffer); else if (pi == PhotometricInterpretation.YbrFull422) buffer = PixelDataConverter.YbrFull422ToRgb(buffer, pixelData.Width); else if (pi == PhotometricInterpretation.YbrPartial422) buffer = PixelDataConverter.YbrPartial422ToRgb(buffer, pixelData.Width); return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer); } else if (pi == PhotometricInterpretation.YbrFull422) { var buffer = pixelData.GetFrame(frame); if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar) throw new DicomImagingException("Unsupported planar configuration for YBR_FULL_422"); return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer); } else { throw new DicomImagingException( "Unsupported pixel data photometric interpretation: {0}", pi.Value); } }
public static bool Compare(DicomPixelData pixels1, DicomPixelData pixels2, out string failureDescription) { failureDescription = string.Empty; if (pixels1.BitsAllocated != pixels2.BitsAllocated) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Bits Allocated varies: {0} , {1}", pixels1.BitsAllocated, pixels2.BitsAllocated); return false; } if (pixels1.BitsStored != pixels2.BitsStored) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Bits Stored varies: {0} , {1}", pixels1.BitsStored, pixels2.BitsStored); return false; } if (pixels1.ImageHeight != pixels2.ImageHeight) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Rows varies: {0} , {1}", pixels1.ImageHeight, pixels2.ImageHeight); return false; } if (pixels1.ImageWidth != pixels2.ImageWidth) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Columns varies: {0} , {1}", pixels1.ImageWidth, pixels2.ImageWidth); return false; } if (pixels1.SamplesPerPixel != pixels2.SamplesPerPixel) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Samples per pixel varies: {0} , {1}", pixels1.SamplesPerPixel, pixels2.SamplesPerPixel); return false; } if (pixels1.NumberOfFrames != pixels2.NumberOfFrames) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Number of frames varies: {0} , {1}", pixels1.NumberOfFrames, pixels2.NumberOfFrames); return false; } long pixelsVarying = 0; long totalVariation = 0; int pixels = pixels1.ImageHeight * pixels1.ImageWidth * pixels1.SamplesPerPixel; if (pixels1.BitsAllocated == 8) { for (int frame = 0; frame < pixels1.NumberOfFrames; frame++) { byte[] pixel1 = pixels1.GetFrame(frame); byte[] pixel2 = pixels2.GetFrame(frame); if (pixels1.HighBit != pixels2.HighBit) { // Justify the pixel, if needed if (DicomUncompressedPixelData.RightAlign(pixel1, pixels1.BitsAllocated, pixels1.BitsStored, pixels1.HighBit)) { //pixels1.HighBit = (ushort)(pixels1.BitsStored - 1); DicomUncompressedPixelData.ZeroUnusedBits(pixel1, pixels1.BitsAllocated, pixels1.BitsStored, pixels1.BitsStored - 1); } if (DicomUncompressedPixelData.RightAlign(pixel2, pixels2.BitsAllocated, pixels2.BitsStored, pixels2.HighBit)) { //pixels2.HighBit = (ushort)(pixels2.BitsStored - 1); DicomUncompressedPixelData.ZeroUnusedBits(pixel2, pixels2.BitsAllocated, pixels2.BitsStored, pixels2.BitsStored - 1); } } int[] intPixels1 = pixels1.IsSigned ? Convert8BitSigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1) : Convert8BitUnsigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1); int[] intPixels2 = pixels2.IsSigned ? Convert8BitSigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2) : Convert8BitUnsigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2); for (int i = 0; i < pixels; i++) if (intPixels1[i] != intPixels2[i]) { pixelsVarying++; totalVariation += Math.Abs(intPixels1[i] - intPixels2[i]); } } if (pixelsVarying > 0) { failureDescription = String.Format( "Tag (7fe0,0010) Pixel Data: {0} of {1} pixels varying, average difference: {2}", pixelsVarying, pixels * pixels1.NumberOfFrames, totalVariation / pixelsVarying); return false; } } else { for (int frame = 0; frame < pixels1.NumberOfFrames; frame++) { byte[] pixel1 = pixels1.GetFrame(frame); byte[] pixel2 = pixels2.GetFrame(frame); if (pixels1.HighBit != pixels2.HighBit) { // Justify the pixel, if needed if (DicomUncompressedPixelData.RightAlign(pixel1, pixels1.BitsAllocated, pixels1.BitsStored, pixels1.HighBit)) { //pixels1.HighBit = (ushort) (pixels1.BitsStored - 1); DicomUncompressedPixelData.ZeroUnusedBits(pixel1, pixels1.BitsAllocated, pixels1.BitsStored, pixels1.BitsStored - 1); } if (DicomUncompressedPixelData.RightAlign(pixel2, pixels2.BitsAllocated, pixels2.BitsStored, pixels2.HighBit)) { //pixels2.HighBit = (ushort)(pixels2.BitsStored - 1); DicomUncompressedPixelData.ZeroUnusedBits(pixel2, pixels2.BitsAllocated, pixels2.BitsStored, pixels2.BitsStored - 1); } } int[] intPixels1 = pixels1.IsSigned ? Convert16BitSigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1) : Convert16BitUnsigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1); int[] intPixels2 = pixels2.IsSigned ? Convert16BitSigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2) : Convert16BitUnsigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2); for (int i = 0; i < pixels; i++) if (intPixels1[i] != intPixels2[i]) { pixelsVarying++; totalVariation += Math.Abs(intPixels1[i] - intPixels2[i]); } } if (pixelsVarying > 0) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: {0} of {1} pixels varying, average difference: {2}", pixelsVarying, pixels, totalVariation / pixelsVarying); return false; } } return true; }
public static IPixelData Create(DicomPixelData pixelData, int frame) { PhotometricInterpretation pi = pixelData.PhotometricInterpretation; if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2 || pi == PhotometricInterpretation.PaletteColor) { if (pixelData.BitsStored <= 8) return new GrayscalePixelDataU8(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame)); else if (pixelData.BitsStored <= 16) { if (pixelData.PixelRepresentation == PixelRepresentation.Signed) return new GrayscalePixelDataS16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); else return new GrayscalePixelDataU16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)); } else throw new DicomImagingException("Unsupported pixel data value for bits stored: {0}", pixelData.BitsStored); } else if (pi == PhotometricInterpretation.Rgb || pi == PhotometricInterpretation.YbrFull) { var buffer = pixelData.GetFrame(frame); if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar) buffer = PixelDataConverter.PlanarToInterleaved24(buffer); return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer); } else { throw new DicomImagingException("Unsupported pixel data photometric interpretation: {0}", pi.Value); } }
public static bool Compare(DicomPixelData pixels1, DicomPixelData pixels2, out string failureDescription) { failureDescription = string.Empty; if (pixels1.BitsAllocated != pixels2.BitsAllocated) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Bits Allocated varies: {0} , {1}", pixels1.BitsAllocated, pixels2.BitsAllocated); return(false); } if (pixels1.BitsStored != pixels2.BitsStored) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Bits Stored varies: {0} , {1}", pixels1.BitsStored, pixels2.BitsStored); return(false); } if (pixels1.ImageHeight != pixels2.ImageHeight) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Rows varies: {0} , {1}", pixels1.ImageHeight, pixels2.ImageHeight); return(false); } if (pixels1.ImageWidth != pixels2.ImageWidth) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Columns varies: {0} , {1}", pixels1.ImageWidth, pixels2.ImageWidth); return(false); } if (pixels1.SamplesPerPixel != pixels2.SamplesPerPixel) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Samples per pixel varies: {0} , {1}", pixels1.SamplesPerPixel, pixels2.SamplesPerPixel); return(false); } if (pixels1.NumberOfFrames != pixels2.NumberOfFrames) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Number of frames varies: {0} , {1}", pixels1.NumberOfFrames, pixels2.NumberOfFrames); return(false); } long pixelsVarying = 0; long totalVariation = 0; int pixels = pixels1.ImageHeight * pixels1.ImageWidth * pixels1.SamplesPerPixel; if (pixels1.BitsAllocated == 8) { for (int frame = 0; frame < pixels1.NumberOfFrames; frame++) { byte[] pixel1 = pixels1.GetFrame(frame); byte[] pixel2 = pixels2.GetFrame(frame); if (pixels1.HighBit != pixels2.HighBit) { // Justify the pixel, if needed if (DicomUncompressedPixelData.RightAlign(pixel1, pixels1.BitsAllocated, pixels1.BitsStored, pixels1.HighBit)) { //pixels1.HighBit = (ushort)(pixels1.BitsStored - 1); DicomUncompressedPixelData.ZeroUnusedBits(pixel1, pixels1.BitsAllocated, pixels1.BitsStored, pixels1.BitsStored - 1); } if (DicomUncompressedPixelData.RightAlign(pixel2, pixels2.BitsAllocated, pixels2.BitsStored, pixels2.HighBit)) { //pixels2.HighBit = (ushort)(pixels2.BitsStored - 1); DicomUncompressedPixelData.ZeroUnusedBits(pixel2, pixels2.BitsAllocated, pixels2.BitsStored, pixels2.BitsStored - 1); } } int[] intPixels1 = pixels1.IsSigned ? Convert8BitSigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1) : Convert8BitUnsigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1); int[] intPixels2 = pixels2.IsSigned ? Convert8BitSigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2) : Convert8BitUnsigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2); for (int i = 0; i < pixels; i++) { if (intPixels1[i] != intPixels2[i]) { pixelsVarying++; totalVariation += Math.Abs(intPixels1[i] - intPixels2[i]); } } } if (pixelsVarying > 0) { failureDescription = String.Format( "Tag (7fe0,0010) Pixel Data: {0} of {1} pixels varying, average difference: {2}", pixelsVarying, pixels * pixels1.NumberOfFrames, totalVariation / pixelsVarying); return(false); } } else { for (int frame = 0; frame < pixels1.NumberOfFrames; frame++) { byte[] pixel1 = pixels1.GetFrame(frame); byte[] pixel2 = pixels2.GetFrame(frame); if (pixels1.HighBit != pixels2.HighBit) { // Justify the pixel, if needed if (DicomUncompressedPixelData.RightAlign(pixel1, pixels1.BitsAllocated, pixels1.BitsStored, pixels1.HighBit)) { //pixels1.HighBit = (ushort) (pixels1.BitsStored - 1); DicomUncompressedPixelData.ZeroUnusedBits(pixel1, pixels1.BitsAllocated, pixels1.BitsStored, pixels1.BitsStored - 1); } if (DicomUncompressedPixelData.RightAlign(pixel2, pixels2.BitsAllocated, pixels2.BitsStored, pixels2.HighBit)) { //pixels2.HighBit = (ushort)(pixels2.BitsStored - 1); DicomUncompressedPixelData.ZeroUnusedBits(pixel2, pixels2.BitsAllocated, pixels2.BitsStored, pixels2.BitsStored - 1); } } int[] intPixels1 = pixels1.IsSigned ? Convert16BitSigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1) : Convert16BitUnsigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1); int[] intPixels2 = pixels2.IsSigned ? Convert16BitSigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2) : Convert16BitUnsigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2); for (int i = 0; i < pixels; i++) { if (intPixels1[i] != intPixels2[i]) { pixelsVarying++; totalVariation += Math.Abs(intPixels1[i] - intPixels2[i]); } } } if (pixelsVarying > 0) { failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: {0} of {1} pixels varying, average difference: {2}", pixelsVarying, pixels, totalVariation / pixelsVarying); return(false); } } return(true); }
internal static void Decode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomJpegParams parameters) { var pixelCount = oldPixelData.Height * oldPixelData.Width; if (parameters.ConvertColorspaceToRGB) { if (oldPixelData.PixelRepresentation == PixelRepresentation.Signed) { throw new DicomCodecException( "JPEG codec unable to perform colorspace conversion on signed pixel data"); } newPixelData.PhotometricInterpretation = PhotometricInterpretation.Rgb; newPixelData.PlanarConfiguration = PlanarConfiguration.Interleaved; } for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var jpegData = oldPixelData.GetFrame(frame); // Destination frame should be of even length var frameSize = newPixelData.UncompressedFrameSize; if ((frameSize & 1) == 1) { ++frameSize; } var destArray = new byte[frameSize]; using (var stream = new MemoryStream(jpegData.Data)) { var decoder = new JpegImage(stream); var w = decoder.Width; var h = decoder.Height; for (var c = 0; c < decoder.ComponentsPerSample; c++) { var pos = newPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? c * pixelCount : c; var offset = newPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? 1 : decoder.ComponentsPerSample; if (newPixelData.BytesAllocated == 1) { for (var y = 0; y < h; ++y) { var row = decoder.GetRow(y); for (var x = 0; x < w; ++x) { destArray[pos] = (byte)row[x][c]; pos += offset; } } } #if SUPPORT16BIT else if (newPixelData.BytesAllocated == 2) { var destArray16 = new short[frameSize >> 1]; for (var y = 0; y < h; ++y) { var row = decoder.GetRow(y); for (var x = 0; x < w; ++x) { destArray16[pos] = row[x][c]; pos += offset; } } Buffer.BlockCopy(destArray16, 0, destArray, 0, frameSize); } #endif else { throw new InvalidOperationException( $"JPEG module does not support Bits Allocated == {newPixelData.BitsAllocated}!"); } } newPixelData.AddFrame(new MemoryByteBuffer(destArray)); } } }