コード例 #1
0
        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);

            DicomWebResponse <IReadOnlyList <Stream> > response = await _client.RetrieveFramesAsync(instanceId.StudyInstanceUid, instanceId.SeriesInstanceUid, instanceId.SopInstanceUid, mediaType, transferSyntax, frames : new[] { 1 });

            int frameIndex = 0;

            foreach (Stream item in response.Value)
            {
                // TODO: verify media type once https://microsofthealth.visualstudio.com/Health/_workitems/edit/75185 is done
                Assert.Equal(item.ToByteArray(), pixelData.GetFrame(frameIndex).Data);
                frameIndex++;
            }
        }
コード例 #2
0
        public async Task GivenUnsupportedTransferSyntax_WhenRetrieveFrameWithOriginalTransferSyntax_ThenOriginalContentReturned()
        {
            var studyInstanceUid  = TestUidGenerator.Generate();
            var seriesInstanceUid = TestUidGenerator.Generate();
            var sopInstanceUid    = TestUidGenerator.Generate();

            DicomFile dicomFile = Samples.CreateRandomDicomFileWith8BitPixelData(
                studyInstanceUid,
                seriesInstanceUid,
                sopInstanceUid,
                transferSyntax: DicomTransferSyntax.HEVCH265Main10ProfileLevel51.UID.UID,
                encode: false);

            await InternalStoreAsync(new[] { dicomFile });

            // Check for series
            DicomWebResponse <IReadOnlyList <Stream> > response = await _client.RetrieveFramesAsync(
                studyInstanceUid,
                seriesInstanceUid,
                sopInstanceUid,
                dicomTransferSyntax : "*",
                frames : new[] { 1 });

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Equal(response.Value[0].ToByteArray(), DicomPixelData.Create(dicomFile.Dataset).GetFrame(0).Data);
        }
コード例 #3
0
        private static void TestRightAlignSigned(ushort[] testValues, int bitsStored, int highBit, short[] expectedValues, bool asBytes, bool asOpposingEndian)
        {
            TestRightAlign(ref testValues, bitsStored, highBit, asBytes, asOpposingEndian);
            var newHighBit = highBit - DicomPixelData.GetLowBit(bitsStored, highBit);

            Assert.AreEqual(expectedValues, DicomSignedToSigned(testValues, newHighBit));
        }
コード例 #4
0
ファイル: DicomRleCodecImpl.cs プロジェクト: aerik/fo-dicom
 public override void Encode(
     DicomPixelData oldPixelData,
     DicomPixelData newPixelData,
     DicomCodecParams parameters)
 {
     DicomRleNativeCodec.Encode(oldPixelData.ToNativePixelData(), newPixelData.ToNativePixelData());
 }
        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());
        }
        public async Task GivenUnsupportedTransferSyntax_WhenRetrieveFrameWithOriginalTransferSyntax_ThenOriginalContentReturned()
        {
            var studyInstanceUid  = TestUidGenerator.Generate();
            var seriesInstanceUid = TestUidGenerator.Generate();
            var sopInstanceUid    = TestUidGenerator.Generate();

            DicomFile dicomFile = Samples.CreateRandomDicomFileWith8BitPixelData(
                studyInstanceUid,
                seriesInstanceUid,
                sopInstanceUid,
                transferSyntax: DicomTransferSyntax.HEVCH265Main10ProfileLevel51.UID.UID,
                encode: false);

            await InternalStoreAsync(new[] { dicomFile });

            // Check for series
            using DicomWebAsyncEnumerableResponse <Stream> response = await _client.RetrieveFramesAsync(
                      studyInstanceUid,
                      seriesInstanceUid,
                      sopInstanceUid,
                      dicomTransferSyntax : "*",
                      frames : new[] { 1 });

            Stream[] results = await response.ToArrayAsync();

            Assert.Collection(
                results,
                item => Assert.Equal(item.ToByteArray(), DicomPixelData.Create(dicomFile.Dataset).GetFrame(0).Data));
        }
コード例 #7
0
ファイル: PaletteColorPipeline.cs プロジェクト: GMZ/fo-dicom
        /// <summary>
        /// Initialize new instance of <seealso cref="PaletteColorPipeline"/> containing palette color LUT extracted from
        /// <paramref name="pixelData"/>
        /// </summary>
        /// <param name="pixelData">Dicom Pixel Data containing paletter color LUT</param>
        public PaletteColorPipeline(DicomPixelData pixelData)
        {
            var lut = pixelData.PaletteColorLUT;
            var first = pixelData.Dataset.Get<int>(DicomTag.RedPaletteColorLookupTableDescriptor, 1);

            _lut = new PaletteColorLUT(first, lut);
        }
コード例 #8
0
        private static DicomDataset Decode(
            DicomDataset oldDataset,
            DicomTransferSyntax outSyntax,
            IDicomCodec codec,
            DicomCodecParams parameters)
        {
            if (codec == null)
            {
                throw new DicomCodecException($"Decoding dataset with transfer syntax: {oldDataset.InternalTransferSyntax} is not supported.");
            }

            var oldPixelData = DicomPixelData.Create(oldDataset);

            var newDataset = oldDataset.Clone();

            newDataset.InternalTransferSyntax = outSyntax;
            var newPixelData = DicomPixelData.Create(newDataset, true);

            codec.Decode(oldPixelData, newPixelData, parameters);

            ProcessOverlays(oldDataset, newDataset);

            newDataset.RecalculateGroupLengths(false);

            return(newDataset);
        }
コード例 #9
0
 public override void Encode(
     DicomPixelData oldPixelData,
     DicomPixelData newPixelData,
     DicomCodecParams parameters)
 {
     DicomJpegCodecImpl.Encode(oldPixelData, newPixelData, parameters as DicomJpegParams);
 }
コード例 #10
0
 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)
     });
 }
コード例 #11
0
        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);
                }
            }
        }
コード例 #12
0
ファイル: AbstractCodecTest.cs プロジェクト: 1059444127/XA
        public static void LosslessImageTestWithConversion(TransferSyntax syntax, DicomFile theFile)
        {
            if (File.Exists(theFile.Filename))
            {
                File.Delete(theFile.Filename);
            }

            DicomFile saveCopy = new DicomFile(theFile.Filename, theFile.MetaInfo.Copy(), theFile.DataSet.Copy());

            theFile.ChangeTransferSyntax(syntax);

            theFile.Save(DicomWriteOptions.ExplicitLengthSequence);

            DicomFile newFile = new DicomFile(theFile.Filename);

            newFile.Load(DicomReadOptions.Default);

            newFile.ChangeTransferSyntax(saveCopy.TransferSyntax);

            string failureDescription;
            bool   result = Compare(DicomPixelData.CreateFrom(newFile),
                                    DicomPixelData.CreateFrom(saveCopy), out failureDescription);

            Assert.IsTrue(result, failureDescription);

            Assert.IsFalse(newFile.DataSet.Equals(saveCopy.DataSet));
        }
コード例 #13
0
ファイル: Samples.cs プロジェクト: xelement2020/dicom-server
        public static void AppendRandomPixelData(int rows, int columns, int frames, params DicomFile[] dicomFiles)
        {
            EnsureArg.IsGte(rows, 0, nameof(rows));
            EnsureArg.IsGte(columns, 0, nameof(columns));
            EnsureArg.IsNotNull(dicomFiles, nameof(dicomFiles));

            var          pixelDataSize = rows * columns;
            const ushort bitsAllocated = 8;

            dicomFiles.Each(x =>
            {
                x.Dataset.AddOrUpdate(DicomTag.Rows, (ushort)rows);
                x.Dataset.AddOrUpdate(DicomTag.Columns, (ushort)columns);
                x.Dataset.AddOrUpdate(DicomTag.BitsAllocated, bitsAllocated);

                var pixelData                 = DicomPixelData.Create(x.Dataset, true);
                pixelData.SamplesPerPixel     = 1;
                pixelData.PixelRepresentation = PixelRepresentation.Unsigned;
                pixelData.BitsStored          = bitsAllocated;
                pixelData.HighBit             = bitsAllocated - 1;

                for (var i = 0; i < frames; i++)
                {
                    pixelData.AddFrame(CreateRandomPixelData(pixelDataSize));
                }
            });
        }
コード例 #14
0
        public async Task <IReadOnlyCollection <Stream> > GetFramesResourceAsync(Stream stream, IEnumerable <int> frames, bool originalTransferSyntaxRequested, string requestedRepresentation)
        {
            EnsureArg.IsNotNull(stream, nameof(stream));
            EnsureArg.IsNotNull(frames, nameof(frames));

            DicomFile dicomFile = await DicomFile.OpenAsync(stream);

            // Validate requested frame index exists in file and retrieve the pixel data associated with the file.
            DicomPixelData pixelData = dicomFile.GetPixelDataAndValidateFrames(frames);

            if (!originalTransferSyntaxRequested && !dicomFile.Dataset.InternalTransferSyntax.Equals(DicomTransferSyntax.Parse(requestedRepresentation)))
            {
                return(frames.Select(frame => new LazyTransformReadOnlyStream <DicomFile>(
                                         dicomFile,
                                         df => _transcoder.TranscodeFrame(df, frame, requestedRepresentation)))
                       .ToArray());
            }
            else
            {
                return(frames.Select(
                           frame => new LazyTransformReadOnlyStream <DicomFile>(
                               dicomFile,
                               df => GetFrameAsDicomData(pixelData, frame)))
                       .ToArray());
            }
        }
コード例 #15
0
        public override void Encode(
            DicomPixelData oldPixelData,
            DicomPixelData newPixelData,
            DicomCodecParams parameters)
        {
            if (oldPixelData.NumberOfFrames == 0) return;

            // IJG eats the extra padding bits. Is there a better way to test for this?
            if (oldPixelData.BitsAllocated == 16 && oldPixelData.BitsStored <= 8)
            {
                // check for embedded overlays?
                newPixelData.BitsAllocated = 8;
            }

            var jparams = parameters as DicomJpegParams ?? GetDefaultParameters() as DicomJpegParams;

            var codec = GetCodec(oldPixelData.BitsStored, jparams);

            var oldNativeData = oldPixelData.ToNativePixelData();
            var newNativeData = newPixelData.ToNativePixelData();
            var jNativeParams = jparams.ToNativeJpegParameters();
            for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++)
            {
                codec.Encode(oldNativeData, newNativeData, jNativeParams, frame);
            }
        }
コード例 #16
0
        public override void Encode(
            DicomPixelData oldPixelData,
            DicomPixelData newPixelData,
            DicomCodecParams parameters)
        {
            if (oldPixelData.NumberOfFrames == 0)
            {
                return;
            }

            // IJG eats the extra padding bits. Is there a better way to test for this?
            if (oldPixelData.BitsAllocated == 16 && oldPixelData.BitsStored <= 8)
            {
                // check for embedded overlays?
                newPixelData.BitsAllocated = 8;
            }

            var jparams = parameters as DicomJpegParams ?? GetDefaultParameters() as DicomJpegParams;

            var codec = GetCodec(oldPixelData.BitsStored, jparams);

            var oldNativeData = oldPixelData.ToNativePixelData();
            var newNativeData = newPixelData.ToNativePixelData();
            var jNativeParams = jparams.ToNativeJpegParameters();

            for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++)
            {
                codec.Encode(oldNativeData, newNativeData, jNativeParams, frame);
            }
        }
コード例 #17
0
		/// <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 || 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);
				else if (pi == PhotometricInterpretation.YbrPartial422)
					buffer = PixelDataConverter.YbrPartial422ToRgb(buffer);

				return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer);
			} else {
				throw new DicomImagingException("Unsupported pixel data photometric interpretation: {0}", pi.Value);
			}
		}
コード例 #18
0
        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);
                }
            }
        }
コード例 #19
0
 public override void Encode(
     DicomPixelData oldPixelData,
     DicomPixelData newPixelData,
     DicomCodecParams parameters)
 {
     DicomJpeg2000NativeCodec.Encode(
         oldPixelData.ToNativePixelData(),
         newPixelData.ToNativePixelData(),
         parameters.ToNativeJpeg2000Parameters());
 }
コード例 #20
0
 public override void Decode(
     DicomPixelData oldPixelData,
     DicomPixelData newPixelData,
     DicomCodecParams parameters)
 {
     DicomJpegLsNativeCodec.Decode(
         oldPixelData.ToNativePixelData(),
         newPixelData.ToNativePixelData(),
         parameters.ToNativeJpegLSParameters());
 }
コード例 #21
0
        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);
            }
        }
コード例 #22
0
        public override void Encode(
            DicomPixelData oldPixelData,
            DicomPixelData newPixelData,
            DicomCodecParams parameters)
        {
#if NETFX_CORE
            DicomJpeg2000NativeCodec.Encode(
                oldPixelData.ToNativePixelData(),
                newPixelData.ToNativePixelData(),
                parameters.ToNativeJpeg2000Parameters());
#else
            DicomJpeg2000CodecImpl.Encode(oldPixelData, newPixelData, parameters as DicomJpeg2000Params);
#endif
        }
コード例 #23
0
ファイル: PixelData.cs プロジェクト: voicupul/fo-dicom
		/// <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);
			}
		}
コード例 #24
0
        public override void Decode(
            DicomPixelData oldPixelData,
            DicomPixelData newPixelData,
            DicomCodecParams parameters)
        {
            if (oldPixelData.NumberOfFrames == 0) return;

            // IJG eats the extra padding bits. Is there a better way to test for this?
            if (newPixelData.BitsAllocated == 16 && newPixelData.BitsStored <= 8)
            {
                // check for embedded overlays here or below?
                newPixelData.BitsAllocated = 8;
            }

            var jparams = parameters as DicomJpegParams ?? GetDefaultParameters() as DicomJpegParams;

            var oldNativeData = oldPixelData.ToNativePixelData();
            int precision;
            try
            {
                try
                {
                    precision = JpegHelper.ScanJpegForBitDepth(oldPixelData);
                }
                catch
                {
                    // if the internal scanner chokes on an image, try again using ijg
                    precision = new Jpeg12Codec(JpegMode.Baseline, 0, 0).ScanHeaderForPrecision(oldNativeData);
                }
            }
            catch
            {
                // the old scanner choked on several valid images...
                // assume the correct encoder was used and let libijg handle the rest
                precision = oldPixelData.BitsStored;
            }

            if (newPixelData.BitsStored <= 8 && precision > 8) newPixelData.BitsAllocated = 16; // embedded overlay?

            var codec = GetCodec(precision, jparams);

            var newNativeData = newPixelData.ToNativePixelData();
            var jNativeParams = jparams.ToNativeJpegParameters();
            for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++)
            {
                codec.Decode(oldNativeData, newNativeData, jNativeParams, frame);
            }
        }
コード例 #25
0
ファイル: DicomJpegCodec.cs プロジェクト: jwake/fo-dicom
 public abstract void Encode(DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters);
コード例 #26
0
ファイル: DicomJpegCodec.cs プロジェクト: jwake/fo-dicom
            //DCMTK djcodecd.cxx
            public static int ScanJpegForBitDepth(DicomPixelData pixelData)
            {
                DicomFragmentSequence element = pixelData.Dataset.Get<DicomFragmentSequence>(DicomTag.PixelData);
                IByteBuffer buffer = element.Fragments[0];
                MemoryStream ms = new MemoryStream(buffer.Data);
                BinaryReader br = EndianBinaryReader.Create(ms, Endian.Big);

                long length = ms.Length;
                while (ms.Position < length) {
                ushort marker = br.ReadUInt16();
                switch (marker) {
                case 0xffc0: // SOF_0: JPEG baseline
                case 0xffc1: // SOF_1: JPEG extended sequential DCT
                case 0xffc2: // SOF_2: JPEG progressive DCT
                case 0xffc3: // SOF_3: JPEG lossless sequential
                case 0xffc5: // SOF_5: differential (hierarchical) extended sequential, Huffman
                case 0xffc6: // SOF_6: differential (hierarchical) progressive, Huffman
                case 0xffc7: // SOF_7: differential (hierarchical) lossless, Huffman
                    ms.Seek(2, SeekOrigin.Current);
                    return (int)br.ReadByte();
                case 0xffc8: // Reserved for JPEG extentions
                    ms.Seek(br.ReadUInt16() - 2, SeekOrigin.Current);
                    break;
                case 0xffc9: // SOF_9: extended sequential, arithmetic
                case 0xffca: // SOF_10: progressive, arithmetic
                case 0xffcb: // SOF_11: lossless, arithmetic
                case 0xffcd: // SOF_13: differential (hierarchical) extended sequential, arithmetic
                case 0xffce: // SOF_14: differential (hierarchical) progressive, arithmetic
                case 0xffcf: // SOF_15: differential (hierarchical) lossless, arithmetic
                    ms.Seek(2, SeekOrigin.Current);
                    return (int)br.ReadByte();
                case 0xffc4: // DHT
                case 0xffcc: // DAC
                    ms.Seek(br.ReadUInt16() - 2, SeekOrigin.Current);
                    break;
                case 0xffd0: // RST m
                case 0xffd1:
                case 0xffd2:
                case 0xffd3:
                case 0xffd4:
                case 0xffd5:
                case 0xffd6:
                case 0xffd7:
                case 0xffd8: // SOI
                case 0xffd9: // EOI
                    break;
                case 0xffda: // SOS
                case 0xffdb: // DQT
                case 0xffdc: // DNL
                case 0xffdd: // DRI
                case 0xffde: // DHP
                case 0xffdf: // EXP
                case 0xffe0: // APPn
                case 0xffe1:
                case 0xffe2:
                case 0xffe3:
                case 0xffe4:
                case 0xffe5:
                case 0xffe6:
                case 0xffe7:
                case 0xffe8:
                case 0xffe9:
                case 0xffea:
                case 0xffeb:
                case 0xffec:
                case 0xffed:
                case 0xffee:
                case 0xffef:
                case 0xfff0: // JPGn
                case 0xfff1:
                case 0xfff2:
                case 0xfff3:
                case 0xfff4:
                case 0xfff5:
                case 0xfff6:
                case 0xfff7:
                case 0xfff8:
                case 0xfff9:
                case 0xfffa:
                case 0xfffb:
                case 0xfffc:
                case 0xfffd:
                case 0xfffe: // COM
                    ms.Seek(br.ReadUInt16() - 2, SeekOrigin.Current);
                    break;
                case 0xff01: // TEM
                    break;
                default:
                    int b1 = br.ReadByte();
                    int b2 = br.ReadByte();
                    if (b1 == 0xff && b2 > 2 && b2 <= 0xbf) // RES reserved markers
                        break;
                    else
                        throw new DicomCodecException("Unable to determine bit depth: JPEG syntax error!");
                }
                }
                throw new DicomCodecException("Unable to determine bit depth: no JPEG SOF marker found!");
            }
コード例 #27
0
ファイル: PixelData.cs プロジェクト: jwake/fo-dicom
 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);
     }
 }
コード例 #28
0
ファイル: AbstractCodecTest.cs プロジェクト: nhannd/Xian
        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;
        }