private static void TestRightAlignSigned(byte[] testValues, int bitsStored, int highBit, sbyte[] expectedValues) { Assert.IsTrue(DicomUncompressedPixelData.ZeroUnusedBits(testValues, bitsStored, highBit)); Assert.IsTrue(DicomUncompressedPixelData.RightAlign(testValues, bitsStored, highBit)); Assert.AreEqual(expectedValues, DicomSignedToSigned(testValues, highBit - DicomPixelData.GetLowBit(bitsStored, highBit))); }
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 TestRightAlign_BitsStored8_NoOp() { var testValues = new byte[] { 128, 255 }; var expectedValues = (byte[])testValues.Clone(); Assert.IsFalse(DicomUncompressedPixelData.RightAlign(expectedValues, 8, 7)); Assert.AreEqual(expectedValues, testValues); }
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); }
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); } }
private static void TestRightAlign(ref ushort[] testValues, int bitsStored, int highBit, bool asBytes, bool asOpposingEndian) { if (!asBytes) { if (asOpposingEndian) { var opposingEndian = (ByteBuffer.LocalMachineEndian == Endian.Big) ? Endian.Little : Endian.Big; ByteConverter.SwapBytes(testValues); Assert.IsTrue(DicomUncompressedPixelData.ZeroUnusedBits(testValues, bitsStored, highBit, opposingEndian)); Assert.IsTrue(DicomUncompressedPixelData.RightAlign(testValues, bitsStored, highBit, opposingEndian)); ByteConverter.SwapBytes(testValues); } else { Assert.IsTrue(DicomUncompressedPixelData.ZeroUnusedBits(testValues, bitsStored, highBit)); Assert.IsTrue(DicomUncompressedPixelData.RightAlign(testValues, bitsStored, highBit)); } } else { if (asOpposingEndian) { ByteConverter.SwapBytes(testValues); var testValuesBytes = ByteConverter.ToByteArray(testValues); var opposingEndian = (ByteBuffer.LocalMachineEndian == Endian.Big) ? Endian.Little : Endian.Big; Assert.IsTrue(DicomUncompressedPixelData.ZeroUnusedBits(testValuesBytes, 16, bitsStored, highBit, opposingEndian)); Assert.IsTrue(DicomUncompressedPixelData.RightAlign(testValuesBytes, 16, bitsStored, highBit, opposingEndian)); testValues = ByteConverter.ToUInt16Array(testValuesBytes); ByteConverter.SwapBytes(testValues); } else { var testValuesBytes = ByteConverter.ToByteArray(testValues); Assert.IsTrue(DicomUncompressedPixelData.ZeroUnusedBits(testValuesBytes, 16, bitsStored, highBit)); Assert.IsTrue(DicomUncompressedPixelData.RightAlign(testValuesBytes, 16, bitsStored, highBit)); testValues = ByteConverter.ToUInt16Array(testValuesBytes); } } }
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); }
private static void TestRightAlign(byte[] testValues, int bitsStored, int highBit, byte[] expectedValues) { Assert.IsTrue(DicomUncompressedPixelData.ZeroUnusedBits(testValues, bitsStored, highBit)); Assert.IsTrue(DicomUncompressedPixelData.RightAlign(testValues, bitsStored, highBit)); Assert.AreEqual(expectedValues, testValues); //Expected values in hex }
public void Go() { string[] files = BuildFileList(); var args = new SelectFolderDialogCreationArgs { Path = GetDirectoryOfFirstPath(), AllowCreateNewFolder = true, Prompt = "Select output folder" }; var result = base.Context.DesktopWindow.ShowSelectFolderDialogBox(args); if (result.Action != DialogBoxAction.Ok) { return; } try { foreach (string file in files) { DicomFile dicomFile = new DicomFile(file); dicomFile.Load(); if (dicomFile.TransferSyntax.Encapsulated) { continue; } DicomAttribute attribute; if (!dicomFile.DataSet.TryGetAttribute(DicomTags.PixelData, out attribute)) { continue; } new OverlayPlaneModuleIod(dicomFile.DataSet).ExtractEmbeddedOverlays(); var rawPixelData = (byte[])attribute.Values; DicomPixelData pd = new DicomUncompressedPixelData(dicomFile); if (DicomUncompressedPixelData.ZeroUnusedBits(rawPixelData, pd.BitsAllocated, pd.BitsStored, pd.HighBit)) { Platform.Log(LogLevel.Info, "Zeroed some unused bits."); } if (DicomUncompressedPixelData.RightAlign(rawPixelData, pd.BitsAllocated, pd.BitsStored, pd.HighBit)) { var newHighBit = (ushort)(pd.HighBit - pd.LowBit); Platform.Log(LogLevel.Info, "Right aligned pixel data (High Bit: {0}->{1}).", pd.HighBit, newHighBit); pd.HighBit = newHighBit; //correct high bit after right-aligning. dicomFile.DataSet[DicomTags.HighBit].SetUInt16(0, newHighBit); } string sourceFileName = System.IO.Path.GetFileNameWithoutExtension(file); string fileName = System.IO.Path.Combine(result.FileName, sourceFileName); fileName += ".fixed-pixeldata.dcm"; dicomFile.Save(fileName); } } catch (Exception e) { ExceptionHandler.Report(e, Context.DesktopWindow); } }