public void ChangeSyntax(TransferSyntax syntax) { try { if (!_dicomFile.TransferSyntax.Encapsulated) { // Check if Overlay is embedded in pixels OverlayPlaneModuleIod overlayIod = new OverlayPlaneModuleIod(_dicomFile.DataSet); for (int i = 0; i < 16; i++) { if (overlayIod.HasOverlayPlane(i)) { OverlayPlane overlay = overlayIod[i]; if (overlay.OverlayData == null) { DicomUncompressedPixelData pd = new DicomUncompressedPixelData(_dicomFile); overlay.ConvertEmbeddedOverlay(pd); } } } } else if (syntax.Encapsulated) { // Must decompress first. _dicomFile.ChangeTransferSyntax(TransferSyntax.ExplicitVrLittleEndian); } _dicomFile.ChangeTransferSyntax(syntax); } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception compressing/decompressing DICOM file"); } }
public void DecodeFrame(int frame, DicomCompressedPixelData oldPixelData, DicomUncompressedPixelData newPixelData, DicomCodecParameters parameters) { DicomRleCodecParameters rleParams = parameters as DicomRleCodecParameters ?? new DicomRleCodecParameters(); int pixelCount = oldPixelData.ImageWidth * oldPixelData.ImageHeight; int numberOfSegments = oldPixelData.BytesAllocated * oldPixelData.SamplesPerPixel; int segmentLength = (pixelCount & 1) == 1 ? pixelCount + 1 : pixelCount; byte[] segment = new byte[segmentLength]; byte[] frameData = new byte[oldPixelData.UncompressedFrameSize]; IList <DicomFragment> rleData = oldPixelData.GetFrameFragments(frame); RLEDecoder decoder = new RLEDecoder(rleData); if (decoder.NumberOfSegments != numberOfSegments) { throw new DicomCodecException("Unexpected number of RLE segments!"); } for (int s = 0; s < numberOfSegments; s++) { decoder.DecodeSegment(s, segment); int sample = s / oldPixelData.BytesAllocated; int sabyte = s % oldPixelData.BytesAllocated; int pos; int offset; if (newPixelData.PlanarConfiguration == 0) { pos = sample * oldPixelData.BytesAllocated; offset = oldPixelData.SamplesPerPixel * oldPixelData.BytesAllocated; } else { pos = sample * oldPixelData.BytesAllocated * pixelCount; offset = oldPixelData.BytesAllocated; } if (rleParams.ReverseByteOrder) { pos += sabyte; } else { pos += oldPixelData.BytesAllocated - sabyte - 1; } for (int p = 0; p < pixelCount; p++) { frameData[pos] = segment[p]; pos += offset; } } newPixelData.AppendFrame(frameData); }
public void TestRightAlign_BitsStored16_NoOp() { var testValues = new ushort[] { 65535, 32767 }; var expectedValues = (ushort[])testValues.Clone(); Assert.IsFalse(DicomUncompressedPixelData.RightAlign(expectedValues, 16, 15)); Assert.AreEqual(testValues, expectedValues); }
public void TestZeroUnusedBits_BitsStored16_NoOp() { var testValues = new ushort[] { 65535, 32767 }; var expectedValues = (ushort[])testValues.Clone(); Assert.IsFalse(DicomUncompressedPixelData.ZeroUnusedBits(expectedValues, 16, 15)); Assert.AreEqual(expectedValues, testValues); }
public void TestZeroUnusedBits_BitsStored8_NoOp() { var testValues = new byte[] { 128, 255 }; var expectedValues = (byte[])testValues.Clone(); Assert.IsFalse(DicomUncompressedPixelData.ZeroUnusedBits(expectedValues, 8, 7)); Assert.AreEqual(expectedValues, testValues); }
protected static void CreatePixelData(DicomAttributeCollection dataSet) { dataSet[DicomTags.PixelData] = null; var pd = new DicomUncompressedPixelData(dataSet); CreatePixelData(pd); pd.UpdateAttributeCollection(dataSet); }
public void DecodeFrame(int frame, DicomCompressedPixelData oldPixelData, DicomUncompressedPixelData newPixelData, DicomCodecParameters parameters) { using (var input = new MemoryStream(oldPixelData.GetFrameFragmentData(frame))) using (var gzipStream = new GZipStream(input, CompressionMode.Decompress, false)) { var data = new byte[oldPixelData.UncompressedFrameSize]; gzipStream.Read(data, 0, data.Length); newPixelData.AppendFrame(data); } }
public void DecodeFrame(int frame, DicomCompressedPixelData oldPixelData, DicomUncompressedPixelData newPixelData, DicomCodecParameters parameters) { using (var input = new MemoryStream(oldPixelData.GetFrameFragmentData(frame))) using (var gzipStream = new GZipStream(input, CompressionMode.Decompress, false)) { var data = new byte[oldPixelData.UncompressedFrameSize]; gzipStream.Read(data, 0, data.Length); newPixelData.AppendFrame(data); } }
public void TestRightAlign_BitsStored7_NoOp() { // 64, 127 // 0\1000000, 0\1111111 var testValues = new byte[] { 64, 127 }; var expectedValues = (byte[])testValues.Clone(); Assert.IsFalse(DicomUncompressedPixelData.RightAlign(testValues, 7, 6)); Assert.AreEqual(expectedValues, testValues); }
public void TestRightAlign_BitsStored15_NoOp() { // Actual: 32767, 21845, 10922 (with extra bit at left=43690) // Test: 0\111111111111111, 0\101010101010101, 1\010101010101010 // Expected: 32767, 21845, 10922 var testValues = new ushort[] { 32767, 21845, 43690 }; var expectedValues = new ushort[] { 32767, 21845, 10922 }; Assert.IsTrue(DicomUncompressedPixelData.ZeroUnusedBits(testValues, 15, 14)); Assert.IsFalse(DicomUncompressedPixelData.RightAlign(testValues, 16, 15)); Assert.AreEqual(expectedValues, testValues); }
public void TestZeroUnusedBits_BitsStored10_HighBit12() { // Actual: 1023, 1023, 1023, 1023, 341, 682 (all with varying extra bits at both ends) // Test: 111\1111111111\111, 010\1111111111\101, 101\1111111111\010, 000\1111111111\000, 111\0101010101\111, 010\1010101010\101 // Expected: 8184, 8184, 8184, 8184, 2728, 5456 var testValues = new ushort[] { 65535, 24573, 49146, 8184, 60079, 21845 }; var expectedValues = new ushort[] { 8184, 8184, 8184, 8184, 2728, 5456 }; Assert.IsTrue(DicomUncompressedPixelData.ZeroUnusedBits(testValues, 10, 12)); Assert.AreEqual(expectedValues, testValues); Assert.IsFalse(DicomUncompressedPixelData.ZeroUnusedBits(testValues, 10, 12)); }
/// <summary> /// Called by the base class to create a new byte buffer containing normalized pixel data /// for this frame (8 or 16-bit grayscale, or 32-bit ARGB). /// </summary> /// <returns>A new byte buffer containing the normalized pixel data.</returns> protected override byte[] CreateNormalizedPixelData() { DicomMessageBase message = this.Parent.SourceMessage; CodeClock clock = new CodeClock(); clock.Start(); PhotometricInterpretation photometricInterpretation; byte[] rawPixelData = null; if (!message.TransferSyntax.Encapsulated) { DicomUncompressedPixelData pixelData = new DicomUncompressedPixelData(message); // DICOM library uses zero-based frame numbers MemoryManager.Execute(delegate { rawPixelData = pixelData.GetFrame(_frameIndex); }); ExtractOverlayFrames(rawPixelData, pixelData.BitsAllocated); photometricInterpretation = PhotometricInterpretation.FromCodeString(message.DataSet[DicomTags.PhotometricInterpretation]); } else if (DicomCodecRegistry.GetCodec(message.TransferSyntax) != null) { DicomCompressedPixelData pixelData = new DicomCompressedPixelData(message); string pi = null; MemoryManager.Execute(delegate { rawPixelData = pixelData.GetFrame(_frameIndex, out pi); }); photometricInterpretation = PhotometricInterpretation.FromCodeString(pi); } else { throw new DicomCodecException("Unsupported transfer syntax"); } if (photometricInterpretation.IsColor) { rawPixelData = ToArgb(message.DataSet, rawPixelData, photometricInterpretation); } else { NormalizeGrayscalePixels(message.DataSet, rawPixelData); } clock.Stop(); PerformanceReportBroker.PublishReport("DicomMessageSopDataSource", "CreateFrameNormalizedPixelData", clock.Seconds); return(rawPixelData); }
public void TestZeroUnusedBits_BitsStored7() { // Actual: 64, 127, 127 (with extra bit at left=255) // Test: 0\1000000, 0\1111111, 1\1111111 // Expected: 64, 127, 127 var testValues = new byte[] { 64, 127, 255 }; var expectedValues = new byte[] { 64, 127, 127 }; Assert.IsTrue(DicomUncompressedPixelData.ZeroUnusedBits(testValues, 7, 6)); Assert.AreEqual(expectedValues, testValues); //Won't have zeroed anything. Assert.IsFalse(DicomUncompressedPixelData.ZeroUnusedBits(testValues, 7, 6)); }
public void TestZeroUnusedBits_BitsStored4_HighBit5() { // Actual: 15, [15, 15, 15, 10, 5, 3] (all with varying extra bits at both ends) // Test: 00\1111\00, 11\1111\11, 01\1111\10, 10\1111\01, 10\1010\10, 01\0101\01, 11\0011\00 // Expected: 60, 60, 60, 60, 40, 20, 12 (actual, but not right-aligned) var testValues = new byte[] { 60, 255, 126, 189, 170, 85, 204 }; var expectedValues = new byte[] { 60, 60, 60, 60, 40, 20, 12 }; Assert.IsTrue(DicomUncompressedPixelData.ZeroUnusedBits(testValues, 4, 5)); Assert.AreEqual(expectedValues, testValues); //Won't have zeroed anything. Assert.IsFalse(DicomUncompressedPixelData.ZeroUnusedBits(testValues, 4, 5)); }
public void TestAdvanced_FileOnDisk_16Bits_OW() { var filename = Path.GetTempFileName(); CreateDicomImage(rows: 20, columns: 30, numberOfFrames: 5).Save(filename); var dcf = new DicomFile(filename); dcf.Load(DicomReadOptions.StorePixelDataReferences); try { var pd = new DicomUncompressedPixelData(dcf); Assert.AreEqual(16, pd.BitsAllocated, "BitsAllocated"); Assert.AreEqual(16, pd.BitsStored, "BitsStored"); Assert.AreEqual(15, pd.HighBit, "HighBit"); Assert.AreEqual(20, pd.ImageHeight, "ImageHeight"); Assert.AreEqual(30, pd.ImageWidth, "ImageWidth"); Assert.AreEqual(5, pd.NumberOfFrames, "NumberOfFrames"); Assert.AreEqual("MONOCHROME2", pd.PhotometricInterpretation, "PhotometricInterpretation"); Assert.AreEqual(0, pd.PixelRepresentation, "PixelRepresentation"); Assert.AreEqual(1, pd.SamplesPerPixel, "SamplesPerPixel"); Assert.AreEqual(20 * 30 * 2, pd.UncompressedFrameSize, "UncompressedFrameSize"); var newFrameData = new byte[pd.UncompressedFrameSize]; for (var n = 0; n < newFrameData.Length; ++n) { newFrameData[n] = 0x7F; } pd.SetFrame(1, newFrameData); pd.UpdateAttributeCollection(dcf.DataSet); var pixelData = dcf.DataSet[DicomTags.PixelData].Values as byte[]; for (var frame = 0; frame < 5; ++frame) { var fd = pd.GetFrame(frame); var expectedValue = frame == 1 ? (byte)0x7F : (byte)(0x80 + frame); Assert.AreEqual(pd.UncompressedFrameSize, fd.Length, "PixelData(frame={0}).Length", frame); AssertBytesEqual(expectedValue, fd, "PixelData(frame={0})", frame); AssertBytesEqual(expectedValue, pixelData, frame * pd.UncompressedFrameSize, pd.UncompressedFrameSize, "AttributeValues(frame={0})", frame); } } finally { File.Delete(filename); } }
public void DecodeFrame(int frame, DicomCompressedPixelData oldPixelData, DicomUncompressedPixelData newPixelData, DicomCodecParameters parameters) { if (oldPixelData.UncompressedFrameSize % 2 == 1) { using (var stream = new MemoryStream(oldPixelData.GetFrameFragmentData(frame))) { var data = new byte[oldPixelData.UncompressedFrameSize]; stream.Read(data, 0, data.Length); newPixelData.AppendFrame(data); } } else { newPixelData.AppendFrame(oldPixelData.GetFrameFragmentData(frame)); } }
public static int[] Convert16BitSigned(byte[] byteInputData, int pixels, DicomUncompressedPixelData pd) { int shiftBits = 32 - pd.BitsStored; int[] intPixels = new int[pixels]; for (int byteArrayCount = 0, pixelCount = 0; byteArrayCount < byteInputData.Length; byteArrayCount += 2, pixelCount++) { intPixels[pixelCount] = BitConverter.ToInt16(byteInputData, byteArrayCount); intPixels[pixelCount] = (intPixels[pixelCount] << shiftBits) >> shiftBits; } return(intPixels); }
public void SetupMRWithOverlay(DicomAttributeCollection theSet) { SetupMR(theSet); OverlayPlaneModuleIod overlayIod = new OverlayPlaneModuleIod(theSet); DicomUncompressedPixelData pd = new DicomUncompressedPixelData(theSet); OverlayPlane overlay = overlayIod[0]; // Embedded overlays are retired in dicom, just doing it for testing purposes theSet[DicomTags.OverlayBitPosition].SetInt32(0, pd.HighBit + 1); overlay.OverlayBitsAllocated = 1; overlay.OverlayColumns = pd.ImageWidth; overlay.OverlayRows = pd.ImageHeight; overlay.OverlayOrigin = new Point(0, 0); overlay.OverlayType = OverlayType.R; }
public void DecodeFrame(int frame, DicomCompressedPixelData oldPixelData, DicomUncompressedPixelData newPixelData, DicomCodecParameters parameters) { if (oldPixelData.UncompressedFrameSize%2 == 1) { using (var stream = new MemoryStream(oldPixelData.GetFrameFragmentData(frame))) { var data = new byte[oldPixelData.UncompressedFrameSize]; stream.Read(data, 0, data.Length); newPixelData.AppendFrame(data); } } else { newPixelData.AppendFrame(oldPixelData.GetFrameFragmentData(frame)); } }
public void SetupMRWithOverlay(DicomAttributeCollection theSet) { SetupMR(theSet); OverlayPlaneModuleIod overlayIod = new OverlayPlaneModuleIod(theSet); DicomUncompressedPixelData pd = new DicomUncompressedPixelData(theSet); OverlayPlane overlay = overlayIod[0]; // Embedded overlays are retired in dicom, just doing it for testing purposes theSet[DicomTags.OverlayBitPosition].SetInt32(0, pd.HighBit + 1); overlay.OverlayBitsAllocated = 1; overlay.OverlayColumns = pd.ImageWidth; overlay.OverlayRows = pd.ImageHeight; overlay.OverlayOrigin = new Point(0, 0); overlay.OverlayType = OverlayType.R; }
public void TestZeroUnusedBits_BitsStored10_HighBit12_AsBytes() { // Actual: 1023, 1023, 1023, 1023, 341, 682 (all with varying extra bits at both ends) // Test: 111\1111111111\111, 010\1111111111\101, 101\1111111111\010, 000\1111111111\000, 111\0101010101\111, 010\1010101010\101 // Expected: 8184, 8184, 8184, 8184, 2728, 5456 var testValues = new ushort[] { 65535, 24573, 49146, 8184, 60079, 21845 }; var expectedValues = new ushort[] { 8184, 8184, 8184, 8184, 2728, 5456 }; var testValuesBytes = ByteConverter.ToByteArray(testValues); //to bytes Assert.IsTrue(DicomUncompressedPixelData.ZeroUnusedBits(testValuesBytes, 16, 10, 12)); testValues = ByteConverter.ToUInt16Array(testValuesBytes); //back to ushorts Assert.AreEqual(expectedValues, testValues); }
// TODO (CR May 2011): Doesn't feel 100% like this method belongs here, // but it doesn't quite fit into DicomPixelData either, which is probably where it should go. /// <summary> /// Extracts all overlays embedded in pixel data and populates the <see cref="DicomTags.OverlayData"/> attribute. /// </summary> /// <returns>True if any overlays were actually extracted, otherwise false.</returns> /// <remarks>Certain restrictions apply to the use of this method: /// <list type="bullet"> /// <item><see cref="IodBase.DicomElementProvider"/> must be a <see cref="DicomDataset"/>.</item> /// <item>The <see cref="DicomTags.PixelData"/> attribute must not contain encapsulated pixel data. /// Check the <see cref="TransferSyntax"/> of the source message before calling this method.</item> /// </list> /// </remarks> public bool ExtractEmbeddedOverlays() { var collection = base.DicomElementProvider as DicomDataset; if (collection == null) { throw new ArgumentException("Module must wrap a DicomDataset in order to extract overlays."); } DicomElement element; if (!DicomElementProvider.TryGetAttribute(DicomTags.PixelData, out element)) { LogAdapter.Logger.Warn("Sop does not appear to have any pixel data from which to extract embedded overlays."); return(false); } if (element is DicomFragmentSequence) { LogAdapter.Logger.Warn("Sop pixel data must be uncompressed to extract overlays."); return(false); } if (element.IsNull) { LogAdapter.Logger.Warn("Sop pixel data has no valid value and cannot have embedded overlays extracted."); return(false); } var pixelData = new DicomUncompressedPixelData(collection); bool anyExtracted = false; // Check if Overlay is embedded in pixels foreach (var overlay in this) { if (overlay.HasOverlayData) { continue; } LogAdapter.Logger.Warn("SOP Instance has embedded overlay in pixel data, extracting"); overlay.ExtractEmbeddedOverlay(pixelData); anyExtracted = true; } return(anyExtracted); }
public DicomFile CreateFile(ushort rows, ushort columns, string photometricInterpretation, ushort bitsStored, ushort bitsAllocated, bool isSigned, ushort numberOfFrames) { DicomFile file = new DicomFile("SCTestImage.dcm"); DicomAttributeCollection dataSet = file.DataSet; SetupSecondaryCapture(dataSet); dataSet[DicomTags.PixelData] = null; DicomUncompressedPixelData pd = new DicomUncompressedPixelData(dataSet) { ImageWidth = columns, ImageHeight = rows, PhotometricInterpretation = photometricInterpretation, BitsAllocated = bitsAllocated, BitsStored = bitsStored, HighBit = (ushort)(bitsStored - 1), PixelRepresentation = (ushort)(isSigned ? 1 : 0), NumberOfFrames = numberOfFrames }; if (photometricInterpretation.Equals("RGB") || photometricInterpretation.Equals("YBR_FULL")) { pd.SamplesPerPixel = 3; pd.PlanarConfiguration = 1; CreateColorPixelData(pd); } else if (photometricInterpretation.Equals("MONOCHROME1") || photometricInterpretation.Equals("MONOCHROME2")) { CreateMonochromePixelData(pd); } else { throw new DicomException("Unsupported Photometric Interpretation in CreateFile"); } pd.UpdateAttributeCollection(dataSet); SetupMetaInfo(file); file.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian; return(file); }
public void GetPixelData(PrintScu.ImageBox imageBox, ColorMode colorMode, out ushort rows, out ushort columns, out byte[] pixelData) { try { LocalSopDataSource dataSource = _file.DataSource as LocalSopDataSource; dataSource.File.Load(DicomReadOptions.Default | DicomReadOptions.StorePixelDataReferences); rows = dataSource.File.DataSet[DicomTags.Rows].GetUInt16(0, 0); columns = dataSource.File.DataSet[DicomTags.Columns].GetUInt16(0, 0); DicomUncompressedPixelData uncompressedPixelData = new DicomUncompressedPixelData(dataSource.File); pixelData = uncompressedPixelData.GetFrame(0); } catch (Exception e) { Platform.Log(LogLevel.Error, string.Format("获得像素数据失败:{0}", e.Message)); throw e; } }
public void TestTogglePixelRep_BitsStored7_HighBit7() { //Test: -64, -31, -8, -1, 0, 13, 43, 63 //Test (bin): 10000000, 11000010, 11110000, 11111110, 00000000, 00011010, 01010110, 01111110 const int bitsAllocated = 8; const int bitsStored = 7; const int highBit = 7; var testValues = new byte[] { 0x80, 0xC2, 0xF0, 0xFE, 0x0, 0x1A, 0x56, 0x7E }; var expectedValues = new byte[] { 0, 33, 56, 63, 64, 77, 107, 127 }; int rescale; DicomUncompressedPixelData.TogglePixelRepresentation(testValues, highBit, bitsStored, bitsAllocated, out rescale); Assert.AreEqual(expectedValues, testValues); Assert.AreEqual(rescale, 64); }
public void TestTogglePixelRep_BitsStored5_HighBit4() { //Test: -16, -11, -7, -1, 0, 7, 11, 15 //Test(bin): 00010000, 00010101, 00011001, 00011111, 00000000, 00000111, 00001011, 00001111 const int bitsAllocated = 8; const int bitsStored = 5; const int highBit = 4; var testValues = new byte[] { 0x10, 0x15, 0x19, 0x1F, 0x0, 0x7, 0xB, 0xF }; var expectedValues = new byte[] { 0, 5, 9, 15, 16, 23, 27, 31 }; int rescale; DicomUncompressedPixelData.TogglePixelRepresentation(testValues, highBit, bitsStored, bitsAllocated, out rescale); Assert.AreEqual(expectedValues, testValues); Assert.AreEqual(rescale, 16); }
public void TestTogglePixelRep_BitsStored7_HighBit6() { //Test: -64, -31, -8, -1, 0, 13, 43, 63 //Test (bin): 01000000, 01100001, 01111000, 01111111, 00000000, 00001101, 00101011, 00111111 const int bitsAllocated = 8; const int bitsStored = 7; const int highBit = 6; var testValues = new byte[] { 0x40, 0x61, 0x78, 0x7F, 0x0, 0xD, 0x2B, 0x3F }; var expectedValues = new byte[] { 0, 33, 56, 63, 64, 77, 107, 127 }; int rescale; DicomUncompressedPixelData.TogglePixelRepresentation(testValues, highBit, bitsStored, bitsAllocated, out rescale); Assert.AreEqual(expectedValues, testValues); Assert.AreEqual(rescale, 64); }
public void TestTogglePixelRep_BitsStored6_HighBit6() { //Test: -32, -16, -8, -1, 0, 7, 13, 31 //Test(bin): 01000000, 01100000, 01110000, 01111110, 00000000, 00001110, 00011010, 00111110 const int bitsAllocated = 8; const int bitsStored = 6; const int highBit = 6; var testValues = new byte[] { 0x40, 0x60, 0x70, 0x7E, 0x0, 0xE, 0x1A, 0x3E }; var expectedValues = new byte[] { 0, 16, 24, 31, 32, 39, 45, 63 }; int rescale; DicomUncompressedPixelData.TogglePixelRepresentation(testValues, highBit, bitsStored, bitsAllocated, out rescale); Assert.AreEqual(expectedValues, testValues); Assert.AreEqual(rescale, 32); }
protected override void Upload(DicomFile dicomObject, int frame, IStorageLocation storeLocation) { var frameIndex = frame - 1; if (dicomObject.TransferSyntax == TransferSyntax.JpegBaselineProcess1) { DicomCompressedPixelData pd = DicomPixelData.CreateFrom(dicomObject) as DicomCompressedPixelData; byte[] buffer = pd.GetFrameFragmentData(frameIndex); storeLocation.Upload(buffer); } else if (false) //TODO: handle compressed images properly! { DicomFile dcmJpeg = new DicomFile( ); DicomUncompressedPixelData unCompressed = DicomPixelData.CreateFrom(dicomObject) as DicomUncompressedPixelData; DicomCompressedPixelData compressed = new DicomCompressedPixelData(unCompressed); //compressed.ImageWidth = unCompressed.ImageWidth; //compressed.ImageHeight = unCompressed.HighBit; compressed.BitsStored = 8; compressed.BitsAllocated = 8; //compressed.HighBit = 7; compressed.SamplesPerPixel = 3; //compressed.PlanarConfiguration = 0; compressed.PhotometricInterpretation = "YBR_FULL_422"; compressed.TransferSyntax = TransferSyntax.JpegBaselineProcess1; byte[] imageBuffer = unCompressed.GetFrame(frameIndex); compressed.AddFrameFragment(imageBuffer); compressed.UpdateMessage(dcmJpeg); storeLocation.Upload(compressed.GetFrame(frameIndex)); //ClearCanvas.Dicom.Codec.Jpeg.Jpeg8Codec codec = new ClearCanvas.Dicom.Codec.Jpeg.Jpeg8Codec (ClearCanvas.Dicom.Codec.Jpeg.JpegMode.Baseline, 0, 0 ) ; //ClearCanvas.Dicom.Codec.Jpeg.DicomJpegParameters jparam = new ClearCanvas.Dicom.Codec.Jpeg.DicomJpegParameters ( ) ; //jparam. //codec. //codec.Encode ( ) } }
private void SetupEncapsulatedImageWithIconSequence(DicomFile file, bool encapsulateIconPixelData) { var codec = new NullDicomCodec(); DicomAttributeCollection dataSet = file.DataSet; SetupSecondaryCapture(dataSet); SetupMetaInfo(file); file.TransferSyntax = TransferSyntax.ImplicitVrLittleEndian; file.ChangeTransferSyntax(codec.CodecTransferSyntax); // explicitly create the icon sequence as either encapsulated or native, so that we are not depending on correct behaviour elsewhere... CreateIconImageSequence(dataSet); if (encapsulateIconPixelData) { var dataset = ((DicomAttributeSQ)dataSet[DicomTags.IconImageSequence])[0]; var pixelData = dataset[DicomTags.PixelData]; var pd = new DicomUncompressedPixelData(dataset); using (var pixelStream = ((DicomAttributeBinary)pixelData).AsStream()) { //Before compression, make the pixel data more "typical", so it's harder to mess up the codecs. //NOTE: Could combine mask and align into one method so we're not iterating twice, but I prefer having the methods separate. if (DicomUncompressedPixelData.RightAlign(pixelStream, pd.BitsAllocated, pd.BitsStored, pd.HighBit)) { var newHighBit = (ushort)(pd.HighBit - pd.LowBit); pd.HighBit = newHighBit; //correct high bit after right-aligning. dataset[DicomTags.HighBit].SetUInt16(0, newHighBit); } DicomUncompressedPixelData.ZeroUnusedBits(pixelStream, pd.BitsAllocated, pd.BitsStored, pd.HighBit); } // Set transfer syntax before compression, the codecs need it. var fragments = new DicomCompressedPixelData(pd) { TransferSyntax = codec.CodecTransferSyntax }; codec.Encode(pd, fragments, null); fragments.UpdateAttributeCollection(dataset); } }
public void TestTogglePixelRep_BitsStored12_HighBit11() { //Test: -2048, -1111, -787, -3, 0, 3, 763, 1567, 2047 //Test(bin): 00001000 00000000, 00001011 10101001, 00001100 11101101, 00001111 11111101, 00000000 00000000, 00000000 00000011, 00000010 11111011, 00000110 00011111, 00000111 11111111, const int bitsAllocated = 16; const int bitsStored = 12; const int highBit = 11; var testValues = ByteConverter.ToByteArray(new ushort[] { 0x800, 0xBA9, 0xCED, 0xFFD, 0x00, 0x03, 0x2FB, 0x61F, 0x7FF }); var expectedValues = new ushort[] { 0, 937, 1261, 2045, 2048, 2051, 2811, 3615, 4095 }; int rescale; DicomUncompressedPixelData.TogglePixelRepresentation(testValues, highBit, bitsStored, bitsAllocated, out rescale); Assert.AreEqual(expectedValues, ByteConverter.ToUInt16Array(testValues)); Assert.AreEqual(rescale, 2048); }
public void TestTogglePixelRep_BitsStored14_HighBit15() { //Test: -8192, -4331, -2177, -3, 0, 3, 2177, 4331, 8191 //Test(bin): 10000000 00000000, 10111100 01010100, 11011101 11111100, 11111111 11110100, 00000000 00000000, 00000000 00001100, 00100010 00000100, 01000011 10101100, 01111111 11111100, const int bitsAllocated = 16; const int bitsStored = 14; const int highBit = 15; var testValues = ByteConverter.ToByteArray(new ushort[] { 0x8000, 0xBC54, 0xDDFC, 0xFFF4, 0x00, 0x0C, 0x2204, 0x43AC, 0x7FFC }); var expectedValues = new ushort[] { 0, 3861, 6015, 8189, 8192, 8195, 10369, 12523, 16383 }; int rescale; DicomUncompressedPixelData.TogglePixelRepresentation(testValues, highBit, bitsStored, bitsAllocated, out rescale); Assert.AreEqual(expectedValues, ByteConverter.ToUInt16Array(testValues)); Assert.AreEqual(rescale, 8192); }
public void TestTogglePixelRep_BitsStored15_HighBit15() { //Test: -16384, -9817, -4331, -3, 0, 3, 4331, 9817, 16383 //Test(bin): 10000000 00000000, 10110011 01001110, 11011110 00101010, 11111111 11111010, 00000000 00000000, 00000000 00000110, 00100001 11010110, 01001100 10110010, 01111111 11111110, const int bitsAllocated = 16; const int bitsStored = 15; const int highBit = 15; var testValues = ByteConverter.ToByteArray(new ushort[] { 0x8000, 0xB34E, 0xDE2A, 0xFFFA, 0x00, 0x06, 0x21D6, 0x4CB2, 0x7FFE }); var expectedValues = new ushort[] { 0, 6567, 12053, 16381, 16384, 16387, 20715, 26201, 32767 }; int rescale; DicomUncompressedPixelData.TogglePixelRepresentation(testValues, highBit, bitsStored, bitsAllocated, out rescale); Assert.AreEqual(expectedValues, ByteConverter.ToUInt16Array(testValues)); Assert.AreEqual(rescale, 16384); }
public unsafe void TestTogglePixelRep_BitsStored16_HighBit15() { //Test: -32768, -21101, -9999, -3, 0, 3, 9787, 21397, 32767 //Test(bin): 10000000 00000000, 10101101 10010011, 11011000 11110001, 11111111 11111101, 00000000 00000000, 00000000 00000011, 00100110 00111011, 01010011 10010101, 01111111 11111111 const int bitsAllocated = 16; const int bitsStored = 16; const int highBit = 15; var testValues = ByteConverter.ToByteArray(new ushort[] { 0x8000, 0xAD93, 0xD8F1, 0xFFFD, 0x00, 0x03, 0x263B, 0x5395, 0x7FFF }); var expectedValues = new ushort[] { 0, 11667, 22769, 32765, 32768, 32771, 42555, 54165, 65535 }; int rescale; DicomUncompressedPixelData.TogglePixelRepresentation(testValues, highBit, bitsStored, bitsAllocated, out rescale); Assert.AreEqual(expectedValues, ByteConverter.ToUInt16Array(testValues)); Assert.AreEqual(rescale, 32768); }
public void Encode(DicomUncompressedPixelData oldPixelData, DicomCompressedPixelData newPixelData, DicomCodecParameters parameters) { for (var n = 0; n < oldPixelData.NumberOfFrames; ++n) { using (var output = new MemoryStream()) { using (var gzipStream = new GZipStream(output, CompressionMode.Compress, true)) { var data = oldPixelData.GetFrame(n); gzipStream.Write(data, 0, data.Length); } // if the compressed stream is odd length, append an extra byte - gzip will know that it's padding during decompression if (output.Length%2 == 1) output.WriteByte(0); newPixelData.AddFrameFragment(output.ToArray()); } } }
private void SetupEncapsulatedImageWithIconSequence(DicomFile file, bool encapsulateIconPixelData) { var codec = new NullDicomCodec(); DicomAttributeCollection dataSet = file.DataSet; SetupSecondaryCapture(dataSet); SetupMetaInfo(file); file.TransferSyntax = TransferSyntax.ImplicitVrLittleEndian; file.ChangeTransferSyntax(codec.CodecTransferSyntax); // explicitly create the icon sequence as either encapsulated or native, so that we are not depending on correct behaviour elsewhere... CreateIconImageSequence(dataSet); if (encapsulateIconPixelData) { var dataset = ((DicomAttributeSQ) dataSet[DicomTags.IconImageSequence])[0]; var pixelData = dataset[DicomTags.PixelData]; var pd = new DicomUncompressedPixelData(dataset); using (var pixelStream = ((DicomAttributeBinary) pixelData).AsStream()) { //Before compression, make the pixel data more "typical", so it's harder to mess up the codecs. //NOTE: Could combine mask and align into one method so we're not iterating twice, but I prefer having the methods separate. if (DicomUncompressedPixelData.RightAlign(pixelStream, pd.BitsAllocated, pd.BitsStored, pd.HighBit)) { var newHighBit = (ushort) (pd.HighBit - pd.LowBit); pd.HighBit = newHighBit; //correct high bit after right-aligning. dataset[DicomTags.HighBit].SetUInt16(0, newHighBit); } DicomUncompressedPixelData.ZeroUnusedBits(pixelStream, pd.BitsAllocated, pd.BitsStored, pd.HighBit); } // Set transfer syntax before compression, the codecs need it. var fragments = new DicomCompressedPixelData(pd) {TransferSyntax = codec.CodecTransferSyntax}; codec.Encode(pd, fragments, null); fragments.UpdateAttributeCollection(dataset); } }
public void Encode(DicomUncompressedPixelData oldPixelData, DicomCompressedPixelData newPixelData, DicomCodecParameters parameters) { if (oldPixelData.UncompressedFrameSize%2 == 1) { for (var n = 0; n < oldPixelData.NumberOfFrames; ++n) { using (var stream = new MemoryStream()) { var data = oldPixelData.GetFrame(n); stream.Write(data, 0, data.Length); stream.WriteByte(0); // must pad fragments to even length newPixelData.AddFrameFragment(stream.ToArray()); } } } else { for (var n = 0; n < oldPixelData.NumberOfFrames; ++n) { newPixelData.AddFrameFragment(oldPixelData.GetFrame(n)); } } }
public void TestBasic_MessageInMemory_8Bits_OB() { var dcf = CreateDicomImage(rows : 20, columns : 30, numberOfFrames : 3, bitsAllocated16 : false, useOB : true); var pd = new DicomUncompressedPixelData(dcf); Assert.AreEqual(8, pd.BitsAllocated, "BitsAllocated"); Assert.AreEqual(8, pd.BitsStored, "BitsStored"); Assert.AreEqual(7, pd.HighBit, "HighBit"); Assert.AreEqual(20, pd.ImageHeight, "ImageHeight"); Assert.AreEqual(30, pd.ImageWidth, "ImageWidth"); Assert.AreEqual(3, pd.NumberOfFrames, "NumberOfFrames"); Assert.AreEqual("MONOCHROME2", pd.PhotometricInterpretation, "PhotometricInterpretation"); Assert.AreEqual(0, pd.PixelRepresentation, "PixelRepresentation"); Assert.AreEqual(1, pd.SamplesPerPixel, "SamplesPerPixel"); Assert.AreEqual(20*30, pd.UncompressedFrameSize, "UncompressedFrameSize"); for (var frame = 0; frame < 3; ++frame) { var fd = pd.GetFrame(frame); Assert.AreEqual(pd.UncompressedFrameSize, fd.Length, "PixelData(frame={0}).Length", frame); AssertBytesEqual((byte) (0x80 + frame), fd, "PixelData(frame={0})", frame); } }
public void TestAdvanced_FileOnDisk_16Bits_OW() { var filename = Path.GetTempFileName(); CreateDicomImage(rows : 20, columns : 30, numberOfFrames : 5).Save(filename); var dcf = new DicomFile(filename); dcf.Load(DicomReadOptions.StorePixelDataReferences); try { var pd = new DicomUncompressedPixelData(dcf); Assert.AreEqual(16, pd.BitsAllocated, "BitsAllocated"); Assert.AreEqual(16, pd.BitsStored, "BitsStored"); Assert.AreEqual(15, pd.HighBit, "HighBit"); Assert.AreEqual(20, pd.ImageHeight, "ImageHeight"); Assert.AreEqual(30, pd.ImageWidth, "ImageWidth"); Assert.AreEqual(5, pd.NumberOfFrames, "NumberOfFrames"); Assert.AreEqual("MONOCHROME2", pd.PhotometricInterpretation, "PhotometricInterpretation"); Assert.AreEqual(0, pd.PixelRepresentation, "PixelRepresentation"); Assert.AreEqual(1, pd.SamplesPerPixel, "SamplesPerPixel"); Assert.AreEqual(20*30*2, pd.UncompressedFrameSize, "UncompressedFrameSize"); var newFrameData = new byte[pd.UncompressedFrameSize]; for (var n = 0; n < newFrameData.Length; ++n) newFrameData[n] = 0x7F; pd.SetFrame(1, newFrameData); pd.UpdateAttributeCollection(dcf.DataSet); var pixelData = dcf.DataSet[DicomTags.PixelData].Values as byte[]; for (var frame = 0; frame < 5; ++frame) { var fd = pd.GetFrame(frame); var expectedValue = frame == 1 ? (byte) 0x7F : (byte) (0x80 + frame); Assert.AreEqual(pd.UncompressedFrameSize, fd.Length, "PixelData(frame={0}).Length", frame); AssertBytesEqual(expectedValue, fd, "PixelData(frame={0})", frame); AssertBytesEqual(expectedValue, pixelData, frame*pd.UncompressedFrameSize, pd.UncompressedFrameSize, "AttributeValues(frame={0})", frame); } } finally { File.Delete(filename); } }
private void CheckPixels(string filename) { DicomReadOptions readOptions = DicomReadOptions.StorePixelDataReferences; DicomFile newFile = new DicomFile(filename); newFile.Load(readOptions); DicomUncompressedPixelData pd = new DicomUncompressedPixelData(newFile.DataSet); for (int frame = 0; frame < pd.NumberOfFrames; frame++) { byte[] data = pd.GetFrame(frame); uint pdVal = (uint)frame + 1; for (int i = 0; i < pd.UncompressedFrameSize; i++, pdVal++) { if (data[i] != pdVal%255) { string val = String.Format("Value bad: frame: {0}, pixel: {1}, val1: {2}, val2: {3}", frame, i, data[i], pdVal%255); Console.Write(val); } Assert.AreEqual(data[i], pdVal%255); } } }
public void TestBasic_FileOnDisk_8Bits_OB() { var filename = Path.GetTempFileName(); CreateDicomImage(rows : 20, columns : 30, numberOfFrames : 3, bitsAllocated16 : false, useOB : true).Save(filename); var dcf = new DicomFile(filename); dcf.Load(DicomReadOptions.StorePixelDataReferences); try { var pd = new DicomUncompressedPixelData(dcf); Assert.AreEqual(8, pd.BitsAllocated, "BitsAllocated"); Assert.AreEqual(8, pd.BitsStored, "BitsStored"); Assert.AreEqual(7, pd.HighBit, "HighBit"); Assert.AreEqual(20, pd.ImageHeight, "ImageHeight"); Assert.AreEqual(30, pd.ImageWidth, "ImageWidth"); Assert.AreEqual(3, pd.NumberOfFrames, "NumberOfFrames"); Assert.AreEqual("MONOCHROME2", pd.PhotometricInterpretation, "PhotometricInterpretation"); Assert.AreEqual(0, pd.PixelRepresentation, "PixelRepresentation"); Assert.AreEqual(1, pd.SamplesPerPixel, "SamplesPerPixel"); Assert.AreEqual(20*30, pd.UncompressedFrameSize, "UncompressedFrameSize"); for (var frame = 0; frame < 3; ++frame) { var fd = pd.GetFrame(frame); Assert.AreEqual(pd.UncompressedFrameSize, fd.Length, "PixelData(frame={0}).Length", frame); AssertBytesEqual((byte) (0x80 + frame), fd, "PixelData(frame={0})", frame); } } finally { File.Delete(filename); } }
public void TestBasic_FileOnDisk_16Bits_BigEndian_OddFrameLength() { var filename = Path.GetTempFileName(); CreateDicomImage(rows : 19, columns : 29, numberOfFrames : 5, endian : Endian.Big).Save(filename); var dcf = new DicomFile(filename); dcf.Load(DicomReadOptions.StorePixelDataReferences); try { var pd = new DicomUncompressedPixelData(dcf); Assert.AreEqual(16, pd.BitsAllocated, "BitsAllocated"); Assert.AreEqual(16, pd.BitsStored, "BitsStored"); Assert.AreEqual(15, pd.HighBit, "HighBit"); Assert.AreEqual(19, pd.ImageHeight, "ImageHeight"); Assert.AreEqual(29, pd.ImageWidth, "ImageWidth"); Assert.AreEqual(5, pd.NumberOfFrames, "NumberOfFrames"); Assert.AreEqual("MONOCHROME2", pd.PhotometricInterpretation, "PhotometricInterpretation"); Assert.AreEqual(0, pd.PixelRepresentation, "PixelRepresentation"); Assert.AreEqual(1, pd.SamplesPerPixel, "SamplesPerPixel"); Assert.AreEqual(19*29*2, pd.UncompressedFrameSize, "UncompressedFrameSize"); for (var frame = 0; frame < 5; ++frame) { var fd = pd.GetFrame(frame); Assert.AreEqual(pd.UncompressedFrameSize, fd.Length, "PixelData(frame={0}).Length", frame); AssertBytesEqual((byte) (0x80 + frame), fd, "PixelData(frame={0})", frame); } } finally { File.Delete(filename); } }
public void PartialFrameTest() { DicomFile file = new DicomFile("RlePartialFrameTest.dcm"); SetupMultiframeXA(file.DataSet, 511, 511, 7); file.ChangeTransferSyntax(TransferSyntax.RleLossless); file.Save(); DicomFile newFile = new DicomFile(file.Filename); newFile.Load(DicomReadOptions.StorePixelDataReferences); DicomPixelData pd; if (!newFile.TransferSyntax.Encapsulated) pd = new DicomUncompressedPixelData(newFile); else if (newFile.TransferSyntax.Equals(TransferSyntax.RleLossless)) pd = new DicomCompressedPixelData(newFile); else throw new DicomCodecException("Unsupported transfer syntax: " + newFile.TransferSyntax); for (int i=0; i< pd.NumberOfFrames; i++) { pd.GetFrame(i); } }
public void DecodeFrame(int frame, DicomCompressedPixelData oldPixelData, DicomUncompressedPixelData newPixelData, DicomCodecParameters parameters) { DicomRleCodecParameters rleParams = parameters as DicomRleCodecParameters; if (rleParams == null) throw new DicomCodecException("Unexpected RLE Codec parameters"); int pixelCount = oldPixelData.ImageWidth * oldPixelData.ImageHeight; int numberOfSegments = oldPixelData.BytesAllocated * oldPixelData.SamplesPerPixel; int segmentLength = (pixelCount & 1) == 1 ? pixelCount + 1 : pixelCount; byte[] segment = new byte[segmentLength]; byte[] frameData = new byte[oldPixelData.UncompressedFrameSize]; IList<DicomFragment> rleData = oldPixelData.GetFrameFragments(frame); RLEDecoder decoder = new RLEDecoder(rleData); if (decoder.NumberOfSegments != numberOfSegments) throw new DicomCodecException("Unexpected number of RLE segments!"); for (int s = 0; s < numberOfSegments; s++) { decoder.DecodeSegment(s, segment); int sample = s / oldPixelData.BytesAllocated; int sabyte = s % oldPixelData.BytesAllocated; int pos; int offset; if (newPixelData.PlanarConfiguration == 0) { pos = sample * oldPixelData.BytesAllocated; offset = oldPixelData.SamplesPerPixel * oldPixelData.BytesAllocated; } else { pos = sample * oldPixelData.BytesAllocated * pixelCount; offset = oldPixelData.BytesAllocated; } if (rleParams.ReverseByteOrder) pos += sabyte; else pos += oldPixelData.BytesAllocated - sabyte - 1; for (int p = 0; p < pixelCount; p++) { frameData[pos] = segment[p]; pos += offset; } } newPixelData.AppendFrame(frameData); }
public static int[] Convert16BitSigned(byte[] byteInputData, int pixels, DicomUncompressedPixelData pd) { int shiftBits = 32 - pd.BitsStored; int[] intPixels = new int[pixels]; for (int byteArrayCount = 0, pixelCount = 0; byteArrayCount < byteInputData.Length; byteArrayCount += 2, pixelCount++) { intPixels[pixelCount] = BitConverter.ToInt16(byteInputData, byteArrayCount); intPixels[pixelCount] = (intPixels[pixelCount] << shiftBits) >> shiftBits; } return intPixels; }
public static int[] Convert8BitSigned(byte[] byteInputData, int pixels, DicomUncompressedPixelData pd) { int shiftBits = 32 - pd.BitsStored; bool bPixelRescale = !string.IsNullOrEmpty(pd.RescaleSlope) && !string.IsNullOrEmpty(pd.RescaleIntercept) && (pd.DecimalRescaleSlope != 1m || pd.DecimalRescaleIntercept != 0m); byte pixelMask = 0x00; for (int x = 0; x < pd.BitsStored; x++) pixelMask = (byte)((pixelMask << 1) | 0x0001); int[] intPixels = new int[pixels]; for (int pixelCount = 0; pixelCount < byteInputData.Length; pixelCount++) { intPixels[pixelCount] = byteInputData[pixelCount] & pixelMask; intPixels[pixelCount] = (((intPixels[pixelCount] << shiftBits)) >> shiftBits); if (bPixelRescale) intPixels[pixelCount] = intPixels[pixelCount] * (int)pd.DecimalRescaleSlope + (int)pd.DecimalRescaleIntercept; } return intPixels; }
protected static void CreateColorPixelData(DicomUncompressedPixelData pd) { int rows = pd.ImageHeight; int cols = pd.ImageWidth; int minValue = pd.IsSigned ? -(1 << (pd.BitsStored - 1)) : 0; int maxValue = (1 << pd.BitsStored) + minValue - 1; const byte noOpByteMask = 0xFF; var byteMask = (byte)(noOpByteMask >> (pd.BitsAllocated - pd.BitsStored)); // Create a small block of pixels in the test pattern in an integer, // then copy/tile into the full size frame data int smallRows = (rows * 3) / 8; int smallColumns = rows / 4; int stripSize = rows / 16; int[] smallPixels = new int[smallRows * smallColumns * 3]; float slope = (float)(maxValue - minValue) / smallColumns; int pixelOffset = 0; for (int i = 0; i < smallRows; i++) { if (i < stripSize) { for (int j = 0; j < smallColumns; j++) { smallPixels[pixelOffset] = (int)((j * slope) + minValue); pixelOffset++; smallPixels[pixelOffset] = 0; pixelOffset++; smallPixels[pixelOffset] = 0; pixelOffset++; } } else if (i > (smallRows - stripSize)) { for (int j = 0; j < smallColumns; j++) { smallPixels[pixelOffset] = 0; pixelOffset++; smallPixels[pixelOffset] = (int)(maxValue - (j * slope)); pixelOffset++; smallPixels[pixelOffset] = 0; pixelOffset++; } } else { int pixel = minValue + (int)((i - stripSize) * slope); if (pixel < minValue) pixel = minValue + 1; if (pixel > maxValue) pixel = maxValue - 1; int start = (smallColumns / 2) - (i - stripSize) / 2; int end = (smallColumns / 2) + (i - stripSize) / 2; for (int j = 0; j < smallColumns; j++) { smallPixels[pixelOffset] = 0; pixelOffset++; smallPixels[pixelOffset] = 0; pixelOffset++; if (j < start) smallPixels[pixelOffset] = minValue; else if (j > end) smallPixels[pixelOffset] = maxValue; else smallPixels[pixelOffset] = pixel; pixelOffset++; } } } // Now create the actual frame for (int frame = 0; frame < pd.NumberOfFrames; frame++) { // Odd length frames are automatically dealt with by DicomUncompressedPixelData byte[] frameData = new byte[pd.UncompressedFrameSize]; pixelOffset = 0; for (int i = 0; i < rows; i++) { int smallOffset = (i%smallRows)*smallColumns*3; for (int j = 0; j < cols*3; j++) { frameData[pixelOffset] = (byte) smallPixels[smallOffset + j%(smallColumns*3)]; frameData[pixelOffset] &= byteMask; pixelOffset++; } } pd.AppendFrame(frameData); } }
protected static void CreatePixelData(DicomUncompressedPixelData pd) { var photometricInterpretation = pd.PhotometricInterpretation; if (photometricInterpretation.Equals("RGB") || photometricInterpretation.Equals("YBR_FULL")) { pd.SamplesPerPixel = 3; pd.PlanarConfiguration = 1; CreateColorPixelData(pd); } else if (photometricInterpretation.Equals("MONOCHROME1") || photometricInterpretation.Equals("MONOCHROME2")) { CreateMonochromePixelData(pd); } else { throw new DicomException("Unsupported Photometric Interpretation in CreateFile"); } }
public void Encode(DicomUncompressedPixelData oldPixelData, DicomCompressedPixelData newPixelData, DicomCodecParameters parameters) { DicomRleCodecParameters rleParams = parameters as DicomRleCodecParameters; if (rleParams == null) throw new DicomCodecException("Unexpected RLE Codec parameters"); // Convert to RGB if (oldPixelData.HasPaletteColorLut && parameters.ConvertPaletteToRGB) { oldPixelData.ConvertPaletteColorToRgb(); newPixelData.HasPaletteColorLut = false; newPixelData.SamplesPerPixel = oldPixelData.SamplesPerPixel; newPixelData.PlanarConfiguration = oldPixelData.PlanarConfiguration; newPixelData.PhotometricInterpretation = oldPixelData.PhotometricInterpretation; } int pixelCount = oldPixelData.ImageWidth * oldPixelData.ImageHeight; int numberOfSegments = oldPixelData.BytesAllocated * oldPixelData.SamplesPerPixel; for (int i = 0; i < oldPixelData.NumberOfFrames; i++) { RLEEncoder encoder = new RLEEncoder(); byte[] frameData = oldPixelData.GetFrame(i); for (int s = 0; s < numberOfSegments; s++) { encoder.NextSegment(); int sample = s / oldPixelData.BytesAllocated; int sabyte = s % oldPixelData.BytesAllocated; int pos; int offset; if (newPixelData.PlanarConfiguration == 0) { pos = sample * oldPixelData.BytesAllocated; offset = numberOfSegments; } else { pos = sample * oldPixelData.BytesAllocated * pixelCount; offset = oldPixelData.BytesAllocated; } if (rleParams.ReverseByteOrder) pos += sabyte; else pos += oldPixelData.BytesAllocated - sabyte - 1; for (int p = 0; p < pixelCount; p++) { if (pos >= frameData.Length) throw new DicomCodecException(""); encoder.Encode(frameData[pos]); pos += offset; } encoder.Flush(); } encoder.MakeEvenLength(); newPixelData.AddFrameFragment(encoder.GetBuffer()); } }
public DicomFile CreateFile(ushort rows, ushort columns, string photometricInterpretation, ushort bitsStored, ushort bitsAllocated, bool isSigned, ushort numberOfFrames) { DicomFile file = new DicomFile("SCTestImage.dcm"); DicomAttributeCollection dataSet = file.DataSet; SetupSecondaryCapture(dataSet); dataSet[DicomTags.PixelData] = null; DicomUncompressedPixelData pd = new DicomUncompressedPixelData(dataSet) { ImageWidth = columns, ImageHeight = rows, PhotometricInterpretation = photometricInterpretation, BitsAllocated = bitsAllocated, BitsStored = bitsStored, HighBit = (ushort) (bitsStored - 1), PixelRepresentation = (ushort) (isSigned ? 1 : 0), NumberOfFrames = numberOfFrames }; if (photometricInterpretation.Equals("RGB") || photometricInterpretation.Equals("YBR_FULL")) { pd.SamplesPerPixel = 3; pd.PlanarConfiguration = 1; CreateColorPixelData(pd); } else if (photometricInterpretation.Equals("MONOCHROME1") || photometricInterpretation.Equals("MONOCHROME2")) { CreateMonochromePixelData(pd); } else { throw new DicomException("Unsupported Photometric Interpretation in CreateFile"); } pd.UpdateAttributeCollection(dataSet); SetupMetaInfo(file); file.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian; return file; }
public static int[] Convert16BitUnsigned(byte[] byteInputData, int pixels, DicomUncompressedPixelData pd) { bool bPixelRescale = !string.IsNullOrEmpty(pd.RescaleSlope) && !string.IsNullOrEmpty(pd.RescaleIntercept) && (pd.DecimalRescaleSlope != 1m || pd.DecimalRescaleIntercept != 0m); ushort pixelMask = 0x0000; for (int x = 0; x < pd.BitsStored; x++) pixelMask = (ushort)((pixelMask << 1) | 0x0001); int[] intPixels = new int[pixels]; for (int byteArrayCount = 0, pixelCount = 0; byteArrayCount < byteInputData.Length; byteArrayCount += 2, pixelCount++) { intPixels[pixelCount] = BitConverter.ToUInt16(byteInputData, byteArrayCount); intPixels[pixelCount] = (ushort)(intPixels[pixelCount] & pixelMask); if (bPixelRescale) intPixels[pixelCount] = intPixels[pixelCount] * (int)pd.DecimalRescaleSlope + (int)pd.DecimalRescaleIntercept; } return intPixels; }
public void Decode(DicomCompressedPixelData oldPixelData, DicomUncompressedPixelData newPixelData, DicomCodecParameters parameters) { for (var n = 0; n < oldPixelData.NumberOfFrames; ++n) DecodeFrame(n, oldPixelData, newPixelData, parameters); }
public DicomFile CreateFile(ushort rows, ushort columns, string photometricInterpretation, ushort bitsStored, ushort bitsAllocated, bool isSigned, ushort numberOfFrames) { DicomFile file = new DicomFile("SCTestImage.dcm"); DicomAttributeCollection dataSet = file.DataSet; SetupSecondaryCapture(dataSet); dataSet[DicomTags.PixelData] = null; DicomUncompressedPixelData pd = new DicomUncompressedPixelData(dataSet) { ImageWidth = columns, ImageHeight = rows, PhotometricInterpretation = photometricInterpretation, BitsAllocated = bitsAllocated, BitsStored = bitsStored, HighBit = (ushort) (bitsStored - 1), PixelRepresentation = (ushort) (isSigned ? 1 : 0), NumberOfFrames = numberOfFrames }; CreatePixelData(pd); pd.UpdateAttributeCollection(dataSet); SetupMetaInfo(file); file.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian; return file; }
protected static void CreatePixelData(DicomAttributeCollection dataSet) { dataSet[DicomTags.PixelData] = null; var pd = new DicomUncompressedPixelData(dataSet); CreatePixelData(pd); pd.UpdateAttributeCollection(dataSet); }
public void TestConversion_MultiframeEmbedded() { const bool bigEndian = false; // these parameters should be kept prime numbers so that we can exercise the overlay handling for rows/frames that cross byte boundaries const int rows = 97; const int columns = 101; const int frames = 7; const int overlayIndex = 0; var overlayData = new bool[rows*columns*frames]; for (int i = 0; i < frames; i++) { overlayData[(i * rows*columns) + 1] = true; overlayData[(i * rows * columns) + 10] = true; overlayData[(i * rows * columns) + 100] = true; overlayData[(i * rows * columns) + 225] = true; overlayData[(i * rows * columns) + 1000] = true; overlayData[(i * rows * columns) + 1001] = true; overlayData[(i * rows * columns) + (rows * columns) - 1] = true; } var dataset = new DicomAttributeCollection(); SetImage(dataset, new byte[rows * columns * 2 * frames], rows, columns, frames, 16, 12, 11, false); SetOverlay(dataset, overlayIndex, overlayData, OverlayType.G, new Point(1, 1), 12, bigEndian); DicomUncompressedPixelData pd = new DicomUncompressedPixelData(dataset); OverlayPlane overlayPlane = new OverlayPlane(overlayIndex, dataset); Assert.IsTrue(overlayPlane.ExtractEmbeddedOverlay(pd), "Failed to convert to Non-Embedded overlay plane."); int actualOverlayFrame; Assert.IsFalse(overlayPlane.TryGetRelevantOverlayFrame(-1, frames, out actualOverlayFrame), "Should not any matching overlay frame for image frame #-1"); Assert.IsFalse(overlayPlane.TryGetRelevantOverlayFrame(0, frames, out actualOverlayFrame), "Should not any matching overlay frame for image frame #0"); Assert.IsFalse(overlayPlane.TryGetRelevantOverlayFrame(8, frames, out actualOverlayFrame), "Should not any matching overlay frame for image frame #8"); // all valid image frame inputs should map 1-to-1 with the same numbered overlay frame Assert.IsTrue(overlayPlane.TryGetRelevantOverlayFrame(1, frames, out actualOverlayFrame), "Should be able to match an overlay frame to image frame #1"); Assert.AreEqual(1, actualOverlayFrame, "Wrong overlay frame matched to image frame #1"); Assert.IsTrue(overlayPlane.TryGetRelevantOverlayFrame(2, frames, out actualOverlayFrame), "Should be able to match an overlay frame to image frame #2"); Assert.AreEqual(2, actualOverlayFrame, "Wrong overlay frame matched to image frame #2"); Assert.IsTrue(overlayPlane.TryGetRelevantOverlayFrame(3, frames, out actualOverlayFrame), "Should be able to match an overlay frame to image frame #3"); Assert.AreEqual(3, actualOverlayFrame, "Wrong overlay frame matched to image frame #3"); Assert.IsTrue(overlayPlane.TryGetRelevantOverlayFrame(4, frames, out actualOverlayFrame), "Should be able to match an overlay frame to image frame #4"); Assert.AreEqual(4, actualOverlayFrame, "Wrong overlay frame matched to image frame #4"); Assert.IsTrue(overlayPlane.TryGetRelevantOverlayFrame(5, frames, out actualOverlayFrame), "Should be able to match an overlay frame to image frame #5"); Assert.AreEqual(5, actualOverlayFrame, "Wrong overlay frame matched to image frame #5"); Assert.IsTrue(overlayPlane.TryGetRelevantOverlayFrame(6, frames, out actualOverlayFrame), "Should be able to match an overlay frame to image frame #6"); Assert.AreEqual(6, actualOverlayFrame, "Wrong overlay frame matched to image frame #6"); Assert.IsTrue(overlayPlane.TryGetRelevantOverlayFrame(7, frames, out actualOverlayFrame), "Should be able to match an overlay frame to image frame #7"); Assert.AreEqual(7, actualOverlayFrame, "Wrong overlay frame matched to image frame #7"); }