예제 #1
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);
        }
예제 #2
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);
            }
        }
예제 #3
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);
            }
        }
예제 #4
0
        /// <summary>
        /// Initializes an instance of <see cref="DicomTranscoder"/>.
        /// </summary>
        /// <param name="inputSyntax">Input transfer syntax.</param>
        /// <param name="outputSyntax">Output transfer syntax.</param>
        /// <param name="inputCodecParams">Input codec parameters.</param>
        /// <param name="outputCodecParams">Output codec parameters.</param>
        public DicomTranscoder(
            DicomTransferSyntax inputSyntax,
            DicomTransferSyntax outputSyntax,
            DicomCodecParams inputCodecParams  = null,
            DicomCodecParams outputCodecParams = null)
        {
            InputSyntax       = inputSyntax;
            OutputSyntax      = outputSyntax;
            InputCodecParams  = inputCodecParams ?? DefaultInputCodecParams(inputSyntax);
            OutputCodecParams = outputCodecParams;

            _inputCodec  = new Lazy <IDicomCodec>(() => InitializeCodec(InputSyntax));
            _outputCodec = new Lazy <IDicomCodec>(() => InitializeCodec(OutputSyntax));
        }
예제 #5
0
        private static DicomDataset Encode(
            DicomDataset oldDataset,
            DicomTransferSyntax outSyntax,
            IDicomCodec codec,
            DicomCodecParams parameters)
        {
            if (codec == null)
            {
                throw new DicomCodecException($"Encoding dataset to transfer syntax {outSyntax} is not supported.");
            }

            var oldPixelData = DicomPixelData.Create(oldDataset);

            var newDataset = oldDataset.Clone();

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

            codec.Encode(oldPixelData, newPixelData, parameters);

            if (outSyntax.IsLossy && newPixelData.NumberOfFrames > 0)
            {
                newDataset.AddOrUpdate(new DicomCodeString(DicomTag.LossyImageCompression, "01"));

                var methods = new List <string>();
                if (newDataset.Contains(DicomTag.LossyImageCompressionMethod))
                {
                    methods.AddRange(newDataset.GetValues <string>(DicomTag.LossyImageCompressionMethod));
                }

                methods.Add(outSyntax.LossyCompressionMethod);
                newDataset.AddOrUpdate(new DicomCodeString(DicomTag.LossyImageCompressionMethod, methods.ToArray()));

                double oldSize = oldPixelData.GetFrame(0).Size;
                double newSize = newPixelData.GetFrame(0).Size;
                var    ratio   = string.Format(CultureInfo.InvariantCulture, "{0:0.000}", oldSize / newSize);
                newDataset.AddOrUpdate(new DicomDecimalString(DicomTag.LossyImageCompressionRatio, ratio));
            }

            ProcessOverlays(oldDataset, newDataset);

            newDataset.RecalculateGroupLengths(false);

            return(newDataset);
        }
예제 #6
0
 public abstract void Decode(
     DicomPixelData oldPixelData,
     DicomPixelData newPixelData,
     DicomCodecParams parameters);