Exemple #1
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);
        }
        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);
        }