Пример #1
0
        internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax)
        {
            //Sometimes there's 0-length ATs...
            uint readCount = length;

            if (readCount >= 2)
            {
                encapgroup = br.ReadUInt16();
                readCount -= 2;
            }
            else
            {
                encapgroup = 0;
            }

            if (readCount >= 2)
            {
                encapelem  = br.ReadUInt16();
                readCount -= 2;
            }
            else
            {
                encapelem = 0;
            }

            br.ReadBytes((int)readCount);

            return(length);
        }
Пример #2
0
 internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax)
 {
     //Store it as LSB-ordered bytes for optimization
     //Maybe down the line add some optimized way to modify a word array if it looks like a user's gonna be doing that a lot for some reason
     Data = br.ReadWords((int)length);
     return(this.length);
 }
Пример #3
0
 internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax)
 {
     //reuse the setter!
     byte[] data = br.ReadBytesUpToMax((int)length);
     Data = data;
     return((uint)data.Length);
 }
Пример #4
0
        internal uint ParseStream(SwappableBinaryReader br, ILogger logger, TransferSyntax transferSyntax, uint length, bool encapImage)
        {
            IsEncapsulatedImage = encapImage;

            if (encapImage && length != 0xFFFFFFFF)
            {
                //Encapsulated Image with explicit length!
                EncapsulatedImageData = br.ReadBytes((int)length);

                //Any way to figure out if we need to MSB-swap this? (i.e. is it an OW or an OB? Does that come from the parent element?)
                return(length);
            }

            bool done  = false;
            uint count = 0;

            while (!done)
            {
                //Check if we're past the end yet
                if (length != 0xFFFFFFFF && count >= length)
                {
                    done = true;
                    continue;
                }

                long readPosition = br.BaseStream.Position;

                //Read in group/element info
                ushort group = br.ReadUInt16();
                ushort elem  = br.ReadUInt16();
                count += 4;

                //Make element
                uint         outLen;
                DICOMElement nelem = DICOMElement.Parse(group, elem, logger, transferSyntax, br, this, false, out outLen);

                //Store reading position in case it's useful later
                nelem.ReadPosition = readPosition;
                count += outLen;

                //Was that the end-of-sequence item?
                if (group == 0xFFFE && elem == 0xE00D)
                {
                    done = true;
                }
                else
                {
                    ElementsLookup[nelem.Tag] = nelem;
                    Elements.Add(nelem);
                }
            }
            return(count);
        }
Пример #5
0
 internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax)
 {
     if (length < 8)
     {
         data = 0;
         br.ReadBytes((int)length);
     }
     else
     {
         data = br.ReadDouble();
         if (length > 8)
         {
             br.ReadBytes((int)length - 8);
         }
     }
     return(length);
 }
Пример #6
0
 internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax)
 {
     if (length < 2)
     {
         //busted...
         data = (ushort)0;
         br.ReadBytes((int)length);
     }
     else if (length == 2)
     {
         data = br.ReadUInt16();
     }
     else if (length > 2)
     {
         uint readBytes = 0;
         DataDictionaryElement elemCheck = DataDictionary.LookupElement(this.Tag);
         if (elemCheck == null || elemCheck.VMMax > 1)
         {
             //Unknown VM or VM goes to > 1
             data = new ushort[length / 2];
             for (int i = 0; i < length / 2; i++)
             {
                 ((ushort[])data)[i] = br.ReadUInt16();
             }
             readBytes = (length / 2) * 2;
         }
         else
         {
             //VM of 1 -- force to single data point
             data      = br.ReadUInt16();
             readBytes = 2;
         }
         if (length - readBytes > 0)
         {
             br.ReadBytes((int)(length - readBytes));
         }
     }
     return(length);
 }
Пример #7
0
        internal void ParsePacket(SwappableBinaryReader dataSource, int itemLength)
        {
            long startOffset = dataSource.BaseStream.Position;

            ContextID = dataSource.ReadByte();
            byte reserved = dataSource.ReadByte();

            Result   = (PresentationResult)dataSource.ReadByte();
            reserved = dataSource.ReadByte();

            while (dataSource.BaseStream.Position - startOffset < itemLength)
            {
                //read sub-item
                byte   subItemType     = dataSource.ReadByte();
                byte   subItemReserved = dataSource.ReadByte();
                ushort subItemLength   = dataSource.ReadUInt16();

                if (subItemType == 0x30)
                {
                    string rawSyntax = Uid.UidRawToString(dataSource.ReadBytes(subItemLength));
                    AbstractSyntaxSpecified = AbstractSyntaxes.Lookup(rawSyntax);
                }
                else if (subItemType == 0x40)
                {
                    string         rawSyntax = Uid.UidRawToString(dataSource.ReadBytes(subItemLength));
                    TransferSyntax syntax    = TransferSyntaxes.Lookup(rawSyntax);
                    if (syntax != null)
                    {
                        TransferSyntaxesProposed.Add(syntax);
                    }
                }
                else
                {
                    //no idea what it is, or we don't care
                    dataSource.ReadBytes(itemLength);
                }
            }
        }
Пример #8
0
        internal bool ParseStream(Stream stream, TransferSyntax transferSyntax, bool allowSyntaxChanges, bool loadImageData, ILogger logger)
        {
            SwappableBinaryReader sr = new SwappableBinaryReader(stream);
            long readPosition        = stream.Position;

            bool inGroup2 = false;

            if (transferSyntax.MSBSwap) //this should be applicable...
            {
                sr.ToggleSwapped();
            }

            TransferSyntax parsedSyntax = null;

            while (readPosition + 8 < stream.Length)
            {
                //Read in group/element info
                ushort group = sr.ReadUInt16();
                ushort elem  = sr.ReadUInt16();

                //Leaving the header?
                if (inGroup2 != (group == 2))
                {
                    if (transferSyntax.MSBSwap)
                    {
                        sr.ToggleSwapped();
                    }

                    inGroup2 = (group == 2);
                }

                //Stop loading if we're at image data and not supposed to read it
                var skipData = !loadImageData && group == 0x7FE0 && elem == 0x0010;

                //Make element
                uint         outLen;
                DICOMElement nelem;
                try
                {
                    nelem = DICOMElement.Parse(group, elem, logger, transferSyntax, sr, null, skipData, out outLen);
                }
                catch (Exception e)
                {
                    logger.Log(LogLevel.Error, "Exception in DICOMElement.Parse: " + e.ToString());
                    return(false);
                }

                //Debugging:
                //Console.WriteLine(nelem.Dump());

                //Store reading position in case it's useful later
                nelem.ReadPosition = readPosition;

                //Store element in lookup array
                Elements[nelem.Tag] = nelem;

                //Store transfer syntax change for after the header
                if (nelem.Tag == DICOMTags.TransferSyntaxUID)
                {
                    parsedSyntax = TransferSyntaxes.Lookup((string)nelem.Data);
                    if (allowSyntaxChanges)
                    {
                        transferSyntax = parsedSyntax;
                    }
                }

                //update read position pointer
                readPosition = stream.Position;
            }

            //Store whatever TS we ended up with
            TransferSyntax = (parsedSyntax != null) ? parsedSyntax : transferSyntax;

            return(true);
        }
Пример #9
0
 internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax)
 {
     //reuse setter
     Data = System.Text.Encoding.ASCII.GetString(br.ReadBytes((int)length));
     return(length);
 }
Пример #10
0
        internal override uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax)
        {
            //Covered by PS 3.5, Chapter 7.5 (pg. 42-45)
            bool encapImage = (Tag == DICOMTags.PixelData);

            bool done  = false;
            uint count = 0;

            while (!done)
            {
                //If explicit length, see if we're done
                if (length != 0xFFFFFFFF && count >= length)
                {
                    done = true;
                    continue;
                }

                ushort grp  = br.ReadUInt16();
                ushort elem = br.ReadUInt16();
                uint   len  = br.ReadUInt32();
                count += 8;

                //Sometimes there's retarded files that are msb swapped inside of sequences outside of the transfer syntax
                bool needMoreSwap = (grp == 0xFEFF);

                if (needMoreSwap)
                {
                    //Swap the reader for now, then swap back after the sqitem
                    br.ToggleSwapped();

                    //still have to swap the stuff we've already read by hand tho
                    grp  = MSBSwapper.SwapW(grp);
                    elem = MSBSwapper.SwapW(elem);
                    len  = MSBSwapper.SwapDW(len);
                }

                if (grp == 0xFFFE && elem == 0xE000)
                {
                    //Normal element, parse it out.
                    SQItem item = new SQItem(this);
                    count += item.ParseStream(br, logger, transferSyntax, len, encapImage);
                    Items.Add(item);
                }
                else if (grp == 0xFFFE && elem == 0xE0DD)
                {
                    //End element

                    //In case there's garbage in there, read the length bytes
                    br.ReadBytes((int)len);
                    count += len;

                    done = true;
                }
                else
                {
                    throw new NotImplementedException();
                }

                //toggle back in case it's just one SQItem that's hosed
                if (needMoreSwap)
                {
                    br.ToggleSwapped();
                }
            }

            return(count);
        }
Пример #11
0
 abstract internal uint ParseData(SwappableBinaryReader br, ILogger logger, uint length, TransferSyntax transferSyntax);
Пример #12
0
        //parseLen returns total bytes read
        internal static DICOMElement Parse(ushort group, ushort elem, ILogger logger, TransferSyntax transferSyntax, SwappableBinaryReader br, SQItem parentSQ, bool skipOverData, out uint parseLen)
        {
            ushort vr;
            uint   len;
            uint   headerBytes = 0;

            // Group 0 is always little-endian implicit vr, group 2 is always little-endian explicit vr
            if ((transferSyntax.ExplicitVR && group != 0) || group == 2)
            {
                vr           = br.ReadUInt16MSB();
                headerBytes += 2;

                if (vr == DICOMElementUT.vrshort || vr == DICOMElementUN.vrshort || vr == DICOMElementOB.vrshort ||
                    vr == DICOMElementOW.vrshort || vr == DICOMElementSQ.vrshort)
                {
                    //next 2 bytes reserved
                    br.ReadUInt16();
                    headerBytes += 2;

                    //len is next 4
                    len          = br.ReadUInt32();
                    headerBytes += 4;
                }
                else
                {
                    //len is next 2
                    len          = br.ReadUInt16();
                    headerBytes += 2;
                }
            }
            else
            {
                //Look up VR in the dictionary
                DataDictionaryElement dde = DataDictionary.LookupElement(group, elem);
                if (dde != null)
                {
                    //Found it.
                    vr = dde.vrshort;
                }
                else
                {
                    //No idea... OB!
                    vr = DICOMElementOB.vrshort;
                }

                //Length will always be 32-bit here
                len          = br.ReadUInt32();
                headerBytes += 4;
            }

            DICOMElement ret = null;

            //Is it a compressed weirdo image data sequence that's actually an SQ?
            if (len == 0xFFFFFFFF)
            {
                ret = new DICOMElementSQ(group, elem);
            }
            else
            {
                ret = CreateByVR(group, elem, vr);
            }

            ret.parentSQItem = parentSQ;

            //Parse internal Data
            parseLen = headerBytes;

            try
            {
                // Can't skip over the length if it's not explicit
                if (skipOverData && len != 0xFFFFFFFF)
                {
                    parseLen += len;
                    br.BaseStream.Seek(len, SeekOrigin.Current);
                }
                else
                {
                    parseLen += ret.ParseData(br, logger, len, transferSyntax);
                }
            }
            catch (Exception e)
            {
                logger.Log(LogLevel.Error, "Exception in ParseData(grp=" + group + ", elem=" + elem + ", len=" + len + "): " + e.ToString());
            }

            return(ret);
        }
Пример #13
0
 internal PresentationContext(SwappableBinaryReader dataSource, int itemLength)
     : this()
 {
     ParsePacket(dataSource, itemLength);
 }